summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/isp/isp.c183
-rw-r--r--sys/dev/isp/isp_freebsd.c58
-rw-r--r--sys/dev/isp/isp_freebsd.h4
-rw-r--r--sys/dev/isp/isp_inline.h299
-rw-r--r--sys/dev/isp/isp_ioctl.h41
-rw-r--r--sys/dev/isp/isp_pci.c28
-rw-r--r--sys/dev/isp/isp_sbus.c3
-rw-r--r--sys/dev/isp/isp_target.c341
-rw-r--r--sys/dev/isp/isp_target.h134
-rw-r--r--sys/dev/isp/isp_tpublic.h237
-rw-r--r--sys/dev/isp/ispmbox.h41
-rw-r--r--sys/dev/isp/ispreg.h21
-rw-r--r--sys/dev/isp/ispvar.h42
13 files changed, 1016 insertions, 416 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index cc0c3c1ddca5..a9666e9e51ea 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -1,10 +1,8 @@
-/* $FreeBSD$ */
/*-
* Machine and OS Independent (well, as best as possible)
* code for the Qlogic ISP SCSI adapters.
*
- * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
- * Feral Software
+ * Copyright (c) 1997-2006 by Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +41,8 @@
#include <dev/ic/isp_netbsd.h>
#endif
#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
#include <dev/isp/isp_freebsd.h>
#endif
#ifdef __OpenBSD__
@@ -95,7 +95,7 @@ static const char xact3[] =
static const char pskip[] =
"SCSI phase skipped for target %d.%d.%d";
static const char topology[] =
- "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
+ "Loop ID %d, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
static const char swrej[] =
"Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
static const char finmsg[] =
@@ -165,6 +165,7 @@ isp_reset(struct ispsoftc *isp)
char *btype = "????";
isp->isp_state = ISP_NILSTATE;
+ MEMZERO(&mbs, sizeof (mbs));
/*
* Basic types (SCSI, FibreChannel and PCI or SBus)
@@ -252,6 +253,12 @@ isp_reset(struct ispsoftc *isp)
case ISP_HA_FC_2312:
btype = "2312";
break;
+ case ISP_HA_FC_2322:
+ btype = "2322";
+ break;
+ case ISP_HA_FC_2422:
+ btype = "2422";
+ break;
default:
break;
}
@@ -677,6 +684,15 @@ again:
mbs.param[0] = MBOX_EXEC_FIRMWARE;
mbs.param[1] = code_org;
+ if (IS_2322(isp) || IS_24XX(isp)) {
+ if (isp->isp_loaded_fw) {
+ mbs.param[2] = 1;
+ } else {
+ mbs.param[2] = 0;
+ }
+ mbs.obits |= 2;
+ }
+
isp_mboxcmd(isp, &mbs, MBLOGNONE);
/*
* Give it a chance to start.
@@ -746,9 +762,8 @@ again:
isp_prt(isp, ISP_LOGDEBUG0,
"Firmware Attributes = 0x%x", mbs.param[6]);
}
- if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
- isp_prt(isp, ISP_LOGCONFIG,
- "Installed in 64-Bit PCI slot");
+ if (IS_2KLOGIN(isp)) {
+ isp_prt(isp, ISP_LOGCONFIG, "2K Logins Supported");
}
}
@@ -869,6 +884,7 @@ isp_scsi_init(struct ispsoftc *isp)
* Set Retry Delay and Count.
* You set both channels at the same time.
*/
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SET_RETRY_COUNT;
mbs.param[1] = sdp_chan0->isp_retry_count;
mbs.param[2] = sdp_chan0->isp_retry_delay;
@@ -1048,6 +1064,7 @@ isp_scsi_channel_init(struct ispsoftc *isp, int channel)
/*
* Set (possibly new) Initiator ID.
*/
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
isp_mboxcmd(isp, &mbs, MBLOGALL);
@@ -1257,9 +1274,9 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_hardaddr = loopid;
if (icbp->icb_hardaddr >= 125) {
/*
- * We end up with a Loop ID of 255 for F-Port topologies
+ * We end up with these Loop IDs for F-Port topologies
*/
- if (icbp->icb_hardaddr != 255) {
+ if (icbp->icb_hardaddr != 0xff || icbp->icb_hardaddr != 0x800) {
isp_prt(isp, ISP_LOGERR,
"bad hard address %u- resetting to zero",
icbp->icb_hardaddr);
@@ -1354,8 +1371,10 @@ isp_fibre_init(struct ispsoftc *isp)
#endif
#endif
+ MEMZERO(&mbs, sizeof (mbs));
+
/*
- * For 22XX > 2.1.26 && 23XX, set someoptions.
+ * For 22XX > 2.1.26 && 23XX, set some options.
* XXX: Probably okay for newer 2100 f/w too.
*/
if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
@@ -1457,6 +1476,7 @@ isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
fcparam *fcp = (fcparam *) isp->isp_param;
mbreg_t mbs;
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
mbs.param[1] = 0;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -1498,8 +1518,14 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
fcparam *fcp = (fcparam *) isp->isp_param;
mbreg_t mbs;
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_PORT_DB;
- mbs.param[1] = id << 8;
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = id;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = id << 8;
+ }
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
@@ -1528,10 +1554,18 @@ isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
u_int64_t wwn = 0;
mbreg_t mbs;
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_PORT_NAME;
- mbs.param[1] = loopid << 8;
- if (nodename)
- mbs.param[1] |= 1;
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = loopid;
+ if (nodename)
+ mbs.param[10] = 1;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = loopid << 8;
+ if (nodename)
+ mbs.param[1] |= 1;
+ }
isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
wwn =
@@ -1647,6 +1681,7 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
/*
* Get our Loop ID (if possible). We really need to have it.
*/
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_LOOP_ID;
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
@@ -1661,7 +1696,11 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
} else {
fcp->isp_topo = TOPO_NL_PORT;
}
- fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
+ /*
+ * XXX: We can get the AL_PA (low 8 bits) from here.
+ * XXX: Where do we get the upper 16 bits?
+ */
+ fcp->isp_portid = mbs.param[2] & 0xff;
/*
* Check to see if we're on a fabric by trying to see if we
@@ -1752,7 +1791,7 @@ not_on_fabric:
}
}
- isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
+ isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid,
fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
/*
@@ -1966,8 +2005,14 @@ isp_pdb_sync(struct ispsoftc *isp)
if (lp->loggedin) {
if (lp->force_logout ||
isp_getpdb(isp, lp->loopid, &pdb) == 0) {
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_FABRIC_LOGOUT;
- mbs.param[1] = lp->loopid << 8;
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = lp->loopid;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = lp->loopid << 8;
+ }
mbs.param[2] = 0;
mbs.param[3] = 0;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
@@ -1988,8 +2033,14 @@ isp_pdb_sync(struct ispsoftc *isp)
loopid = lp - fcp->portdb;
lp->loopid = FL_PORT_ID;
do {
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_FABRIC_LOGIN;
- mbs.param[1] = loopid << 8;
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = loopid;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = loopid << 8;
+ }
mbs.param[2] = portid >> 16;
mbs.param[3] = portid & 0xffff;
isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
@@ -2104,10 +2155,14 @@ dump_em:
lp->valid = 0;
isp_prt(isp, ISP_LOGINFO,
ldumped, loopid, lp->loopid, lp->portid);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_FABRIC_LOGOUT;
- mbs.param[1] = lp->loopid << 8;
- mbs.param[2] = 0;
- mbs.param[3] = 0;
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = lp->loopid;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = lp->loopid << 8;
+ }
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate != LOOP_SYNCING_PDB) {
@@ -2488,6 +2543,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
rq->snscb_data[5] = (portid >> 16) & 0xff;
isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2638,6 +2694,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
rq->snscb_fc4_type = ftype;
isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2715,6 +2772,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
isp_put_gxn_id_request(isp, gq,
(sns_gxn_id_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2770,6 +2828,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
isp_put_gxn_id_request(isp, gq,
(sns_gxn_id_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2833,6 +2892,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
isp_put_gxn_id_request(isp, gq,
(sns_gxn_id_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2934,6 +2994,7 @@ isp_register_fc4_type(struct ispsoftc *isp)
#endif
FC_SCRATCH_ACQUIRE(isp);
isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -3273,15 +3334,19 @@ isp_start(XS_T *xs)
reqp->req_flags = XS_TAG_TYPE(xs);
}
}
- reqp->req_target = target | (XS_CHANNEL(xs) << 7);
if (IS_SCSI(isp)) {
+ reqp->req_target = target | (XS_CHANNEL(xs) << 7);
reqp->req_lun_trn = XS_LUN(xs);
reqp->req_cdblen = XS_CDBLEN(xs);
+ } else if (IS_2KLOGIN(isp)) {
+ ((ispreqt2e_t *)reqp)->req_target = target;
+ ((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
+ } else if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+ ((ispreqt2_t *)reqp)->req_target = target;
+ ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
} else {
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
- ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
- else
- ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
+ ((ispreqt2_t *)reqp)->req_target = target;
+ ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
}
MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
@@ -3333,6 +3398,8 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
int bus, tgt;
u_int16_t handle;
+ MEMZERO(&mbs, sizeof (mbs));
+
switch (ctl) {
default:
isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
@@ -3369,7 +3436,16 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
tgt = (*((int *) arg)) & 0xffff;
bus = (*((int *) arg)) >> 16;
mbs.param[0] = MBOX_ABORT_TARGET;
- mbs.param[1] = (tgt << 8) | (bus << 15);
+ if (IS_SCSI(isp)) {
+ mbs.param[1] = (tgt << 8) | (bus << 15);
+ } else {
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = tgt;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = (tgt << 8);
+ }
+ }
mbs.param[2] = 3; /* 'delay', in seconds */
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
@@ -3393,7 +3469,11 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
mbs.param[0] = MBOX_ABORT;
if (IS_FC(isp)) {
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- mbs.param[1] = tgt << 8;
+ if (IS_2KLOGIN(isp)) {
+ mbs.param[1] = tgt;
+ } else {
+ mbs.param[1] = tgt << 8;
+ }
mbs.param[4] = 0;
mbs.param[5] = 0;
mbs.param[6] = XS_LUN(xs);
@@ -3541,7 +3621,7 @@ again:
if (isp->isp_mboxbsy) {
int i = 0, obits = isp->isp_obits;
isp->isp_mboxtmp[i++] = mbox;
- for (i = 1; i < MAX_MAILBOX; i++) {
+ for (i = 1; i < MAX_MAILBOX(isp); i++) {
if ((obits & (1 << i)) == 0) {
continue;
}
@@ -4145,8 +4225,6 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
}
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
- FCPARAM(isp)->isp_lipseq =
- ISP_READ(isp, OUTMAILBOX1);
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp->isp_sendmarker = 1;
@@ -4300,7 +4378,7 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
int i, nh;
u_int16_t handles[16];
- for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
+ for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
if ((bus & (1 << i)) == 0) {
continue;
}
@@ -4716,6 +4794,7 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
mbreg_t mbs;
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_INIT_LIP;
isp_mboxcmd_qnw(isp, &mbs, 1);
}
@@ -4810,7 +4889,6 @@ isp_mbox_continue(struct ispsoftc *isp)
return (-1);
}
-
/*
* Clear the previous interrupt.
*/
@@ -4820,6 +4898,7 @@ isp_mbox_continue(struct ispsoftc *isp)
/*
* Continue with next word.
*/
+ MEMZERO(&mbs, sizeof (mbs));
ptr = isp->isp_mbxworkp;
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
@@ -4840,10 +4919,10 @@ isp_mbox_continue(struct ispsoftc *isp)
}
-#define HIBYT(x) ((x) >> 0x8)
-#define LOBYT(x) ((x) & 0xff)
-#define ISPOPMAP(a, b) (((a) << 8) | (b))
-static const u_int16_t mbpscsi[] = {
+#define HIWRD(x) ((x) >> 16)
+#define LOWRD(x) ((x) & 0xffff)
+#define ISPOPMAP(a, b) (((a) << 16) | (b))
+static const u_int32_t mbpscsi[] = {
ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
@@ -5039,7 +5118,7 @@ static char *scsi_mbcmd_names[] = {
};
#endif
-static const u_int16_t mbpfc[] = {
+static const u_int32_t mbpfc[] = {
ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
@@ -5312,7 +5391,7 @@ static void
isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
{
unsigned int ibits, obits, box, opcode;
- const u_int16_t *mcp;
+ const u_int32_t *mcp;
if (IS_FC(isp)) {
mcp = mbpfc;
@@ -5320,9 +5399,11 @@ isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
mcp = mbpscsi;
}
opcode = mbp->param[0];
- ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- for (box = 0; box < MAX_MAILBOX; box++) {
+ ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ ibits |= mbp->ibits;
+ obits |= mbp->obits;
+ for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (ibits & (1 << box)) {
ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
}
@@ -5351,7 +5432,7 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
{
char *cname, *xname, tname[16], mname[16];
unsigned int lim, ibits, obits, box, opcode;
- const u_int16_t *mcp;
+ const u_int32_t *mcp;
if (IS_FC(isp)) {
mcp = mbpfc;
@@ -5367,8 +5448,11 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
return;
}
- ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
+ ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+
+ ibits |= mbp->ibits;
+ obits |= mbp->obits;
if (ibits == 0 && obits == 0) {
mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
@@ -5381,7 +5465,7 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
*/
MBOX_ACQUIRE(isp);
- for (box = 0; box < MAX_MAILBOX; box++) {
+ for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (ibits & (1 << box)) {
ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
}
@@ -5418,7 +5502,7 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
/*
* Copy back output registers.
*/
- for (box = 0; box < MAX_MAILBOX; box++) {
+ for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (obits & (1 << box)) {
mbp->param[box] = isp->isp_mboxtmp[box];
}
@@ -5498,6 +5582,7 @@ isp_fw_state(struct ispsoftc *isp)
mbreg_t mbs;
fcparam *fcp = isp->isp_param;
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_FW_STATE;
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
@@ -5535,6 +5620,7 @@ isp_update_bus(struct ispsoftc *isp, int bus)
}
sdp = isp->isp_param;
sdp += bus;
+ MEMZERO(&mbs, sizeof (mbs));
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
u_int16_t flags, period, offset;
@@ -5650,6 +5736,7 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
mbreg_t mbs;
sdparam *sdp;
+ MEMZERO(&mbs, sizeof (mbs));
if (IS_FC(isp)) {
fcparam *fcp = (fcparam *) isp->isp_param;
int nvfail;
@@ -6467,6 +6554,7 @@ isp2200_fw_dump(struct ispsoftc *isp)
mbreg_t mbs;
u_int16_t *ptr;
+ MEMZERO(&mbs, sizeof (mbs));
ptr = FCPARAM(isp)->isp_dump_data;
if (ptr == NULL) {
isp_prt(isp, ISP_LOGERR,
@@ -6611,6 +6699,7 @@ isp2300_fw_dump(struct ispsoftc *isp)
mbreg_t mbs;
u_int16_t *ptr;
+ MEMZERO(&mbs, sizeof (mbs));
ptr = FCPARAM(isp)->isp_dump_data;
if (ptr == NULL) {
isp_prt(isp, ISP_LOGERR,
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index de468f5f33fb..2268092de2c3 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -1,7 +1,8 @@
/*-
* Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
*
- * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
+ * 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
@@ -507,6 +508,7 @@ ispioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *t
{
int needmarker;
struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
+ u_int16_t loopid;
mbreg_t mbs;
if (IS_SCSI(isp)) {
@@ -516,33 +518,36 @@ ispioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *t
memset(&mbs, 0, sizeof (mbs));
needmarker = retval = 0;
-
+ loopid = fct->loopid;
+ if (IS_2KLOGIN(isp) == 0) {
+ loopid <<= 8;
+ }
switch (fct->action) {
case CLEAR_ACA:
mbs.param[0] = MBOX_CLEAR_ACA;
- mbs.param[1] = fct->loopid << 8;
+ mbs.param[1] = loopid;
mbs.param[2] = fct->lun;
break;
case TARGET_RESET:
mbs.param[0] = MBOX_TARGET_RESET;
- mbs.param[1] = fct->loopid << 8;
+ mbs.param[1] = loopid;
needmarker = 1;
break;
case LUN_RESET:
mbs.param[0] = MBOX_LUN_RESET;
- mbs.param[1] = fct->loopid << 8;
+ mbs.param[1] = loopid;
mbs.param[2] = fct->lun;
needmarker = 1;
break;
case CLEAR_TASK_SET:
mbs.param[0] = MBOX_CLEAR_TASK_SET;
- mbs.param[1] = fct->loopid << 8;
+ mbs.param[1] = loopid;
mbs.param[2] = fct->lun;
needmarker = 1;
break;
case ABORT_TASK_SET:
mbs.param[0] = MBOX_ABORT_TASK_SET;
- mbs.param[1] = fct->loopid << 8;
+ mbs.param[1] = loopid;
mbs.param[2] = fct->lun;
needmarker = 1;
break;
@@ -606,7 +611,6 @@ static cam_status isp_target_start_ctio(struct ispsoftc *, union ccb *);
static int isp_handle_platform_atio(struct ispsoftc *, at_entry_t *);
static int isp_handle_platform_atio2(struct ispsoftc *, at2_entry_t *);
static int isp_handle_platform_ctio(struct ispsoftc *, void *);
-static void isp_handle_platform_ctio_fastpost(struct ispsoftc *, u_int32_t);
static int isp_handle_platform_notify_scsi(struct ispsoftc *, in_entry_t *);
static int isp_handle_platform_notify_fc(struct ispsoftc *, in_fcentry_t *);
@@ -1796,19 +1800,6 @@ isp_handle_platform_ctio(struct ispsoftc *isp, void *arg)
return (0);
}
-static void
-isp_handle_platform_ctio_fastpost(struct ispsoftc *isp, u_int32_t token)
-{
- union ccb *ccb;
- ccb = isp_find_xs_tgt(isp, token & 0xffff);
- KASSERT((ccb != NULL),
- ("null ccb in isp_handle_platform_ctio_fastpost"));
- isp_destroy_tgt_handle(isp, token & 0xffff);
- isp_prt(isp, ISP_LOGTDEBUG1, "CTIOx[%x] fastpost complete",
- token & 0xffff);
- isp_complete_ctio(ccb);
-}
-
static int
isp_handle_platform_notify_scsi(struct ispsoftc *isp, in_entry_t *inp)
{
@@ -3081,30 +3072,11 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
break;
}
#ifdef ISP_TARGET_MODE
- case ISPASYNC_TARGET_MESSAGE:
+ case ISPASYNC_TARGET_NOTIFY:
{
- tmd_msg_t *mp = arg;
- isp_prt(isp, ISP_LOGALL,
- "bus %d iid %d tgt %d lun %d ttype %x tval %x msg[0]=%x",
- mp->nt_bus, (int) mp->nt_iid, (int) mp->nt_tgt,
- (int) mp->nt_lun, mp->nt_tagtype, mp->nt_tagval,
- mp->nt_msg[0]);
- break;
- }
- case ISPASYNC_TARGET_EVENT:
- {
- tmd_event_t *ep = arg;
- if (ep->ev_event == ASYNC_CTIO_DONE) {
- /*
- * ACK the interrupt first
- */
- ISP_WRITE(isp, BIU_SEMA, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- isp_handle_platform_ctio_fastpost(isp, ep->ev_bus);
- break;
- }
+ tmd_notify_t *nt = arg;
isp_prt(isp, ISP_LOGALL,
- "bus %d event code 0x%x", ep->ev_bus, ep->ev_event);
+ "target notify code 0x%x", nt->nt_ncode);
break;
}
case ISPASYNC_TARGET_ACTION:
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 4b3a4d3f95f7..50b46bbab4df 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -1,7 +1,9 @@
/* $FreeBSD$ */
/*-
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions
- * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 by Matthew Jacob
+ *
+ * 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
diff --git a/sys/dev/isp/isp_inline.h b/sys/dev/isp/isp_inline.h
index c09ec9cd25dd..e6649b821323 100644
--- a/sys/dev/isp/isp_inline.h
+++ b/sys/dev/isp/isp_inline.h
@@ -2,10 +2,8 @@
/*-
* Qlogic Host Adapter Inline Functions
*
- * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
- * Feral Software
+ * Copyright (c) 1999-2006 by Matthew Jacob
* All rights reserved.
- * mjacob@feral.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -314,8 +312,12 @@ isp_put_request(struct ispsoftc *, ispreq_t *, ispreq_t *);
static INLINE void
isp_put_request_t2(struct ispsoftc *, ispreqt2_t *, ispreqt2_t *);
static INLINE void
+isp_put_request_t2e(struct ispsoftc *, ispreqt2e_t *, ispreqt2e_t *);
+static INLINE void
isp_put_request_t3(struct ispsoftc *, ispreqt3_t *, ispreqt3_t *);
static INLINE void
+isp_put_request_t3e(struct ispsoftc *, ispreqt3e_t *, ispreqt3e_t *);
+static INLINE void
isp_put_extended_request(struct ispsoftc *, ispextreq_t *, ispextreq_t *);
static INLINE void
isp_put_cont_req(struct ispsoftc *, ispcontreq_t *, ispcontreq_t *);
@@ -366,16 +368,24 @@ isp_get_atio(struct ispsoftc *, at_entry_t *, at_entry_t *);
static INLINE void
isp_put_atio2(struct ispsoftc *, at2_entry_t *, at2_entry_t *);
static INLINE void
+isp_put_atio2e(struct ispsoftc *, at2e_entry_t *, at2e_entry_t *);
+static INLINE void
isp_get_atio2(struct ispsoftc *, at2_entry_t *, at2_entry_t *);
static INLINE void
+isp_get_atio2e(struct ispsoftc *, at2e_entry_t *, at2e_entry_t *);
+static INLINE void
isp_put_ctio(struct ispsoftc *, ct_entry_t *, ct_entry_t *);
static INLINE void
isp_get_ctio(struct ispsoftc *, ct_entry_t *, ct_entry_t *);
static INLINE void
isp_put_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_entry_t *);
static INLINE void
+isp_put_ctio2e(struct ispsoftc *, ct2e_entry_t *, ct2e_entry_t *);
+static INLINE void
isp_get_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_entry_t *);
static INLINE void
+isp_get_ctio2e(struct ispsoftc *, ct2e_entry_t *, ct2e_entry_t *);
+static INLINE void
isp_put_enable_lun(struct ispsoftc *, lun_entry_t *, lun_entry_t *);
static INLINE void
isp_get_enable_lun(struct ispsoftc *, lun_entry_t *, lun_entry_t *);
@@ -386,15 +396,23 @@ isp_get_notify(struct ispsoftc *, in_entry_t *, in_entry_t *);
static INLINE void
isp_put_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_t *);
static INLINE void
+isp_put_notify_fc_e(struct ispsoftc *, in_fcentry_e_t *, in_fcentry_e_t *);
+static INLINE void
isp_get_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_t *);
static INLINE void
+isp_get_notify_fc_e(struct ispsoftc *, in_fcentry_e_t *, in_fcentry_e_t *);
+static INLINE void
isp_put_notify_ack(struct ispsoftc *, na_entry_t *, na_entry_t *);
static INLINE void
isp_get_notify_ack(struct ispsoftc *, na_entry_t *, na_entry_t *);
static INLINE void
isp_put_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
static INLINE void
+isp_put_notify_ack_fc_e(struct ispsoftc *, na_fcentry_e_t *, na_fcentry_e_t *);
+static INLINE void
isp_get_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
+static INLINE void
+isp_get_notify_ack_fc_e(struct ispsoftc *, na_fcentry_e_t *, na_fcentry_e_t *);
#endif
#define ISP_IS_SBUS(isp) \
@@ -517,6 +535,30 @@ isp_put_request_t2(struct ispsoftc *isp, ispreqt2_t *tqsrc, ispreqt2_t *tqdst)
}
static INLINE void
+isp_put_request_t2e(struct ispsoftc *isp, ispreqt2e_t *tqsrc, ispreqt2e_t *tqdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
+ ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
+ ISP_IOXPUT_16(isp, tqsrc->req_target, &tqdst->req_target);
+ ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun);
+ ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags);
+ ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2);
+ ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time);
+ ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count);
+ for (i = 0; i < 16; i++) {
+ ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt);
+ for (i = 0; i < ISP_RQDSEG_T2; i++) {
+ ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base,
+ &tqdst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count,
+ &tqdst->req_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
isp_put_request_t3(struct ispsoftc *isp, ispreqt3_t *tqsrc, ispreqt3_t *tqdst)
{
int i;
@@ -544,6 +586,32 @@ isp_put_request_t3(struct ispsoftc *isp, ispreqt3_t *tqsrc, ispreqt3_t *tqdst)
}
static INLINE void
+isp_put_request_t3e(struct ispsoftc *isp, ispreqt3e_t *tqsrc, ispreqt3e_t *tqdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
+ ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
+ ISP_IOXPUT_16(isp, tqsrc->req_target, &tqdst->req_target);
+ ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun);
+ ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags);
+ ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2);
+ ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time);
+ ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count);
+ for (i = 0; i < 16; i++) {
+ ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt);
+ for (i = 0; i < ISP_RQDSEG_T3; i++) {
+ ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base,
+ &tqdst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_basehi,
+ &tqdst->req_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count,
+ &tqdst->req_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
isp_put_extended_request(struct ispsoftc *isp, ispextreq_t *xqsrc,
ispextreq_t *xqdst)
{
@@ -1072,6 +1140,35 @@ isp_put_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
}
static INLINE void
+isp_put_atio2e(struct ispsoftc *isp, at2e_entry_t *atsrc, at2e_entry_t *atdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &atsrc->at_header, &atdst->at_header);
+ ISP_IOXPUT_32(isp, atsrc->at_reserved, &atdst->at_reserved);
+ ISP_IOXPUT_16(isp, atsrc->at_iid, &atdst->at_iid);
+ ISP_IOXPUT_16(isp, atsrc->at_rxid, &atdst->at_rxid);
+ ISP_IOXPUT_16(isp, atsrc->at_flags, &atdst->at_flags);
+ ISP_IOXPUT_16(isp, atsrc->at_status, &atdst->at_status);
+ ISP_IOXPUT_8(isp, atsrc->at_crn, &atdst->at_crn);
+ ISP_IOXPUT_8(isp, atsrc->at_taskcodes, &atdst->at_taskcodes);
+ ISP_IOXPUT_8(isp, atsrc->at_taskflags, &atdst->at_taskflags);
+ ISP_IOXPUT_8(isp, atsrc->at_execodes, &atdst->at_execodes);
+ for (i = 0; i < ATIO2_CDBLEN; i++) {
+ ISP_IOXPUT_8(isp, atsrc->at_cdb[i], &atdst->at_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, atsrc->at_datalen, &atdst->at_datalen);
+ ISP_IOXPUT_16(isp, atsrc->at_scclun, &atdst->at_scclun);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, atsrc->at_wwpn[i], &atdst->at_wwpn[i]);
+ }
+ for (i = 0; i < 6; i++) {
+ ISP_IOXPUT_16(isp, atsrc->at_reserved2[i],
+ &atdst->at_reserved2[i]);
+ }
+ ISP_IOXPUT_16(isp, atsrc->at_oxid, &atdst->at_oxid);
+}
+
+static INLINE void
isp_get_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
{
int i;
@@ -1102,6 +1199,35 @@ isp_get_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
}
static INLINE void
+isp_get_atio2e(struct ispsoftc *isp, at2e_entry_t *atsrc, at2e_entry_t *atdst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
+ ISP_IOXGET_32(isp, &atsrc->at_reserved, atdst->at_reserved);
+ ISP_IOXGET_16(isp, &atsrc->at_iid, atdst->at_iid);
+ ISP_IOXGET_16(isp, &atsrc->at_rxid, atdst->at_rxid);
+ ISP_IOXGET_16(isp, &atsrc->at_flags, atdst->at_flags);
+ ISP_IOXGET_16(isp, &atsrc->at_status, atdst->at_status);
+ ISP_IOXGET_8(isp, &atsrc->at_crn, atdst->at_crn);
+ ISP_IOXGET_8(isp, &atsrc->at_taskcodes, atdst->at_taskcodes);
+ ISP_IOXGET_8(isp, &atsrc->at_taskflags, atdst->at_taskflags);
+ ISP_IOXGET_8(isp, &atsrc->at_execodes, atdst->at_execodes);
+ for (i = 0; i < ATIO2_CDBLEN; i++) {
+ ISP_IOXGET_8(isp, &atsrc->at_cdb[i], atdst->at_cdb[i]);
+ }
+ ISP_IOXGET_32(isp, &atsrc->at_datalen, atdst->at_datalen);
+ ISP_IOXGET_16(isp, &atsrc->at_scclun, atdst->at_scclun);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_16(isp, &atsrc->at_wwpn[i], atdst->at_wwpn[i]);
+ }
+ for (i = 0; i < 6; i++) {
+ ISP_IOXGET_16(isp, &atsrc->at_reserved2[i],
+ atdst->at_reserved2[i]);
+ }
+ ISP_IOXGET_16(isp, &atsrc->at_oxid, atdst->at_oxid);
+}
+
+static INLINE void
isp_put_ctio(struct ispsoftc *isp, ct_entry_t *ctsrc, ct_entry_t *ctdst)
{
int i;
@@ -1268,6 +1394,89 @@ isp_put_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
}
static INLINE void
+isp_put_ctio2e(struct ispsoftc *isp, ct2e_entry_t *ctsrc, ct2e_entry_t *ctdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
+ ISP_IOXPUT_16(isp, ctsrc->ct_reserved, &ctdst->ct_reserved);
+ ISP_IOXPUT_16(isp, ctsrc->ct_fwhandle, &ctdst->ct_fwhandle);
+ ISP_IOXPUT_16(isp, ctsrc->ct_iid, &ctdst->ct_iid);
+ ISP_IOXPUT_16(isp, ctsrc->ct_rxid, &ctdst->ct_rxid);
+ ISP_IOXPUT_16(isp, ctsrc->ct_flags, &ctdst->ct_flags);
+ ISP_IOXPUT_16(isp, ctsrc->ct_timeout, &ctdst->ct_timeout);
+ ISP_IOXPUT_16(isp, ctsrc->ct_seg_count, &ctdst->ct_seg_count);
+ ISP_IOXPUT_32(isp, ctsrc->ct_resid, &ctdst->ct_resid);
+ ISP_IOXPUT_32(isp, ctsrc->ct_reloff, &ctdst->ct_reloff);
+ if ((ctsrc->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m0._reserved,
+ &ctdst->rsp.m0._reserved);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m0._reserved2,
+ &ctdst->rsp.m0._reserved2);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m0.ct_scsi_status,
+ &ctdst->rsp.m0.ct_scsi_status);
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_xfrlen,
+ &ctdst->rsp.m0.ct_xfrlen);
+ if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
+ for (i = 0; i < ISP_RQDSEG_T2; i++) {
+ ISP_IOXPUT_32(isp,
+ ctsrc->rsp.m0.ct_dataseg[i].ds_base,
+ &ctdst->rsp.m0.ct_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp,
+ ctsrc->rsp.m0.ct_dataseg[i].ds_count,
+ &ctdst->rsp.m0.ct_dataseg[i].ds_count);
+ }
+ } else if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
+ for (i = 0; i < ISP_RQDSEG_T3; i++) {
+ ISP_IOXPUT_32(isp,
+ ctsrc->rsp.m0.ct_dataseg64[i].ds_base,
+ &ctdst->rsp.m0.ct_dataseg64[i].ds_base);
+ ISP_IOXPUT_32(isp,
+ ctsrc->rsp.m0.ct_dataseg64[i].ds_basehi,
+ &ctdst->rsp.m0.ct_dataseg64[i].ds_basehi);
+ ISP_IOXPUT_32(isp,
+ ctsrc->rsp.m0.ct_dataseg64[i].ds_count,
+ &ctdst->rsp.m0.ct_dataseg64[i].ds_count);
+ }
+ } else if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m0.ct_dslist.ds_type,
+ &ctdst->rsp.m0.ct_dslist.ds_type);
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_dslist.ds_segment,
+ &ctdst->rsp.m0.ct_dslist.ds_segment);
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_dslist.ds_base,
+ &ctdst->rsp.m0.ct_dslist.ds_base);
+ }
+ } else if ((ctsrc->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m1._reserved,
+ &ctdst->rsp.m1._reserved);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m1._reserved2,
+ &ctdst->rsp.m1._reserved2);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_senselen,
+ &ctdst->rsp.m1.ct_senselen);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_scsi_status,
+ &ctdst->rsp.m1.ct_scsi_status);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_resplen,
+ &ctdst->rsp.m1.ct_resplen);
+ for (i = 0; i < MAXRESPLEN; i++) {
+ ISP_IOXPUT_8(isp, ctsrc->rsp.m1.ct_resp[i],
+ &ctdst->rsp.m1.ct_resp[i]);
+ }
+ } else {
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m2._reserved,
+ &ctdst->rsp.m2._reserved);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m2._reserved2,
+ &ctdst->rsp.m2._reserved2);
+ ISP_IOXPUT_16(isp, ctsrc->rsp.m2._reserved3,
+ &ctdst->rsp.m2._reserved3);
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_datalen,
+ &ctdst->rsp.m2.ct_datalen);
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ &ctdst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ &ctdst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
+ }
+}
+
+static INLINE void
isp_get_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
{
isp_copy_in_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
@@ -1285,6 +1494,22 @@ isp_get_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
}
static INLINE void
+isp_get_ctio2e(struct ispsoftc *isp, ct2e_entry_t *ctsrc, ct2e_entry_t *ctdst)
+{
+ isp_copy_in_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
+ ISP_IOXGET_16(isp, &ctsrc->ct_reserved, ctdst->ct_reserved);
+ ISP_IOXGET_16(isp, &ctsrc->ct_fwhandle, ctdst->ct_fwhandle);
+ ISP_IOXGET_16(isp, &ctsrc->ct_iid, ctdst->ct_iid);
+ ISP_IOXGET_16(isp, &ctsrc->ct_rxid, ctdst->ct_rxid);
+ ISP_IOXGET_16(isp, &ctsrc->ct_flags, ctdst->ct_flags);
+ ISP_IOXGET_16(isp, &ctsrc->ct_status, ctdst->ct_status);
+ ISP_IOXGET_16(isp, &ctsrc->ct_timeout, ctdst->ct_timeout);
+ ISP_IOXGET_16(isp, &ctsrc->ct_seg_count, ctdst->ct_seg_count);
+ ISP_IOXGET_32(isp, &ctsrc->ct_reloff, ctdst->ct_reloff);
+ ISP_IOXGET_32(isp, &ctsrc->ct_resid, ctdst->ct_resid);
+}
+
+static INLINE void
isp_put_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
{
int i;
@@ -1454,6 +1679,20 @@ isp_put_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
}
static INLINE void
+isp_put_notify_fc_e(struct ispsoftc *isp, in_fcentry_e_t *insrc,
+ in_fcentry_e_t *indst)
+{
+ isp_copy_out_hdr(isp, &insrc->in_header, &indst->in_header);
+ ISP_IOXPUT_32(isp, insrc->in_reserved, &indst->in_reserved);
+ ISP_IOXPUT_16(isp, insrc->in_iid, &indst->in_iid);
+ ISP_IOXPUT_16(isp, insrc->in_scclun, &indst->in_scclun);
+ ISP_IOXPUT_32(isp, insrc->in_reserved2, &indst->in_reserved2);
+ ISP_IOXPUT_16(isp, insrc->in_status, &indst->in_status);
+ ISP_IOXPUT_16(isp, insrc->in_task_flags, &indst->in_task_flags);
+ ISP_IOXPUT_16(isp, insrc->in_seqid, &indst->in_seqid);
+}
+
+static INLINE void
isp_get_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
in_fcentry_t *indst)
{
@@ -1469,6 +1708,20 @@ isp_get_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
}
static INLINE void
+isp_get_notify_fc_e(struct ispsoftc *isp, in_fcentry_e_t *insrc,
+ in_fcentry_e_t *indst)
+{
+ isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
+ ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
+ ISP_IOXGET_16(isp, &insrc->in_iid, indst->in_iid);
+ ISP_IOXGET_16(isp, &insrc->in_scclun, indst->in_scclun);
+ ISP_IOXGET_32(isp, &insrc->in_reserved2, indst->in_reserved2);
+ ISP_IOXGET_16(isp, &insrc->in_status, indst->in_status);
+ ISP_IOXGET_16(isp, &insrc->in_task_flags, indst->in_task_flags);
+ ISP_IOXGET_16(isp, &insrc->in_seqid, indst->in_seqid);
+}
+
+static INLINE void
isp_put_notify_ack(struct ispsoftc *isp, na_entry_t *nasrc, na_entry_t *nadst)
{
int i;
@@ -1538,6 +1791,26 @@ isp_put_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
}
static INLINE void
+isp_put_notify_ack_fc_e(struct ispsoftc *isp, na_fcentry_e_t *nasrc,
+ na_fcentry_e_t *nadst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &nasrc->na_header, &nadst->na_header);
+ ISP_IOXPUT_32(isp, nasrc->na_reserved, &nadst->na_reserved);
+ ISP_IOXPUT_16(isp, nasrc->na_iid, &nadst->na_iid);
+ ISP_IOXPUT_16(isp, nasrc->na_scclun, &nadst->na_scclun);
+ ISP_IOXPUT_16(isp, nasrc->na_flags, &nadst->na_flags);
+ ISP_IOXPUT_16(isp, nasrc->na_reserved2, &nadst->na_reserved2);
+ ISP_IOXPUT_16(isp, nasrc->na_status, &nadst->na_status);
+ ISP_IOXPUT_16(isp, nasrc->na_task_flags, &nadst->na_task_flags);
+ ISP_IOXPUT_16(isp, nasrc->na_seqid, &nadst->na_seqid);
+ for (i = 0; i < NA2_RSVDLEN; i++) {
+ ISP_IOXPUT_16(isp, nasrc->na_reserved3[i],
+ &nadst->na_reserved3[i]);
+ }
+}
+
+static INLINE void
isp_get_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
na_fcentry_t *nadst)
{
@@ -1557,5 +1830,25 @@ isp_get_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
nadst->na_reserved3[i]);
}
}
+
+static INLINE void
+isp_get_notify_ack_fc_e(struct ispsoftc *isp, na_fcentry_e_t *nasrc,
+ na_fcentry_e_t *nadst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &nasrc->na_header, &nadst->na_header);
+ ISP_IOXGET_32(isp, &nasrc->na_reserved, nadst->na_reserved);
+ ISP_IOXGET_16(isp, &nasrc->na_iid, nadst->na_iid);
+ ISP_IOXGET_16(isp, &nasrc->na_scclun, nadst->na_scclun);
+ ISP_IOXGET_16(isp, &nasrc->na_flags, nadst->na_flags);
+ ISP_IOXGET_16(isp, &nasrc->na_reserved2, nadst->na_reserved2);
+ ISP_IOXGET_16(isp, &nasrc->na_status, nadst->na_status);
+ ISP_IOXGET_16(isp, &nasrc->na_task_flags, nadst->na_task_flags);
+ ISP_IOXGET_16(isp, &nasrc->na_seqid, nadst->na_seqid);
+ for (i = 0; i < NA2_RSVDLEN; i++) {
+ ISP_IOXGET_16(isp, &nasrc->na_reserved3[i],
+ nadst->na_reserved3[i]);
+ }
+}
#endif
#endif /* _ISP_INLINE_H */
diff --git a/sys/dev/isp/isp_ioctl.h b/sys/dev/isp/isp_ioctl.h
index 099b10478771..7cf61495bb2a 100644
--- a/sys/dev/isp/isp_ioctl.h
+++ b/sys/dev/isp/isp_ioctl.h
@@ -1,34 +1,29 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2001 by Matthew Jacob
+ *
+ * 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.
- * 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.
- *
- * Alternatively, this software may be distributed under the terms of the
- * the GNU Public License ("GPL", Library, Version 2).
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 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.
- *
- * Matthew Jacob <mjacob@feral.com)
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 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.
*/
/*
* ioctl definitions for Qlogic FC/SCSI HBA driver
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index b75867c8bb12..4d2810e6f0bf 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -2,7 +2,8 @@
* PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
* FreeBSD Version.
*
- * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
+ * 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
@@ -24,6 +25,7 @@
* 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.
+ *
*/
#include <sys/cdefs.h>
@@ -220,6 +222,10 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_PRODUCT_QLOGIC_ISP2312 0x2312
#endif
+#ifndef PCI_PRODUCT_QLOGIC_ISP2322
+#define PCI_PRODUCT_QLOGIC_ISP2322 0x2322
+#endif
+
#ifndef PCI_PRODUCT_QLOGIC_ISP6312
#define PCI_PRODUCT_QLOGIC_ISP6312 0x6312
#endif
@@ -254,6 +260,9 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_QLOGIC_ISP2312 \
((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP2322 \
+ ((PCI_PRODUCT_QLOGIC_ISP2322 << 16) | PCI_VENDOR_QLOGIC)
+
#define PCI_QLOGIC_ISP6312 \
((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC)
@@ -336,6 +345,9 @@ isp_pci_probe(device_t dev)
case PCI_QLOGIC_ISP2312:
device_set_desc(dev, "Qlogic ISP 2312 PCI FC-AL Adapter");
break;
+ case PCI_QLOGIC_ISP2322:
+ device_set_desc(dev, "Qlogic ISP 2322 PCI FC-AL Adapter");
+ break;
case PCI_QLOGIC_ISP6312:
device_set_desc(dev, "Qlogic ISP 6312 PCI FC-AL Adapter");
break;
@@ -534,6 +546,13 @@ isp_pci_attach(device_t dev)
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
PCI_MBOX_REGS2300_OFF;
}
+ if (pci_get_devid(dev) == PCI_QLOGIC_ISP2322) {
+ mdvp = &mdvec_2300;
+ basetype = ISP_HA_FC_2322;
+ psize = sizeof (fcparam);
+ pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
+ PCI_MBOX_REGS2300_OFF;
+ }
isp = &pcs->pci_isp;
isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO);
if (isp->isp_param == NULL) {
@@ -550,7 +569,10 @@ isp_pci_attach(device_t dev)
* Try and find firmware for this device.
*/
- if (isp_get_firmware_p) {
+ /*
+ * Don't even attempt to get firmware for the 2322/2422 (yet)
+ */
+ if (IS_2322(isp) == 0 && IS_24XX(isp) == 0 && isp_get_firmware_p) {
int device = (int) pci_get_device(dev);
#ifdef ISP_TARGET_MODE
(*isp_get_firmware_p)(0, 1, device, &mdvp->dv_ispfw);
@@ -744,7 +766,7 @@ isp_pci_attach(device_t dev)
/*
* Last minute checks...
*/
- if (IS_2312(isp)) {
+ if (IS_23XX(isp)) {
isp->isp_port = pci_get_function(dev);
}
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index 5f87f3dbb08e..8914d9aba64c 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -2,7 +2,8 @@
* PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
* FreeBSD Version.
*
- * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
+ * 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
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index 1d4b397bbad5..f561cd90b75e 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -1,10 +1,8 @@
-/* $FreeBSD$ */
/*-
* Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
*
- * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
+ * Copyright (c) 1997-2006 by Matthew Jacob
* All rights reserved.
- * mjacob@feral.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,6 +38,9 @@
#include <dev/ic/isp_netbsd.h>
#endif
#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <dev/isp/isp_freebsd.h>
#endif
#ifdef __OpenBSD__
@@ -57,9 +58,8 @@ static const char atior[] =
"ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
"on bus %d";
-static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
-static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
-static void isp_notify_ack(struct ispsoftc *, void *);
+static void isp_got_msg(struct ispsoftc *, in_entry_t *);
+static void isp_got_msg_fc(struct ispsoftc *, in_fcentry_t *);
static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
@@ -118,24 +118,32 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
union {
at_entry_t *atiop;
at2_entry_t *at2iop;
+ at2e_entry_t *at2eiop;
ct_entry_t *ctiop;
ct2_entry_t *ct2iop;
+ ct2e_entry_t *ct2eiop;
lun_entry_t *lunenp;
in_entry_t *inotp;
in_fcentry_t *inot_fcp;
+ in_fcentry_e_t *inote_fcp;
na_entry_t *nackp;
na_fcentry_t *nack_fcp;
+ na_fcentry_e_t *nacke_fcp;
isphdr_t *hp;
void * *vp;
#define atiop unp.atiop
#define at2iop unp.at2iop
+#define at2eiop unp.at2eiop
#define ctiop unp.ctiop
#define ct2iop unp.ct2iop
+#define ct2eiop unp.ct2eiop
#define lunenp unp.lunenp
#define inotp unp.inotp
#define inot_fcp unp.inot_fcp
+#define inote_fcp unp.inote_fcp
#define nackp unp.nackp
#define nack_fcp unp.nack_fcp
+#define nacke_fcp unp.nacke_fcp
#define hdrp unp.hp
} unp;
u_int8_t local[QENTRY_LEN];
@@ -156,12 +164,18 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
isp_handle_ctio(isp, (ct_entry_t *) local);
break;
case RQSTYPE_ATIO2:
- isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
+ if (IS_2KLOGIN(isp))
+ isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
+ else
+ isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
isp_handle_atio2(isp, (at2_entry_t *) local);
break;
case RQSTYPE_CTIO3:
case RQSTYPE_CTIO2:
- isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
+ if (IS_2KLOGIN(isp))
+ isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
+ else
+ isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
isp_handle_ctio2(isp, (ct2_entry_t *) local);
break;
case RQSTYPE_ENABLE_LUN:
@@ -180,7 +194,9 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
*/
bus = 0;
if (IS_FC(isp)) {
- isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
+ if (IS_2KLOGIN(isp))
+ isp_get_notify_fc_e(isp, inote_fcp, (in_fcentry_e_t *)local);
+ isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
inot_fcp = (in_fcentry_t *) local;
status = inot_fcp->in_status;
seqid = inot_fcp->in_seqid;
@@ -198,24 +214,21 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
"Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
bus, status, seqid);
- /*
- * ACK it right away.
- */
- isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
switch (status) {
- case IN_RESET:
- (void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
- break;
case IN_MSG_RECEIVED:
case IN_IDE_RECEIVED:
if (IS_FC(isp)) {
- isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
+ isp_got_msg_fc(isp, (in_fcentry_t *)local);
} else {
- isp_got_msg(isp, bus, (in_entry_t *)local);
+ isp_got_msg(isp, (in_entry_t *)local);
}
break;
case IN_RSRC_UNAVAIL:
isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
+ isp_notify_ack(isp, local);
+ break;
+ case IN_RESET:
+ isp_target_async(isp, 0, ASYNC_BUS_RESET);
break;
case IN_PORT_LOGOUT:
case IN_ABORT_TASK:
@@ -226,6 +239,7 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
default:
isp_prt(isp, ISP_LOGERR,
"bad status (0x%x) in isp_target_notify", status);
+ isp_notify_ack(isp, local);
break;
}
break;
@@ -236,8 +250,12 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
* Immediate Notify entry for some asynchronous event.
*/
if (IS_FC(isp)) {
- isp_get_notify_ack_fc(isp, nack_fcp,
- (na_fcentry_t *)local);
+ if (IS_2KLOGIN(isp))
+ isp_get_notify_ack_fc_e(isp, nacke_fcp,
+ (na_fcentry_e_t *)local);
+ else
+ isp_get_notify_ack_fc(isp, nack_fcp,
+ (na_fcentry_t *)local);
nack_fcp = (na_fcentry_t *)local;
isp_prt(isp, ISP_LOGTDEBUG1,
"Notify Ack status=0x%x seqid 0x%x",
@@ -258,13 +276,17 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
}
#undef atiop
#undef at2iop
+#undef at2eiop
#undef ctiop
#undef ct2iop
+#undef ct2eiop
#undef lunenp
#undef inotp
#undef inot_fcp
+#undef inote_fcp
#undef nackp
#undef nack_fcp
+#undef nacke_fcp
#undef hdrp
return (rval);
}
@@ -375,6 +397,7 @@ isp_target_put_atio(struct ispsoftc *isp, void *arg)
union {
at_entry_t _atio;
at2_entry_t _atio2;
+ at2e_entry_t _atio2e;
} atun;
MEMZERO(&atun, sizeof atun);
@@ -387,7 +410,11 @@ isp_target_put_atio(struct ispsoftc *isp, void *arg)
} else {
atun._atio2.at_lun = (u_int8_t) aep->at_lun;
}
- atun._atio2.at_iid = aep->at_iid;
+ if (IS_2KLOGIN(isp)) {
+ atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
+ } else {
+ atun._atio2.at_iid = aep->at_iid;
+ }
atun._atio2.at_rxid = aep->at_rxid;
atun._atio2.at_status = CT_OK;
} else {
@@ -431,6 +458,7 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
union {
ct_entry_t _ctio;
ct2_entry_t _ctio2;
+ ct2e_entry_t _ctio2e;
} un;
MEMZERO(&un, sizeof un);
@@ -442,10 +470,14 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
cto->ct_header.rqs_entry_count = 1;
- cto->ct_iid = aep->at_iid;
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
cto->ct_lun = aep->at_lun;
}
+ if (IS_2KLOGIN(isp)) {
+ un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
+ } else {
+ cto->ct_iid = aep->at_iid;
+ }
cto->ct_rxid = aep->at_rxid;
cto->rsp.m1.ct_scsi_status = sts;
cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
@@ -494,65 +526,74 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
int
isp_target_async(struct ispsoftc *isp, int bus, int event)
{
- tmd_event_t evt;
- tmd_msg_t msg;
+ tmd_notify_t notify;
+
+ MEMZERO(&notify, sizeof (tmd_notify_t));
+ notify.nt_hba = isp;
+ /* nt_str set in outer layers */
+ notify.nt_iid = INI_ANY;
+ /* nt_tgt set in outer layers */
+ notify.nt_lun = LUN_ANY;
+ notify.nt_tagval = TAG_ANY;
+
+ if (IS_SCSI(isp)) {
+ TAG_INSERT_BUS(notify.nt_tagval, bus);
+ }
switch (event) {
- /*
- * These three we handle here to propagate an effective bus reset
- * upstream, but these do not require any immediate notify actions
- * so we return when done.
- */
- case ASYNC_LIP_F8:
- case ASYNC_LIP_OCCURRED:
case ASYNC_LOOP_UP:
+ case ASYNC_PTPMODE:
+ notify.nt_ncode = NT_LINK_UP;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
case ASYNC_LOOP_DOWN:
+ notify.nt_ncode = NT_LINK_DOWN;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
+ case ASYNC_LIP_F8:
+ case ASYNC_LIP_OCCURRED:
case ASYNC_LOOP_RESET:
- case ASYNC_PTPMODE:
- /*
- * These don't require any immediate notify actions. We used
- * treat them like SCSI Bus Resets, but that was just plain
- * wrong. Let the normal CTIO completion report what occurred.
- */
- return (0);
-
+ notify.nt_ncode = NT_LIP_RESET;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
case ASYNC_BUS_RESET:
- case ASYNC_TIMEOUT_RESET:
- if (IS_FC(isp)) {
- return (0); /* we'll be getting an inotify instead */
- }
- evt.ev_bus = bus;
- evt.ev_event = event;
- (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
+ case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
+ notify.nt_ncode = NT_BUS_RESET;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_DEVICE_RESET:
- /*
- * Bus Device Reset resets a specific target, so
- * we pass this as a synthesized message.
- */
- MEMZERO(&msg, sizeof msg);
+ notify.nt_ncode = NT_TARGET_RESET;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
+ case ASYNC_CTIO_DONE:
+ {
+ uint8_t storage[QENTRY_LEN];
+ memset(storage, 0, QENTRY_LEN);
if (IS_FC(isp)) {
- msg.nt_iid = FCPARAM(isp)->isp_loopid;
+ ct2_entry_t *ct = (ct2_entry_t *) storage;
+ ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
+ ct->ct_status = CT_OK;
+ ct->ct_syshandle = bus;
+ ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
} else {
- msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
+ ct_entry_t *ct = (ct_entry_t *) storage;
+ ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
+ ct->ct_status = CT_OK;
+ ct->ct_fwhandle = bus;
+ ct->ct_flags = CT_SENDSTATUS;
}
- msg.nt_bus = bus;
- msg.nt_msg[0] = MSG_BUS_DEV_RESET;
- (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
- break;
- case ASYNC_CTIO_DONE:
- evt.ev_bus = bus;
- evt.ev_event = event;
- (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
return (0);
+ }
default:
isp_prt(isp, ISP_LOGERR,
"isp_target_async: unknown event 0x%x", event);
+ if (isp->isp_state == ISP_RUNSTATE) {
+ isp_notify_ack(isp, NULL);
+ }
break;
}
- if (isp->isp_state == ISP_RUNSTATE)
- isp_notify_ack(isp, NULL);
- return(0);
+ return (0);
}
@@ -565,25 +606,54 @@ isp_target_async(struct ispsoftc *isp, int bus, int event)
*/
static void
-isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
+isp_got_msg(struct ispsoftc *isp, in_entry_t *inp)
{
+ tmd_notify_t nt;
u_int8_t status = inp->in_status & ~QLTM_SVALID;
+ MEMZERO(&nt, sizeof (nt));
+ nt.nt_hba = isp;
+ /* nt_str set in outer layers */
+ nt.nt_iid = GET_IID_VAL(inp->in_iid);
+ nt.nt_tgt = inp->in_tgt;
+ nt.nt_lun = inp->in_lun;
+ IN_MAKE_TAGID(nt.nt_tagval, 0, inp);
+ nt.nt_lreserved = inp;
+
if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
- tmd_msg_t msg;
-
- MEMZERO(&msg, sizeof (msg));
- msg.nt_bus = bus;
- msg.nt_iid = inp->in_iid;
- msg.nt_tgt = inp->in_tgt;
- msg.nt_lun = inp->in_lun;
- msg.nt_tagtype = inp->in_tag_type;
- IN_MAKE_TAGID(msg.nt_tagval, 0, inp);
- MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
- (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
+ switch (inp->in_msg[0]) {
+ case MSG_ABORT:
+ nt.nt_ncode = NT_ABORT_TASK_SET;
+ break;
+ case MSG_BUS_DEV_RESET:
+ nt.nt_ncode = NT_TARGET_RESET;
+ break;
+ case MSG_ABORT_TAG:
+ nt.nt_ncode = NT_ABORT_TASK;
+ break;
+ case MSG_CLEAR_QUEUE:
+ nt.nt_ncode = NT_CLEAR_TASK_SET;
+ break;
+ case MSG_REL_RECOVERY:
+ nt.nt_ncode = NT_CLEAR_ACA;
+ break;
+ case MSG_TERM_IO_PROC:
+ nt.nt_ncode = NT_ABORT_TASK;
+ break;
+ case MSG_LUN_RESET:
+ nt.nt_ncode = NT_LUN_RESET;
+ break;
+ default:
+ isp_prt(isp, ISP_LOGERR,
+ "unhandled message 0x%x", inp->in_msg[0]);
+ isp_notify_ack(isp, inp);
+ return;
+ }
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
} else {
isp_prt(isp, ISP_LOGERR,
"unknown immediate notify status 0x%x", inp->in_status);
+ isp_notify_ack(isp, inp);
}
}
@@ -591,64 +661,71 @@ isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
* Synthesize a message from the task management flags in a FCP_CMND_IU.
*/
static void
-isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
+isp_got_msg_fc(struct ispsoftc *isp, in_fcentry_t *inp)
{
- int lun;
- static const char f1[] = "%s from iid %d lun %d seq 0x%x";
+ tmd_notify_t nt;
+ static const char f1[] = "%s from iid 0x%08x%08x lun %d seq 0x%x";
static const char f2[] =
- "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
+ "unknown %s 0x%x lun %d iid 0x%08x%08x task flags 0x%x seq 0x%x\n";
+ MEMZERO(&nt, sizeof (tmd_notify_t));
+ nt.nt_hba = isp;
+ /*
+ * XXX: LOOK UP TRANSLATION IN CURRENT LPORTDB
+ */
+ if (IS_2KLOGIN(isp)) {
+ nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
+ } else {
+ nt.nt_iid = inp->in_iid; /* possibly reset in outer layer */
+ }
+ /* nt_tgt set in outer layers */
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- lun = inp->in_scclun;
+ nt.nt_lun = inp->in_scclun;
} else {
- lun = inp->in_lun;
+ nt.nt_lun = inp->in_lun;
}
+ IN_FC_MAKE_TAGID(nt.nt_tagval, 0, inp);
+ nt.nt_lreserved = inp;
if (inp->in_status != IN_MSG_RECEIVED) {
isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
- inp->in_status, lun, inp->in_iid,
+ inp->in_status, nt.nt_lun, (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid,
inp->in_task_flags, inp->in_seqid);
+ isp_notify_ack(isp, inp);
+ return;
+ }
+
+ if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
+ (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_ABORT_TASK_SET;
+ } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
+ (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_CLEAR_TASK_SET;
+ } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
+ (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_LUN_RESET;
+ } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
+ (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_TARGET_RESET;
+ } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
+ (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_CLEAR_ACA;
} else {
- tmd_msg_t msg;
-
- MEMZERO(&msg, sizeof (msg));
- msg.nt_bus = bus;
- msg.nt_iid = inp->in_iid;
- IN_FC_MAKE_TAGID(msg.nt_tagval, 0, inp);
- msg.nt_lun = lun;
-
- if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_ABORT;
- } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_CLEAR_QUEUE;
- } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_LUN_RESET;
- } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_BUS_DEV_RESET;
- } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_REL_RECOVERY;
- } else {
- isp_prt(isp, ISP_LOGWARN, f2, "task flag",
- inp->in_status, lun, inp->in_iid,
- inp->in_task_flags, inp->in_seqid);
- }
- if (msg.nt_msg[0]) {
- (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
- }
+ isp_prt(isp, ISP_LOGWARN, f2, "task flag",
+ inp->in_status, nt.nt_lun, (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid,
+ inp->in_task_flags, inp->in_seqid);
+ isp_notify_ack(isp, inp);
+ return;
}
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
}
-static void
+void
isp_notify_ack(struct ispsoftc *isp, void *arg)
{
char storage[QENTRY_LEN];
@@ -668,7 +745,11 @@ isp_notify_ack(struct ispsoftc *isp, void *arg)
if (arg) {
in_fcentry_t *inp = arg;
MEMCPY(storage, arg, sizeof (isphdr_t));
- na->na_iid = inp->in_iid;
+ if (IS_2KLOGIN(isp)) {
+ ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid;
+ } else {
+ na->na_iid = inp->in_iid;
+ }
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
na->na_lun = inp->in_scclun;
} else {
@@ -686,7 +767,11 @@ isp_notify_ack(struct ispsoftc *isp, void *arg)
}
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
na->na_header.rqs_entry_count = 1;
- isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
+ if (IS_2KLOGIN(isp)) {
+ isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp);
+ } else {
+ isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
+ }
} else {
na_entry_t *na = (na_entry_t *) storage;
if (arg) {
@@ -794,7 +879,7 @@ isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
static void
isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
{
- int lun;
+ int lun, iid;
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
lun = aep->at_scclun;
@@ -802,6 +887,12 @@ isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
lun = aep->at_lun;
}
+ if (IS_2KLOGIN(isp)) {
+ iid = ((at2e_entry_t *)aep)->at_iid;
+ } else {
+ iid = aep->at_iid;
+ }
+
/*
* The firmware status (except for the QLTM_SVALID bit) indicates
* why this ATIO was sent to us.
@@ -861,14 +952,14 @@ isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
* Ignore it because the async event will clear things
* up for us.
*/
- isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
+ isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
break;
default:
isp_prt(isp, ISP_LOGERR,
"Unknown ATIO2 status 0x%x from initiator %d for lun %d",
- aep->at_status, aep->at_iid, lun);
+ aep->at_status, iid, lun);
(void) isp_target_put_atio(isp, aep);
break;
}
diff --git a/sys/dev/isp/isp_target.h b/sys/dev/isp/isp_target.h
index dff513dd5a1c..0386fcb96281 100644
--- a/sys/dev/isp/isp_target.h
+++ b/sys/dev/isp/isp_target.h
@@ -7,12 +7,9 @@
* pms@psconsult.com
* All rights reserved.
*
- * Additional Copyright (c) 1999, 2000, 2001
- * Matthew Jacob
- * mjacob@feral.com
+ * Additonal 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:
@@ -28,6 +25,8 @@
* 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.
@@ -120,6 +119,17 @@ typedef struct {
u_int16_t in_seqid; /* sequence id */
} in_fcentry_t;
+typedef struct {
+ isphdr_t in_header;
+ u_int32_t in_reserved;
+ u_int16_t in_iid; /* initiator */
+ u_int16_t in_scclun;
+ u_int32_t in_reserved2;
+ u_int16_t in_status;
+ u_int16_t in_task_flags;
+ u_int16_t in_seqid; /* sequence id */
+} in_fcentry_e_t;
+
/*
* Values for the in_status field
*/
@@ -205,6 +215,20 @@ typedef struct {
u_int16_t na_seqid; /* sequence id */
u_int16_t na_reserved3[NA2_RSVDLEN];
} na_fcentry_t;
+
+typedef struct {
+ isphdr_t na_header;
+ u_int32_t na_reserved;
+ u_int16_t na_iid; /* initiator */
+ u_int16_t na_scclun;
+ u_int16_t na_flags;
+ u_int16_t na_reserved2;
+ u_int16_t na_status;
+ u_int16_t na_task_flags;
+ u_int16_t na_seqid; /* sequence id */
+ u_int16_t na_reserved3[NA2_RSVDLEN];
+} na_fcentry_e_t;
+
#define NAFC_RCOUNT 0x80 /* increment resource count */
#define NAFC_RST_CLRD 0x20 /* Clear LIP Reset */
/*
@@ -254,30 +278,38 @@ typedef struct {
tid |= (aep->at_tag_val << 16); \
tid |= (1 << 24); \
} \
- tid |= (inst << 25)
+ tid |= (GET_BUS_VAL(aep->at_iid) << 25); \
+ tid |= (inst << 26)
-#define CT_MAKE_TAGID(tid, inst, ct) \
+#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 |= (inst << 25)
+ 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) >> 25) & 0x7f)
+#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, inst, inp) \
tid = inp->in_seqid; \
tid |= (inp->in_tag_val << 16); \
tid |= (1 << 24); \
- tid |= (inst << 25)
+ tid |= (GET_BUS_VAL(inp->in_iid) << 25); \
+ tid |= (inst << 26)
#define TAG_INSERT_INST(tid, inst) \
- tid &= ~(0x1ffffff); \
- tid |= (inst << 25)
+ 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
@@ -304,6 +336,25 @@ typedef struct {
u_int16_t at_oxid;
} at2_entry_t;
+typedef struct {
+ isphdr_t at_header;
+ u_int32_t at_reserved;
+ u_int16_t at_iid; /* initiator */
+ u_int16_t at_rxid; /* response ID */
+ u_int16_t at_flags;
+ u_int16_t at_status; /* firmware status */
+ u_int8_t at_crn; /* command reference number */
+ u_int8_t at_taskcodes;
+ u_int8_t at_taskflags;
+ u_int8_t at_execodes;
+ u_int8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */
+ u_int32_t at_datalen; /* allocated data len */
+ u_int16_t at_scclun; /* SCC Lun or reserved */
+ u_int16_t at_wwpn[4]; /* WWPN of initiator */
+ u_int16_t at_reserved2[6];
+ u_int16_t at_oxid;
+} at2e_entry_t;
+
#define ATIO2_WWPN_OFFSET 0x2A
#define ATIO2_OXID_OFFSET 0x3E
@@ -332,6 +383,11 @@ typedef struct {
#define AT2_GET_INST(val) ((val) >> 16)
#define AT2_GET_HANDLE AT2_GET_TAG
+#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, inst, inp) \
tid = inp->in_seqid; \
tid |= (inst << 16)
@@ -381,8 +437,8 @@ typedef struct {
* 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 129 && 255 (these represent devices that have
- * logged in across a SCSI fabric).
+ * 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)
@@ -430,6 +486,8 @@ typedef struct {
#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
@@ -509,6 +567,48 @@ typedef struct {
} rsp;
} ct2_entry_t;
+typedef struct {
+ isphdr_t ct_header;
+ u_int16_t ct_reserved;
+ u_int16_t ct_fwhandle; /* just to match CTIO */
+ u_int16_t ct_iid; /* initiator id */
+ u_int16_t ct_rxid; /* response ID */
+ u_int16_t ct_flags;
+ u_int16_t ct_status; /* isp status */
+ u_int16_t ct_timeout;
+ u_int16_t ct_seg_count;
+ u_int32_t ct_reloff; /* relative offset */
+ int32_t ct_resid; /* residual length */
+ union {
+ struct {
+ u_int32_t _reserved;
+ u_int16_t _reserved2;
+ u_int16_t ct_scsi_status;
+ u_int32_t ct_xfrlen;
+ union {
+ ispds_t ct_a[ISP_RQDSEG_T2]; /* CTIO2 */
+ ispds64_t ct_b[ISP_RQDSEG_T3]; /* CTIO3 */
+ ispdslist_t ct_c; /* CTIO4 */
+ } _u;
+ } m0;
+ struct {
+ u_int16_t _reserved;
+ u_int16_t _reserved2;
+ u_int16_t ct_senselen;
+ u_int16_t ct_scsi_status;
+ u_int16_t ct_resplen;
+ u_int8_t ct_resp[MAXRESPLEN];
+ } m1;
+ struct {
+ u_int32_t _reserved;
+ u_int16_t _reserved2;
+ u_int16_t _reserved3;
+ u_int32_t ct_datalen;
+ ispds_t ct_fcp_rsp_iudata;
+ } m2;
+ } rsp;
+} ct2e_entry_t;
+
/*
* ct_flags values for CTIO2
*/
@@ -557,6 +657,12 @@ typedef struct {
int isp_target_notify(struct ispsoftc *, void *, u_int16_t *);
/*
+ * This function externalizes the ability to acknowledge an Immediate Notify
+ * request.
+ */
+void isp_notify_ack(struct ispsoftc *, void *);
+
+/*
* Enable/Disable/Modify a logical unit.
* (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt, opaque)
*/
@@ -589,6 +695,6 @@ int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t);
*
* Return nonzero if the interrupt that generated this event has been dismissed.
*/
-
int isp_target_async(struct ispsoftc *, int, int);
+
#endif /* _ISP_TARGET_H */
diff --git a/sys/dev/isp/isp_tpublic.h b/sys/dev/isp/isp_tpublic.h
index a2773323d68e..fdaaf16b5aff 100644
--- a/sys/dev/isp/isp_tpublic.h
+++ b/sys/dev/isp/isp_tpublic.h
@@ -1,16 +1,16 @@
/* $FreeBSD$ */
/*-
* Qlogic ISP Host Adapter Public Target Interface Structures && Routines
- *---------------------------------------
- * Copyright (c) 2000 by Matthew Jacob
+ *
+ * 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.
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
@@ -25,38 +25,120 @@
* 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.
- *
- * Matthew Jacob
- * Feral Software
- * mjacob@feral.com
+ */
+/*
+ * Qlogic ISP Host Adapter Public Target Interface Structures && Routines
*/
+#ifndef _ISP_TPUBLIC_H
+#define _ISP_TPUBLIC_H 1
+
/*
- * Required software target mode message and event handling structures.
- *
- * The message and event structures are used by the MI layer
- * to propagate messages and events upstream.
+ * Action codes set by the Qlogic 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;
-#ifndef IN_MSGLEN
-#define IN_MSGLEN 8
-#endif
+/*
+ * Action codes set by the external layer for the
+ * MD Qlogic 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_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 2
typedef struct {
- void * nt_hba; /* HBA tag */
- u_int64_t nt_iid; /* inititator id */
- u_int64_t nt_tgt; /* target id */
- u_int64_t nt_lun; /* logical unit */
- u_int32_t nt_tagval; /* tag value */
- u_int8_t nt_bus; /* bus */
- u_int8_t nt_tagtype; /* tag type */
- u_int8_t nt_msg[IN_MSGLEN]; /* message content */
-} tmd_msg_t;
+ void * r_identity;
+ void (*r_action)(qact_e, void *);
+ char r_name[8];
+ int r_inst;
+ int r_version;
+ enum { R_FC, R_SCSI } r_type;
+} hba_register_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 nt_padding; /* padding */
+ uint32_t nt_tagval; /* tag value */
+ tmd_ncode_t nt_ncode; /* action */
+ void * nt_lreserved;
+ void * nt_hreserved;
+} tmd_notify_t;
+#define LUN_ANY 0xffff
+#define INI_ANY ((uint64_t) -1)
+#define TAG_ANY 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 cd_hba, cd_iid, cd_chan, cd_tgt and cd_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.
+ *
+ * Logical unit zero must be the first enabled and the last disabled.
+ */
typedef struct {
- void * ev_hba; /* HBA tag */
- u_int32_t ev_bus; /* bus */
- u_int32_t ev_event; /* type of async event */
-} tmd_event_t;
+ void * en_private; /* for outer layer usage */
+ void * en_hba; /* HBA tag */
+ u_int64_t en_iid; /* initiator ID */
+ u_int64_t en_tgt; /* target id */
+ u_int64_t en_lun; /* logical unit */
+ u_int8_t en_chan; /* channel on card */
+ int32_t en_error;
+} enadis_t;
/*
* Suggested Software Target Mode Command Handling structure.
@@ -262,37 +344,6 @@ typedef struct tmd_cmd {
/*
- * Action codes set by the Qlogic 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_TEVENT, /* the argument is a pointer to a tmd_event_t */
- QOUT_TMSG, /* the argument is a pointer to a tmd_msg_t */
- QOUT_IOCTL, /* the argument is a pointer to a ioctl_cmd_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 Qlogic 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_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_IOCTL, /* the argument is a pointer to a ioctl_cmd_t */
- QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */
-} qact_e;
-
-
-/*
* A word about the START/CONT/DONE/FIN dance:
*
* When the HBA is enabled for receiving commands, one may show up
@@ -320,72 +371,6 @@ typedef enum {
*/
/*
- * A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
- * with cd_hba, cd_iid, cd_chan, cd_tgt and cd_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.
- *
- * Logical unit zero must be the first enabled and the last disabled.
- */
-typedef struct {
- void * cd_private; /* for outer layer usage */
- void * cd_hba; /* HBA tag */
- u_int64_t cd_iid; /* initiator ID */
- u_int64_t cd_tgt; /* target id */
- u_int64_t cd_lun; /* logical unit */
- u_int8_t cd_chan; /* channel on card */
- int32_t cd_error;
-} enadis_t;
-
-/*
- * 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 1
-typedef struct {
- void * r_identity;
- void (*r_action)(qact_e, void *);
- char r_name[8];
- int r_inst;
- int r_version;
- enum { R_FC, R_SCSI } r_type;
-} hba_register_t;
-
-/*
- * This structure is used to pass an encapsulated ioctl through to the
- * MD layer. In many implementations it's often convenient to open just
- * one device, but actions you want to take need to be taken on the
- * underlying HBA. Rather than invent a separate protocol for each action,
- * an ioctl passthrough seems simpler.
- *
- * In order to avoid cross domain copy problems, though, the caller will
- * be responsible for allocating and providing a staging area for all ioctl
- * related data. This, unavoidably, requires some ioctl decode capability
- * in the outer layer code.`
- *
- * And also, albeit being cheesy, we'll define a few internal ioctls here.
- */
-typedef struct {
- void * i_identity; /* HBA tag */
- void * i_syncptr; /* synchronization pointer */
- int i_cmd; /* ioctl command */
- void * i_arg; /* ioctl argument area */
- int i_errno; /* ioctl error return */
-} ioctl_cmd_t;
-
-#define QI_IOC ('Q' << 8)
-#define QI_SCSI_TINI QI_IOC|0
-#define QI_SCSI_CMD QI_IOC|1
-#define QI_WWPN_XLT QI_IOC|2
-
-/*
* Target handler functions.
*
* The MD target handler function (the outer layer calls this)
@@ -398,4 +383,4 @@ typedef struct {
*
* void system_target_handler(tact_e, void *arg)
*/
-
+#endif /* _ISP_TPUBLIC_H */
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index b810faaa6344..a7f5b90d91c1 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -2,7 +2,7 @@
/*-
* Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
*
- * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
+ * Copyright (c) 1997-2006 by Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -160,10 +160,6 @@
#define MBOX_BUSY 0x04
-typedef struct {
- u_int16_t param[8];
-} mbreg_t;
-
/*
* Mailbox Command Complete Status Codes
*/
@@ -351,6 +347,7 @@ typedef struct {
#define SYNC_DEVICE 0
#define SYNC_TARGET 1
#define SYNC_ALL 2
+#define SYNC_LIP 3
#define ISP_RQDSEG_T2 3
typedef struct {
@@ -368,6 +365,20 @@ typedef struct {
ispds_t req_dataseg[ISP_RQDSEG_T2];
} ispreqt2_t;
+typedef struct {
+ isphdr_t req_header;
+ u_int32_t req_handle;
+ u_int16_t req_target;
+ u_int16_t req_scclun;
+ u_int16_t req_flags;
+ u_int16_t _res2;
+ u_int16_t req_time;
+ u_int16_t req_seg_count;
+ u_int8_t req_cdb[16];
+ u_int32_t req_totalcnt;
+ ispds_t req_dataseg[ISP_RQDSEG_T2];
+} ispreqt2e_t;
+
#define ISP_RQDSEG_T3 2
typedef struct {
isphdr_t req_header;
@@ -384,6 +395,20 @@ typedef struct {
ispds64_t req_dataseg[ISP_RQDSEG_T3];
} ispreqt3_t;
+typedef struct {
+ isphdr_t req_header;
+ u_int32_t req_handle;
+ u_int16_t req_target;
+ u_int16_t req_scclun;
+ u_int16_t req_flags;
+ u_int16_t _res2;
+ u_int16_t req_time;
+ u_int16_t req_seg_count;
+ u_int8_t req_cdb[16];
+ u_int32_t req_totalcnt;
+ ispds64_t req_dataseg[ISP_RQDSEG_T3];
+} ispreqt3e_t;
+
/* req_flag values */
#define REQFLAG_NODISCON 0x0001
#define REQFLAG_HTAG 0x0002
@@ -569,6 +594,12 @@ typedef struct {
#define ISP_FW_ATTR_CLASS2 0x08
#define ISP_FW_ATTR_FCTAPE 0x10
#define ISP_FW_ATTR_IP 0x20
+#define ISP_FW_ATTR_VI 0x40
+#define ISP_FW_ATTR_VI_SOLARIS 0x80
+#define ISP_FW_ATTR_2KLOGINS 0x100 /* XXX: just a guess */
+
+#define IS_2KLOGIN(isp) \
+ (IS_FC(isp) && (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_2KLOGINS))
/*
* Reduced Interrupt Operation Response Queue Entreis
diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h
index 163ac9894d90..21d75ca7d4ec 100644
--- a/sys/dev/isp/ispreg.h
+++ b/sys/dev/isp/ispreg.h
@@ -3,7 +3,7 @@
* Machine Independent (well, as best as possible) register
* definitions for Qlogic ISP SCSI adapters.
*
- * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
+ * Copyright (c) 1997-2006 by Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -371,15 +371,26 @@
#define OUTMAILBOX6 (MBOX_BLOCK+0xC)
#define OUTMAILBOX7 (MBOX_BLOCK+0xE)
+/*
+ * Strictly speaking, it's
+ * SCSI && 2100 : 8 MBOX registers
+ * 2200: 24 MBOX registers
+ * 2300: 32 MBOX registers
+ */
#define MBOX_OFF(n) (MBOX_BLOCK + ((n) << 1))
#define NMBOX(isp) \
(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
- ((isp)->isp_type & ISP_HA_FC))? 8 : 6)
+ ((isp)->isp_type & ISP_HA_FC))? 12 : 6)
#define NMBOX_BMASK(isp) \
(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
- ((isp)->isp_type & ISP_HA_FC))? 0xff : 0x3f)
-
-#define MAX_MAILBOX 8
+ ((isp)->isp_type & ISP_HA_FC))? 0xfff : 0x3f)
+
+#define MAX_MAILBOX(isp) ((IS_FC(isp))? 12 : 8)
+#define MAILBOX_STORAGE 12
+typedef struct {
+ u_int16_t param[MAILBOX_STORAGE];
+ u_int16_t ibits, obits;
+} mbreg_t;
/*
* Fibre Protocol Module and Frame Buffer Register Offsets/Definitions (2X00).
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index e71a952cf8fd..ead95a9b62cc 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -2,7 +2,7 @@
/*-
* Soft Definitions for for Qlogic ISP SCSI adapters.
*
- * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
+ * Copyright (c) 1997-2006 by Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,6 @@
* 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.
- *
*/
#ifndef _ISPVAR_H
@@ -174,7 +173,6 @@ typedef u_int32_t isp_dma_addr_t;
/*
* SCSI Specific Host Adapter Parameters- per bus, per target
*/
-
typedef struct {
u_int isp_gotdparms : 1,
isp_req_ack_active_neg : 1,
@@ -230,7 +228,6 @@ typedef struct {
#define DPARM_DEFAULT (0xFF00 & ~DPARM_QFRZ)
#define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
-
/* technically, not really correct, as they need to be rated based upon clock */
#define ISP_80M_SYNCPARMS 0x0c09
#define ISP_40M_SYNCPARMS 0x0c0a
@@ -254,8 +251,9 @@ typedef struct {
#endif
typedef struct {
- u_int32_t isp_fwoptions : 16,
- isp_gbspeed : 2,
+ u_int32_t : 13,
+ isp_gbspeed : 3,
+ : 2,
isp_iid_set : 1,
loop_seen_once : 1,
isp_loopstate : 4, /* Current Loop State */
@@ -263,11 +261,11 @@ typedef struct {
isp_gotdparms : 1,
isp_topo : 3,
isp_onfabric : 1;
- u_int8_t isp_iid; /* 'initiator' id */
- u_int8_t isp_loopid; /* hard loop id */
- u_int8_t isp_alpa; /* ALPA */
- u_int32_t isp_portid;
- volatile u_int16_t isp_lipseq; /* LIP sequence # */
+ u_int32_t : 8,
+ isp_portid : 24; /* S_ID */
+ u_int16_t isp_fwoptions;
+ u_int16_t isp_iid; /* 'initiator' id */
+ u_int16_t isp_loopid; /* hard loop id */
u_int16_t isp_fwattr; /* firmware attributes */
u_int8_t isp_execthrottle;
u_int8_t isp_retry_delay;
@@ -287,20 +285,20 @@ typedef struct {
* to move around.
*/
struct lportdb {
- u_int32_t
- port_type : 8,
- loopid : 8,
+ u_int32_t loopid : 16,
+ : 2,
fc4_type : 4,
last_fabric_dev : 1,
- : 2,
relogin : 1,
force_logout : 1,
was_fabric_dev : 1,
fabric_dev : 1,
loggedin : 1,
roles : 2,
+ tvalid : 1,
valid : 1;
- u_int32_t portid;
+ u_int32_t port_type : 8,
+ portid : 24;
u_int64_t node_wwn;
u_int64_t port_wwn;
} portdb[MAX_FC_TARG], tport[FC_PORT_ID];
@@ -414,7 +412,7 @@ typedef struct ispsoftc {
volatile u_int16_t isp_resodx; /* index of next result */
volatile u_int16_t isp_rspbsy;
volatile u_int16_t isp_lasthdls; /* last handle seed */
- volatile u_int16_t isp_mboxtmp[MAX_MAILBOX];
+ volatile u_int16_t isp_mboxtmp[MAILBOX_STORAGE];
volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */
volatile u_int16_t isp_mbxwrk0;
volatile u_int16_t isp_mbxwrk1;
@@ -554,6 +552,9 @@ typedef struct ispsoftc {
#define ISP_HA_FC_2200 0x20
#define ISP_HA_FC_2300 0x30
#define ISP_HA_FC_2312 0x40
+#define ISP_HA_FC_2322 0x50
+#define ISP_HA_FC_2400 0x60
+#define ISP_HA_FC_2422 0x61
#define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI)
#define IS_1240(isp) (isp->isp_type == ISP_HA_SCSI_1240)
@@ -574,6 +575,8 @@ typedef struct ispsoftc {
#define IS_23XX(isp) ((isp)->isp_type >= ISP_HA_FC_2300)
#define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300)
#define IS_2312(isp) ((isp)->isp_type == ISP_HA_FC_2312)
+#define IS_2322(isp) ((isp)->isp_type == ISP_HA_FC_2322)
+#define IS_24XX(isp) ((isp)->isp_type >= ISP_HA_FC_2400)
/*
* DMA cookie macros
@@ -742,9 +745,8 @@ typedef enum {
ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */
ISPASYNC_FABRIC_DEV, /* FC Fabric Device Arrival */
ISPASYNC_PROMENADE, /* FC Objects coming && going */
- ISPASYNC_TARGET_MESSAGE, /* target message */
- ISPASYNC_TARGET_EVENT, /* target asynchronous event */
- ISPASYNC_TARGET_ACTION, /* other target command action */
+ ISPASYNC_TARGET_NOTIFY, /* target asynchronous notification event */
+ ISPASYNC_TARGET_ACTION, /* target action requested */
ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */
ISPASYNC_UNHANDLED_RESPONSE, /* Unhandled Response Entry */
ISPASYNC_FW_CRASH, /* Firmware has crashed */