summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2001-12-11 00:18:45 +0000
committermjacob <mjacob@FreeBSD.org>2001-12-11 00:18:45 +0000
commit991ffbae5691ddb93149381b3c23fcf0763b63bd (patch)
treec9f72bc76f2873325753abbad1598b1881e3e759
parent356efe3c0b9c059153349979d7c80cd8b40c104c (diff)
downloadFreeBSD-src-991ffbae5691ddb93149381b3c23fcf0763b63bd.zip
FreeBSD-src-991ffbae5691ddb93149381b3c23fcf0763b63bd.tar.gz
Major restructuring for swizzling to the request queue and unswizzling from
the response queue. Instead of the ad hoc ISP_SWIZZLE_REQUEST, we now have a complete set of inline functions in isp_inline.h. Each platform is responsible for providing just one of a set of ISP_IOX_{GET,PUT}{8,16,32} macros. The reason this needs to be done is that we need to have a single set of functions that will work correctly on multiple architectures for both little and big endian machines. It also needs to work correctly in the case that we have the request or response queues in memory that has to be treated specially (e.g., have ddi_dma_sync called on it for Solaris after we update it or before we read from it). It also has to handle the SBus cards (for platforms that have them) which, while on a Big Endian machine, do *not* require *most* of the request/response queue entry fields to be swizzled or unswizzled. One thing that falls out of this is that we no longer build requests in the request queue itself. Instead, we build the request locally (e.g., on the stack) and then as part of the swizzling operation, copy it to the request queue entry we've allocated. I thought long and hard about whether this was too expensive a change to make as it in a lot of cases requires an extra copy. On balance, the flexbility is worth it. With any luck, the entry that we build locally stays in a processor writeback cache (after all, it's only 64 bytes) so that the cost of actually flushing it to the memory area that is the shared queue with the PCI device is not all that expensive. We may examine this again and try to get clever in the future to try and avoid copies. Another change that falls out of this is that MEMORYBARRIER should be taken a lot more seriously. The macro ISP_ADD_REQUEST does a MEMORYBARRIER on the entry being added. But there had been many other places this had been missing. It's now very important that it be done. Additional changes: Fix a longstanding buglet of sorts. When we get an entry via isp_getrqentry, the iptr value that gets returned is the value we intend to eventually plug into the ISP registers as the entry *one past* the last one we've written- *not* the current entry we're updating. All along we've been calling sync functions on the wrong index value. Argh. The 'fix' here is to rename all 'iptr' variables as 'nxti' to remember that this is the 'next' pointer- not the current pointer. Devote a single bit to mboxbsy- and set aside bits for output mbox registers that we need to pick up- we can have at least one command which does not have any defined output registers (MBOX_EXECUTE_FIRMWARE). MFC after: 2 weeks
-rw-r--r--sys/dev/isp/isp.c257
-rw-r--r--sys/dev/isp/isp_freebsd.c41
-rw-r--r--sys/dev/isp/isp_freebsd.h49
-rw-r--r--sys/dev/isp/isp_inline.h1048
-rw-r--r--sys/dev/isp/isp_pci.c304
-rw-r--r--sys/dev/isp/isp_target.c76
-rw-r--r--sys/dev/isp/isp_target.h215
-rw-r--r--sys/dev/isp/ispmbox.h37
-rw-r--r--sys/dev/isp/ispvar.h52
9 files changed, 1500 insertions, 579 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 4863075..4049eb5 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -109,37 +109,37 @@ static const char sc4[] = "NVRAM";
/*
* Local function prototypes.
*/
-static int isp_parse_async __P((struct ispsoftc *, int));
-static int isp_handle_other_response
-__P((struct ispsoftc *, ispstatusreq_t *, u_int16_t *));
-static void isp_parse_status
-__P((struct ispsoftc *, ispstatusreq_t *, XS_T *));
-static void isp_fastpost_complete __P((struct ispsoftc *, u_int16_t));
-static void isp_scsi_init __P((struct ispsoftc *));
-static void isp_scsi_channel_init __P((struct ispsoftc *, int));
-static void isp_fibre_init __P((struct ispsoftc *));
-static void isp_mark_getpdb_all __P((struct ispsoftc *));
-static int isp_getmap __P((struct ispsoftc *, fcpos_map_t *));
-static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *));
-static u_int64_t isp_get_portname __P((struct ispsoftc *, int, int));
-static int isp_fclink_test __P((struct ispsoftc *, int));
-static char *isp2100_fw_statename __P((int));
-static int isp_pdb_sync __P((struct ispsoftc *));
-static int isp_scan_loop __P((struct ispsoftc *));
-static int isp_scan_fabric __P((struct ispsoftc *));
-static void isp_register_fc4_type __P((struct ispsoftc *));
-static void isp_fw_state __P((struct ispsoftc *));
-static void isp_mboxcmd __P((struct ispsoftc *, mbreg_t *, int));
-
-static void isp_update __P((struct ispsoftc *));
-static void isp_update_bus __P((struct ispsoftc *, int));
-static void isp_setdfltparm __P((struct ispsoftc *, int));
-static int isp_read_nvram __P((struct ispsoftc *));
-static void isp_rdnvram_word __P((struct ispsoftc *, int, u_int16_t *));
-static void isp_parse_nvram_1020 __P((struct ispsoftc *, u_int8_t *));
-static void isp_parse_nvram_1080 __P((struct ispsoftc *, int, u_int8_t *));
-static void isp_parse_nvram_12160 __P((struct ispsoftc *, int, u_int8_t *));
-static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *));
+static int isp_parse_async(struct ispsoftc *, int);
+static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
+ u_int16_t *);
+static void
+isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
+static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
+static void isp_scsi_init(struct ispsoftc *);
+static void isp_scsi_channel_init(struct ispsoftc *, int);
+static void isp_fibre_init(struct ispsoftc *);
+static void isp_mark_getpdb_all(struct ispsoftc *);
+static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
+static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
+static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
+static int isp_fclink_test(struct ispsoftc *, int);
+static char *isp2100_fw_statename(int);
+static int isp_pdb_sync(struct ispsoftc *);
+static int isp_scan_loop(struct ispsoftc *);
+static int isp_scan_fabric(struct ispsoftc *);
+static void isp_register_fc4_type(struct ispsoftc *);
+static void isp_fw_state(struct ispsoftc *);
+static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
+
+static void isp_update(struct ispsoftc *);
+static void isp_update_bus(struct ispsoftc *, int);
+static void isp_setdfltparm(struct ispsoftc *, int);
+static int isp_read_nvram(struct ispsoftc *);
+static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
+static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
+static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
+static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
+static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
/*
* Reset Hardware.
@@ -692,7 +692,7 @@ again:
* major, minor, micro revisions in the mailbox registers, which
* is really, really, annoying.
*/
- if (isp->isp_bustype == ISP_BT_SBUS) {
+ if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
if (dodnld) {
#ifdef ISP_TARGET_MODE
isp->isp_fwrev[0] = 7;
@@ -1107,7 +1107,7 @@ static void
isp_fibre_init(struct ispsoftc *isp)
{
fcparam *fcp;
- isp_icb_t *icbp;
+ isp_icb_t local, *icbp = &local;
mbreg_t mbs;
int loopid;
u_int64_t nwwn, pwwn;
@@ -1129,9 +1129,7 @@ isp_fibre_init(struct ispsoftc *isp)
}
loopid = DEFAULT_LOOPID(isp);
- icbp = (isp_icb_t *) fcp->isp_scratch;
MEMZERO(icbp, sizeof (*icbp));
-
icbp->icb_version = ICB_VERSION1;
/*
@@ -1289,8 +1287,7 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
isp_prt(isp, ISP_LOGDEBUG1,
"isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions);
- ISP_SWIZZLE_ICB(isp, icbp);
-
+ isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
/*
* Init the firmware
@@ -1383,7 +1380,7 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- ISP_UNSWIZZLE_AND_COPY_PDBP(isp, pdbp, fcp->isp_scratch);
+ isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
return (0);
}
return (-1);
@@ -2264,9 +2261,6 @@ isp_scan_fabric(struct ispsoftc *isp)
{
fcparam *fcp = isp->isp_param;
u_int32_t portid, first_portid, last_portid;
- sns_screq_t *reqp;
- sns_scrsp_t *resp;
- mbreg_t mbs;
int hicap, first_portid_seen, last_port_same;
if (fcp->isp_onfabric == 0) {
@@ -2274,8 +2268,7 @@ isp_scan_fabric(struct ispsoftc *isp)
return (0);
}
- reqp = (sns_screq_t *) fcp->isp_scratch;
- resp = (sns_scrsp_t *) (&((char *)fcp->isp_scratch)[0x100]);
+
/*
* Since Port IDs are 24 bits, we can check against having seen
* anything yet with this value.
@@ -2285,22 +2278,26 @@ isp_scan_fabric(struct ispsoftc *isp)
first_portid = portid = fcp->isp_portid;
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
+
for (first_portid_seen = hicap = 0; hicap < 65535; hicap++) {
- MEMZERO((void *) reqp, SNS_GAN_REQ_SIZE);
- reqp->snscb_rblen = SNS_GAN_RESP_SIZE >> 1;
- reqp->snscb_addr[RQRSP_ADDR0015] =
- DMA_WD0(fcp->isp_scdma + 0x100);
- reqp->snscb_addr[RQRSP_ADDR1631] =
- DMA_WD1(fcp->isp_scdma + 0x100);
- reqp->snscb_addr[RQRSP_ADDR3247] =
- DMA_WD2(fcp->isp_scdma + 0x100);
- reqp->snscb_addr[RQRSP_ADDR4863] =
- DMA_WD3(fcp->isp_scdma + 0x100);
- reqp->snscb_sblen = 6;
- reqp->snscb_data[0] = SNS_GAN;
- reqp->snscb_data[4] = portid & 0xffff;
- reqp->snscb_data[5] = (portid >> 16) & 0xff;
- ISP_SWIZZLE_SNS_REQ(isp, reqp);
+ mbreg_t mbs;
+ sns_screq_t *rq;
+ sns_scrsp_t *rs0, *rs1;
+ u_int8_t sc[SNS_GAN_REQ_SIZE];
+
+ rq = (sns_screq_t *)sc;
+ MEMZERO((void *) rq, SNS_GAN_REQ_SIZE);
+ rq->snscb_rblen = SNS_GAN_RESP_SIZE >> 1;
+ rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
+ rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
+ rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
+ rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
+ rq->snscb_sblen = 6;
+ rq->snscb_data[0] = SNS_GAN;
+ rq->snscb_data[4] = portid & 0xffff;
+ 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_GAN_REQ_SIZE);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GAN_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2351,11 +2348,14 @@ isp_scan_fabric(struct ispsoftc *isp)
fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
return (-1);
}
- ISP_UNSWIZZLE_SNS_RSP(isp, resp, SNS_GAN_RESP_SIZE >> 1);
- portid = (((u_int32_t) resp->snscb_port_id[0]) << 16) |
- (((u_int32_t) resp->snscb_port_id[1]) << 8) |
- (((u_int32_t) resp->snscb_port_id[2]));
- (void) isp_async(isp, ISPASYNC_FABRIC_DEV, resp);
+ MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GAN_RESP_SIZE);
+ rs1 = (sns_scrsp_t *) fcp->isp_scratch;
+ rs0 = (sns_scrsp_t *) ((u_int8_t *)fcp->isp_scratch + 0x100);
+ isp_get_sns_response(isp, rs0, rs1, SNS_GAN_RESP_SIZE >> 1);
+ portid = (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
+ (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
+ (((u_int32_t) rs1->snscb_port_id[2]));
+ (void) isp_async(isp, ISPASYNC_FABRIC_DEV, rs1);
if (first_portid == portid) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
@@ -2386,10 +2386,10 @@ static void
isp_register_fc4_type(struct ispsoftc *isp)
{
fcparam *fcp = isp->isp_param;
- sns_screq_t *reqp;
+ u_int8_t local[SNS_RFT_REQ_SIZE];
+ sns_screq_t *reqp = (sns_screq_t *) local;
mbreg_t mbs;
- reqp = (sns_screq_t *) fcp->isp_scratch;
MEMZERO((void *) reqp, SNS_RFT_REQ_SIZE);
reqp->snscb_rblen = SNS_RFT_RESP_SIZE >> 1;
reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
@@ -2404,7 +2404,7 @@ isp_register_fc4_type(struct ispsoftc *isp)
#if 0
reqp->snscb_data[6] |= 20; /* ISO/IEC 8802-2 LLC/SNAP */
#endif
- ISP_SWIZZLE_SNS_REQ(isp, reqp);
+ isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_RFT_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
@@ -2428,14 +2428,9 @@ int
isp_start(XS_T *xs)
{
struct ispsoftc *isp;
- u_int16_t iptr, optr, handle;
- union {
- ispreq_t *_reqp;
- ispreqt2_t *_t2reqp;
- } _u;
-#define reqp _u._reqp
-#define t2reqp _u._t2reqp
-#define UZSIZE max(sizeof (ispreq_t), sizeof (ispreqt2_t))
+ u_int16_t nxti, optr, handle;
+ u_int8_t local[QENTRY_LEN];
+ ispreq_t *reqp, *qep;
int target, i;
XS_INITERR(xs);
@@ -2667,7 +2662,7 @@ isp_start(XS_T *xs)
isp_update(isp);
}
- if (isp_getrqentry(isp, &iptr, &optr, (void **) &reqp)) {
+ if (isp_getrqentry(isp, &nxti, &optr, (void **)&qep)) {
isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
@@ -2678,6 +2673,7 @@ isp_start(XS_T *xs)
* We do dual duty here (cough) for synchronizing for busses other
* than which we got here to send a command to.
*/
+ reqp = (ispreq_t *) local;
if (isp->isp_sendmarker) {
u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
/*
@@ -2687,15 +2683,15 @@ isp_start(XS_T *xs)
if ((isp->isp_sendmarker & (1 << i)) == 0) {
continue;
}
- MEMZERO((void *) reqp, sizeof (*reqp));
+ MEMZERO((void *) reqp, QENTRY_LEN);
reqp->req_header.rqs_entry_count = 1;
reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
reqp->req_modifier = SYNC_ALL;
reqp->req_target = i << 7; /* insert bus number */
- ISP_SWIZZLE_REQUEST(isp, reqp);
- ISP_ADD_REQUEST(isp, iptr);
-
- if (isp_getrqentry(isp, &iptr, &optr, (void **)&reqp)) {
+ isp_put_request(isp, reqp, qep);
+ ISP_ADD_REQUEST(isp, nxti);
+ isp->isp_sendmarker &= ~(1 << i);
+ if (isp_getrqentry(isp, &nxti, &optr, (void **) &qep)) {
isp_prt(isp, ISP_LOGDEBUG0,
"Request Queue Overflow+");
XS_SETERR(xs, HBA_BOTCH);
@@ -2704,7 +2700,7 @@ isp_start(XS_T *xs)
}
}
- MEMZERO((void *) reqp, UZSIZE);
+ MEMZERO((void *)reqp, QENTRY_LEN);
reqp->req_header.rqs_entry_count = 1;
if (IS_FC(isp)) {
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
@@ -2728,16 +2724,16 @@ isp_start(XS_T *xs)
* but this breaks for some devices (IBM drives).
*/
if (XS_TAG_P(xs)) {
- t2reqp->req_flags = XS_TAG_TYPE(xs);
+ ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
} else {
/*
* If we don't know what tag to use, use HEAD OF QUEUE
* for Request Sense or Simple.
*/
if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */
- t2reqp->req_flags = REQFLAG_HTAG;
+ ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
else
- t2reqp->req_flags = REQFLAG_STAG;
+ ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
}
} else {
sdparam *sdp = (sdparam *)isp->isp_param;
@@ -2753,34 +2749,29 @@ isp_start(XS_T *xs)
reqp->req_cdblen = XS_CDBLEN(xs);
} else {
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
- t2reqp->req_scclun = XS_LUN(xs);
+ ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
else
- t2reqp->req_lun_trn = XS_LUN(xs);
+ ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
}
MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
reqp->req_time = XS_TIME(xs) / 1000;
- if (reqp->req_time == 0 && XS_TIME(xs))
+ if (reqp->req_time == 0 && XS_TIME(xs)) {
reqp->req_time = 1;
-
- /*
- * Always give a bit more leeway to commands after a bus reset.
- * XXX: DOES NOT DISTINGUISH WHICH PORT MAY HAVE BEEN SYNCED
- */
- if (isp->isp_sendmarker && reqp->req_time < 5) {
- reqp->req_time = 5;
}
+
if (isp_save_xs(isp, xs, &handle)) {
isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
reqp->req_handle = handle;
+
/*
* Set up DMA and/or do any bus swizzling of the request entry
* so that the Qlogic F/W understands what is being asked of it.
- */
- i = ISP_DMASETUP(isp, xs, reqp, &iptr, optr);
+ */
+ i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
if (i != CMD_QUEUED) {
isp_destroy_handle(isp, handle);
/*
@@ -2794,13 +2785,9 @@ isp_start(XS_T *xs)
"START cmd for %d.%d.%d cmd 0x%x datalen %ld",
XS_CHANNEL(xs), target, XS_LUN(xs), XS_CDBP(xs)[0],
(long) XS_XFRLEN(xs));
- ISP_ADD_REQUEST(isp, iptr);
+ ISP_ADD_REQUEST(isp, nxti);
isp->isp_nactive++;
- if (isp->isp_sendmarker)
- isp->isp_sendmarker = 0;
return (CMD_QUEUED);
-#undef reqp
-#undef t2reqp
}
/*
@@ -3007,8 +2994,8 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
*/
if (sema) {
if (mbox & 0x4000) {
- int obits, i = 0;
- if ((obits = isp->isp_mboxbsy) != 0) {
+ if (isp->isp_mboxbsy) {
+ int i = 0, obits = isp->isp_obits;
isp->isp_mboxtmp[i++] = mbox;
for (i = 1; i < MAX_MAILBOX; i++) {
if ((obits & (1 << i)) == 0) {
@@ -3119,25 +3106,38 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
ISP_WRITE(isp, BIU_SEMA, 0);
while (optr != iptr) {
- ispstatusreq_t *sp;
+ ispstatusreq_t local, *sp = &local;
+ isphdr_t *hp;
+ int type;
u_int16_t oop;
int buddaboom = 0;
- sp = (ispstatusreq_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
+ hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
oop = optr;
optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
nlooked++;
/*
- * Do any appropriate unswizzling of what the Qlogic f/w has
- * written into memory so it makes sense to us. This is a
- * per-platform thing. Also includes any memory barriers.
+ * Synchronize our view of this response queue entry.
*/
- ISP_UNSWIZZLE_RESPONSE(isp, sp, oop);
- if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
- if (isp_handle_other_response(isp, sp, &optr) == 0) {
- MEMZERO(sp, sizeof (isphdr_t));
+ MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
+
+ type = isp_get_response_type(isp, hp);
+
+ if (type == RQSTYPE_RESPONSE) {
+ isp_get_response(isp, (ispstatusreq_t *) hp, sp);
+ } else {
+ if (!isp_handle_other_response(isp, type, hp, &optr)) {
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
}
+
+ /*
+ * After this point, we'll just look at the header as
+ * we don't know how to deal with the rest of the
+ * response.
+ */
+ isp_get_response(isp, (ispstatusreq_t *) hp, sp);
+
/*
* It really has to be a bounced request just copied
* from the request queue to the response queue. If
@@ -3151,7 +3151,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
isp_print_bytes(isp, "Queue Entry",
QENTRY_LEN, sp);
}
- MEMZERO(sp, sizeof (isphdr_t));
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
}
buddaboom = 1;
@@ -3190,7 +3190,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
#undef _RQS_OFLAGS
}
if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
- MEMZERO(sp, sizeof (isphdr_t));
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
isp_prt(isp, ISP_LOGERR,
"bad request handle %d (type 0x%x, flags 0x%x)",
sp->req_handle, sp->req_header.rqs_entry_type,
@@ -3200,7 +3200,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
}
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
- MEMZERO(sp, sizeof (isphdr_t));
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x in xflist",
sp->req_handle);
@@ -3209,6 +3209,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
}
isp_destroy_handle(isp, sp->req_handle);
if (sp->req_status_flags & RQSTF_BUS_RESET) {
+ XS_SETERR(xs, HBA_BUSRESET);
isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
}
if (buddaboom) {
@@ -3332,7 +3333,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
if (isp->isp_nactive > 0)
isp->isp_nactive--;
complist[ndone++] = xs; /* defer completion call until later */
- MEMZERO(sp, sizeof (isphdr_t));
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
if (ndone == MAX_REQUESTQ_COMPLETIONS) {
break;
}
@@ -3651,10 +3652,10 @@ isp_parse_async(struct ispsoftc *isp, int mbox)
*/
static int
-isp_handle_other_response(struct ispsoftc *isp,
- ispstatusreq_t *sp, u_int16_t *optrp)
+isp_handle_other_response(struct ispsoftc *isp, int type,
+ isphdr_t *hp, u_int16_t *optrp)
{
- switch (sp->req_header.rqs_entry_type) {
+ switch (type) {
case RQSTYPE_STATUS_CONT:
isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
return (0);
@@ -3669,18 +3670,18 @@ isp_handle_other_response(struct ispsoftc *isp,
case RQSTYPE_CTIO2:
case RQSTYPE_CTIO3:
#ifdef ISP_TARGET_MODE
- return (isp_target_notify(isp, sp, optrp));
+ return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp));
#else
optrp = optrp;
/* FALLTHROUGH */
#endif
case RQSTYPE_REQUEST:
default:
- if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, sp)) {
+ if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
return (0);
}
isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
- sp->req_header.rqs_entry_type);
+ isp_get_response_type(isp, hp));
return (-1);
}
}
@@ -4568,7 +4569,8 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
/*
* We assume that we can't overwrite a previous command.
*/
- isp->isp_mboxbsy = obits;
+ isp->isp_obits = obits;
+ isp->isp_mboxbsy = 1;
/*
* Set Host Interrupt condition so that RISC will pick up mailbox regs.
@@ -4580,6 +4582,15 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
*/
MBOX_WAIT_COMPLETE(isp);
+ if (isp->isp_mboxbsy) {
+ /*
+ * Command timed out.
+ */
+ isp->isp_mboxbsy = 0;
+ MBOX_RELEASE(isp);
+ return;
+ }
+
/*
* Copy back output registers.
*/
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index b4c606e..dd2be33 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -929,15 +929,16 @@ isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
void *qe;
struct ccb_scsiio *cso = &ccb->csio;
u_int16_t *hp, save_handle;
- u_int16_t iptr, optr;
+ u_int16_t nxti, optr;
+ u_int8_t local[QENTRY_LEN];
- if (isp_getrqentry(isp, &iptr, &optr, &qe)) {
+ if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
xpt_print_path(ccb->ccb_h.path);
printf("Request Queue Overflow in isp_target_start_ctio\n");
return (CAM_RESRC_UNAVAIL);
}
- bzero(qe, QENTRY_LEN);
+ bzero(local, QENTRY_LEN);
/*
* We're either moving data or completing a command here.
@@ -945,7 +946,7 @@ isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
if (IS_FC(isp)) {
atio_private_data_t *atp;
- ct2_entry_t *cto = qe;
+ ct2_entry_t *cto = (ct2_entry_t *) local;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
cto->ct_header.rqs_entry_count = 1;
@@ -1008,7 +1009,7 @@ isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
cto->ct_timeout = 10;
hp = &cto->ct_syshandle;
} else {
- ct_entry_t *cto = qe;
+ ct_entry_t *cto = (ct_entry_t *) local;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
cto->ct_header.rqs_entry_count = 1;
@@ -1063,9 +1064,9 @@ isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
save_handle = *hp;
- switch (ISP_DMASETUP(isp, cso, qe, &iptr, optr)) {
+ switch (ISP_DMASETUP(isp, cso, (ispreq_t *) local, &nxti, optr)) {
case CMD_QUEUED:
- ISP_ADD_REQUEST(isp, iptr);
+ ISP_ADD_REQUEST(isp, nxti);
return (CAM_REQ_INPROG);
case CMD_EAGAIN:
@@ -1092,12 +1093,12 @@ isp_target_putback_atio(union ccb *ccb)
{
struct ispsoftc *isp;
struct ccb_scsiio *cso;
- u_int16_t iptr, optr;
+ u_int16_t nxti, optr;
void *qe;
isp = XS_ISP(ccb);
- if (isp_getrqentry(isp, &iptr, &optr, &qe)) {
+ if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
(void) timeout(isp_refire_putback_atio, ccb, 10);
isp_prt(isp, ISP_LOGWARN,
"isp_target_putback_atio: Request Queue Overflow");
@@ -1106,7 +1107,8 @@ isp_target_putback_atio(union ccb *ccb)
bzero(qe, QENTRY_LEN);
cso = &ccb->csio;
if (IS_FC(isp)) {
- at2_entry_t *at = qe;
+ at2_entry_t local, *at = &local;
+ MEMZERO(at, sizeof (at2_entry_t));
at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
at->at_header.rqs_entry_count = 1;
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
@@ -1116,9 +1118,10 @@ isp_target_putback_atio(union ccb *ccb)
}
at->at_status = CT_OK;
at->at_rxid = cso->tag_id;
- ISP_SWIZ_ATIO2(isp, qe, qe);
+ isp_put_atio2(isp, at, qe);
} else {
- at_entry_t *at = qe;
+ at_entry_t local, *at = &local;
+ MEMZERO(at, sizeof (at_entry_t));
at->at_header.rqs_entry_type = RQSTYPE_ATIO;
at->at_header.rqs_entry_count = 1;
at->at_iid = cso->init_id;
@@ -1128,10 +1131,10 @@ isp_target_putback_atio(union ccb *ccb)
at->at_status = CT_OK;
at->at_tag_val = AT_GET_TAG(cso->tag_id);
at->at_handle = AT_GET_HANDLE(cso->tag_id);
- ISP_SWIZ_ATIO(isp, qe, qe);
+ isp_put_atio(isp, at, qe);
}
ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe);
- ISP_ADD_REQUEST(isp, iptr);
+ ISP_ADD_REQUEST(isp, nxti);
isp_complete_ctio(ccb);
}
@@ -1666,12 +1669,12 @@ isp_watchdog(void *arg)
XS_CMD_C_WDOG(xs);
isp_done(xs);
} else {
- u_int16_t iptr, optr;
- ispreq_t *mp;
+ u_int16_t nxti, optr;
+ ispreq_t local, *mp= &local, *qe;
XS_CMD_C_WDOG(xs);
xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz);
- if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) {
+ if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) {
ISP_UNLOCK(isp);
return;
}
@@ -1681,8 +1684,8 @@ isp_watchdog(void *arg)
mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
mp->req_modifier = SYNC_ALL;
mp->req_target = XS_CHANNEL(xs) << 7;
- ISP_SWIZZLE_REQUEST(isp, mp);
- ISP_ADD_REQUEST(isp, iptr);
+ isp_put_request(isp, mp, qe);
+ ISP_ADD_REQUEST(isp, nxti);
}
} else {
isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command");
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 66533ca..fbf9def 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -60,12 +60,21 @@
#include "opt_ddb.h"
#include "opt_isp.h"
+/*
+ * Efficiency- get rid of SBus code && tests unless we need them.
+ */
+#if defined(__sparcv9__ ) || defined(__sparc__)
+#define ISP_SBUS_SUPPORTED 1
+#else
+#define ISP_SBUS_SUPPORTED 0
+#endif
#define HANDLE_LOOPSTATE_IN_OUTER_LAYERS 1
typedef void ispfwfunc __P((int, int, int, const u_int16_t **));
#ifdef ISP_TARGET_MODE
+#define ISP_TARGET_FUNCTIONS 1
#define ATPDPSIZE 256
typedef struct {
u_int32_t orig_datalen;
@@ -264,14 +273,38 @@ struct isposinfo {
#define ISP_NODEWWN(isp) FCPARAM(isp)->isp_nodewwn
#define ISP_PORTWWN(isp) FCPARAM(isp)->isp_portwwn
-#define ISP_UNSWIZZLE_AND_COPY_PDBP(isp, dest, src) \
- if((void *)src != (void *)dest) bcopy(src, dest, sizeof (isp_pdb_t))
-#define ISP_SWIZZLE_ICB(a, b)
-#define ISP_SWIZZLE_REQUEST(a, b)
-#define ISP_UNSWIZZLE_RESPONSE(a, b, c)
-#define ISP_SWIZZLE_SNS_REQ(a, b)
-#define ISP_UNSWIZZLE_SNS_RSP(a, b, c)
-#define ISP_SWIZZLE_NVRAM_WORD(isp, x)
+#if BYTE_ORDER == BIG_ENDIAN
+#ifdef ISP_SBUS_SUPPORTED
+#define ISP_IOXPUT_8(isp, s, d) *(d) = s
+#define ISP_IOXPUT_16(isp, s, d) \
+ *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s)
+#define ISP_IOXPUT_32(isp, s, d) \
+ *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s)
+#define ISP_IOXGET_8(isp, s, d) d = (*((u_int8_t *)s))
+#define ISP_IOXGET_16(isp, s, d) \
+ d = (isp->isp_bustype == ISP_BT_SBUS)? \
+ *((u_int16_t *)s) : bswap16(*((u_int16_t *)s))
+#define ISP_IOXGET_32(isp, s, d) \
+ d = (isp->isp_bustype == ISP_BT_SBUS)? \
+ *((u_int32_t *)s) : bswap32(*((u_int32_t *)s))
+#else
+#define ISP_IOXPUT_8(isp, s, d) *(d) = s
+#define ISP_IOXPUT_16(isp, s, d) *(d) = bswap16(s)
+#define ISP_IOXPUT_32(isp, s, d) *(d) = bswap32(s)
+#define ISP_IOXGET_8(isp, s, d) d = (*((u_int8_t *)s))
+#define ISP_IOXGET_16(isp, s, d) d = bswap16(*((u_int16_t *)s))
+#define ISP_IOXGET_32(isp, s, d) d = bswap32(*((u_int32_t *)s))
+#endif
+#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = bswap16(*rp)
+#else
+#define ISP_IOXPUT_8(isp, s, d) *(d) = s
+#define ISP_IOXPUT_16(isp, s, d) *(d) = s
+#define ISP_IOXPUT_32(isp, s, d) *(d) = s
+#define ISP_IOXGET_8(isp, s, d) d = *(s)
+#define ISP_IOXGET_16(isp, s, d) d = *(s)
+#define ISP_IOXGET_32(isp, s, d) d = *(s)
+#define ISP_SWIZZLE_NVRAM_WORD(isp, rp)
+#endif
/*
* Includes of common header files
diff --git a/sys/dev/isp/isp_inline.h b/sys/dev/isp/isp_inline.h
index fe7ed4b..9dd9004 100644
--- a/sys/dev/isp/isp_inline.h
+++ b/sys/dev/isp/isp_inline.h
@@ -236,4 +236,1052 @@ isp_fc_runstate(struct ispsoftc *isp, int tval)
}
return (0);
}
+
+/*
+ * Functions to move stuff to a form that the QLogic RISC engine understands
+ * and functions to move stuff back to a form the processor understands.
+ *
+ * Each platform is required to provide the 8, 16 and 32 bit
+ * swizzle and unswizzle macros (ISP_IOX{PUT|GET}_{8,16,32})
+ *
+ * The assumption is that swizzling and unswizzling is mostly done 'in place'
+ * (with a few exceptions for efficiency).
+ */
+
+static INLINE void isp_copy_out_hdr(struct ispsoftc *, isphdr_t *, isphdr_t *);
+static INLINE void isp_copy_in_hdr(struct ispsoftc *, isphdr_t *, isphdr_t *);
+static INLINE int isp_get_response_type(struct ispsoftc *, isphdr_t *);
+
+static INLINE void
+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_t3(struct ispsoftc *, ispreqt3_t *, ispreqt3_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 *);
+static INLINE void
+isp_put_cont64_req(struct ispsoftc *, ispcontreq64_t *, ispcontreq64_t *);
+static INLINE void
+isp_get_response(struct ispsoftc *, ispstatusreq_t *, ispstatusreq_t *);
+static INLINE void
+isp_get_response_x(struct ispsoftc *, ispstatus_cont_t *, ispstatus_cont_t *);
+static INLINE void
+isp_put_icb(struct ispsoftc *, isp_icb_t *, isp_icb_t *);
+static INLINE void
+isp_get_pdb(struct ispsoftc *, isp_pdb_t *, isp_pdb_t *);
+static INLINE void
+isp_put_sns_request(struct ispsoftc *, sns_screq_t *, sns_screq_t *);
+static INLINE void
+isp_get_sns_response(struct ispsoftc *, sns_scrsp_t *, sns_scrsp_t *, int);
+#ifdef ISP_TARGET_MODE
+#ifndef _ISP_TARGET_H
+#include "isp_target.h"
+#endif
+static INLINE void
+isp_put_atio(struct ispsoftc *, at_entry_t *, at_entry_t *);
+static INLINE void
+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_get_atio2(struct ispsoftc *, at2_entry_t *, at2_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_get_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_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 *);
+static INLINE void
+isp_put_notify(struct ispsoftc *, in_entry_t *, in_entry_t *);
+static INLINE void
+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_get_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_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_get_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
+#endif
+
+#define ISP_IS_SBUS(isp) \
+ (ISP_SBUS_SUPPORTED && (isp)->isp_bustype == ISP_BT_SBUS)
+
+/*
+ * Swizzle/Copy Functions
+ */
+static INLINE void
+isp_copy_out_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
+{
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, hpsrc->rqs_entry_type,
+ &hpdst->rqs_entry_count);
+ ISP_IOXPUT_8(isp, hpsrc->rqs_entry_count,
+ &hpdst->rqs_entry_type);
+ ISP_IOXPUT_8(isp, hpsrc->rqs_seqno,
+ &hpdst->rqs_flags);
+ ISP_IOXPUT_8(isp, hpsrc->rqs_flags,
+ &hpdst->rqs_seqno);
+ } else {
+ ISP_IOXPUT_8(isp, hpsrc->rqs_entry_type,
+ &hpdst->rqs_entry_type);
+ ISP_IOXPUT_8(isp, hpsrc->rqs_entry_count,
+ &hpdst->rqs_entry_count);
+ ISP_IOXPUT_8(isp, hpsrc->rqs_seqno,
+ &hpdst->rqs_seqno);
+ ISP_IOXPUT_8(isp, hpsrc->rqs_flags,
+ &hpdst->rqs_flags);
+ }
+}
+
+static INLINE void
+isp_copy_in_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
+{
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &hpsrc->rqs_entry_type,
+ hpdst->rqs_entry_count);
+ ISP_IOXGET_8(isp, &hpsrc->rqs_entry_count,
+ hpdst->rqs_entry_type);
+ ISP_IOXGET_8(isp, &hpsrc->rqs_seqno,
+ hpdst->rqs_flags);
+ ISP_IOXGET_8(isp, &hpsrc->rqs_flags,
+ hpdst->rqs_seqno);
+ } else {
+ ISP_IOXGET_8(isp, &hpsrc->rqs_entry_type,
+ hpdst->rqs_entry_type);
+ ISP_IOXGET_8(isp, &hpsrc->rqs_entry_count,
+ hpdst->rqs_entry_count);
+ ISP_IOXGET_8(isp, &hpsrc->rqs_seqno,
+ hpdst->rqs_seqno);
+ ISP_IOXGET_8(isp, &hpsrc->rqs_flags,
+ hpdst->rqs_flags);
+ }
+}
+
+static INLINE int
+isp_get_response_type(struct ispsoftc *isp, isphdr_t *hp)
+{
+ uint8_t type;
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &hp->rqs_entry_count, type);
+ } else {
+ ISP_IOXGET_8(isp, &hp->rqs_entry_type, type);
+ }
+ return ((int)type);
+}
+
+static INLINE void
+isp_put_request(struct ispsoftc *isp, ispreq_t *rqsrc, ispreq_t *rqdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &rqsrc->req_header, &rqdst->req_header);
+ ISP_IOXPUT_32(isp, rqsrc->req_handle, &rqdst->req_handle);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, rqsrc->req_lun_trn, &rqdst->req_target);
+ ISP_IOXPUT_8(isp, rqsrc->req_target, &rqdst->req_lun_trn);
+ } else {
+ ISP_IOXPUT_8(isp, rqsrc->req_lun_trn, &rqdst->req_lun_trn);
+ ISP_IOXPUT_8(isp, rqsrc->req_target, &rqdst->req_target);
+ }
+ ISP_IOXPUT_16(isp, rqsrc->req_cdblen, &rqdst->req_cdblen);
+ ISP_IOXPUT_16(isp, rqsrc->req_flags, &rqdst->req_flags);
+ ISP_IOXPUT_16(isp, rqsrc->req_time, &rqdst->req_time);
+ ISP_IOXPUT_16(isp, rqsrc->req_seg_count, &rqdst->req_seg_count);
+ for (i = 0; i < 12; i++) {
+ ISP_IOXPUT_8(isp, rqsrc->req_cdb[i], &rqdst->req_cdb[i]);
+ }
+ for (i = 0; i < ISP_RQDSEG; i++) {
+ ISP_IOXPUT_32(isp, rqsrc->req_dataseg[i].ds_base,
+ &rqdst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, rqsrc->req_dataseg[i].ds_count,
+ &rqdst->req_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
+isp_put_request_t2(struct ispsoftc *isp, ispreqt2_t *tqsrc, ispreqt2_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_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn);
+ ISP_IOXPUT_8(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;
+ isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
+ ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
+ ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn);
+ ISP_IOXPUT_8(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_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)
+{
+ int i;
+ isp_copy_out_hdr(isp, &xqsrc->req_header, &xqdst->req_header);
+ ISP_IOXPUT_32(isp, xqsrc->req_handle, &xqdst->req_handle);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_target);
+ ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_lun_trn);
+ } else {
+ ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_lun_trn);
+ ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_target);
+ }
+ ISP_IOXPUT_16(isp, xqsrc->req_cdblen, &xqdst->req_cdblen);
+ ISP_IOXPUT_16(isp, xqsrc->req_flags, &xqdst->req_flags);
+ ISP_IOXPUT_16(isp, xqsrc->req_time, &xqdst->req_time);
+ ISP_IOXPUT_16(isp, xqsrc->req_seg_count, &xqdst->req_seg_count);
+ for (i = 0; i < 44; i++) {
+ ISP_IOXPUT_8(isp, xqsrc->req_cdb[i], &xqdst->req_cdb[i]);
+ }
+}
+
+static INLINE void
+isp_put_cont_req(struct ispsoftc *isp, ispcontreq_t *cqsrc, ispcontreq_t *cqdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &cqsrc->req_header, &cqdst->req_header);
+ for (i = 0; i < ISP_CDSEG; i++) {
+ ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_base,
+ &cqdst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_count,
+ &cqdst->req_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
+isp_put_cont64_req(struct ispsoftc *isp, ispcontreq64_t *cqsrc,
+ ispcontreq64_t *cqdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &cqsrc->req_header, &cqdst->req_header);
+ for (i = 0; i < ISP_CDSEG64; i++) {
+ ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_base,
+ &cqdst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_basehi,
+ &cqdst->req_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_count,
+ &cqdst->req_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
+isp_get_response(struct ispsoftc *isp, ispstatusreq_t *spsrc,
+ ispstatusreq_t *spdst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &spsrc->req_header, &spdst->req_header);
+ ISP_IOXGET_32(isp, &spsrc->req_handle, spdst->req_handle);
+ ISP_IOXGET_16(isp, &spsrc->req_scsi_status, spdst->req_scsi_status);
+ ISP_IOXGET_16(isp, &spsrc->req_completion_status,
+ spdst->req_completion_status);
+ ISP_IOXGET_16(isp, &spsrc->req_state_flags, spdst->req_state_flags);
+ ISP_IOXGET_16(isp, &spsrc->req_status_flags, spdst->req_status_flags);
+ ISP_IOXGET_16(isp, &spsrc->req_time, spdst->req_time);
+ ISP_IOXGET_16(isp, &spsrc->req_sense_len, spdst->req_sense_len);
+ ISP_IOXGET_32(isp, &spsrc->req_resid, spdst->req_resid);
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &spsrc->req_response[i],
+ spdst->req_response[i]);
+ }
+ for (i = 0; i < 32; i++) {
+ ISP_IOXGET_8(isp, &spsrc->req_sense_data[i],
+ spdst->req_sense_data[i]);
+ }
+}
+
+static INLINE void
+isp_get_response_x(struct ispsoftc *isp, ispstatus_cont_t *cpsrc,
+ ispstatus_cont_t *cpdst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &cpsrc->req_header, &cpdst->req_header);
+ for (i = 0; i < 60; i++) {
+ ISP_IOXGET_8(isp, &cpsrc->req_sense_data[i],
+ cpdst->req_sense_data[i]);
+ }
+}
+
+static INLINE void
+isp_put_icb(struct ispsoftc *isp, isp_icb_t *Is, isp_icb_t *Id)
+{
+ int i;
+ ISP_SWAP8(Is->icb_version, Is->_reserved0);
+ ISP_IOXPUT_8(isp, Is->icb_version, &Id->icb_version);
+ ISP_IOXPUT_8(isp, Is->_reserved0, &Id->_reserved0);
+ ISP_IOXPUT_16(isp, Is->icb_fwoptions, &Id->icb_fwoptions);
+ ISP_IOXPUT_16(isp, Is->icb_maxfrmlen, &Id->icb_maxfrmlen);
+ ISP_IOXPUT_16(isp, Is->icb_maxalloc, &Id->icb_maxalloc);
+ ISP_IOXPUT_16(isp, Is->icb_execthrottle, &Id->icb_execthrottle);
+ ISP_SWAP8(Is->icb_retry_count, Is->icb_retry_delay);
+ ISP_IOXPUT_8(isp, Is->icb_retry_count, &Id->icb_retry_count);
+ ISP_IOXPUT_8(isp, Is->icb_retry_delay, &Id->icb_retry_delay);
+ for (i = 0; i < 8; i++) {
+ ISP_IOXPUT_8(isp, Is->icb_portname[i], &Id->icb_portname[i]);
+ }
+ ISP_IOXPUT_16(isp, Is->icb_hardaddr, &Id->icb_hardaddr);
+ ISP_SWAP8(Is->icb_iqdevtype, Is->icb_logintime);
+ ISP_IOXPUT_8(isp, Is->icb_iqdevtype, &Id->icb_iqdevtype);
+ ISP_IOXPUT_8(isp, Is->icb_logintime, &Id->icb_logintime);
+ for (i = 0; i < 8; i++) {
+ ISP_IOXPUT_8(isp, Is->icb_nodename[i], &Id->icb_nodename[i]);
+ }
+ ISP_IOXPUT_16(isp, Is->icb_rqstout, &Id->icb_rqstout);
+ ISP_IOXPUT_16(isp, Is->icb_rspnsin, &Id->icb_rspnsin);
+ ISP_IOXPUT_16(isp, Is->icb_rqstqlen, &Id->icb_rqstqlen);
+ ISP_IOXPUT_16(isp, Is->icb_rsltqlen, &Id->icb_rsltqlen);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, Is->icb_rqstaddr[i], &Id->icb_rqstaddr[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, Is->icb_respaddr[i], &Id->icb_respaddr[i]);
+ }
+ ISP_IOXPUT_16(isp, Is->icb_lunenables, &Id->icb_lunenables);
+ ISP_SWAP8(Is->icb_ccnt, Is->icb_icnt);
+ ISP_IOXPUT_8(isp, Is->icb_ccnt, &Id->icb_ccnt);
+ ISP_IOXPUT_8(isp, Is->icb_icnt, &Id->icb_icnt);
+ ISP_IOXPUT_16(isp, Is->icb_lunetimeout, &Id->icb_lunetimeout);
+ ISP_IOXPUT_16(isp, Is->icb_xfwoptions, &Id->icb_xfwoptions);
+ ISP_SWAP8(Is->icb_racctimer, Is->icb_idelaytimer);
+ ISP_IOXPUT_8(isp, Is->icb_racctimer, &Id->icb_racctimer);
+ ISP_IOXPUT_8(isp, Is->icb_idelaytimer, &Id->icb_idelaytimer);
+ ISP_IOXPUT_16(isp, Is->icb_zfwoptions, &Id->icb_zfwoptions);
+}
+
+static INLINE void
+isp_get_pdb(struct ispsoftc *isp, isp_pdb_t *src, isp_pdb_t *dst)
+{
+ int i;
+ ISP_IOXGET_16(isp, &src->pdb_options, dst->pdb_options);
+ ISP_IOXGET_8(isp, &src->pdb_mstate, dst->pdb_mstate);
+ ISP_IOXGET_8(isp, &src->pdb_sstate, dst->pdb_sstate);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_hardaddr_bits[i],
+ dst->pdb_hardaddr_bits[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_portid_bits[i],
+ dst->pdb_portid_bits[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_nodename[i], dst->pdb_nodename[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_portname[i], dst->pdb_portname[i]);
+ }
+ ISP_IOXGET_16(isp, &src->pdb_execthrottle, dst->pdb_execthrottle);
+ ISP_IOXGET_16(isp, &src->pdb_exec_count, dst->pdb_exec_count);
+ ISP_IOXGET_8(isp, &src->pdb_retry_count, dst->pdb_retry_count);
+ ISP_IOXGET_8(isp, &src->pdb_retry_delay, dst->pdb_retry_delay);
+ ISP_IOXGET_16(isp, &src->pdb_resalloc, dst->pdb_resalloc);
+ ISP_IOXGET_16(isp, &src->pdb_curalloc, dst->pdb_curalloc);
+ ISP_IOXGET_16(isp, &src->pdb_qhead, dst->pdb_qhead);
+ ISP_IOXGET_16(isp, &src->pdb_qtail, dst->pdb_qtail);
+ ISP_IOXGET_16(isp, &src->pdb_tl_next, dst->pdb_tl_next);
+ ISP_IOXGET_16(isp, &src->pdb_tl_last, dst->pdb_tl_last);
+ ISP_IOXGET_16(isp, &src->pdb_features, dst->pdb_features);
+ ISP_IOXGET_16(isp, &src->pdb_pconcurrnt, dst->pdb_pconcurrnt);
+ ISP_IOXGET_16(isp, &src->pdb_roi, dst->pdb_roi);
+ ISP_IOXGET_8(isp, &src->pdb_target, dst->pdb_target);
+ ISP_IOXGET_8(isp, &src->pdb_initiator, dst->pdb_initiator);
+ ISP_IOXGET_16(isp, &src->pdb_rdsiz, dst->pdb_rdsiz);
+ ISP_IOXGET_16(isp, &src->pdb_ncseq, dst->pdb_ncseq);
+ ISP_IOXGET_16(isp, &src->pdb_noseq, dst->pdb_noseq);
+ ISP_IOXGET_16(isp, &src->pdb_labrtflg, dst->pdb_labrtflg);
+ ISP_IOXGET_16(isp, &src->pdb_lstopflg, dst->pdb_lstopflg);
+ ISP_IOXGET_16(isp, &src->pdb_sqhead, dst->pdb_sqhead);
+ ISP_IOXGET_16(isp, &src->pdb_sqtail, dst->pdb_sqtail);
+ ISP_IOXGET_16(isp, &src->pdb_ptimer, dst->pdb_ptimer);
+ ISP_IOXGET_16(isp, &src->pdb_nxt_seqid, dst->pdb_nxt_seqid);
+ ISP_IOXGET_16(isp, &src->pdb_fcount, dst->pdb_fcount);
+ ISP_IOXGET_16(isp, &src->pdb_prli_len, dst->pdb_prli_len);
+ ISP_IOXGET_16(isp, &src->pdb_prli_svc0, dst->pdb_prli_svc0);
+ ISP_IOXGET_16(isp, &src->pdb_prli_svc3, dst->pdb_prli_svc3);
+ ISP_IOXGET_16(isp, &src->pdb_loopid, dst->pdb_loopid);
+ ISP_IOXGET_16(isp, &src->pdb_il_ptr, dst->pdb_il_ptr);
+ ISP_IOXGET_16(isp, &src->pdb_sl_ptr, dst->pdb_sl_ptr);
+}
+
+static INLINE void
+isp_put_sns_request(struct ispsoftc *isp, sns_screq_t *src, sns_screq_t *dst)
+{
+ int i, nw = (int) src->snscb_sblen;
+ ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->snscb_addr[i], &dst->snscb_addr[i]);
+ }
+ ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen);
+ for (i = 0; i < nw; i++) {
+ ISP_IOXPUT_16(isp, src->snscb_data[i], &dst->snscb_data[i]);
+ }
+
+}
+
+static INLINE void
+isp_get_sns_response(struct ispsoftc *isp, sns_scrsp_t *src,
+ sns_scrsp_t *dst, int nwords)
+{
+ int i;
+ for (i = 0; i < 16; i++) {
+ ISP_IOXGET_8(isp, &src->snscb_cthdr[i], dst->snscb_cthdr[i]);
+ }
+ ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type);
+ for (i = 0; i < 3; i++) {
+ ISP_IOXGET_8(isp, &src->snscb_port_id[i],
+ dst->snscb_port_id[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &src->snscb_portname[i],
+ dst->snscb_portname[i]);
+ }
+ for (i = 0; i < nwords; i++) {
+ ISP_IOXGET_16(isp, &src->snscb_data[i], dst->snscb_data[i]);
+ }
+}
+
+#ifdef ISP_TARGET_MODE
+static INLINE void
+isp_put_atio(struct ispsoftc *isp, at_entry_t *atsrc, at_entry_t *atdst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &atsrc->at_header, &atdst->at_header);
+ ISP_IOXPUT_16(isp, atsrc->at_reserved, &atdst->at_reserved);
+ ISP_IOXPUT_16(isp, atsrc->at_handle, &atdst->at_handle);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_iid);
+ ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_lun);
+ ISP_IOXPUT_8(isp, atsrc->at_cdblen, &atdst->at_tgt);
+ ISP_IOXPUT_8(isp, atsrc->at_tgt, &atdst->at_cdblen);
+ ISP_IOXPUT_8(isp, atsrc->at_status, &atdst->at_scsi_status);
+ ISP_IOXPUT_8(isp, atsrc->at_scsi_status, &atdst->at_status);
+ ISP_IOXPUT_8(isp, atsrc->at_tag_val, &atdst->at_tag_type);
+ ISP_IOXPUT_8(isp, atsrc->at_tag_type, &atdst->at_tag_val);
+ } else {
+ ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_lun);
+ ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_iid);
+ ISP_IOXPUT_8(isp, atsrc->at_cdblen, &atdst->at_cdblen);
+ ISP_IOXPUT_8(isp, atsrc->at_tgt, &atdst->at_tgt);
+ ISP_IOXPUT_8(isp, atsrc->at_status, &atdst->at_status);
+ ISP_IOXPUT_8(isp, atsrc->at_scsi_status,
+ &atdst->at_scsi_status);
+ ISP_IOXPUT_8(isp, atsrc->at_tag_val, &atdst->at_tag_val);
+ ISP_IOXPUT_8(isp, atsrc->at_tag_type, &atdst->at_tag_type);
+ }
+ ISP_IOXPUT_32(isp, atsrc->at_flags, &atdst->at_flags);
+ for (i = 0; i < ATIO_CDBLEN; i++) {
+ ISP_IOXPUT_8(isp, atsrc->at_cdb[i], &atdst->at_cdb[i]);
+ }
+ for (i = 0; i < QLTM_SENSELEN; i++) {
+ ISP_IOXPUT_8(isp, atsrc->at_sense[i], &atdst->at_sense[i]);
+ }
+}
+
+static INLINE void
+isp_get_atio(struct ispsoftc *isp, at_entry_t *atsrc, at_entry_t *atdst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
+ ISP_IOXGET_16(isp, &atsrc->at_reserved, atdst->at_reserved);
+ ISP_IOXGET_16(isp, &atsrc->at_handle, atdst->at_handle);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_iid);
+ ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_lun);
+ ISP_IOXGET_8(isp, &atsrc->at_cdblen, atdst->at_tgt);
+ ISP_IOXGET_8(isp, &atsrc->at_tgt, atdst->at_cdblen);
+ ISP_IOXGET_8(isp, &atsrc->at_status, atdst->at_scsi_status);
+ ISP_IOXGET_8(isp, &atsrc->at_scsi_status, atdst->at_status);
+ ISP_IOXGET_8(isp, &atsrc->at_tag_val, atdst->at_tag_type);
+ ISP_IOXGET_8(isp, &atsrc->at_tag_type, atdst->at_tag_val);
+ } else {
+ ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_lun);
+ ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_iid);
+ ISP_IOXGET_8(isp, &atsrc->at_cdblen, atdst->at_cdblen);
+ ISP_IOXGET_8(isp, &atsrc->at_tgt, atdst->at_tgt);
+ ISP_IOXGET_8(isp, &atsrc->at_status, atdst->at_status);
+ ISP_IOXGET_8(isp, &atsrc->at_scsi_status,
+ atdst->at_scsi_status);
+ ISP_IOXGET_8(isp, &atsrc->at_tag_val, atdst->at_tag_val);
+ ISP_IOXGET_8(isp, &atsrc->at_tag_type, atdst->at_tag_type);
+ }
+ ISP_IOXGET_32(isp, &atsrc->at_flags, atdst->at_flags);
+ for (i = 0; i < ATIO_CDBLEN; i++) {
+ ISP_IOXGET_8(isp, &atsrc->at_cdb[i], atdst->at_cdb[i]);
+ }
+ for (i = 0; i < QLTM_SENSELEN; i++) {
+ ISP_IOXGET_8(isp, &atsrc->at_sense[i], atdst->at_sense[i]);
+ }
+}
+
+static INLINE void
+isp_put_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_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_8(isp, atsrc->at_lun, &atdst->at_lun);
+ ISP_IOXPUT_8(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_reserved1, &atdst->at_reserved1);
+ 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 < 10; i++) {
+ ISP_IOXPUT_8(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;
+ isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
+ ISP_IOXGET_32(isp, &atsrc->at_reserved, atdst->at_reserved);
+ ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_lun);
+ ISP_IOXGET_8(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_reserved1, atdst->at_reserved1);
+ 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 < 10; i++) {
+ ISP_IOXGET_8(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;
+ 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);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_lun);
+ ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_iid);
+ ISP_IOXPUT_8(isp, ctsrc->ct_tgt, &ctdst->ct_reserved2);
+ ISP_IOXPUT_8(isp, ctsrc->ct_reserved2, &ctdst->ct_tgt);
+ ISP_IOXPUT_8(isp, ctsrc->ct_status, &ctdst->ct_scsi_status);
+ ISP_IOXPUT_8(isp, ctsrc->ct_scsi_status, &ctdst->ct_status);
+ ISP_IOXPUT_8(isp, ctsrc->ct_tag_type, &ctdst->ct_tag_val);
+ ISP_IOXPUT_8(isp, ctsrc->ct_tag_val, &ctdst->ct_tag_type);
+ } else {
+ ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_iid);
+ ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_lun);
+ ISP_IOXPUT_8(isp, ctsrc->ct_tgt, &ctdst->ct_tgt);
+ ISP_IOXPUT_8(isp, ctsrc->ct_reserved2, &ctdst->ct_reserved2);
+ ISP_IOXPUT_8(isp, ctsrc->ct_scsi_status,
+ &ctdst->ct_scsi_status);
+ ISP_IOXPUT_8(isp, ctsrc->ct_status, &ctdst->ct_status);
+ ISP_IOXPUT_8(isp, ctsrc->ct_tag_type, &ctdst->ct_tag_type);
+ ISP_IOXPUT_8(isp, ctsrc->ct_tag_val, &ctdst->ct_tag_val);
+ }
+ ISP_IOXPUT_32(isp, ctsrc->ct_flags, &ctdst->ct_flags);
+ ISP_IOXPUT_32(isp, ctsrc->ct_xfrlen, &ctdst->ct_xfrlen);
+ ISP_IOXPUT_32(isp, ctsrc->ct_resid, &ctdst->ct_resid);
+ ISP_IOXPUT_16(isp, ctsrc->ct_timeout, &ctdst->ct_timeout);
+ ISP_IOXPUT_16(isp, ctsrc->ct_seg_count, &ctdst->ct_seg_count);
+ for (i = 0; i < ISP_RQDSEG; i++) {
+ ISP_IOXPUT_32(isp, ctsrc->ct_dataseg[i].ds_base,
+ &ctdst->ct_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, ctsrc->ct_dataseg[i].ds_count,
+ &ctdst->ct_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
+isp_get_ctio(struct ispsoftc *isp, ct_entry_t *ctsrc, ct_entry_t *ctdst)
+{
+ int i;
+ 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);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_iid);
+ ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_lun);
+ ISP_IOXGET_8(isp, &ctsrc->ct_reserved2, ctdst->ct_tgt);
+ ISP_IOXGET_8(isp, &ctsrc->ct_tgt, ctdst->ct_reserved2);
+ ISP_IOXGET_8(isp, &ctsrc->ct_status, ctdst->ct_scsi_status);
+ ISP_IOXGET_8(isp, &ctsrc->ct_scsi_status, ctdst->ct_status);
+ ISP_IOXGET_8(isp, &ctsrc->ct_tag_val, ctdst->ct_tag_type);
+ ISP_IOXGET_8(isp, &ctsrc->ct_tag_type, ctdst->ct_tag_val);
+ } else {
+ ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_lun);
+ ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_iid);
+ ISP_IOXGET_8(isp, &ctsrc->ct_reserved2, ctdst->ct_reserved2);
+ ISP_IOXGET_8(isp, &ctsrc->ct_tgt, ctdst->ct_tgt);
+ ISP_IOXGET_8(isp, &ctsrc->ct_status, ctdst->ct_status);
+ ISP_IOXGET_8(isp, &ctsrc->ct_scsi_status,
+ ctdst->ct_scsi_status);
+ ISP_IOXGET_8(isp, &ctsrc->ct_tag_val, ctdst->ct_tag_val);
+ ISP_IOXGET_8(isp, &ctsrc->ct_tag_type, ctdst->ct_tag_type);
+ }
+ ISP_IOXGET_32(isp, &ctsrc->ct_flags, ctdst->ct_flags);
+ ISP_IOXGET_32(isp, &ctsrc->ct_xfrlen, ctdst->ct_xfrlen);
+ ISP_IOXGET_32(isp, &ctsrc->ct_resid, ctdst->ct_resid);
+ ISP_IOXGET_16(isp, &ctsrc->ct_timeout, ctdst->ct_timeout);
+ ISP_IOXGET_16(isp, &ctsrc->ct_seg_count, ctdst->ct_seg_count);
+ for (i = 0; i < ISP_RQDSEG; i++) {
+ ISP_IOXGET_32(isp,
+ &ctsrc->ct_dataseg[i].ds_base,
+ ctdst->ct_dataseg[i].ds_base);
+ ISP_IOXGET_32(isp,
+ &ctsrc->ct_dataseg[i].ds_count,
+ ctdst->ct_dataseg[i].ds_count);
+ }
+}
+
+static INLINE void
+isp_put_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_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_8(isp, ctsrc->ct_lun, &ctdst->ct_lun);
+ ISP_IOXPUT_8(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);
+ 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)
+{
+ int i;
+ 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_8(isp, &ctsrc->ct_lun, ctdst->ct_lun);
+ ISP_IOXGET_8(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);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_32(isp, &ctsrc->rsp.fw._reserved[i],
+ ctdst->rsp.fw._reserved[i]);
+ }
+ ISP_IOXGET_16(isp, &ctsrc->rsp.fw.ct_scsi_status,
+ ctdst->rsp.fw.ct_scsi_status);
+ for (i = 0; i < QLTM_SENSELEN; i++) {
+ ISP_IOXGET_8(isp, &ctsrc->rsp.fw.ct_sense[i],
+ ctdst->rsp.fw.ct_sense[i]);
+ }
+}
+
+static INLINE void
+isp_put_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &lesrc->le_header, &ledst->le_header);
+ ISP_IOXPUT_32(isp, lesrc->le_reserved, &ledst->le_reserved);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_rsvd);
+ ISP_IOXPUT_8(isp, lesrc->le_rsvd, &ledst->le_lun);
+ ISP_IOXPUT_8(isp, lesrc->le_ops, &ledst->le_tgt);
+ ISP_IOXPUT_8(isp, lesrc->le_tgt, &ledst->le_ops);
+ ISP_IOXPUT_8(isp, lesrc->le_status, &ledst->le_reserved2);
+ ISP_IOXPUT_8(isp, lesrc->le_reserved2, &ledst->le_status);
+ ISP_IOXPUT_8(isp, lesrc->le_cmd_count, &ledst->le_in_count);
+ ISP_IOXPUT_8(isp, lesrc->le_in_count, &ledst->le_cmd_count);
+ ISP_IOXPUT_8(isp, lesrc->le_cdb6len, &ledst->le_cdb7len);
+ ISP_IOXPUT_8(isp, lesrc->le_cdb7len, &ledst->le_cdb6len);
+ } else {
+ ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_lun);
+ ISP_IOXPUT_8(isp, lesrc->le_rsvd, &ledst->le_rsvd);
+ ISP_IOXPUT_8(isp, lesrc->le_ops, &ledst->le_ops);
+ ISP_IOXPUT_8(isp, lesrc->le_tgt, &ledst->le_tgt);
+ ISP_IOXPUT_8(isp, lesrc->le_status, &ledst->le_status);
+ ISP_IOXPUT_8(isp, lesrc->le_reserved2, &ledst->le_reserved2);
+ ISP_IOXPUT_8(isp, lesrc->le_cmd_count, &ledst->le_cmd_count);
+ ISP_IOXPUT_8(isp, lesrc->le_in_count, &ledst->le_in_count);
+ ISP_IOXPUT_8(isp, lesrc->le_cdb6len, &ledst->le_cdb6len);
+ ISP_IOXPUT_8(isp, lesrc->le_cdb7len, &ledst->le_cdb7len);
+ }
+ ISP_IOXPUT_32(isp, lesrc->le_flags, &ledst->le_flags);
+ ISP_IOXPUT_16(isp, lesrc->le_timeout, &ledst->le_timeout);
+ for (i = 0; i < 20; i++) {
+ ISP_IOXPUT_8(isp, lesrc->le_reserved3[i],
+ &ledst->le_reserved3[i]);
+ }
+}
+
+static INLINE void
+isp_get_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &lesrc->le_header, &ledst->le_header);
+ ISP_IOXGET_32(isp, &lesrc->le_reserved, ledst->le_reserved);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_rsvd);
+ ISP_IOXGET_8(isp, &lesrc->le_rsvd, ledst->le_lun);
+ ISP_IOXGET_8(isp, &lesrc->le_ops, ledst->le_tgt);
+ ISP_IOXGET_8(isp, &lesrc->le_tgt, ledst->le_ops);
+ ISP_IOXGET_8(isp, &lesrc->le_status, ledst->le_reserved2);
+ ISP_IOXGET_8(isp, &lesrc->le_reserved2, ledst->le_status);
+ ISP_IOXGET_8(isp, &lesrc->le_cmd_count, ledst->le_in_count);
+ ISP_IOXGET_8(isp, &lesrc->le_in_count, ledst->le_cmd_count);
+ ISP_IOXGET_8(isp, &lesrc->le_cdb6len, ledst->le_cdb7len);
+ ISP_IOXGET_8(isp, &lesrc->le_cdb7len, ledst->le_cdb6len);
+ } else {
+ ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_lun);
+ ISP_IOXGET_8(isp, &lesrc->le_rsvd, ledst->le_rsvd);
+ ISP_IOXGET_8(isp, &lesrc->le_ops, ledst->le_ops);
+ ISP_IOXGET_8(isp, &lesrc->le_tgt, ledst->le_tgt);
+ ISP_IOXGET_8(isp, &lesrc->le_status, ledst->le_status);
+ ISP_IOXGET_8(isp, &lesrc->le_reserved2, ledst->le_reserved2);
+ ISP_IOXGET_8(isp, &lesrc->le_cmd_count, ledst->le_cmd_count);
+ ISP_IOXGET_8(isp, &lesrc->le_in_count, ledst->le_in_count);
+ ISP_IOXGET_8(isp, &lesrc->le_cdb6len, ledst->le_cdb6len);
+ ISP_IOXGET_8(isp, &lesrc->le_cdb7len, ledst->le_cdb7len);
+ }
+ ISP_IOXGET_32(isp, &lesrc->le_flags, ledst->le_flags);
+ ISP_IOXGET_16(isp, &lesrc->le_timeout, ledst->le_timeout);
+ for (i = 0; i < 20; i++) {
+ ISP_IOXGET_8(isp, &lesrc->le_reserved3[i],
+ ledst->le_reserved3[i]);
+ }
+}
+
+static INLINE void
+isp_put_notify(struct ispsoftc *isp, in_entry_t *insrc, in_entry_t *indst)
+{
+ int i;
+ isp_copy_out_hdr(isp, &insrc->in_header, &indst->in_header);
+ ISP_IOXPUT_32(isp, insrc->in_reserved, &indst->in_reserved);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_iid);
+ ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_lun);
+ ISP_IOXPUT_8(isp, insrc->in_reserved2, &indst->in_tgt);
+ ISP_IOXPUT_8(isp, insrc->in_tgt, &indst->in_reserved2);
+ ISP_IOXPUT_8(isp, insrc->in_status, &indst->in_rsvd2);
+ ISP_IOXPUT_8(isp, insrc->in_rsvd2, &indst->in_status);
+ ISP_IOXPUT_8(isp, insrc->in_tag_val, &indst->in_tag_type);
+ ISP_IOXPUT_8(isp, insrc->in_tag_type, &indst->in_tag_val);
+ } else {
+ ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_lun);
+ ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_iid);
+ ISP_IOXPUT_8(isp, insrc->in_reserved2, &indst->in_reserved2);
+ ISP_IOXPUT_8(isp, insrc->in_tgt, &indst->in_tgt);
+ ISP_IOXPUT_8(isp, insrc->in_status, &indst->in_status);
+ ISP_IOXPUT_8(isp, insrc->in_rsvd2, &indst->in_rsvd2);
+ ISP_IOXPUT_8(isp, insrc->in_tag_val, &indst->in_tag_val);
+ ISP_IOXPUT_8(isp, insrc->in_tag_type, &indst->in_tag_type);
+ }
+ ISP_IOXPUT_32(isp, insrc->in_flags, &indst->in_flags);
+ ISP_IOXPUT_16(isp, insrc->in_seqid, &indst->in_seqid);
+ for (i = 0; i < IN_MSGLEN; i++) {
+ ISP_IOXPUT_8(isp, insrc->in_msg[i], &indst->in_msg[i]);
+ }
+ for (i = 0; i < IN_RSVDLEN; i++) {
+ ISP_IOXPUT_8(isp, insrc->in_reserved3[i],
+ &indst->in_reserved3[i]);
+ }
+ for (i = 0; i < QLTM_SENSELEN; i++) {
+ ISP_IOXPUT_8(isp, insrc->in_sense[i],
+ &indst->in_sense[i]);
+ }
+}
+
+static INLINE void
+isp_get_notify(struct ispsoftc *isp, in_entry_t *insrc, in_entry_t *indst)
+{
+ int i;
+ isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
+ ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_iid);
+ ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_lun);
+ ISP_IOXGET_8(isp, &insrc->in_reserved2, indst->in_tgt);
+ ISP_IOXGET_8(isp, &insrc->in_tgt, indst->in_reserved2);
+ ISP_IOXGET_8(isp, &insrc->in_status, indst->in_rsvd2);
+ ISP_IOXGET_8(isp, &insrc->in_rsvd2, indst->in_status);
+ ISP_IOXGET_8(isp, &insrc->in_tag_val, indst->in_tag_type);
+ ISP_IOXGET_8(isp, &insrc->in_tag_type, indst->in_tag_val);
+ } else {
+ ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_lun);
+ ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_iid);
+ ISP_IOXGET_8(isp, &insrc->in_reserved2, indst->in_reserved2);
+ ISP_IOXGET_8(isp, &insrc->in_tgt, indst->in_tgt);
+ ISP_IOXGET_8(isp, &insrc->in_status, indst->in_status);
+ ISP_IOXGET_8(isp, &insrc->in_rsvd2, indst->in_rsvd2);
+ ISP_IOXGET_8(isp, &insrc->in_tag_val, indst->in_tag_val);
+ ISP_IOXGET_8(isp, &insrc->in_tag_type, indst->in_tag_type);
+ }
+ ISP_IOXGET_32(isp, &insrc->in_flags, indst->in_flags);
+ ISP_IOXGET_16(isp, &insrc->in_seqid, indst->in_seqid);
+ for (i = 0; i < IN_MSGLEN; i++) {
+ ISP_IOXGET_8(isp, &insrc->in_msg[i], indst->in_msg[i]);
+ }
+ for (i = 0; i < IN_RSVDLEN; i++) {
+ ISP_IOXGET_8(isp, &insrc->in_reserved3[i],
+ indst->in_reserved3[i]);
+ }
+ for (i = 0; i < QLTM_SENSELEN; i++) {
+ ISP_IOXGET_8(isp, &insrc->in_sense[i],
+ indst->in_sense[i]);
+ }
+}
+
+static INLINE void
+isp_put_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
+ in_fcentry_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_8(isp, insrc->in_lun, &indst->in_lun);
+ ISP_IOXPUT_8(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)
+{
+ isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
+ ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
+ ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_lun);
+ ISP_IOXGET_8(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;
+ isp_copy_out_hdr(isp, &nasrc->na_header, &nadst->na_header);
+ ISP_IOXPUT_32(isp, nasrc->na_reserved, &nadst->na_reserved);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_iid);
+ ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_lun);
+ ISP_IOXPUT_8(isp, nasrc->na_status, &nadst->na_event);
+ ISP_IOXPUT_8(isp, nasrc->na_event, &nadst->na_status);
+ } else {
+ ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_lun);
+ ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_iid);
+ ISP_IOXPUT_8(isp, nasrc->na_status, &nadst->na_status);
+ ISP_IOXPUT_8(isp, nasrc->na_event, &nadst->na_event);
+ }
+ ISP_IOXPUT_32(isp, nasrc->na_flags, &nadst->na_flags);
+ for (i = 0; i < NA_RSVDLEN; i++) {
+ ISP_IOXPUT_16(isp, nasrc->na_reserved3[i],
+ &nadst->na_reserved3[i]);
+ }
+}
+
+static INLINE void
+isp_get_notify_ack(struct ispsoftc *isp, na_entry_t *nasrc, na_entry_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);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_iid);
+ ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_lun);
+ ISP_IOXGET_8(isp, &nasrc->na_status, nadst->na_event);
+ ISP_IOXGET_8(isp, &nasrc->na_event, nadst->na_status);
+ } else {
+ ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_lun);
+ ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_iid);
+ ISP_IOXGET_8(isp, &nasrc->na_status, nadst->na_status);
+ ISP_IOXGET_8(isp, &nasrc->na_event, nadst->na_event);
+ }
+ ISP_IOXGET_32(isp, &nasrc->na_flags, nadst->na_flags);
+ for (i = 0; i < NA_RSVDLEN; i++) {
+ ISP_IOXGET_16(isp, &nasrc->na_reserved3[i],
+ nadst->na_reserved3[i]);
+ }
+}
+
+static INLINE void
+isp_put_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
+ na_fcentry_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_8(isp, nasrc->na_lun, &nadst->na_lun);
+ ISP_IOXPUT_8(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)
+{
+ 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_8(isp, &nasrc->na_lun, nadst->na_lun);
+ ISP_IOXGET_8(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_pci.c b/sys/dev/isp/isp_pci.c
index c5af27e..95c40e79 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1139,7 +1139,7 @@ typedef struct {
struct ispsoftc *isp;
void *cmd_token;
void *rq;
- u_int16_t *iptrp;
+ u_int16_t *nxtip;
u_int16_t optr;
u_int error;
} mush_t;
@@ -1173,23 +1173,27 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
{
mush_t *mp;
struct ccb_scsiio *csio;
+ struct ispsoftc *isp;
struct isp_pcisoftc *pci;
bus_dmamap_t *dp;
+ ct_entry_t *cto, *qe;
u_int8_t scsi_status;
- ct_entry_t *cto;
- u_int16_t handle;
+ u_int16_t curi, nxti, handle;
u_int32_t sflags;
- int nctios, send_status;
int32_t resid;
- int i, j;
+ int nth_ctio, nctios, send_status;
mp = (mush_t *) arg;
if (error) {
mp->error = error;
return;
}
+
+ isp = mp->isp;
csio = mp->cmd_token;
cto = mp->rq;
+ curi = isp->isp_reqidx;
+ qe = (ct_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curi);
cto->ct_xfrlen = 0;
cto->ct_seg_count = 0;
@@ -1198,13 +1202,13 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
if (nseg == 0) {
cto->ct_header.rqs_seqno = 1;
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO[%x] lun%d iid%d tag %x flgs %x sts %x ssts %x res %d",
cto->ct_fwhandle, csio->ccb_h.target_lun, cto->ct_iid,
cto->ct_tag_val, cto->ct_flags, cto->ct_status,
cto->ct_scsi_status, cto->ct_resid);
- ISP_TDQE(mp->isp, "tdma_mk[no data]", *mp->iptrp, cto);
- ISP_SWIZ_CTIO(mp->isp, cto, cto);
+ ISP_TDQE(isp, "tdma_mk[no data]", curi, cto);
+ isp_put_ctio(isp, cto, qe);
return;
}
@@ -1214,22 +1218,10 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
}
/*
- * Check to see that we don't overflow.
- */
- for (i = 0, j = *mp->iptrp; i < nctios; i++) {
- j = ISP_NXT_QENTRY(j, RQUEST_QUEUE_LEN(isp));
- if (j == mp->optr) {
- isp_prt(mp->isp, ISP_LOGWARN,
- "Request Queue Overflow [tdma_mk]");
- mp->error = MUSHERR_NOQENTRIES;
- return;
- }
- }
-
- /*
* Save syshandle, and potentially any SCSI status, which we'll
* reinsert on the last CTIO we're going to send.
*/
+
handle = cto->ct_syshandle;
cto->ct_syshandle = 0;
cto->ct_header.rqs_seqno = 0;
@@ -1263,7 +1255,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->ct_resid = 0;
cto->ct_scsi_status = 0;
- pci = (struct isp_pcisoftc *)mp->isp;
+ pci = (struct isp_pcisoftc *)isp;
dp = &pci->dmaps[isp_handle_index(handle)];
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD);
@@ -1271,8 +1263,9 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREWRITE);
}
+ nxti = *mp->nxtip;
- while (nctios--) {
+ for (nth_ctio = 0; nth_ctio < nctios; nth_ctio++) {
int seglim;
seglim = nseg;
@@ -1299,7 +1292,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* extra CTIO with final status.
*/
if (send_status == 0) {
- isp_prt(mp->isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGWARN,
"tdma_mk ran out of segments");
mp->error = EINVAL;
return;
@@ -1316,7 +1309,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* along and only clear it if we're now sending status.
*/
- if (nctios == 0) {
+ if (nth_ctio == nctios - 1) {
/*
* We're the last in a sequence of CTIOs, so mark
* this CTIO and save the handle to the CCB such that
@@ -1325,6 +1318,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* rest of the command. We *don't* give this to the
* firmware to work on- the caller will do that.
*/
+
cto->ct_syshandle = handle;
cto->ct_header.rqs_seqno = 1;
@@ -1334,23 +1328,27 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->ct_resid = resid;
}
if (send_status) {
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO[%x] lun%d iid %d tag %x ct_flags %x "
"scsi status %x resid %d",
cto->ct_fwhandle, csio->ccb_h.target_lun,
cto->ct_iid, cto->ct_tag_val, cto->ct_flags,
cto->ct_scsi_status, cto->ct_resid);
} else {
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO[%x] lun%d iid%d tag %x ct_flags 0x%x",
cto->ct_fwhandle, csio->ccb_h.target_lun,
cto->ct_iid, cto->ct_tag_val,
cto->ct_flags);
}
- ISP_TDQE(mp->isp, "last tdma_mk", *mp->iptrp, cto);
- ISP_SWIZ_CTIO(mp->isp, cto, cto);
+ isp_put_ctio(isp, cto, qe);
+ ISP_TDQE(isp, "last tdma_mk", curi, cto);
+ if (nctios > 1) {
+ MEMORYBARRIER(isp, SYNC_REQUEST,
+ curi, QENTRY_LEN);
+ }
} else {
- ct_entry_t *octo = cto;
+ ct_entry_t *oqe = qe;
/*
* Make sure syshandle fields are clean
@@ -1358,70 +1356,69 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->ct_syshandle = 0;
cto->ct_header.rqs_seqno = 0;
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO[%x] lun%d for ID%d ct_flags 0x%x",
cto->ct_fwhandle, csio->ccb_h.target_lun,
cto->ct_iid, cto->ct_flags);
- ISP_TDQE(mp->isp, "tdma_mk", *mp->iptrp, cto);
/*
* Get a new CTIO
*/
- cto = (ct_entry_t *)
- ISP_QUEUE_ENTRY(mp->isp->isp_rquest, *mp->iptrp);
- j = *mp->iptrp;
- *mp->iptrp =
- ISP_NXT_QENTRY(*mp->iptrp, RQUEST_QUEUE_LEN(isp));
- if (*mp->iptrp == mp->optr) {
- isp_prt(mp->isp, ISP_LOGTDEBUG0,
+ qe = (ct_entry_t *)
+ ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
+ nxti = ISP_NXT_QENTRY(nxti, RQUEST_QUEUE_LEN(isp));
+ if (nxti == mp->optr) {
+ isp_prt(isp, ISP_LOGTDEBUG0,
"Queue Overflow in tdma_mk");
mp->error = MUSHERR_NOQENTRIES;
return;
}
+
+ /*
+ * Now that we're done with the old CTIO,
+ * flush it out to the request queue.
+ */
+ ISP_TDQE(isp, "dma_tgt_fc", curi, cto);
+ isp_put_ctio(isp, cto, oqe);
+ if (nth_ctio != 0) {
+ MEMORYBARRIER(isp, SYNC_REQUEST, curi,
+ QENTRY_LEN);
+ }
+ curi = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp));
+
/*
- * Fill in the new CTIO with info from the old one.
+ * Reset some fields in the CTIO so we can reuse
+ * for the next one we'll flush to the request
+ * queue.
*/
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
cto->ct_header.rqs_entry_count = 1;
- cto->ct_fwhandle = octo->ct_fwhandle;
cto->ct_header.rqs_flags = 0;
- cto->ct_lun = octo->ct_lun;
- cto->ct_iid = octo->ct_iid;
- cto->ct_reserved2 = octo->ct_reserved2;
- cto->ct_tgt = octo->ct_tgt;
- cto->ct_flags = octo->ct_flags;
cto->ct_status = 0;
cto->ct_scsi_status = 0;
- cto->ct_tag_val = octo->ct_tag_val;
- cto->ct_tag_type = octo->ct_tag_type;
cto->ct_xfrlen = 0;
cto->ct_resid = 0;
- cto->ct_timeout = octo->ct_timeout;
cto->ct_seg_count = 0;
MEMZERO(cto->ct_dataseg, sizeof(cto->ct_dataseg));
- /*
- * Now swizzle the old one for the consumption
- * of the chip and give it to the firmware to
- * work on while we do the next.
- */
- ISP_SWIZ_CTIO(mp->isp, octo, octo);
- ISP_ADD_REQUEST(mp->isp, j);
}
}
+ *mp->nxtip = nxti;
}
static void
tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
{
mush_t *mp;
+ u_int8_t sense[QLTM_SENSELEN];
struct ccb_scsiio *csio;
+ struct ispsoftc *isp;
struct isp_pcisoftc *pci;
bus_dmamap_t *dp;
- ct2_entry_t *cto;
+ ct2_entry_t *cto, *qe;
u_int16_t scsi_status, send_status, send_sense, handle;
+ u_int16_t curi, nxti;
int32_t resid;
- u_int8_t sense[QLTM_SENSELEN];
- int nctios, j;
+ int nth_ctio, nctios;
mp = (mush_t *) arg;
if (error) {
@@ -1429,12 +1426,15 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
return;
}
+ isp = mp->isp;
csio = mp->cmd_token;
cto = mp->rq;
+ curi = isp->isp_reqidx;
+ qe = (ct2_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curi);
if (nseg == 0) {
if ((cto->ct_flags & CT2_FLAG_MMASK) != CT2_FLAG_MODE1) {
- isp_prt(mp->isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGWARN,
"dma2_tgt_fc, a status CTIO2 without MODE1 "
"set (0x%x)", cto->ct_flags);
mp->error = EINVAL;
@@ -1455,18 +1455,18 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
cto->ct_seg_count = 0;
cto->ct_reloff = 0;
- ISP_TDQE(mp->isp, "dma2_tgt_fc[no data]", *mp->iptrp, cto);
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO2[%x] lun %d->iid%d flgs 0x%x sts 0x%x ssts "
"0x%x res %d", cto->ct_rxid, csio->ccb_h.target_lun,
cto->ct_iid, cto->ct_flags, cto->ct_status,
cto->rsp.m1.ct_scsi_status, cto->ct_resid);
- ISP_SWIZ_CTIO2(isp, cto, cto);
+ isp_put_ctio2(isp, cto, qe);
+ ISP_TDQE(isp, "dma2_tgt_fc[no data]", curi, qe);
return;
}
if ((cto->ct_flags & CT2_FLAG_MMASK) != CT2_FLAG_MODE0) {
- isp_prt(mp->isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGWARN,
"dma2_tgt_fc, a data CTIO2 without MODE0 set "
"(0x%x)", cto->ct_flags);
mp->error = EINVAL;
@@ -1529,7 +1529,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->rsp.m0.ct_scsi_status = 0;
MEMZERO(&cto->rsp, sizeof (cto->rsp));
- pci = (struct isp_pcisoftc *)mp->isp;
+ pci = (struct isp_pcisoftc *)isp;
dp = &pci->dmaps[isp_handle_index(handle)];
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD);
@@ -1537,14 +1537,17 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREWRITE);
}
- while (nctios--) {
- int seg, seglim;
+ nxti = *mp->nxtip;
+
+ for (nth_ctio = 0; nth_ctio < nctios; nth_ctio++) {
+ u_int32_t oxfrlen;
+ int seglim;
seglim = nseg;
if (seglim) {
+ int seg;
if (seglim > ISP_RQDSEG_T2)
seglim = ISP_RQDSEG_T2;
-
for (seg = 0; seg < seglim; seg++) {
cto->rsp.m0.ct_dataseg[seg].ds_base =
dm_segs->ds_addr;
@@ -1554,20 +1557,23 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
dm_segs++;
}
cto->ct_seg_count = seg;
+ oxfrlen = cto->rsp.m0.ct_xfrlen;
} else {
/*
* This case should only happen when we're sending a
* synthesized MODE1 final status with sense data.
*/
if (send_sense == 0) {
- isp_prt(mp->isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGWARN,
"dma2_tgt_fc ran out of segments, "
"no SENSE DATA");
mp->error = EINVAL;
return;
}
+ oxfrlen = 0;
}
+
/*
* At this point, the fields ct_lun, ct_iid, ct_rxid,
* ct_timeout have been carried over unchanged from what
@@ -1583,8 +1589,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
*
*/
- if (nctios == 0) {
-
+ if (nth_ctio == nctios - 1) {
/*
* We're the last in a sequence of CTIO2s, so mark this
* CTIO2 and save the handle to the CCB such that when
@@ -1633,70 +1638,76 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
CT2_DATA_OVER;
}
}
- ISP_TDQE(mp->isp, "last dma2_tgt_fc", *mp->iptrp, cto);
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO2[%x] lun %d->iid%d flgs 0x%x sts 0x%x"
" ssts 0x%x res %d", cto->ct_rxid,
csio->ccb_h.target_lun, (int) cto->ct_iid,
cto->ct_flags, cto->ct_status,
cto->rsp.m1.ct_scsi_status, cto->ct_resid);
- ISP_SWIZ_CTIO2(isp, cto, cto);
+ isp_put_ctio2(isp, cto, qe);
+ ISP_TDQE(isp, "last dma2_tgt_fc", curi, qe);
+ if (nctios > 1) {
+ MEMORYBARRIER(isp, SYNC_REQUEST,
+ curi, QENTRY_LEN);
+ }
} else {
- ct2_entry_t *octo = cto;
+ ct2_entry_t *oqe = qe;
/*
* Make sure handle fields are clean
*/
cto->ct_syshandle = 0;
cto->ct_header.rqs_seqno = 0;
-
- ISP_TDQE(mp->isp, "dma2_tgt_fc", *mp->iptrp, cto);
- isp_prt(mp->isp, ISP_LOGTDEBUG1,
+ isp_prt(isp, ISP_LOGTDEBUG1,
"CTIO2[%x] lun %d->iid%d flgs 0x%x",
cto->ct_rxid, csio->ccb_h.target_lun,
(int) cto->ct_iid, cto->ct_flags);
/*
- * Get a new CTIO2
+ * Get a new CTIO2 entry from the request queue.
*/
- cto = (ct2_entry_t *)
- ISP_QUEUE_ENTRY(mp->isp->isp_rquest, *mp->iptrp);
- j = *mp->iptrp;
- *mp->iptrp =
- ISP_NXT_QENTRY(*mp->iptrp, RQUEST_QUEUE_LEN(isp));
- if (*mp->iptrp == mp->optr) {
- isp_prt(mp->isp, ISP_LOGWARN,
+ qe = (ct2_entry_t *)
+ ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
+ nxti = ISP_NXT_QENTRY(nxti, RQUEST_QUEUE_LEN(isp));
+ if (nxti == mp->optr) {
+ isp_prt(isp, ISP_LOGWARN,
"Queue Overflow in dma2_tgt_fc");
mp->error = MUSHERR_NOQENTRIES;
return;
}
/*
- * Fill in the new CTIO2 with info from the old one.
+ * Now that we're done with the old CTIO2,
+ * flush it out to the request queue.
+ */
+ ISP_TDQE(isp, "tdma_mkfc", curi, cto);
+ isp_put_ctio2(isp, cto, oqe);
+ if (nth_ctio != 0) {
+ MEMORYBARRIER(isp, SYNC_REQUEST, curi,
+ QENTRY_LEN);
+ }
+ curi = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp));
+
+ /*
+ * Reset some fields in the CTIO2 so we can reuse
+ * for the next one we'll flush to the request
+ * queue.
*/
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
cto->ct_header.rqs_entry_count = 1;
cto->ct_header.rqs_flags = 0;
- /* ct_header.rqs_seqno && ct_syshandle done later */
- cto->ct_fwhandle = octo->ct_fwhandle;
- cto->ct_lun = octo->ct_lun;
- cto->ct_iid = octo->ct_iid;
- cto->ct_rxid = octo->ct_rxid;
- cto->ct_flags = octo->ct_flags;
cto->ct_status = 0;
cto->ct_resid = 0;
- cto->ct_timeout = octo->ct_timeout;
cto->ct_seg_count = 0;
/*
* Adjust the new relative offset by the amount which
* is recorded in the data segment of the old CTIO2 we
* just finished filling out.
*/
- cto->ct_reloff += octo->rsp.m0.ct_xfrlen;
+ cto->ct_reloff += oxfrlen;
MEMZERO(&cto->rsp, sizeof (cto->rsp));
- ISP_SWIZ_CTIO2(isp, octo, octo);
- ISP_ADD_REQUEST(mp->isp, j);
}
}
+ *mp->nxtip = nxti;
}
#endif
@@ -1706,13 +1717,14 @@ static void
dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
{
mush_t *mp;
+ struct ispsoftc *isp;
struct ccb_scsiio *csio;
struct isp_pcisoftc *pci;
bus_dmamap_t *dp;
bus_dma_segment_t *eseg;
ispreq_t *rq;
- ispcontreq_t *crq;
int seglim, datalen;
+ u_int16_t nxti;
mp = (mush_t *) arg;
if (error) {
@@ -1726,9 +1738,11 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
return;
}
csio = mp->cmd_token;
+ isp = mp->isp;
rq = mp->rq;
pci = (struct isp_pcisoftc *)mp->isp;
dp = &pci->dmaps[isp_handle_index(rq->req_handle)];
+ nxti = *mp->nxtip;
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD);
@@ -1748,7 +1762,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* until we've covered the entire transfer.
*/
- if (IS_FC(mp->isp)) {
+ if (IS_FC(isp)) {
seglim = ISP_RQDSEG_T2;
((ispreqt2_t *)rq)->req_totalcnt = datalen;
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
@@ -1772,7 +1786,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
eseg = dm_segs + nseg;
while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) {
- if (IS_FC(mp->isp)) {
+ if (IS_FC(isp)) {
ispreqt2_t *rq2 = (ispreqt2_t *)rq;
rq2->req_dataseg[rq2->req_seg_count].ds_base =
dm_segs->ds_addr;
@@ -1785,38 +1799,24 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
dm_segs->ds_len;
}
datalen -= dm_segs->ds_len;
-#if 0
- if (IS_FC(mp->isp)) {
- ispreqt2_t *rq2 = (ispreqt2_t *)rq;
- device_printf(mp->isp->isp_dev,
- "seg0[%d] cnt 0x%x paddr 0x%08x\n",
- rq->req_seg_count,
- rq2->req_dataseg[rq2->req_seg_count].ds_count,
- rq2->req_dataseg[rq2->req_seg_count].ds_base);
- } else {
- device_printf(mp->isp->isp_dev,
- "seg0[%d] cnt 0x%x paddr 0x%08x\n",
- rq->req_seg_count,
- rq->req_dataseg[rq->req_seg_count].ds_count,
- rq->req_dataseg[rq->req_seg_count].ds_base);
- }
-#endif
rq->req_seg_count++;
dm_segs++;
}
while (datalen > 0 && dm_segs != eseg) {
- crq = (ispcontreq_t *)
- ISP_QUEUE_ENTRY(mp->isp->isp_rquest, *mp->iptrp);
- *mp->iptrp = ISP_NXT_QENTRY(*mp->iptrp, RQUEST_QUEUE_LEN(isp));
- if (*mp->iptrp == mp->optr) {
- isp_prt(mp->isp,
- ISP_LOGDEBUG0, "Request Queue Overflow++");
+ u_int16_t onxti;
+ ispcontreq_t local, *crq = &local, *cqe;
+
+ cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
+ onxti = nxti;
+ nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp));
+ if (nxti == mp->optr) {
+ isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
mp->error = MUSHERR_NOQENTRIES;
return;
}
rq->req_header.rqs_entry_count++;
- bzero((void *)crq, sizeof (*crq));
+ MEMZERO((void *)crq, sizeof (*crq));
crq->req_header.rqs_entry_count = 1;
crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
@@ -1826,30 +1826,28 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
dm_segs->ds_addr;
crq->req_dataseg[seglim].ds_count =
dm_segs->ds_len;
-#if 0
- device_printf(mp->isp->isp_dev,
- "seg%d[%d] cnt 0x%x paddr 0x%08x\n",
- rq->req_header.rqs_entry_count-1,
- seglim, crq->req_dataseg[seglim].ds_count,
- crq->req_dataseg[seglim].ds_base);
-#endif
rq->req_seg_count++;
dm_segs++;
seglim++;
datalen -= dm_segs->ds_len;
}
+ isp_put_cont_req(isp, crq, cqe);
+ MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
}
+ *mp->nxtip = nxti;
}
static int
isp_pci_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq,
- u_int16_t *iptrp, u_int16_t optr)
+ u_int16_t *nxtip, u_int16_t optr)
{
struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
+ ispreq_t *qep;
bus_dmamap_t *dp = NULL;
mush_t mush, *mp;
void (*eptr)(void *, bus_dma_segment_t *, int, int);
+ qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
#ifdef ISP_TARGET_MODE
if (csio->ccb_h.func_code == XPT_CONT_TARGET_IO) {
if (IS_FC(isp)) {
@@ -1863,26 +1861,21 @@ isp_pci_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq,
mp->isp = isp;
mp->cmd_token = csio;
mp->rq = rq; /* really a ct_entry_t or ct2_entry_t */
- mp->iptrp = iptrp;
+ mp->nxtip = nxtip;
mp->optr = optr;
mp->error = 0;
(*eptr)(mp, NULL, 0, 0);
- goto exit;
+ goto mbxsync;
}
} else
#endif
eptr = dma2;
- /*
- * NB: if we need to do request queue entry swizzling,
- * NB: this is where it would need to be done for cmds
- * NB: that move no data. For commands that move data,
- * NB: swizzling would take place in those functions.
- */
+
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE ||
(csio->dxfer_len == 0)) {
rq->req_seg_count = 1;
- return (CMD_QUEUED);
+ goto mbxsync;
}
/*
@@ -1893,7 +1886,7 @@ isp_pci_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq,
mp->isp = isp;
mp->cmd_token = csio;
mp->rq = rq;
- mp->iptrp = iptrp;
+ mp->nxtip = nxtip;
mp->optr = optr;
mp->error = 0;
@@ -1941,9 +1934,6 @@ isp_pci_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq,
(*eptr)(mp, segs, csio->sglist_cnt, 0);
}
}
-#ifdef ISP_TARGET_MODE
-exit:
-#endif
if (mp->error) {
int retval = CMD_COMPLETE;
if (mp->error == MUSHERR_NOQENTRIES) {
@@ -1956,19 +1946,21 @@ exit:
XS_SETERR(csio, CAM_UNREC_HBA_ERROR);
}
return (retval);
- } else {
- /*
- * Check to see if we weren't cancelled while sleeping on
- * getting DMA resources...
- */
- if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
- if (dp) {
- bus_dmamap_unload(pci->parent_dmat, *dp);
- }
- return (CMD_COMPLETE);
- }
- return (CMD_QUEUED);
}
+mbxsync:
+ switch (rq->req_header.rqs_entry_type) {
+ case RQSTYPE_REQUEST:
+ isp_put_request(isp, rq, qep);
+ break;
+ case RQSTYPE_CMDONLY:
+ isp_put_extended_request(isp, (ispextreq_t *)rq,
+ (ispextreq_t *)qep);
+ break;
+ case RQSTYPE_T2RQS:
+ isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) qep);
+ break;
+ }
+ return (CMD_QUEUED);
}
static void
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index 72a898e..a4bcf6f 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -134,28 +134,35 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
#define nack_fcp unp.nack_fcp
#define hdrp unp.hp
} unp;
- int bus, rval = 0;
+ u_int8_t local[QENTRY_LEN];
+ int bus, type, rval = 0;
+ type = isp_get_response_type(isp, (isphdr_t *)vptr);
unp.vp = vptr;
ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
- switch(hdrp->rqs_entry_type) {
+ switch(type) {
case RQSTYPE_ATIO:
- isp_handle_atio(isp, atiop);
+ isp_get_atio(isp, atiop, (at_entry_t *) local);
+ isp_handle_atio(isp, (at_entry_t *) local);
break;
case RQSTYPE_CTIO:
- isp_handle_ctio(isp, ctiop);
+ isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
+ isp_handle_ctio(isp, (ct_entry_t *) local);
break;
case RQSTYPE_ATIO2:
- isp_handle_atio2(isp, at2iop);
+ isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
+ isp_handle_atio2(isp, (at2_entry_t *) local);
break;
case RQSTYPE_CTIO2:
- isp_handle_ctio2(isp, ct2iop);
+ isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
+ isp_handle_ctio2(isp, (ct2_entry_t *) local);
break;
case RQSTYPE_ENABLE_LUN:
case RQSTYPE_MODIFY_LUN:
- (void) isp_async(isp, ISPASYNC_TARGET_ACTION, vptr);
+ isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
break;
case RQSTYPE_NOTIFY:
@@ -168,9 +175,13 @@ 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);
+ inot_fcp = (in_fcentry_t *) local;
status = inot_fcp->in_status;
seqid = inot_fcp->in_seqid;
} else {
+ isp_get_notify(isp, inotp, (in_entry_t *)local);
+ inotp = (in_entry_t *) local;
status = inotp->in_status & 0xff;
seqid = inotp->in_seqid;
if (IS_DUALBUS(isp)) {
@@ -185,7 +196,7 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
/*
* ACK it right away.
*/
- isp_notify_ack(isp, (status == IN_RESET)? NULL : vptr);
+ isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
switch (status) {
case IN_RESET:
(void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
@@ -193,9 +204,9 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
case IN_MSG_RECEIVED:
case IN_IDE_RECEIVED:
if (IS_FC(isp)) {
- isp_got_msg_fc(isp, bus, vptr);
+ isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
} else {
- isp_got_msg(isp, bus, vptr);
+ isp_got_msg(isp, bus, (in_entry_t *)local);
}
break;
case IN_RSRC_UNAVAIL:
@@ -233,10 +244,15 @@ 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);
+ nack_fcp = (na_fcentry_t *)local;
isp_prt(isp, ISP_LOGTDEBUG1,
"Notify Ack status=0x%x seqid 0x%x",
nack_fcp->na_status, nack_fcp->na_seqid);
} else {
+ isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
+ nackp = (na_entry_t *)local;
isp_prt(isp, ISP_LOGTDEBUG1,
"Notify Ack event 0x%x status=0x%x seqid 0x%x",
nackp->na_event, nackp->na_status, nackp->na_seqid);
@@ -244,8 +260,7 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
break;
default:
isp_prt(isp, ISP_LOGERR,
- "Unknown entry type 0x%x in isp_target_notify",
- hdrp->rqs_entry_type);
+ "Unknown entry type 0x%x in isp_target_notify", type);
rval = -1;
break;
}
@@ -277,7 +292,7 @@ isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
int cmd_cnt, int inot_cnt, u_int32_t opaque)
{
lun_entry_t el;
- u_int16_t iptr, optr;
+ u_int16_t nxti, optr;
void *outp;
@@ -314,14 +329,14 @@ isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
}
el.le_timeout = 2;
- if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
- isp_prt(isp, ISP_LOGWARN,
+ if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
+ isp_prt(isp, ISP_LOGERR,
"Request Queue Overflow in isp_lun_cmd");
return (-1);
}
- ISP_SWIZ_ENABLE_LUN(isp, outp, &el);
ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
- ISP_ADD_REQUEST(isp, iptr);
+ isp_put_enable_lun(isp, &el, outp);
+ ISP_ADD_REQUEST(isp, nxti);
return (0);
}
@@ -330,26 +345,26 @@ int
isp_target_put_entry(struct ispsoftc *isp, void *ap)
{
void *outp;
- u_int16_t iptr, optr;
+ u_int16_t nxti, optr;
u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
- if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
+ if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
isp_prt(isp, ISP_LOGWARN,
"Request Queue Overflow in isp_target_put_entry");
return (-1);
}
switch (etype) {
case RQSTYPE_ATIO:
- ISP_SWIZ_ATIO(isp, outp, ap);
+ isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
break;
case RQSTYPE_ATIO2:
- ISP_SWIZ_ATIO2(isp, outp, ap);
+ isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
break;
case RQSTYPE_CTIO:
- ISP_SWIZ_CTIO(isp, outp, ap);
+ isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
break;
case RQSTYPE_CTIO2:
- ISP_SWIZ_CTIO2(isp, outp, ap);
+ isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
break;
default:
isp_prt(isp, ISP_LOGERR,
@@ -358,8 +373,7 @@ isp_target_put_entry(struct ispsoftc *isp, void *ap)
}
ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);;
-
- ISP_ADD_REQUEST(isp, iptr);
+ ISP_ADD_REQUEST(isp, nxti);
return (0);
}
@@ -639,10 +653,10 @@ static void
isp_notify_ack(struct ispsoftc *isp, void *arg)
{
char storage[QENTRY_LEN];
- u_int16_t iptr, optr;
+ u_int16_t nxti, optr;
void *outp;
- if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
+ if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
isp_prt(isp, ISP_LOGWARN,
"Request Queue Overflow For isp_notify_ack");
return;
@@ -672,7 +686,7 @@ 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_SWIZ_NOT_ACK_FC(isp, outp, na);
+ isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
} else {
na_entry_t *na = (na_entry_t *) storage;
if (arg) {
@@ -690,10 +704,10 @@ 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_SWIZ_NOT_ACK(isp, outp, na);
+ isp_put_notify_ack(isp, na, (na_entry_t *)outp);
}
ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
- ISP_ADD_REQUEST(isp, iptr);
+ ISP_ADD_REQUEST(isp, nxti);
}
static void
@@ -738,7 +752,7 @@ isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
* its command resource count, and the firmware is
* recovering from a Bus Device Reset, it returns
* the ATIO with this status. We set the command
- * resource count in the Enable Lun entry and no
+ * resource count in the Enable Lun entry and do
* not increment it. Therefore we should never get
* this status here.
*/
diff --git a/sys/dev/isp/isp_target.h b/sys/dev/isp/isp_target.h
index bc6627a..f714f1e 100644
--- a/sys/dev/isp/isp_target.h
+++ b/sys/dev/isp/isp_target.h
@@ -320,7 +320,14 @@ typedef struct {
u_int32_t ct_resid; /* residual length */
u_int16_t ct_timeout;
u_int16_t ct_seg_count;
- ispds_t ct_dataseg[ISP_RQDSEG];
+ /*
+ * This is so we can share tag name space with
+ * CTIO{2,3,4} with the minimum of pain.
+ */
+ union {
+ ispds_t ct_a[ISP_RQDSEG];
+ } _u;
+#define ct_dataseg _u.ct_a
} ct_entry_t;
/*
@@ -413,7 +420,7 @@ typedef struct {
union {
/*
* The three different modes that the target driver
- * can set the CTIO2 up as.
+ * 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.
@@ -429,15 +436,14 @@ typedef struct {
u_int16_t _reserved2;
u_int16_t ct_scsi_status;
u_int32_t ct_xfrlen;
- ispds_t ct_dataseg[ISP_RQDSEG_T2];
- /*
- * For CTIO3, an ispds64_t would go here, padded
- * to the end of the request.
- */
- /*
- * For CTIO4, an ispdlist_t would go here, padded
- * to the end of the request.
- */
+ union {
+ ispds_t ct_a[ISP_RQDSEG_T2]; /* CTIO2 */
+ ispds64_t ct_b[ISP_RQDSEG_T3]; /* CTIO3 */
+ ispdslist_t ct_c; /* CTIO4 */
+ } _u;
+#define ct_dataseg _u.ct_a
+#define ct_dataseg64 _u.ct_b
+#define ct_dslist _u.ct_c
} m0;
struct {
u_int16_t _reserved;
@@ -495,195 +501,16 @@ typedef struct {
#define CT2_DATA_UNDER 0x0800
/*
- * Macros for packing/unpacking the above structures
- */
-
-#ifdef __sparc__
-#define ISP_SBUS_SWOZZLE(isp, src, dst, taga, tagb) \
- if (isp->isp_bustype == ISP_BT_SBUS) { \
- u_int8_t tmp = src -> taga; \
- dst -> taga = dst -> tagb; \
- src -> tagb = tmp; \
- } else { \
- dst -> taga = src -> taga; \
- dst -> tagb = src -> taga; \
- }
-#else
-#define ISP_SBUS_SWOZZLE(isp, src, dst, taga, tagb) \
- dst -> taga = src -> taga; \
- dst -> tagb = src -> taga
-#endif
-
-#define MCIDF(d, s) if ((void *) d != (void *)s) MEMCPY(d, s, QENTRY_LEN)
-
-/* This is really only for SBus cards on a sparc */
-#ifdef __sparc__
-#define ISP_SWIZ_ATIO(isp, vdst, vsrc) \
-{ \
- at_entry_t *src = (at_entry_t *) vsrc; \
- at_entry_t *dst = (at_entry_t *) vdst; \
- dst->at_header = src->at_header; \
- dst->at_reserved = src->at_reserved; \
- dst->at_handle = src->at_handle; \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_lun, at_iid); \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_cdblen, at_tgt); \
- dst->at_flags = src->at_flags; \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_status, at_scsi_status); \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_tag_val, at_tag_type); \
- MEMCPY(dst->at_cdb, src->at_cdb, ATIO_CDBLEN); \
- MEMCPY(dst->at_sense, src->at_sense, QLTM_SENSELEN); \
-}
-#define ISP_SWIZ_ATIO2(isp, vdst, vsrc) \
-{ \
- at2_entry_t *src = (at2_entry_t *) vsrc; \
- at2_entry_t *dst = (at2_entry_t *) vdst; \
- dst->at_reserved = src->at_reserved; \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_lun, at_iid); \
- dst->at_rxid = src->at_rxid; \
- dst->at_flags = src->at_flags; \
- dst->at_status = src->at_status; \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_reserved1, at_taskcodes); \
- ISP_SBUS_SWOZZLE(isp, src, dst, at_taskflags, at_execodes); \
- MEMCPY(dst->at_cdb, src->at_cdb, ATIO2_CDBLEN); \
- dst->at_datalen = src->at_datalen; \
- dst->at_scclun = src->at_scclun; \
- MEMCPY(dst->at_reserved2, src->at_reserved2, sizeof dst->at_reserved2);\
- dst->at_oxid = src->at_oxid; \
-}
-#define ISP_SWIZ_CTIO(isp, vdst, vsrc) \
-{ \
- ct_entry_t *src = (ct_entry_t *) vsrc; \
- ct_entry_t *dst = (ct_entry_t *) vdst; \
- dst->ct_header = src->ct_header; \
- dst->ct_syshandle = src->ct_syshandle; \
- dst->ct_fwhandle = src->ct_fwhandle; \
- dst->ct_fwhandle = src->ct_fwhandle; \
- ISP_SBUS_SWOZZLE(isp, src, dst, ct_lun, ct_iid); \
- ISP_SBUS_SWOZZLE(isp, src, dst, ct_reserved2, ct_tgt); \
- dst->ct_flags = src->ct_flags; \
- ISP_SBUS_SWOZZLE(isp, src, dst, ct_status, ct_scsi_status); \
- ISP_SBUS_SWOZZLE(isp, src, dst, ct_tag_val, ct_tag_type); \
- dst->ct_xfrlen = src->ct_xfrlen; \
- dst->ct_resid = src->ct_resid; \
- dst->ct_timeout = src->ct_timeout; \
- dst->ct_seg_count = src->ct_seg_count; \
- MEMCPY(dst->ct_dataseg, src->ct_dataseg, sizeof (dst->ct_dataseg)); \
-}
-#define ISP_SWIZ_CTIO2(isp, vdst, vsrc) \
-{ \
- ct2_entry_t *src = (ct2_entry_t *) vsrc; \
- ct2_entry_t *dst = (ct2_entry_t *) vdst; \
- dst->ct_header = src->ct_header; \
- dst->ct_syshandle = src->ct_syshandle; \
- dst->ct_fwhandle = src->ct_fwhandle; \
- dst->ct_fwhandle = src->ct_fwhandle; \
- ISP_SBUS_SWOZZLE(isp, src, dst, ct_lun, ct_iid); \
- dst->ct_rxid = src->ct_rxid; \
- dst->ct_flags = src->ct_flags; \
- dst->ct_status = src->ct_status; \
- dst->ct_timeout = src->ct_timeout; \
- dst->ct_seg_count = src->ct_seg_count; \
- dst->ct_reloff = src->ct_reloff; \
- dst->ct_resid = src->ct_resid; \
- dst->rsp = src->rsp; \
-}
-#define ISP_SWIZ_ENABLE_LUN(isp, vdst, vsrc) \
-{ \
- lun_entry_t *src = (lun_entry_t *)vsrc; \
- lun_entry_t *dst = (lun_entry_t *)vdst; \
- dst->le_header = src->le_header; \
- dst->le_reserved2 = src->le_reserved2; \
- ISP_SBUS_SWOZZLE(isp, src, dst, le_lun, le_rsvd); \
- ISP_SBUS_SWOZZLE(isp, src, dst, le_ops, le_tgt); \
- dst->le_flags = src->le_flags; \
- ISP_SBUS_SWOZZLE(isp, src, dst, le_status, le_reserved2); \
- ISP_SBUS_SWOZZLE(isp, src, dst, le_cmd_count, le_in_count); \
- ISP_SBUS_SWOZZLE(isp, src, dst, le_cdb6len, le_cdb7len); \
- dst->le_timeout = src->le_timeout; \
- dst->le_reserved = src->le_reserved; \
-}
-#define ISP_SWIZ_NOTIFY(isp, vdst, vsrc) \
-{ \
- in_entry_type *src = (in_entry_t *)vsrc; \
- in_entry_type *dst = (in_entry_t *)vdst; \
- dst->in_header = src->in_header; \
- dst->in_reserved2 = src->in_reserved2; \
- ISP_SBUS_SWOZZLE(isp, src, dst, in_lun, in_iid); \
- ISP_SBUS_SWOZZLE(isp, src, dst, in_reserved2, in_tgt); \
- dst->in_flags = src->in_flags; \
- ISP_SBUS_SWOZZLE(isp, src, dst, in_status, in_rsvd2); \
- ISP_SBUS_SWOZZLE(isp, src, dst, in_tag_val, in_tag_type); \
- dst->in_seqid = src->in_seqid; \
- MEMCPY(dst->in_msg, src->in_msg, IN_MSGLEN); \
- MEMCPY(dst->in_reserved, src->in_reserved, IN_RESERVED); \
- MEMCPY(dst->in_sense, src->in_sense, QLTM_SENSELEN); \
-}
-#define ISP_SWIZ_NOTIFY_FC(isp, vdst, vsrc) \
-{ \
- in_fcentry_type *src = (in_fcentry_t *)vsrc; \
- in_fcentry_type *dst = (in_fcentry_t *)vdst; \
- dst->in_header = src->in_header; \
- dst->in_reserved2 = src->in_reserved2; \
- ISP_SBUS_SWOZZLE(isp, src, dst, in_lun, in_iid); \
- dst->in_scclun = src->in_scclun; \
- dst->in_reserved2 = src->in_reserved2; \
- dst->in_status = src->in_status; \
- dst->in_task_flags = src->in_task_flags; \
- dst->in_seqid = src->in_seqid; \
-}
-#define ISP_SWIZ_NOT_ACK(isp, vdst, vsrc) \
-{ \
- na_entry_t *src = (na_entry_t *)vsrc; \
- na_entry_t *dst = (na_entry_t *)vdst; \
- dst->na_header = src->na_header; \
- dst->na_reserved = src->na_reserved; \
- ISP_SBUS_SWOZZLE(isp, src, dst, na_lun, na_iid); \
- dst->na_reserved2 = src->na_reserved2; \
- ISP_SBUS_SWOZZLE(isp, src, dst, na_reserved, na_tgt); \
- dst->na_flags = src->na_flags; \
- ISP_SBUS_SWOZZLE(isp, src, dst, na_status, na_event); \
- dst->na_seqid = src->na_seqid; \
- MEMCPY(dst->na_reserved3, src->na_reserved3, NA_RSVDLEN); \
-}
-#define ISP_SWIZ_NOT_ACK_FC(isp, vdst, vsrc) \
-{ \
- na_fcentry_t *src = (na_fcentry_t *)vsrc; \
- na_fcentry_t *dst = (na_fcentry_t *)vdst; \
- dst->na_header = src->na_header; \
- dst->na_reserved = src->na_reserved; \
- ISP_SBUS_SWOZZLE(isp, src, dst, na_lun, na_iid); \
- dst->na_scclun = src->na_scclun; \
- dst->na_flags = src->na_flags; \
- dst->na_reserved2 = src->na_reserved2; \
- dst->na_status = src->na_status; \
- dst->na_task_flags = src->na_task_flags; \
- dst->na_seqid = src->na_seqid; \
- MEMCPY(dst->na_reserved3, src->na_reserved3, NA2_RSVDLEN); \
-}
-#else
-#define ISP_SWIZ_ATIO(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_ATIO2(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_CTIO(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_CTIO2(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_ENABLE_LUN(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_ATIO2(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_CTIO2(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_NOTIFY(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_NOTIFY_FC(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_NOT_ACK(isp, d, s) MCIDF(d, s)
-#define ISP_SWIZ_NOT_ACK_FC(isp, d, s) MCIDF(d, s)
-#endif
-
-/*
* Debug macros
*/
#define ISP_TDQE(isp, msg, idx, arg) \
if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
+#ifdef ISP_TARGET_FUNCTIONS
/*
- * The functions below are target mode functions that
- * are generally internal to the Qlogic driver.
+ * The functions below are for the publicly available
+ * target mode functions that are internal to the Qlogic driver.
*/
/*
@@ -724,5 +551,5 @@ int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t);
*/
void isp_target_async(struct ispsoftc *, int, int);
-
+#endif
#endif /* _ISP_TARGET_H */
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index 78ef00d..ac4613c 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -253,6 +253,8 @@ typedef struct {
u_int32_t ds_count;
} ispds64_t;
+#define DSTYPE_32BIT 0
+#define DSTYPE_64BIT 1
typedef struct {
u_int16_t ds_type; /* 0-> ispds_t, 1-> ispds64_t */
u_int32_t ds_segment; /* unused */
@@ -263,7 +265,7 @@ typedef struct {
/*
* These elements get swizzled around for SBus instances.
*/
-#define _ISP_SWAP8(a, b) { \
+#define ISP_SWAP8(a, b) { \
u_int8_t tmp; \
tmp = a; \
a = b; \
@@ -275,18 +277,6 @@ typedef struct {
u_int8_t rqs_seqno;
u_int8_t rqs_flags;
} isphdr_t;
-/*
- * There are no (for all intents and purposes) non-sparc SBus machines
- */
-#ifdef __sparc__
-#define ISP_SBUSIFY_ISPHDR(isp, hdrp) \
- if ((isp)->isp_bustype == ISP_BT_SBUS) { \
- _ISP_SWAP8((hdrp)->rqs_entry_count, (hdrp)->rqs_entry_type); \
- _ISP_SWAP8((hdrp)->rqs_flags, (hdrp)->rqs_seqno); \
- }
-#else
-#define ISP_SBUSIFY_ISPHDR(a, b)
-#endif
/* RQS Flag definitions */
#define RQSFLAG_CONTINUATION 0x01
@@ -350,18 +340,6 @@ typedef struct {
#define SYNC_TARGET 1
#define SYNC_ALL 2
-/*
- * There are no (for all intents and purposes) non-sparc SBus machines
- */
-#ifdef __sparc__
-#define ISP_SBUSIFY_ISPREQ(isp, rqp) \
- if ((isp)->isp_bustype == ISP_BT_SBUS) { \
- _ISP_SWAP8((rqp)->req_target, (rqp)->req_lun_trn); \
- }
-#else
-#define ISP_SBUSIFY_ISPREQ(a, b)
-#endif
-
#define ISP_RQDSEG_T2 3
typedef struct {
isphdr_t req_header;
@@ -373,7 +351,7 @@ typedef struct {
u_int16_t _res2;
u_int16_t req_time;
u_int16_t req_seg_count;
- u_int32_t req_cdb[4];
+ u_int8_t req_cdb[16];
u_int32_t req_totalcnt;
ispds_t req_dataseg[ISP_RQDSEG_T2];
} ispreqt2_t;
@@ -389,7 +367,7 @@ typedef struct {
u_int16_t _res2;
u_int16_t req_time;
u_int16_t req_seg_count;
- u_int32_t req_cdb[4];
+ u_int8_t req_cdb[16];
u_int32_t req_totalcnt;
ispds64_t req_dataseg[ISP_RQDSEG_T3];
} ispreqt3_t;
@@ -456,6 +434,11 @@ typedef struct {
u_int8_t req_sense_data[32];
} ispstatusreq_t;
+typedef struct {
+ isphdr_t req_header;
+ u_int8_t req_sense_data[60];
+} ispstatus_cont_t;
+
/*
* For Qlogic 2X00, the high order byte of SCSI status has
* additional meaning.
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 95bd276..c905d8b 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -54,7 +54,7 @@
#endif
#define ISP_CORE_VERSION_MAJOR 2
-#define ISP_CORE_VERSION_MINOR 4
+#define ISP_CORE_VERSION_MINOR 5
/*
* Vector for bus specific code to provide specific services.
@@ -160,10 +160,10 @@ struct ispmdvec {
#define ISP_QAVAIL(isp) \
ISP_QFREE(isp->isp_reqidx, isp->isp_reqodx, RQUEST_QUEUE_LEN(isp))
-#define ISP_ADD_REQUEST(isp, iptr) \
- MEMORYBARRIER(isp, SYNC_REQUEST, iptr, QENTRY_LEN); \
- WRITE_REQUEST_QUEUE_IN_POINTER(isp, iptr); \
- isp->isp_reqidx = iptr
+#define ISP_ADD_REQUEST(isp, nxti) \
+ MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN); \
+ WRITE_REQUEST_QUEUE_IN_POINTER(isp, nxti); \
+ isp->isp_reqidx = nxti
/*
* SCSI Specific Host Adapter Parameters- per bus, per target
@@ -350,12 +350,13 @@ typedef struct ispsoftc {
u_int32_t isp_maxluns; /* maximum luns supported */
u_int32_t isp_clock : 8, /* input clock */
- : 6,
- isp_role : 2,
- : 1,
+ : 5,
+ isp_failed : 1, /* board failed */
+ isp_open : 1, /* opened (ioctl) */
isp_touched : 1, /* board ever seen? */
isp_bustype : 1, /* SBus or PCI */
isp_loaded_fw : 1, /* loaded firmware */
+ isp_role : 2, /* roles supported */
isp_dblev : 12; /* debug log mask */
u_int32_t isp_confopts; /* config options */
@@ -376,8 +377,8 @@ typedef struct ispsoftc {
*/
volatile u_int32_t
- isp_mboxbsy : 8, /* mailbox command active */
- : 1,
+ isp_obits : 8, /* mailbox command output */
+ isp_mboxbsy : 1, /* mailbox command active */
isp_state : 3,
isp_sendmarker : 2, /* send a marker entry */
isp_update : 2, /* update parameters */
@@ -481,6 +482,14 @@ typedef struct ispsoftc {
#define ISP_BT_SBUS 1 /* SBus Implementations */
/*
+ * If we have not otherwise defined SBus support away make sure
+ * it is defined here such that the code is included as default
+ */
+#ifndef ISP_SBUS_SUPPORTED
+#define ISP_SBUS_SUPPORTED 1
+#endif
+
+/*
* Chip Types
*/
#define ISP_HA_SCSI 0xf
@@ -656,9 +665,8 @@ int isp_control(struct ispsoftc *, ispctl_t, void *);
*
* ISPASYNC_UNHANDLED_RESPONSE gives outer layers a chance to parse a
* response queue entry not otherwise handled. The outer layer should
- * return non-zero if it handled it. The 'arg' points to a (possibly only
- * partially) massaged response queue entry (see the platform's
- * ISP_UNSWIZZLE_RESPONSE macro).
+ * return non-zero if it handled it. The 'arg' points to an unmassaged
+ * response queue entry.
*/
typedef enum {
@@ -819,14 +827,16 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* Block.
*
* (XXX these do endian specific transformations- in transition XXX)
- * ISP_SWIZZLE_ICB
- * ISP_UNSWIZZLE_AND_COPY_PDBP
- * ISP_SWIZZLE_CONTINUATION
- * ISP_SWIZZLE_REQUEST
- * ISP_UNSWIZZLE_RESPONSE
- * ISP_SWIZZLE_SNS_REQ
- * ISP_UNSWIZZLE_SNS_RSP
- * ISP_SWIZZLE_NVRAM_WORD
+ *
+ * ISP_IOXPUT_8(struct ispsoftc *, u_int8_t srcval, u_int8_t *dstptr)
+ * ISP_IOXPUT_16(struct ispsoftc *, u_int16_t srcval, u_int16_t *dstptr)
+ * ISP_IOXPUT_32(struct ispsoftc *, u_int32_t srcval, u_int32_t *dstptr)
+ *
+ * ISP_IOXGET_8(struct ispsoftc *, u_int8_t *srcptr, u_int8_t dstrval)
+ * ISP_IOXGET_16(struct ispsoftc *, u_int16_t *srcptr, u_int16_t dstrval)
+ * ISP_IOXGET_32(struct ispsoftc *, u_int32_t *srcptr, u_int32_t dstrval)
+ *
+ * ISP_SWIZZLE_NVRAM_WORD(struct ispsoftc *, u_int16_t *)
*/
#endif /* _ISPVAR_H */
OpenPOWER on IntegriCloud