diff options
author | mjacob <mjacob@cvs.openbsd.org> | 2001-12-14 00:20:56 +0000 |
---|---|---|
committer | mjacob <mjacob@cvs.openbsd.org> | 2001-12-14 00:20:56 +0000 |
commit | 17d4cdf5fb28cbcf2a7f35a2029314c30369a46f (patch) | |
tree | b39666b472468774f4e8f103699528500aa0af0b /sys | |
parent | b3b7dc842a6cac27f1954516ba9e702ba2b1ef05 (diff) |
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).
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.
For OpenSD, it does a ddi_dmamap_sync as appropriate. This gets us out of
the explicit ddi_dmamap_sync on the whole response queue that we did for SBus
cards at each interrupt. Now, because SBus/sparc doesn't use bus_dma, some
shenanigans were done to support this. But Jason was nice enough to test the
SBus/sparcv9 changes for me, and they did the right thing as well.
Set things up so that platforms that cannot have an SBus don't get a lot of
the SBus code checks (dead coded out).
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).
Explicitly decode GetAllNext SNS Response back *as* a GetAllNext response.
Otherwise, we won't unswizzle it correctly.
Nuke some additional __P macros.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc/dev/isp_sbus.c | 34 | ||||
-rw-r--r-- | sys/dev/ic/isp.c | 259 | ||||
-rw-r--r-- | sys/dev/ic/isp_inline.h | 1105 | ||||
-rw-r--r-- | sys/dev/ic/isp_openbsd.c | 12 | ||||
-rw-r--r-- | sys/dev/ic/isp_openbsd.h | 120 | ||||
-rw-r--r-- | sys/dev/ic/isp_target.c | 78 | ||||
-rw-r--r-- | sys/dev/ic/isp_target.h | 217 | ||||
-rw-r--r-- | sys/dev/ic/ispmbox.h | 39 | ||||
-rw-r--r-- | sys/dev/ic/ispvar.h | 54 | ||||
-rw-r--r-- | sys/dev/pci/isp_pci.c | 234 |
10 files changed, 1615 insertions, 537 deletions
diff --git a/sys/arch/sparc/dev/isp_sbus.c b/sys/arch/sparc/dev/isp_sbus.c index c564086e0e1..99548e366e3 100644 --- a/sys/arch/sparc/dev/isp_sbus.c +++ b/sys/arch/sparc/dev/isp_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_sbus.c,v 1.18 2001/09/01 07:16:39 mjacob Exp $ */ +/* $OpenBSD: isp_sbus.c,v 1.19 2001/12/14 00:20:54 mjacob Exp $ */ /* * SBus specific probe and attach routines for Qlogic ISP SCSI adapters. * @@ -47,6 +47,15 @@ #include <dev/microcode/isp/asm_sbus.h> #endif +#define ISP_SBUSIFY_ISPHDR(isp, hdrp) \ + ISP_SWAP8((hdrp)->rqs_entry_count, (hdrp)->rqs_entry_type); \ + ISP_SWAP8((hdrp)->rqs_flags, (hdrp)->rqs_seqno); + +#define ISP_SWIZZLE_REQUEST(a, b) \ + ISP_SBUSIFY_ISPHDR(a, &(b)->req_header); \ + ISP_SWAP8((b)->req_target, (b)->req_lun_trn) + + static int isp_sbus_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *); static u_int16_t isp_sbus_rd_reg(struct ispsoftc *, int); @@ -80,7 +89,7 @@ struct isp_sbussoftc { struct ispsoftc sbus_isp; sdparam sbus_dev; struct intrhand sbus_ih; - volatile u_char *sbus_reg; + volatile u_int16_t *sbus_reg; int sbus_node; int sbus_pri; struct ispmdvec sbus_mdvec; @@ -148,9 +157,9 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux) sbc->sbus_mdvec = mdvec; if (ca->ca_ra.ra_vaddr) { - sbc->sbus_reg = (volatile u_char *) ca->ca_ra.ra_vaddr; + sbc->sbus_reg = (volatile u_int16_t *) ca->ca_ra.ra_vaddr; } else { - sbc->sbus_reg = (volatile u_char *) + sbc->sbus_reg = (volatile u_int16_t *) mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len); } sbc->sbus_node = ca->ca_ra.ra_node; @@ -273,15 +282,14 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux) (((struct isp_sbussoftc *)a)->sbus_poff[((x) & _BLK_REG_MASK) >> \ _BLK_REG_SHFT] + ((x) & 0xff)) -#define BXR2(pcs, off) \ - (*((u_int16_t *) &sbc->sbus_reg[off])) +#define BXR2(pcs, off) (sbc->sbus_reg[off >> 1]) static int isp_sbus_rd_isr(struct ispsoftc *isp, u_int16_t *isrp, u_int16_t *semap, u_int16_t *mbp) { struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; - u_int16_t isr, sema; + volatile u_int16_t isr, sema; isr = BXR2(pcs, IspVirt2Off(isp, BIU_ISR)); sema = BXR2(pcs, IspVirt2Off(isp, BIU_SEMA)); @@ -304,7 +312,7 @@ isp_sbus_rd_reg(struct ispsoftc *isp, int regoff) struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; int offset = sbc->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; offset += (regoff & 0xff); - return (*((u_int16_t *) &sbc->sbus_reg[offset])); + return ((u_int16_t) sbc->sbus_reg[offset >> 1]); } static void @@ -313,7 +321,7 @@ isp_sbus_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val) struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; int offset = sbc->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; offset += (regoff & 0xff); - *((u_int16_t *) &sbc->sbus_reg[offset]) = val; + sbc->sbus_reg[offset >> 1] = val; } @@ -382,10 +390,12 @@ isp_sbus_dmasetup(struct ispsoftc *isp, struct scsi_xfer *xs, ispreq_t *rq, u_int16_t *iptrp, u_int16_t optr) { struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; + ispreq_t *qe; ispcontreq_t *crq; vaddr_t kdvma; int dosleep = (xs->flags & SCSI_NOSLEEP) != 0; + qe = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); if (xs->datalen == 0) { rq->req_seg_count = 1; goto mbxsync; @@ -444,6 +454,7 @@ isp_sbus_dmasetup(struct ispsoftc *isp, struct scsi_xfer *xs, ispreq_t *rq, mbxsync: ISP_SWIZZLE_REQUEST(isp, rq); + bcopy(rq, qe, sizeof (ispreq_t)); return (CMD_QUEUED); } @@ -478,11 +489,6 @@ isp_sbus_intr(void *arg) isp->isp_intbogus++; return (0); } else { -#if 0 - struct iss_sbussoftc *s = (struct isp_sbussoftc *)isp; - bus_dmamap_sync(s->pci_dmat, s->pci_result_dmap, - BUS_DMASYNC_POSTREAD); -#endif isp->isp_osinfo.onintstack = 1; isp_intr(isp, isr, sema, mbox); isp->isp_osinfo.onintstack = 0; diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c index aa7be6eb073..44a41ff45dd 100644 --- a/sys/dev/ic/isp.c +++ b/sys/dev/ic/isp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp.c,v 1.24 2001/10/24 18:31:15 mjacob Exp $ */ +/* $OpenBSD: isp.c,v 1.25 2001/12/14 00:20:54 mjacob Exp $ */ /* * Machine and OS Independent (well, as best as possible) * code for the Qlogic ISP SCSI adapters. @@ -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_ganrsp_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_ganrsp_t *) fcp->isp_scratch; + rs0 = (sns_ganrsp_t *) ((u_int8_t *)fcp->isp_scratch + 0x100); + isp_get_gan_response(isp, rs0, rs1); + 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/ic/isp_inline.h b/sys/dev/ic/isp_inline.h index afdb6c99a27..d6511261ebe 100644 --- a/sys/dev/ic/isp_inline.h +++ b/sys/dev/ic/isp_inline.h @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_inline.h,v 1.9 2001/09/01 07:16:40 mjacob Exp $ */ +/* $OpenBSD: isp_inline.h,v 1.10 2001/12/14 00:20:55 mjacob Exp $ */ /* * Qlogic Host Adapter Inline Functions * @@ -236,4 +236,1107 @@ 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); +static INLINE void +isp_get_gan_response(struct ispsoftc *, sns_ganrsp_t *, sns_ganrsp_t *); +#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]); + } +} + +static INLINE void +isp_get_gan_response(struct ispsoftc *isp, sns_ganrsp_t *src, sns_ganrsp_t *dst) +{ + 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]); + } + ISP_IOXGET_8(isp, &src->snscb_pnlen, dst->snscb_pnlen); + for (i = 0; i < 255; i++) { + ISP_IOXGET_8(isp, &src->snscb_pname[i], dst->snscb_pname[i]); + } + for (i = 0; i < 8; i++) { + ISP_IOXGET_8(isp, &src->snscb_nodename[i], + dst->snscb_nodename[i]); + } + ISP_IOXGET_8(isp, &src->snscb_nnlen, dst->snscb_nnlen); + for (i = 0; i < 255; i++) { + ISP_IOXGET_8(isp, &src->snscb_nname[i], dst->snscb_nname[i]); + } + for (i = 0; i < 8; i++) { + ISP_IOXGET_8(isp, &src->snscb_ipassoc[i], + dst->snscb_ipassoc[i]); + } + for (i = 0; i < 16; i++) { + ISP_IOXGET_8(isp, &src->snscb_ipaddr[i], dst->snscb_ipaddr[i]); + } + for (i = 0; i < 4; i++) { + ISP_IOXGET_8(isp, &src->snscb_svc_class[i], + dst->snscb_svc_class[i]); + } + for (i = 0; i < 32; i++) { + ISP_IOXGET_8(isp, &src->snscb_fc4_types[i], + dst->snscb_fc4_types[i]); + } + for (i = 0; i < 8; i++) { + ISP_IOXGET_8(isp, &src->snscb_fpname[i], dst->snscb_fpname[i]); + } + ISP_IOXGET_8(isp, &src->snscb_reserved, dst->snscb_reserved); + for (i = 0; i < 3; i++) { + ISP_IOXGET_8(isp, &src->snscb_hardaddr[i], + dst->snscb_hardaddr[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/ic/isp_openbsd.c b/sys/dev/ic/isp_openbsd.c index 4ea4399d73e..59f60a1fdac 100644 --- a/sys/dev/ic/isp_openbsd.c +++ b/sys/dev/ic/isp_openbsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_openbsd.c,v 1.21 2001/12/13 00:15:40 nordin Exp $ */ +/* $OpenBSD: isp_openbsd.c,v 1.22 2001/12/14 00:20:55 mjacob Exp $ */ /* * Platform (OpenBSD) dependent common attachment code for Qlogic adapters. * @@ -529,8 +529,8 @@ isp_wdog(void *arg) XS_CMD_S_CLEAR(xs); isp_done(xs); } else { - u_int16_t iptr, optr; - ispreq_t *mp; + u_int16_t nxti, optr; + ispreq_t local, *mp = &local, *qe; isp_prt(isp, ISP_LOGWARN, "possible command timeout on handle %x", handle); @@ -538,7 +538,7 @@ isp_wdog(void *arg) XS_CMD_C_WDOG(xs); timeout_add(&xs->stimeout, _XT(xs)); XS_CMD_S_TIMER(xs); - if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) { + if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) { ISP_UNLOCK(isp); return; } @@ -548,8 +548,8 @@ isp_wdog(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 if (isp->isp_dblev) { isp_prt(isp, ISP_LOGDEBUG1, "watchdog with no command"); diff --git a/sys/dev/ic/isp_openbsd.h b/sys/dev/ic/isp_openbsd.h index 408551e8303..7cafc074cbc 100644 --- a/sys/dev/ic/isp_openbsd.h +++ b/sys/dev/ic/isp_openbsd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_openbsd.h,v 1.17 2001/11/06 19:53:18 miod Exp $ */ +/* $OpenBSD: isp_openbsd.h,v 1.18 2001/12/14 00:20:55 mjacob Exp $ */ /* * OpenBSD Specific definitions for the Qlogic ISP Host Adapter */ @@ -41,6 +41,10 @@ #include <sys/user.h> #include <sys/queue.h> +#if !(defined(__sparc__) && !defined(__sparcv9__)) +#include <machine/bus.h> +#endif + #include <scsi/scsi_all.h> #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> @@ -50,9 +54,17 @@ #include <uvm/uvm_extern.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 ISP_PLATFORM_VERSION_MAJOR 2 -#define ISP_PLATFORM_VERSION_MINOR 0 +#define ISP_PLATFORM_VERSION_MINOR 1 struct isposinfo { struct device _dev; @@ -63,6 +75,16 @@ struct isposinfo { int mboxwaiting; u_int32_t islocked; u_int32_t onintstack; +#if !(defined(__sparc__) && !defined(__sparcv9__)) + bus_dma_tag_t dmatag; + bus_dmamap_t rqdmap; + bus_dmamap_t rsdmap; + bus_dmamap_t scdmap; /* FC only */ +#define isp_dmatag isp_osinfo.dmatag +#define isp_rqdmap isp_osinfo.rqdmap +#define isp_rsdmap isp_osinfo.rsdmap +#define isp_scdmap isp_osinfo.scdmap +#endif unsigned int : 28, rtpend : 1, @@ -112,14 +134,52 @@ struct isposinfo { #define MAXISPREQUEST(isp) 256 -#ifdef __alpha__ -#define MEMORYBARRIER(isp, type, offset, size) alpha_mb() +#if !(defined(__sparc__) && !defined(__sparcv9__)) +#define MEMORYBARRIER(isp, type, offset, size) \ +switch (type) { \ +case SYNC_REQUEST: \ +{ \ + off_t off = (off_t) offset * QENTRY_LEN; \ + bus_dmamap_sync(isp->isp_dmatag, isp->isp_rqdmap, \ + off, size, BUS_DMASYNC_PREWRITE); \ + break; \ +} \ +case SYNC_RESULT: \ +{ \ + off_t off = (off_t) offset * QENTRY_LEN; \ + off += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); \ + bus_dmamap_sync(isp->isp_dmatag, isp->isp_rsdmap, \ + off, size, BUS_DMASYNC_POSTREAD); \ + break; \ +} \ +case SYNC_SFORDEV: \ +{ \ + off_t off = \ + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) + \ + ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)) + offset; \ + bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \ + off, size, BUS_DMASYNC_PREWRITE); \ + break; \ +} \ +case SYNC_SFORCPU: \ +{ \ + off_t off = \ + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) + \ + ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)) + offset; \ + bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \ + off, size, BUS_DMASYNC_POSTREAD); \ + break; \ +} \ +case SYNC_REG: \ +default: \ + break; \ +} #else #define MEMORYBARRIER(isp, type, offset, size) #endif #define MBOX_ACQUIRE(isp) -#define MBOX_WAIT_COMPLETE isp_wait_complete +#define MBOX_WAIT_COMPLETE isp_wait_complete #define MBOX_NOTIFY_COMPLETE(isp) \ if (isp->isp_osinfo.mboxwaiting) { \ @@ -194,29 +254,37 @@ 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) -#ifdef __sparc__ -#define ISP_SWIZZLE_REQUEST(a, b) \ - ISP_SBUSIFY_ISPHDR(a, &(b)->req_header); \ - ISP_SBUSIFY_ISPREQ(a, b) -#define ISP_UNSWIZZLE_RESPONSE(a, b, c) \ - ISP_SBUSIFY_ISPHDR(a, &(b)->req_header) +#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 : swap16(s) +#define ISP_IOXPUT_32(isp, s, d) \ + *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : swap32(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) : swap16(*((u_int16_t *)s)) +#define ISP_IOXGET_32(isp, s, d) \ + d = (isp->isp_bustype == ISP_BT_SBUS)? \ + *((u_int32_t *)s) : swap32(*((u_int32_t *)s)) #else -#define ISP_SWIZZLE_REQUEST(a, b) -#define ISP_UNSWIZZLE_RESPONSE(a, b, c) +#define ISP_IOXPUT_8(isp, s, d) *(d) = s +#define ISP_IOXPUT_16(isp, s, d) *(d) = swap16(s) +#define ISP_IOXPUT_32(isp, s, d) *(d) = swap32(s) +#define ISP_IOXGET_8(isp, s, d) d = (*((u_int8_t *)s)) +#define ISP_IOXGET_16(isp, s, d) d = swap16(*((u_int16_t *)s)) +#define ISP_IOXGET_32(isp, s, d) d = swap32(*((u_int32_t *)s)) #endif -#define ISP_SWIZZLE_SNS_REQ(a, b) -#define ISP_UNSWIZZLE_SNS_RSP(a, b, c) -#ifdef __sparc__ -#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) \ - { \ - u_int16_t tmp = *rp >> 8; \ - tmp |= ((*rp & 0xff) << 8); \ - *rp = tmp; \ - } +#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = swap16(*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 @@ -336,7 +404,7 @@ isp_wait_complete(struct ispsoftc *isp) { if (MUST_POLL(isp)) { int usecs = 0; - while (usecs < 2 * 1000000) { + while (usecs < 5 * 1000000) { u_int16_t isr, sema, mbox; if (isp->isp_mboxbsy == 0) { break; diff --git a/sys/dev/ic/isp_target.c b/sys/dev/ic/isp_target.c index d51345d5b38..6277cd14c27 100644 --- a/sys/dev/ic/isp_target.c +++ b/sys/dev/ic/isp_target.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_target.c,v 1.6 2001/10/06 22:45:52 mjacob Exp $ */ +/* $OpenBSD: isp_target.c,v 1.7 2001/12/14 00:20:55 mjacob Exp $ */ /* * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. * @@ -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/ic/isp_target.h b/sys/dev/ic/isp_target.h index ba5b90d10e7..8ace3c8af19 100644 --- a/sys/dev/ic/isp_target.h +++ b/sys/dev/ic/isp_target.h @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_target.h,v 1.8 2001/10/06 22:45:52 mjacob Exp $ */ +/* $OpenBSD: isp_target.h,v 1.9 2001/12/14 00:20:55 mjacob Exp $ */ /* @(#)isp_target.h 1.3 */ /* @@ -322,7 +322,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; /* @@ -415,7 +422,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. @@ -431,15 +438,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; @@ -497,195 +503,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. */ /* @@ -726,5 +553,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/ic/ispmbox.h b/sys/dev/ic/ispmbox.h index 06ddd74149c..71f56aeb180 100644 --- a/sys/dev/ic/ispmbox.h +++ b/sys/dev/ic/ispmbox.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ispmbox.h,v 1.15 2001/10/06 22:45:52 mjacob Exp $ */ +/* $OpenBSD: ispmbox.h,v 1.16 2001/12/14 00:20:55 mjacob Exp $ */ /* * Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters. * @@ -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/ic/ispvar.h b/sys/dev/ic/ispvar.h index d826ce10926..6b880efb6b4 100644 --- a/sys/dev/ic/ispvar.h +++ b/sys/dev/ic/ispvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ispvar.h,v 1.18 2001/10/06 22:45:52 mjacob Exp $ */ +/* $OpenBSD: ispvar.h,v 1.19 2001/12/14 00:20:55 mjacob Exp $ */ /* * Soft Definitions for for Qlogic ISP SCSI adapters. * @@ -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 */ diff --git a/sys/dev/pci/isp_pci.c b/sys/dev/pci/isp_pci.c index 063c5033aec..405803a2180 100644 --- a/sys/dev/pci/isp_pci.c +++ b/sys/dev/pci/isp_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_pci.c,v 1.26 2001/11/05 17:25:58 art Exp $ */ +/* $OpenBSD: isp_pci.c,v 1.27 2001/12/14 00:20:55 mjacob Exp $ */ /* * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. * @@ -299,10 +299,6 @@ struct isp_pcisoftc { pcitag_t pci_tag; bus_space_tag_t pci_st; bus_space_handle_t pci_sh; - bus_dma_tag_t pci_dmat; - bus_dmamap_t pci_scratch_dmap; /* for fcp only */ - bus_dmamap_t pci_rquest_dmap; - bus_dmamap_t pci_result_dmap; bus_dmamap_t *pci_xfer_dmap; void * pci_ih; int16_t pci_poff[_NREG_BLKS]; @@ -371,7 +367,7 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux) bus_space_handle_t sh, ioh, memh; pci_intr_handle_t ih; const char *intrstr; - int ioh_valid, memh_valid, i; + int ioh_valid, memh_valid; bus_addr_t iobase, mbase; bus_size_t iosize, msize; @@ -437,7 +433,6 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux) pcs->pci_st = st; pcs->pci_sh = sh; - pcs->pci_dmat = pa->pa_dmat; pcs->pci_pc = pa->pa_pc; pcs->pci_tag = pa->pa_tag; pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; @@ -591,6 +586,7 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux) } #endif + isp->isp_dmatag = pa->pa_dmat; isp->isp_revision = rev; /* @@ -663,23 +659,6 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux) free(isp->isp_param, M_DEVBUF); return; } - - /* - * Create the DMA maps for the data transfers. - */ - for (i = 0; i < isp->isp_maxcmds; i++) { - if (bus_dmamap_create(pcs->pci_dmat, MAXPHYS, - (MAXPHYS / NBPG) + 1, MAXPHYS, 0, BUS_DMA_NOWAIT, - &pcs->pci_xfer_dmap[i])) { - printf("%s: can't create dma maps\n", isp->isp_name); - isp_uninit(isp); - ISP_UNLOCK(isp); - free(isp->isp_param, M_DEVBUF); - return; - } - } - - /* * Do Generic attach now. */ @@ -908,51 +887,87 @@ isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val) static int isp_pci_mbxdma(struct ispsoftc *isp) { - struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; - bus_dma_segment_t seg; + struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; + bus_dma_tag_t dmat = isp->isp_dmatag; + bus_dma_segment_t sg; bus_size_t len; fcparam *fcp; - int rseg; + int rs, i; if (isp->isp_rquest_dma) /* been here before? */ return (0); - len = isp->isp_maxcmds * sizeof (XS_T); + len = isp->isp_maxcmds * sizeof (XS_T *); isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK); + if (isp->isp_xflist == NULL) { + isp_prt(isp, ISP_LOGERR, "cannot malloc xflist array"); + return (1); + } bzero(isp->isp_xflist, len); len = isp->isp_maxcmds * sizeof (bus_dmamap_t); - pci->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK); + pcs->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK); + if (pcs->pci_xfer_dmap == NULL) { + free(isp->isp_xflist, M_DEVBUF); + isp->isp_xflist = NULL; + isp_prt(isp, ISP_LOGERR, "cannot malloc dma map array"); + return (1); + } + + for (i = 0; i < isp->isp_maxcmds; i++) { + if (bus_dmamap_create(dmat, MAXPHYS, (MAXPHYS / NBPG) + 1, + MAXPHYS, 0, BUS_DMA_NOWAIT, &pcs->pci_xfer_dmap[i])) { + isp_prt(isp, ISP_LOGERR, "cannot create dma maps"); + break; + } + } + + if (i < isp->isp_maxcmds) { + while (--i >= 0) { + bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]); + } + free(isp->isp_xflist, M_DEVBUF); + free(pcs->pci_xfer_dmap, M_DEVBUF); + isp->isp_xflist = NULL; + pcs->pci_xfer_dmap = NULL; + return (1); + } /* * Allocate and map the request queue. */ len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); - if (bus_dmamem_alloc(pci->pci_dmat, len, NBPG, 0, &seg, 1, &rseg, - BUS_DMA_NOWAIT) || bus_dmamem_map(pci->pci_dmat, &seg, rseg, len, - (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) - return (1); - if (bus_dmamap_create(pci->pci_dmat, len, 1, len, 0, BUS_DMA_NOWAIT, - &pci->pci_rquest_dmap) || - bus_dmamap_load(pci->pci_dmat, pci->pci_rquest_dmap, - (caddr_t)isp->isp_rquest, len, NULL, BUS_DMA_NOWAIT)) - return (1); + if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs, + BUS_DMA_NOWAIT) || + bus_dmamem_map(isp->isp_dmatag, &sg, rs, len, + (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { + goto dmafail; + } - isp->isp_rquest_dma = pci->pci_rquest_dmap->dm_segs[0].ds_addr; + if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT, + &isp->isp_rqdmap) || bus_dmamap_load(dmat, isp->isp_rqdmap, + (caddr_t)isp->isp_rquest, len, NULL, + BUS_DMA_NOWAIT)) { + goto dmafail; + } + isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr; /* * Allocate and map the result queue. */ len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); - if (bus_dmamem_alloc(pci->pci_dmat, len, NBPG, 0, &seg, 1, &rseg, - BUS_DMA_NOWAIT) || bus_dmamem_map(pci->pci_dmat, &seg, rseg, len, - (caddr_t *)&isp->isp_result, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) - return (1); - if (bus_dmamap_create(pci->pci_dmat, len, 1, len, 0, BUS_DMA_NOWAIT, - &pci->pci_result_dmap) || - bus_dmamap_load(pci->pci_dmat, pci->pci_result_dmap, - (caddr_t)isp->isp_result, len, NULL, BUS_DMA_NOWAIT)) - return (1); - isp->isp_result_dma = pci->pci_result_dmap->dm_segs[0].ds_addr; + if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs, + BUS_DMA_NOWAIT) || + bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result, + BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { + goto dmafail; + } + if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT, + &isp->isp_rsdmap) || bus_dmamap_load(isp->isp_dmatag, + isp->isp_rsdmap, (caddr_t)isp->isp_result, len, NULL, + BUS_DMA_NOWAIT)) { + goto dmafail; + } + isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr; if (IS_SCSI(isp)) { return (0); @@ -960,30 +975,44 @@ isp_pci_mbxdma(struct ispsoftc *isp) fcp = isp->isp_param; len = ISP2100_SCRLEN; - if (bus_dmamem_alloc(pci->pci_dmat, len, NBPG, 0, &seg, 1, &rseg, - BUS_DMA_NOWAIT) || bus_dmamem_map(pci->pci_dmat, &seg, rseg, len, - (caddr_t *)&fcp->isp_scratch, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) - return (1); - if (bus_dmamap_create(pci->pci_dmat, len, 1, len, 0, BUS_DMA_NOWAIT, - &pci->pci_scratch_dmap) || bus_dmamap_load(pci->pci_dmat, - pci->pci_scratch_dmap, (caddr_t)fcp->isp_scratch, len, NULL, - BUS_DMA_NOWAIT)) - return (1); - fcp->isp_scdma = pci->pci_scratch_dmap->dm_segs[0].ds_addr; + if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs, + BUS_DMA_NOWAIT) || + bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch, + BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { + goto dmafail; + } + if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT, + &isp->isp_scdmap) || bus_dmamap_load(dmat, + isp->isp_scdmap, (caddr_t)fcp->isp_scratch, len, NULL, + BUS_DMA_NOWAIT)) { + goto dmafail; + } + fcp->isp_scdma = isp->isp_scdmap->dm_segs[0].ds_addr; return (0); +dmafail: + isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure"); + for (i = 0; i < isp->isp_maxcmds; i++) { + bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]); + } + free(isp->isp_xflist, M_DEVBUF); + free(pcs->pci_xfer_dmap, M_DEVBUF); + isp->isp_xflist = NULL; + pcs->pci_xfer_dmap = NULL; + return (1); } static int -isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, u_int16_t *iptrp, - u_int16_t optr) +isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, + u_int16_t *nxtip, u_int16_t optr) { - struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; + struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; bus_dmamap_t dmap; - ispcontreq_t *crq; + u_int16_t starti = isp->isp_reqidx, nxti = *nxtip; + ispreq_t *qep; int segcnt, seg, error, ovseg, seglim, drq; - dmap = pci->pci_xfer_dmap[isp_handle_index(rq->req_handle)]; - + qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, starti); + dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)]; if (xs->datalen == 0) { rq->req_seg_count = 1; goto mbxsync; @@ -1000,14 +1029,14 @@ isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, u_int16_t *iptrp, ((ispreqt2_t *)rq)->req_totalcnt = xs->datalen; ((ispreqt2_t *)rq)->req_flags |= drq; } else { + rq->req_flags |= drq; if (XS_CDBLEN(xs) > 12) seglim = 0; else seglim = ISP_RQDSEG; - rq->req_flags |= drq; } - error = bus_dmamap_load(pci->pci_dmat, dmap, xs->data, xs->datalen, - NULL, xs->flags & SCSI_NOSLEEP ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); + error = bus_dmamap_load(isp->isp_dmatag, dmap, xs->data, xs->datalen, + NULL, (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); if (error) { XS_SETERR(xs, HBA_BOTCH); return (CMD_COMPLETE); @@ -1015,6 +1044,10 @@ isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, u_int16_t *iptrp, segcnt = dmap->dm_nsegs; + isp_prt(isp, ISP_LOGDEBUG2, "%d byte %s %p in %d segs", + xs->datalen, (xs->flags & SCSI_DATA_IN)? "read to" : + "write from", xs->data, segcnt); + for (seg = 0, rq->req_seg_count = 0; seg < segcnt && rq->req_seg_count < seglim; seg++, rq->req_seg_count++) { @@ -1030,17 +1063,27 @@ isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, u_int16_t *iptrp, rq->req_dataseg[rq->req_seg_count].ds_base = dmap->dm_segs[seg].ds_addr; } + isp_prt(isp, ISP_LOGDEBUG2, "seg0.[%d]={0x%lx,%lu}", + rq->req_seg_count, (long) dmap->dm_segs[seg].ds_addr, + (unsigned long) dmap->dm_segs[seg].ds_len); } - if (seg == segcnt) + if (seg == segcnt) { goto dmasync; + } do { - crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp); - *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN(isp)); - if (*iptrp == optr) { + u_int16_t onxti; + ispcontreq_t *crq, *cqe, local; + + crq = &local; + + cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); + onxti = nxti; + nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); + if (nxti == optr) { isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); - bus_dmamap_unload(pci->pci_dmat, dmap); + bus_dmamap_unload(isp->isp_dmatag, dmap); XS_SETERR(xs, HBA_BOTCH); return (CMD_EAGAIN); } @@ -1055,18 +1098,34 @@ isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, u_int16_t *iptrp, dmap->dm_segs[seg].ds_len; crq->req_dataseg[ovseg].ds_base = dmap->dm_segs[seg].ds_addr; + isp_prt(isp, ISP_LOGDEBUG2, "seg%d.[%d]={0x%lx,%lu}", + rq->req_header.rqs_entry_count - 1, + rq->req_seg_count, (long)dmap->dm_segs[seg].ds_addr, + (unsigned long) dmap->dm_segs[seg].ds_len); } + isp_put_cont_req(isp, crq, cqe); + MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); } while (seg < segcnt); dmasync: - bus_dmamap_sync(pci->pci_dmat, dmap, 0, dmap->dm_mapsize, - (xs->flags & SCSI_DATA_IN) ? - BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize, + (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : + BUS_DMASYNC_PREWRITE); mbxsync: - ISP_SWIZZLE_REQUEST(isp, rq); - bus_dmamap_sync(pci->pci_dmat, pci->pci_rquest_dmap, 0, - pci->pci_rquest_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); + 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; + } + *nxtip = nxti; return (CMD_QUEUED); } @@ -1075,15 +1134,12 @@ isp_pci_intr(void *arg) { u_int16_t isr, sema, mbox; struct ispsoftc *isp = (struct ispsoftc *)arg; - struct isp_pcisoftc *p = (struct isp_pcisoftc *)isp; isp->isp_intcnt++; if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) { isp->isp_intbogus++; return (0); } else { - bus_dmamap_sync(p->pci_dmat, p->pci_result_dmap, 0, - p->pci_result_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); isp->isp_osinfo.onintstack = 1; isp_intr(isp, isr, sema, mbox); isp->isp_osinfo.onintstack = 0; @@ -1094,12 +1150,12 @@ isp_pci_intr(void *arg) static void isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle) { - struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; - bus_dmamap_t dmap = pci->pci_xfer_dmap[isp_handle_index(handle)]; - bus_dmamap_sync(pci->pci_dmat, dmap, 0, dmap->dm_mapsize, - xs->flags & SCSI_DATA_IN ? + struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; + bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)]; + bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize, + (xs->flags & SCSI_DATA_IN)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(pci->pci_dmat, dmap); + bus_dmamap_unload(isp->isp_dmatag, dmap); } static void @@ -1112,9 +1168,9 @@ isp_pci_reset1(struct ispsoftc *isp) static void isp_pci_dumpregs(struct ispsoftc *isp, const char *msg) { - struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; + struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; if (msg) isp_prt(isp, ISP_LOGERR, "%s", msg); isp_prt(isp, ISP_LOGERR, "PCI Status Command/Status=%x\n", - pci_conf_read(pci->pci_pc, pci->pci_tag, PCI_COMMAND_STATUS_REG)); + pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG)); } |