Implement and use Fast Posting for both parallel && fibre. Redo a bit of
the startup code. Implement a call to outer framework function so that asynchronous events can be handled (e.g., speed negotiation, target mode). Roll internal release tags.
This commit is contained in:
parent
513722ba25
commit
6bcdc2b5d2
468
sys/dev/ic/isp.c
468
sys/dev/ic/isp.c
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: isp.c,v 1.30 1999/01/10 05:07:53 mjacob Exp $ */
|
||||
/* release_12_28_98_A+ */
|
||||
/* $NetBSD: isp.c,v 1.31 1999/01/30 07:31:50 mjacob Exp $ */
|
||||
/* release_01_29_99 */
|
||||
/*
|
||||
* Machine and OS Independent (well, as best as possible)
|
||||
* code for the Qlogic ISP SCSI adapters.
|
||||
@ -118,7 +118,7 @@ static void isp_rdnvram_word __P((struct ispsoftc *, int, u_int16_t *));
|
||||
/*
|
||||
* Reset Hardware.
|
||||
*
|
||||
* Hit the chip over the head, download new f/w.
|
||||
* Hit the chip over the head, download new f/w and set it running.
|
||||
*
|
||||
* Locking done elsewhere.
|
||||
*/
|
||||
@ -128,7 +128,7 @@ isp_reset(isp)
|
||||
{
|
||||
static char once = 1;
|
||||
mbreg_t mbs;
|
||||
int loops, i, dodnld = 1, deadchip;
|
||||
int loops, i, dodnld = 1;
|
||||
char *revname;
|
||||
|
||||
isp->isp_state = ISP_NILSTATE;
|
||||
@ -139,17 +139,40 @@ isp_reset(isp)
|
||||
* here.
|
||||
*/
|
||||
isp->isp_dblev = DFLT_DBLEVEL;
|
||||
deadchip = ISP_READ(isp, HCCR) & HCCR_RESET;
|
||||
if (deadchip) {
|
||||
|
||||
/*
|
||||
* Get the current running firmware revision out of the
|
||||
* chip before we hit it over the head (if this is our
|
||||
* first time through). Note that we store this as the
|
||||
* 'ROM' firmware revision- which it may not be. In any
|
||||
* case, we don't really use this yet, but we may in
|
||||
* the future.
|
||||
*/
|
||||
if (once == 1) {
|
||||
/*
|
||||
* Just in case it was paused...
|
||||
*/
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
|
||||
if (ISP_READ(isp, HCCR) & HCCR_RESET) {
|
||||
isp_dumpregs(isp, "still reset after release");
|
||||
SYS_DELAY(1000);
|
||||
once = 0;
|
||||
mbs.param[0] = MBOX_ABOUT_FIRMWARE;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
/*
|
||||
* If this fails, it probably means we're running
|
||||
* an old prom, if anything at all...
|
||||
*/
|
||||
isp->isp_romfw_rev = 0;
|
||||
} else {
|
||||
deadchip = 1;
|
||||
isp->isp_romfw_rev =
|
||||
(((u_int16_t) mbs.param[1]) << 10) + mbs.param[2];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put it into PAUSE mode.
|
||||
*/
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
|
||||
|
||||
if (isp->isp_type & ISP_HA_FC) {
|
||||
revname = "2100";
|
||||
} else {
|
||||
@ -192,62 +215,36 @@ isp_reset(isp)
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Try and figure out if we're connected to a differential bus.
|
||||
* You have to pause the RISC processor to read SXP registers.
|
||||
* Now, while we're at it, gather info about ultra
|
||||
* and/or differential mode.
|
||||
*/
|
||||
if (deadchip == 0) {
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
|
||||
i = 100;
|
||||
while ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
|
||||
SYS_DELAY(20);
|
||||
if (--i == 0) {
|
||||
isp_dumpregs(isp,
|
||||
"cannot stop RISC processor");
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
i = 0;
|
||||
sdp->isp_diffmode = 0;
|
||||
}
|
||||
if (i > 0) {
|
||||
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) {
|
||||
IDPRINTF(2, ("%s: Differential Mode Set\n",
|
||||
isp->isp_name));
|
||||
sdp->isp_diffmode = 1;
|
||||
} else {
|
||||
sdp->isp_diffmode = 0;
|
||||
}
|
||||
|
||||
if (isp->isp_bustype != ISP_BT_SBUS) {
|
||||
ISP_CLRBITS(isp, BIU_CONF1, BIU_PCI_CONF1_SXP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out whether we're ultra capable.
|
||||
*/
|
||||
i = ISP_READ(isp, RISC_PSR);
|
||||
if (isp->isp_bustype != ISP_BT_SBUS) {
|
||||
i &= RISC_PSR_PCI_ULTRA;
|
||||
} else {
|
||||
i &= RISC_PSR_SBUS_ULTRA;
|
||||
}
|
||||
if (i) {
|
||||
IDPRINTF(2, ("%s: Ultra Mode Capable\n",
|
||||
isp->isp_name));
|
||||
sdp->isp_clock = 60;
|
||||
} else {
|
||||
sdp->isp_clock = 40;
|
||||
}
|
||||
/*
|
||||
* Restart processor, if necessary.
|
||||
*/
|
||||
if (deadchip == 0)
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
|
||||
i = ISP_READ(isp, RISC_PSR);
|
||||
if (isp->isp_bustype == ISP_BT_SBUS) {
|
||||
i &= RISC_PSR_SBUS_ULTRA;
|
||||
} 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;
|
||||
sdp->isp_clock = 60;
|
||||
} else {
|
||||
sdp->isp_ultramode = 0;
|
||||
sdp->isp_clock = 40;
|
||||
}
|
||||
|
||||
/*
|
||||
* Machine dependent clock (if set) overrides
|
||||
* our generic determinations.
|
||||
@ -257,6 +254,7 @@ isp_reset(isp)
|
||||
sdp->isp_clock = isp->isp_mdvec->dv_clock;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -264,27 +262,7 @@ isp_reset(isp)
|
||||
*/
|
||||
ISP_RESET0(isp);
|
||||
|
||||
if (once == 1 && deadchip == 0) {
|
||||
once = 0;
|
||||
/*
|
||||
* Get the current running firmware revision out of the
|
||||
* chip before we hit it over the head (if this is our
|
||||
* first time through). Note that we store this as the
|
||||
* 'ROM' firmware revision- which it may not be. In any
|
||||
* case, we don't really use this yet, but we may in
|
||||
* the future.
|
||||
*/
|
||||
mbs.param[0] = MBOX_ABOUT_FIRMWARE;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
IDPRINTF(3, ("%s: initial ABOUT FIRMWARE command "
|
||||
"failed\n", isp->isp_name));
|
||||
} else {
|
||||
isp->isp_romfw_rev =
|
||||
(((u_int16_t) mbs.param[1]) << 10) + mbs.param[2];
|
||||
}
|
||||
}
|
||||
|
||||
again:
|
||||
|
||||
/*
|
||||
* Hit the chip over the head with hammer,
|
||||
@ -311,6 +289,10 @@ isp_reset(isp)
|
||||
* A slight delay...
|
||||
*/
|
||||
SYS_DELAY(100);
|
||||
|
||||
/*
|
||||
* Clear data && control DMA engines.
|
||||
*/
|
||||
ISP_WRITE(isp, CDMA2100_CONTROL,
|
||||
DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
ISP_WRITE(isp, TDMA2100_CONTROL,
|
||||
@ -337,41 +319,62 @@ isp_reset(isp)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* More initialization
|
||||
* After we've fired this chip up, zero out the conf1 register
|
||||
* for SCSI adapters and other settings for the 2100.
|
||||
*/
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
ISP_WRITE(isp, BIU_CONF1, 0);
|
||||
} else {
|
||||
ISP_WRITE(isp, BIU2100_CSR, 0);
|
||||
/*
|
||||
* All 2100's are 60Mhz with fast rams onboard.
|
||||
*/
|
||||
ISP_WRITE(isp, RISC_MTR2100, 0x1212);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset RISC Processor
|
||||
*/
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
|
||||
SYS_DELAY(100);
|
||||
|
||||
/*
|
||||
* Establish some initial burst rate thingies
|
||||
* Establish some initial burst rate stuff.
|
||||
* (only for the 1XX0 boards). This really should
|
||||
* be done later after fetching from NVRAM.
|
||||
*/
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
u_int16_t conf1 = isp->isp_mdvec->dv_conf1;
|
||||
u_int16_t tmp = isp->isp_mdvec->dv_conf1;
|
||||
/*
|
||||
* Busted FIFO. Turn off all but burst enables.
|
||||
*/
|
||||
if (isp->isp_type == ISP_HA_SCSI_1040A) {
|
||||
conf1 &= BIU_BURST_ENABLE;
|
||||
tmp &= BIU_BURST_ENABLE;
|
||||
}
|
||||
ISP_SETBITS(isp, BIU_CONF1, conf1);
|
||||
if (conf1 & BIU_BURST_ENABLE) {
|
||||
ISP_SETBITS(isp, BIU_CONF1, tmp);
|
||||
if (tmp & BIU_BURST_ENABLE) {
|
||||
ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
|
||||
ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
|
||||
}
|
||||
#ifdef PTI_CARDS
|
||||
if (((sdparam *) isp->isp_param)->isp_ultramode) {
|
||||
while(ISP_READ(isp, RISC_MTR) != 0x1313) {
|
||||
ISP_WRITE(isp, RISC_MTR, 0x1313);
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
|
||||
}
|
||||
} else {
|
||||
ISP_WRITE(isp, RISC_MTR, 0x1212);
|
||||
}
|
||||
/*
|
||||
* PTI specific register
|
||||
*/
|
||||
ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
|
||||
#else
|
||||
ISP_WRITE(isp, RISC_MTR, 0x1212);
|
||||
#endif
|
||||
} else {
|
||||
ISP_WRITE(isp, RISC_MTR2100, 0x1212);
|
||||
}
|
||||
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
|
||||
|
||||
/*
|
||||
@ -384,6 +387,25 @@ isp_reset(isp)
|
||||
*/
|
||||
ENABLE_INTS(isp);
|
||||
|
||||
/*
|
||||
* Wait for everything to finish firing up...
|
||||
*/
|
||||
loops = MBOX_DELAY_COUNT;
|
||||
while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
|
||||
SYS_DELAY(100);
|
||||
if (--loops < 0) {
|
||||
PRINTF("%s: MBOX_BUSY never cleared on reset\n",
|
||||
isp->isp_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Up until this point we've done everything by just reading or
|
||||
* setting registers. From this point on we rely on at least *some*
|
||||
* kind of firmware running in the card.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Do some sanity checking.
|
||||
*/
|
||||
@ -430,29 +452,29 @@ isp_reset(isp)
|
||||
dodnld = 0;
|
||||
}
|
||||
|
||||
if (dodnld) {
|
||||
if (dodnld && isp->isp_mdvec->dv_fwlen) {
|
||||
for (i = 0; i < isp->isp_mdvec->dv_fwlen; i++) {
|
||||
mbs.param[0] = MBOX_WRITE_RAM_WORD;
|
||||
mbs.param[1] = isp->isp_mdvec->dv_codeorg + i;
|
||||
mbs.param[2] = isp->isp_mdvec->dv_ispfw[i];
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_dumpregs(isp, "f/w download failed");
|
||||
return;
|
||||
PRINTF("%s: F/W download failed at word %d\n",
|
||||
isp->isp_name, i);
|
||||
dodnld = 0;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
if (isp->isp_mdvec->dv_fwlen) {
|
||||
/*
|
||||
* Verify that it downloaded correctly.
|
||||
*/
|
||||
mbs.param[0] = MBOX_VERIFY_CHECKSUM;
|
||||
mbs.param[1] = isp->isp_mdvec->dv_codeorg;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_dumpregs(isp, "ram checksum failure");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Verify that it downloaded correctly.
|
||||
*/
|
||||
mbs.param[0] = MBOX_VERIFY_CHECKSUM;
|
||||
mbs.param[1] = isp->isp_mdvec->dv_codeorg;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_dumpregs(isp, "ram checksum failure");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
IDPRINTF(3, ("%s: skipping f/w download\n", isp->isp_name));
|
||||
@ -466,7 +488,10 @@ isp_reset(isp)
|
||||
*/
|
||||
|
||||
mbs.param[0] = MBOX_EXEC_FIRMWARE;
|
||||
mbs.param[1] = isp->isp_mdvec->dv_codeorg;
|
||||
if (isp->isp_mdvec->dv_codeorg)
|
||||
mbs.param[1] = isp->isp_mdvec->dv_codeorg;
|
||||
else
|
||||
mbs.param[1] = 0x1000;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
@ -506,7 +531,7 @@ isp_reset(isp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize Hardware to known state
|
||||
* Initialize Parameters of Hardware to a known state.
|
||||
*
|
||||
* Locks are held before coming here.
|
||||
*/
|
||||
@ -674,6 +699,10 @@ isp_init(isp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* And mark this as an unannounced device
|
||||
*/
|
||||
sdp->isp_devparam[tgt].dev_announced = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -710,6 +739,19 @@ isp_init(isp)
|
||||
}
|
||||
isp->isp_reqidx = isp->isp_reqodx = 0;
|
||||
|
||||
/*
|
||||
* Turn on Fast Posting
|
||||
*/
|
||||
if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) {
|
||||
mbs.param[0] = MBOX_SET_FW_FEATURES;
|
||||
mbs.param[1] = FW_FEATURE_FAST_POST;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
PRINTF("%s: unable to enable FAST Posting\n",
|
||||
isp->isp_name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: See whether or not for 7.55 F/W or later we
|
||||
* XXX: can do without this, and see whether we should
|
||||
@ -763,6 +805,15 @@ isp_fibre_init(isp)
|
||||
loopid = fcp->isp_loopid;
|
||||
#endif
|
||||
|
||||
#if defined(ISP2100_FABRIC) && defined(ISP2100_SCCLUN)
|
||||
PRINTF("%s: Fabric Support, Expanded Lun Support\n", isp->isp_name);
|
||||
#endif
|
||||
#if defined(ISP2100_FABRIC) && !defined(ISP2100_SCCLUN)
|
||||
PRINTF("%s: Fabric Support\n", isp->isp_name);
|
||||
#endif
|
||||
#if !defined(ISP2100_FABRIC) && defined(ISP2100_SCCLUN)
|
||||
PRINTF("%s: Expanded Lun Support\n", isp->isp_name);
|
||||
#endif
|
||||
|
||||
icbp = (isp_icb_t *) fcp->isp_scratch;
|
||||
MEMZERO(icbp, sizeof (*icbp));
|
||||
@ -773,7 +824,7 @@ isp_fibre_init(isp)
|
||||
#else
|
||||
fcp->isp_fwoptions = 0;
|
||||
#endif
|
||||
fcp->isp_fwoptions |= ICBOPT_INI_ADISC|ICBOPT_FAIRNESS;
|
||||
fcp->isp_fwoptions |= ICBOPT_INI_ADISC|ICBOPT_FAIRNESS|ICBOPT_FAST_POST;
|
||||
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
|
||||
fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
|
||||
#ifdef CHECKME
|
||||
@ -785,6 +836,7 @@ isp_fibre_init(isp)
|
||||
*/
|
||||
fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
|
||||
#endif
|
||||
|
||||
icbp->icb_fwoptions = fcp->isp_fwoptions;
|
||||
icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
|
||||
if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
|
||||
@ -1058,7 +1110,7 @@ ispscsicmd(xs)
|
||||
#endif
|
||||
|
||||
}
|
||||
memcpy(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
|
||||
MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
|
||||
|
||||
IDPRINTF(5, ("%s(%d.%d): START%d cmd 0x%x datalen %d\n", isp->isp_name,
|
||||
XS_TGT(xs), XS_LUN(xs), reqp->req_header.rqs_seqno,
|
||||
@ -1227,9 +1279,28 @@ isp_intr(arg)
|
||||
|
||||
if (ISP_READ(isp, BIU_SEMA) & 1) {
|
||||
u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
|
||||
if (isp_parse_async(isp, (int) mbox))
|
||||
return (1);
|
||||
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 (isp->isp_nactive > 0)
|
||||
isp->isp_nactive--;
|
||||
complist[ndone++] = xs;
|
||||
}
|
||||
}
|
||||
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
|
||||
@ -1319,14 +1390,24 @@ isp_intr(arg)
|
||||
XS_STS(xs) = sp->req_scsi_status & 0xff;
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
if (sp->req_state_flags & RQSF_GOT_SENSE) {
|
||||
memcpy(XS_SNSP(xs), sp->req_sense_data,
|
||||
MEMCPY(XS_SNSP(xs), sp->req_sense_data,
|
||||
XS_SNSLEN(xs));
|
||||
XS_SNS_IS_VALID(xs);
|
||||
}
|
||||
/*
|
||||
* A new synchronous rate was negotiated for this
|
||||
* target. Mark state such that we'll go look up
|
||||
* that which has changed later.
|
||||
*/
|
||||
if (sp->req_status_flags & RQSTF_NEGOTIATION) {
|
||||
sdparam *sdp = isp->isp_param;
|
||||
isp->isp_update = 1;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_refresh = 1;
|
||||
}
|
||||
} else {
|
||||
if (XS_STS(xs) == SCSI_CHECK) {
|
||||
XS_SNS_IS_VALID(xs);
|
||||
memcpy(XS_SNSP(xs), sp->req_sense_data,
|
||||
MEMCPY(XS_SNSP(xs), sp->req_sense_data,
|
||||
XS_SNSLEN(xs));
|
||||
sp->req_state_flags |= RQSF_GOT_SENSE;
|
||||
}
|
||||
@ -1419,6 +1500,8 @@ isp_parse_async(isp, mbox)
|
||||
struct ispsoftc *isp;
|
||||
int mbox;
|
||||
{
|
||||
u_int32_t fast_post_handle = 0;
|
||||
|
||||
switch (mbox) {
|
||||
case ASYNC_BUS_RESET:
|
||||
PRINTF("%s: SCSI bus reset detected\n", isp->isp_name);
|
||||
@ -1434,7 +1517,7 @@ isp_parse_async(isp, mbox)
|
||||
isp->isp_name, mbox);
|
||||
isp_restart(isp);
|
||||
/* no point continuing after this */
|
||||
return (1);
|
||||
return (-1);
|
||||
|
||||
case ASYNC_RQS_XFER_ERR:
|
||||
PRINTF("%s: Request Queue Transfer Error\n", isp->isp_name);
|
||||
@ -1489,11 +1572,10 @@ isp_parse_async(isp, mbox)
|
||||
break;
|
||||
|
||||
case ASYNC_CMD_CMPLT:
|
||||
PRINTF("%s: fast post completion\n", isp->isp_name);
|
||||
#if 0
|
||||
fast_post_handle = (ISP_READ(isp, OUTMAILBOX1) << 16) |
|
||||
ISP_READ(isp, OUTMAILBOX2);
|
||||
#endif
|
||||
fast_post_handle = (ISP_READ(isp, OUTMAILBOX2) << 16) |
|
||||
ISP_READ(isp, OUTMAILBOX1);
|
||||
IDPRINTF(3, ("%s: fast post completion of %u\n", isp->isp_name,
|
||||
fast_post_handle));
|
||||
break;
|
||||
|
||||
case ASYNC_CTIO_DONE:
|
||||
@ -1532,7 +1614,7 @@ isp_parse_async(isp, mbox)
|
||||
PRINTF("%s: async %x\n", isp->isp_name, mbox);
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
return (fast_post_handle);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1718,7 +1800,7 @@ isp_handle_other_response(isp, sp, optrp)
|
||||
ct2->req_seg_count = 1;
|
||||
if (at2->req_cdb[0] == 0x12) {
|
||||
s = sizeof(tgtiqd);
|
||||
memcpy(fcp->isp_scratch, tgtiqd, s);
|
||||
MEMCPY(fcp->isp_scratch, tgtiqd, s);
|
||||
} else {
|
||||
s = at2->req_datalen;
|
||||
MEMZERO(fcp->isp_scratch, s);
|
||||
@ -1773,7 +1855,7 @@ isp_handle_other_response(isp, sp, optrp)
|
||||
ct2->req_m.mode1.req_sense_len = 18;
|
||||
ct2->req_m.mode1.req_scsi_status |=
|
||||
at2->req_scsi_status;
|
||||
memcpy(ct2->req_m.mode1.req_response,
|
||||
MEMCPY(ct2->req_m.mode1.req_response,
|
||||
at2->req_sense, sizeof (at2->req_sense));
|
||||
}
|
||||
break;
|
||||
@ -1826,7 +1908,7 @@ isp_handle_other_response(isp, sp, optrp)
|
||||
PRINTF("%s: Request Queue Overflow other response\n",
|
||||
isp->isp_name);
|
||||
} else {
|
||||
memcpy(reqp, ireqp, reqsize);
|
||||
MEMCPY(reqp, ireqp, reqsize);
|
||||
ISP_WRITE(isp, INMAILBOX4, iptr);
|
||||
isp->isp_reqidx = iptr;
|
||||
}
|
||||
@ -1954,7 +2036,7 @@ isp_notify_ack(isp, ptrp)
|
||||
PRINTF("%s: Request Queue Overflow For isp_notify_ack\n",
|
||||
isp->isp_name);
|
||||
} else {
|
||||
memcpy(reqp, ireqp, sizeof (un));
|
||||
MEMCPY(reqp, ireqp, sizeof (un));
|
||||
ISP_WRITE(isp, INMAILBOX4, iptr);
|
||||
isp->isp_reqidx = iptr;
|
||||
}
|
||||
@ -2009,7 +2091,7 @@ isp_handle_atio (isp, aep)
|
||||
|
||||
|
||||
if (status & TGTSVALID) {
|
||||
memcpy(&cdp->cd_sensedata, aep->at_sense,
|
||||
MEMCPY(&cdp->cd_sensedata, aep->at_sense,
|
||||
sizeof (cdp->cd_sensedata));
|
||||
PRINTF("%s: Bus Phase Sequence error key 0x%x\n",
|
||||
isp->isp_name, cdp->cd_sensedata[2] & 0xf);
|
||||
@ -2050,7 +2132,7 @@ isp_handle_atio (isp, aep)
|
||||
cdp->cd_lun = aep->at_lun;
|
||||
cdp->cd_tagtype = aep->at_tag_type;
|
||||
cdp->cd_tagval = aep->at_tag_val;
|
||||
memcpy(cdp->cd_cdb, aep->at_cdb, 16);
|
||||
MEMCPY(cdp->cd_cdb, aep->at_cdb, 16);
|
||||
PRINTF("%s: CDB 0x%x itl %d/%d/%d\n", isp->isp_name,
|
||||
cdp->cd_cdb[0], cdp->cd_iid, cdp->cd_tgt, cdp->cd_lun);
|
||||
(*isp->isp_tmd_newcmd)(isp, cdp);
|
||||
@ -2126,7 +2208,7 @@ isp_handle_atio2(isp, aep)
|
||||
cdp->cd_iid = aep->at_iid;
|
||||
cdp->cd_tgt = 0;
|
||||
cdp->cd_lun = aep->at_lun;
|
||||
memcpy(cdp->cd_cdb, aep->at_cdb, 16);
|
||||
MEMCPY(cdp->cd_cdb, aep->at_cdb, 16);
|
||||
cdp->cd_rxid = aep->at_rxid;
|
||||
cdp->cp_origdlen = aep->at_datalen;
|
||||
cdp->cp_totbytes = 0;
|
||||
@ -2354,8 +2436,8 @@ isp_parse_status(isp, sp, xs)
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
sdparam *sdp = isp->isp_param;
|
||||
isp->isp_update = 1;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_flags &= ~DPARM_WIDE;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
|
||||
}
|
||||
XS_SETERR(xs, HBA_NOERROR);
|
||||
return;
|
||||
@ -2366,8 +2448,8 @@ isp_parse_status(isp, sp, xs)
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
sdparam *sdp = isp->isp_param;
|
||||
isp->isp_update = 1;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_flags &= ~DPARM_SYNC;
|
||||
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2491,8 +2573,8 @@ static u_int8_t mbpcnt[] = {
|
||||
MAKNIB(0, 0), /* 0x47: */
|
||||
MAKNIB(0, 0), /* 0x48: */
|
||||
MAKNIB(0, 0), /* 0x49: */
|
||||
MAKNIB(0, 0), /* 0x4a: */
|
||||
MAKNIB(0, 0), /* 0x4b: */
|
||||
MAKNIB(2, 1), /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
|
||||
MAKNIB(1, 2), /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
|
||||
MAKNIB(0, 0), /* 0x4c: */
|
||||
MAKNIB(0, 0), /* 0x4d: */
|
||||
MAKNIB(0, 0), /* 0x4e: */
|
||||
@ -2879,77 +2961,68 @@ isp_update(isp)
|
||||
|
||||
sdp = isp->isp_param;
|
||||
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
|
||||
u_int16_t flags, period, offset, changed;
|
||||
int get;
|
||||
|
||||
if (sdp->isp_devparam[tgt].dev_enable == 0) {
|
||||
continue;
|
||||
}
|
||||
if (sdp->isp_devparam[tgt].dev_update == 0) {
|
||||
|
||||
if (sdp->isp_devparam[tgt].dev_update) {
|
||||
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
|
||||
mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
|
||||
mbs.param[3] =
|
||||
(sdp->isp_devparam[tgt].sync_offset << 8) |
|
||||
(sdp->isp_devparam[tgt].sync_period);
|
||||
sdp->isp_devparam[tgt].dev_update = 0;
|
||||
sdp->isp_devparam[tgt].dev_refresh = 1;
|
||||
isp->isp_update = 1;
|
||||
get = 0;
|
||||
} else if (sdp->isp_devparam[tgt].dev_refresh) {
|
||||
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
|
||||
sdp->isp_devparam[tgt].dev_refresh = 0;
|
||||
get = 1;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
mbs.param[1] = tgt << 8;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
PRINTF("%s: failed to %cet SCSI parameters for "
|
||||
"target %d\n", isp->isp_name, (get)? 'g' : 's',
|
||||
tgt);
|
||||
continue;
|
||||
}
|
||||
|
||||
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
|
||||
mbs.param[1] = tgt << 8;
|
||||
mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
|
||||
mbs.param[3] =
|
||||
(sdp->isp_devparam[tgt].sync_offset << 8) |
|
||||
(sdp->isp_devparam[tgt].sync_period);
|
||||
|
||||
IDPRINTF(3, ("\n%s: tgt %d cflags %x offset %x period %x\n",
|
||||
isp->isp_name, tgt, mbs.param[2], mbs.param[3] >> 8,
|
||||
mbs.param[3] & 0xff));
|
||||
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
PRINTF("%s: failed to change SCSI parameters for "
|
||||
"target %d\n", isp->isp_name, tgt);
|
||||
} else {
|
||||
char *wt;
|
||||
int x, flags;
|
||||
|
||||
flags = sdp->isp_devparam[tgt].cur_dflags =
|
||||
if (get == 0) {
|
||||
sdp->isp_devparam[tgt].cur_dflags =
|
||||
sdp->isp_devparam[tgt].dev_flags;
|
||||
|
||||
x = sdp->isp_devparam[tgt].sync_period & 0xff;
|
||||
if (flags & DPARM_SYNC) {
|
||||
if (x == (ISP_20M_SYNCPARMS & 0xff)) {
|
||||
x = 20;
|
||||
} else if (x == (ISP_10M_SYNCPARMS & 0xff)) {
|
||||
x = 10;
|
||||
} else if (x == (ISP_08M_SYNCPARMS & 0xff)) {
|
||||
x = 8;
|
||||
} else if (x == (ISP_05M_SYNCPARMS & 0xff)) {
|
||||
x = 5;
|
||||
} else if (x == (ISP_04M_SYNCPARMS & 0xff)) {
|
||||
x = 4;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
switch (flags & (DPARM_WIDE|DPARM_TQING)) {
|
||||
case DPARM_WIDE:
|
||||
wt = ", 16 bit wide\n";
|
||||
break;
|
||||
case DPARM_TQING:
|
||||
wt = ", Tagged Queueing Enabled\n";
|
||||
break;
|
||||
case DPARM_WIDE|DPARM_TQING:
|
||||
wt = ", 16 bit wide, Tagged Queueing Enabled\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
wt = "\n";
|
||||
break;
|
||||
}
|
||||
if (x) {
|
||||
IDPRINTF(3, ("%s: Target %d maximum Sync Mode "
|
||||
"at %dMHz%s", isp->isp_name, tgt, x, wt));
|
||||
} else {
|
||||
IDPRINTF(3, ("%s: Target %d Async Mode%s",
|
||||
isp->isp_name, tgt, wt));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
flags = mbs.param[2];
|
||||
period = mbs.param[3] & 0xff;
|
||||
offset = mbs.param[3] >> 8;
|
||||
if (sdp->isp_devparam[tgt].cur_dflags != flags ||
|
||||
sdp->isp_devparam[tgt].sync_period != period ||
|
||||
sdp->isp_devparam[tgt].sync_offset != offset) {
|
||||
IDPRINTF(3, ("%s: tgt %d flags 0x%x period %d "
|
||||
"off %d\n", isp->isp_name, tgt, flags,
|
||||
period, offset));
|
||||
changed = 1;
|
||||
} else {
|
||||
changed = 0;
|
||||
}
|
||||
|
||||
sdp->isp_devparam[tgt].cur_dflags = flags;
|
||||
sdp->isp_devparam[tgt].dev_flags = flags;
|
||||
sdp->isp_devparam[tgt].sync_period = period;
|
||||
sdp->isp_devparam[tgt].sync_offset = offset;
|
||||
if (sdp->isp_devparam[tgt].dev_announced == 0 || changed) {
|
||||
if (isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &tgt))
|
||||
sdp->isp_devparam[tgt].dev_announced = 0;
|
||||
else
|
||||
sdp->isp_devparam[tgt].dev_announced = 1;
|
||||
}
|
||||
sdp->isp_devparam[tgt].dev_update = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3283,7 +3356,6 @@ isp_read_nvram(isp)
|
||||
ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
|
||||
|
||||
sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
|
||||
|
||||
#if 0
|
||||
PRINTF("%s: fifo_threshold = 0x%x cbena%d dbena%d\n",
|
||||
isp->isp_name, sdp->isp_fifo_threshold,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: isp_netbsd.c,v 1.8 1998/12/28 19:10:43 mjacob Exp $ */
|
||||
/* release_12_28_98_A */
|
||||
/* $NetBSD: isp_netbsd.c,v 1.9 1999/01/30 07:31:50 mjacob Exp $ */
|
||||
/* release_01_29_99 */
|
||||
/*
|
||||
* Platform (NetBSD) dependent common attachment code for Qlogic adapters.
|
||||
*
|
||||
@ -300,3 +300,54 @@ isp_uninit(isp)
|
||||
|
||||
ISP_IUNLOCK(isp);
|
||||
}
|
||||
|
||||
int
|
||||
isp_async(isp, cmd, arg)
|
||||
struct ispsoftc *isp;
|
||||
ispasync_t cmd;
|
||||
void *arg;
|
||||
{
|
||||
switch (cmd) {
|
||||
case ISPASYNC_NEW_TGT_PARAMS:
|
||||
if (isp->isp_type & ISP_HA_SCSI) {
|
||||
sdparam *sdp = isp->isp_param;
|
||||
char *wt;
|
||||
int ns, flags, tgt;
|
||||
|
||||
tgt = *((int *) arg);
|
||||
|
||||
flags = sdp->isp_devparam[tgt].dev_flags;
|
||||
if (flags & DPARM_SYNC) {
|
||||
ns = sdp->isp_devparam[tgt].sync_period * 4;
|
||||
} else {
|
||||
ns = 0;
|
||||
}
|
||||
switch (flags & (DPARM_WIDE|DPARM_TQING)) {
|
||||
case DPARM_WIDE:
|
||||
wt = ", 16 bit wide\n";
|
||||
break;
|
||||
case DPARM_TQING:
|
||||
wt = ", Tagged Queueing Enabled\n";
|
||||
break;
|
||||
case DPARM_WIDE|DPARM_TQING:
|
||||
wt = ", 16 bit wide, Tagged Queueing Enabled\n";
|
||||
break;
|
||||
default:
|
||||
wt = "\n";
|
||||
break;
|
||||
}
|
||||
if (ns) {
|
||||
printf("%s: Target %d at %dMHz Max Offset %d%s",
|
||||
isp->isp_name, tgt, 1000 / ns,
|
||||
sdp->isp_devparam[tgt].sync_offset, wt);
|
||||
} else {
|
||||
printf("%s: Target %d Async Mode%s",
|
||||
isp->isp_name, tgt, wt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: isp_netbsd.h,v 1.8 1999/01/10 05:04:18 mjacob Exp $ */
|
||||
/* release_12_28_98_A+ */
|
||||
/* $NetBSD: isp_netbsd.h,v 1.9 1999/01/30 07:31:50 mjacob Exp $ */
|
||||
/* release_01_29_99 */
|
||||
/*
|
||||
* NetBSD Specific definitions for the Qlogic ISP Host Adapter
|
||||
*
|
||||
@ -81,6 +81,7 @@ struct isposinfo {
|
||||
#define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x
|
||||
|
||||
#define MEMZERO bzero
|
||||
#define MEMCPY(dst, src, count) bcopy((src), (dst), (count))
|
||||
|
||||
#if defined(SCSIDEBUG)
|
||||
#define DFLT_DBLEVEL 3
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: ispmbox.h,v 1.11 1998/12/28 19:10:43 mjacob Exp $ */
|
||||
/* release_12_28_98_A */
|
||||
/* $NetBSD: ispmbox.h,v 1.12 1999/01/30 07:31:51 mjacob Exp $ */
|
||||
/* release_01_29_99 */
|
||||
/*
|
||||
* Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
|
||||
*
|
||||
@ -109,6 +109,10 @@
|
||||
#define MBOX_RETURN_BIOS_BLOCK_ADDR 0x0040
|
||||
#define MBOX_WRITE_FOUR_RAM_WORDS 0x0041
|
||||
#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
|
||||
|
||||
/* These are for the ISP2100 FC cards */
|
||||
#define MBOX_GET_LOOP_ID 0x20
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: ispreg.h,v 1.10 1998/12/28 19:10:43 mjacob Exp $ */
|
||||
/* release_12_28_98_A */
|
||||
/* $NetBSD: ispreg.h,v 1.11 1999/01/30 07:31:51 mjacob Exp $ */
|
||||
/* release_01_29_99 */
|
||||
/*
|
||||
* Machine Independent (well, as best as possible) register
|
||||
* definitions for Qlogic ISP SCSI adapters.
|
||||
@ -514,6 +514,7 @@
|
||||
#define RISC_MTR2100 RISC_BLOCK+0x30
|
||||
|
||||
#define RISC_EMB RISC_BLOCK+0x30 /* RW*: Ext Mem Boundary */
|
||||
#define DUAL_BANK 8
|
||||
#define RISC_SP RISC_BLOCK+0x32 /* RW*: Stack Pointer */
|
||||
#define RISC_HRL RISC_BLOCK+0x3e /* R *: Hardware Rev Level */
|
||||
#define HCCR RISC_BLOCK+0x40 /* RW : Host Command & Ctrl */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: ispvar.h,v 1.16 1999/01/10 05:04:46 mjacob Exp $ */
|
||||
/* release_12_28_98_A+ */
|
||||
/* $NetBSD: ispvar.h,v 1.17 1999/01/30 07:31:51 mjacob Exp $ */
|
||||
/* release_01_29_99 */
|
||||
/*
|
||||
* Soft Definitions for for Qlogic ISP SCSI adapters.
|
||||
*
|
||||
@ -51,7 +51,7 @@
|
||||
#define ISP_CORE_VERSION_MINOR 5
|
||||
|
||||
/*
|
||||
* Vector for MD code to provide specific services.
|
||||
* Vector for bus specific code to provide specific services.
|
||||
*/
|
||||
struct ispsoftc;
|
||||
struct ispmdvec {
|
||||
@ -91,7 +91,7 @@ struct ispmdvec {
|
||||
((in == out)? (qlen - 1) : ((in > out)? \
|
||||
((qlen - 1) - (in - out)) : (out - in - 1)))
|
||||
/*
|
||||
* SCSI (as opposed to FC-PH) Specific Host Adapter Parameters
|
||||
* SCSI Specific Host Adapter Parameters
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
@ -100,6 +100,7 @@ typedef struct {
|
||||
isp_cmd_dma_burst_enable: 1,
|
||||
isp_data_dma_burst_enabl: 1,
|
||||
isp_fifo_threshold : 3,
|
||||
isp_ultramode : 1,
|
||||
isp_diffmode : 1,
|
||||
isp_fast_mttr : 1,
|
||||
isp_initiator_id : 4,
|
||||
@ -112,8 +113,11 @@ typedef struct {
|
||||
u_int8_t isp_retry_count;
|
||||
u_int8_t isp_retry_delay;
|
||||
struct {
|
||||
u_int dev_update : 1,
|
||||
u_int
|
||||
dev_enable : 1,
|
||||
dev_announced : 1,
|
||||
dev_update : 1,
|
||||
dev_refresh : 1,
|
||||
exc_throttle : 7,
|
||||
sync_offset : 4,
|
||||
sync_period : 8;
|
||||
@ -272,7 +276,7 @@ struct ispsoftc {
|
||||
* jeez, so I blow a couple of KB per host adapter...
|
||||
* and it *is* faster.
|
||||
*/
|
||||
volatile ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN];
|
||||
ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN];
|
||||
|
||||
/*
|
||||
* request/result queues and dma handles for them.
|
||||
@ -340,7 +344,7 @@ struct ispsoftc {
|
||||
#define ISP_HA_FC_2100 0x10
|
||||
|
||||
/*
|
||||
* Macros to read, write ISP registers through MD code
|
||||
* Macros to read, write ISP registers through bus specific code.
|
||||
*/
|
||||
|
||||
#define ISP_READ(isp, reg) \
|
||||
@ -403,13 +407,14 @@ int isp_intr __P((void *));
|
||||
int32_t ispscsicmd __P((ISP_SCSI_XFER_T *));
|
||||
|
||||
/*
|
||||
* Platform Dependent to Internal Control Point
|
||||
* Platform Dependent to External to Internal Control Function
|
||||
*
|
||||
* For: Aborting a running command - arg is an ISP_SCSI_XFER_T *
|
||||
* Resetting a Device - arg is target to reset
|
||||
* Resetting a BUS - arg is ignored
|
||||
* Updating parameters - arg is ignored
|
||||
*
|
||||
* First argument is this instance's softc pointer.
|
||||
* Second argument is an index into xflist array.
|
||||
* Assumes all locks must be held already.
|
||||
*/
|
||||
@ -421,6 +426,21 @@ typedef enum {
|
||||
} ispctl_t;
|
||||
int isp_control __P((struct ispsoftc *, ispctl_t, void *));
|
||||
|
||||
|
||||
/*
|
||||
* Platform Dependent to Internal to External Control Function
|
||||
* (each platform must provide such a function)
|
||||
*
|
||||
* For: Announcing Target Paramter Changes (arg is target)
|
||||
*
|
||||
* Assumes all locks are held.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ISPASYNC_NEW_TGT_PARAMS
|
||||
} ispasync_t;
|
||||
int isp_async __P((struct ispsoftc *, ispasync_t, void *));
|
||||
|
||||
/*
|
||||
* lost command routine (XXXX IN TRANSITION XXXX)
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user