mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-25 09:32:38 +00:00
Patch from Stanislaw Gruszka <stanislawg1@open-e.com>
This is SCST driver for ISP Qlogic chipsets commonly used in many SCSI and FC host bus adapters. Supported chipset are listed in README file, incomplete list of supported HBA's is in doc/Hardware.txt . It is based on Matthew Jacob's multiplatform driver for ISP chipsets, which can be download from ftp://ftp.feral.com/pub/isp/isp_dist.tgz git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@135 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
Copyright (c) 1997-2007 by Matthew Jacob
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
Alternatively, this software may be distributed under the terms of the
|
||||
the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
is the GNU Public License:
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
Matthew Jacob
|
||||
Feral Software
|
||||
421 Laurel Avenue
|
||||
Menlo Park, CA 94025
|
||||
USA
|
||||
|
||||
gplbsd at feral com
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
ifndef KDIR
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
endif
|
||||
|
||||
export KDIR
|
||||
|
||||
all:
|
||||
$(MAKE) -C linux-2.6 tgt
|
||||
|
||||
clean:
|
||||
$(MAKE) -C linux-2.6 clean
|
||||
|
||||
install:
|
||||
$(MAKE) -C linux-2.6 install
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
$Id: README,v 1.30 2007/03/05 19:10:52 mjacob Exp $
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Supported Cards:
|
||||
|
||||
SBus ISP1000 && ISP1000U
|
||||
PCI SCSI ISP1020
|
||||
PCI Ultra SCSI ISP1040, ISP1240 (dual bus)
|
||||
PCI Ultra2 SCSI ISP1080, ISP1280 (dual bus)
|
||||
PCI Ultra3 SCSI ISP12160 (dual bus)
|
||||
PCI Fibre Channel
|
||||
1-Gbit:
|
||||
ISP2100, ISP2102
|
||||
ISP2200, ISP2202, ISP2204
|
||||
|
||||
2-Gbit:
|
||||
ISP2300, ISP2312, ISP2324, 2340, 2342
|
||||
ISP2322, ISP6322
|
||||
ISP200
|
||||
4-Gbit:
|
||||
ISP2422, ISP2432
|
||||
|
||||
You should note that some old non-Qlogic (or very old Qlogic) 2100 cards may
|
||||
have trouble loading firmware. The newer f/w for 2100s is > 0x8000 words,
|
||||
which PROM code on some cards has trouble loading- define the token
|
||||
USE_SMALLER_2100_FIRMWARE to select 1.15.37 f/w for the 2100.
|
||||
|
||||
For 23XX (but not 2322) 2K Login firmware is available and is recommended.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,48 @@
|
||||
WARNING: This driver is not finished, USE ONLY FOR TESTING.
|
||||
|
||||
This is SCST driver for ISP Qlogic chipsets commonly used in many SCSI and FC
|
||||
host bus adapters. Supported chipset are listed in README file, incomplete
|
||||
list of supported HBA's is in doc/Hardware.txt .
|
||||
|
||||
It is based on Matthew Jacob's multiplatform driver for ISP chipsets,
|
||||
which can be download from ftp://ftp.feral.com/pub/isp/isp_dist.tgz. The
|
||||
update for SCST was made and supported by Stanislaw Gruszka
|
||||
<stanislawg1@open-e.com>.
|
||||
|
||||
Driver operate same hardware as qla2x00tgt, but have one adventage over it:
|
||||
support of 24xx series of Qlogic adapters.
|
||||
|
||||
INSTALLATION:
|
||||
|
||||
Build driver with command
|
||||
$ make
|
||||
Then install isp_mod, isp_scst modules
|
||||
$ make install
|
||||
|
||||
Other Qlogic drivers can not coexist in system, unload all other qla modules
|
||||
|
||||
$ rmmod qla2x00tgt
|
||||
$ rmmod qla2400
|
||||
$ rmmod qla2300
|
||||
$ rmmod qla2200
|
||||
$ rmmod qla2xxx
|
||||
|
||||
Load isp modules
|
||||
|
||||
$ modprobe isp_scst
|
||||
$ modprobe isp_mod
|
||||
|
||||
Enable all logical units to work in target mode
|
||||
|
||||
$ echo 1 > /proc/scsi_tgt/qla_isp/0
|
||||
|
||||
(to unload isp_mod.ko module you must write 0 to this file).
|
||||
This is not switching target/initiator role. If you have more then one device,
|
||||
role of each you can set using isp_roles parameter, like in example:
|
||||
|
||||
$ modprobe isp_mode isp_roles="b0300=initiator"
|
||||
|
||||
Magic number "b0300" is DEVID value, which you can find in /proc/scsi/isp/X
|
||||
|
||||
To attach logical units continue with normal SCST setup
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,252 @@
|
||||
/* $Id: isp_library.h,v 1.22 2007/05/31 18:35:28 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
#ifndef _ISP_LIBRARY_H
|
||||
#define _ISP_LIBRARY_H
|
||||
|
||||
extern int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *);
|
||||
extern XS_T *isp_find_xs(ispsoftc_t *, uint32_t);
|
||||
extern uint32_t isp_find_handle(ispsoftc_t *, XS_T *);
|
||||
extern uint32_t isp_handle_index(uint32_t);
|
||||
extern void isp_destroy_handle(ispsoftc_t *, uint32_t);
|
||||
extern int isp_getrqentry(ispsoftc_t *, uint32_t *, uint32_t *, void **);
|
||||
extern void isp_print_qentry (ispsoftc_t *, char *, int, void *);
|
||||
extern void isp_print_bytes(ispsoftc_t *, const char *, int, void *);
|
||||
extern int isp_fc_runstate(ispsoftc_t *, int, int);
|
||||
extern void isp_dump_portdb(ispsoftc_t *, int);
|
||||
extern void isp_shutdown(ispsoftc_t *);
|
||||
extern void isp_put_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
extern void isp_get_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
extern int isp_get_response_type(ispsoftc_t *, isphdr_t *);
|
||||
extern void
|
||||
isp_put_request(ispsoftc_t *, ispreq_t *, ispreq_t *);
|
||||
extern void
|
||||
isp_put_marker(ispsoftc_t *, isp_marker_t *, isp_marker_t *);
|
||||
extern void
|
||||
isp_put_marker_24xx(ispsoftc_t *, isp_marker_24xx_t *, isp_marker_24xx_t *);
|
||||
extern void
|
||||
isp_put_request_t2(ispsoftc_t *, ispreqt2_t *, ispreqt2_t *);
|
||||
extern void
|
||||
isp_put_request_t2e(ispsoftc_t *, ispreqt2e_t *, ispreqt2e_t *);
|
||||
extern void
|
||||
isp_put_request_t3(ispsoftc_t *, ispreqt3_t *, ispreqt3_t *);
|
||||
extern void
|
||||
isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
|
||||
extern void
|
||||
isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
|
||||
extern void
|
||||
isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
|
||||
extern void
|
||||
isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
extern void
|
||||
isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
|
||||
extern void
|
||||
isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
|
||||
extern void
|
||||
isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
|
||||
extern void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *,
|
||||
isp24xx_statusreq_t *);
|
||||
void
|
||||
isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
extern void
|
||||
isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
|
||||
extern void
|
||||
isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
|
||||
extern void
|
||||
isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
|
||||
extern void
|
||||
isp_get_pdb_21xx(ispsoftc_t *, isp_pdb_21xx_t *, isp_pdb_21xx_t *);
|
||||
extern void
|
||||
isp_get_pdb_24xx(ispsoftc_t *, isp_pdb_24xx_t *, isp_pdb_24xx_t *);
|
||||
extern void
|
||||
isp_get_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
|
||||
extern void
|
||||
isp_put_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
|
||||
extern void
|
||||
isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
|
||||
extern void
|
||||
isp_get_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
|
||||
extern void
|
||||
isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
|
||||
extern void
|
||||
isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
|
||||
extern void
|
||||
isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *);
|
||||
extern void
|
||||
isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *,
|
||||
sns_gid_ft_req_t *);
|
||||
extern void
|
||||
isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *,
|
||||
sns_gxn_id_req_t *);
|
||||
extern void
|
||||
isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int);
|
||||
extern void
|
||||
isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *,
|
||||
sns_gid_ft_rsp_t *, int);
|
||||
extern void
|
||||
isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *,
|
||||
sns_gxn_id_rsp_t *);
|
||||
extern void
|
||||
isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *,
|
||||
sns_gff_id_rsp_t *);
|
||||
extern void
|
||||
isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *,
|
||||
sns_ga_nxt_rsp_t *);
|
||||
extern void
|
||||
isp_get_els(ispsoftc_t *, els_t *, els_t *);
|
||||
extern void
|
||||
isp_put_els(ispsoftc_t *, els_t *, els_t *);
|
||||
extern void
|
||||
isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
|
||||
extern void
|
||||
isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
|
||||
extern void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
|
||||
extern void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
extern void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
|
||||
#define ISP_HANDLE_MASK 0x7fff
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <dev/ic/isp_target.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <dev/isp/isp_target.h>
|
||||
#else
|
||||
#include "isp_target.h"
|
||||
#endif
|
||||
|
||||
#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
|
||||
|
||||
extern int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *);
|
||||
extern void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
|
||||
extern uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
|
||||
extern void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
|
||||
|
||||
extern void
|
||||
isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
extern void
|
||||
isp_get_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
extern void
|
||||
isp_put_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
|
||||
extern void
|
||||
isp_put_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
|
||||
extern void
|
||||
isp_get_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
|
||||
extern void
|
||||
isp_get_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
|
||||
extern void
|
||||
isp_get_atio7(ispsoftc_t *isp, at7_entry_t *, at7_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
|
||||
extern void
|
||||
isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
|
||||
extern void
|
||||
isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
|
||||
extern void
|
||||
isp_put_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
|
||||
extern void
|
||||
isp_get_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
|
||||
extern void
|
||||
isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
|
||||
extern void
|
||||
isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
|
||||
extern void
|
||||
isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_get_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
|
||||
extern void
|
||||
isp_get_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
|
||||
extern void
|
||||
isp_get_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_put_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
|
||||
extern void
|
||||
isp_get_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
|
||||
extern void
|
||||
isp_put_notify_24xx_ack(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_put_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
|
||||
extern void
|
||||
isp_put_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
|
||||
extern void isp_put_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
|
||||
na_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_get_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
|
||||
extern void
|
||||
isp_get_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
|
||||
extern void isp_get_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
|
||||
na_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_get_abts(ispsoftc_t *, abts_t *, abts_t *);
|
||||
extern void
|
||||
isp_put_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
|
||||
extern void
|
||||
isp_get_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
|
||||
#endif /* ISP_TARGET_MODE */
|
||||
#endif /* _ISP_LIBRARY_H */
|
||||
@@ -0,0 +1,239 @@
|
||||
/* $Id: isp_stds.h,v 1.10 2007/03/10 01:56:34 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Structures that derive directly from public standards.
|
||||
*/
|
||||
#ifndef _ISP_STDS_H
|
||||
#define _ISP_STDS_H
|
||||
|
||||
/*
|
||||
* FC Frame Header
|
||||
*
|
||||
* Source: dpANS-X3.xxx-199x, section 18 (AKA FC-PH-2)
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t r_ctl;
|
||||
uint8_t d_id[3];
|
||||
uint8_t cs_ctl;
|
||||
uint8_t s_id[3];
|
||||
uint8_t type;
|
||||
uint8_t f_ctl;
|
||||
uint8_t seq_id;
|
||||
uint8_t df_ctl;
|
||||
uint16_t seq_cnt;
|
||||
uint16_t ox_id;
|
||||
uint16_t rx_id;
|
||||
uint32_t parameter;
|
||||
} fc_hdr_t;
|
||||
|
||||
/*
|
||||
* FCP_CMND_IU Payload
|
||||
*
|
||||
* Source: NICTS T10, Project 1144D, Revision 07a, Section 9 (AKA fcp2-r07a)
|
||||
*
|
||||
* Notes:
|
||||
* When additional cdb length is defined in fcp_cmnd_alen_datadir,
|
||||
* bits 2..7, the actual cdb length is 16 + ((fcp_cmnd_alen_datadir>>2)*4),
|
||||
* with the datalength following in MSB format just after.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t fcp_cmnd_lun[8];
|
||||
uint8_t fcp_cmnd_crn;
|
||||
uint8_t fcp_cmnd_task_attribute;
|
||||
uint8_t fcp_cmnd_task_management;
|
||||
uint8_t fcp_cmnd_alen_datadir;
|
||||
union {
|
||||
struct {
|
||||
uint8_t fcp_cmnd_cdb[16];
|
||||
uint32_t fcp_cmnd_dl;
|
||||
} sf;
|
||||
struct {
|
||||
uint8_t fcp_cmnd_cdb[1];
|
||||
} lf;
|
||||
} cdb_dl;
|
||||
} fcp_cmnd_iu_t;
|
||||
|
||||
|
||||
#define FCP_CMND_TASK_ATTR_SIMPLE 0x00
|
||||
#define FCP_CMND_TASK_ATTR_HEAD 0x01
|
||||
#define FCP_CMND_TASK_ATTR_ORDERED 0x02
|
||||
#define FCP_CMND_TASK_ATTR_ACA 0x04
|
||||
#define FCP_CMND_TASK_ATTR_UNTAGGED 0x05
|
||||
#define FCP_CMND_TASK_ATTR_MASK 0x07
|
||||
|
||||
#define FCP_CMND_ADDTL_CDBLEN_SHIFT 2
|
||||
|
||||
#define FCP_CMND_DATA_WRITE 0x01
|
||||
#define FCP_CMND_DATA_READ 0x02
|
||||
|
||||
#define FCP_CMND_DATA_DIR_MASK 0x03
|
||||
|
||||
#define FCP_CMND_TMF_CLEAR_ACA 0x40
|
||||
#define FCP_CMND_TMF_TGT_RESET 0x20
|
||||
#define FCP_CMND_TMF_LUN_RESET 0x10
|
||||
#define FCP_CMND_TMF_CLEAR_TASK_SET 0x04
|
||||
#define FCP_CMND_TMF_ABORT_TASK_SET 0x02
|
||||
|
||||
/*
|
||||
* Basic CT IU Header
|
||||
*
|
||||
* Source: X3.288-199x Generic Services 2 Rev 5.3 (FC-GS-2) Section 4.3.1
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t ct_revision;
|
||||
uint8_t ct_in_id[3];
|
||||
uint8_t ct_fcs_type;
|
||||
uint8_t ct_fcs_subtype;
|
||||
uint8_t ct_options;
|
||||
uint8_t ct_reserved0;
|
||||
uint16_t ct_cmd_resp;
|
||||
uint16_t ct_bcnt_resid;
|
||||
uint8_t ct_reserved1;
|
||||
uint8_t ct_reason;
|
||||
uint8_t ct_explanation;
|
||||
uint8_t ct_vunique;
|
||||
} ct_hdr_t;
|
||||
#define CT_REVISION 1
|
||||
#define CT_FC_TYPE_FC 0xFC
|
||||
#define CT_FC_SUBTYPE_NS 0x02
|
||||
|
||||
/*
|
||||
* RFT_ID Requet CT_IU
|
||||
*
|
||||
* Source: NCITS xxx-200x Generic Services- 5 Rev 8.5 Section 5.2.5.30
|
||||
*/
|
||||
typedef struct {
|
||||
ct_hdr_t rftid_hdr;
|
||||
uint8_t rftid_reserved;
|
||||
uint8_t rftid_portid[3];
|
||||
uint32_t rftid_fc4types[8];
|
||||
} rft_id_t;
|
||||
|
||||
/*
|
||||
* FCP Response Code Definitions
|
||||
* Source: NCITS T10, Project 1144D, Revision 07a (aka FCP2r07a)
|
||||
*/
|
||||
#define FCP_RSPNS_CODE_OFFSET 3
|
||||
|
||||
#define FCP_RSPNS_TMF_DONE 0
|
||||
#define FCP_RSPNS_DLBRSTX 1
|
||||
#define FCP_RSPNS_BADCMND 2
|
||||
#define FCP_RSPNS_EROFS 3
|
||||
#define FCP_RSPNS_TMF_REJECT 4
|
||||
#define FCP_RSPNS_TMF_FAILED 5
|
||||
|
||||
|
||||
/* unconverted miscellany */
|
||||
/*
|
||||
* Basic FC Link Service defines
|
||||
*/
|
||||
/*
|
||||
* These are in the R_CTL field.
|
||||
*/
|
||||
#define ABTS 0x81
|
||||
#define BA_ACC 0x84 /* of ABORT SEQUENCE */
|
||||
#define BA_RJT 0x85 /* of ABORT SEQUENCE */
|
||||
|
||||
/*
|
||||
* Link Service Accept/Reject
|
||||
*/
|
||||
#define LS_ACC 0x8002
|
||||
#define LS_RJT 0x8001
|
||||
|
||||
/*
|
||||
* FC ELS Codes- bits 31-24 of the first payload word of an ELS frame.
|
||||
*/
|
||||
#define PLOGI 0x03
|
||||
#define FLOGI 0x04
|
||||
#define LOGO 0x05
|
||||
#define ABTX 0x06
|
||||
#define PRLI 0x20
|
||||
#define PRLO 0x21
|
||||
#define TPRLO 0x24
|
||||
#define RNC 0x53
|
||||
|
||||
/*
|
||||
* FC4 defines
|
||||
*/
|
||||
#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP */
|
||||
#define FC4_SCSI 8 /* SCSI-3 via Fibre Channel Protocol (FCP) */
|
||||
#define FC4_FC_SVC 0x20 /* Fibre Channel Services */
|
||||
|
||||
#ifndef MSG_ABORT
|
||||
#define MSG_ABORT 0x06
|
||||
#endif
|
||||
#ifndef MSG_BUS_DEV_RESET
|
||||
#define MSG_BUS_DEV_RESET 0x0c
|
||||
#endif
|
||||
#ifndef MSG_ABORT_TAG
|
||||
#define MSG_ABORT_TAG 0x0d
|
||||
#endif
|
||||
#ifndef MSG_CLEAR_QUEUE
|
||||
#define MSG_CLEAR_QUEUE 0x0e
|
||||
#endif
|
||||
#ifndef MSG_REL_RECOVERY
|
||||
#define MSG_REL_RECOVERY 0x10
|
||||
#endif
|
||||
#ifndef MSG_TERM_IO_PROC
|
||||
#define MSG_TERM_IO_PROC 0x11
|
||||
#endif
|
||||
#ifndef MSG_LUN_RESET
|
||||
#define MSG_LUN_RESET 0x17
|
||||
#endif
|
||||
|
||||
#endif /* _ISP_STDS_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,973 @@
|
||||
/* $Id: isp_target.h,v 1.50 2007/06/01 17:19:31 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Qlogic Target Mode Structure and Flag Definitions
|
||||
*/
|
||||
#ifndef _ISP_TARGET_H
|
||||
#define _ISP_TARGET_H
|
||||
|
||||
#define QLTM_SENSELEN 18 /* non-FC cards only */
|
||||
#define QLTM_SVALID 0x80
|
||||
|
||||
/*
|
||||
* Structure for Enable Lun and Modify Lun queue entries
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t le_header;
|
||||
uint32_t le_reserved;
|
||||
uint8_t le_lun;
|
||||
uint8_t le_rsvd;
|
||||
uint8_t le_ops; /* Modify LUN only */
|
||||
uint8_t le_tgt; /* Not for FC */
|
||||
uint32_t le_flags; /* Not for FC */
|
||||
uint8_t le_status;
|
||||
uint8_t le_reserved2;
|
||||
uint8_t le_cmd_count;
|
||||
uint8_t le_in_count;
|
||||
uint8_t le_cdb6len; /* Not for FC */
|
||||
uint8_t le_cdb7len; /* Not for FC */
|
||||
uint16_t le_timeout;
|
||||
uint16_t le_reserved3[20];
|
||||
} lun_entry_t;
|
||||
|
||||
/*
|
||||
* le_flags values
|
||||
*/
|
||||
#define LUN_TQAE 0x00000002 /* bit1 Tagged Queue Action Enable */
|
||||
#define LUN_DSSM 0x01000000 /* bit24 Disable Sending SDP Message */
|
||||
#define LUN_DISAD 0x02000000 /* bit25 Disable autodisconnect */
|
||||
#define LUN_DM 0x40000000 /* bit30 Disconnects Mandatory */
|
||||
|
||||
/*
|
||||
* le_ops values
|
||||
*/
|
||||
#define LUN_CCINCR 0x01 /* increment command count */
|
||||
#define LUN_CCDECR 0x02 /* decrement command count */
|
||||
#define LUN_ININCR 0x40 /* increment immed. notify count */
|
||||
#define LUN_INDECR 0x80 /* decrement immed. notify count */
|
||||
|
||||
/*
|
||||
* le_status values
|
||||
*/
|
||||
#define LUN_OK 0x01 /* we be rockin' */
|
||||
#define LUN_ERR 0x04 /* request completed with error */
|
||||
#define LUN_INVAL 0x06 /* invalid request */
|
||||
#define LUN_NOCAP 0x16 /* can't provide requested capability */
|
||||
#define LUN_ENABLED 0x3E /* LUN already enabled */
|
||||
|
||||
/*
|
||||
* Immediate Notify Entry structure
|
||||
*/
|
||||
#define IN_MSGLEN 8 /* 8 bytes */
|
||||
#define IN_RSVDLEN 8 /* 8 words */
|
||||
typedef struct {
|
||||
isphdr_t in_header;
|
||||
uint32_t in_reserved;
|
||||
uint8_t in_lun; /* lun */
|
||||
uint8_t in_iid; /* initiator */
|
||||
uint8_t in_reserved2;
|
||||
uint8_t in_tgt; /* target */
|
||||
uint32_t in_flags;
|
||||
uint8_t in_status;
|
||||
uint8_t in_rsvd2;
|
||||
uint8_t in_tag_val; /* tag value */
|
||||
uint8_t in_tag_type; /* tag type */
|
||||
uint16_t in_seqid; /* sequence id */
|
||||
uint8_t in_msg[IN_MSGLEN]; /* SCSI message bytes */
|
||||
uint16_t in_reserved3[IN_RSVDLEN];
|
||||
uint8_t in_sense[QLTM_SENSELEN];/* suggested sense data */
|
||||
} in_entry_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t in_header;
|
||||
uint32_t in_reserved;
|
||||
uint8_t in_lun; /* lun */
|
||||
uint8_t in_iid; /* initiator */
|
||||
uint16_t in_scclun;
|
||||
uint32_t in_reserved2;
|
||||
uint16_t in_status;
|
||||
uint16_t in_task_flags;
|
||||
uint16_t in_seqid; /* sequence id */
|
||||
} in_fcentry_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t in_header;
|
||||
uint32_t in_reserved;
|
||||
uint16_t in_iid; /* initiator */
|
||||
uint16_t in_scclun;
|
||||
uint32_t in_reserved2;
|
||||
uint16_t in_status;
|
||||
uint16_t in_task_flags;
|
||||
uint16_t in_seqid; /* sequence id */
|
||||
} in_fcentry_e_t;
|
||||
|
||||
/*
|
||||
* Values for the in_status field
|
||||
*/
|
||||
#define IN_REJECT 0x0D /* Message Reject message received */
|
||||
#define IN_RESET 0x0E /* Bus Reset occurred */
|
||||
#define IN_NO_RCAP 0x16 /* requested capability not available */
|
||||
#define IN_IDE_RECEIVED 0x33 /* Initiator Detected Error msg received */
|
||||
#define IN_RSRC_UNAVAIL 0x34 /* resource unavailable */
|
||||
#define IN_MSG_RECEIVED 0x36 /* SCSI message received */
|
||||
#define IN_ABORT_TASK 0x20 /* task named in RX_ID is being aborted (FC) */
|
||||
#define IN_PORT_LOGOUT 0x29 /* port has logged out (FC) */
|
||||
#define IN_PORT_CHANGED 0x2A /* port changed */
|
||||
#define IN_GLOBAL_LOGO 0x2E /* all ports logged out */
|
||||
#define IN_NO_NEXUS 0x3B /* Nexus not established */
|
||||
|
||||
/*
|
||||
* Values for the in_task_flags field- should only get one at a time!
|
||||
*/
|
||||
#define TASK_FLAGS_RESERVED_MASK (0xe700)
|
||||
#define TASK_FLAGS_CLEAR_ACA (1<<14)
|
||||
#define TASK_FLAGS_TARGET_RESET (1<<13)
|
||||
#define TASK_FLAGS_LUN_RESET (1<<12)
|
||||
#define TASK_FLAGS_CLEAR_TASK_SET (1<<10)
|
||||
#define TASK_FLAGS_ABORT_TASK_SET (1<<9)
|
||||
|
||||
/*
|
||||
* ISP24XX Immediate Notify
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t in_header;
|
||||
uint32_t in_reserved;
|
||||
uint16_t in_nphdl;
|
||||
uint16_t in_reserved1;
|
||||
uint16_t in_flags;
|
||||
uint16_t in_srr_rxid;
|
||||
uint16_t in_status;
|
||||
uint8_t in_status_subcode;
|
||||
uint8_t in_reserved2;
|
||||
uint32_t in_rxid;
|
||||
uint16_t in_srr_reloff_lo;
|
||||
uint16_t in_srr_reloff_hi;
|
||||
uint16_t in_srr_iu;
|
||||
uint16_t in_srr_oxid;
|
||||
uint8_t in_reserved3[18];
|
||||
uint8_t in_reserved4;
|
||||
uint8_t in_vpindex;
|
||||
uint32_t in_reserved5;
|
||||
uint16_t in_portid_lo;
|
||||
uint8_t in_portid_hi;
|
||||
uint8_t in_reserved6;
|
||||
uint16_t in_reserved7;
|
||||
uint16_t in_oxid;
|
||||
} in_fcentry_24xx_t;
|
||||
|
||||
#define IN24XX_FLAG_PUREX_IOCB 0x1
|
||||
#define IN24XX_FLAG_GLOBAL_LOGOUT 0x2
|
||||
|
||||
#define IN24XX_LIP_RESET 0x0E
|
||||
#define IN24XX_LINK_RESET 0x0F
|
||||
#define IN24XX_PORT_LOGOUT 0x29
|
||||
#define IN24XX_PORT_CHANGED 0x2A
|
||||
#define IN24XX_LINK_FAILED 0x2E
|
||||
#define IN24XX_SRR_RCVD 0x45
|
||||
#define IN24XX_ELS_RCVD 0x46 /*
|
||||
* login-affectin ELS received- check
|
||||
* subcode for specific opcode
|
||||
*/
|
||||
/*
|
||||
* Notify Acknowledge Entry structure
|
||||
*/
|
||||
#define NA_RSVDLEN 22
|
||||
typedef struct {
|
||||
isphdr_t na_header;
|
||||
uint32_t na_reserved;
|
||||
uint8_t na_lun; /* lun */
|
||||
uint8_t na_iid; /* initiator */
|
||||
uint8_t na_reserved2;
|
||||
uint8_t na_tgt; /* target */
|
||||
uint32_t na_flags;
|
||||
uint8_t na_status;
|
||||
uint8_t na_event;
|
||||
uint16_t na_seqid; /* sequence id */
|
||||
uint16_t na_reserved3[NA_RSVDLEN];
|
||||
} na_entry_t;
|
||||
|
||||
/*
|
||||
* Value for the na_event field
|
||||
*/
|
||||
#define NA_RST_CLRD 0x80 /* Clear an async event notification */
|
||||
#define NA_OK 0x01 /* Notify Acknowledge Succeeded */
|
||||
#define NA_INVALID 0x06 /* Invalid Notify Acknowledge */
|
||||
|
||||
#define NA2_RSVDLEN 21
|
||||
typedef struct {
|
||||
isphdr_t na_header;
|
||||
uint32_t na_reserved;
|
||||
uint8_t na_reserved1;
|
||||
uint8_t na_iid; /* initiator loop id */
|
||||
uint16_t na_response;
|
||||
uint16_t na_flags;
|
||||
uint16_t na_reserved2;
|
||||
uint16_t na_status;
|
||||
uint16_t na_task_flags;
|
||||
uint16_t na_seqid; /* sequence id */
|
||||
uint16_t na_reserved3[NA2_RSVDLEN];
|
||||
} na_fcentry_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t na_header;
|
||||
uint32_t na_reserved;
|
||||
uint16_t na_iid; /* initiator loop id */
|
||||
uint16_t na_response; /* response code */
|
||||
uint16_t na_flags;
|
||||
uint16_t na_reserved2;
|
||||
uint16_t na_status;
|
||||
uint16_t na_task_flags;
|
||||
uint16_t na_seqid; /* sequence id */
|
||||
uint16_t na_reserved3[NA2_RSVDLEN];
|
||||
} na_fcentry_e_t;
|
||||
|
||||
#define NAFC_RCOUNT 0x80 /* increment resource count */
|
||||
#define NAFC_RST_CLRD 0x20 /* Clear LIP Reset */
|
||||
#define NAFC_TVALID 0x10 /* task mangement response code is valid */
|
||||
|
||||
/*
|
||||
* ISP24XX Notify Acknowledge
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
isphdr_t na_header;
|
||||
uint32_t na_handle;
|
||||
uint16_t na_nphdl;
|
||||
uint16_t na_reserved1;
|
||||
uint16_t na_flags;
|
||||
uint16_t na_srr_rxid;
|
||||
uint16_t na_status;
|
||||
uint8_t na_status_subcode;
|
||||
uint8_t na_reserved2;
|
||||
uint32_t na_rxid;
|
||||
uint16_t na_srr_reloff_lo;
|
||||
uint16_t na_srr_reloff_hi;
|
||||
uint16_t na_srr_iu;
|
||||
uint16_t na_srr_flags;
|
||||
uint8_t na_reserved3[18];
|
||||
uint8_t na_reserved4;
|
||||
uint8_t na_vpindex;
|
||||
uint8_t na_srr_reject_vunique;
|
||||
uint8_t na_srr_reject_explanation;
|
||||
uint8_t na_srr_reject_code;
|
||||
uint8_t na_reserved5;
|
||||
uint8_t na_reserved6[6];
|
||||
uint16_t na_oxid;
|
||||
} na_fcentry_24xx_t;
|
||||
|
||||
/*
|
||||
* Accept Target I/O Entry structure
|
||||
*/
|
||||
#define ATIO_CDBLEN 26
|
||||
|
||||
typedef struct {
|
||||
isphdr_t at_header;
|
||||
uint16_t at_reserved;
|
||||
uint16_t at_handle;
|
||||
uint8_t at_lun; /* lun */
|
||||
uint8_t at_iid; /* initiator */
|
||||
uint8_t at_cdblen; /* cdb length */
|
||||
uint8_t at_tgt; /* target */
|
||||
uint32_t at_flags;
|
||||
uint8_t at_status; /* firmware status */
|
||||
uint8_t at_scsi_status; /* scsi status */
|
||||
uint8_t at_tag_val; /* tag value */
|
||||
uint8_t at_tag_type; /* tag type */
|
||||
uint8_t at_cdb[ATIO_CDBLEN]; /* received CDB */
|
||||
uint8_t at_sense[QLTM_SENSELEN];/* suggested sense data */
|
||||
} at_entry_t;
|
||||
|
||||
/*
|
||||
* at_flags values
|
||||
*/
|
||||
#define AT_NODISC 0x00008000 /* disconnect disabled */
|
||||
#define AT_TQAE 0x00000002 /* Tagged Queue Action enabled */
|
||||
|
||||
/*
|
||||
* at_status values
|
||||
*/
|
||||
#define AT_PATH_INVALID 0x07 /* ATIO sent to firmware for disabled lun */
|
||||
#define AT_RESET 0x0E /* SCSI Bus Reset Occurred */
|
||||
#define AT_PHASE_ERROR 0x14 /* Bus phase sequence error */
|
||||
#define AT_NOCAP 0x16 /* Requested capability not available */
|
||||
#define AT_BDR_MSG 0x17 /* Bus Device Reset msg received */
|
||||
#define AT_CDB 0x3D /* CDB received */
|
||||
/*
|
||||
* Macros to create and fetch and test concatenated handle and tag value macros
|
||||
*/
|
||||
|
||||
#define AT_MAKE_TAGID(tid, bus, inst, aep) \
|
||||
tid = aep->at_handle; \
|
||||
if (aep->at_flags & AT_TQAE) { \
|
||||
tid |= (aep->at_tag_val << 16); \
|
||||
tid |= (1 << 24); \
|
||||
} \
|
||||
tid |= (bus << 25); \
|
||||
tid |= (inst << 26)
|
||||
|
||||
#define CT_MAKE_TAGID(tid, bus, inst, ct) \
|
||||
tid = ct->ct_fwhandle; \
|
||||
if (ct->ct_flags & CT_TQAE) { \
|
||||
tid |= (ct->ct_tag_val << 16); \
|
||||
tid |= (1 << 24); \
|
||||
} \
|
||||
tid |= ((bus & 0x1) << 25); \
|
||||
tid |= (inst << 26)
|
||||
|
||||
#define AT_HAS_TAG(val) ((val) & (1 << 24))
|
||||
#define AT_GET_TAG(val) (((val) >> 16) & 0xff)
|
||||
#define AT_GET_INST(val) (((val) >> 26) & 0x3f)
|
||||
#define AT_GET_BUS(val) (((val) >> 25) & 0x1)
|
||||
#define AT_GET_HANDLE(val) ((val) & 0xffff)
|
||||
|
||||
#define IN_MAKE_TAGID(tid, bus, inst, inp) \
|
||||
tid = inp->in_seqid; \
|
||||
tid |= (inp->in_tag_val << 16); \
|
||||
tid |= (1 << 24); \
|
||||
tid |= (bus << 25); \
|
||||
tid |= (inst << 26)
|
||||
|
||||
#define TAG_INSERT_INST(tid, inst) \
|
||||
tid &= ~(0x3ffffff); \
|
||||
tid |= (inst << 26)
|
||||
|
||||
#define TAG_INSERT_BUS(tid, bus) \
|
||||
tid &= ~(1 << 25); \
|
||||
tid |= (bus << 25)
|
||||
|
||||
/*
|
||||
* Accept Target I/O Entry structure, Type 2
|
||||
*/
|
||||
#define ATIO2_CDBLEN 16
|
||||
|
||||
typedef struct {
|
||||
isphdr_t at_header;
|
||||
uint32_t at_reserved;
|
||||
uint8_t at_lun; /* lun or reserved */
|
||||
uint8_t at_iid; /* initiator */
|
||||
uint16_t at_rxid; /* response ID */
|
||||
uint16_t at_flags;
|
||||
uint16_t at_status; /* firmware status */
|
||||
uint8_t at_crn; /* command reference number */
|
||||
uint8_t at_taskcodes;
|
||||
uint8_t at_taskflags;
|
||||
uint8_t at_execodes;
|
||||
uint8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */
|
||||
uint32_t at_datalen; /* allocated data len */
|
||||
uint16_t at_scclun; /* SCC Lun or reserved */
|
||||
uint16_t at_wwpn[4]; /* WWPN of initiator */
|
||||
uint16_t at_reserved2[6];
|
||||
uint16_t at_oxid;
|
||||
} at2_entry_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t at_header;
|
||||
uint32_t at_reserved;
|
||||
uint16_t at_iid; /* initiator */
|
||||
uint16_t at_rxid; /* response ID */
|
||||
uint16_t at_flags;
|
||||
uint16_t at_status; /* firmware status */
|
||||
uint8_t at_crn; /* command reference number */
|
||||
uint8_t at_taskcodes;
|
||||
uint8_t at_taskflags;
|
||||
uint8_t at_execodes;
|
||||
uint8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */
|
||||
uint32_t at_datalen; /* allocated data len */
|
||||
uint16_t at_scclun; /* SCC Lun or reserved */
|
||||
uint16_t at_wwpn[4]; /* WWPN of initiator */
|
||||
uint16_t at_reserved2[6];
|
||||
uint16_t at_oxid;
|
||||
} at2e_entry_t;
|
||||
|
||||
#define ATIO2_WWPN_OFFSET 0x2A
|
||||
#define ATIO2_OXID_OFFSET 0x3E
|
||||
|
||||
#define ATIO2_TC_ATTR_MASK 0x7
|
||||
#define ATIO2_TC_ATTR_SIMPLEQ 0
|
||||
#define ATIO2_TC_ATTR_HEADOFQ 1
|
||||
#define ATIO2_TC_ATTR_ORDERED 2
|
||||
#define ATIO2_TC_ATTR_ACAQ 4
|
||||
#define ATIO2_TC_ATTR_UNTAGGED 5
|
||||
|
||||
#define ATIO2_EX_WRITE 0x1
|
||||
#define ATIO2_EX_READ 0x2
|
||||
/*
|
||||
* Macros to create and fetch and test concatenated handle and tag value macros
|
||||
*/
|
||||
#define AT2_MAKE_TAGID(tid, bus, inst, aep) \
|
||||
tid = aep->at_rxid; \
|
||||
tid |= (((uint64_t)inst) << 32); \
|
||||
tid |= (((uint64_t)bus) << 48)
|
||||
|
||||
#define CT2_MAKE_TAGID(tid, bus, inst, ct) \
|
||||
tid = ct->ct_rxid; \
|
||||
tid |= (((uint64_t)inst) << 32); \
|
||||
tid |= (((uint64_t)(bus & 0xff)) << 48)
|
||||
|
||||
#define AT2_HAS_TAG(val) 1
|
||||
#define AT2_GET_TAG(val) ((val) & 0xffffffff)
|
||||
#define AT2_GET_INST(val) ((val) >> 32)
|
||||
#define AT2_GET_HANDLE AT2_GET_TAG
|
||||
#define AT2_GET_BUS(val) (((val) >> 48) & 0xff)
|
||||
|
||||
#define FC_HAS_TAG AT2_HAS_TAG
|
||||
#define FC_GET_TAG AT2_GET_TAG
|
||||
#define FC_GET_INST AT2_GET_INST
|
||||
#define FC_GET_HANDLE AT2_GET_HANDLE
|
||||
|
||||
#define IN_FC_MAKE_TAGID(tid, bus, inst, seqid) \
|
||||
tid = seqid; \
|
||||
tid |= (((uint64_t)inst) << 32); \
|
||||
tid |= (((uint64_t)(bus & 0xff)) << 48)
|
||||
|
||||
#define FC_TAG_INSERT_INST(tid, inst) \
|
||||
tid &= ~0xffff00000000ull; \
|
||||
tid |= (((uint64_t)inst) << 32)
|
||||
|
||||
/*
|
||||
* 24XX ATIO Definition
|
||||
*
|
||||
* This is *quite* different from other entry types.
|
||||
* First of all, it has its own queue it comes in on.
|
||||
*
|
||||
* Secondly, it doesn't have a normal header.
|
||||
*
|
||||
* Thirdly, it's just a passthru of the FCP CMND IU
|
||||
* which is recorded in big endian mode.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t at_type;
|
||||
uint8_t at_count;
|
||||
/*
|
||||
* Task attribute in high four bits,
|
||||
* the rest is the FCP CMND IU Length.
|
||||
* NB: the command can extend past the
|
||||
* length for a single queue entry.
|
||||
*/
|
||||
uint16_t at_ta_len;
|
||||
uint32_t at_rxid;
|
||||
fc_hdr_t at_hdr;
|
||||
fcp_cmnd_iu_t at_cmnd;
|
||||
} at7_entry_t;
|
||||
|
||||
|
||||
/*
|
||||
* Continue Target I/O Entry structure
|
||||
* Request from driver. The response from the
|
||||
* ISP firmware is the same except that the last 18
|
||||
* bytes are overwritten by suggested sense data if
|
||||
* the 'autosense valid' bit is set in the status byte.
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint16_t ct_syshandle;
|
||||
uint16_t ct_fwhandle; /* required by f/w */
|
||||
uint8_t ct_lun; /* lun */
|
||||
uint8_t ct_iid; /* initiator id */
|
||||
uint8_t ct_reserved2;
|
||||
uint8_t ct_tgt; /* our target id */
|
||||
uint32_t ct_flags;
|
||||
uint8_t ct_status; /* isp status */
|
||||
uint8_t ct_scsi_status; /* scsi status */
|
||||
uint8_t ct_tag_val; /* tag value */
|
||||
uint8_t ct_tag_type; /* tag type */
|
||||
uint32_t ct_xfrlen; /* transfer length */
|
||||
uint32_t ct_resid; /* residual length */
|
||||
uint16_t ct_timeout;
|
||||
uint16_t ct_seg_count;
|
||||
ispds_t ct_dataseg[ISP_RQDSEG];
|
||||
} ct_entry_t;
|
||||
|
||||
/*
|
||||
* For some of the dual port SCSI adapters, port (bus #) is reported
|
||||
* in the MSbit of ct_iid. Bit fields are a bit too awkward here.
|
||||
*
|
||||
* Note that this does not apply to FC adapters at all which can and
|
||||
* do report IIDs between 0x81 && 0xfe (or 0x7ff) which represent devices
|
||||
* that have logged in across a SCSI fabric.
|
||||
*/
|
||||
#define GET_IID_VAL(x) (x & 0x3f)
|
||||
#define GET_BUS_VAL(x) ((x >> 7) & 0x1)
|
||||
#define SET_IID_VAL(y, x) y = ((y & ~0x3f) | (x & 0x3f))
|
||||
#define SET_BUS_VAL(y, x) y = ((y & 0x3f) | ((x & 0x1) << 7))
|
||||
|
||||
/*
|
||||
* ct_flags values
|
||||
*/
|
||||
#define CT_TQAE 0x00000002 /* bit 1, Tagged Queue Action enable */
|
||||
#define CT_DATA_IN 0x00000040 /* bits 6&7, Data direction */
|
||||
#define CT_DATA_OUT 0x00000080 /* bits 6&7, Data direction */
|
||||
#define CT_NO_DATA 0x000000C0 /* bits 6&7, Data direction */
|
||||
#define CT_CCINCR 0x00000100 /* bit 8, autoincrement atio count */
|
||||
#define CT_DATAMASK 0x000000C0 /* bits 6&7, Data direction */
|
||||
#define CT_INISYNCWIDE 0x00004000 /* bit 14, Do Sync/Wide Negotiation */
|
||||
#define CT_NODISC 0x00008000 /* bit 15, Disconnects disabled */
|
||||
#define CT_DSDP 0x01000000 /* bit 24, Disable Save Data Pointers */
|
||||
#define CT_SENDRDP 0x04000000 /* bit 26, Send Restore Pointers msg */
|
||||
#define CT_SENDSTATUS 0x80000000 /* bit 31, Send SCSI status byte */
|
||||
|
||||
/*
|
||||
* ct_status values
|
||||
* - set by the firmware when it returns the CTIO
|
||||
*/
|
||||
#define CT_OK 0x01 /* completed without error */
|
||||
#define CT_ABORTED 0x02 /* aborted by host */
|
||||
#define CT_ERR 0x04 /* see sense data for error */
|
||||
#define CT_INVAL 0x06 /* request for disabled lun */
|
||||
#define CT_NOPATH 0x07 /* invalid ITL nexus */
|
||||
#define CT_INVRXID 0x08 /* (FC only) Invalid RX_ID */
|
||||
#define CT_DATA_OVER 0x09 /* (FC only) Data Overrun */
|
||||
#define CT_RSELTMO 0x0A /* reselection timeout after 2 tries */
|
||||
#define CT_TIMEOUT 0x0B /* timed out */
|
||||
#define CT_RESET 0x0E /* SCSI Bus Reset occurred */
|
||||
#define CT_PARITY 0x0F /* Uncorrectable Parity Error */
|
||||
#define CT_BUS_ERROR 0x10 /* (FC Only) DMA PCI Error */
|
||||
#define CT_PANIC 0x13 /* Unrecoverable Error */
|
||||
#define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */
|
||||
#define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */
|
||||
#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
|
||||
#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */
|
||||
#define CT_PORTUNAVAIL 0x28 /* port not available */
|
||||
#define CT_LOGOUT 0x29 /* port logout */
|
||||
#define CT_PORTCHANGED 0x2A /* port changed */
|
||||
#define CT_IDE 0x33 /* Initiator Detected Error */
|
||||
#define CT_NOACK 0x35 /* Outstanding Immed. Notify. entry */
|
||||
#define CT_SRR 0x45 /* SRR Received */
|
||||
#define CT_LUN_RESET 0x48 /* Lun Reset Received */
|
||||
|
||||
/*
|
||||
* When the firmware returns a CTIO entry, it may overwrite the last
|
||||
* part of the structure with sense data. This starts at offset 0x2E
|
||||
* into the entry, which is in the middle of ct_dataseg[1]. Rather
|
||||
* than define a new struct for this, I'm just using the sense data
|
||||
* offset.
|
||||
*/
|
||||
#define CTIO_SENSE_OFFSET 0x2E
|
||||
|
||||
/*
|
||||
* Entry length in u_longs. All entries are the same size so
|
||||
* any one will do as the numerator.
|
||||
*/
|
||||
#define UINT32_ENTRY_SIZE (sizeof(at_entry_t)/sizeof(uint32_t))
|
||||
|
||||
/*
|
||||
* QLA2100 CTIO (type 2) entry
|
||||
*/
|
||||
#define MAXRESPLEN 26
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint32_t ct_syshandle;
|
||||
uint8_t ct_lun; /* lun */
|
||||
uint8_t ct_iid; /* initiator id */
|
||||
uint16_t ct_rxid; /* response ID */
|
||||
uint16_t ct_flags;
|
||||
uint16_t ct_status; /* isp status */
|
||||
uint16_t ct_timeout;
|
||||
uint16_t ct_seg_count;
|
||||
uint32_t ct_reloff; /* relative offset */
|
||||
int32_t ct_resid; /* residual length */
|
||||
union {
|
||||
/*
|
||||
* The three different modes that the target driver
|
||||
* can set the CTIO{2,3,4} up as.
|
||||
*
|
||||
* The first is for sending FCP_DATA_IUs as well as
|
||||
* (optionally) sending a terminal SCSI status FCP_RSP_IU.
|
||||
*
|
||||
* The second is for sending SCSI sense data in an FCP_RSP_IU.
|
||||
* Note that no FCP_DATA_IUs will be sent.
|
||||
*
|
||||
* The third is for sending FCP_RSP_IUs as built specifically
|
||||
* in system memory as located by the isp_dataseg.
|
||||
*/
|
||||
struct {
|
||||
uint32_t _reserved;
|
||||
uint16_t _reserved2;
|
||||
uint16_t ct_scsi_status;
|
||||
uint32_t ct_xfrlen;
|
||||
union {
|
||||
ispds_t ct_dataseg[ISP_RQDSEG_T2];
|
||||
ispds64_t ct_dataseg64[ISP_RQDSEG_T3];
|
||||
ispdslist_t ct_dslist;
|
||||
} u;
|
||||
} m0;
|
||||
struct {
|
||||
uint16_t _reserved;
|
||||
uint16_t _reserved2;
|
||||
uint16_t ct_senselen;
|
||||
uint16_t ct_scsi_status;
|
||||
uint16_t ct_resplen;
|
||||
uint8_t ct_resp[MAXRESPLEN];
|
||||
} m1;
|
||||
struct {
|
||||
uint32_t _reserved;
|
||||
uint16_t _reserved2;
|
||||
uint16_t _reserved3;
|
||||
uint32_t ct_datalen;
|
||||
ispds_t ct_fcp_rsp_iudata;
|
||||
} m2;
|
||||
} rsp;
|
||||
} ct2_entry_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint32_t ct_syshandle;
|
||||
uint16_t ct_iid; /* initiator id */
|
||||
uint16_t ct_rxid; /* response ID */
|
||||
uint16_t ct_flags;
|
||||
uint16_t ct_status; /* isp status */
|
||||
uint16_t ct_timeout;
|
||||
uint16_t ct_seg_count;
|
||||
uint32_t ct_reloff; /* relative offset */
|
||||
int32_t ct_resid; /* residual length */
|
||||
union {
|
||||
struct {
|
||||
uint32_t _reserved;
|
||||
uint16_t _reserved2;
|
||||
uint16_t ct_scsi_status;
|
||||
uint32_t ct_xfrlen;
|
||||
union {
|
||||
ispds_t ct_dataseg[ISP_RQDSEG_T2];
|
||||
ispds64_t ct_dataseg64[ISP_RQDSEG_T3];
|
||||
ispdslist_t ct_dslist;
|
||||
} u;
|
||||
} m0;
|
||||
struct {
|
||||
uint16_t _reserved;
|
||||
uint16_t _reserved2;
|
||||
uint16_t ct_senselen;
|
||||
uint16_t ct_scsi_status;
|
||||
uint16_t ct_resplen;
|
||||
uint8_t ct_resp[MAXRESPLEN];
|
||||
} m1;
|
||||
struct {
|
||||
uint32_t _reserved;
|
||||
uint16_t _reserved2;
|
||||
uint16_t _reserved3;
|
||||
uint32_t ct_datalen;
|
||||
ispds_t ct_fcp_rsp_iudata;
|
||||
} m2;
|
||||
} rsp;
|
||||
} ct2e_entry_t;
|
||||
|
||||
/*
|
||||
* ct_flags values for CTIO2
|
||||
*/
|
||||
#define CT2_FLAG_MODE0 0x0000
|
||||
#define CT2_FLAG_MODE1 0x0001
|
||||
#define CT2_FLAG_MODE2 0x0002
|
||||
#define CT2_FLAG_MMASK 0x0003
|
||||
#define CT2_DATA_IN 0x0040
|
||||
#define CT2_DATA_OUT 0x0080
|
||||
#define CT2_NO_DATA 0x00C0
|
||||
#define CT2_DATAMASK 0x00C0
|
||||
#define CT2_CCINCR 0x0100
|
||||
#define CT2_FASTPOST 0x0200
|
||||
#define CT2_CONFIRM 0x2000
|
||||
#define CT2_TERMINATE 0x4000
|
||||
#define CT2_SENDSTATUS 0x8000
|
||||
|
||||
/*
|
||||
* ct_status values are (mostly) the same as that for ct_entry.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ct_scsi_status values- the low 8 bits are the normal SCSI status
|
||||
* we know and love. The upper 8 bits are validity markers for FCP_RSP_IU
|
||||
* fields.
|
||||
*/
|
||||
#define CT2_RSPLEN_VALID 0x0100
|
||||
#define CT2_SNSLEN_VALID 0x0200
|
||||
#define CT2_DATA_OVER 0x0400
|
||||
#define CT2_DATA_UNDER 0x0800
|
||||
|
||||
/*
|
||||
* ISP24XX CTIO
|
||||
*/
|
||||
#define MAXRESPLEN_24XX 24
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint32_t ct_syshandle;
|
||||
uint16_t ct_nphdl; /* status on returned CTIOs */
|
||||
uint16_t ct_timeout;
|
||||
uint16_t ct_seg_count;
|
||||
uint8_t ct_vpindex;
|
||||
uint8_t ct_xflags;
|
||||
uint16_t ct_iid_lo; /* low 16 bits of portid */
|
||||
uint8_t ct_iid_hi; /* hi 8 bits of portid */
|
||||
uint8_t ct_reserved;
|
||||
uint32_t ct_rxid;
|
||||
uint16_t ct_senselen; /* mode 0 only */
|
||||
uint16_t ct_flags;
|
||||
int32_t ct_resid; /* residual length */
|
||||
uint16_t ct_oxid;
|
||||
uint16_t ct_scsi_status; /* modes 0 && 1 only */
|
||||
union {
|
||||
struct {
|
||||
uint32_t reloff;
|
||||
uint32_t reserved0;
|
||||
uint32_t ct_xfrlen;
|
||||
uint32_t reserved1;
|
||||
ispds64_t ds;
|
||||
} m0;
|
||||
struct {
|
||||
uint16_t ct_resplen;
|
||||
uint16_t reserved;
|
||||
uint8_t ct_resp[MAXRESPLEN_24XX];
|
||||
} m1;
|
||||
struct {
|
||||
uint32_t reserved0;
|
||||
uint32_t ct_datalen;
|
||||
uint32_t reserved1;
|
||||
ispds64_t ct_fcp_rsp_iudata;
|
||||
} m2;
|
||||
} rsp;
|
||||
} ct7_entry_t;
|
||||
|
||||
/*
|
||||
* ct_flags values for CTIO7
|
||||
*/
|
||||
#define CT7_DATA_IN 0x0002
|
||||
#define CT7_DATA_OUT 0x0001
|
||||
#define CT7_NO_DATA 0x0000
|
||||
#define CT7_DATAMASK 0x003
|
||||
#define CT7_DSD_ENABLE 0x0004
|
||||
#define CT7_CONF_STSFD 0x0010
|
||||
#define CT7_EXPLCT_CONF 0x0020
|
||||
#define CT7_FLAG_MODE0 0x0000
|
||||
#define CT7_FLAG_MODE1 0x0040
|
||||
#define CT7_FLAG_MODE7 0x0080
|
||||
#define CT7_FLAG_MMASK 0x00C0
|
||||
#define CT7_FASTPOST 0x0100
|
||||
#define CT7_ATTR_MASK 0x1e00 /* task attributes from atio7 */
|
||||
#define CT7_CONFIRM 0x2000
|
||||
#define CT7_TERMINATE 0x4000
|
||||
#define CT7_SENDSTATUS 0x8000
|
||||
|
||||
/*
|
||||
* Type 7 CTIO status codes
|
||||
*/
|
||||
#define CT7_OK 0x01 /* completed without error */
|
||||
#define CT7_ABORTED 0x02 /* aborted by host */
|
||||
#define CT7_ERR 0x04 /* see sense data for error */
|
||||
#define CT7_INVAL 0x06 /* request for disabled lun */
|
||||
#define CT7_INVRXID 0x08 /* (FC only) Invalid RX_ID */
|
||||
#define CT7_DATA_OVER 0x09 /* (FC only) Data Overrun */
|
||||
#define CT7_TIMEOUT 0x0B /* timed out */
|
||||
#define CT7_RESET 0x0E /* LIP Rset Received */
|
||||
#define CT7_BUS_ERROR 0x10 /* DMA PCI Error */
|
||||
#define CT7_REASSY_ERR 0x11 /* DMA reassembly error */
|
||||
#define CT7_DATA_UNDER 0x15 /* (FC only) Data Underrun */
|
||||
#define CT7_PORTUNAVAIL 0x28 /* port not available */
|
||||
#define CT7_LOGOUT 0x29 /* port logout */
|
||||
#define CT7_PORTCHANGED 0x2A /* port changed */
|
||||
#define CT7_SRR 0x45 /* SRR Received */
|
||||
|
||||
/*
|
||||
* Other 24XX related target IOCBs
|
||||
*/
|
||||
|
||||
/*
|
||||
* ABTS Received
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t abts_header;
|
||||
uint8_t abts_reserved0[6];
|
||||
uint16_t abts_nphdl;
|
||||
uint16_t abts_reserved1;
|
||||
uint16_t abts_sof;
|
||||
uint32_t abts_rxid_abts;
|
||||
uint16_t abts_did_lo;
|
||||
uint8_t abts_did_hi;
|
||||
uint8_t abts_r_ctl;
|
||||
uint16_t abts_sid_lo;
|
||||
uint8_t abts_sid_hi;
|
||||
uint8_t abts_cs_ctl;
|
||||
uint16_t abts_fs_ctl;
|
||||
uint8_t abts_f_ctl;
|
||||
uint8_t abts_type;
|
||||
uint16_t abts_seq_cnt;
|
||||
uint8_t abts_df_ctl;
|
||||
uint8_t abts_seq_id;
|
||||
uint16_t abts_rx_id;
|
||||
uint16_t abts_ox_id;
|
||||
uint32_t abts_param;
|
||||
uint8_t abts_reserved2[16];
|
||||
uint32_t abts_rxid_task;
|
||||
} abts_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t abts_rsp_header;
|
||||
uint32_t abts_rsp_handle;
|
||||
uint16_t abts_rsp_status;
|
||||
uint16_t abts_rsp_nphdl;
|
||||
uint16_t abts_rsp_ctl_flags;
|
||||
uint16_t abts_rsp_sof;
|
||||
uint32_t abts_rsp_rxid_abts;
|
||||
uint16_t abts_rsp_did_lo;
|
||||
uint8_t abts_rsp_did_hi;
|
||||
uint8_t abts_rsp_r_ctl;
|
||||
uint16_t abts_rsp_sid_lo;
|
||||
uint8_t abts_rsp_sid_hi;
|
||||
uint8_t abts_rsp_cs_ctl;
|
||||
uint16_t abts_rsp_f_ctl_lo;
|
||||
uint8_t abts_rsp_f_ctl_hi;
|
||||
uint8_t abts_rsp_type;
|
||||
uint16_t abts_rsp_seq_cnt;
|
||||
uint8_t abts_rsp_df_ctl;
|
||||
uint8_t abts_rsp_seq_id;
|
||||
uint16_t abts_rsp_rx_id;
|
||||
uint16_t abts_rsp_ox_id;
|
||||
uint32_t abts_rsp_param;
|
||||
union {
|
||||
struct {
|
||||
uint16_t reserved;
|
||||
uint8_t last_seq_id;
|
||||
uint8_t seq_id_valid;
|
||||
uint16_t aborted_rx_id;
|
||||
uint16_t aborted_ox_id;
|
||||
uint16_t high_seq_cnt;
|
||||
uint16_t low_seq_cnt;
|
||||
uint8_t reserved2[4];
|
||||
} ba_acc;
|
||||
struct {
|
||||
uint8_t vendor_unique;
|
||||
uint8_t explanation;
|
||||
uint8_t reason;
|
||||
uint8_t reserved;
|
||||
uint8_t reserved2[12];
|
||||
} ba_rjt;
|
||||
struct {
|
||||
uint8_t reserved[8];
|
||||
uint32_t subcode1;
|
||||
uint32_t subcode2;
|
||||
} rsp;
|
||||
uint8_t reserved[16];
|
||||
} abts_rsp_payload;
|
||||
uint32_t abts_rsp_rxid_task;
|
||||
} abts_rsp_t;
|
||||
|
||||
/* terminate this ABTS exchange */
|
||||
#define ISP24XX_ABTS_RSP_TERMINATE 0x01
|
||||
|
||||
#define ISP24XX_ABTS_RSP_COMPLETE 0x00
|
||||
#define ISP24XX_ABTS_RSP_RESET 0x04
|
||||
#define ISP24XX_ABTS_RSP_ABORTED 0x05
|
||||
#define ISP24XX_ABTS_RSP_TIMEOUT 0x06
|
||||
#define ISP24XX_ABTS_RSP_INVXID 0x08
|
||||
#define ISP24XX_ABTS_RSP_LOGOUT 0x29
|
||||
#define ISP24XX_ABTS_RSP_SUBCODE 0x31
|
||||
|
||||
/*
|
||||
* Debug macros
|
||||
*/
|
||||
|
||||
#define ISP_TDQE(isp, msg, idx, arg) \
|
||||
if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
|
||||
|
||||
#ifndef ISP_TOOLS
|
||||
/*
|
||||
* The functions below are for the publicly available
|
||||
* target mode functions that are internal to the Qlogic driver.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function handles new response queue entry appropriate for target mode.
|
||||
*/
|
||||
int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
|
||||
|
||||
/*
|
||||
* This function externalizes the ability to acknowledge an Immediate Notify
|
||||
* request.
|
||||
*/
|
||||
void isp_notify_ack(ispsoftc_t *, void *);
|
||||
|
||||
/*
|
||||
* Enable/Disable/Modify a logical unit.
|
||||
* (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt)
|
||||
*/
|
||||
#define DFLT_CMND_CNT 0xfe /* unmonitored */
|
||||
#define DFLT_INOT_CNT 0xfe /* unmonitored */
|
||||
int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int, int);
|
||||
|
||||
/*
|
||||
* General request queue 'put' routine for target mode entries.
|
||||
*/
|
||||
int isp_target_put_entry(ispsoftc_t *isp, void *);
|
||||
|
||||
/*
|
||||
* General routine to put back an ATIO entry-
|
||||
* used for replenishing f/w resource counts.
|
||||
* The argument is a pointer to a source ATIO
|
||||
* or ATIO2.
|
||||
*/
|
||||
int isp_target_put_atio(ispsoftc_t *, void *);
|
||||
|
||||
/*
|
||||
* General routine to send a final CTIO for a command- used mostly for
|
||||
* local responses.
|
||||
*/
|
||||
int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint32_t);
|
||||
#define ECMD_SVALID 0x100
|
||||
|
||||
/*
|
||||
* Handle an asynchronous event
|
||||
*
|
||||
* Return nonzero if the interrupt that generated this event has been dismissed.
|
||||
*/
|
||||
int isp_target_async(ispsoftc_t *, int, int);
|
||||
#endif
|
||||
#endif /* _ISP_TARGET_H */
|
||||
@@ -0,0 +1,456 @@
|
||||
/* $Id: isp_tpublic.h,v 1.31 2007/04/30 18:47:23 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Host Adapter Public Target Interface Structures && Routines
|
||||
*/
|
||||
|
||||
#ifndef _ISP_TPUBLIC_H
|
||||
#define _ISP_TPUBLIC_H 1
|
||||
|
||||
/*
|
||||
* Action codes set by the MD target driver for
|
||||
* the external layer to figure out what to do with.
|
||||
*/
|
||||
typedef enum {
|
||||
QOUT_HBA_REG=0, /* the argument is a pointer to a hba_register_t */
|
||||
QOUT_ENABLE, /* the argument is a pointer to a enadis_t */
|
||||
QOUT_DISABLE, /* the argument is a pointer to a enadis_t */
|
||||
QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
|
||||
QOUT_TMD_DONE, /* the argument is a pointer to a tmd_cmd_t */
|
||||
QOUT_NOTIFY, /* the argument is a pointer to a tmd_notify_t */
|
||||
QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */
|
||||
} tact_e;
|
||||
|
||||
/*
|
||||
* Action codes set by the external layer for the
|
||||
* MD driver to figure out what to do with.
|
||||
*/
|
||||
typedef enum {
|
||||
QIN_HBA_REG=99, /* the argument is a pointer to a hba_register_t */
|
||||
QIN_GETINFO, /* the argument is a pointer to a info_t */
|
||||
QIN_SETINFO, /* the argument is a pointer to a info_t */
|
||||
QIN_GETDLIST, /* the argument is a pointer to a fc_dlist_t */
|
||||
QIN_ENABLE, /* the argument is a pointer to a enadis_t */
|
||||
QIN_DISABLE, /* the argument is a pointer to a enadis_t */
|
||||
QIN_TMD_CONT, /* the argument is a pointer to a tmd_cmd_t */
|
||||
QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */
|
||||
QIN_NOTIFY_ACK, /* the argument is a pointer to a tmd_notify_t */
|
||||
QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */
|
||||
} qact_e;
|
||||
|
||||
/*
|
||||
* This structure is used to register to other software modules the
|
||||
* binding of an HBA identifier, driver name and instance and the
|
||||
* lun width capapbilities of this target driver. It's up to each
|
||||
* platform to figure out how it wants to do this, but a typical
|
||||
* sequence would be for the MD layer to find some external module's
|
||||
* entry point and start by sending a QOUT_HBA_REG with info filled
|
||||
* in, and the external module to call back with a QIN_HBA_REG that
|
||||
* passes back the corresponding information.
|
||||
*/
|
||||
#define QR_VERSION 16
|
||||
typedef struct {
|
||||
/* NB: tags from here to r_version must never change */
|
||||
void * r_identity;
|
||||
void (*r_action)(qact_e, void *);
|
||||
char r_name[8];
|
||||
int r_inst;
|
||||
int r_version;
|
||||
uint32_t r_locator;
|
||||
uint32_t r_nchannels;
|
||||
enum { R_FC, R_SPI } r_type;
|
||||
void * r_private;
|
||||
} hba_register_t;
|
||||
|
||||
/*
|
||||
* An information structure that is used to get or set per-channel transport layer parameters.
|
||||
*/
|
||||
typedef struct {
|
||||
void * i_identity;
|
||||
enum { I_FC, I_SPI } i_type;
|
||||
int i_channel;
|
||||
int i_error;
|
||||
union {
|
||||
struct {
|
||||
uint64_t wwnn_nvram;
|
||||
uint64_t wwpn_nvram;
|
||||
uint64_t wwnn;
|
||||
uint64_t wwpn;
|
||||
} fc;
|
||||
struct {
|
||||
int iid;
|
||||
} spi;
|
||||
} i_id;
|
||||
} info_t;
|
||||
|
||||
/*
|
||||
* An information structure to return a list of logged in WWPNs. FC specific.
|
||||
*/
|
||||
typedef struct {
|
||||
void * d_identity;
|
||||
int d_channel;
|
||||
int d_error;
|
||||
int d_count;
|
||||
uint64_t * d_wwpns;
|
||||
} fc_dlist_t;
|
||||
/*
|
||||
* Notify structure
|
||||
*/
|
||||
typedef enum {
|
||||
NT_ABORT_TASK=0x1000,
|
||||
NT_ABORT_TASK_SET,
|
||||
NT_CLEAR_ACA,
|
||||
NT_CLEAR_TASK_SET,
|
||||
NT_LUN_RESET,
|
||||
NT_TARGET_RESET,
|
||||
NT_BUS_RESET,
|
||||
NT_LIP_RESET,
|
||||
NT_LINK_UP,
|
||||
NT_LINK_DOWN,
|
||||
NT_LOGOUT,
|
||||
NT_HBA_RESET
|
||||
} tmd_ncode_t;
|
||||
|
||||
typedef struct tmd_notify {
|
||||
void * nt_hba; /* HBA tag */
|
||||
uint64_t nt_iid; /* inititator id */
|
||||
uint64_t nt_tgt; /* target id */
|
||||
uint16_t nt_lun; /* logical unit */
|
||||
uint16_t : 15,
|
||||
nt_need_ack : 1; /* this notify needs an ACK */
|
||||
uint64_t nt_tagval; /* tag value */
|
||||
uint32_t nt_channel; /* channel id */
|
||||
tmd_ncode_t nt_ncode; /* action */
|
||||
void * nt_lreserved;
|
||||
void * nt_hreserved;
|
||||
} tmd_notify_t;
|
||||
#define LUN_ANY 0xffff
|
||||
#define TGT_ANY ((uint64_t) -1)
|
||||
#define INI_ANY ((uint64_t) -1)
|
||||
#define TAG_ANY ((uint64_t) 0)
|
||||
#define MATCH_TMD(tmd, iid, lun, tag) \
|
||||
( \
|
||||
(tmd) && \
|
||||
(iid == INI_ANY || iid == tmd->cd_iid) && \
|
||||
(lun == LUN_ANY || lun == tmd->cd_lun) && \
|
||||
(tag == TAG_ANY || tag == tmd->cd_tagval) \
|
||||
)
|
||||
|
||||
/*
|
||||
* A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
|
||||
* with en_hba, en_iid, en_chan, en_tgt and en_lun filled out.
|
||||
*
|
||||
* If an error occurs in either enabling or disabling the described lun
|
||||
* cd_error is set with an appropriate non-zero value.
|
||||
*/
|
||||
typedef struct {
|
||||
void * en_private; /* for outer layer usage */
|
||||
void * en_hba; /* HBA tag */
|
||||
uint64_t en_iid; /* initiator ID */
|
||||
uint64_t en_tgt; /* target id */
|
||||
uint16_t en_lun; /* logical unit */
|
||||
uint16_t en_chan; /* channel on card */
|
||||
int en_error;
|
||||
} enadis_t;
|
||||
|
||||
/*
|
||||
* Suggested Software Target Mode Command Handling structure.
|
||||
*
|
||||
* A note about terminology:
|
||||
*
|
||||
* MD stands for "Machine Dependent".
|
||||
*
|
||||
* This driver is structured in three layers: Outer MD, core, and inner MD.
|
||||
* The latter also is bus dependent (i.e., is cognizant of PCI bus issues
|
||||
* as well as platform issues).
|
||||
*
|
||||
*
|
||||
* "Outer Layer" means "Other Module"
|
||||
*
|
||||
* Some additional module that actually implements SCSI target command
|
||||
* policy is the recipient of incoming commands and the source of the
|
||||
* disposition for them.
|
||||
*
|
||||
* The command structure below is one suggested possible MD command structure,
|
||||
* but since the handling of thbis is entirely in the MD layer, there is
|
||||
* no explicit or implicit requirement that it be used.
|
||||
*
|
||||
* The cd_private tag should be used by the MD layer to keep a free list
|
||||
* of these structures. Code outside of this driver can then use this
|
||||
* to identify it's own unit structures. That is, when not on the MD
|
||||
* layer's freelist, the MD layer should shove into it the identifier
|
||||
* that the outer layer has for it- passed in on an initial QIN_HBA_REG
|
||||
* call (see below).
|
||||
*
|
||||
* The cd_hba tag is a tag that uniquely identifies the HBA this target
|
||||
* mode command is coming from. The outer layer has to pass this back
|
||||
* unchanged to avoid chaos.
|
||||
*
|
||||
* The cd_iid, cd_tgt, cd_lun and cd_port tags are used to identify the
|
||||
* id of the initiator who sent us a command, the target claim to be, the
|
||||
* lun on the target we claim to be, and the port instance (for multiple
|
||||
* port host adapters) that this applies to (consider it an extra port
|
||||
* parameter). The iid, tgt and lun values are deliberately chosen to be
|
||||
* fat so that, for example, World Wide Names can be used instead of
|
||||
* the units that the firmware uses (in the case where the MD
|
||||
* layer maintains a port database, for example).
|
||||
*
|
||||
* The cd_tagtype field specifies what kind of command tag type, if
|
||||
* any, has been sent with the command. Note that the Outer Layer
|
||||
* still needs to pass the tag handle through unchanged even
|
||||
* if the tag type is CD_UNTAGGED.
|
||||
*
|
||||
* The cd_cdb contains storage for the passed in command descriptor block.
|
||||
* There is no need to define length as the callee should be able to
|
||||
* figure this out.
|
||||
*
|
||||
* The tag cd_lflags are the flags set by the MD driver when it gets
|
||||
* command incoming or when it needs to inform any outside entities
|
||||
* that the last requested action failed.
|
||||
*
|
||||
* The tag cd_hflags should be set by any outside software to indicate
|
||||
* the validity of sense and status fields (defined below) and to indicate
|
||||
* the direction data is expected to move. It is an error to have both
|
||||
* CDFH_DATA_IN and CDFH_DATA_OUT set.
|
||||
*
|
||||
* If the CDFH_STSVALID flag is set, the command should be completed (after
|
||||
* sending any data and/or status). If CDFH_SNSVALID is set and the MD layer
|
||||
* can also handle sending the associated sense data (either back with an
|
||||
* FCP RESPONSE IU for Fibre Channel or otherwise automatically handling a
|
||||
* REQUEST SENSE from the initator for this target/lun), the MD layer will
|
||||
* set the CDFL_SENTSENSE flag on successful transmission of the sense data.
|
||||
* It is an error for the CDFH_SNSVALID bit to be set and CDFH_STSVALID not
|
||||
* to be set. It is an error for the CDFH_SNSVALID be set and the associated
|
||||
* SCSI status (cd_scsi_status) not be set to CHECK CONDITON.
|
||||
*
|
||||
* The tag cd_data points to a data segment to either be filled or
|
||||
* read from depending on the direction of data movement. The tag
|
||||
* is undefined if no data direction is set. The MD layer and outer
|
||||
* layers must agree on the meaning of cd_data and it is specifically
|
||||
* not defined here.
|
||||
*
|
||||
* The tag cd_totlen is the total data amount expected to be moved
|
||||
* over the life of the command. It may be set by the MD layer, possibly
|
||||
* from the datalen field of an FCP CMND IU unit. If it shows up in the outer
|
||||
* layers set to zero and the CDB indicates data should be moved, the outer
|
||||
* layer should set it to the amount expected to be moved.
|
||||
*
|
||||
* The tag cd_resid should be the total residual of data not transferred.
|
||||
* The outer layers need to set this at the begining of command processing
|
||||
* to equal cd_totlen. As data is successfully moved, this value is decreased.
|
||||
* At the end of a command, any nonzero residual indicates the number of bytes
|
||||
* requested by the command but not moved.
|
||||
*
|
||||
* The tag cd_xfrlen is the length of the currently active data transfer.
|
||||
* This allows several interations between any outside software and the
|
||||
* MD layer to move data.
|
||||
*
|
||||
* The reason that total length and total residual have to be tracked
|
||||
* is to keep track of relative offset.
|
||||
*
|
||||
* The tags cd_sense and cd_scsi_status are pretty obvious.
|
||||
*
|
||||
* The tag cd_error is to communicate between the MD layer and outer software
|
||||
* the current error conditions.
|
||||
*
|
||||
* The tag cd_lreserved, cd_hreserved are scratch areas for use for the MD
|
||||
* and outer layers respectively.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TMD_CDBLEN
|
||||
#define TMD_CDBLEN 16
|
||||
#endif
|
||||
#ifndef TMD_SENSELEN
|
||||
#define TMD_SENSELEN 18
|
||||
#endif
|
||||
#ifndef QCDS
|
||||
#define QCDS (sizeof (void *))
|
||||
#endif
|
||||
|
||||
typedef struct tmd_cmd {
|
||||
void * cd_private; /* private data pointer */
|
||||
void * cd_hba; /* HBA tag */
|
||||
void * cd_data; /* 'pointer' to data */
|
||||
uint64_t cd_iid; /* initiator ID */
|
||||
uint64_t cd_tgt; /* target id */
|
||||
uint8_t cd_lun[8]; /* logical unit */
|
||||
uint64_t cd_tagval; /* tag value */
|
||||
uint32_t cd_channel; /* channel index */
|
||||
uint32_t cd_lflags; /* flags lower level sets */
|
||||
uint32_t cd_hflags; /* flags higher level sets */
|
||||
uint32_t cd_totlen; /* total data load */
|
||||
uint32_t cd_resid; /* total data residual */
|
||||
uint32_t cd_xfrlen; /* current data load */
|
||||
int32_t cd_error; /* current error */
|
||||
uint8_t cd_tagtype; /* tag type */
|
||||
uint8_t cd_scsi_status;
|
||||
uint8_t cd_sense[TMD_SENSELEN];
|
||||
uint8_t cd_cdb[TMD_CDBLEN];
|
||||
union {
|
||||
void * ptrs[QCDS / sizeof (void *)];
|
||||
uint64_t llongs[QCDS / sizeof (uint64_t)];
|
||||
uint32_t longs[QCDS / sizeof (uint32_t)];
|
||||
uint16_t shorts[QCDS / sizeof (uint16_t)];
|
||||
uint8_t bytes[QCDS];
|
||||
} cd_lreserved[4], cd_hreserved[4];
|
||||
} tmd_cmd_t;
|
||||
|
||||
/* defined tags */
|
||||
#define CD_UNTAGGED 0
|
||||
#define CD_SIMPLE_TAG 1
|
||||
#define CD_ORDERED_TAG 2
|
||||
#define CD_HEAD_TAG 3
|
||||
#define CD_ACA_TAG 4
|
||||
|
||||
#ifndef TMD_SIZE
|
||||
#define TMD_SIZE (sizeof (tmd_cmd_t))
|
||||
#endif
|
||||
|
||||
#define L0LUN_TO_FLATLUN(lptr) ((((lptr)[0] & 0x3f) << 8) | ((lptr)[1]))
|
||||
#define FLATLUN_TO_L0LUN(lptr, lun) \
|
||||
(lptr)[1] = lun & 0xff; \
|
||||
if (sizeof (lun) == 1) { \
|
||||
(lptr)[0] = 0; \
|
||||
} else { \
|
||||
uint16_t nl = lun; \
|
||||
if (nl == LUN_ANY) { \
|
||||
(lptr)[0] = (nl >> 8) & 0xff; \
|
||||
} else if (nl < 256) { \
|
||||
(lptr)[0] = 0; \
|
||||
} else { \
|
||||
(lptr)[0] = 0x40 | ((nl >> 8) & 0x3f); \
|
||||
} \
|
||||
} \
|
||||
memset(&(lptr)[2], 0, 6)
|
||||
|
||||
/*
|
||||
* Note that NODISC (obviously) doesn't apply to non-SPI transport.
|
||||
*
|
||||
* Note that knowing the data direction and lengh at the time of receipt of
|
||||
* a command from the initiator is a feature only of Fibre Channel.
|
||||
*
|
||||
* The CDFL_BIDIR is in anticipation of the adoption of some newer
|
||||
* features required by OSD.
|
||||
*
|
||||
* The principle selector for MD layer to know whether data is to
|
||||
* be transferred in any QOUT_TMD_CONT call is cd_xfrlen- the
|
||||
* flags CDFH_DATA_IN and CDFH_DATA_OUT define which direction.
|
||||
*/
|
||||
#define CDFL_SNSVALID 0x01 /* sense data (from f/w) good */
|
||||
#define CDFL_SENTSTATUS 0x02 /* last action sent status */
|
||||
#define CDFL_DATA_IN 0x04 /* target (us) -> initiator (them) */
|
||||
#define CDFL_DATA_OUT 0x08 /* initiator (them) -> target (us) */
|
||||
#define CDFL_BIDIR 0x0C /* bidirectional data */
|
||||
#define CDFL_ERROR 0x10 /* last action ended in error */
|
||||
#define CDFL_NODISC 0x20 /* disconnects disabled */
|
||||
#define CDFL_SENTSENSE 0x40 /* last action sent sense data */
|
||||
#define CDFL_BUSY 0x80 /* this command is not on a free list */
|
||||
#define CDFL_PRIVATE 0xFF000000 /* private layer flags */
|
||||
|
||||
#define CDFH_SNSVALID 0x01 /* sense data (from outer layer) good */
|
||||
#define CDFH_STSVALID 0x02 /* status valid */
|
||||
#define CDFH_DATA_IN 0x04 /* target (us) -> initiator (them) */
|
||||
#define CDFH_DATA_OUT 0x08 /* initiator (them) -> target (us) */
|
||||
#define CDFH_DATA_MASK 0x0C /* mask to cover data direction */
|
||||
#define CDFH_PRIVATE 0xFF000000 /* private layer flags */
|
||||
|
||||
|
||||
/*
|
||||
* A word about the START/CONT/DONE/FIN dance:
|
||||
*
|
||||
* When the HBA is enabled for receiving commands, one may show up
|
||||
* without notice. When that happens, the MD target mode driver
|
||||
* gets a tmd_cmd_t, fills it with the info that just arrived, and
|
||||
* calls the outer layer with a QOUT_TMD_START code and pointer to
|
||||
* the tmd_cmd_t.
|
||||
*
|
||||
* The outer layer decodes the command, fetches data, prepares stuff,
|
||||
* whatever, and starts by passing back the pointer with a QIN_TMD_CONT
|
||||
* code which causes the MD target mode driver to generate CTIOs to
|
||||
* satisfy whatever action needs to be taken. When those CTIOs complete,
|
||||
* the MD target driver sends the pointer to the cmd_tmd_t back with
|
||||
* a QOUT_TMD_DONE code. This repeats for as long as necessary. These
|
||||
* may not be done in parallel- they are sequential operations.
|
||||
*
|
||||
* The outer layer signals it wants to end the command by settings within
|
||||
* the tmd_cmd_t itself. When the final QIN_TMD_CONT is reported completed,
|
||||
* the outer layer frees the tmd_cmd_t by sending the pointer to it
|
||||
* back with a QIN_TMD_FIN code.
|
||||
*
|
||||
* The graph looks like:
|
||||
*
|
||||
* QOUT_TMD_START -> [ QIN_TMD_CONT -> QOUT_TMD_DONE ] * -> QIN_TMD_FIN.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Target handler functions.
|
||||
*
|
||||
* The MD target handler function (the outer layer calls this)
|
||||
* should be be prototyped like:
|
||||
*
|
||||
* void target_action(qact_e, void *arg)
|
||||
*
|
||||
* The outer layer target handler function (the MD layer calls this)
|
||||
* should be be prototyped like:
|
||||
*
|
||||
* void scsi_target_handler(tact_e, void *arg)
|
||||
*/
|
||||
#endif /* _ISP_TPUBLIC_H */
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,649 @@
|
||||
$Id: DriverManual.txt,v 1.6 2006/02/17 22:53:44 mjacob Exp $
|
||||
Copyright (c) 1997-2004 by Matthew Jacob
|
||||
All rights reserved.
|
||||
|
||||
Driver Theory of Operation Manual
|
||||
|
||||
1. Introduction
|
||||
|
||||
This is a short text document that will describe the background, goals
|
||||
for, and current theory of operation for the joint Fibre Channel/SCSI
|
||||
HBA driver for QLogic hardware.
|
||||
|
||||
Because this driver is an ongoing project, do not expect this manual
|
||||
to remain entirely up to date. Like a lot of software engineering, the
|
||||
ultimate documentation is the driver source. However, this manual should
|
||||
serve as a solid basis for attempting to understand where the driver
|
||||
started and what is trying to be accomplished with the current source.
|
||||
|
||||
The reader is expected to understand the basics of SCSI and Fibre Channel
|
||||
and to be familiar with the range of platforms that Solaris, Linux and
|
||||
the variant "BSD" Open Source systems are available on. A glossary and
|
||||
a few references will be placed at the end of the document.
|
||||
|
||||
There will be references to functions and structures within the body of
|
||||
this document. These can be easily found within the source using editor
|
||||
tags or grep. There will be few code examples here as the code already
|
||||
exists where the reader can easily find it.
|
||||
|
||||
2. A Brief History for this Driver
|
||||
|
||||
This driver originally started as part of work funded by NASA Ames
|
||||
Research Center's Numerical Aerodynamic Simulation center ("NAS" for
|
||||
short) for the QLogic PCI 1020 and 1040 SCSI Host Adapters as part of my
|
||||
work at porting the NetBSD Operating System to the Alpha architectures
|
||||
(specifically the AlphaServer 8200 and 8400 platforms). In short, it
|
||||
started just as simple single SCSI HBA driver for just the purpose of
|
||||
running off a SCSI disk. This work took place starting in January, 1997.
|
||||
|
||||
Because the first implementation was for NetBSD, which runs on a very
|
||||
large number of platforms, and because NetBSD supported both systems with
|
||||
SBus cards (e.g., Sun SPARC systems) as well as systems with PCI cards,
|
||||
and because the QLogic SCSI cards came in both SBus and PCI versions, the
|
||||
initial implementation followed the very thoughtful NetBSD design tenet
|
||||
of splitting drivers into what are called MI (for Machine Independent)
|
||||
and MD (Machine Dependent) portions. The original design therefore was
|
||||
from the premise that the driver would drive both SBus and PCI card
|
||||
variants. These busses are similar but have quite different constraints,
|
||||
and while the QLogic SBus and PCI cards are very similar, there are some
|
||||
significant differences.
|
||||
|
||||
After this initial goal had been met, there began to be some talk about
|
||||
looking into implementing Fibre Channel mass storage at NAS. At this time
|
||||
the QLogic 2100 FC/AL HBA was about to become available. After looking at
|
||||
the way it was designed I concluded that it was so darned close to being
|
||||
just like the SCSI HBAs that it would be insane to *not* leverage off of
|
||||
the existing driver. So, we ended up with a driver for NetBSD that drove
|
||||
PCI and SBus SCSI cards, and now also drove the QLogic 2100 FC-AL HBA.
|
||||
|
||||
After this, ports to non-NetBSD platforms became interesting as well.
|
||||
This took the driver out of the interest with NAS and into interested
|
||||
support from a number of other places. Since the original NetBSD
|
||||
development, the driver has been ported to FreeBSD, OpenBSD, Linux,
|
||||
Solaris, and two proprietary systems. Following from the original MI/MD
|
||||
design of NetBSD, a rather successful attempt has been made to keep the
|
||||
Operating System Platform differences segregated and to a minimum.
|
||||
|
||||
Along the way, support for the 2200 as well as full fabric and target
|
||||
mode support has been added, and 2300 support as well as an FC-IP stack
|
||||
are planned.
|
||||
|
||||
3. Driver Design Goals
|
||||
|
||||
The driver has not started out as one normally would do such an effort.
|
||||
Normally you design via top-down methodologies and set an intial goal
|
||||
and meet it. This driver has had a design goal that changes from almost
|
||||
the very first. This has been an extremely peculiar, if not risque,
|
||||
experience. As a consequence, this section of this document contains
|
||||
a bit of "reconstruction after the fact" in that the design goals are
|
||||
as I perceive them to be now- not necessarily what they started as.
|
||||
|
||||
The primary design goal now is to have a driver that can run both the
|
||||
SCSI and Fibre Channel SCSI prototocols on multiple OS platforms with
|
||||
as little OS platform support code as possible.
|
||||
|
||||
The intended support targets for SCSI HBAs is to support the single and
|
||||
dual channel PCI Ultra2 and PCI Ultra3 cards as well as the older PCI
|
||||
Ultra single channel cards and SBus cards.
|
||||
|
||||
The intended support targets for Fibre Channel HBAs is the 2100, 2200
|
||||
and 2300 PCI cards.
|
||||
|
||||
Fibre Channel support should include complete fabric and public loop
|
||||
as well as private loop and private loop, direct-attach topologies.
|
||||
FC-IP support is also a goal.
|
||||
|
||||
For both SCSI and Fibre Channel, simultaneous target/initiator mode support
|
||||
is a goal.
|
||||
|
||||
Pure, raw, performance is not a primary goal of this design. This design,
|
||||
because it has a tremendous amount of code common across multiple
|
||||
platforms, will undoubtedly never be able to beat the performance of a
|
||||
driver that is specifically designed for a single platform and a single
|
||||
card. However, it is a good strong secondary goal to make the performance
|
||||
penalties in this design as small as possible.
|
||||
|
||||
Another primary aim, which almost need not be stated, is that the
|
||||
implementation of platform differences must not clutter up the common
|
||||
code with platform specific defines. Instead, some reasonable layering
|
||||
semantics are defined such that platform specifics can be kept in the
|
||||
platform specific code.
|
||||
|
||||
4. QLogic Hardware Architecture
|
||||
|
||||
In order to make the design of this driver more intelligible, some
|
||||
description of the Qlogic hardware architecture is in order. This will
|
||||
not be an exhaustive description of how this card works, but will
|
||||
note enough of the important features so that the driver design is
|
||||
hopefully clearer.
|
||||
|
||||
4.1 Basic QLogic hardware
|
||||
|
||||
The QLogic HBA cards all contain a tiny 16-bit RISC-like processor and
|
||||
varying sizes of SRAM. Each card contains a Bus Interface Unit (BIU)
|
||||
as appropriate for the host bus (SBus or PCI). The BIUs allow access
|
||||
to a set of dual-ranked 16 bit incoming and outgoing mailbox registers
|
||||
as well as access to control registers that control the RISC or access
|
||||
other portions of the card (e.g., Flash BIOS). The term 'dual-ranked'
|
||||
means that at the same host visible address if you write a mailbox
|
||||
register, that is a write to an (incoming, to the HBA) mailbox register,
|
||||
while a read to the same address reads another (outgoing, to the HBA)
|
||||
mailbox register with completely different data. Each HBA also then has
|
||||
core and auxillary logic which either is used to interface to a SCSI bus
|
||||
(or to external bus drivers that connect to a SCSI bus), or to connect
|
||||
to a Fibre Channel bus.
|
||||
|
||||
4.2 Basic Control Interface
|
||||
|
||||
There are two principle I/O control mechanisms by which the driver
|
||||
communicates with and controls the QLogic HBA. The first mechanism is to
|
||||
use the incoming mailbox registers to interrupt and issue commands to
|
||||
the RISC processor (with results usually, but not always, ending up in
|
||||
the ougtoing mailbox registers). The second mechanism is to establish,
|
||||
via mailbox commands, circular request and response queues in system
|
||||
memory that are then shared between the QLogic and the driver. The
|
||||
request queue is used to queue requests (e.g., I/O requests) for the
|
||||
QLogic HBA's RISC engine to copy into the HBA memory and process. The
|
||||
result queue is used by the QLogic HBA's RISC engine to place results of
|
||||
requests read from the request queue, as well as to place notification
|
||||
of asynchronous events (e.g., incoming commands in target mode).
|
||||
|
||||
To give a bit more precise scale to the preceding description, the QLogic
|
||||
HBA has 8 dual-ranked 16 bit mailbox registers, mostly for out-of-band
|
||||
control purposes. The QLogic HBA then utilizes a circular request queue
|
||||
of 64 byte fixed size Queue Entries to receive normal initiator mode
|
||||
I/O commands (or continue target mode requests). The request queue may
|
||||
be up to 256 elements for the QLogic 1020 and 1040 chipsets, but may
|
||||
be quite larger for the QLogic 12X0/12160 SCSI and QLogic 2X00 Fibre
|
||||
Channel chipsets.
|
||||
|
||||
In addition to synchronously initiated usage of mailbox commands by
|
||||
the host system, the QLogic may also deliver asynchronous notifications
|
||||
solely in outgoing mailbox registers. These asynchronous notifications in
|
||||
mailboxes may be things like notification of SCSI Bus resets, or that the
|
||||
Fabric Name server has sent a change notification, or even that a specific
|
||||
I/O command completed without error (this is called 'Fast Posting'
|
||||
and saves the QLogic HBA from having to write a response queue entry).
|
||||
|
||||
The QLogic HBA is an interrupting card, and when servicing an interrupt
|
||||
you really only have to check for either a mailbox interrupt or an
|
||||
interrupt notification that the the response queue has an entry to
|
||||
be dequeued.
|
||||
|
||||
4.3 Fibre Channel SCSI out of SCSI
|
||||
|
||||
QLogic took the approach in introducing the 2X00 cards to just treat
|
||||
FC-AL as a 'fat' SCSI bus (a SCSI bus with more than 15 targets). All
|
||||
of the things that you really need to do with Fibre Channel with respect
|
||||
to providing FC-4 services on top of a Class 3 connection are performed
|
||||
by the RISC engine on the QLogic card itself. This means that from
|
||||
an HBA driver point of view, very little needs to change that would
|
||||
distinguish addressing a Fibre Channel disk from addressing a plain
|
||||
old SCSI disk.
|
||||
|
||||
However, in the details it's not *quite* that simple. For example, in
|
||||
order to manage Fabric Connections, the HBA driver has to do explicit
|
||||
binding of entities it's queried from the name server to specific 'target'
|
||||
ids (targets, in this case, being a virtual entity).
|
||||
|
||||
Still- the HBA firmware does really nearly all of the tedious management
|
||||
of Fibre Channel login state. The corollary to this sometimes is the
|
||||
lack of ability to say why a particular login connection to a Fibre
|
||||
Channel disk is not working well.
|
||||
|
||||
There are clear limits with the QLogic card in managing fabric devices.
|
||||
The QLogic manages local loop devices (LoopID or Target 0..126) itself,
|
||||
but for the management of fabric devices, it has an absolute limit of
|
||||
253 simultaneous connections (256 entries less 3 reserved entries).
|
||||
|
||||
5. Driver Architecture
|
||||
|
||||
5.1 Driver Assumptions
|
||||
|
||||
The first basic assumption for this driver is that the requirements for
|
||||
a SCSI HBA driver for any system is that of a 2 or 3 layer model where
|
||||
there are SCSI target device drivers (drivers which drive SCSI disks,
|
||||
SCSI tapes, and so on), possibly a middle services layer, and a bottom
|
||||
layer that manages the transport of SCSI CDB's out a SCSI bus (or across
|
||||
Fibre Channel) to a SCSI device. It's assumed that each SCSI command is
|
||||
a separate structure (or pointer to a structure) that contains the SCSI
|
||||
CDB and a place to store SCSI Status and SCSI Sense Data.
|
||||
|
||||
This turns out to be a pretty good assumption. All of the Open Source
|
||||
systems (*BSD and Linux) and most of the proprietary systems have this
|
||||
kind of structure. This has been the way to manage SCSI subsystems for
|
||||
at least ten years.
|
||||
|
||||
There are some additional basic assumptions that this driver makes- primarily
|
||||
in the arena of basic simple services like memory zeroing, memory copying,
|
||||
delay, sleep, microtime functions. It doesn't assume much more than this.
|
||||
|
||||
5.2 Overall Driver Architecture
|
||||
|
||||
The driver is split into a core (machine independent) module and platform
|
||||
and bus specific outer modules (machine dependent).
|
||||
|
||||
The core code (in the files isp.c, isp_inline.h, ispvar.h, ispreg.h and
|
||||
ispmbox.h) handles:
|
||||
|
||||
+ Chipset recognition and reset and firmware download (isp_reset)
|
||||
+ Board Initialization (isp_init)
|
||||
+ First level interrupt handling (response retrieval) (isp_intr)
|
||||
+ A SCSI command queueing entry point (isp_start)
|
||||
+ A set of control services accessed either via local requirements within
|
||||
the core module or via an externally visible control entry point
|
||||
(isp_control).
|
||||
|
||||
The platform/bus specific modules (and definitions) depend on each
|
||||
platform, and they provide both definitions and functions for the core
|
||||
module's use. Generally a platform module set is split into a bus
|
||||
dependent module (where configuration is begun from and bus specific
|
||||
support functions reside) and relatively thin platform specific layer
|
||||
which serves as the interconnect with the rest of this platform's SCSI
|
||||
subsystem.
|
||||
|
||||
For ease of bus specific access issues, a centralized soft state
|
||||
structure is maintained for each HBA instance (struct ispsoftc). This
|
||||
soft state structure contains a machine/bus dependent vector (mdvec)
|
||||
for functions that read and write hardware registers, set up DMA for the
|
||||
request/response queues and fibre channel scratch area, set up and tear
|
||||
down DMA mappings for a SCSI command, provide a pointer to firmware to
|
||||
load, and other minor things.
|
||||
|
||||
The machine dependent outer module must provide functional entry points
|
||||
for the core module:
|
||||
|
||||
+ A SCSI command completion handoff point (isp_done)
|
||||
+ An asynchronous event handler (isp_async)
|
||||
+ A logging/printing function (isp_prt)
|
||||
|
||||
The machine dependent outer module code must also provide a set of
|
||||
abstracting definitions which is what the core module utilizes heavily
|
||||
to do its job. These are discussed in detail in the comments in the
|
||||
file ispvar.h, but to give a sense of the range of what is required,
|
||||
let's illustrate two basic classes of these defines.
|
||||
|
||||
The first class are "structure definition/access" class. An
|
||||
example of these would be:
|
||||
|
||||
XS_T Platform SCSI transaction type (i.e., command for HBA)
|
||||
..
|
||||
XS_TGT(xs) gets the target from an XS_T
|
||||
..
|
||||
XS_TAG_TYPE(xs) which type of tag to use
|
||||
..
|
||||
|
||||
The second class are 'functional' class definitions. Some examples of
|
||||
this class are:
|
||||
|
||||
MEMZERO(dst, src) platform zeroing function
|
||||
..
|
||||
MBOX_WAIT_COMPLETE(struct ispsoftc *) wait for mailbox cmd to be done
|
||||
|
||||
Note that the former is likely to be simple replacement with bzero or
|
||||
memset on most systems, while the latter could be quite complex.
|
||||
|
||||
This soft state structure also contains different parameter information
|
||||
based upon whether this is a SCSI HBA or a Fibre Channel HBA (which is
|
||||
filled in by the code module).
|
||||
|
||||
In order to clear up what is undoubtedly a seeming confusion of
|
||||
interconnects, a description of the typical flow of code that performs
|
||||
boards initialization and command transactions may help.
|
||||
|
||||
5.3 Initialization Code Flow
|
||||
|
||||
Typically a bus specific module for a platform (e.g., one that wants
|
||||
to configure a PCI card) is entered via that platform's configuration
|
||||
methods. If this module recognizes a card and can utilize or construct the
|
||||
space for the HBA instance softc, it does so, and initializes the machine
|
||||
dependent vector as well as any other platform specific information that
|
||||
can be hidden in or associated with this structure.
|
||||
|
||||
Configuration at this point usually involves mapping in board registers
|
||||
and registering an interrupt. It's quite possible that the core module's
|
||||
isp_intr function is adequate to be the interrupt entry point, but often
|
||||
it's more useful have a bus specific wrapper module that calls isp_intr.
|
||||
|
||||
After mapping and interrupt registry is done, isp_reset is called.
|
||||
Part of the isp_reset call may cause callbacks out to the bus dependent
|
||||
module to perform allocation and/or mapping of Request and Response
|
||||
queues (as well as a Fibre Channel scratch area if this is a Fibre
|
||||
Channel HBA). The reason this is considered 'bus dependent' is that
|
||||
only the bus dependent module may have the information that says how
|
||||
one could perform I/O mapping and dependent (e.g., on a Solaris system)
|
||||
on the Request and Reponse queues. Another callback can enable the *use*
|
||||
of interrupts should this platform be able to finish configuration in
|
||||
interrupt driven mode.
|
||||
|
||||
If isp_reset is successful at resetting the QLogic chipset and downloading
|
||||
new firmware (if available) and setting it running, isp_init is called. If
|
||||
isp_init is successful in doing initial board setups (including reading
|
||||
NVRAM from the QLogic card), then this bus specicic module will call the
|
||||
platform dependent module that takes the appropriate steps to 'register'
|
||||
this HBA with this platform's SCSI subsystem. Examining either the
|
||||
OpenBSD or the NetBSD isp_pci.c or isp_sbus.c files may assist the reader
|
||||
here in clarifying some of this.
|
||||
|
||||
5.4 Initiator Mode Command Code Flow
|
||||
|
||||
A succesful execution of isp_init will lead to the driver 'registering'
|
||||
itself with this platform's SCSI subsystem. One assumed action for this
|
||||
is the registry of a function the the SCSI subsystem for this platform
|
||||
will call when it has a SCSI command to run.
|
||||
|
||||
The platform specific module function that receives this will do whatever
|
||||
it needs to to prepare this command for execution in the core module. This
|
||||
sounds vague, but it's also very flexible. In principle, this could be
|
||||
a complete marshalling/demarshalling of this platform's SCSI command
|
||||
structure (should it be impossible to represent in an XS_T). In addition,
|
||||
this function can also block commands from running (if, e.g., Fibre
|
||||
Channel loop state would preclude successful starting of the command).
|
||||
|
||||
When it's ready to do so, the function isp_start is called with this
|
||||
command. This core module tries to allocate request queue space for
|
||||
this command. It also calls through the machine dependent vector
|
||||
function to make sure any DMA mapping for this command is done.
|
||||
|
||||
Now, DMA mapping here is possibly a misnomer, as more than just
|
||||
DMA mapping can be done in this bus dependent function. This is
|
||||
also the place where any endian byte-swizzling will be done. At any
|
||||
rate, this function is called last because the process of establishing
|
||||
DMA addresses for any command may in fact consume more Request Queue
|
||||
entries than there are currently available. If the mapping and other
|
||||
functions are successful, the QLogic mailbox inbox pointer register
|
||||
is updated to indicate to the QLogic that it has a new request to
|
||||
read.
|
||||
|
||||
If this function is unsuccessful, policy as to what to do at this point is
|
||||
left to the machine dependent platform function which called isp_start. In
|
||||
some platforms, temporary resource shortages can be handled by the main
|
||||
SCSI subsystem. In other platforms, the machine dependent code has to
|
||||
handle this.
|
||||
|
||||
In order to keep track of commands that are in progress, the soft state
|
||||
structure contains an array of 'handles' that are associated with each
|
||||
active command. When you send a command to the QLogic firmware, a portion
|
||||
of the Request Queue entry can contain a non-zero handle identifier so
|
||||
that at a later point in time in reading either a Response Queue entry
|
||||
or from a Fast Posting mailbox completion interrupt, you can take this
|
||||
handle to find the command you were waiting on. It should be noted that
|
||||
this is probably one of the most dangerous areas of this driver. Corrupted
|
||||
handles will lead to system panics.
|
||||
|
||||
At some later point in time an interrupt will occur. Eventually,
|
||||
isp_intr will be called. This core module will determine what the cause
|
||||
of the interrupt is, and if it is for a completing command. That is,
|
||||
it'll determine the handle and fetch the pointer to the command out of
|
||||
storage within the soft state structure. Skipping over a lot of details,
|
||||
the machine dependent code supplied function isp_done is called with the
|
||||
pointer to the completing command. This would then be the glue layer that
|
||||
informs the SCSI subsystem for this platform that a command is complete.
|
||||
|
||||
5.5 Asynchronous Events
|
||||
|
||||
Interrupts occur for events other than commands (mailbox or request queue
|
||||
started commands) completing. These are called Asynchronous Mailbox
|
||||
interrupts. When some external event causes the SCSI bus to be reset,
|
||||
or when a Fibre Channel loop changes state (e.g., a LIP is observed),
|
||||
this generates such an asynchronous event.
|
||||
|
||||
Each platform module has to provide an isp_async entry point that will
|
||||
handle a set of these. This isp_async entry point also handles things
|
||||
which aren't properly async events but are simply natural outgrowths
|
||||
of code flow for another core function (see discussion on fabric device
|
||||
management below).
|
||||
|
||||
5.6 Target Mode Code Flow
|
||||
|
||||
This section could use a lot of expansion, but this covers the basics.
|
||||
The basic QLogic model for target mode is based upon the ANSI CAM
|
||||
specification.
|
||||
|
||||
The QLogic cards, when operating in target mode, follow a code flow that is
|
||||
essentially the inverse of that for intiator mode describe above. In this
|
||||
scenario, an interrupt occurs, and present on the Response Queue is a
|
||||
queue entry element defining a new command arriving from an initiator
|
||||
In CAM terminology this is an ATIO (Accept Target IO) command.
|
||||
|
||||
This is passed to possibly external target mode handler. This driver
|
||||
provides some handling for this in a core module, but also leaves
|
||||
things open enough that a completely different target mode handler
|
||||
may accept this incoming queue entry.
|
||||
|
||||
The external target mode handler then turns around forms up a
|
||||
response to this 'response' that just arrived which is then placed
|
||||
on the Request Queue and handled very much like an initiator mode
|
||||
command (i.e., calling the bus dependent DMA mapping function). In
|
||||
CAM terminology, this is a CTIO (Continue Target IO) command.
|
||||
|
||||
If this entry completes the command, no more need occur. But often
|
||||
this handles only part of the requested command, so the QLogic
|
||||
firmware will rewrite the response to the initial 'response' again
|
||||
(i.e., returning the CTIO just sent) onto the Response Queue,
|
||||
whereupon the target mode handler will respond to that, and so on
|
||||
until the command is completely handled (the last CTIO is sent).
|
||||
|
||||
Other events that are not associated with commands also arrive
|
||||
as asynchronous events. In CAM terminology, these are called
|
||||
INOTIFY (Immediate Notify) commands. Things like task management
|
||||
functions (e.g., ABORT TASK) or BUS RESET arrive via INOTIFY
|
||||
commands. The driver is responsible for acknowledging the receipt
|
||||
of such INOTIFYs.
|
||||
|
||||
Because no platform other than FreeBSD provides basic SCSI Subsystem
|
||||
target mode support, this design has been left extremely open ended,
|
||||
and as such it's a bit hard to describe in more detail than this.
|
||||
|
||||
5.7 Locking Assumptions
|
||||
|
||||
The observant reader by now is likely to have asked the question, "but what
|
||||
about locking? Or interrupt masking" by now.
|
||||
|
||||
The basic assumption about this is that the core module does not know
|
||||
anything directly about locking or interrupt masking. It may assume that
|
||||
upon entry (e.g., via isp_start, isp_control, isp_intr) that appropriate
|
||||
locking and interrupt masking has been done.
|
||||
|
||||
The platform dependent code may also therefore assume that if it is
|
||||
called (e.g., isp_done or isp_async) that any locking or masking that
|
||||
was in place upon the entry to the core module is still there. It is up
|
||||
to the platform dependent code to worry about avoiding any lock nesting
|
||||
issues. As an example of this, the Linux implementation simply queues
|
||||
up commands completed via the callout to isp_done, which it then pushes
|
||||
out to the SCSI subsystem after a return from it's calling isp_intr is
|
||||
executed (and locks dropped appropriately, as well as avoidance of deep
|
||||
interrupt stacks).
|
||||
|
||||
Recent changes in the design have now eased what had been an original
|
||||
requirement that the while in the core module no locks or interrupt
|
||||
masking could be dropped. It's now up to each platform to figure out how
|
||||
to implement this. This is principally used in the execution of mailbox
|
||||
commands (which are principally used for Loop and Fabric management via
|
||||
the isp_control function).
|
||||
|
||||
5.8 SCSI Specifics
|
||||
|
||||
The driver core or platform dependent architecture issues that are specific
|
||||
to SCSI are few. There is a basic assumption that the QLogic firmware
|
||||
supported Automatic Request sense will work- there is no particular provision
|
||||
for disabling it's usage on a per-command basis.
|
||||
|
||||
5.9 Fibre Channel Specifics
|
||||
|
||||
Fibre Channel presents an interesting challenge here. The QLogic firmware
|
||||
architecture for dealing with Fibre Channel as just a 'fat' SCSI bus
|
||||
is fine on the face of it, but there are some subtle and not so subtle
|
||||
problems here.
|
||||
|
||||
5.9.1 Firmware State
|
||||
|
||||
Part of the initialization (isp_init) for Fibre Channel HBAs involves
|
||||
sending a command (Initialize Control Block) that establishes Node
|
||||
and Port WWNs as well as topology preferences. After this occurs,
|
||||
the QLogic firmware tries to traverese through serveral states:
|
||||
|
||||
FW_CONFIG_WAIT
|
||||
FW_WAIT_AL_PA
|
||||
FW_WAIT_LOGIN
|
||||
FW_READY
|
||||
FW_LOSS_OF_SYNC
|
||||
FW_ERROR
|
||||
FW_REINIT
|
||||
FW_NON_PART
|
||||
|
||||
It starts with FW_CONFIG_WAIT, attempts to get an AL_PA (if on an FC-AL
|
||||
loop instead of being connected as an N-port), waits to log into all
|
||||
FC-AL loop entities and then hopefully transitions to FW_READY state.
|
||||
|
||||
Clearly, no command should be attempted prior to FW_READY state is
|
||||
achieved. The core internal function isp_fclink_test (reachable via
|
||||
isp_control with the ISPCTL_FCLINK_TEST function code). This function
|
||||
also determines connection topology (i.e., whether we're attached to a
|
||||
fabric or not).
|
||||
|
||||
5.9.2. Loop State Transitions- From Nil to Ready
|
||||
|
||||
Once the firmware has transitioned to a ready state, then the state of the
|
||||
connection to either arbitrated loop or to a fabric has to be ascertained,
|
||||
and the identity of all loop members (and fabric members validated).
|
||||
|
||||
This can be very complicated, and it isn't made easy in that the QLogic
|
||||
firmware manages PLOGI and PRLI to devices that are on a local loop, but
|
||||
it is the driver that must manage PLOGI/PRLI with devices on the fabric.
|
||||
|
||||
In order to manage this state an eight level staging of current "Loop"
|
||||
(where "Loop" is taken to mean FC-AL or N- or F-port connections) states
|
||||
in the following ascending order:
|
||||
|
||||
LOOP_NIL
|
||||
LOOP_LIP_RCVD
|
||||
LOOP_PDB_RCVD
|
||||
LOOP_SCANNING_FABRIC
|
||||
LOOP_FSCAN_DONE
|
||||
LOOP_SCANNING_LOOP
|
||||
LOOP_LSCAN_DONE
|
||||
LOOP_SYNCING_PDB
|
||||
LOOP_READY
|
||||
|
||||
When the core code initializes the QLogic firmware, it sets the loop
|
||||
state to LOOP_NIL. The first 'LIP Received' asynchronous event sets state
|
||||
to LOOP_LIP_RCVD. This should be followed by a "Port Database Changed"
|
||||
asynchronous event which will set the state to LOOP_PDB_RCVD. Each of
|
||||
these states, when entered, causes an isp_async event call to the
|
||||
machine dependent layers with the ISPASYNC_CHANGE_NOTIFY code.
|
||||
|
||||
After the state of LOOP_PDB_RCVD is reached, the internal core function
|
||||
isp_scan_fabric (reachable via isp_control(..ISPCTL_SCAN_FABRIC)) will,
|
||||
if the connection is to a fabric, use Simple Name Server mailbox mediated
|
||||
commands to dump the entire fabric contents. For each new entity, an
|
||||
isp_async event will be generated that says a Fabric device has arrived
|
||||
(ISPASYNC_FABRIC_DEV). The function that isp_async must perform in this
|
||||
step is to insert possibly remove devices that it wants to have the
|
||||
QLogic firmware log into (at LOOP_SYNCING_PDB state level)).
|
||||
|
||||
After this has occurred, the state LOOP_FSCAN_DONE is set, and then the
|
||||
internal function isp_scan_loop (isp_control(...ISPCTL_SCAN_LOOP)) can
|
||||
be called which will then scan for any local (FC-AL) entries by asking
|
||||
for each possible local loop id the QLogic firmware for a Port Database
|
||||
entry. It's at this level some entries cached locally are purged
|
||||
or shifting loopids are managed (see section 5.9.4).
|
||||
|
||||
The final step after this is to call the internal function isp_pdb_sync
|
||||
(isp_control(..ISPCTL_PDB_SYNC)). The purpose of this function is to
|
||||
then perform the PLOGI/PRLI functions for fabric devices. The next state
|
||||
entered after this is LOOP_READY, which means that the driver is ready
|
||||
to process commands to send to Fibre Channel devices.
|
||||
|
||||
5.9.3 Fibre Channel variants of Initiator Mode Code Flow
|
||||
|
||||
The code flow in isp_start for Fibre Channel devices is the same as it is
|
||||
for SCSI devices, but with a notable exception.
|
||||
|
||||
Maintained within the fibre channel specific portion of the driver soft
|
||||
state structure is a distillation of the existing population of both
|
||||
local loop and fabric devices. Because Loop IDs can shift on a local
|
||||
loop but we wish to retain a 'constant' Target ID (see 5.9.4), this
|
||||
is indexed directly via the Target ID for the command (XS_TGT(xs)).
|
||||
|
||||
If there is a valid entry for this Target ID, the command is started
|
||||
(with the stored 'Loop ID'). If not the command is completed with
|
||||
the error that is just like a SCSI Selection Timeout error.
|
||||
|
||||
This code is currently somewhat in transition. Some platforms to
|
||||
do firmware and loop state management (as described above) at this
|
||||
point. Other platforms manage this from the machine dependent layers. The
|
||||
important function to watch in this respect is isp_fc_runstate (in
|
||||
isp_inline.h).
|
||||
|
||||
5.9.4 "Target" in Fibre Channel is a fixed virtual construct
|
||||
|
||||
Very few systems can cope with the notion that "Target" for a disk
|
||||
device can change while you're using it. But one of the properties of
|
||||
for arbitrated loop is that the physical bus address for a loop member
|
||||
(the AL_PA) can change depending on when and how things are inserted in
|
||||
the loop.
|
||||
|
||||
To illustrate this, let's take an example. Let's say you start with a
|
||||
loop that has 5 disks in it. At boot time, the system will likely find
|
||||
them and see them in this order:
|
||||
|
||||
disk# Loop ID Target ID
|
||||
disk0 0 0
|
||||
disk1 1 1
|
||||
disk2 2 2
|
||||
disk3 3 3
|
||||
disk4 4 4
|
||||
|
||||
The driver uses 'Loop ID' when it forms requests to send a comamnd to
|
||||
each disk. However, it reports to NetBSD that things exist as 'Target
|
||||
ID'. As you can see here, there is perfect correspondence between disk,
|
||||
Loop ID and Target ID.
|
||||
|
||||
Let's say you add a new disk between disk2 and disk3 while things are
|
||||
running. You don't really often see this, but you *could* see this where
|
||||
the loop has to renegotiate, and you end up with:
|
||||
|
||||
disk# Loop ID Target ID
|
||||
disk0 0 0
|
||||
disk1 1 1
|
||||
disk2 2 2
|
||||
diskN 3 ?
|
||||
disk3 4 ?
|
||||
disk4 5 ?
|
||||
|
||||
Clearly, you don't want disk3 and disk4's "Target ID" to change while you're
|
||||
running since currently mounted filesystems will get trashed.
|
||||
|
||||
What the driver is supposed to do (this is the function of isp_scan_loop),
|
||||
is regenerate things such that the following then occurs:
|
||||
|
||||
disk# Loop ID Target ID
|
||||
disk0 0 0
|
||||
disk1 1 1
|
||||
disk2 2 2
|
||||
diskN 3 5
|
||||
disk3 4 3
|
||||
disk4 5 4
|
||||
|
||||
So, "Target" is a virtual entity that is maintained while you're running.
|
||||
|
||||
6. Glossary
|
||||
|
||||
HBA - Host Bus Adapter
|
||||
|
||||
SCSI - Small Computer
|
||||
|
||||
7. References
|
||||
|
||||
Various URLs of interest:
|
||||
|
||||
http://www.netbsd.org - NetBSD's Web Page
|
||||
http://www.openbsd.org - OpenBSD's Web Page
|
||||
http://www.freebsd.org - FreeBSD's Web Page
|
||||
|
||||
http://www.t10.org - ANSI SCSI Commitee's Web Page
|
||||
(SCSI Specs)
|
||||
http://www.t11.org - NCITS Device Interface Web Page
|
||||
(Fibre Channel Specs)
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
$Id: Hardware.txt,v 1.6 2006/02/17 22:53:44 mjacob Exp $
|
||||
Copyright (c) 1997-2004 by Matthew Jacob
|
||||
All rights reserved.
|
||||
|
||||
Hardware that is Known To or Should Work with This Driver
|
||||
|
||||
|
||||
0. Intro
|
||||
|
||||
This is not an endorsement for hardware vendors (there will be
|
||||
no "where to buy" URLs here with a couple of exception). This
|
||||
is simply a list of things I know work, or should work, plus
|
||||
maybe a couple of notes as to what you should do to make it
|
||||
work. Corrections accepted. Even better would be to send me
|
||||
hardware to I can test it.
|
||||
|
||||
I'll put a rough range of costs in US$ that I know about. No doubt
|
||||
it'll differ from your expectations.
|
||||
|
||||
1. HBAs
|
||||
|
||||
Qlogic 2100, 2102
|
||||
2200, 2202, 2204
|
||||
|
||||
There are various suffices that indicate copper or optical
|
||||
connectors, or 33 vs. 66MHz PCI bus operation. None of these
|
||||
have a software impact.
|
||||
|
||||
Approx cost: 1K$ for a 2200
|
||||
|
||||
Qlogic 2300, 2312, 2340, 2342
|
||||
|
||||
These are the new 2-Gigabit cards. Optical only.
|
||||
|
||||
Approx cost: ??????
|
||||
|
||||
|
||||
Antares P-0033, P-0034, P-0036
|
||||
|
||||
There many other vendors that use the Qlogic 2X00 chipset. Some older
|
||||
2100 boards (not on this list) have a bug in the ROM that causes a
|
||||
failure to download newer firmware that is larger than 0x7fff words.
|
||||
|
||||
Approx cost: 850$ for a P-0036
|
||||
|
||||
|
||||
|
||||
In general, the 2200 class chip is to be preferred.
|
||||
|
||||
|
||||
2. Hubs
|
||||
|
||||
Vixel 1000
|
||||
Vixel 2000
|
||||
Of the two, the 1000 (7 ports, vs. 12 ports) has had fewer problems-
|
||||
it's an old workhorse.
|
||||
|
||||
|
||||
Approx cost: 1.5K$ for Vixel 1000, 2.5K$ for 2000
|
||||
|
||||
Gadzoox Cappellix 3000
|
||||
Don't forget to use telnet to configure the Cappellix ports
|
||||
to the role you're using them for- otherwise things don't
|
||||
work well at all.
|
||||
|
||||
(cost: I have no idea... certainly less than a switch)
|
||||
|
||||
3. Switches
|
||||
|
||||
Brocade Silkworm II
|
||||
Brocade 2X00
|
||||
Brocade 3X00
|
||||
|
||||
Especially with revision 2 or higher f/w, this is now best
|
||||
of breed for fabrics or segmented loop (which Brocade
|
||||
calls "QuickLoop").
|
||||
|
||||
For the Silkworm II, set operating mode to "Tachyon" (mode 3).
|
||||
|
||||
The web interace isn't good- but telnet is what I prefer anyhow.
|
||||
|
||||
You can't connect a Silkworm II and the other Brocades together
|
||||
as E-ports to make a large fabric (at least with the f/w *I*
|
||||
had for the Silkworm II).
|
||||
|
||||
Approx cost of a Brocade 2400 with no GBICs is about 8K$ when
|
||||
I recently checked the US Government SEWP price list- no doubt
|
||||
it'll be a bit more for others. I'd assume around 10K$.
|
||||
|
||||
ANCOR Sanbox1
|
||||
ANCOR Sanbox2 (2Gb)
|
||||
|
||||
These are also fine switches, but you have to use a browser
|
||||
with working java to manage it.
|
||||
|
||||
These also support fabric and segmented loops.
|
||||
|
||||
These switches now *do* form E-ports with each other.
|
||||
|
||||
(cost: no idea)
|
||||
|
||||
McData (model unknown, oem'd by HP as "SureStore FC Director")
|
||||
|
||||
Works well. Very very expensive.
|
||||
|
||||
4. Cables/GBICs
|
||||
|
||||
Multimode optical is adequate for Fibre Channel- the same cable is
|
||||
used for Gigabit Ethernet.
|
||||
|
||||
Copper DB-9 and Copper HSS-DC connectors are also fine. Copper &&
|
||||
Optical both are rated to 1.026Gbit- copper is naturally shorter
|
||||
(the longest I've used is a 15meter cable but it's supposed to go
|
||||
longer).
|
||||
|
||||
The reason to use copper instead of optical is that if step on one of
|
||||
the really fat DB-9 cables you can get, it'll survive. Optical usually
|
||||
dies quickly if you step on it.
|
||||
|
||||
Approx cost: I don't know what optical is- you can expect to pay maybe
|
||||
a 100$ for a 3m copper cable.
|
||||
|
||||
GBICs-
|
||||
|
||||
I use Finisar copper and IBM Opticals.
|
||||
|
||||
Approx Cost: Copper GBICs are 70$ each. Opticals are twice that or more.
|
||||
|
||||
|
||||
Vendor: (this is the one exception I'll make because it turns out to be
|
||||
an incredible pain to find FC copper cabling and GBICs- the source I
|
||||
use for GBICs and copper cables is http://www.scsi-cables.com)
|
||||
|
||||
|
||||
Other:
|
||||
There now is apparently a source for little connector boards
|
||||
to connect to bare drives: http://www.cinonic.com.
|
||||
|
||||
|
||||
5. Storage JBODs/RAID
|
||||
|
||||
JMR 4-Bay
|
||||
|
||||
Rinky-tink, but a solid 4 bay loop only entry model.
|
||||
|
||||
I paid 1000$ for mine- overprice, IMO.
|
||||
|
||||
JMR Fortra
|
||||
|
||||
I rather like this box. The blue LEDs are a very nice touch- you
|
||||
can see them very clearly from 50 feet away.
|
||||
|
||||
I paid 2000$ for one used.
|
||||
|
||||
Sun A5X00
|
||||
|
||||
Very expensive (in my opinion) but well crafted. Has two SES
|
||||
instances, so you can use the ses driver (and the example
|
||||
code in /usr/share/examples) for power/thermal/slot monitoring.
|
||||
|
||||
Approx Cost: The last I saw for a price list item on this was 22K$
|
||||
for a unpopulated (no disk drive) A5X00.
|
||||
|
||||
|
||||
DataDirect E1000 RAID
|
||||
|
||||
Don't connect both SCSI and FC interfaces at the same time- a SCSI
|
||||
reset will cause the DataDirect to think you want to use the SCSI
|
||||
interface and a LIP on the FC interface will cause it to think you
|
||||
want to use the FC interface. Use only one connector at a time so
|
||||
both you and the DataDirect are sure about what you want.
|
||||
|
||||
Cost: I have no idea.
|
||||
|
||||
Veritas ServPoint
|
||||
|
||||
This is a software storage virtualization engine that
|
||||
runs on Sparc/Solaris in target mode for frontend
|
||||
and with other FC or SCSI as the backend storage. FreeBSD
|
||||
has been used extensively to test it.
|
||||
|
||||
|
||||
Cost: I have no idea.
|
||||
|
||||
6. Disk Drives
|
||||
|
||||
I have used lots of different Seagate and a few IBM drives and
|
||||
typically have had few problems with them. These are the bare
|
||||
drives with 40-pin SCA connectors in back. They go into the JBODs
|
||||
you assemble.
|
||||
|
||||
Seagate does make, but I can no longer find, a little paddleboard
|
||||
single drive connector that goes from DB-9 FC to the 40-pin SCA
|
||||
connector- primarily for you to try and evaluate a single FC drive.
|
||||
|
||||
All FC-AL disk drives are dual ported (i.e., have separte 'A' and
|
||||
'B' ports- which are completely separate loops). This seems to work
|
||||
reasonably enough, but I haven't tested it much. It really depends
|
||||
on the JBOD you put them to carry this dual port to the outside
|
||||
world. The JMR boxes have it. The Sun A5X00 you have to pay for
|
||||
an extra IB card to carry it out.
|
||||
|
||||
Approx Cost: You'll find that FC drives are the same cost if not
|
||||
slightly cheaper than the equivalent Ultra3 SCSI drives.
|
||||
|
||||
7. Recommended Configurations
|
||||
|
||||
These are recommendations that are biased toward the cautious side. They
|
||||
do not represent formal engineering commitments- just suggestions as to
|
||||
what I would expect to work.
|
||||
|
||||
A. The simpletst form of a connection topology I can suggest for
|
||||
a small SAN (i.e., replacement for SCSI JBOD/RAID):
|
||||
|
||||
HOST
|
||||
2xxx <----------> Single Unit of Storage (JBOD, RAID)
|
||||
|
||||
This is called a PL_DA (Private Loop, Direct Attach) topology.
|
||||
|
||||
B. The next most simple form of a connection topology I can suggest for
|
||||
a medium local SAN (where you do not plan to do dynamic insertion
|
||||
and removal of devices while I/Os are active):
|
||||
|
||||
HOST
|
||||
2xxx <----------> +--------
|
||||
| Vixel |
|
||||
| 1000 |
|
||||
| +<---> Storage
|
||||
| |
|
||||
| +<---> Storage
|
||||
| |
|
||||
| +<---> Storage
|
||||
--------
|
||||
|
||||
This is a Private Loop topology. Remember that this can get very unstable
|
||||
if you make it too long. A good practice is to try it in a staged fashion.
|
||||
|
||||
It is possible with some units to "daisy chain", e.g.:
|
||||
|
||||
HOST
|
||||
2xxx <----------> (JBOD, RAID) <--------> (JBOD, RAID)
|
||||
|
||||
In practice I have had poor results with these configurations. They *should*
|
||||
work fine, but for both the JMR and the Sun A5X00 I tend to get LIP storms
|
||||
and so the second unit just isn't seen and the loop isn't stable.
|
||||
|
||||
Now, this could simply be my lack of clean, newer, h/w (or, in general,
|
||||
a lack of h/w), but I would recommend the use of a hub if you want to
|
||||
stay with Private Loop and have more than one FC target.
|
||||
|
||||
You should also note this can begin to be the basis for a shared SAN
|
||||
solution. For example, the above configuration can be extended to be:
|
||||
|
||||
HOST
|
||||
2xxx <----------> +--------
|
||||
| Vixel |
|
||||
| 1000 |
|
||||
| +<---> Storage
|
||||
| |
|
||||
| +<---> Storage
|
||||
| |
|
||||
| +<---> Storage
|
||||
HOST | |
|
||||
2xxx <----------> +--------
|
||||
|
||||
However, note that there is nothing to mediate locking of devices, and
|
||||
it is also conceivable that the reboot of one host can, by causing
|
||||
a LIP storm, cause problems with the I/Os from the other host.
|
||||
(in other words, this topology hasn't really been made safe yet for
|
||||
this driver).
|
||||
|
||||
D. You can repeat the topology in #B with a switch that is set to be
|
||||
in segmented loop mode. This avoids LIPs propagating where you don't
|
||||
want them to- and this makes for a much more reliable, if more expensive,
|
||||
SAN.
|
||||
|
||||
E. The next level of complexity is a Switched Fabric. The following topology
|
||||
is good when you start to begin to get to want more performance. Private
|
||||
and Public Arbitrated Loop, while 100MB/s, is a shared medium. Direct
|
||||
connections to a switch can run full-duplex at full speed.
|
||||
|
||||
HOST
|
||||
2xxx <----------> +---------
|
||||
| Brocade|
|
||||
| 2400 |
|
||||
| +<---> Storage
|
||||
| |
|
||||
| +<---> Storage
|
||||
| |
|
||||
| +<---> Storage
|
||||
HOST | |
|
||||
2xxx <----------> +---------
|
||||
|
||||
|
||||
I would call this the best configuration available now. It can expand
|
||||
substantially if you cascade switches.
|
||||
|
||||
There is a hard limit of about 253 devices for each Qlogic HBA- and the
|
||||
fabric login policy is simplistic (log them in as you find them). If
|
||||
somebody actually runs into a configuration that's larger, let me know
|
||||
and I'll work on some tools that would allow you some policy choices
|
||||
as to which would be interesting devices to actually connect to.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
# $Id: Makefile,v 1.5 2007/03/10 02:27:53 mjacob Exp $
|
||||
#
|
||||
# Makefile
|
||||
#
|
||||
# Copyright (c) 2006-2007 by Matthew Jacob
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
# Feral Software
|
||||
# 421 Laurel Avenue
|
||||
# Menlo Park, CA 94025
|
||||
# USA
|
||||
#
|
||||
# gpl at feral com
|
||||
#
|
||||
ifndef KDIR
|
||||
LVERS = $(shell uname -r)
|
||||
LINUX ?= /lib/modules/${LVERS}/build
|
||||
else
|
||||
LINUX = ${KDIR}
|
||||
endif
|
||||
|
||||
all: links
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build
|
||||
|
||||
tgt: links
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build ISP_TARGET_MODE=1
|
||||
|
||||
clean:
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build clean
|
||||
@$(MAKE) -C build clean_links
|
||||
@$(RM) tags
|
||||
|
||||
install:
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build modules_install
|
||||
|
||||
links:
|
||||
@$(MAKE) -C build make_links
|
||||
|
||||
tools:
|
||||
cd ../linux && $(MAKE) tools
|
||||
|
||||
tags: FRC
|
||||
@ctags --recurse --append=no --exclude=Makefile --exclude=freebsd --exclude=solaris ../
|
||||
|
||||
FRC:
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# $Id: Makefile,v 1.13 2007/03/10 02:27:53 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 2006-2007 by Matthew Jacob
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
# Feral Software
|
||||
# 421 Laurel Avenue
|
||||
# Menlo Park, CA 94025
|
||||
# USA
|
||||
#
|
||||
# gpl at feral com
|
||||
|
||||
M ?= $(CURDIR)
|
||||
TDIR = $(M)/../../
|
||||
COM_OBJ = isp.o isp_library.o isp_target.o
|
||||
LNX_OBJ = isp_cb_ops.o isp_linux.o isp_pci.o
|
||||
COM_DIR = ${TDIR}/common
|
||||
LNX_DIR = ${TDIR}/linux
|
||||
SCST_DIR = ${TDIR}/../scst/include
|
||||
|
||||
STG_SRC = isp_scst.c
|
||||
|
||||
#EXTRA_CFLAGS += -Wall -Werror -Idrivers/scsi -I${COM_DIR} -I${LNX_DIR} -I${TDIR}/firmware -I${SCST_DIR}
|
||||
EXTRA_CFLAGS += -Wall -Idrivers/scsi -I${COM_DIR} -I${LNX_DIR} -I${TDIR}/firmware -I${SCST_DIR}
|
||||
|
||||
clean-files := *.o scsi_target_ctl Module.symvers
|
||||
|
||||
ifdef ISP_TARGET_MODE
|
||||
|
||||
EXTRA_CFLAGS += -DISP_TARGET_MODE=1 -DISP_DEFAULT_ROLES=ISP_ROLE_NONE
|
||||
|
||||
obj-m := isp_mod.o isp_scst.o
|
||||
|
||||
else
|
||||
|
||||
obj-m := isp_mod.o
|
||||
|
||||
endif
|
||||
|
||||
isp_mod-objs := ${COM_OBJ} ${LNX_OBJ}
|
||||
|
||||
clean_links:
|
||||
@${RM} $(COM_OBJ:.o=.c) $(LNX_OBJ:.o=.c) ${STG_SRC}
|
||||
|
||||
make_links: clean_links
|
||||
@for j in ${COM_OBJ:.o=.c}; do ln -s ${COM_DIR}/$$j; done
|
||||
@for j in ${LNX_OBJ:.o=.c}; do ln -s ${LNX_DIR}/$$j; done
|
||||
@for j in ${STG_SRC}; do ln -s ${LNX_DIR}/$$j; done
|
||||
@@ -0,0 +1,13 @@
|
||||
$Id: LINUX_BUILD_INSTRUCTIONS,v 1.23 2006/06/29 21:14:53 mjacob Exp $
|
||||
Copyright (c) 1997-2006 by Matthew Jacob
|
||||
All rights reserved.
|
||||
|
||||
This driver is for Linux-2.4 and Linux-2.6 kernels only. If you build
|
||||
in this directory, this is for Linux-2.4 only. To build Linux-2.6, change
|
||||
directory to ../Linux-2.6.
|
||||
|
||||
Since this is a mature product, it's recommended that you just use the 2.4.32
|
||||
kernel from the ftp.kernel.org repository and build this as a module.
|
||||
|
||||
If you need to build this inside the kernel tree itself, there is
|
||||
a patch set for linux 2.4.20. This hasn't been tested in quite a while.
|
||||
@@ -0,0 +1,52 @@
|
||||
$Id: LINUX_TARGET_MODE_HOWTO,v 1.17 2006/06/29 21:14:54 mjacob Exp $
|
||||
Copyright (c) 1997-2006 by Matthew Jacob
|
||||
All rights reserved.
|
||||
|
||||
|
||||
Target Mode usage instructions (for 2.4.X)
|
||||
|
||||
A. Build for target mode enabled, use the target 'tgt', as in:
|
||||
|
||||
make tgt
|
||||
|
||||
Static compilation into the kernel isn't supported.
|
||||
|
||||
B. Install scsi_tgt.o && isp_mod.o into the appropriate places, e.g.:
|
||||
|
||||
|
||||
For 2.4.X:
|
||||
cp isp_mod.o /lib/modules/RELEASE/kernel/drivers/scsi
|
||||
cp scsi_target.o /lib/modules/RELEASE/kernel/drivers/scsi
|
||||
|
||||
where RELEASE is the full kernel release number you build against.
|
||||
|
||||
C. Type 'depmod -a'. Type 'modprobe isp_mod' to load both isp_mod and the
|
||||
scsi_tgt module. Usually the loader will pull in scsi_tgt.o as needed,
|
||||
but you can alwyas do 'modprobe scsi_tgt' by itself first.
|
||||
|
||||
You can also add 'isp_debug=0xXXXX' to turn on debugging for target
|
||||
mode- See ispvar.h for good values to try- but 0xe0f is a good healthy
|
||||
amount to try.
|
||||
|
||||
If you load scsi_tgt.o first, you can add 'scsi_tdebug=1' to the
|
||||
load line as well.
|
||||
|
||||
This now leaves you with isp loaded, and registered with scsi_target, but
|
||||
with no LUNs enabled.
|
||||
|
||||
D. Do
|
||||
|
||||
scsi_target_ctl enable ispN channel target lun
|
||||
|
||||
where 'N' is the unit you want to enable a lun on (lun 0 must be first),
|
||||
channel the port number (this really applies only to dual bus
|
||||
SCSI cards), target (which is ignored) and lun.
|
||||
|
||||
Use disable to disable a lun. Lun 0 must be last out as it was
|
||||
first in.
|
||||
|
||||
E. Things missing
|
||||
|
||||
The discerning amongst you will note that scsi_target is incomplete
|
||||
at best. That is by design- it's up to *you* to write interesting
|
||||
replacements for it.
|
||||
@@ -0,0 +1,143 @@
|
||||
# $Id: Makefile,v 1.27 2006/12/18 18:24:00 mjacob Exp $
|
||||
#
|
||||
# Qlogic ISP Host Adapter Build File
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense at feral com
|
||||
#
|
||||
#
|
||||
LVERS = $(shell uname -r)
|
||||
LINUX ?= /lib/modules/${LVERS}/build
|
||||
SERNO = $(shell hostid)
|
||||
_SLIST = s/i.86/i386/ -e s/sun4u/sparc64/ -e s/sun4d/sparc/ \
|
||||
-e s/sun4m/sparc/ -e s/sun4c/sparc/ -e s/arm.*/arm/ \
|
||||
-e s/sa110/arm/
|
||||
ARCH := $(shell uname -m | sed -e $(_SLIST))
|
||||
CC = cc
|
||||
XFLAGS =
|
||||
MODV = -DMODVERSIONS
|
||||
MODF = -DMODULE ${MODV}
|
||||
DEFS = -D__KERNEL__ $(TMODE) $(MODF) ${XFLAGS} -DSERNO=\"$(SERNO)\"
|
||||
KMOD = isp_mod.o
|
||||
include Makefile.${ARCH}
|
||||
IFLAGS = -I. -I../common -I../firmware -I${LINUX}/drivers/scsi \
|
||||
-I${LINUX}/include
|
||||
GKCFLAGS+= $(DEFS) $(IFLAGS) -Werror -Wall -Wstrict-prototypes ${KCFLAGS}
|
||||
COMD = ../common
|
||||
ALLSRC = isp_pci.c isp_linux.c isp_cb_ops.c \
|
||||
${COMD}/isp.c ${COMD}/isp_target.c ${COMD}/isp_library.c
|
||||
COM_HDRS= ${COMD}/ispmbox.h ${COMD}/ispvar.h ${COMD}/ispreg.h \
|
||||
${COMD}/isp_library.h ${COMD}/isp_target.h \
|
||||
${COMD}/isp_tpublic.h ${COMD}/isp_stds.h
|
||||
KOBJ = isp_pci.o isp_linux.o isp.o isp_cb_ops.o isp_target.o isp_library.o
|
||||
TOOLS = isp_clrstats isp_debug isp_getrole isp_getstats isp_rescan \
|
||||
isp_lip isp_setrole isp_getpdb isp_gethba isp_struct
|
||||
CFLAGS = -O -I. -I../common
|
||||
LOC_HDRS= isp_linux.h
|
||||
ALL_HDRS= ${LOC_HDRS} ${COM_HDRS}
|
||||
|
||||
VPATH = . ../tools
|
||||
|
||||
|
||||
all: $(KMOD)
|
||||
|
||||
isp_mod.o: ${KOBJ}
|
||||
$(LD) -r -o $@ ${KOBJ}
|
||||
|
||||
isp_pci.o: ./isp_pci.c $(COM_HDRS) $(LOC_HDRS)
|
||||
$(CC) $(GKCFLAGS) -c -o isp_pci.o ./isp_pci.c
|
||||
|
||||
isp.o: ${COMD}/isp.c $(COM_HDRS) $(LOC_HDRS)
|
||||
$(CC) $(GKCFLAGS) -c -o $@ ${COMD}/isp.c
|
||||
|
||||
isp_target.o: ${COMD}/isp_target.c ${COMD}/isp_target.h $(ALL_HDRS)
|
||||
$(CC) $(GKCFLAGS) -c -o $@ ${COMD}/isp_target.c
|
||||
|
||||
isp_library.o: ${COMD}/isp_library.c ${COMD}/isp_library.h $(ALL_HDRS)
|
||||
$(CC) $(GKCFLAGS) -c -o $@ ${COMD}/isp_library.c
|
||||
|
||||
|
||||
isp_linux.o: isp_linux.c $(COM_HDRS) $(LOC_HDRS)
|
||||
$(CC) $(GKCFLAGS) -c -o $@ ./isp_linux.c
|
||||
|
||||
isp_cb_ops.o: isp_cb_ops.c $(COM_HDRS) $(LOC_HDRS)
|
||||
$(CC) $(GKCFLAGS) -c -o $@ ./isp_cb_ops.c
|
||||
|
||||
|
||||
scsi_tgt.o: scsi_target.c scsi_target.h ${ALL_HDRS}
|
||||
$(CC) $(GKCFLAGS) -c -o scsi_target.o scsi_target.c
|
||||
$(LD) -r -o $@ scsi_target.o
|
||||
|
||||
alltgt:
|
||||
$(MAKE) TMODE='-DISP_TARGET_MODE=1 -DISP_DEFAULT_ROLES=ISP_ROLE_NONE ' all
|
||||
|
||||
scsi_target_ctl: scsi_target_ctl.o scsi_target.h
|
||||
$(CC) -o $@ scsi_target_ctl.c
|
||||
|
||||
tgt := KMOD += scsi_tgt.o
|
||||
tgt: scsi_target_ctl scsi_tgt.o alltgt
|
||||
|
||||
tools := CFLAGS += -O -I.
|
||||
tools: ${TOOLS}
|
||||
|
||||
|
||||
tags: FRC
|
||||
ctags *.[ch] ../common/*.[ch]
|
||||
|
||||
etags: FRC
|
||||
etags --declarations --members *.[ch] ../common/*.[ch]
|
||||
|
||||
clean:
|
||||
@touch x.o
|
||||
$(RM) *.o scsi_target_ctl ${TOOLS}
|
||||
|
||||
clobber: clean
|
||||
${RM} tags TAGS
|
||||
|
||||
FRC:
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# $Id: Makefile.alpha,v 1.8 2006/02/17 22:53:51 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense at feral com
|
||||
#
|
||||
KCFLAGS = -fomit-frame-pointer -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 \
|
||||
-Wa,-mev6 -O2 -include ${LINUX}/include/linux/modversions.h
|
||||
@@ -0,0 +1,52 @@
|
||||
# $Id: Makefile.i386,v 1.11 2006/11/16 00:19:47 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense feral com
|
||||
#
|
||||
KCFLAGS = -fno-strict-aliasing -pipe -march=i686 -g -O2 \
|
||||
-include ${LINUX}/include/linux/modversions.h
|
||||
@@ -0,0 +1,55 @@
|
||||
# $Id: Makefile.ppc,v 1.8 2006/02/17 22:53:51 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense feral com
|
||||
#
|
||||
CC=gcc
|
||||
KCFLAGS = -fomit-frame-pointer -fno-strict-aliasing -D__powerpc__ \
|
||||
-fsigned-char -msoft-float -pipe -fno-builtin -ffixed-r2 \
|
||||
-Wno-uninitialized -mmultiple -mstring -O2 \
|
||||
-include ${LINUX}/include/linux/modversions.h
|
||||
@@ -0,0 +1,55 @@
|
||||
# $Id: Makefile.sparc,v 1.8 2006/02/17 22:53:51 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense at feral com
|
||||
#
|
||||
CC=gcc
|
||||
KCFLAGS= -fomit-frame-pointer -fno-strict-aliasing -m32 -pipe -mno-fpu \
|
||||
-fcall-used-g5 -fcall-used-g7 -O2 \
|
||||
-include ${LINUX}/include/linux/modversions.h
|
||||
KMOD = isp_sbus.o
|
||||
@@ -0,0 +1,56 @@
|
||||
# $Id: Makefile.sparc64,v 1.8 2006/02/17 22:53:51 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense at feral com
|
||||
#
|
||||
CC=sparc64-linux-gcc
|
||||
KCFLAGS = -fomit-frame-pointer -fno-strict-aliasing -m64 -pipe -mno-fpu \
|
||||
-mcpu=ultrasparc -mcmodel=medlow -ffixed-g4 -fcall-used-g5 \
|
||||
-fcall-used-g7 -Wno-sign-compare -O2 \
|
||||
-include ${LINUX}/include/linux/modversions.h
|
||||
LDFLAGS=-m elf64_sparc -r
|
||||
@@ -0,0 +1,52 @@
|
||||
# $Id: Makefile.x86_64,v 1.5 2006/02/17 22:53:52 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 2006 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
#
|
||||
# isplicense at feral com
|
||||
#
|
||||
KCFLAGS = -fno-strict-aliasing -fno-common -fomit-frame-pointer -mno-red-zone -mcmodel=kernel -pipe -fno-reorder-blocks -finline-limit=2000 -fno-strength-reduce -Wno-sign-compare -fno-asynchronous-unwind-tables -fno-unit-at-a-time -march=nocona
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,373 @@
|
||||
/*****************************************************************************
|
||||
* QLOGIC LINUX SOFTWARE
|
||||
*
|
||||
* QLogic ISP2x00 device driver ioctl definition file
|
||||
* Copyright (C) 2005 QLogic Corporation
|
||||
* (www.qlogic.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* File Name: exioctln.h
|
||||
|
||||
Rev 24 October 06, 2005 RL
|
||||
- Added reserve internal ioctl command code for future use.
|
||||
|
||||
Rev 23 June 22, 2005 RL
|
||||
- Corrected assignment condition of EXT_ADDR_MODE_OS value.
|
||||
|
||||
Rev 22 February 25, 2005 RL
|
||||
- Added reserve internal ioctl command codes.
|
||||
|
||||
Rev 21 February 1, 2005 RL
|
||||
- Deleted AdapterModel field and bit definition for
|
||||
EXT_LN_DRIVER_DATA.
|
||||
|
||||
Rev 20 December 20, 2004 RL
|
||||
- Decreased MAX_HBA_OS value again.
|
||||
|
||||
Rev 19 September 9, 2004 RL
|
||||
- Added AdapterModel field and bit definition for
|
||||
EXT_LN_DRIVER_DATA.
|
||||
|
||||
Rev 18 August 6, 2004 RL
|
||||
- Added 'Flags' field and bit defines for EXT_LN_DRIVER_DATA.
|
||||
- Corrected UINT64 define to real 64 bit.
|
||||
- Corrected ioctl command value definition so it is
|
||||
the same value in both 32bit and 64bit environments.
|
||||
- Added NFO command values.
|
||||
- Changed EXT_CC_STARTIOCTL to EXT_CC_GET_HBA_CNT.
|
||||
|
||||
Rev 17 August 08, 2003 RL
|
||||
- Decreased MAX_HBA_OS value to both decrease wasted space
|
||||
in shared mem so it can be used to store other data, and
|
||||
to decrease unnecesary loops checking through all adapters.
|
||||
|
||||
Rev 16 July 31, 2003 RL
|
||||
- Added definitions for Status field in discovered target
|
||||
structure.
|
||||
- Updated ioctl command value assignment on PPC64 so this
|
||||
file can be shared with API lib.
|
||||
|
||||
Rev 15 June 03, 2003 RL
|
||||
- Modified ioctl command code value assignment so it also
|
||||
works on PPC64.
|
||||
|
||||
Rev 14 February 25, 2003 RL
|
||||
- Added EXT_CC_DRIVER_SPECIFIC ioctl command to return
|
||||
some driver specific data that can be used by API library
|
||||
to determine how to maintain backward compatibility
|
||||
of certain features.
|
||||
|
||||
Rev 13 January 31, 2003 RL
|
||||
- Changed the value of EXT_DEF_USE_HBASELECT to avoid
|
||||
conflicting with older implementation of FO API lib.
|
||||
|
||||
Rev 12 January 20, 2003 RL
|
||||
- Added EXT_DEF_USE_HBASELECT definition for use by
|
||||
the SETINSTANCE command.
|
||||
|
||||
Rev 11 December 10, 2002 RL
|
||||
- Added EXT_CC_SEND_ELS_PASSTHRU_OS definition.
|
||||
|
||||
Rev 10 October 26, 2001 RL
|
||||
- Corrected MAX_HBA, MAX_TARGET and MAX_LUN values to 255.
|
||||
|
||||
Rev 9 July 26, 2001 RL
|
||||
- Added definition of signed types.
|
||||
|
||||
Rev 8 July 05, 2001 RL
|
||||
- Redefined ioctl command values.
|
||||
|
||||
Rev 7 Nov 06, 2000 BN
|
||||
- Added EXT_DEF_MAX_AEN_QUEUE_OS define
|
||||
- Added define for handle_hba_t
|
||||
|
||||
Rev 6 Oct 25, 2000 BN
|
||||
- Added EXT_CC_DRIVER_PROP_OS define
|
||||
|
||||
Rev 5 Oct 25, 2000 BN
|
||||
- Redo the copyright header and add AEN details
|
||||
|
||||
Rev 4 Oct 23, 2000 BN
|
||||
- Added definition for BOOLEAN
|
||||
|
||||
Rev 3 Oct 23, 2000 BN
|
||||
- Added definitions for EXT_ADDR_MODE_OS
|
||||
and also include of <linux/ioctl.h>
|
||||
|
||||
Rev 2 Oct 18, 2000 BN
|
||||
- Enable API Exention support
|
||||
|
||||
Rev 1 Original version Sep 7, 2000 BN
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _EXIOCT_LN_H_
|
||||
#define _EXIOCT_LN_H_
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#ifdef APILIB
|
||||
#include <stdint.h>
|
||||
#include <linux/types.h>
|
||||
#include <bits/wordsize.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef INT8
|
||||
#define INT8 int8_t
|
||||
#endif
|
||||
|
||||
#ifndef INT16
|
||||
#define INT16 int16_t
|
||||
#endif
|
||||
|
||||
#ifndef INT32
|
||||
#define INT32 int32_t
|
||||
#endif
|
||||
|
||||
#ifndef UINT8
|
||||
#define UINT8 uint8_t
|
||||
#endif
|
||||
|
||||
#ifndef UINT16
|
||||
#define UINT16 uint16_t
|
||||
#endif
|
||||
|
||||
#ifndef UINT32
|
||||
#define UINT32 uint32_t
|
||||
#endif
|
||||
|
||||
#ifndef UINT64
|
||||
#define UINT64 uint64_t
|
||||
#endif
|
||||
|
||||
#ifndef UINT64_O
|
||||
#define UINT64_O void * /* old define for FC drivers */
|
||||
#endif
|
||||
|
||||
#ifndef BOOLEAN
|
||||
#define BOOLEAN uint8_t
|
||||
#endif
|
||||
|
||||
#ifndef HANDLE
|
||||
#define HANDLE int
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
#define EXT_ADDR_MODE_OS EXT_DEF_ADDR_MODE_64
|
||||
#else
|
||||
#define EXT_ADDR_MODE_OS EXT_DEF_ADDR_MODE_32
|
||||
#endif
|
||||
|
||||
|
||||
#define QLMULTIPATH_MAGIC 'y'
|
||||
|
||||
#define _QLBUILD /* for exioct.h to enable include of qinsdmgt.h */
|
||||
|
||||
|
||||
#define EXT_DEF_MAX_HBA_OS 31 /* 0x1F */
|
||||
#define EXT_DEF_MAX_HBAS 32 /* 0 - 0x1F */
|
||||
|
||||
#define EXT_DEF_MAX_BUS_OS 1
|
||||
|
||||
#define EXT_DEF_MAX_TARGET_OS 255 /* 0xFE */
|
||||
#define EXT_DEF_MAX_TARGETS 256 /* 0 - 0xFE */
|
||||
|
||||
#define EXT_DEF_MAX_LUN_OS 255 /* 0xFE */
|
||||
#define EXT_DEF_MAX_LUNS 256 /* 0 - 0xFE */
|
||||
|
||||
#define EXT_DEF_MAX_AEN_QUEUE_OS 64
|
||||
#define EXT_DEF_MAX_TGTEV_QUEUE_OS 256 /* max tgts in driver */
|
||||
#define EXT_DEF_MAX_NFOEV_QUEUE_OS 256
|
||||
|
||||
#define EXT_DEF_FC_HEADER_LEN 24
|
||||
#define EXT_DEF_ELS_RJT_LENGTH 0x08 /* 8 */
|
||||
#define EXT_DEF_ELS_RPS_ACC_LENGTH 0x40 /* 64 */
|
||||
#define EXT_DEF_ELS_RLS_ACC_LENGTH 0x1C /* 28 */
|
||||
|
||||
#define EXT_DEF_USE_HBASELECT 0x02 /* bit 1: HbaSelect field now
|
||||
* used to specify destination
|
||||
* HBA of each command.
|
||||
* SetInstance cmd is now
|
||||
* issued only once during
|
||||
* API initialization.
|
||||
*/
|
||||
|
||||
/* target status flags */
|
||||
#define EXT_DEF_TGTSTAT_OFFLINE 0x01
|
||||
#define EXT_DEF_TGTSTAT_IN_CFG 0x02
|
||||
|
||||
#define EXT_DEF_REGULAR_SIGNATURE "QLOGIC"
|
||||
|
||||
|
||||
/*****************/
|
||||
/* Command codes */
|
||||
/*****************/
|
||||
#define QL_IOCTL_BASE(idx) \
|
||||
_IOWR(QLMULTIPATH_MAGIC, idx, EXT_IOCTL)
|
||||
|
||||
#define QL_IOCTL_CMD(idx) QL_IOCTL_BASE(idx)
|
||||
|
||||
/***************************************************************
|
||||
* These are regular/external command codes, starting from 0.
|
||||
* The regular command code end index must be updated whenever
|
||||
* adding new commands.
|
||||
***************************************************************/
|
||||
#define EXT_DEF_LN_REG_CC_START_IDX 0x00 /* reg cmd start index */
|
||||
|
||||
#define EXT_CC_QUERY_OS /* QUERY */ \
|
||||
QL_IOCTL_CMD(0x00)
|
||||
#define EXT_CC_SEND_FCCT_PASSTHRU_OS /* FCCT_PASSTHRU */ \
|
||||
QL_IOCTL_CMD(0x01)
|
||||
#define EXT_CC_REG_AEN_OS /* REG_AEN */ \
|
||||
QL_IOCTL_CMD(0x02)
|
||||
#define EXT_CC_GET_AEN_OS /* GET_AEN */ \
|
||||
QL_IOCTL_CMD(0x03)
|
||||
#define EXT_CC_SEND_ELS_RNID_OS /* SEND_ELS_RNID */ \
|
||||
QL_IOCTL_CMD(0x04)
|
||||
#define EXT_CC_SCSI_PASSTHRU_OS /* SCSI_PASSTHRU */ \
|
||||
QL_IOCTL_CMD(0x05)
|
||||
|
||||
#define EXT_CC_GET_DATA_OS /* GET_DATA */ \
|
||||
QL_IOCTL_CMD(0x06)
|
||||
#define EXT_CC_SET_DATA_OS /* SET_DATA */ \
|
||||
QL_IOCTL_CMD(0x07)
|
||||
|
||||
#define EXT_DEF_LN_REG_CC_END_IDX 0x07 /* reg cmd end index */
|
||||
|
||||
/*****************************************
|
||||
* Following are internal command codes.
|
||||
* See inioct.h.
|
||||
*****************************************/
|
||||
#define EXT_DEF_LN_INT_CC_START_IDX 0x08 /* int cmd start index */
|
||||
#define EXT_CC_RESERVED0A_OS \
|
||||
QL_IOCTL_CMD(0x08)
|
||||
#define EXT_CC_RESERVED0B_OS \
|
||||
QL_IOCTL_CMD(0x09)
|
||||
|
||||
#define EXT_CC_RESERVED0C_OS \
|
||||
QL_IOCTL_CMD(0x0a)
|
||||
#define EXT_CC_RESERVED0D_OS \
|
||||
QL_IOCTL_CMD(0x0b)
|
||||
|
||||
#define EXT_CC_RESERVED0E_OS \
|
||||
QL_IOCTL_CMD(0x0c)
|
||||
#define EXT_CC_RESERVED0F_OS \
|
||||
QL_IOCTL_CMD(0x0d)
|
||||
|
||||
#define EXT_CC_RESERVED0G_OS \
|
||||
QL_IOCTL_CMD(0x0e)
|
||||
#define EXT_CC_RESERVED0H_OS \
|
||||
QL_IOCTL_CMD(0x0f)
|
||||
|
||||
#define EXT_CC_RESERVED0I_OS \
|
||||
QL_IOCTL_CMD(0x10)
|
||||
#define EXT_CC_RESERVED0J_OS \
|
||||
QL_IOCTL_CMD(0x11)
|
||||
#define EXT_CC_RESERVED0K_OS \
|
||||
QL_IOCTL_CMD(0x12)
|
||||
#define EXT_CC_RESERVED0L_OS \
|
||||
QL_IOCTL_CMD(0x13)
|
||||
|
||||
#define EXT_CC_RESERVED0Z_OS \
|
||||
QL_IOCTL_CMD(0x21)
|
||||
|
||||
#define EXT_DEF_LN_INT_CC_END_IDX 0x21 /* supported int cmd end idx */
|
||||
|
||||
/********************************************************/
|
||||
/* These are additional regular/external command codes. */
|
||||
/********************************************************/
|
||||
#define EXT_DEF_LN_ADD_CC_START_IDX 0x30 /* additional cmd start index */
|
||||
#define EXT_CC_SEND_ELS_PASSTHRU_OS \
|
||||
QL_IOCTL_CMD(0x30)
|
||||
#define EXT_DEF_LN_ADD_CC_END_IDX 0x30 /* additional cmd end index */
|
||||
|
||||
|
||||
/********************************************************
|
||||
* NextGen Failover (NFO) ioctl command codes range from
|
||||
* 0x37 to 0x4f. See qlnfoln.h
|
||||
********************************************************/
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Failover ioctl command codes range from 0xc0 to 0xdf.
|
||||
* See definition in qlfoln.h.
|
||||
********************************************************/
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* These are Linux driver implementation specific commands. Values */
|
||||
/* start from highest possible value and in decreasing order. */
|
||||
/*******************************************************************/
|
||||
#define EXT_DEF_LN_SPC_CC_START_IDX 0xff /* LN specific cmd start idx */
|
||||
|
||||
#define EXT_CC_GET_HBA_CNT /* GET_HBA_CNT */ \
|
||||
QL_IOCTL_CMD(0xff)
|
||||
#define EXT_CC_SETINSTANCE /* SETINSTANCE */ \
|
||||
QL_IOCTL_CMD(0xfe)
|
||||
#define EXT_CC_WWPN_TO_SCSIADDR /* WWPN_TO_SCSIADDR */ \
|
||||
QL_IOCTL_CMD(0xfd)
|
||||
#define EXT_CC_DRIVER_SPECIFIC /* DRIVER_SPECIFIC */ \
|
||||
QL_IOCTL_CMD(0xfc)
|
||||
|
||||
#define EXT_DEF_LN_SPC_CC_END_IDX 0xfc /* LN specific cmd end idx */
|
||||
|
||||
|
||||
/*
|
||||
* Response struct definition
|
||||
*/
|
||||
typedef struct _EXT_LN_DRV_VERSION {
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
UINT8 Patch;
|
||||
UINT8 Beta;
|
||||
UINT8 Reserved[4];
|
||||
} EXT_LN_DRV_VERSION; /* 8 */
|
||||
|
||||
typedef struct _EXT_LN_DRIVER_DATA {
|
||||
EXT_LN_DRV_VERSION DrvVer; /* 8 */
|
||||
UINT32 Flags; /* 4 */
|
||||
UINT32 Reserved[13]; /* 52 */
|
||||
} EXT_LN_DRIVER_DATA, *PEXT_LN_DRIVER_DATA; /* 64 */
|
||||
|
||||
/* Bit defines for the Flags field */
|
||||
#define EXT_DEF_NGFO_CAPABLE 0x0001 /* bit 0: failover capable */
|
||||
#define EXT_DEF_NGFO_ENABLED 0x0002 /* bit 1: failover enabled */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we almost follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-indent-level: 2
|
||||
* c-brace-imaginary-offset: 0
|
||||
* c-brace-offset: -2
|
||||
* c-argdecl-indent: 2
|
||||
* c-label-offset: -2
|
||||
* c-continued-statement-offset: 4
|
||||
* c-continued-brace-offset: 0
|
||||
* indent-tabs-mode: nil
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif /* _EXIOCT_LN_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,228 @@
|
||||
/* $Id: isp_ioctl.h,v 1.18 2007/05/31 18:35:28 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* ioctl definitions for Qlogic FC/SCSI HBA driver
|
||||
*/
|
||||
#define ISP_IOC (0x4D4A5100) /* 'MJQ' << 8 */
|
||||
|
||||
/*
|
||||
* This ioctl sets/retrieves the debugging level for this hba instance.
|
||||
* Note that this is not a simple integer level- see ispvar.h for definitions.
|
||||
*
|
||||
* The arguments is a pointer to an integer with the new debugging level.
|
||||
* The old value is written into this argument.
|
||||
*/
|
||||
|
||||
#define ISP_SDBLEV (ISP_IOC | 1)
|
||||
|
||||
/*
|
||||
* This ioctl resets the HBA. Use with caution.
|
||||
*/
|
||||
#define ISP_RESETHBA (ISP_IOC | 2)
|
||||
|
||||
/*
|
||||
* This ioctl performs a fibre chanel rescan.
|
||||
*/
|
||||
#define ISP_RESCAN (ISP_IOC | 3)
|
||||
|
||||
/*
|
||||
* This ioctl performs a reset and then will set the adapter to the
|
||||
* role that was passed in (the old role will be returned). It almost
|
||||
* goes w/o saying: use with caution.
|
||||
*/
|
||||
#define ISP_SETROLE (ISP_IOC | 4)
|
||||
|
||||
#define ISP_ROLE_NONE 0x0
|
||||
#define ISP_ROLE_TARGET 0x1
|
||||
#define ISP_ROLE_INITIATOR 0x2
|
||||
#define ISP_ROLE_BOTH (ISP_ROLE_TARGET|ISP_ROLE_INITIATOR)
|
||||
#ifndef ISP_DEFAULT_ROLES
|
||||
#define ISP_DEFAULT_ROLES ISP_ROLE_BOTH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the current adapter role
|
||||
*/
|
||||
#define ISP_GETROLE (ISP_IOC | 5)
|
||||
|
||||
/*
|
||||
* Get/Clear Stats
|
||||
*/
|
||||
#define ISP_STATS_VERSION 0
|
||||
typedef struct {
|
||||
uint8_t isp_stat_version;
|
||||
uint8_t isp_type; /* (ro) reflects chip type */
|
||||
uint8_t isp_revision; /* (ro) reflects chip version */
|
||||
uint8_t unused1;
|
||||
uint32_t unused2;
|
||||
/*
|
||||
* Statistics Counters
|
||||
*/
|
||||
#define ISP_NSTATS 16
|
||||
#define ISP_INTCNT 0
|
||||
#define ISP_INTBOGUS 1
|
||||
#define ISP_INTMBOXC 2
|
||||
#define ISP_INGOASYNC 3
|
||||
#define ISP_RSLTCCMPLT 4
|
||||
#define ISP_FPHCCMCPLT 5
|
||||
#define ISP_RSCCHIWAT 6
|
||||
#define ISP_FPCCHIWAT 7
|
||||
uint64_t isp_stats[ISP_NSTATS];
|
||||
} isp_stats_t;
|
||||
|
||||
#define ISP_GET_STATS (ISP_IOC | 6)
|
||||
#define ISP_CLR_STATS (ISP_IOC | 7)
|
||||
|
||||
/*
|
||||
* Initiate a LIP
|
||||
*/
|
||||
#define ISP_FC_LIP (ISP_IOC | 8)
|
||||
|
||||
/*
|
||||
* Return the Port Database structure for the named device, or ENODEV if none.
|
||||
* Caller fills in virtual loopid (0..255/2048), aka 'target'. The driver returns
|
||||
* ENODEV (if nothing valid there) or the actual loopid (for local loop devices
|
||||
* only), 24 bit Port ID and Node and Port WWNs.
|
||||
*/
|
||||
struct isp_fc_device {
|
||||
uint32_t loopid; /* 0..255/2048 */
|
||||
uint32_t : 6,
|
||||
role : 2,
|
||||
portid : 24; /* 24 bit Port ID */
|
||||
uint64_t node_wwn;
|
||||
uint64_t port_wwn;
|
||||
};
|
||||
#define ISP_FC_GETDINFO (ISP_IOC | 9)
|
||||
|
||||
/*
|
||||
* Get F/W crash dump
|
||||
*/
|
||||
#define ISP_GET_FW_CRASH_DUMP (ISP_IOC | 10)
|
||||
#define ISP_FORCE_CRASH_DUMP (ISP_IOC | 11)
|
||||
|
||||
/*
|
||||
* Get information about this Host Adapter, including current connection
|
||||
* topology and capabilities.
|
||||
*/
|
||||
struct isp_hba_device {
|
||||
uint32_t
|
||||
: 8,
|
||||
: 4,
|
||||
fc_speed : 4, /* Gbps */
|
||||
: 2,
|
||||
fc_class2 : 1,
|
||||
fc_ip_supported : 1,
|
||||
fc_scsi_supported : 1,
|
||||
fc_topology : 3,
|
||||
fc_loopid : 8;
|
||||
uint8_t fc_fw_major;
|
||||
uint8_t fc_fw_minor;
|
||||
uint8_t fc_fw_micro;
|
||||
uint8_t fc_nchannels;
|
||||
uint64_t nvram_node_wwn;
|
||||
uint64_t nvram_port_wwn;
|
||||
uint64_t active_node_wwn;
|
||||
uint64_t active_port_wwn;
|
||||
};
|
||||
|
||||
#define ISP_TOPO_UNKNOWN 0 /* connection topology unknown */
|
||||
#define ISP_TOPO_FCAL 1 /* private or PL_DA */
|
||||
#define ISP_TOPO_LPORT 2 /* public loop */
|
||||
#define ISP_TOPO_NPORT 3 /* N-port */
|
||||
#define ISP_TOPO_FPORT 4 /* F-port */
|
||||
|
||||
#define ISP_FC_GETHINFO (ISP_IOC|12)
|
||||
|
||||
/*
|
||||
* Set Active WWNN/WWPN
|
||||
*/
|
||||
struct isp_wwn {
|
||||
uint32_t _reserved[2];
|
||||
uint64_t node_wwn;
|
||||
uint64_t port_wwn;
|
||||
};
|
||||
|
||||
#define ISP_FC_SET_WWN (ISP_IOC | 20)
|
||||
|
||||
/*
|
||||
* Various Reset Goodies
|
||||
*/
|
||||
struct isp_fc_tsk_mgmt {
|
||||
uint32_t loopid; /* 0..255/2048 */
|
||||
uint32_t lun;
|
||||
enum {
|
||||
IPT_CLEAR_ACA,
|
||||
IPT_TARGET_RESET,
|
||||
IPT_LUN_RESET,
|
||||
IPT_CLEAR_TASK_SET,
|
||||
IPT_ABORT_TASK_SET
|
||||
} action;
|
||||
};
|
||||
#define ISP_TSK_MGMT (ISP_IOC | 21)
|
||||
|
||||
/*
|
||||
* Just gimme a list of WWPNs that are logged into us.
|
||||
*/
|
||||
#define ISP_DL_MAX 256
|
||||
typedef struct {
|
||||
uint16_t count;
|
||||
uint16_t channel;
|
||||
uint64_t wwpns[1];
|
||||
} isp_dlist_t;
|
||||
#define ISP_FC_GETDLIST (ISP_IOC | 22)
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
||||
/* $Id: scsi_target.h,v 1.26 2007/03/10 01:56:34 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* SCSI Target Control Port
|
||||
*/
|
||||
#define SCSI_TARGET "scsi_target"
|
||||
#define SCSI_TARGET_DEV "/proc/" SCSI_TARGET
|
||||
|
||||
/*
|
||||
* SCSI Target Stub Driver for Linux for a memory or user agent disk device.
|
||||
* Ioctl Definitions File.
|
||||
*/
|
||||
|
||||
#define _SI ('e' << 8)
|
||||
|
||||
/*
|
||||
* Set new debugging level (get previous) (int argument).
|
||||
*/
|
||||
#define SC_DEBUG (_SI | 0)
|
||||
|
||||
/*
|
||||
* Enable/Disable lun
|
||||
*/
|
||||
typedef struct {
|
||||
char hba_name_unit[16]; /* e.g., "isp0" */
|
||||
uint64_t nbytes; /* disk size, in bytes */
|
||||
uint16_t lun; /* lun to map it to */
|
||||
uint16_t flags; /* flags */
|
||||
} sc_enable_t;
|
||||
#define SC_EF_OVERCOMMIT 0x01 /* allow overcommit */
|
||||
|
||||
#define SC_ENABLE_LUN (_SI | 1)
|
||||
#define SC_DISABLE_LUN (_SI | 2)
|
||||
|
||||
/*
|
||||
* Overcommit disks have to have data written to backing store
|
||||
* and read from it.
|
||||
*/
|
||||
typedef struct {
|
||||
char hba_name_unit[16]; /* e.g., "isp0" */
|
||||
uint16_t lun; /* lun */
|
||||
uint16_t : 14,
|
||||
sync : 1, /* (implied) sync after write */
|
||||
read : 1; /* read (from target to initiator) flag */
|
||||
void * tag; /* id tag for this command */
|
||||
void * addr; /* user buffer address */
|
||||
uint32_t len; /* user buffer length */
|
||||
uint64_t off; /* disk offset */
|
||||
uint32_t amt; /* this command's actual data length */
|
||||
int err; /* from user app */
|
||||
} sc_io_t;
|
||||
#define SC_GET_IO (_SI | 3)
|
||||
#define SC_PUT_IO (_SI | 4)
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
@@ -0,0 +1,267 @@
|
||||
/* $Id: scsi_target_ctl.c,v 1.18 2007/03/10 01:56:34 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* SCSI Target Mode "stub" control program for Linux.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "scsi_target.h"
|
||||
|
||||
#define dprintf if (debug) printf
|
||||
|
||||
const char usage[] = "usage: %s\n\
|
||||
scsi_target_ctl debug level\n\
|
||||
scsi_target_ctl enable hba-name-unit nbytes lun [ overcommit-file ]\n\
|
||||
scsi_target_ctl disable hba-name-unit lun\n";
|
||||
|
||||
static uint64_t szarg(char *);
|
||||
static void ioloop(int, int, char *, uint16_t);
|
||||
static int debug;
|
||||
|
||||
int
|
||||
main(int a, char **v)
|
||||
{
|
||||
union {
|
||||
sc_enable_t _x;
|
||||
int _y;
|
||||
} x;
|
||||
int iofd = -1, fd, action, dd = 0;
|
||||
char *progname;
|
||||
|
||||
if (v) {
|
||||
progname = v[0];
|
||||
if (progname == NULL) {
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
return (1);
|
||||
}
|
||||
|
||||
debug = getenv("DEBUG") != NULL;
|
||||
|
||||
if (a < 3 || a > 6) {
|
||||
usage:
|
||||
fprintf(stderr, usage, progname);
|
||||
return (1);
|
||||
}
|
||||
|
||||
memset(&x, 0, sizeof (x));
|
||||
if (strcmp(v[1], "enable") == 0) {
|
||||
if (a < 5) {
|
||||
goto usage;
|
||||
}
|
||||
action = SC_ENABLE_LUN;
|
||||
strncpy(x._x.hba_name_unit, v[2], sizeof (x._x.hba_name_unit));
|
||||
x._x.nbytes = szarg(v[3]);
|
||||
x._x.lun = atoi(v[4]);
|
||||
if (a == 6) {
|
||||
iofd = open(v[5], O_RDWR);
|
||||
if (iofd < 0) {
|
||||
perror(v[5]);
|
||||
return (1);
|
||||
}
|
||||
dprintf("opened %s to back size 0x%016llx bytes\n", v[5], (unsigned long long) x._x.nbytes);
|
||||
x._x.flags = SC_EF_OVERCOMMIT;
|
||||
}
|
||||
} else if (strcmp(v[1], "disable") == 0) {
|
||||
if (a != 4) {
|
||||
goto usage;
|
||||
}
|
||||
action = SC_DISABLE_LUN;
|
||||
strncpy(x._x.hba_name_unit, v[2], sizeof (x._x.hba_name_unit));
|
||||
x._x.lun = atoi(v[3]);
|
||||
} else if (strcmp(v[1], "debug") == 0) {
|
||||
if (a != 3) {
|
||||
goto usage;
|
||||
}
|
||||
action = SC_DEBUG;
|
||||
dd = x._y = atoi(v[2]);
|
||||
} else {
|
||||
goto usage;
|
||||
}
|
||||
|
||||
|
||||
if ((fd = open(SCSI_TARGET_DEV, O_RDWR)) < 0) {
|
||||
perror(SCSI_TARGET_DEV);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (ioctl(fd, action, &x) < 0) {
|
||||
perror(v[1]);
|
||||
return (2);
|
||||
}
|
||||
if (action == SC_ENABLE_LUN && iofd != -1) {
|
||||
ioloop(fd, iofd, x._x.hba_name_unit, x._x.lun);
|
||||
}
|
||||
if (action == SC_DEBUG) {
|
||||
printf("old debug level: %d; new debug level %d\n", x._y, dd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
szarg(char *n)
|
||||
{
|
||||
uint64_t result;
|
||||
char *q = n;
|
||||
|
||||
while (isxdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
result = (uint64_t) strtoull(n, NULL, 0);
|
||||
if (*q == '\0') {
|
||||
return (result);
|
||||
}
|
||||
if (strcasecmp(q, "kib") == 0) {
|
||||
result <<= 10;
|
||||
} else if (strcasecmp(q, "mib") == 0) {
|
||||
result <<= 20;
|
||||
} else if (strcasecmp(q, "gib") == 0) {
|
||||
result <<= 30;
|
||||
} else if (strcasecmp(q, "tib") == 0) {
|
||||
result <<= 40;
|
||||
} else if (strcasecmp(q, "pib") == 0) {
|
||||
result <<= 50;
|
||||
} else if (strcasecmp(q, "k") == 0) {
|
||||
result <<= 10;
|
||||
} else if (strcasecmp(q, "m") == 0) {
|
||||
result <<= 20;
|
||||
} else if (strcasecmp(q, "g") == 0) {
|
||||
result <<= 30;
|
||||
} else if (strcasecmp(q, "t") == 0) {
|
||||
result <<= 40;
|
||||
} else if (strcasecmp(q, "p") == 0) {
|
||||
result <<= 50;
|
||||
} else if (strcasecmp(q, "kb") == 0) {
|
||||
result *= 1000;
|
||||
} else if (strcasecmp(q, "mb") == 0) {
|
||||
result *= 1000000;
|
||||
} else if (strcasecmp(q, "gb") == 0) {
|
||||
result *= 1000000000ULL;
|
||||
} else if (strcasecmp(q, "tb") == 0) {
|
||||
result *= 1000000000000ULL;
|
||||
} else if (strcasecmp(q, "pb") == 0) {
|
||||
result *= 1000000000000000ULL;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
ioloop(int fd, int iofd, char *hba, uint16_t lun)
|
||||
{
|
||||
sc_io_t sc;
|
||||
off_t off;
|
||||
int amt;
|
||||
void *buffer = valloc(4 << 20);
|
||||
|
||||
for (;;) {
|
||||
memset(&sc, 0, sizeof (sc));
|
||||
strcpy(sc.hba_name_unit, hba);
|
||||
sc.lun = lun;
|
||||
sc.addr = buffer;
|
||||
sc.len = 4 << 20;
|
||||
if (ioctl(fd, SC_GET_IO, &sc) < 0) {
|
||||
if (errno == EINTR || errno == ENOENT) {
|
||||
continue;
|
||||
}
|
||||
perror("SC_GET_IO");
|
||||
break;
|
||||
}
|
||||
off = (off_t) sc.off;
|
||||
if (lseek(iofd, off, SEEK_SET) != off) {
|
||||
perror("lseek");
|
||||
break;
|
||||
}
|
||||
if (sc.read) {
|
||||
amt = read(iofd, sc.addr, sc.amt);
|
||||
dprintf(" read %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt);
|
||||
} else {
|
||||
amt = write(iofd, sc.addr, sc.amt);
|
||||
dprintf("write %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt);
|
||||
if (sc.sync) {
|
||||
if (fdatasync(iofd) < 0) {
|
||||
sc.err = errno;
|
||||
perror("FDATASYNC");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (amt < 0) {
|
||||
perror(sc.read? "read" : "write");
|
||||
sc.err = errno;
|
||||
sc.len = 0;
|
||||
} else {
|
||||
sc.len = amt;
|
||||
}
|
||||
if (ioctl(fd, SC_PUT_IO, &sc) < 0) {
|
||||
perror("SC_PUT_IO");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
Reference in New Issue
Block a user