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:
Vladislav Bolkhovitin
2007-06-25 16:32:46 +00:00
parent 5a261fcdd6
commit 451443a6c8
47 changed files with 106062 additions and 0 deletions
+53
View File
@@ -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
+15
View File
@@ -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
+30
View File
@@ -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.
------------------------------------------------------------------------------
+48
View File
@@ -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
+8340
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+252
View File
@@ -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 */
+239
View File
@@ -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
+973
View File
@@ -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 */
+456
View File
@@ -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
+649
View File
@@ -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)
+304
View File
@@ -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
+61
View File
@@ -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:
+63
View File
@@ -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
+13
View File
@@ -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.
+52
View File
@@ -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.
+143
View File
@@ -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:
+52
View File
@@ -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
+52
View File
@@ -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
+55
View File
@@ -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
+55
View File
@@ -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
+56
View File
@@ -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
+52
View File
@@ -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
+373
View File
@@ -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
+228
View File
@@ -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
+109
View File
@@ -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
*/
+267
View File
@@ -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
*/