diff options
author | mjacob <mjacob@FreeBSD.org> | 2002-02-04 21:04:25 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2002-02-04 21:04:25 +0000 |
commit | 6d2dbc994419de3783c034893bc621f5c5adb66f (patch) | |
tree | 6bc5ce3afd87000d0d3bd51b3708bd7ccb43fbc6 /sys | |
parent | 451f832b15e0cbdcd136f1c8cbea2496ca4fa965 (diff) | |
download | FreeBSD-src-6d2dbc994419de3783c034893bc621f5c5adb66f.zip FreeBSD-src-6d2dbc994419de3783c034893bc621f5c5adb66f.tar.gz |
+ A variety of 23XX changes:
disable MWI on 2300
based on function code, set an 'isp_port' for the 2312- it's a
separate instance, but the NVRAM is shared, and the second port's
NVRAM is at offset 256.
+ Enable RIO operation for LVD SCSI cards. This makes a *big* difference
as even under reasonable load we get batched completions of about 30
commands at a time on, say, an ISP1080.
+ Do 'continuation' mailbox commands- this allows us to specify a work
area within the softc and 'continue' repeated mailbox commands. This is
more or less on an ad hoc basis and is currently only used for firmware
loading (which f/w now loads substantially faster becuase the calling
thread is only woken when all the f/w words are loaded- not for each
one of the 40000 f/w words that gets loaded).
+ If we're about to return from isp_intr with a 'bogus interrupt' indication,
and we're not a 23XX card, check to see whether the semaphore register is
currently *2* (not *1* as it should be) and whether there's an async completion
sitting in outgoing mailbox0. This seems to capture cases of lost fast posting
and RIO interrupts that the 12160 && 1080 have been known to pump out under
extreme load (extreme, as in > 250 active commands).
+ FC_SCRATCH_ACQUIRE/FC_SCRATCH_RELEASE macros.
+ Endian correct swizzle/unswizzle of an ATIO2 that has a WWPN in it.
MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/isp/isp.c | 187 | ||||
-rw-r--r-- | sys/dev/isp/isp_freebsd.h | 11 | ||||
-rw-r--r-- | sys/dev/isp/isp_inline.h | 16 | ||||
-rw-r--r-- | sys/dev/isp/isp_ioctl.h | 12 | ||||
-rw-r--r-- | sys/dev/isp/isp_pci.c | 21 | ||||
-rw-r--r-- | sys/dev/isp/isp_target.c | 5 | ||||
-rw-r--r-- | sys/dev/isp/isp_target.h | 5 | ||||
-rw-r--r-- | sys/dev/isp/ispmbox.h | 4 | ||||
-rw-r--r-- | sys/dev/isp/ispreg.h | 3 | ||||
-rw-r--r-- | sys/dev/isp/ispvar.h | 11 |
10 files changed, 219 insertions, 56 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 094d029..35d6587f 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -115,6 +115,7 @@ static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *, static void isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *); static void isp_fastpost_complete(struct ispsoftc *, u_int16_t); +static int isp_mbox_continue(struct ispsoftc *); static void isp_scsi_init(struct ispsoftc *); static void isp_scsi_channel_init(struct ispsoftc *, int); static void isp_fibre_init(struct ispsoftc *); @@ -129,6 +130,7 @@ 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_qnw(struct ispsoftc *, mbreg_t *); static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int); static void isp_update(struct ispsoftc *); @@ -240,9 +242,11 @@ isp_reset(struct ispsoftc *isp) btype = "2200"; break; case ISP_HA_FC_2300: - case ISP_HA_FC_2312: btype = "2300"; break; + case ISP_HA_FC_2312: + btype = "2312"; + break; default: break; } @@ -626,20 +630,20 @@ again: code_org = ISP_CODE_ORG; if (dodnld) { - u_int16_t fwlen = isp->isp_mdvec->dv_ispfw[3]; - for (i = 0; i < fwlen; i++) { - mbs.param[0] = MBOX_WRITE_RAM_WORD; - mbs.param[1] = code_org + i; - mbs.param[2] = isp->isp_mdvec->dv_ispfw[i]; - isp_mboxcmd(isp, &mbs, MBLOGNONE); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - isp_prt(isp, ISP_LOGERR, - "F/W download failed at word %d", i); - dodnld = 0; - goto again; - } + isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1]; + isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1; + isp->isp_mbxwrk1 = code_org + 1; + mbs.param[0] = MBOX_WRITE_RAM_WORD; + mbs.param[1] = code_org; + mbs.param[2] = isp->isp_mdvec->dv_ispfw[0]; + isp_mboxcmd(isp, &mbs, MBLOGNONE); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "F/W download failed at word %d", + isp->isp_mbxwrk1 - code_org); + dodnld = 0; + goto again; } - /* * Verify that it downloaded correctly. */ @@ -967,8 +971,15 @@ isp_scsi_init(struct ispsoftc *isp) mbs.param[1] = 0; if (IS_ULTRA2(isp)) mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; +#ifndef ISP_NO_RIO + if (IS_ULTRA2(isp) || IS_1240(isp)) + mbs.param[1] |= FW_FEATURE_RIO_16BIT; +#else +#ifndef ISP_NO_FASTPOST if (IS_ULTRA2(isp) || IS_1240(isp)) mbs.param[1] |= FW_FEATURE_FAST_POST; +#endif +#endif if (mbs.param[1] != 0) { u_int16_t sfeat = mbs.param[1]; isp_mboxcmd(isp, &mbs, MBLOGALL); @@ -1225,7 +1236,7 @@ isp_fibre_init(struct ispsoftc *isp) break; } if (IS_23XX(isp)) { - if (!IS_2312(isp) && isp->isp_revision < 2) { + if (IS_2300(isp) && isp->isp_revision < 2) { icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; } if (isp->isp_confopts & ISP_CFG_ONEGB) { @@ -1236,9 +1247,13 @@ isp_fibre_init(struct ispsoftc *isp) icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO; } } - icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; - icbp->icb_racctimer = 4; - icbp->icb_idelaytimer = 8; +#ifndef ISP_NO_RIO_FC + if ((isp->isp_role & ISP_ROLE_TARGET) == 0) { + icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; + icbp->icb_racctimer = 4; + icbp->icb_idelaytimer = 8; + } +#endif } if ((IS_2200(isp) && ISP_FW_REVX(isp->isp_fwrev) >= @@ -1291,6 +1306,8 @@ 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); + + FC_SCRATCH_ACQUIRE(isp); isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch); /* @@ -1305,6 +1322,7 @@ isp_fibre_init(struct ispsoftc *isp) mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); isp_mboxcmd(isp, &mbs, MBLOGALL); + FC_SCRATCH_RELEASE(isp); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; } @@ -1344,12 +1362,15 @@ isp_getmap(struct ispsoftc *isp, fcpos_map_t *map) */ mbs.param[6] = 0; mbs.param[7] = 0; + FC_SCRATCH_ACQUIRE(isp); isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t)); map->fwmap = mbs.param[1] != 0; + FC_SCRATCH_RELEASE(isp); return (0); } + FC_SCRATCH_RELEASE(isp); return (-1); } @@ -1382,11 +1403,14 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp) */ mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); + FC_SCRATCH_ACQUIRE(isp); isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp); + FC_SCRATCH_RELEASE(isp); return (0); } + FC_SCRATCH_RELEASE(isp); return (-1); } @@ -1611,7 +1635,7 @@ not_on_fabric: } } - isp_prt(isp, ISP_LOGINFO, topology, fcp->isp_loopid, fcp->isp_alpa, + isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]); /* @@ -1807,7 +1831,7 @@ isp_pdb_sync(struct ispsoftc *isp) nwwnn == lp->node_wwn && nwwpn == lp->port_wwn && lp->roles == nrole && lp->force_logout == 0) { lp->loggedin = lp->valid = 1; - isp_prt(isp, ISP_LOGINFO, lretained, + isp_prt(isp, ISP_LOGCONFIG, lretained, (int) (lp - fcp->portdb), (int) lp->loopid, lp->portid); continue; @@ -2282,7 +2306,6 @@ 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++) { mbreg_t mbs; sns_screq_t *rq; @@ -2300,6 +2323,7 @@ isp_scan_fabric(struct ispsoftc *isp) rq->snscb_data[0] = SNS_GAN; rq->snscb_data[4] = portid & 0xffff; rq->snscb_data[5] = (portid >> 16) & 0xff; + FC_SCRATCH_ACQUIRE(isp); 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; @@ -2350,12 +2374,14 @@ isp_scan_fabric(struct ispsoftc *isp) } if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate < LOOP_SCANNING_FABRIC) { + FC_SCRATCH_RELEASE(isp); return (-1); } 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); + FC_SCRATCH_RELEASE(isp); 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])); @@ -2408,6 +2434,7 @@ isp_register_fc4_type(struct ispsoftc *isp) #if 0 reqp->snscb_data[6] |= 20; /* ISO/IEC 8802-2 LLC/SNAP */ #endif + FC_SCRATCH_ACQUIRE(isp); 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; @@ -2419,6 +2446,7 @@ isp_register_fc4_type(struct ispsoftc *isp) mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); isp_mboxcmd(isp, &mbs, MBLOGALL); + FC_SCRATCH_RELEASE(isp); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded"); } @@ -2983,7 +3011,9 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg) * Limit our stack depth by sticking with the max likely number * of completions on a request queue at any one time. */ +#ifndef MAX_REQUESTQ_COMPLETIONS #define MAX_REQUESTQ_COMPLETIONS 64 +#endif void isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) @@ -2992,12 +3022,14 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) u_int16_t iptr, optr, junk; int i, nlooked = 0, ndone = 0; +again: /* * Is this a mailbox related interrupt? * The mailbox semaphore will be nonzero if so. */ if (sema) { if (mbox & 0x4000) { + isp->isp_intmboxc++; if (isp->isp_mboxbsy) { int i = 0, obits = isp->isp_obits; isp->isp_mboxtmp[i++] = mbox; @@ -3008,13 +3040,17 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i)); } + if (isp->isp_mbxwrk0) { + if (isp_mbox_continue(isp) == 0) { + return; + } + } MBOX_NOTIFY_COMPLETE(isp); } else { isp_prt(isp, ISP_LOGWARN, "Mbox Command Async (0x%x) with no waiters", mbox); } - isp->isp_intmboxc++; } else if (isp_parse_async(isp, mbox) < 0) { return; } @@ -3049,6 +3085,9 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) */ if (IS_23XX(isp)) { optr = ISP_READ(isp, isp->isp_respoutrp); + /* + * Debug: to be taken out eventually + */ if (isp->isp_residx != optr) { isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x", optr, isp->isp_residx); @@ -3099,10 +3138,19 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) junk = ISP_READ(isp, BIU_ISR); } if (optr == iptr) { - isp_prt(isp, ISP_LOGDEBUG0, + if (IS_23XX(isp)) { + ; + } else { + sema = ISP_READ(isp, BIU_SEMA); + mbox = ISP_READ(isp, OUTMAILBOX0); + if ((sema & 0x3) && (mbox & 0x8000)) { + goto again; + } + } + isp->isp_intbogus++; + isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr); - isp->isp_intbogus++; } } ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); @@ -3526,13 +3574,13 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox) * Bus gets overloaded with the handle. Dual bus * cards don't put bus# into the handle. */ - bus = (ISP_READ(isp, OUTMAILBOX2) << 16) | - ISP_READ(isp, OUTMAILBOX1); - isp_target_async(isp, bus, mbox); + isp_target_async(isp, ((ISP_READ(isp, OUTMAILBOX2) << 16) | + ISP_READ(isp, OUTMAILBOX1)), mbox); #else isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done"); #endif - break; + isp->isp_fphccmplt++; /* count it as a fast posting intr */ + return (0); case ASYNC_LIP_F8: case ASYNC_LIP_OCCURRED: @@ -3727,6 +3775,7 @@ isp_handle_other_response(struct ispsoftc *isp, int type, case RQSTYPE_ATIO2: case RQSTYPE_CTIO2: case RQSTYPE_CTIO3: + isp->isp_rsltccmplt++; /* count as a response completion */ #ifdef ISP_TARGET_MODE return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)); #else @@ -4120,6 +4169,40 @@ isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph) isp_done(xs); } +static int +isp_mbox_continue(struct ispsoftc *isp) +{ + mbreg_t mbs; + u_int16_t *ptr; + + if (isp->isp_lastmbxcmd != MBOX_WRITE_RAM_WORD) { + return (1); + } + if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) { + isp->isp_mbxwrk0 = 0; + return (-1); + } + + /* + * Clear the previous interrupt. + */ + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); + ISP_WRITE(isp, BIU_SEMA, 0); + + /* + * Continue with next word. + */ + mbs.param[0] = MBOX_WRITE_RAM_WORD; + mbs.param[1] = isp->isp_mbxwrk1++; + ptr = isp->isp_mbxworkp; + mbs.param[2] = *ptr++; + isp->isp_mbxworkp = ptr; + isp->isp_mbxwrk0 -= 1; + isp_mboxcmd_qnw(isp, &mbs); + return (0); +} + + #define HIBYT(x) ((x) >> 0x8) #define LOBYT(x) ((x) & 0xff) #define ISPOPMAP(a, b) (((a) << 8) | (b)) @@ -4582,6 +4665,34 @@ static char *fc_mbcmd_names[] = { #endif static void +isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp) +{ + unsigned int lim, ibits, obits, box, opcode; + u_int16_t *mcp; + + if (IS_FC(isp)) { + mcp = mbpfc; + lim = (sizeof (mbpfc) / sizeof (mbpfc[0])); + } else { + mcp = mbpscsi; + lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0])); + } + opcode = mbp->param[0]; + ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp); + obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp); + for (box = 0; box < MAX_MAILBOX; box++) { + if (ibits & (1 << box)) { + ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]); + } + isp->isp_mboxtmp[box] = mbp->param[box] = 0; + } + isp->isp_lastmbxcmd = opcode; + isp->isp_obits = obits; + isp->isp_mboxbsy = 1; + ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); +} + +static void isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask) { char *cname, *xname, tname[16], mname[16]; @@ -5218,6 +5329,9 @@ isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp) if (IS_FC(isp)) { wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1); + if (IS_2312(isp) && isp->isp_port) { + wo += 128; + } rqst = (ISP_NVRAM_READ << 8) | wo; cbits = 10; } else if (IS_ULTRA2(isp)) { @@ -5600,13 +5714,18 @@ isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data) } } fcp->isp_portwwn = wwn; - wwn = ISP2100_NVRAM_NODE_NAME(nvram_data); - if (wwn) { - isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x", - (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff)); - if ((wwn >> 60) == 0) { - wwn |= (((u_int64_t) 2)<< 60); + if (IS_2200(isp) || IS_23XX(isp)) { + wwn = ISP2200_NVRAM_NODE_NAME(nvram_data); + if (wwn) { + isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x", + (u_int32_t) (wwn >> 32), + (u_int32_t) (wwn & 0xffffffff)); + if ((wwn >> 60) == 0) { + wwn |= (((u_int64_t) 2)<< 60); + } } + } else { + wwn &= ~((u_int64_t) 0xfff << 48); } fcp->isp_nodewwn = wwn; diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index fbf9def..1aa6b83 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -71,7 +71,7 @@ #define HANDLE_LOOPSTATE_IN_OUTER_LAYERS 1 -typedef void ispfwfunc __P((int, int, int, const u_int16_t **)); +typedef void ispfwfunc __P((int, int, int, u_int16_t **)); #ifdef ISP_TARGET_MODE #define ISP_TARGET_FUNCTIONS 1 @@ -192,6 +192,9 @@ struct isposinfo { isp->isp_mboxbsy = 0 #define MBOX_RELEASE(isp) +#define FC_SCRATCH_ACQUIRE(isp) +#define FC_SCRATCH_RELEASE(isp) + #ifndef SCSI_GOOD #define SCSI_GOOD SCSI_STATUS_OK #endif @@ -363,9 +366,10 @@ static INLINE void isp_mbox_wait_complete(struct ispsoftc *isp) { if (isp->isp_osinfo.intsok) { + int lim = ((isp->isp_mbxwrk0)? 120 : 20) * hz; isp->isp_osinfo.mboxwaiting = 1; (void) msleep(&isp->isp_osinfo.mboxwaiting, - &isp->isp_lock, PRIBIO, "isp_mboxwaiting", 10 * hz); + &isp->isp_lock, PRIBIO, "isp_mboxwaiting", lim); if (isp->isp_mboxbsy != 0) { isp_prt(isp, ISP_LOGWARN, "Interrupting Mailbox Command (0x%x) Timeout", @@ -374,8 +378,9 @@ isp_mbox_wait_complete(struct ispsoftc *isp) } isp->isp_osinfo.mboxwaiting = 0; } else { + int lim = ((isp->isp_mbxwrk0)? 240 : 60) * 10000; int j; - for (j = 0; j < 60 * 10000; j++) { + for (j = 0; j < lim; j++) { u_int16_t isr, sema, mbox; if (isp->isp_mboxbsy == 0) { break; diff --git a/sys/dev/isp/isp_inline.h b/sys/dev/isp/isp_inline.h index 7a90293..f65c365 100644 --- a/sys/dev/isp/isp_inline.h +++ b/sys/dev/isp/isp_inline.h @@ -379,7 +379,7 @@ isp_copy_in_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst) static INLINE int isp_get_response_type(struct ispsoftc *isp, isphdr_t *hp) { - uint8_t type; + u_int8_t type; if (ISP_IS_SBUS(isp)) { ISP_IOXGET_8(isp, &hp->rqs_entry_count, type); } else { @@ -856,8 +856,11 @@ isp_put_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst) } 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], + for (i = 0; i < 4; i++) { + ISP_IOXPUT_16(isp, atsrc->at_wwpn[i], &atdst->at_wwpn[i]); + } + for (i = 0; i < 6; i++) { + ISP_IOXPUT_16(isp, atsrc->at_reserved2[i], &atdst->at_reserved2[i]); } ISP_IOXPUT_16(isp, atsrc->at_oxid, &atdst->at_oxid); @@ -883,8 +886,11 @@ isp_get_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst) } 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], + for (i = 0; i < 4; i++) { + ISP_IOXGET_16(isp, &atsrc->at_wwpn[i], atdst->at_wwpn[i]); + } + for (i = 0; i < 6; i++) { + ISP_IOXGET_16(isp, &atsrc->at_reserved2[i], atdst->at_reserved2[i]); } ISP_IOXGET_16(isp, &atsrc->at_oxid, atdst->at_oxid); diff --git a/sys/dev/isp/isp_ioctl.h b/sys/dev/isp/isp_ioctl.h index b52b2b5..61f921b 100644 --- a/sys/dev/isp/isp_ioctl.h +++ b/sys/dev/isp/isp_ioctl.h @@ -79,11 +79,11 @@ struct isp_fc_device { */ #define ISP_STATS_VERSION 0 typedef struct { - uint8_t isp_stat_version; - uint8_t isp_type; /* (ro) reflects chip type */ - uint8_t isp_revision; /* (ro) reflects chip version */ - uint8_t unused1; - uint32_t unused2; + u_int8_t isp_stat_version; + u_int8_t isp_type; /* (ro) reflects chip type */ + u_int8_t isp_revision; /* (ro) reflects chip version */ + u_int8_t unused1; + u_int32_t unused2; /* * Statistics Counters */ @@ -96,7 +96,7 @@ typedef struct { #define ISP_FPHCCMCPLT 5 #define ISP_RSCCHIWAT 6 #define ISP_FPCCHIWAT 7 - uint64_t isp_stats[ISP_NSTATS]; + u_int64_t isp_stats[ISP_NSTATS]; } isp_stats_t; #define ISP_GET_STATS _IOR(ISP_IOC, 6, isp_stats_t) diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 95c40e79..2dfac81 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -496,14 +496,20 @@ isp_pci_attach(device_t dev) pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2100_OFF; } - if (pci_get_devid(dev) == PCI_QLOGIC_ISP2300 || - pci_get_devid(dev) == PCI_QLOGIC_ISP2312) { + if (pci_get_devid(dev) == PCI_QLOGIC_ISP2300) { mdvp = &mdvec_2300; basetype = ISP_HA_FC_2300; psize = sizeof (fcparam); pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF; } + if (pci_get_devid(dev) == PCI_QLOGIC_ISP2312) { + mdvp = &mdvec_2300; + basetype = ISP_HA_FC_2312; + psize = sizeof (fcparam); + pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = + PCI_MBOX_REGS2300_OFF; + } isp = &pcs->pci_isp; isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO); if (isp->isp_param == NULL) { @@ -535,6 +541,9 @@ isp_pci_attach(device_t dev) */ cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN; + if (IS_2300(isp)) { /* per QLogic errata */ + cmd &= ~PCIM_CMD_INVEN; + } pci_write_config(dev, PCIR_COMMAND, cmd, 1); /* @@ -684,6 +693,13 @@ isp_pci_attach(device_t dev) isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; /* + * Last minute checks... + */ + if (IS_2312(isp)) { + isp->isp_port = pci_get_function(dev); + } + + /* * Make sure we're in reset state. */ ISP_LOCK(isp); @@ -852,6 +868,7 @@ isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp, case ISPR2HST_MBX_OK: case ISPR2HST_MBX_FAIL: case ISPR2HST_ASYNC_EVENT: + case ISPR2HST_RIO_16: case ISPR2HST_FPOST: case ISPR2HST_FPOST_CTIO: *isrp = r2hisr & 0xffff; diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c index a4bcf6f..05a8446 100644 --- a/sys/dev/isp/isp_target.c +++ b/sys/dev/isp/isp_target.c @@ -29,6 +29,10 @@ */ /* + * Bug fixes gratefully acknowledged from: + * Oded Kedem <oded@kashya.com> + */ +/* * Include header file appropriate for platform we're building on. */ @@ -678,6 +682,7 @@ isp_notify_ack(struct ispsoftc *isp, void *arg) na->na_task_flags = inp->in_task_flags; na->na_seqid = inp->in_seqid; na->na_flags = NAFC_RCOUNT; + na->na_status = inp->in_status; if (inp->in_status == IN_RESET) { na->na_flags |= NAFC_RST_CLRD; } diff --git a/sys/dev/isp/isp_target.h b/sys/dev/isp/isp_target.h index f714f1e..f911a17 100644 --- a/sys/dev/isp/isp_target.h +++ b/sys/dev/isp/isp_target.h @@ -280,8 +280,9 @@ typedef struct { u_int8_t at_execodes; u_int8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */ u_int32_t at_datalen; /* allocated data len */ - u_int16_t at_scclun; /* SCC Lun or reserved */ - u_int16_t at_reserved2[10]; + u_int16_t at_scclun; /* SCC Lun or reserved */ + u_int16_t at_wwpn[4]; /* WWPN of initiator */ + u_int16_t at_reserved2[6]; u_int16_t at_oxid; } at2_entry_t; diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index 6204f46..bc4ae54 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -104,8 +104,10 @@ #define MBOX_EXEC_BIOS_IOCB 0x0042 #define MBOX_SET_FW_FEATURES 0x004a #define MBOX_GET_FW_FEATURES 0x004b -#define FW_FEATURE_LVD_NOTIFY 0x2 #define FW_FEATURE_FAST_POST 0x1 +#define FW_FEATURE_LVD_NOTIFY 0x2 +#define FW_FEATURE_RIO_32BIT 0x4 +#define FW_FEATURE_RIO_16BIT 0x8 #define MBOX_ENABLE_TARGET_MODE 0x0055 #define ENABLE_TARGET_FLAG 0x8000 diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h index 3904525..7a57b5a 100644 --- a/sys/dev/isp/ispreg.h +++ b/sys/dev/isp/ispreg.h @@ -955,7 +955,7 @@ #define ISP2100_NVRAM_HARDLOOPID(c) (c)[26] -#define ISP2100_NVRAM_NODE_NAME(c) (\ +#define ISP2200_NVRAM_NODE_NAME(c) (\ (((u_int64_t)(c)[30]) << 56) | \ (((u_int64_t)(c)[31]) << 48) | \ (((u_int64_t)(c)[32]) << 40) | \ @@ -985,4 +985,5 @@ #define ISP2100_NVRAM_BOOT_LUN(c) (c)[80] +#define ISP2200_HBA_FEATURES(c) (c)[232] | ((c)[233] << 8) #endif /* _ISPREG_H */ diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index b0b694d..40d82d1 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -73,7 +73,7 @@ struct ispmdvec { void (*dv_reset0) (struct ispsoftc *); void (*dv_reset1) (struct ispsoftc *); void (*dv_dregs) (struct ispsoftc *, const char *); - const u_int16_t *dv_ispfw; /* ptr to f/w */ + u_int16_t *dv_ispfw; /* ptr to f/w */ u_int16_t dv_conf1; u_int16_t dv_clock; /* clock frequency */ }; @@ -350,7 +350,8 @@ typedef struct ispsoftc { u_int32_t isp_maxluns; /* maximum luns supported */ u_int32_t isp_clock : 8, /* input clock */ - : 5, + : 4, + isp_port : 1, /* 23XX only */ isp_failed : 1, /* board failed */ isp_open : 1, /* opened (ioctl) */ isp_touched : 1, /* board ever seen? */ @@ -395,6 +396,10 @@ typedef struct ispsoftc { volatile u_int16_t isp_lasthdls; /* last handle seed */ volatile u_int16_t isp_mboxtmp[MAX_MAILBOX]; volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */ + volatile u_int16_t isp_mbxwrk0; + volatile u_int16_t isp_mbxwrk1; + volatile u_int16_t isp_mbxwrk2; + void * isp_mbxworkp; /* * Active commands are stored here, indexed by handle functions. @@ -772,6 +777,8 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...); * MBOX_NOTIFY_COMPLETE(struct ispsoftc *) notification of mbox cmd donee * MBOX_RELEASE(struct ispsoftc *) release lock on mailbox regs * + * FC_SCRATCH_ACQUIRE(struct ispsoftc *) acquire lock on FC scratch area + * FC_SCRATCH_RELEASE(struct ispsoftc *) acquire lock on FC scratch area * * SCSI_GOOD SCSI 'Good' Status * SCSI_CHECK SCSI 'Check Condition' Status |