diff options
| author | mjacob <mjacob@NetBSD.org> | 1999-03-17 06:15:47 +0000 |
|---|---|---|
| committer | mjacob <mjacob@NetBSD.org> | 1999-03-17 06:15:47 +0000 |
| commit | 008b51d0a67df5a677ae8f099c61fb0f900512df (patch) | |
| tree | e1ceaab77ec367d43ab35bf6f7e274f84a656890 /sys/dev | |
| parent | 690045798e544421afaae8fc6fb08c000e95d6e3 (diff) | |
Update the driver with some infrastructure for the 1080. Fix an embarrassing
clock botch bug. Additional infrastructure for PDB change stuff.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/isp.c | 716 | ||||
| -rw-r--r-- | sys/dev/ic/isp_netbsd.c | 121 | ||||
| -rw-r--r-- | sys/dev/ic/isp_netbsd.h | 104 | ||||
| -rw-r--r-- | sys/dev/ic/ispmbox.h | 100 | ||||
| -rw-r--r-- | sys/dev/ic/ispreg.h | 90 | ||||
| -rw-r--r-- | sys/dev/ic/ispvar.h | 33 |
6 files changed, 876 insertions, 288 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c index aacb35cc13a..e59cfbdcc12 100644 --- a/sys/dev/ic/isp.c +++ b/sys/dev/ic/isp.c @@ -1,5 +1,5 @@ -/* $NetBSD: isp.c,v 1.32 1999/02/09 00:52:23 mjacob Exp $ */ -/* release_02_05_99 */ +/* $NetBSD: isp.c,v 1.33 1999/03/17 06:15:47 mjacob Exp $ */ +/* release_03_16_99 */ /* * Machine and OS Independent (well, as best as possible) * code for the Qlogic ISP SCSI adapters. @@ -51,6 +51,9 @@ #ifdef __FreeBSD__ #include <dev/isp/isp_freebsd.h> #endif +#ifdef __OpenBSD__ +#include <dev/ic/isp_openbsd.h> +#endif #ifdef __linux__ #include "isp_linux.h" #endif @@ -74,9 +77,13 @@ static const char tgtiqd[36] = { # ifdef __FreeBSD__ 0x46, 0x52, 0x45, 0x45, 0x42, 0x52, 0x44, 0x20, # else -# ifdef linux - 0x4C, 0x49, 0x4E, 0x55, 0x58, 0x20, 0x20, 0x20, +# ifdef __OpenBSD__ + 0x4F, 0x50, 0x45, 0x4E, 0x42, 0x52, 0x44, 0x20, # else +# ifdef linux + 0x4C, 0x49, 0x4E, 0x55, 0x58, 0x20, 0x20, 0x20, +# else +# endif # endif # endif #endif @@ -102,12 +109,14 @@ static void isp_handle_ctio2 __P((struct ispsoftc *, void *)); #endif static void isp_parse_status __P((struct ispsoftc *, ispstatusreq_t *, ISP_SCSI_XFER_T *)); +static void isp_fastpost_complete __P((struct ispsoftc *, int)); static void isp_fibre_init __P((struct ispsoftc *)); +static void isp_mark_getpdb_all __P((struct ispsoftc *)); +static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *)); +static int isp_fclink_test __P((struct ispsoftc *)); static void isp_fw_state __P((struct ispsoftc *)); static void isp_dumpregs __P((struct ispsoftc *, const char *)); static void isp_dumpxflist __P((struct ispsoftc *)); -static void isp_prtstst __P((ispstatusreq_t *)); -static char *isp2100_fw_statename __P((int)); static void isp_mboxcmd __P((struct ispsoftc *, mbreg_t *)); static void isp_update __P((struct ispsoftc *)); @@ -126,7 +135,6 @@ void isp_reset(isp) struct ispsoftc *isp; { - static char once = 1; mbreg_t mbs; int loops, i, dodnld = 1; char *revname; @@ -153,12 +161,11 @@ isp_reset(isp) * case, we don't really use this yet, but we may in * the future. */ - if (once == 1) { + if (isp->isp_used == 0) { /* * Just in case it was paused... */ ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); - once = 0; mbs.param[0] = MBOX_ABOUT_FIRMWARE; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -171,6 +178,7 @@ isp_reset(isp) isp->isp_romfw_rev = (((u_int16_t) mbs.param[1]) << 10) + mbs.param[2]; } + isp->isp_used = 1; } /* @@ -178,8 +186,14 @@ isp_reset(isp) */ ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); - if (isp->isp_type & ISP_HA_FC) { + if (IS_FC(isp)) { revname = "2100"; + } else if (IS_1080(isp)) { + sdparam *sdp = isp->isp_param; + revname = "1080"; + sdp->isp_clock = 0; /* don't set clock */ + sdp->isp_diffmode = 1; + sdp->isp_ultramode = 1; } else { sdparam *sdp = isp->isp_param; i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK; @@ -223,9 +237,6 @@ isp_reset(isp) * Now, while we're at it, gather info about ultra * and/or differential mode. */ - if (isp->isp_bustype != ISP_BT_SBUS) { - ISP_SETBITS(isp, BIU_CONF1, BIU_PCI_CONF1_SXP); - } if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) { PRINTF("%s: Differential Mode\n", isp->isp_name); sdp->isp_diffmode = 1; @@ -238,16 +249,19 @@ isp_reset(isp) } else { i &= RISC_PSR_PCI_ULTRA; } - if (isp->isp_bustype != ISP_BT_SBUS) { - ISP_CLRBITS(isp, BIU_CONF1, BIU_PCI_CONF1_SXP); - } if (i != 0) { PRINTF("%s: Ultra Mode Capable\n", isp->isp_name); sdp->isp_ultramode = 1; + /* + * If we're in Ultra Mode, we have to be 60Mhz clock- + * even for the SBus version. + */ sdp->isp_clock = 60; } else { sdp->isp_ultramode = 0; - sdp->isp_clock = 40; + /* + * Clock is known. Gronk. + */ } /* @@ -274,13 +288,21 @@ again: * and give the ISP a chance to recover. */ - if (isp->isp_type & ISP_HA_SCSI) { + if (IS_SCSI(isp)) { ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET); /* * A slight delay... */ SYS_DELAY(100); +#if 0 + PRINTF("%s: mbox0-5: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + isp->isp_name, ISP_READ(isp, OUTMAILBOX0), + ISP_READ(isp, OUTMAILBOX1), ISP_READ(isp, OUTMAILBOX2), + ISP_READ(isp, OUTMAILBOX3), ISP_READ(isp, OUTMAILBOX4), + ISP_READ(isp, OUTMAILBOX5)); +#endif + /* * Clear data && control DMA engines. */ @@ -288,6 +310,8 @@ again: DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); + + } else { ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET); /* @@ -330,7 +354,7 @@ again: * for SCSI adapters and other settings for the 2100. */ - if (isp->isp_type & ISP_HA_SCSI) { + if (IS_SCSI(isp)) { ISP_WRITE(isp, BIU_CONF1, 0); } else { ISP_WRITE(isp, BIU2100_CSR, 0); @@ -347,7 +371,7 @@ again: * (only for the 1XX0 boards). This really should * be done later after fetching from NVRAM. */ - if (isp->isp_type & ISP_HA_SCSI) { + if (IS_SCSI(isp)) { u_int16_t tmp = isp->isp_mdvec->dv_conf1; /* * Busted FIFO. Turn off all but burst enables. @@ -560,11 +584,18 @@ isp_init(isp) isp_setdfltparm(isp); /* + * Set up DMA for the request and result mailboxes. + */ + if (ISP_MBOXDMASETUP(isp) != 0) { + PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name); + return; + } + + /* * If we're fibre, we have a completely different * initialization method. */ - - if (isp->isp_type & ISP_HA_FC) { + if (IS_FC(isp)) { isp_fibre_init(isp); return; } @@ -712,14 +743,6 @@ isp_init(isp) sdp->isp_devparam[tgt].dev_announced = 0; } - /* - * Set up DMA for the request and result mailboxes. - */ - if (ISP_MBOXDMASETUP(isp) != 0) { - PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name); - return; - } - mbs.param[0] = MBOX_INIT_RES_QUEUE; mbs.param[1] = RESULT_QUEUE_LEN; mbs.param[2] = (u_int16_t) (isp->isp_result_dma >> 16); @@ -797,14 +820,9 @@ isp_fibre_init(isp) isp_icb_t *icbp; mbreg_t mbs; int count, loopid; - u_int8_t lwfs; fcp = isp->isp_param; - if (ISP_MBOXDMASETUP(isp) != 0) { - PRINTF("%s: can't setup DMA for mailboxes\n", isp->isp_name); - return; - } /* * For systems that don't have BIOS methods for which * we can easily change the NVRAM based loopid, we'll @@ -847,10 +865,7 @@ isp_fibre_init(isp) #ifdef CHECKME fcp->isp_fwoptions |= ICBOPT_USE_PORTNAME; #endif -#ifdef THIS_WORKED - /* - * This has unhappiness in target mode - */ +#ifdef ISP2100_FABRIC fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN; #endif @@ -882,6 +897,7 @@ isp_fibre_init(isp) (u_int16_t) (isp->isp_result_dma & 0xffff); icbp->icb_respaddr[RQRSP_ADDR1631] = (u_int16_t) (isp->isp_result_dma >> 16); + MemoryBarrier(); for (count = 0; count < 10; count++) { mbs.param[0] = MBOX_INIT_FIRMWARE; @@ -899,11 +915,13 @@ isp_fibre_init(isp) case MBOX_COMMAND_COMPLETE: count = 10; break; + case ASYNC_PDB_CHANGED: + isp_mark_getpdb_all(isp); + /* FALL THROUGH */ case ASYNC_LIP_OCCURRED: case ASYNC_LOOP_UP: case ASYNC_LOOP_DOWN: case ASYNC_LOOP_RESET: - case ASYNC_PDB_CHANGED: case ASYNC_CHANGE_NOTIFY: if (count > 9) { PRINTF("%s: too many retries to get going- " @@ -918,12 +936,118 @@ isp_fibre_init(isp) } isp->isp_reqidx = isp->isp_reqodx = 0; isp->isp_residx = 0; + isp->isp_sendmarker = 1; + + /* + * Whatever happens, we're now committed to being here. + */ + isp->isp_state = ISP_INITSTATE; + fcp->isp_fwstate = FW_CONFIG_WAIT; + +#ifdef ISP_TARGET_MODE + if (isp_modify_lun(isp, 0, 1, 1)) { + PRINTF("%s: failed to enable target mode\n", isp->isp_name); + } +#endif +} + +/* + * Fibre Channel Support- get the port database for the id. + * + * Locks are held before coming here. Return 0 if success, + * else failure. + */ + +static void +isp_mark_getpdb_all(isp) + struct ispsoftc *isp; +{ + isp_pdb_t *p; + fcparam *fcp = (fcparam *) isp->isp_param; + for (p = &fcp->isp_pdb[0]; p < &fcp->isp_pdb[MAX_FC_TARG]; p++) { + p->pdb_options = INVALID_PDB_OPTIONS; + } +} + +static int +isp_getpdb(isp, id, pdbp) + struct ispsoftc *isp; + int id; + isp_pdb_t *pdbp; +{ +#ifdef GETPDB_WORKING_YET + fcparam *fcp = (fcparam *) isp->isp_param; + mbreg_t mbs; + + /* + * Get Port Queue Parameters first- this is + * a Q&D way to see whether we're logged into + * this port. + */ + mbs.param[0] = MBOX_GET_DEV_QUEUE_PARAMS; + mbs.param[1] = id << 8; + mbs.param[2] = 0; +#ifdef ISP2100_SCCLUN + mbs.param[3] = 0; +#endif + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) + return (-1); + + mbs.param[0] = MBOX_GET_PORT_DB; + mbs.param[1] = id << 8; + mbs.param[2] = (u_int16_t) (fcp->isp_scdma >> 16); + mbs.param[3] = (u_int16_t) (fcp->isp_scdma & 0xffff); + mbs.param[4] = 0; + mbs.param[5] = 0; + mbs.param[6] = 0; + mbs.param[7] = 0; + isp_mboxcmd(isp, &mbs); + switch (mbs.param[0]) { + case MBOX_COMMAND_COMPLETE: + MemoryBarrier(); + MEMCPY(pdbp, fcp->isp_scratch, sizeof (isp_pdb_t)); + break; + case MBOX_HOST_INTERFACE_ERROR: + PRINTF("%s: DMA error getting port database\n", isp->isp_name); + return (-1); + case MBOX_COMMAND_PARAM_ERROR: + /* Not Logged In */ + IDPRINTF(3, ("%s: Comand Param Error on Get Port Database\n", + isp->isp_name)); + return (-1); + default: + PRINTF("%s: error 0x%x getting port database for ID %d\n", + isp->isp_name, mbs.param[0], id); + return (-1); + } +#else + pdbp->pdb_options = 1; +#endif + return (0); +} + +/* + * Make sure we have good FC link and know our Loop ID. + */ + +static int +isp_fclink_test(isp) + struct ispsoftc *isp; +{ + mbreg_t mbs; + int count; + u_int8_t lwfs; + fcparam *fcp; + + fcp = isp->isp_param; /* - * Wait up to 5 seconds for FW to go to READY state. + * Wait up to N microseconds for F/W to go to a ready state. + * This is a platform specific */ lwfs = FW_CONFIG_WAIT; - for (count = 0; count < 12000; count++) { + for (count = 0; count < FC_FW_READY_DELAY; count += 100) { isp_fw_state(isp); if (lwfs != fcp->isp_fwstate) { PRINTF("%s: Firmware State %s -> %s\n", @@ -934,38 +1058,30 @@ isp_fibre_init(isp) if (fcp->isp_fwstate == FW_READY) { break; } - SYS_DELAY(1000); /* wait one millisecond */ + SYS_DELAY(100); /* wait 100 microseconds */ } - isp->isp_sendmarker = 1; /* - * Get our Loop ID - * (if possible) + * If we haven't gone to 'ready' state, return. */ - if (fcp->isp_fwstate == FW_READY) { - mbs.param[0] = MBOX_GET_LOOP_ID; - isp_mboxcmd(isp, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - isp_dumpregs(isp, "GET LOOP ID failed"); - return; - } - fcp->isp_loopid = mbs.param[1]; - fcp->isp_alpa = mbs.param[2]; - PRINTF("%s: Loop ID %d, ALPA 0x%x\n", isp->isp_name, - fcp->isp_loopid, fcp->isp_alpa); - isp->isp_state = ISP_INITSTATE; -#ifdef ISP_TARGET_MODE - DISABLE_INTS(isp); - if (isp_modify_lun(isp, 0, 1, 1)) { - PRINTF("%s: failed to enable target mode\n", - isp->isp_name); - } - ENABLE_INTS(isp); -#endif - } else { - PRINTF("%s: failed to go to FW READY state- will not attach\n", - isp->isp_name); + if (fcp->isp_fwstate != FW_READY) { + return (-1); } + /* + * Get our Loop ID (if possible). We really need to have it. + */ + mbs.param[0] = MBOX_GET_LOOP_ID; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + PRINTF("%s: GET LOOP ID failed\n", isp->isp_name); + return (-1); + } + fcp->isp_loopid = mbs.param[1]; + fcp->isp_alpa = mbs.param[2]; + PRINTF("%s: Loop ID %d, ALPA 0x%x\n", isp->isp_name, + fcp->isp_loopid, fcp->isp_alpa); + return (0); + } /* @@ -985,7 +1101,7 @@ ispscsicmd(xs) #define reqp _u._reqp #define t2reqp _u._t2reqp #define UZSIZE max(sizeof (ispreq_t), sizeof (ispreqt2_t)) - int i; + int i, rqidx; XS_INITERR(xs); isp = XS_ISP(xs); @@ -997,9 +1113,10 @@ ispscsicmd(xs) } /* - * We *could* do the different sequence type that has clos - * to the whole Queue Entry for the command,. + * We *could* do the different sequence type that has close + * to the whole Queue Entry for the command,... */ + if (XS_CDBLEN(xs) > ((isp->isp_type & ISP_HA_FC)? 16 : 12)) { PRINTF("%s: unsupported cdb length (%d)\n", isp->isp_name, XS_CDBLEN(xs)); @@ -1008,7 +1125,48 @@ ispscsicmd(xs) } /* - * First check to see if any HBA or Device + * Check to see whether we have good firmware state still or + * need to refresh our port database for this target. + */ + if (IS_FC(isp)) { + fcparam *fcp = isp->isp_param; + isp_pdb_t *pdbp = &fcp->isp_pdb[XS_TGT(xs)]; + + /* + * Check for f/w being in ready state. Well, okay, + * our cached copy of it... + */ + if (fcp->isp_fwstate != FW_READY) { + if (isp_fclink_test(isp)) { + XS_SETERR(xs, HBA_SELTIMEOUT); + return (CMD_COMPLETE); + } + } + /* + * Here's the spot we would need to find out whether + * the port names have changed, whether it's still + * a target role, etc.. + */ + if (pdbp->pdb_options == INVALID_PDB_OPTIONS) { + /* + * If we don't know what it is- don't talk to it. + * This also handles cases where it's not logged + * into this port/target. + */ + if (isp_getpdb(isp, XS_TGT(xs), pdbp)) { + XS_SETERR(xs, HBA_SELTIMEOUT); + return (CMD_COMPLETE); +#ifdef GETPDB_WORKING_YET + } else { + isp_async(isp, ISPASYNC_PDB_CHANGE_COMPLETE, + (void *) (long) XS_TGT(xs)); +#endif + } + } + } + + /* + * Next check to see if any HBA or Device * parameters need to be updated. */ if (isp->isp_update) { @@ -1025,9 +1183,6 @@ ispscsicmd(xs) XS_SETERR(xs, HBA_BOTCH); return (CMD_EAGAIN); } - if (isp->isp_type & ISP_HA_FC) { - DISABLE_INTS(isp); - } if (isp->isp_sendmarker) { u_int8_t niptr; @@ -1038,8 +1193,6 @@ ispscsicmd(xs) marker->req_header.rqs_entry_type = RQSTYPE_MARKER; marker->req_modifier = SYNC_ALL; - isp->isp_sendmarker = 0; - /* * Unconditionally update the input pointer anyway. */ @@ -1048,9 +1201,6 @@ ispscsicmd(xs) niptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN); if (niptr == optr) { - if (isp->isp_type & ISP_HA_FC) { - ENABLE_INTS(isp); - } IDPRINTF(2, ("%s: Request Queue Overflow+\n", isp->isp_name)); XS_SETERR(xs, HBA_BOTCH); @@ -1070,13 +1220,11 @@ ispscsicmd(xs) reqp->req_header.rqs_flags = 0; reqp->req_header.rqs_seqno = isp->isp_seqno++; - for (i = 0; i < RQUEST_QUEUE_LEN; i++) { - if (isp->isp_xflist[i] == NULL) + for (rqidx = 0; rqidx < RQUEST_QUEUE_LEN; rqidx++) { + if (isp->isp_xflist[rqidx] == NULL) break; } - if (i == RQUEST_QUEUE_LEN) { - if (isp->isp_type & ISP_HA_FC) - ENABLE_INTS(isp); + if (rqidx == RQUEST_QUEUE_LEN) { IDPRINTF(2, ("%s: out of xflist pointers\n", isp->isp_name)); XS_SETERR(xs, HBA_BOTCH); return (CMD_EAGAIN); @@ -1085,8 +1233,8 @@ ispscsicmd(xs) * Never have a handle that is zero, so * set req_handle off by one. */ - isp->isp_xflist[i] = xs; - reqp->req_handle = i+1; + isp->isp_xflist[rqidx] = xs; + reqp->req_handle = rqidx+1; } if (isp->isp_type & ISP_HA_FC) { @@ -1120,7 +1268,7 @@ ispscsicmd(xs) reqp->req_lun_trn = XS_LUN(xs); reqp->req_cdblen = XS_CDBLEN(xs); } else { -#ifdef SCCLUN +#ifdef ISP2100_SCCLUN reqp->req_scclun = XS_LUN(xs); #else reqp->req_lun_trn = XS_LUN(xs); @@ -1136,10 +1284,19 @@ ispscsicmd(xs) reqp->req_time = XS_TIME(xs) / 1000; if (reqp->req_time == 0 && XS_TIME(xs)) reqp->req_time = 1; + + /* + * Always give a bit more leeway to commands after a bus reset. + */ + if (isp->isp_sendmarker && reqp->req_time < 5) + reqp->req_time = 5; + i = ISP_DMASETUP(isp, xs, reqp, &iptr, optr); if (i != CMD_QUEUED) { - if (isp->isp_type & ISP_HA_FC) - ENABLE_INTS(isp); + /* + * Take memory of it away... + */ + isp->isp_xflist[rqidx] = NULL; /* * dmasetup sets actual error in packet, and * return what we were given to return. @@ -1147,12 +1304,12 @@ ispscsicmd(xs) return (i); } XS_SETERR(xs, HBA_NOERROR); + MemoryBarrier(); ISP_WRITE(isp, INMAILBOX4, iptr); isp->isp_reqidx = iptr; - if (isp->isp_type & ISP_HA_FC) { - ENABLE_INTS(isp); - } isp->isp_nactive++; + if (isp->isp_sendmarker) + isp->isp_sendmarker = 0; return (CMD_QUEUED); #undef reqp #undef t2reqp @@ -1180,10 +1337,20 @@ isp_control(isp, ctl, arg) break; case ISPCTL_RESET_BUS: + /* + * This is really important to have set after a bus reset. + */ + isp->isp_sendmarker = 1; + + /* + * Issue a bus reset. + */ mbs.param[0] = MBOX_BUS_RESET; if (isp->isp_type & ISP_HA_SCSI) { mbs.param[1] = ((sdparam *) isp->isp_param)->isp_bus_reset_delay; + if (mbs.param[1] < 2) + mbs.param[1] = 2; } else { /* * Unparameterized. @@ -1195,10 +1362,6 @@ isp_control(isp, ctl, arg) isp_dumpregs(isp, "isp_control SCSI bus reset failed"); break; } - /* - * This is really important to have set after a bus reset. - */ - isp->isp_sendmarker = 1; PRINTF("%s: driver initiated bus reset\n", isp->isp_name); return (0); @@ -1229,7 +1392,7 @@ isp_control(isp, ctl, arg) break; } mbs.param[0] = MBOX_ABORT; -#ifdef SCCLUN +#ifdef ISP2100_SCCLUN if (isp->isp_type & ISP_HA_FC) { mbs.param[1] = XS_TGT(xs) << 8; mbs.param[4] = 0; @@ -1256,6 +1419,9 @@ isp_control(isp, ctl, arg) case ISPCTL_UPDATE_PARAMS: isp_update(isp); return(0); + + case ISPCTL_FCLINK_TEST: + return (isp_fclink_test(isp)); } return (-1); } @@ -1298,30 +1464,37 @@ isp_intr(arg) if (ISP_READ(isp, BIU_SEMA) & 1) { u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0); - u_int32_t fast_post_handle = isp_parse_async(isp, (int) mbox); - ISP_WRITE(isp, BIU_SEMA, 0); - if (fast_post_handle < 0) { - return (1); - } else if (fast_post_handle > 0) { - xs = (ISP_SCSI_XFER_T *) - isp->isp_xflist[fast_post_handle - 1]; - isp->isp_xflist[fast_post_handle - 1] = NULL; - /* - * Since we don't have a result queue entry item, - * we must believe that SCSI status is zero and - * that all data transferred. - */ - XS_RESID(xs) = 0; - XS_STS(xs) = 0; - if (XS_XFRLEN(xs)) { - ISP_DMAFREE(isp, xs, fast_post_handle - 1); + if (mbox & 0x4000) { + if (mbox != MBOX_COMMAND_COMPLETE) { + PRINTF("%s: isp_intr sees 0x%x\n", + isp->isp_name,mbox); + } + ISP_WRITE(isp, BIU_SEMA, 0); + } else { + u_int32_t fhandle = isp_parse_async(isp, (int) mbox); + ISP_WRITE(isp, BIU_SEMA, 0); + if (fhandle < 0) { + return (1); + } else if (fhandle > 0) { + xs = (ISP_SCSI_XFER_T *) + isp->isp_xflist[fhandle - 1]; + isp->isp_xflist[fhandle - 1] = NULL; + /* + * Since we don't have a result queue entry + * item, we must believe that SCSI status is + * zero and that all data transferred. + */ + XS_RESID(xs) = 0; + XS_STS(xs) = 0; + if (XS_XFRLEN(xs)) { + ISP_DMAFREE(isp, xs, fhandle - 1); + } + if (isp->isp_nactive > 0) + isp->isp_nactive--; + complist[ndone++] = xs; } - if (isp->isp_nactive > 0) - isp->isp_nactive--; - complist[ndone++] = xs; } } - ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); optr = isp->isp_residx; @@ -1342,7 +1515,7 @@ isp_intr(arg) oop = optr; optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN); nlooked++; - + MemoryBarrier(); if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) { if (isp_handle_other_response(isp, sp, &optr) == 0) { ISP_WRITE(isp, INMAILBOX5, optr); @@ -1499,7 +1672,7 @@ isp_intr(arg) * what the outpointer is. It also is a trigger to update the * ISP's notion of what we've seen so far. */ - if (ndone) { + if (nlooked) { ISP_WRITE(isp, INMAILBOX5, optr); isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4); } @@ -1525,8 +1698,10 @@ isp_parse_async(isp, mbox) u_int32_t fast_post_handle = 0; switch (mbox) { + case MBOX_COMMAND_COMPLETE: /* sometimes these show up */ + break; case ASYNC_BUS_RESET: - PRINTF("%s: SCSI bus reset detected\n", isp->isp_name); + isp_async(isp, ISPASYNC_BUS_RESET, NULL); isp->isp_sendmarker = 1; #ifdef ISP_TARGET_MODE isp_notify_ack(isp, NULL); @@ -1563,6 +1738,7 @@ isp_parse_async(isp, mbox) break; case ASYNC_DEVICE_RESET: + isp->isp_sendmarker = 1; PRINTF("%s: device reset\n", isp->isp_name); #ifdef ISP_TARGET_MODE isp_notify_ack(isp, NULL); @@ -1606,20 +1782,21 @@ isp_parse_async(isp, mbox) break; case ASYNC_LIP_OCCURRED: + isp->isp_sendmarker = 1; PRINTF("%s: LIP occurred\n", isp->isp_name); break; case ASYNC_LOOP_UP: - PRINTF("%s: Loop UP\n", isp->isp_name); + isp->isp_sendmarker = 1; isp_async(isp, ISPASYNC_LOOP_UP, NULL); break; case ASYNC_LOOP_DOWN: - PRINTF("%s: Loop DOWN\n", isp->isp_name); isp_async(isp, ISPASYNC_LOOP_DOWN, NULL); break; case ASYNC_LOOP_RESET: + isp->isp_sendmarker = 1; PRINTF("%s: Loop RESET\n", isp->isp_name); #ifdef ISP_TARGET_MODE isp_notify_ack(isp, NULL); @@ -1627,15 +1804,16 @@ isp_parse_async(isp, mbox) break; case ASYNC_PDB_CHANGED: + isp->isp_sendmarker = 1; + isp_mark_getpdb_all(isp); PRINTF("%s: Port Database Changed\n", isp->isp_name); break; case ASYNC_CHANGE_NOTIFY: - PRINTF("%s: Name Server Database Changed\n", isp->isp_name); break; default: - PRINTF("%s: async %x\n", isp->isp_name, mbox); + PRINTF("%s: unknown async code 0x%x\n", isp->isp_name, mbox); break; } return (fast_post_handle); @@ -1756,7 +1934,7 @@ isp_handle_other_response(isp, sp, optrp) ispatiot2_t *at2 = (ispatiot2_t *) sp; int s, lun; -#ifdef SCCLUN +#ifdef ISP2100_SCCLUN lun = at2->req_scclun; #else lun = at2->req_lun; @@ -1804,7 +1982,7 @@ isp_handle_other_response(isp, sp, optrp) ct2->req_header.rqs_flags = 0; ct2->req_header.rqs_seqno = isp->isp_seqno++; ct2->req_handle = (at2->req_initiator << 16) | lun; -#ifndef SCCLUN +#ifndef ISP2100_SCCLUN ct2->req_lun = lun; #endif ct2->req_initiator = at2->req_initiator; @@ -2519,6 +2697,35 @@ isp_parse_status(isp, sp, xs) XS_SETERR(xs, HBA_BOTCH); } +static void +isp_fastpost_complete(isp, fph) + struct ispsoftc *isp; + int fph; +{ + ISP_SCSI_XFER_T *xs; + + if (fph < 1) + return; + xs = (ISP_SCSI_XFER_T *) isp->isp_xflist[fph - 1]; + isp->isp_xflist[fph - 1] = NULL; + if (xs == NULL) { + PRINTF("%s: fast posting handle 0x%x not found\n", + isp->isp_name, fph - 1); + return; + } + /* + * Since we don't have a result queue entry item, + * we must believe that SCSI status is zero and + * that all data transferred. + */ + XS_RESID(xs) = 0; + XS_STS(xs) = 0; + if (XS_XFRLEN(xs)) { + ISP_DMAFREE(isp, xs, fph - 1); + } + XS_CMD_DONE(xs); +} + #define HINIB(x) ((x) >> 0x4) #define LONIB(x) ((x) & 0xf) #define MAKNIB(a, b) (((a) << 4) | (b)) @@ -2627,8 +2834,17 @@ static u_int8_t mbpcnt[] = { MAKNIB(3, 1), /* 0x65: MBOX_CLEAR_ACA */ MAKNIB(3, 1), /* 0x66: MBOX_TARGET_RESET */ MAKNIB(3, 1), /* 0x67: MBOX_CLEAR_TASK_SET */ - MAKNIB(3, 1), /* 0x69: MBOX_ABORT_TASK_SET */ - MAKNIB(1, 2) /* 0x69: MBOX_GET_FW_STATE */ + MAKNIB(3, 1), /* 0x68: MBOX_ABORT_TASK_SET */ + MAKNIB(1, 2), /* 0x69: MBOX_GET_FW_STATE */ + MAKNIB(2, 8), /* 0x6a: MBOX_GET_PORT_NAME */ + MAKNIB(8, 1), /* 0x6b: MBOX_GET_LINK_STATUS */ + MAKNIB(4, 4), /* 0x6c: MBOX_INIT_LIP_RESET */ + MAKNIB(0, 0), /* 0x6d: */ + MAKNIB(0, 0), /* 0x6e: */ + MAKNIB(0, 0), /* 0x6f: */ + MAKNIB(0, 0), /* 0x70: */ + MAKNIB(0, 0), /* 0x71: */ + MAKNIB(4, 1) /* 0x72: MBOX_INIT_LIP_LOGIN */ }; #define NMBCOM (sizeof (mbpcnt) / sizeof (mbpcnt[0])) @@ -2665,7 +2881,7 @@ isp_mboxcmd(isp, mbp) /* * Check for variants */ -#ifdef SCCLUN +#ifdef ISP2100_SCCLUN if (isp->isp_type & ISP_HA_FC) { switch (mbp->param[0]) { case MBOX_ABORT: @@ -2687,33 +2903,68 @@ isp_mboxcmd(isp, mbp) command_known: +#define NEW_MB_WAY 1 +#ifdef NEW_MB_WAY /* - * Make sure we can send some words.. + * Set semaphore on mailbox registers to win any races to acquire them. + */ + ISP_WRITE(isp, BIU_SEMA, 1); +#endif + + + /* + * Make sure we can send some words. Check to see id there's + * an async mbox event pending. */ loops = MBOX_DELAY_COUNT; while ((ISP_READ(isp, HCCR) & HCCR_HOST_INT) != 0) { SYS_DELAY(100); - if (--loops < 0) { - PRINTF("%s: isp_mboxcmd timeout #1\n", isp->isp_name); - if (dld++) { - return; - } - PRINTF("%s: but we'll try again, isr=%x\n", - isp->isp_name, ISP_READ(isp, BIU_ISR)); - if (ISP_READ(isp, BIU_SEMA) & 1) { - u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0); - if (isp_parse_async(isp, (int) mbox)) + if (ISP_READ(isp, BIU_SEMA) & 1) { + int fph; + u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0); + /* + * We have a pending MBOX async event. + */ + if (mbox & 0x8000) { + fph = isp_parse_async(isp, (int) mbox); + ISP_WRITE(isp, BIU_SEMA, 0); + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); + if (fph < 0) { return; + } else if (fph > 0) { + isp_fastpost_complete(isp, fph); + } + SYS_DELAY(100); + goto command_known; + } + /* + * We have a pending MBOX completion? Might be + * from a previous command. We can't (sometimes) + * just clear HOST INTERRUPT, so we'll just silently + * eat this here. + */ + if (mbox == MBOX_COMMAND_COMPLETE) { ISP_WRITE(isp, BIU_SEMA, 0); + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); + SYS_DELAY(100); + goto command_known; } + } + if (--loops < 0) { + if (dld++ > 10) { + PRINTF("%s: isp_mboxcmd could not get command " + "started\n", isp->isp_name); + return; + } + ISP_WRITE(isp, BIU_SEMA, 0); ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); goto command_known; } } /* - * Write input parameters + * Write input parameters. */ switch (inparam) { case 8: ISP_WRITE(isp, INMAILBOX7, mbp->param[7]); mbp->param[7] = 0; @@ -2727,20 +2978,23 @@ command_known: } /* - * Clear semaphore on mailbox registers + * Clear RISC int condition. */ - ISP_WRITE(isp, BIU_SEMA, 0); + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); /* - * Clear RISC int condition. + * Clear semaphore on mailbox registers so that the Qlogic + * may update outgoing registers. */ - ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); + ISP_WRITE(isp, BIU_SEMA, 0); + ENABLE_INTS(isp); /* * Set Host Interrupt condition so that RISC will pick up mailbox regs. */ ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); +#ifndef NEW_MB_WAY /* * Wait until RISC int is set, except 2100 */ @@ -2762,24 +3016,83 @@ command_known: loops = MBOX_DELAY_COUNT; while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) { SYS_DELAY(100); + /* + * Wierd- I've seen the case where the semaphore register + * isn't getting set- sort of a violation of the protocol.. + */ + if (ISP_READ(isp, OUTMAILBOX0) & 0x4000) + break; if (--loops < 0) { PRINTF("%s: isp_mboxcmd timeout #3\n", isp->isp_name); return; } } +#else + /* + * Wait until HOST INT has gone away (meaning that the Qlogic + * has picked up the mailbox command. Wait a long time. + */ + loops = MBOX_DELAY_COUNT * 5; + while ((ISP_READ(isp, HCCR) & HCCR_CMD_CLEAR_RISC_INT) != 0) { + SYS_DELAY(100); + if (--loops < 0) { + PRINTF("%s: isp_mboxcmd timeout #2\n", isp->isp_name); + return; + } + } /* - * Make sure that the MBOX_BUSY has gone away + * While the Semaphore registers isn't set, wait for the Qlogic + * to process the mailbox command. Again- wait a long time. */ - loops = MBOX_DELAY_COUNT; - while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) { + loops = MBOX_DELAY_COUNT * 5; + while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) { SYS_DELAY(100); + /* + * Wierd- I've seen the case where the semaphore register + * isn't getting set- sort of a violation of the protocol.. + */ + if (ISP_READ(isp, OUTMAILBOX0) & 0x4000) + break; if (--loops < 0) { - PRINTF("%s: isp_mboxcmd timeout #4\n", isp->isp_name); + PRINTF("%s: isp_mboxcmd timeout #3\n", isp->isp_name); return; } } +#endif + /* + * Make sure that the MBOX_BUSY has gone away + */ + loops = MBOX_DELAY_COUNT; + for (;;) { + u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0); + if (mbox == MBOX_BUSY) { + if (--loops < 0) { + PRINTF("%s: isp_mboxcmd timeout #4\n", + isp->isp_name); + return; + } + SYS_DELAY(100); + continue; + } + /* + * We have a pending MBOX async event. + */ + if (mbox & 0x8000) { + int fph = isp_parse_async(isp, (int) mbox); + ISP_WRITE(isp, BIU_SEMA, 0); + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); + if (fph < 0) { + return; + } else if (fph > 0) { + isp_fastpost_complete(isp, fph); + } + SYS_DELAY(100); + continue; + } + break; + } /* * Pick up output parameters. @@ -2828,17 +3141,29 @@ command_known: isp->isp_name, opcode); break; case MBOX_COMMAND_PARAM_ERROR: - PRINTF("%s: mbox cmd %x failed with COMMAND_PARAM_ERROR\n", - isp->isp_name, opcode); + switch (opcode) { + case MBOX_GET_PORT_DB: + case MBOX_GET_PORT_NAME: + case MBOX_GET_DEV_QUEUE_PARAMS: + break; + default: + PRINTF("%s: mbox cmd %x failed with " + "COMMAND_PARAM_ERROR\n", isp->isp_name, opcode); + } break; /* * Be silent about these... */ - case ASYNC_LOOP_UP: case ASYNC_LIP_OCCURRED: + case ASYNC_LOOP_UP: + case ASYNC_LOOP_DOWN: + case ASYNC_LOOP_RESET: + case ASYNC_CHANGE_NOTIFY: + break; case ASYNC_PDB_CHANGED: + isp_mark_getpdb_all(isp); break; default: @@ -2960,12 +3285,19 @@ again: mbs.param[0] = MBOX_GET_FW_STATE; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - if (mbs.param[0] == ASYNC_LIP_OCCURRED || - mbs.param[0] == ASYNC_PDB_CHANGED || - mbs.param[0] == ASYNC_LOOP_UP) { + switch (mbs.param[0]) { + case ASYNC_PDB_CHANGED: + isp_mark_getpdb_all(isp); + /* FALL THROUGH */ + case ASYNC_LIP_OCCURRED: + case ASYNC_LOOP_UP: + case ASYNC_LOOP_DOWN: + case ASYNC_LOOP_RESET: + case ASYNC_CHANGE_NOTIFY: if (once++ < 2) { goto again; } + break; } isp_dumpregs(isp, "GET FIRMWARE STATE failed"); return; @@ -3024,6 +3356,10 @@ isp_update(isp) } if (get == 0) { + /* + * XXX: Need a SYNC_TARGET for efficiency... + */ + isp->isp_sendmarker = 1; sdp->isp_devparam[tgt].cur_dflags = sdp->isp_devparam[tgt].dev_flags; continue; @@ -3076,7 +3412,7 @@ isp_setdfltparm(isp) (isp_read_nvram(isp) == 0)) { return; } - if (isp->isp_type & ISP_HA_FC) { + if (IS_FC(isp)) { fcparam *fcp = (fcparam *) isp->isp_param; fcp->isp_maxfrmlen = ICB_DFLT_FRMLEN; fcp->isp_maxalloc = 256; @@ -3232,66 +3568,6 @@ isp_restart(isp) } /* - * Miscellaneous debug statements. - */ -static void -isp_prtstst(sp) - ispstatusreq_t *sp; -{ - PRINTF("states->"); - if (sp->req_state_flags & RQSF_GOT_BUS) - PRINTF("GOT_BUS "); - if (sp->req_state_flags & RQSF_GOT_TARGET) - PRINTF("GOT_TGT "); - if (sp->req_state_flags & RQSF_SENT_CDB) - PRINTF("SENT_CDB "); - if (sp->req_state_flags & RQSF_XFRD_DATA) - PRINTF("XFRD_DATA "); - if (sp->req_state_flags & RQSF_GOT_STATUS) - PRINTF("GOT_STS "); - if (sp->req_state_flags & RQSF_GOT_SENSE) - PRINTF("GOT_SNS "); - if (sp->req_state_flags & RQSF_XFER_COMPLETE) - PRINTF("XFR_CMPLT "); - PRINTF("\n"); - PRINTF("status->"); - if (sp->req_status_flags & RQSTF_DISCONNECT) - PRINTF("Disconnect "); - if (sp->req_status_flags & RQSTF_SYNCHRONOUS) - PRINTF("Sync_xfr "); - if (sp->req_status_flags & RQSTF_PARITY_ERROR) - PRINTF("Parity "); - if (sp->req_status_flags & RQSTF_BUS_RESET) - PRINTF("Bus_Reset "); - if (sp->req_status_flags & RQSTF_DEVICE_RESET) - PRINTF("Device_Reset "); - if (sp->req_status_flags & RQSTF_ABORTED) - PRINTF("Aborted "); - if (sp->req_status_flags & RQSTF_TIMEOUT) - PRINTF("Timeout "); - if (sp->req_status_flags & RQSTF_NEGOTIATION) - PRINTF("Negotiation "); - PRINTF("\n"); -} - -static char * -isp2100_fw_statename(state) - int state; -{ - switch(state) { - case FW_CONFIG_WAIT: return "Config Wait"; - case FW_WAIT_AL_PA: return "Waiting for AL/PA"; - case FW_WAIT_LOGIN: return "Wait Login"; - case FW_READY: return "Ready"; - case FW_LOSS_OF_SYNC: return "Loss Of Sync"; - case FW_ERROR: return "Error"; - case FW_REINIT: return "Re-Init"; - case FW_NON_PART: return "Nonparticipating"; - default: return "eh?"; - } -} - -/* * NVRAM Routines */ @@ -3308,7 +3584,7 @@ isp_read_nvram(isp) #define nvram_data _n._x #define nvram_words _n._s - if (isp->isp_type & ISP_HA_FC) { + if (IS_FC(isp)) { amt = ISP2100_NVRAM_SIZE; minversion = 1; } else { diff --git a/sys/dev/ic/isp_netbsd.c b/sys/dev/ic/isp_netbsd.c index 0057e111f69..5a889b43104 100644 --- a/sys/dev/ic/isp_netbsd.c +++ b/sys/dev/ic/isp_netbsd.c @@ -1,5 +1,5 @@ -/* $NetBSD: isp_netbsd.c,v 1.10 1999/02/09 00:42:22 mjacob Exp $ */ -/* release_02_05_99 */ +/* $NetBSD: isp_netbsd.c,v 1.11 1999/03/17 06:15:48 mjacob Exp $ */ +/* release_03_16_99 */ /* * Platform (NetBSD) dependent common attachment code for Qlogic adapters. * @@ -79,8 +79,15 @@ isp_attach(isp) TAILQ_INIT(&isp->isp_osinfo.waitq); if (isp->isp_type & ISP_HA_FC) { + /* + * Give it another chance here to come alive... + */ + fcparam *fcp = isp->isp_param; + if (fcp->isp_fwstate != FW_READY) { + (void) isp_control(isp, ISPCTL_FCLINK_TEST, NULL); + } isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_FC_TARG-1; -#ifdef SCCLUN +#ifdef ISP2100_SCCLUN /* * 16 bits worth, but let's be reasonable.. */ @@ -124,8 +131,12 @@ isp_attach(isp) * XXX: that async events happen. */ - if (isp->isp_type & ISP_HA_SCSI) + if (isp->isp_type & ISP_HA_SCSI) { (void) isp_control(isp, ISPCTL_RESET_BUS, NULL); + SYS_DELAY(2*1000000); + } else { + ; + } /* * Start the watchdog. @@ -193,6 +204,20 @@ ispcmd(xs) isp->isp_update = 1; } } + + if (isp->isp_state < ISP_RUNSTATE) { + DISABLE_INTS(isp); + isp_init(isp); + if (isp->isp_state != ISP_INITSTATE) { + ENABLE_INTS(isp); + (void) splx(s); + XS_SETERR(xs, HBA_BOTCH); + return (CMD_COMPLETE); + } + isp->isp_state = ISP_RUNSTATE; + ENABLE_INTS(isp); + } + /* * Check for queue blockage... */ @@ -208,7 +233,9 @@ ispcmd(xs) return (CMD_QUEUED); } + DISABLE_INTS(isp); result = ispscsicmd(xs); + ENABLE_INTS(isp); if (result != CMD_QUEUED || (xs->flags & SCSI_POLL) == 0) { (void) splx(s); return (result); @@ -339,13 +366,17 @@ isp_internal_restart(arg) void *arg; { struct ispsoftc *isp = arg; - int result, nrestarted = 0, s = splbio(); + int result, nrestarted = 0, s; + s = splbio(); if (isp->isp_osinfo.blocked == 0) { struct scsipi_xfer *xs; while ((xs = TAILQ_FIRST(&isp->isp_osinfo.waitq)) != NULL) { TAILQ_REMOVE(&isp->isp_osinfo.waitq, xs, adapter_q); - if ((result = ispscsicmd(xs)) != CMD_QUEUED) { + DISABLE_INTS(isp); + result = ispscsicmd(xs); + ENABLE_INTS(isp); + if (result != CMD_QUEUED) { printf("%s: botched command restart (0x%x)\n", isp->isp_name, result); xs->flags |= ITSDONE; @@ -368,17 +399,6 @@ isp_async(isp, cmd, arg) { int s = splbio(); switch (cmd) { - case ISPASYNC_LOOP_DOWN: - /* - * Hopefully we get here in time to minimize the number - * of commands we are firing off that are sure to die. - */ - isp->isp_osinfo.blocked = 1; - break; - case ISPASYNC_LOOP_UP: - isp->isp_osinfo.blocked = 0; - timeout(isp_internal_restart, isp, 1); - break; case ISPASYNC_NEW_TGT_PARAMS: if (isp->isp_type & ISP_HA_SCSI) { sdparam *sdp = isp->isp_param; @@ -417,6 +437,73 @@ isp_async(isp, cmd, arg) } } break; + case ISPASYNC_BUS_RESET: + printf("%s: SCSI bus reset detected\n", isp->isp_name); + break; + case ISPASYNC_LOOP_DOWN: + /* + * Hopefully we get here in time to minimize the number + * of commands we are firing off that are sure to die. + */ + isp->isp_osinfo.blocked = 1; + printf("%s: Loop DOWN\n", isp->isp_name); + break; + case ISPASYNC_LOOP_UP: + isp->isp_osinfo.blocked = 0; + timeout(isp_internal_restart, isp, 1); + printf("%s: Loop UP\n", isp->isp_name); + break; + case ISPASYNC_PDB_CHANGE_COMPLETE: + if (isp->isp_type & ISP_HA_FC) { + static char *roles[4] = { + "No", "Target", "Initiator", "Target/Initiator" + }; + long tgt = (long) arg; + isp_pdb_t *pdbp = &((fcparam *)isp->isp_param)->isp_pdb[tgt]; + printf("%s: Loop ID %d, %s role\n", + isp->isp_name, pdbp->pdb_loopid, + roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]); + printf(" Node Address 0x%x WWN 0x" + "%02x%02x%02x%02x%02x%02x%02x%02x\n", + BITS2WORD(pdbp->pdb_portid_bits), + pdbp->pdb_portname[0], pdbp->pdb_portname[1], + pdbp->pdb_portname[2], pdbp->pdb_portname[3], + pdbp->pdb_portname[4], pdbp->pdb_portname[5], + pdbp->pdb_portname[6], pdbp->pdb_portname[7]); + if (pdbp->pdb_options & PDB_OPTIONS_ADISC) + printf(" Hard Address 0x%x WWN 0x" + "%02x%02x%02x%02x%02x%02x%02x%02x\n", + BITS2WORD(pdbp->pdb_hardaddr_bits), + pdbp->pdb_nodename[0], + pdbp->pdb_nodename[1], + pdbp->pdb_nodename[2], + pdbp->pdb_nodename[3], + pdbp->pdb_nodename[4], + pdbp->pdb_nodename[5], + pdbp->pdb_nodename[6], + pdbp->pdb_nodename[7]); + switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) { + case SVC3_TGT_ROLE|SVC3_INI_ROLE: + printf(" Master State=%s, Slave State=%s\n", + isp2100_pdb_statename(pdbp->pdb_mstate), + isp2100_pdb_statename(pdbp->pdb_sstate)); + break; + case SVC3_TGT_ROLE: + printf(" Master State=%s\n", + isp2100_pdb_statename(pdbp->pdb_mstate)); + break; + case SVC3_INI_ROLE: + printf(" Slave State=%s\n", + isp2100_pdb_statename(pdbp->pdb_sstate)); + break; + default: + break; + } + break; + } + case ISPASYNC_CHANGE_NOTIFY: + printf("%s: Name Server Database Changed\n", isp->isp_name); + break; default: break; } diff --git a/sys/dev/ic/isp_netbsd.h b/sys/dev/ic/isp_netbsd.h index b6cd37378fb..f804da6bb24 100644 --- a/sys/dev/ic/isp_netbsd.h +++ b/sys/dev/ic/isp_netbsd.h @@ -1,5 +1,5 @@ -/* $NetBSD: isp_netbsd.h,v 1.10 1999/02/09 00:37:35 mjacob Exp $ */ -/* release_01_29_99 */ +/* $NetBSD: isp_netbsd.h,v 1.11 1999/03/17 06:15:48 mjacob Exp $ */ +/* release_03_16_99 */ /* * NetBSD Specific definitions for the Qlogic ISP Host Adapter * @@ -63,7 +63,7 @@ #include <vm/pmap.h> #define ISP_PLATFORM_VERSION_MAJOR 0 -#define ISP_PLATFORM_VERSION_MINOR 991 +#define ISP_PLATFORM_VERSION_MINOR 992 #define ISP_SCSI_XFER_T struct scsipi_xfer struct isposinfo { @@ -84,6 +84,11 @@ struct isposinfo { #define MEMZERO bzero #define MEMCPY(dst, src, count) bcopy((src), (dst), (count)) +#ifdef __alpha__ +#define MemoryBarrier alpha_mb +#else +#define MemoryBarrier() +#endif #if defined(SCSIDEBUG) #define DFLT_DBLEVEL 3 @@ -105,8 +110,8 @@ struct isposinfo { #define XS_NULL(xs) xs == NULL || xs->sc_link == NULL #define XS_ISP(xs) (xs)->sc_link->adapter_softc -#define XS_LUN(xs) (xs)->sc_link->scsipi_scsi.lun -#define XS_TGT(xs) (xs)->sc_link->scsipi_scsi.target +#define XS_LUN(xs) ((int) (xs)->sc_link->scsipi_scsi.lun) +#define XS_TGT(xs) ((int) (xs)->sc_link->scsipi_scsi.target) #define XS_RESID(xs) (xs)->resid #define XS_XFRLEN(xs) (xs)->datalen #define XS_CDBLEN(xs) (xs)->cmdlen @@ -166,6 +171,95 @@ struct isposinfo { #define WATCH_INTERVAL 30 +#define FC_FW_READY_DELAY (12 * 1000000) + extern void isp_attach __P((struct ispsoftc *)); extern void isp_uninit __P((struct ispsoftc *)); + +static inline void isp_prtstst(ispstatusreq_t *sp) +{ + char buf[128]; + sprintf(buf, "states->"); + if (sp->req_state_flags & RQSF_GOT_BUS) + sprintf(buf, "%s%s", buf, "GOT_BUS "); + if (sp->req_state_flags & RQSF_GOT_TARGET) + sprintf(buf, "%s%s", buf, "GOT_TGT "); + if (sp->req_state_flags & RQSF_SENT_CDB) + sprintf(buf, "%s%s", buf, "SENT_CDB "); + if (sp->req_state_flags & RQSF_XFRD_DATA) + sprintf(buf, "%s%s", buf, "XFRD_DATA "); + if (sp->req_state_flags & RQSF_GOT_STATUS) + sprintf(buf, "%s%s", buf, "GOT_STS "); + if (sp->req_state_flags & RQSF_GOT_SENSE) + sprintf(buf, "%s%s", buf, "GOT_SNS "); + if (sp->req_state_flags & RQSF_XFER_COMPLETE) + sprintf(buf, "%s%s", buf, "XFR_CMPLT "); + sprintf(buf, "%s%s", buf, "\n"); + sprintf(buf, "%s%s", buf, "status->"); + if (sp->req_status_flags & RQSTF_DISCONNECT) + sprintf(buf, "%s%s", buf, "Disconnect "); + if (sp->req_status_flags & RQSTF_SYNCHRONOUS) + sprintf(buf, "%s%s", buf, "Sync_xfr "); + if (sp->req_status_flags & RQSTF_PARITY_ERROR) + sprintf(buf, "%s%s", buf, "Parity "); + if (sp->req_status_flags & RQSTF_BUS_RESET) + sprintf(buf, "%s%s", buf, "Bus_Reset "); + if (sp->req_status_flags & RQSTF_DEVICE_RESET) + sprintf(buf, "%s%s", buf, "Device_Reset "); + if (sp->req_status_flags & RQSTF_ABORTED) + sprintf(buf, "%s%s", buf, "Aborted "); + if (sp->req_status_flags & RQSTF_TIMEOUT) + sprintf(buf, "%s%s", buf, "Timeout "); + if (sp->req_status_flags & RQSTF_NEGOTIATION) + sprintf(buf, "%s%s", buf, "Negotiation "); + sprintf(buf, "%s%s", buf, "\n"); +} + +static inline const char *isp2100_fw_statename(int state) +{ + static char buf[16]; + switch(state) { + case FW_CONFIG_WAIT: return "Config Wait"; + case FW_WAIT_AL_PA: return "Waiting for AL_PA"; + case FW_WAIT_LOGIN: return "Wait Login"; + case FW_READY: return "Ready"; + case FW_LOSS_OF_SYNC: return "Loss Of Sync"; + case FW_ERROR: return "Error"; + case FW_REINIT: return "Re-Init"; + case FW_NON_PART: return "Nonparticipating"; + default: + sprintf(buf, "?0x%x?", state); + return buf; + } +} + +static inline const char *isp2100_pdb_statename(int pdb_state) +{ + static char buf[16]; + switch(pdb_state) { + case PDB_STATE_DISCOVERY: return "Port Discovery"; + case PDB_STATE_WDISC_ACK: return "Waiting Port Discovery ACK"; + case PDB_STATE_PLOGI: return "Port Login"; + case PDB_STATE_PLOGI_ACK: return "Wait Port Login ACK"; + case PDB_STATE_PRLI: return "Process Login"; + case PDB_STATE_PRLI_ACK: return "Wait Process Login ACK"; + case PDB_STATE_LOGGED_IN: return "Logged In"; + case PDB_STATE_PORT_UNAVAIL: return "Port Unavailable"; + case PDB_STATE_PRLO: return "Process Logout"; + case PDB_STATE_PRLO_ACK: return "Wait Process Logout ACK"; + case PDB_STATE_PLOGO: return "Port Logout"; + case PDB_STATE_PLOG_ACK: return "Wait Port Logout ACK"; + default: + sprintf(buf, "?0x%x?", pdb_state); + return buf; + } +} + +/* + * Keep these off for now... + */ +#define ISP_NO_FASTPOST_SCSI 1 +#define ISP_NO_FASTPOST_FC 1 +#define ISP_DISABLE_1080_SUPPORT 1 + #endif /* _ISP_NETBSD_H */ diff --git a/sys/dev/ic/ispmbox.h b/sys/dev/ic/ispmbox.h index d920d3f8fe6..a71c378cee1 100644 --- a/sys/dev/ic/ispmbox.h +++ b/sys/dev/ic/ispmbox.h @@ -1,5 +1,5 @@ -/* $NetBSD: ispmbox.h,v 1.13 1999/02/09 00:44:06 mjacob Exp $ */ -/* release_02_05_99 */ +/* $NetBSD: ispmbox.h,v 1.14 1999/03/17 06:15:48 mjacob Exp $ */ +/* release_03_16_99 */ /* * Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters. * @@ -127,7 +127,8 @@ #define MBOX_CLEAR_TASK_SET 0x67 #define MBOX_ABORT_TASK_SET 0x68 #define MBOX_GET_FW_STATE 0x69 -#define MBOX_GET_LINK_STATUS 0x6a +#define MBOX_GET_PORT_NAME 0x6a +#define MBOX_GET_LINK_STATUS 0x6b #define MBOX_INIT_LIP_RESET 0x6c #define MBOX_INIT_LIP_LOGIN 0x72 @@ -429,7 +430,7 @@ typedef struct { #define RQSTF_NEGOTIATION 0x0080 /* - * FC (ISP2100) specific initialization data structures + * FC (ISP2100) specific data structures */ /* @@ -522,6 +523,97 @@ typedef struct { array[ICB_NNM7] = (u_int8_t) ((wwn >> 56) & 0xff) /* + * Port Data Base Element + */ + +typedef struct { + u_int16_t pdb_options; +#if BYTE_ORDER == BIG_ENDIAN + u_int8_t pdb_sstate; + u_int8_t pdb_mstate; +#else + u_int8_t pdb_mstate; + u_int8_t pdb_sstate; +#endif +#if BYTE_ORDER == BIG_ENDIAN +#define BITS2WORD(x) \ + (x)[1] << 16 | (x)[2] << 8 | (x)[3] +#else +#define BITS2WORD(x) \ + (x)[0] << 16 | (x)[3] << 8 | (x)[2] +#endif + u_int8_t pdb_hardaddr_bits[4]; + u_int8_t pdb_portid_bits[4]; + u_int8_t pdb_nodename[8]; + u_int8_t pdb_portname[8]; + u_int16_t pdb_execthrottle; + u_int16_t pdb_exec_count; +#if BYTE_ORDER == BIG_ENDIAN + u_int8_t pdb_retry_delay; + u_int8_t pdb_retry_count; +#else + u_int8_t pdb_retry_count; + u_int8_t pdb_retry_delay; +#endif + u_int16_t pdb_resalloc; + u_int16_t pdb_curalloc; + u_int16_t pdb_qhead; + u_int16_t pdb_qtail; + u_int16_t pdb_tl_next; + u_int16_t pdb_tl_last; + u_int16_t pdb_features; /* PLOGI, Common Service */ + u_int16_t pdb_pconcurrnt; /* PLOGI, Common Service */ + u_int16_t pdb_roi; /* PLOGI, Common Service */ +#if BYTE_ORDER == BIG_ENDIAN + u_int8_t pdb_initiator; /* PLOGI, Class 3 Control Flags */ + u_int8_t pdb_target; +#else + u_int8_t pdb_target; + u_int8_t pdb_initiator; /* PLOGI, Class 3 Control Flags */ +#endif + u_int16_t pdb_rdsiz; /* PLOGI, Class 3 */ + u_int16_t pdb_ncseq; /* PLOGI, Class 3 */ + u_int16_t pdb_noseq; /* PLOGI, Class 3 */ + u_int16_t pdb_labrtflg; + u_int16_t pdb_lstopflg; + u_int16_t pdb_sqhead; + u_int16_t pdb_sqtail; + u_int16_t pdb_ptimer; + u_int16_t pdb_nxt_seqid; + u_int16_t pdb_fcount; + u_int16_t pdb_prli_len; + u_int16_t pdb_prli_svc0; + u_int16_t pdb_prli_svc3; + u_int16_t pdb_loopid; + u_int16_t pdb_il_ptr; + u_int16_t pdb_sl_ptr; +} isp_pdb_t; + +#define INVALID_PDB_OPTIONS 0xDEAD + +#define PDB_OPTIONS_XMITTING (1<<11) +#define PDB_OPTIONS_LNKXMIT (1<<10) +#define PDB_OPTIONS_ABORTED (1<<9) +#define PDB_OPTIONS_ADISC (1<<1) + +#define PDB_STATE_DISCOVERY 0 +#define PDB_STATE_WDISC_ACK 1 +#define PDB_STATE_PLOGI 2 +#define PDB_STATE_PLOGI_ACK 3 +#define PDB_STATE_PRLI 4 +#define PDB_STATE_PRLI_ACK 5 +#define PDB_STATE_LOGGED_IN 6 +#define PDB_STATE_PORT_UNAVAIL 7 +#define PDB_STATE_PRLO 8 +#define PDB_STATE_PRLO_ACK 9 +#define PDB_STATE_PLOGO 10 +#define PDB_STATE_PLOG_ACK 11 + +#define SVC3_TGT_ROLE 0x10 +#define SVC3_INI_ROLE 0x20 +#define SVC3_ROLE_MASK 0x30 + +/* * Target Mode Structures */ #define TGTSVALID 0x80 /* scsi status & sense data valid */ diff --git a/sys/dev/ic/ispreg.h b/sys/dev/ic/ispreg.h index 6e9e6736482..8fed5bd456e 100644 --- a/sys/dev/ic/ispreg.h +++ b/sys/dev/ic/ispreg.h @@ -1,5 +1,5 @@ -/* $NetBSD: ispreg.h,v 1.12 1999/02/09 00:44:42 mjacob Exp $ */ -/* release_02_05_99 */ +/* $NetBSD: ispreg.h,v 1.13 1999/03/17 06:15:48 mjacob Exp $ */ +/* release_03_16_99 */ /* * Machine Independent (well, as best as possible) register * definitions for Qlogic ISP SCSI adapters. @@ -57,28 +57,40 @@ * Sad but true, different architectures have different offsets. */ -#define BIU_REGS_OFF 0x00 +#define BIU_REGS_OFF 0x00 -#define PCI_MBOX_REGS_OFF 0x70 -#define PCI_MBOX_REGS2100_OFF 0x10 +#define PCI_MBOX_REGS_OFF 0x70 +#define PCI_MBOX_REGS2100_OFF 0x10 #define SBUS_MBOX_REGS_OFF 0x80 -#define PCI_SXP_REGS_OFF 0x80 +#define PCI_SXP_REGS_OFF 0x80 #define SBUS_SXP_REGS_OFF 0x200 -#define PCI_RISC_REGS_OFF 0x80 +#define PCI_RISC_REGS_OFF 0x80 #define SBUS_RISC_REGS_OFF 0x400 +/* Bless me! Chip designers have putzed it again! */ +#define ISP1080_DMA_REGS_OFF 0x60 +#define DMA_REGS_OFF 0x00 /* same as BIU block */ + /* * NB: The *_BLOCK definitions have no specific hardware meaning. * They serve simply to note to the MD layer which block of * registers offsets are being accessed. */ +#define _NREG_BLKS 5 +#define _BLK_REG_SHFT 13 +#define _BLK_REG_MASK (7 << _BLK_REG_SHFT) +#define BIU_BLOCK (0 << _BLK_REG_SHFT) +#define MBOX_BLOCK (1 << _BLK_REG_SHFT) +#define SXP_BLOCK (2 << _BLK_REG_SHFT) +#define RISC_BLOCK (3 << _BLK_REG_SHFT) +#define DMA_BLOCK (4 << _BLK_REG_SHFT) /* * Bus Interface Block Register Offsets */ -#define BIU_BLOCK 0x0100 + #define BIU_ID_LO BIU_BLOCK+0x0 /* R : Bus ID, Low */ #define BIU2100_FLASH_ADDR BIU_BLOCK+0x0 #define BIU_ID_HI BIU_BLOCK+0x2 /* R : Bus ID, High */ @@ -90,34 +102,37 @@ #define BIU_ISR BIU_BLOCK+0xA /* R : Bus Interface Status */ #define BIU_SEMA BIU_BLOCK+0xC /* RW : Bus Semaphore */ #define BIU_NVRAM BIU_BLOCK+0xE /* RW : Bus NVRAM */ -#define CDMA_CONF BIU_BLOCK+0x20 /* RW*: DMA Configuration */ -#define CDMA2100_CONTROL CDMA_CONF -#define CDMA_CONTROL BIU_BLOCK+0x22 /* RW*: DMA Control */ -#define CDMA_STATUS BIU_BLOCK+0x24 /* R : DMA Status */ -#define CDMA_FIFO_STS BIU_BLOCK+0x26 /* R : DMA FIFO Status */ -#define CDMA_COUNT BIU_BLOCK+0x28 /* RW*: DMA Transfer Count */ -#define CDMA_ADDR0 BIU_BLOCK+0x2C /* RW*: DMA Address, Word 0 */ -#define CDMA_ADDR1 BIU_BLOCK+0x2E /* RW*: DMA Address, Word 1 */ -/* these are for the 1040A cards */ -#define CDMA_ADDR2 BIU_BLOCK+0x30 /* RW*: DMA Address, Word 2 */ -#define CDMA_ADDR3 BIU_BLOCK+0x32 /* RW*: DMA Address, Word 3 */ +#define DFIFO_COMMAND BIU_BLOCK+0x60 /* RW : Command FIFO Port */ +#define RDMA2100_CONTROL DFIFO_COMMAND +#define DFIFO_DATA BIU_BLOCK+0x62 /* RW : Data FIFO Port */ -#define DDMA_CONF BIU_BLOCK+0x40 /* RW*: DMA Configuration */ +/* + * Putzed DMA register layouts. + */ +#define CDMA_CONF DMA_BLOCK+0x20 /* RW*: DMA Configuration */ +#define CDMA2100_CONTROL CDMA_CONF +#define CDMA_CONTROL DMA_BLOCK+0x22 /* RW*: DMA Control */ +#define CDMA_STATUS DMA_BLOCK+0x24 /* R : DMA Status */ +#define CDMA_FIFO_STS DMA_BLOCK+0x26 /* R : DMA FIFO Status */ +#define CDMA_COUNT DMA_BLOCK+0x28 /* RW*: DMA Transfer Count */ +#define CDMA_ADDR0 DMA_BLOCK+0x2C /* RW*: DMA Address, Word 0 */ +#define CDMA_ADDR1 DMA_BLOCK+0x2E /* RW*: DMA Address, Word 1 */ +#define CDMA_ADDR2 DMA_BLOCK+0x30 /* RW*: DMA Address, Word 2 */ +#define CDMA_ADDR3 DMA_BLOCK+0x32 /* RW*: DMA Address, Word 3 */ + +#define DDMA_CONF DMA_BLOCK+0x40 /* RW*: DMA Configuration */ #define TDMA2100_CONTROL DDMA_CONF -#define DDMA_CONTROL BIU_BLOCK+0x42 /* RW*: DMA Control */ -#define DDMA_STATUS BIU_BLOCK+0x44 /* R : DMA Status */ -#define DDMA_FIFO_STS BIU_BLOCK+0x46 /* R : DMA FIFO Status */ -#define DDMA_COUNT_LO BIU_BLOCK+0x48 /* RW*: DMA Xfer Count, Low */ -#define DDMA_COUNT_HI BIU_BLOCK+0x4A /* RW*: DMA Xfer Count, High */ -#define DDMA_ADDR0 BIU_BLOCK+0x4C /* RW*: DMA Address, Word 0 */ -#define DDMA_ADDR1 BIU_BLOCK+0x4E /* RW*: DMA Address, Word 1 */ +#define DDMA_CONTROL DMA_BLOCK+0x42 /* RW*: DMA Control */ +#define DDMA_STATUS DMA_BLOCK+0x44 /* R : DMA Status */ +#define DDMA_FIFO_STS DMA_BLOCK+0x46 /* R : DMA FIFO Status */ +#define DDMA_COUNT_LO DMA_BLOCK+0x48 /* RW*: DMA Xfer Count, Low */ +#define DDMA_COUNT_HI DMA_BLOCK+0x4A /* RW*: DMA Xfer Count, High */ +#define DDMA_ADDR0 DMA_BLOCK+0x4C /* RW*: DMA Address, Word 0 */ +#define DDMA_ADDR1 DMA_BLOCK+0x4E /* RW*: DMA Address, Word 1 */ /* these are for the 1040A cards */ -#define DDMA_ADDR2 BIU_BLOCK+0x50 /* RW*: DMA Address, Word 2 */ -#define DDMA_ADDR3 BIU_BLOCK+0x52 /* RW*: DMA Address, Word 3 */ +#define DDMA_ADDR2 DMA_BLOCK+0x50 /* RW*: DMA Address, Word 2 */ +#define DDMA_ADDR3 DMA_BLOCK+0x52 /* RW*: DMA Address, Word 3 */ -#define DFIFO_COMMAND BIU_BLOCK+0x60 /* RW : Command FIFO Port */ -#define RDMA2100_CONTROL DFIFO_COMMAND -#define DFIFO_DATA BIU_BLOCK+0x62 /* RW : Data FIFO Port */ /* * Bus Interface Block Register Definitions @@ -141,6 +156,9 @@ #define BIU_SBUS_CONF1_BURST8 0x0008 /* Enable 8-byte bursts */ #define BIU_PCI_CONF1_SXP 0x0008 /* SXP register select */ +#define BIU_PCI1080_CONF1_SXP 0x0100 /* SXP bank select */ +#define BIU_PCI1080_CONF1_DMA 0x0300 /* DMA bank select */ + /* ISP2100 Bus Control/Status Register */ #define BIU2100_ICSR_REGBSEL 0x30 /* RW: register bank select */ @@ -175,6 +193,11 @@ ISP_WRITE(isp, BIU_ICR, BIU_ICR_ENABLE_RISC_INT | BIU_ICR_ENABLE_ALL_INTS) : \ ISP_WRITE(isp, BIU_ICR, BIU2100_ICR_ENA_RISC_INT | BIU2100_ICR_ENABLE_ALL_INTS) +#define INTS_ENABLED(isp) ((isp->isp_type & ISP_HA_SCSI)? \ + (ISP_READ(isp, BIU_ICR) & (BIU_ICR_ENABLE_RISC_INT|BIU_ICR_ENABLE_ALL_INTS)) :\ + (ISP_READ(isp, BIU_ICR) & \ + (BIU2100_ICR_ENA_RISC_INT|BIU2100_ICR_ENABLE_ALL_INTS))) + #define DISABLE_INTS(isp) ISP_WRITE(isp, BIU_ICR, 0) /* BUS STATUS REGISTER */ @@ -287,7 +310,6 @@ * Mailbox Block Register Offsets */ -#define MBOX_BLOCK 0x0200 #define INMAILBOX0 MBOX_BLOCK+0x0 #define INMAILBOX1 MBOX_BLOCK+0x2 #define INMAILBOX2 MBOX_BLOCK+0x4 @@ -314,7 +336,6 @@ /* * SXP Block Register Offsets */ -#define SXP_BLOCK 0x0400 #define SXP_PART_ID SXP_BLOCK+0x0 /* R : Part ID Code */ #define SXP_CONFIG1 SXP_BLOCK+0x2 /* RW*: Configuration Reg #1 */ #define SXP_CONFIG2 SXP_BLOCK+0x4 /* RW*: Configuration Reg #2 */ @@ -485,7 +506,6 @@ /* * RISC and Host Command and Control Block Register Offsets */ -#define RISC_BLOCK 0x0800 #define RISC_ACC RISC_BLOCK+0x0 /* RW*: Accumulator */ #define RISC_R1 RISC_BLOCK+0x2 /* RW*: GP Reg R1 */ diff --git a/sys/dev/ic/ispvar.h b/sys/dev/ic/ispvar.h index 3293a308d3d..1018e93286a 100644 --- a/sys/dev/ic/ispvar.h +++ b/sys/dev/ic/ispvar.h @@ -1,5 +1,5 @@ -/* $NetBSD: ispvar.h,v 1.18 1999/02/09 00:46:25 mjacob Exp $ */ -/* release_02_05_99 */ +/* $NetBSD: ispvar.h,v 1.19 1999/03/17 06:15:48 mjacob Exp $ */ +/* release_03_16_99 */ /* * Soft Definitions for for Qlogic ISP SCSI adapters. * @@ -37,7 +37,7 @@ #ifndef _ISPVAR_H #define _ISPVAR_H -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) #include <dev/ic/ispmbox.h> #endif #ifdef __FreeBSD__ @@ -77,13 +77,17 @@ struct ispmdvec { }; #define MAX_TARGETS 16 +#ifdef ISP2100_FABRIC +#define MAX_FC_TARG 256 +#else #define MAX_FC_TARG 126 +#endif #define DEFAULT_LOOPID 113 /* queue length must be a power of two */ #define QENTRY_LEN 64 #define RQUEST_QUEUE_LEN MAXISPREQUEST -#define RESULT_QUEUE_LEN (MAXISPREQUEST/4) +#define RESULT_QUEUE_LEN (MAXISPREQUEST/2) #define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN)) #define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN) #define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1)) @@ -164,6 +168,11 @@ typedef struct { u_int16_t isp_maxfrmlen; u_int16_t isp_fwoptions; /* + * Port Data Base + */ + isp_pdb_t isp_pdb[MAX_FC_TARG]; + + /* * Scratch DMA mapped in area to fetch Port Database stuff, etc. */ volatile caddr_t isp_scratch; @@ -237,7 +246,8 @@ struct ispsoftc { u_int : 8, isp_confopts : 8, - : 2, + : 1, + isp_used : 1, isp_dblev : 3, isp_gotdparms : 1, isp_dogactive : 1, @@ -256,7 +266,7 @@ struct ispsoftc { : 19, isp_state : 3, isp_sendmarker : 1, /* send a marker entry */ - isp_update : 1, /* update paramters */ + isp_update : 1, /* update parameters */ isp_nactive : 9; /* how many commands active */ /* @@ -341,9 +351,14 @@ struct ispsoftc { #define ISP_HA_SCSI_1040 0x4 #define ISP_HA_SCSI_1040A 0x5 #define ISP_HA_SCSI_1040B 0x6 +#define ISP_HA_SCSI_1080 0xe #define ISP_HA_FC 0xf0 #define ISP_HA_FC_2100 0x10 +#define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI) +#define IS_1080(isp) (isp->isp_type == ISP_HA_SCSI_1080) +#define IS_FC(isp) (isp->isp_type & ISP_HA_FC) + /* * Macros to read, write ISP registers through bus specific code. */ @@ -424,6 +439,7 @@ typedef enum { ISPCTL_RESET_DEV, ISPCTL_ABORT_CMD, ISPCTL_UPDATE_PARAMS, + ISPCTL_FCLINK_TEST } ispctl_t; int isp_control __P((struct ispsoftc *, ispctl_t, void *)); @@ -439,8 +455,11 @@ int isp_control __P((struct ispsoftc *, ispctl_t, void *)); typedef enum { ISPASYNC_NEW_TGT_PARAMS, + ISPASYNC_BUS_RESET, /* Bus Reset */ ISPASYNC_LOOP_DOWN, /* Obvious FC only */ - ISPASYNC_LOOP_UP /* Obvious FC only */ + ISPASYNC_LOOP_UP, /* "" */ + ISPASYNC_PDB_CHANGE_COMPLETE, /* "" */ + ISPASYNC_CHANGE_NOTIFY /* "" */ } ispasync_t; int isp_async __P((struct ispsoftc *, ispasync_t, void *)); |
