diff options
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)); } |