Add in 1080 LVD support and some basis also for the 1240. The port database

printout is now enabled.
This commit is contained in:
Matt Jacob 1999-03-25 22:52:45 +00:00
parent 7aae9d1348
commit 4394c92f52
6 changed files with 413 additions and 302 deletions

View File

@ -1,14 +1,12 @@
/* $Id: isp.c,v 1.13 1999/02/09 01:07:06 mjacob Exp $ */
/* release_03_16_99 */
/* $Id: isp.c,v 1.14 1999/03/17 05:04:38 mjacob Exp $ */
/* release_03_25_99 */
/*
* Machine and OS Independent (well, as best as possible)
* code for the Qlogic ISP SCSI adapters.
*
*---------------------------------------
* Copyright (c) 1997, 1998 by Matthew Jacob
* NASA/Ames Research Center
* All rights reserved.
*---------------------------------------
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -113,7 +111,7 @@ 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 int isp_fclink_test __P((struct ispsoftc *, int));
static void isp_fw_state __P((struct ispsoftc *));
static void isp_dumpregs __P((struct ispsoftc *, const char *));
static void isp_dumpxflist __P((struct ispsoftc *));
@ -189,11 +187,33 @@ isp_reset(isp)
if (IS_FC(isp)) {
revname = "2100";
} else if (IS_1080(isp)) {
u_int16_t l;
sdparam *sdp = isp->isp_param;
revname = "1080";
sdp->isp_clock = 0; /* don't set clock */
sdp->isp_diffmode = 1;
sdp->isp_ultramode = 1;
sdp->isp_clock = 100;
l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
switch (l) {
case ISP1080_LVD_MODE:
sdp->isp_lvdmode = 1;
PRINTF("%s: LVD Mode\n", isp->isp_name);
break;
case ISP1080_HVD_MODE:
sdp->isp_diffmode = 1;
PRINTF("%s: Differential Mode\n", isp->isp_name);
break;
case ISP1080_SE_MODE:
sdp->isp_ultramode = 1;
PRINTF("%s: Single-Ended Mode\n", isp->isp_name);
break;
default:
/*
* Hmm. Up in a wierd mode. This means all SCSI I/O
* buffer lines are tristated, so we're in a lot of
* trouble if we don't set things up right.
*/
PRINTF("%s: Illegal Mode 0x%x\n", isp->isp_name, l);
break;
}
} else {
sdparam *sdp = isp->isp_param;
i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
@ -203,7 +223,7 @@ isp_reset(isp)
isp->isp_name, i);
/* FALLTHROUGH */
case 1:
revname = "1020";
revname = "1020";
isp->isp_type = ISP_HA_SCSI_1020;
sdp->isp_clock = 40;
break;
@ -213,7 +233,7 @@ isp_reset(isp)
* run the clock rate up for that unless told to
* do so by the Ultra Capable bits being set.
*/
revname = "1020A";
revname = "1020A";
isp->isp_type = ISP_HA_SCSI_1020A;
sdp->isp_clock = 40;
break;
@ -257,7 +277,7 @@ isp_reset(isp)
* even for the SBus version.
*/
sdp->isp_clock = 60;
} else {
} else {
sdp->isp_ultramode = 0;
/*
* Clock is known. Gronk.
@ -307,9 +327,9 @@ again:
* Clear data && control DMA engines.
*/
ISP_WRITE(isp, CDMA_CONTROL,
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
ISP_WRITE(isp, DDMA_CONTROL,
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
} else {
@ -386,11 +406,11 @@ again:
}
#ifdef PTI_CARDS
if (((sdparam *) isp->isp_param)->isp_ultramode) {
while(ISP_READ(isp, RISC_MTR) != 0x1313) {
while (ISP_READ(isp, RISC_MTR) != 0x1313) {
ISP_WRITE(isp, RISC_MTR, 0x1313);
ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
}
} else {
} else {
ISP_WRITE(isp, RISC_MTR, 0x1212);
}
/*
@ -550,7 +570,7 @@ again:
PRINTF("%s: Board Revision %s, %s F/W Revision %d.%d\n",
isp->isp_name, revname, dodnld? "loaded" : "resident",
mbs.param[1], mbs.param[2]);
if (isp->isp_type & ISP_HA_FC) {
if (IS_FC(isp)) {
if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
PRINTF("%s: in 64-Bit PCI slot\n", isp->isp_name);
}
@ -590,7 +610,7 @@ isp_init(isp)
PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name);
return;
}
/*
* If we're fibre, we have a completely different
* initialization method.
@ -693,27 +713,25 @@ isp_init(isp)
/*
* It is not quite clear when this changed over so that
* we could force narrow and async, so assume >= 7.55.
*
* Otherwise, a SCSI bus reset issued below will force
* the back to the narrow, async state (but see note
* below also). Technically we should also do without
* Parity.
*/
if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) {
sdf |= DPARM_NARROW | DPARM_ASYNC;
}
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[1] = tgt << 8;
mbs.param[2] = sdf;
mbs.param[3] = 0;
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdf = DPARM_SAFE_DFLT;
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[1] = tgt << 8;
mbs.param[2] = sdf;
mbs.param[3] = 0;
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
PRINTF("%s: failed even to set defaults for "
@ -721,8 +739,26 @@ isp_init(isp)
continue;
}
}
sdp->isp_devparam[tgt].cur_dflags = sdf;
/*
* We don't update dev_flags with what we've set
* because that's not the ultimate goal setting.
* If we succeed with the command, we *do* update
* cur_dflags.
*/
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
mbs.param[1] = (tgt << 8);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
/*
* Urrr.... We'll set cur_dflags to DPARM_SAFE_DFLT so
* we don't try and do tags if tags aren't enabled.
*/
sdp->isp_devparam[tgt].cur_dflags = DPARM_SAFE_DFLT;
} else {
sdp->isp_devparam[tgt].cur_dflags = mbs.param[2];
sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8;
sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff;
}
maxlun = (isp->isp_fwrev >= ISP_FW_REV(7, 55))? 32 : 8;
for (lun = 0; lun < maxlun; lun++) {
mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
@ -770,25 +806,32 @@ isp_init(isp)
isp->isp_reqidx = isp->isp_reqodx = 0;
/*
* Turn on Fast Posting
* Turn on Fast Posting, LVD transitions
*/
#ifndef ISP_NO_FASTPOST_SCSI
if (isp->isp_fwrev >= ISP_FW_REV(7, 55)) {
if (IS_1080(isp) || 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);
#ifndef ISP_NO_FASTPOST_SCSI
mbs.param[1] |= FW_FEATURE_FAST_POST;
#else
mbs.param[1] = 0;
#endif
if (IS_1080(isp))
mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
if (mbs.param[1] != 0) {
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
PRINTF("%s: unable enable FW features\n",
isp->isp_name);
}
}
}
#endif
/*
* Let the outer layers decide whether to issue a SCSI bus reset.
*/
#if 0
/*
/*
* XXX: See whether or not for 7.55 F/W or later we
* XXX: can do without this, and see whether we should
* XXX: honor the NVRAM SCSI_RESET_DISABLE token.
@ -944,6 +987,8 @@ isp_fibre_init(isp)
isp->isp_state = ISP_INITSTATE;
fcp->isp_fwstate = FW_CONFIG_WAIT;
isp_mark_getpdb_all(isp);
#ifdef ISP_TARGET_MODE
if (isp_modify_lun(isp, 0, 1, 1)) {
PRINTF("%s: failed to enable target mode\n", isp->isp_name);
@ -975,31 +1020,19 @@ isp_getpdb(isp, id, pdbp)
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;
/*
* Unneeded. For the 2100, except for initializing f/w, registers
* 4/5 have to not be written to.
* mbs.param[4] = 0;
* mbs.param[5] = 0;
*
*/
mbs.param[6] = 0;
mbs.param[7] = 0;
isp_mboxcmd(isp, &mbs);
@ -1014,16 +1047,13 @@ isp_getpdb(isp, id, pdbp)
case MBOX_COMMAND_PARAM_ERROR:
/* Not Logged In */
IDPRINTF(3, ("%s: Comand Param Error on Get Port Database\n",
isp->isp_name));
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);
}
@ -1032,8 +1062,9 @@ isp_getpdb(isp, id, pdbp)
*/
static int
isp_fclink_test(isp)
isp_fclink_test(isp, waitdelay)
struct ispsoftc *isp;
int waitdelay;
{
mbreg_t mbs;
int count;
@ -1044,10 +1075,9 @@ isp_fclink_test(isp)
/*
* 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 < FC_FW_READY_DELAY; count += 100) {
for (count = 0; count < waitdelay; count += 100) {
isp_fw_state(isp);
if (lwfs != fcp->isp_fwstate) {
PRINTF("%s: Firmware State %s -> %s\n",
@ -1067,13 +1097,14 @@ isp_fclink_test(isp)
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);
PRINTF("%s: GET LOOP ID failed\n", isp->isp_name);
return (-1);
}
fcp->isp_loopid = mbs.param[1];
@ -1114,7 +1145,7 @@ ispscsicmd(xs)
/*
* We *could* do the different sequence type that has close
* to the whole Queue Entry for the command,...
* to the whole Queue Entry for the command...
*/
if (XS_CDBLEN(xs) > ((isp->isp_type & ISP_HA_FC)? 16 : 12)) {
@ -1137,30 +1168,18 @@ ispscsicmd(xs)
* our cached copy of it...
*/
if (fcp->isp_fwstate != FW_READY) {
if (isp_fclink_test(isp)) {
if (isp_fclink_test(isp, FC_FW_READY_DELAY)) {
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..
* Refresh our port database if needed.
*/
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 {
if (isp_getpdb(isp, XS_TGT(xs), pdbp) == 0) {
isp_async(isp, ISPASYNC_PDB_CHANGE_COMPLETE,
(void *) (long) XS_TGT(xs));
#endif
}
}
}
@ -1242,6 +1261,7 @@ ispscsicmd(xs)
* See comment in isp_intr
*/
XS_RESID(xs) = 0;
/*
* Fibre Channel always requires some kind of tag.
* If we're marked as "Can't Tag", just do simple
@ -1252,7 +1272,7 @@ ispscsicmd(xs)
if (XS_CANTAG(xs)) {
t2reqp->req_flags = XS_KINDOF_TAG(xs);
} else {
t2reqp->req_flags = REQFLAG_STAG;
t2reqp->req_flags = REQFLAG_STAG;
}
} else {
sdparam *sdp = (sdparam *)isp->isp_param;
@ -1365,7 +1385,7 @@ isp_control(isp, ctl, arg)
PRINTF("%s: driver initiated bus reset\n", isp->isp_name);
return (0);
case ISPCTL_RESET_DEV:
case ISPCTL_RESET_DEV:
mbs.param[0] = MBOX_ABORT_TARGET;
mbs.param[1] = ((long)arg) << 8;
mbs.param[2] = 3; /* 'delay', in seconds */
@ -1379,7 +1399,7 @@ isp_control(isp, ctl, arg)
isp->isp_sendmarker = 1;
return (0);
case ISPCTL_ABORT_CMD:
case ISPCTL_ABORT_CMD:
xs = (ISP_SCSI_XFER_T *) arg;
for (i = 0; i < RQUEST_QUEUE_LEN; i++) {
if (xs == isp->isp_xflist[i]) {
@ -1418,10 +1438,10 @@ isp_control(isp, ctl, arg)
case ISPCTL_UPDATE_PARAMS:
isp_update(isp);
return(0);
return (0);
case ISPCTL_FCLINK_TEST:
return (isp_fclink_test(isp));
return (isp_fclink_test(isp, FC_FW_READY_DELAY));
}
return (-1);
}
@ -1448,7 +1468,7 @@ isp_intr(arg)
if (isr == 0 || (isr & BIU2100_ISR_RISC_INT) == 0) {
if (isr) {
IDPRINTF(4, ("%s: isp_intr isr=%x\n",
isp->isp_name, isr));
isp->isp_name, isr));
}
return (0);
}
@ -1456,7 +1476,7 @@ isp_intr(arg)
if (isr == 0 || (isr & BIU_ISR_RISC_INT) == 0) {
if (isr) {
IDPRINTF(4, ("%s: isp_intr isr=%x\n",
isp->isp_name, isr));
isp->isp_name, isr));
}
return (0);
}
@ -1465,10 +1485,8 @@ isp_intr(arg)
if (ISP_READ(isp, BIU_SEMA) & 1) {
u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
if (mbox & 0x4000) {
if (mbox != MBOX_COMMAND_COMPLETE) {
PRINTF("%s: isp_intr sees 0x%x\n",
isp->isp_name,mbox);
}
IDPRINTF(3, ("%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);
@ -1476,8 +1494,7 @@ isp_intr(arg)
if (fhandle < 0) {
return (1);
} else if (fhandle > 0) {
xs = (ISP_SCSI_XFER_T *)
isp->isp_xflist[fhandle - 1];
xs = (void *)isp->isp_xflist[fhandle - 1];
isp->isp_xflist[fhandle - 1] = NULL;
/*
* Since we don't have a result queue entry
@ -1491,7 +1508,7 @@ isp_intr(arg)
}
if (isp->isp_nactive > 0)
isp->isp_nactive--;
complist[ndone++] = xs;
complist[ndone++] = xs;
}
}
}
@ -1565,7 +1582,7 @@ isp_intr(arg)
ISP_WRITE(isp, INMAILBOX5, optr);
continue;
}
xs = (ISP_SCSI_XFER_T *) isp->isp_xflist[sp->req_handle - 1];
xs = (void *) isp->isp_xflist[sp->req_handle - 1];
if (xs == NULL) {
PRINTF("%s: NULL xs in xflist (handle %x)\n",
isp->isp_name, sp->req_handle);
@ -1674,7 +1691,7 @@ isp_intr(arg)
*/
if (nlooked) {
ISP_WRITE(isp, INMAILBOX5, optr);
isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);
isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);
}
isp->isp_residx = optr;
for (i = 0; i < ndone; i++) {
@ -1765,8 +1782,37 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_BUS_TRANSIT:
PRINTF("%s: LBD->HVD Transition 0x%x\n",
isp->isp_name, ISP_READ(isp, OUTMAILBOX1));
mbox = ISP_READ(isp, OUTMAILBOX2);
switch (mbox & 0x1c00) {
case SXP_PINS_LVD_MODE:
PRINTF("%s: Transition to LVD mode\n", isp->isp_name);
((sdparam *)isp->isp_param)->isp_diffmode = 0;
((sdparam *)isp->isp_param)->isp_ultramode = 0;
((sdparam *)isp->isp_param)->isp_lvdmode = 1;
break;
case SXP_PINS_HVD_MODE:
PRINTF("%s: Transition to Differential mode\n",
isp->isp_name);
((sdparam *)isp->isp_param)->isp_diffmode = 1;
((sdparam *)isp->isp_param)->isp_ultramode = 0;
((sdparam *)isp->isp_param)->isp_lvdmode = 0;
break;
case SXP_PINS_SE_MODE:
PRINTF("%s: Transition to Single Ended mode\n",
isp->isp_name);
((sdparam *)isp->isp_param)->isp_diffmode = 0;
((sdparam *)isp->isp_param)->isp_ultramode = 1;
((sdparam *)isp->isp_param)->isp_lvdmode = 0;
break;
default:
PRINTF("%s: Transition to unknown mode 0x%x\n",
isp->isp_name, mbox);
break;
}
/*
* XXX: Set up to renegotiate again!
*/
isp->isp_sendmarker = 1;
break;
case ASYNC_CMD_CMPLT:
@ -1839,7 +1885,7 @@ isp_handle_other_response(isp, sp, optrp)
in_fcentry_t *inot_fc;
na_entry_t *nack;
na_fcentry_t *nack_fc;
void *voidp;
void *voidp;
#define atio un.atio
#define at2io un.at2io
#define ctio un.ctio
@ -1900,20 +1946,20 @@ isp_handle_other_response(isp, sp, optrp)
ptisp_got_msg(ptp, &inot);
break;
case IN_RSRC_UNAVAIL:
PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name);
break;
case IN_ABORT_TASK:
PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name);
break;
case IN_ABORT_TASK:
PRINTF("%s: Abort Task iid %d rx_id 0x%x\n",
inot_fc->in_iid, seqid);
break;
case IN_PORT_LOGOUT:
break;
case IN_PORT_LOGOUT:
PRINTF("%s: Port Logout for Initiator %d\n",
isp->isp_name, inot_fc->in_iid);
break;
default:
break;
default:
PRINTF("%s: bad status (0x%x) in Immediate Notify\n",
isp->isp_name, status);
break;
isp->isp_name, status);
break;
}
isp_notify_ack(isp, un.voidp);
@ -2001,7 +2047,7 @@ isp_handle_other_response(isp, sp, optrp)
ct2->req_m.mode0.req_scsi_status = CTIO2_STATUS_VALID;
ct2->req_seg_count = 1;
if (at2->req_cdb[0] == 0x12) {
s = sizeof(tgtiqd);
s = sizeof (tgtiqd);
MEMCPY(fcp->isp_scratch, tgtiqd, s);
} else {
s = at2->req_datalen;
@ -2073,7 +2119,7 @@ isp_handle_other_response(isp, sp, optrp)
PRINTF("%s: CTIO2 returned status 0x%x\n", isp->isp_name,
ct2->req_status);
/*
* Return the ATIO to the board.
* Return the ATIO to the board.
*/
at2 = (ispatiot2_t *) sp;
at2->req_header.rqs_entry_type = RQSTYPE_ATIO2;
@ -2274,7 +2320,7 @@ isp_handle_atio (isp, aep)
* did not set DiscPriv in the identify message. We don't care
* about this so it's ignored.
*/
switch(status & ~TGTSVALID) {
switch (status & ~TGTSVALID) {
case AT_PATH_INVALID:
/*
* ATIO rejected by the firmware due to disabled lun.
@ -2373,7 +2419,7 @@ isp_handle_atio2(isp, aep)
* why this ATIO was sent to us.
* If SenseValid is set, the firware has recommended Sense Data.
*/
switch(status & ~TGTSVALID) {
switch (status & ~TGTSVALID) {
case AT_PATH_INVALID:
/*
* ATIO rejected by the firmware due to disabled lun.
@ -2691,7 +2737,7 @@ isp_parse_status(isp, sp, xs)
default:
PRINTF("%s: comp status %x\n", isp->isp_name,
sp->req_completion_status);
sp->req_completion_status);
break;
}
XS_SETERR(xs, HBA_BOTCH);
@ -2728,7 +2774,7 @@ isp_fastpost_complete(isp, fph)
#define HINIB(x) ((x) >> 0x4)
#define LONIB(x) ((x) & 0xf)
#define MAKNIB(a, b) (((a) << 4) | (b))
#define MAKNIB(a, b) (((a) << 4) | (b))
static u_int8_t mbpcnt[] = {
MAKNIB(1, 1), /* 0x00: MBOX_NO_OP */
MAKNIB(5, 5), /* 0x01: MBOX_LOAD_RAM */
@ -2754,7 +2800,7 @@ static u_int8_t mbpcnt[] = {
MAKNIB(4, 4), /* 0x15: MBOX_ABORT */
MAKNIB(2, 2), /* 0x16: MBOX_ABORT_DEVICE */
MAKNIB(3, 3), /* 0x17: MBOX_ABORT_TARGET */
MAKNIB(2, 2), /* 0x18: MBOX_BUS_RESET */
MAKNIB(3, 1), /* 0x18: MBOX_BUS_RESET */
MAKNIB(2, 3), /* 0x19: MBOX_STOP_QUEUE */
MAKNIB(2, 3), /* 0x1a: MBOX_START_QUEUE */
MAKNIB(2, 3), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
@ -2903,14 +2949,10 @@ isp_mboxcmd(isp, mbp)
command_known:
#define NEW_MB_WAY 1
#ifdef NEW_MB_WAY
/*
* 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
@ -2963,14 +3005,39 @@ command_known:
}
}
/*
* If we're a 1080 or a 1240, make sure that for a couple of commands
* the port parameter is set. This is sort of a temporary solution
* to do it here rather than every place a mailbox command is formed.
*/
if (IS_1080(isp) || IS_12X0(isp)) {
switch (mbp->param[0]) {
case MBOX_BUS_RESET:
mbp->param[2] = isp->isp_port;
break;
default:
break;
}
}
/*
* Write input parameters.
*/
switch (inparam) {
case 8: ISP_WRITE(isp, INMAILBOX7, mbp->param[7]); mbp->param[7] = 0;
case 7: ISP_WRITE(isp, INMAILBOX6, mbp->param[6]); mbp->param[6] = 0;
case 6: ISP_WRITE(isp, INMAILBOX5, mbp->param[5]); mbp->param[5] = 0;
case 5: ISP_WRITE(isp, INMAILBOX4, mbp->param[4]); mbp->param[4] = 0;
case 6:
/*
* The Qlogic 2100 cannot have registers 4 and 5 written to
* after initialization or BAD THINGS HAPPEN (tm).
*/
if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE)
ISP_WRITE(isp, INMAILBOX5, mbp->param[5]);
mbp->param[5] = 0;
case 5:
if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE)
ISP_WRITE(isp, INMAILBOX4, mbp->param[4]);
mbp->param[4] = 0;
case 4: ISP_WRITE(isp, INMAILBOX3, mbp->param[3]); mbp->param[3] = 0;
case 3: ISP_WRITE(isp, INMAILBOX2, mbp->param[2]); mbp->param[2] = 0;
case 2: ISP_WRITE(isp, INMAILBOX1, mbp->param[1]); mbp->param[1] = 0;
@ -2994,40 +3061,6 @@ command_known:
*/
ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
#ifndef NEW_MB_WAY
/*
* Wait until RISC int is set, except 2100
*/
if ((isp->isp_type & ISP_HA_FC) == 0) {
loops = MBOX_DELAY_COUNT;
while ((ISP_READ(isp, BIU_ISR) & BIU_ISR_RISC_INT) == 0) {
SYS_DELAY(100);
if (--loops < 0) {
PRINTF("%s: isp_mboxcmd timeout #2\n",
isp->isp_name);
return;
}
}
}
/*
* Check to make sure that the semaphore has been set.
*/
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.
@ -3059,7 +3092,6 @@ command_known:
return;
}
}
#endif
/*
* Make sure that the MBOX_BUSY has gone away
@ -3121,7 +3153,7 @@ command_known:
/*
* Just to be chatty here...
*/
switch(mbp->param[0]) {
switch (mbp->param[0]) {
case MBOX_COMMAND_COMPLETE:
break;
case MBOX_INVALID_COMMAND:
@ -3194,7 +3226,7 @@ isp_lostcmd(isp, xs)
}
if (mbs.param[1]) {
PRINTF("%s: %d commands on completion queue\n",
isp->isp_name, mbs.param[1]);
isp->isp_name, mbs.param[1]);
}
if (XS_NULL(xs))
return;
@ -3227,7 +3259,7 @@ isp_dumpregs(isp, msg)
else
PRINTF(" biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
PRINTF(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR),
ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
PRINTF("risc_hccr=%x\n", ISP_READ(isp, HCCR));
@ -3329,6 +3361,12 @@ isp_update(isp)
continue;
}
/*
* If the goal is to update the status of the device,
* take what's in dev_flags and try and set the device
* toward that. Otherwise, if we're just refreshing the
* current device state, get the current parameters.
*/
if (sdp->isp_devparam[tgt].dev_update) {
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
@ -3336,8 +3374,20 @@ isp_update(isp)
(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;
/*
* A command completion later that has
* RQSTF_NEGOTIATION set will cause
* the dev_refresh/announce cycle.
*
* Note: It is really important to update our current
* flags with at least the state of TAG capabilities-
* otherwise we might try and send a tagged command
* when we have it all turned off. So change it here
* to say that current already matches goal.
*/
sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
sdp->isp_devparam[tgt].cur_dflags |=
(sdp->isp_devparam[tgt].dev_flags & DPARM_TQING);
get = 0;
} else if (sdp->isp_devparam[tgt].dev_refresh) {
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
@ -3360,16 +3410,14 @@ isp_update(isp)
* XXX: Need a SYNC_TARGET for efficiency...
*/
isp->isp_sendmarker = 1;
sdp->isp_devparam[tgt].cur_dflags =
sdp->isp_devparam[tgt].dev_flags;
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) {
sdp->isp_devparam[tgt].cur_period != period ||
sdp->isp_devparam[tgt].cur_offset != offset) {
IDPRINTF(3, ("%s: tgt %d flags 0x%x period %d "
"off %d\n", isp->isp_name, tgt, flags,
period, offset));
@ -3377,11 +3425,9 @@ isp_update(isp)
} 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;
sdp->isp_devparam[tgt].cur_period = period;
sdp->isp_devparam[tgt].cur_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;
@ -3395,7 +3441,7 @@ static void
isp_setdfltparm(isp)
struct ispsoftc *isp;
{
int i;
int tgt;
mbreg_t mbs;
sdparam *sdp;
@ -3408,9 +3454,17 @@ isp_setdfltparm(isp)
}
isp->isp_gotdparms = 1;
if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0 &&
(isp_read_nvram(isp) == 0)) {
return;
/*
* If we've not been told to avoid reading NVRAM, try and read it.
* If we're successful reading it, we can return since NVRAM will
* tell us the right thing to do. Otherwise, establish some reasonable
* defaults.
*/
if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
if (isp_read_nvram(isp) == 0) {
return;
}
}
if (IS_FC(isp)) {
fcparam *fcp = (fcparam *) isp->isp_param;
@ -3441,19 +3495,32 @@ isp_setdfltparm(isp)
sdp->isp_data_line_active_neg = (mbs.param[1] >> 5) & 0x1;
}
for (i = 0; i < MAX_TARGETS; i++) {
sdp->isp_devparam[i].dev_flags = DPARM_DEFAULT;
sdp->isp_devparam[i].cur_dflags = DPARM_SAFE_DFLT;
/*
* The trick here is to establish a default for the default (honk!)
* state (dev_flags). Then try and get the current status from
* the card to fill in the current state. We don't, in fact, set
* the default to the SAFE default state- that's not the goal state.
*/
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
sdp->isp_devparam[tgt].cur_offset = 0;
sdp->isp_devparam[tgt].cur_period = 0;
sdp->isp_devparam[tgt].dev_flags = DPARM_DEFAULT;
sdp->isp_devparam[tgt].cur_dflags = 0;
if (isp->isp_type < ISP_HA_SCSI_1040 ||
(sdp->isp_clock && sdp->isp_clock < 60)) {
sdp->isp_devparam[i].sync_offset =
sdp->isp_devparam[tgt].sync_offset =
ISP_10M_SYNCPARMS >> 8;
sdp->isp_devparam[i].sync_period =
sdp->isp_devparam[tgt].sync_period =
ISP_10M_SYNCPARMS & 0xff;
} else if (IS_1080(isp)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_40M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_40M_SYNCPARMS & 0xff;
} else {
sdp->isp_devparam[i].sync_offset =
sdp->isp_devparam[tgt].sync_offset =
ISP_20M_SYNCPARMS >> 8;
sdp->isp_devparam[i].sync_period =
sdp->isp_devparam[tgt].sync_period =
ISP_20M_SYNCPARMS & 0xff;
}
@ -3461,29 +3528,33 @@ isp_setdfltparm(isp)
* Don't get current target parameters if we've been
* told not to use NVRAM- it's really the same thing.
*/
if (isp->isp_confopts & ISP_CFG_NONVRAM)
if (isp->isp_confopts & ISP_CFG_NONVRAM) {
continue;
}
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
mbs.param[1] = i << 8;
mbs.param[1] = tgt << 8;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
continue;
}
sdp->isp_devparam[i].dev_flags = mbs.param[2];
sdp->isp_devparam[tgt].cur_dflags = mbs.param[2];
sdp->isp_devparam[tgt].dev_flags = mbs.param[2];
sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff;
sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8;
/*
* The maximum period we can really see
* here is 100 (decimal), or 400 ns.
* For some unknown reason we sometimes
* get back wildass numbers from the
* boot device's parameters.
*
* XXX: Hmm- this may be based on a different
* XXX: clock rate.
* boot device's parameters (alpha only).
*/
if ((mbs.param[3] & 0xff) <= 0x64) {
sdp->isp_devparam[i].sync_period = mbs.param[3] & 0xff;
sdp->isp_devparam[i].sync_offset = mbs.param[3] >> 8;
sdp->isp_devparam[tgt].sync_period =
mbs.param[3] & 0xff;
sdp->isp_devparam[tgt].sync_offset =
mbs.param[3] >> 8;
}
/*
@ -3491,11 +3562,11 @@ isp_setdfltparm(isp)
*/
if (((sdp->isp_clock && sdp->isp_clock < 60) ||
(isp->isp_type < ISP_HA_SCSI_1020A)) &&
(sdp->isp_devparam[i].sync_period ==
(sdp->isp_devparam[tgt].sync_period <=
(ISP_20M_SYNCPARMS & 0xff))) {
sdp->isp_devparam[i].sync_offset =
sdp->isp_devparam[tgt].sync_offset =
ISP_10M_SYNCPARMS >> 8;
sdp->isp_devparam[i].sync_period =
sdp->isp_devparam[tgt].sync_period =
ISP_10M_SYNCPARMS & 0xff;
}
}
@ -3519,13 +3590,13 @@ isp_setdfltparm(isp)
sdp->isp_retry_count = 0;
sdp->isp_retry_delay = 1;
for (i = 0; i < MAX_TARGETS; i++) {
sdp->isp_devparam[i].exc_throttle = 16;
sdp->isp_devparam[i].dev_enable = 1;
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
sdp->isp_devparam[tgt].exc_throttle = 16;
sdp->isp_devparam[tgt].dev_enable = 1;
}
}
/*
/*
* Re-initialize the ISP and complete all orphaned commands
* with a 'botched' notice.
*
@ -3653,7 +3724,7 @@ isp_read_nvram(isp)
sdp->isp_async_data_setup = 6;
}
}
sdp->isp_req_ack_active_neg =
ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
@ -3757,6 +3828,7 @@ isp_read_nvram(isp)
sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
if (ISP_NVRAM_TGT_DISC(nvram_data, i))
sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */
if (isp->isp_dblev > 2) {
PRINTF(" Target %d: Enabled %d Throttle %d "
"Offset %d Period %d Flags 0x%x\n", i,

View File

@ -1,5 +1,5 @@
/* $Id: isp_freebsd.c,v 1.12 1999/02/09 01:08:38 mjacob Exp $ */
/* release_03_16_99 */
/* $Id: isp_freebsd.c,v 1.13 1999/03/17 05:04:38 mjacob Exp $ */
/* release_03_25_99 */
/*
* Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
*
@ -329,7 +329,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
/*
* Note that these operations affect the
* the permanent flags (dev_flags)- not
* the goal flags (dev_flags)- not
* the current state flags. Then we mark
* things so that the next operation to
* this HBA will cause the update to occur.
@ -371,8 +371,10 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
} else {
*dptr &= ~DPARM_SYNC;
}
IDPRINTF(3, ("%s: set target %d period %d offset %d "
"dev_flags 0x%x\n", isp->isp_name, tgt,
IDPRINTF(3, ("%s: %d set %s period 0x%x offset 0x%x"
" flags 0x%x\n", isp->isp_name, tgt,
(cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
"current" : "user",
sdp->isp_devparam[tgt].sync_period,
sdp->isp_devparam[tgt].sync_offset,
sdp->isp_devparam[tgt].dev_flags));
@ -407,12 +409,17 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
} else {
sdparam *sdp = isp->isp_param;
u_int16_t dval;
u_int16_t dval, pval, oval;
if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) {
dval = sdp->isp_devparam[tgt].cur_dflags;
else
oval = sdp->isp_devparam[tgt].cur_offset;
pval = sdp->isp_devparam[tgt].cur_period;
} else {
dval = sdp->isp_devparam[tgt].dev_flags;
oval = sdp->isp_devparam[tgt].sync_offset;
pval = sdp->isp_devparam[tgt].sync_period;
}
s = splcam();
cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
@ -431,17 +438,18 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
if ((dval & DPARM_SYNC) &&
(sdp->isp_devparam[tgt].sync_offset)) {
cts->sync_period =
sdp->isp_devparam[tgt].sync_period;
cts->sync_offset =
sdp->isp_devparam[tgt].sync_offset;
if ((dval & DPARM_SYNC) && oval != 0) {
cts->sync_period = pval;
cts->sync_offset = oval;
cts->valid |=
CCB_TRANS_SYNC_RATE_VALID |
CCB_TRANS_SYNC_OFFSET_VALID;
}
splx(s);
IDPRINTF(3, ("%s: %d get %s period 0x%x offset 0x%x"
" flags 0x%x\n", isp->isp_name, tgt,
(cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
"current" : "user", pval, oval, dval));
}
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
@ -503,9 +511,9 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
cpi->version_num = 1;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
cpi->target_sprt = 0;
cpi->hba_misc = 0;
cpi->hba_eng_cnt = 0;
if (isp->isp_type & ISP_HA_FC) {
if (IS_FC(isp)) {
cpi->hba_misc = PIM_NOBUSRESET;
cpi->max_target = MAX_FC_TARG-1;
cpi->initiator_id =
((fcparam *)isp->isp_param)->isp_loopid;
@ -515,6 +523,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
cpi->max_lun = (1 << 4) - 1;
#endif
} else {
cpi->hba_misc = 0;
cpi->initiator_id =
((sdparam *)isp->isp_param)->isp_initiator_id;
cpi->max_target = MAX_TARGETS-1;
@ -612,7 +621,7 @@ isp_async(isp, cmd, arg)
break;
}
flags = sdp->isp_devparam[tgt].dev_flags;
flags = sdp->isp_devparam[tgt].cur_dflags;
neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
if (flags & DPARM_DISC) {
neg.flags |= CCB_TRANS_DISC_ENB;
@ -623,14 +632,15 @@ isp_async(isp, cmd, arg)
neg.valid |= CCB_TRANS_BUS_WIDTH_VALID;
neg.bus_width = (flags & DPARM_WIDE)?
MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
neg.sync_period = sdp->isp_devparam[tgt].sync_period;
neg.sync_offset = sdp->isp_devparam[tgt].sync_offset;
neg.sync_period = sdp->isp_devparam[tgt].cur_period;
neg.sync_offset = sdp->isp_devparam[tgt].cur_offset;
if (flags & DPARM_SYNC) {
neg.valid |= CCB_TRANS_SYNC_RATE_VALID |
CCB_TRANS_SYNC_OFFSET_VALID;
neg.valid |=
CCB_TRANS_SYNC_RATE_VALID |
CCB_TRANS_SYNC_OFFSET_VALID;
}
IDPRINTF(3, ("%s: new params target %d period %d "
"offset %d flags 0x%x\n", isp->isp_name, tgt,
IDPRINTF(3, ("%s: New params tgt %d period 0x%x "
"offset 0x%x flags 0x%x\n", isp->isp_name, tgt,
neg.sync_period, neg.sync_offset, flags));
xpt_setup_ccb(&neg.ccb_h, tmppath, 1);
xpt_async(AC_TRANSFER_NEG, tmppath, &neg);
@ -676,55 +686,48 @@ isp_async(isp, cmd, arg)
}
break;
case ISPASYNC_PDB_CHANGE_COMPLETE:
if (isp->isp_type & ISP_HA_FC) {
int i;
if (IS_FC(isp)) {
long i = (long) arg;
static char *roles[4] = {
"No", "Target", "Initiator", "Target/Initiator"
};
for (i = 0; i < MAX_FC_TARG; i++) {
isp_pdb_t *pdbp =
&((fcparam *)isp->isp_param)->isp_pdb[i];
if (pdbp->pdb_options == INVALID_PDB_OPTIONS)
continue;
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"
isp_pdb_t *pdbp = &((fcparam *)isp->isp_param)->isp_pdb[i];
if (pdbp->pdb_options == INVALID_PDB_OPTIONS) {
break;
}
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_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;
}
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;
}
@ -945,15 +948,34 @@ isp_async(isp, cmd, arg)
if (isp->isp_type & ISP_HA_SCSI) {
sdparam *sdp = isp->isp_param;
char *wt;
int ns, flags, tgt;
int mhz, flags, tgt, period;
tgt = *((int *) arg);
flags = sdp->isp_devparam[tgt].dev_flags;
if (flags & DPARM_SYNC) {
ns = sdp->isp_devparam[tgt].sync_period * 4;
flags = sdp->isp_devparam[tgt].cur_dflags;
period = sdp->isp_devparam[tgt].cur_period;
if ((flags & DPARM_SYNC) && period &&
(sdp->isp_devparam[tgt].cur_offset) != 0) {
if (sdp->isp_lvdmode) {
switch (period) {
case 0xa:
mhz = 40;
break;
case 0xb:
mhz = 33;
break;
case 0xc:
mhz = 25;
break;
default:
mhz = 1000 / (period * 4);
break;
}
} else {
mhz = 1000 / (period * 4);
}
} else {
ns = 0;
mhz = 0;
}
switch (flags & (DPARM_WIDE|DPARM_TQING)) {
case DPARM_WIDE:
@ -969,10 +991,10 @@ isp_async(isp, cmd, arg)
wt = "\n";
break;
}
if (ns) {
if (mhz) {
printf("%s: Target %d at %dMHz Max Offset %d%s",
isp->isp_name, tgt, 1000 / ns,
sdp->isp_devparam[tgt].sync_offset, wt);
isp->isp_name, tgt, mhz,
sdp->isp_devparam[tgt].cur_offset, wt);
} else {
printf("%s: Target %d Async Mode%s",
isp->isp_name, tgt, wt);

View File

@ -1,5 +1,5 @@
/* $Id: isp_freebsd.h,v 1.11 1999/02/09 01:05:42 mjacob Exp $ */
/* release_03_16_99 */
/* $Id: isp_freebsd.h,v 1.12 1999/03/17 05:04:39 mjacob Exp $ */
/* release_03_25_99 */
/*
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (non CAM version)
*---------------------------------------
@ -36,7 +36,7 @@
#define _ISP_FREEBSD_H
#define ISP_PLATFORM_VERSION_MAJOR 0
#define ISP_PLATFORM_VERSION_MINOR 98
#define ISP_PLATFORM_VERSION_MINOR 99
#include <sys/param.h>
@ -90,8 +90,8 @@ struct isposinfo {
#define XS_NULL(xs) xs == NULL || xs->sc_link == NULL
#define XS_ISP(xs) \
((struct ispsoftc *) (xs)->sc_link->adapter_softc)
#define XS_LUN(xs) (xs)->sc_link->lun
#define XS_TGT(xs) (xs)->sc_link->target
#define XS_LUN(xs) ((int) (xs)->sc_link->lun)
#define XS_TGT(xs) ((int) (xs)->sc_link->target)
#define XS_RESID(xs) (xs)->resid
#define XS_XFRLEN(xs) (xs)->datalen
#define XS_CDBLEN(xs) (xs)->cmdlen
@ -267,6 +267,5 @@ static __inline const char *isp2100_pdb_statename(int pdb_state)
#define ISP_NO_FASTPOST_SCSI 1
#define ISP_NO_FASTPOST_FC 1
#define ISP_DISABLE_1080_SUPPORT 1
#endif /* _ISP_FREEBSD_H */

View File

@ -1,5 +1,5 @@
/* $Id: isp_freebsd_cam.h,v 1.14 1999/02/09 01:09:03 mjacob Exp $ */
/* release_03_16_99 */
/* $Id: isp_freebsd_cam.h,v 1.15 1999/03/17 05:04:39 mjacob Exp $ */
/* release_03_25_99 */
/*
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (CAM version)
*---------------------------------------

View File

@ -1,14 +1,13 @@
/* $Id: ispreg.h,v 1.6 1999/02/09 01:09:35 mjacob Exp $ */
/* release_03_16_99 */
/* $Id: ispreg.h,v 1.7 1999/03/17 05:04:39 mjacob Exp $ */
/* release_03_25_99 */
/*
* Machine Independent (well, as best as possible) register
* definitions for Qlogic ISP SCSI adapters.
*
*---------------------------------------
* Copyright (c) 1997 by Matthew Jacob
* Copyright (c) 1997, 1998, 1999 by Matthew Jacob
* NASA/Ames Research Center
* All rights reserved.
*---------------------------------------
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -159,7 +158,7 @@
#define BIU_PCI1080_CONF1_SXP 0x0100 /* SXP bank select */
#define BIU_PCI1080_CONF1_DMA 0x0300 /* DMA bank select */
/* ISP2100 Bus Control/Status Register */
/* ISP2100 Bus Control/Status Register */
#define BIU2100_ICSR_REGBSEL 0x30 /* RW: register bank select */
#define BIU2100_RISC_REGS (0 << 4) /* RISC Regs */
@ -503,6 +502,18 @@
#define SXP_PINS_DIFF_TARGET 0x0002 /* Enable SXP target mode */
#define SXP_PINS_DIFF_INITIATOR 0x0001 /* Enable SXP initiator mode */
/* 1080 only */
#define SXP_PINS_LVD_MODE 0x1000
#define SXP_PINS_HVD_MODE 0x0800
#define SXP_PINS_SE_MODE 0x0400
/* The above have to be put together with the DIFFM pin to make sense */
#define ISP1080_LVD_MODE (SXP_PINS_LVD_MODE)
#define ISP1080_HVD_MODE (SXP_PINS_HVD_MODE|SXP_PINS_DIFF_MODE)
#define ISP1080_SE_MODE (SXP_PINS_SE_MODE)
#define ISP1080_MODE_MASK \
(SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE|SXP_PINS_DIFF_MODE)
/*
* RISC and Host Command and Control Block Register Offsets
*/
@ -604,8 +615,8 @@
*/
#define ISP_NVRAM_SIZE 128
#define ISPBSMX(c, byte, shift, mask) \
#define ISPBSMX(c, byte, shift, mask) \
(((c)[(byte)] >> (shift)) & (mask))
#define ISP_NVRAM_VERSION(c) (c)[4]
@ -677,7 +688,7 @@
#define ISP2100_NVRAM_RETRY_COUNT(c) (c)[16]
#define ISP2100_NVRAM_RETRY_DELAY(c) (c)[17]
#define ISP2100_NVRAM_NODE_NAME(c) ( \
#define ISP2100_NVRAM_NODE_NAME(c) (\
(((u_int64_t)(c)[18]) << 56) | \
(((u_int64_t)(c)[19]) << 48) | \
(((u_int64_t)(c)[20]) << 40) | \
@ -696,7 +707,7 @@
#define ISP2100_NVRAM_DISABLE_CODELOAD(c) ISPBSMX(c, 70, 4, 0x01)
#define ISP2100_NVRAM_SET_CACHELINESZ(c) ISPBSMX(c, 70, 5, 0x01)
#define ISP2100_NVRAM_BOOT_NODE_NAME(c) ( \
#define ISP2100_NVRAM_BOOT_NODE_NAME(c) (\
(((u_int64_t)(c)[72]) << 56) | \
(((u_int64_t)(c)[73]) << 48) | \
(((u_int64_t)(c)[74]) << 40) | \

View File

@ -1,5 +1,5 @@
/* $Id: ispvar.h,v 1.10 1999/02/09 01:11:35 mjacob Exp $ */
/* release_03_16_99 */
/* $Id: ispvar.h,v 1.11 1999/03/17 05:04:39 mjacob Exp $ */
/* release_03_25_99 */
/*
* Soft Definitions for for Qlogic ISP SCSI adapters.
*
@ -48,7 +48,7 @@
#endif
#define ISP_CORE_VERSION_MAJOR 1
#define ISP_CORE_VERSION_MINOR 6
#define ISP_CORE_VERSION_MINOR 7
/*
* Vector for bus specific code to provide specific services.
@ -106,6 +106,7 @@ typedef struct {
isp_fifo_threshold : 3,
isp_ultramode : 1,
isp_diffmode : 1,
isp_lvdmode : 1,
isp_fast_mttr : 1,
isp_initiator_id : 4,
isp_async_data_setup : 4;
@ -122,11 +123,13 @@ typedef struct {
dev_announced : 1,
dev_update : 1,
dev_refresh : 1,
exc_throttle : 7,
sync_offset : 4,
sync_period : 8;
u_int16_t dev_flags; /* persistent device flags */
u_int16_t cur_dflags; /* current device flags */
exc_throttle : 8,
cur_offset : 4,
sync_offset : 4;
u_int8_t cur_period; /* current sync period */
u_int8_t sync_period; /* goal sync period */
u_int16_t dev_flags; /* goal device flags */
u_int16_t cur_dflags; /* current device flags */
} isp_devparam[MAX_TARGETS];
} sdparam; /* scsi device parameters */
@ -147,6 +150,8 @@ typedef struct {
#define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
/* technically, not really correct, as they need to be rated based upon clock */
#define ISP_40M_SYNCPARMS 0x080a
#define ISP_20M_SYNCPARMS 0x080c
#define ISP_10M_SYNCPARMS 0x0c19
#define ISP_08M_SYNCPARMS 0x0c25
@ -246,7 +251,7 @@ struct ispsoftc {
u_int : 8,
isp_confopts : 8,
: 1,
isp_port : 1, /* for dual ported impls */
isp_used : 1,
isp_dblev : 3,
isp_gotdparms : 1,
@ -351,12 +356,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_SCSI_1080 0xd
#define ISP_HA_SCSI_12X0 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_12X0(isp) (isp->isp_type == ISP_HA_SCSI_12X0)
#define IS_FC(isp) (isp->isp_type & ISP_HA_FC)
/*