Add 4Gb (24XX) support and lay the foundation for a lot of new stuff.
This commit is contained in:
parent
6576695766
commit
10365e5a68
4920
sys/dev/isp/isp.c
4920
sys/dev/isp/isp.c
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,9 @@ __FBSDID("$FreeBSD$");
|
||||
MODULE_VERSION(isp, 1);
|
||||
MODULE_DEPEND(isp, cam, 1, 1, 1);
|
||||
int isp_announced = 0;
|
||||
int isp_fabric_hysteresis = 5;
|
||||
int isp_loop_down_limit = 300; /* default loop down limit */
|
||||
int isp_quickboot_time = 5; /* don't wait more than N secs for loop up */
|
||||
|
||||
static d_ioctl_t ispioctl;
|
||||
static void isp_intr_enable(void *);
|
||||
@ -242,7 +245,7 @@ isp_attach(ispsoftc_t *isp)
|
||||
|
||||
if (isp->isp_role != ISP_ROLE_NONE) {
|
||||
isp->isp_state = ISP_RUNSTATE;
|
||||
ENABLE_INTS(isp);
|
||||
ISP_ENABLE_INTS(isp);
|
||||
}
|
||||
if (isplist == NULL) {
|
||||
isplist = isp;
|
||||
@ -387,7 +390,7 @@ ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
|
||||
case ISP_FC_GETDINFO:
|
||||
{
|
||||
struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
|
||||
struct lportdb *lp;
|
||||
fcportdb_t *lp;
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
break;
|
||||
@ -398,9 +401,9 @@ ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
|
||||
}
|
||||
ISP_LOCK(isp);
|
||||
lp = &FCPARAM(isp)->portdb[ifc->loopid];
|
||||
if (lp->valid) {
|
||||
if (lp->state == FC_PORTDB_STATE_VALID) {
|
||||
ifc->role = lp->roles;
|
||||
ifc->loopid = lp->loopid;
|
||||
ifc->loopid = lp->handle;
|
||||
ifc->portid = lp->portid;
|
||||
ifc->node_wwn = lp->node_wwn;
|
||||
ifc->port_wwn = lp->port_wwn;
|
||||
@ -566,7 +569,7 @@ ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
|
||||
memset(&mbs, 0, sizeof (mbs));
|
||||
needmarker = retval = 0;
|
||||
loopid = fct->loopid;
|
||||
if (IS_2KLOGIN(isp) == 0) {
|
||||
if (FCPARAM(isp)->isp_2klogin == 0) {
|
||||
loopid <<= 8;
|
||||
}
|
||||
switch (fct->action) {
|
||||
@ -657,10 +660,7 @@ isp_intr_enable(void *arg)
|
||||
{
|
||||
ispsoftc_t *isp = arg;
|
||||
if (isp->isp_role != ISP_ROLE_NONE) {
|
||||
ENABLE_INTS(isp);
|
||||
#if 0
|
||||
isp->isp_osinfo.intsok = 1;
|
||||
#endif
|
||||
ISP_ENABLE_INTS(isp);
|
||||
}
|
||||
/* Release our hook so that the boot can continue. */
|
||||
config_intrhook_disestablish(&isp->isp_osinfo.ehook);
|
||||
@ -911,7 +911,7 @@ isp_en_lun(ispsoftc_t *isp, union ccb *ccb)
|
||||
/*
|
||||
* This is as a good a place as any to check f/w capabilities.
|
||||
*/
|
||||
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) == 0) {
|
||||
if (FCPARAM(isp)->isp_tmode == 0) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"firmware does not support target mode");
|
||||
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
|
||||
@ -921,9 +921,8 @@ isp_en_lun(ispsoftc_t *isp, union ccb *ccb)
|
||||
* XXX: We *could* handle non-SCCLUN f/w, but we'd have to
|
||||
* XXX: dorks with our already fragile enable/disable code.
|
||||
*/
|
||||
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"firmware not SCCLUN capable");
|
||||
if (FCPARAM(isp)->isp_sccfw == 0) {
|
||||
isp_prt(isp, ISP_LOGERR, "firmware not SCCLUN capable");
|
||||
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
|
||||
return (-1);
|
||||
}
|
||||
@ -1280,8 +1279,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
|
||||
{
|
||||
void *qe;
|
||||
struct ccb_scsiio *cso = &ccb->csio;
|
||||
uint16_t *hp, save_handle;
|
||||
uint16_t nxti, optr;
|
||||
uint32_t nxti, optr, handle;
|
||||
uint8_t local[QENTRY_LEN];
|
||||
|
||||
|
||||
@ -1303,11 +1301,11 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
|
||||
|
||||
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
|
||||
cto->ct_header.rqs_entry_count = 1;
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
|
||||
} else {
|
||||
cto->ct_iid = cso->init_id;
|
||||
if (!(FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)) {
|
||||
if (FCPARAM(isp)->isp_sccfw == 0) {
|
||||
cto->ct_lun = ccb->ccb_h.target_lun;
|
||||
}
|
||||
}
|
||||
@ -1386,7 +1384,6 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
|
||||
atp->state = ATPD_STATE_CTIO;
|
||||
}
|
||||
cto->ct_timeout = 10;
|
||||
hp = &cto->ct_syshandle;
|
||||
} else {
|
||||
ct_entry_t *cto = (ct_entry_t *) local;
|
||||
|
||||
@ -1422,10 +1419,9 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
|
||||
}
|
||||
ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
|
||||
cto->ct_timeout = 10;
|
||||
hp = &cto->ct_syshandle;
|
||||
}
|
||||
|
||||
if (isp_save_xs_tgt(isp, ccb, hp)) {
|
||||
if (isp_save_xs_tgt(isp, ccb, &handle)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
printf("No XFLIST pointers for isp_target_start_ctio\n");
|
||||
XS_SETERR(ccb, CAM_REQUEUE_REQ);
|
||||
@ -1442,7 +1438,13 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
|
||||
* format.
|
||||
*/
|
||||
|
||||
save_handle = *hp;
|
||||
if (IS_FC(isp)) {
|
||||
ct2_entry_t *cto = (ct2_entry_t *) local;
|
||||
cto->ct_syshandle = handle;
|
||||
} else {
|
||||
ct_entry_t *cto = (ct_entry_t *) local;
|
||||
cto->ct_syshandle = handle;
|
||||
}
|
||||
|
||||
switch (ISP_DMASETUP(isp, cso, (ispreq_t *) local, &nxti, optr)) {
|
||||
case CMD_QUEUED:
|
||||
@ -1457,7 +1459,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
isp_destroy_tgt_handle(isp, save_handle);
|
||||
isp_destroy_tgt_handle(isp, handle);
|
||||
|
||||
out:
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
@ -1478,7 +1480,7 @@ isp_target_putback_atio(union ccb *ccb)
|
||||
{
|
||||
ispsoftc_t *isp;
|
||||
struct ccb_scsiio *cso;
|
||||
uint16_t nxti, optr;
|
||||
uint32_t nxti, optr;
|
||||
void *qe;
|
||||
|
||||
isp = XS_ISP(ccb);
|
||||
@ -1496,7 +1498,7 @@ isp_target_putback_atio(union ccb *ccb)
|
||||
MEMZERO(at, sizeof (at2_entry_t));
|
||||
at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
|
||||
at->at_header.rqs_entry_count = 1;
|
||||
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
|
||||
if (FCPARAM(isp)->isp_sccfw) {
|
||||
at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
|
||||
} else {
|
||||
at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
|
||||
@ -1685,7 +1687,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
|
||||
if (FCPARAM(isp)->isp_sccfw) {
|
||||
lun = aep->at_scclun;
|
||||
} else {
|
||||
lun = aep->at_lun;
|
||||
@ -1731,8 +1733,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
|
||||
lun, tptr->atio_count);
|
||||
|
||||
if (tptr == &isp->isp_osinfo.tsdflt[0]) {
|
||||
atiop->ccb_h.target_id =
|
||||
((fcparam *)isp->isp_param)->isp_loopid;
|
||||
atiop->ccb_h.target_id = FCPARAM(isp)->isp_loopid;
|
||||
atiop->ccb_h.target_lun = lun;
|
||||
}
|
||||
/*
|
||||
@ -2004,7 +2005,8 @@ static void
|
||||
isp_poll(struct cam_sim *sim)
|
||||
{
|
||||
ispsoftc_t *isp = cam_sim_softc(sim);
|
||||
uint16_t isr, sema, mbox;
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
|
||||
ISP_LOCK(isp);
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
|
||||
@ -2020,7 +2022,6 @@ isp_watchdog(void *arg)
|
||||
XS_T *xs = arg;
|
||||
ispsoftc_t *isp = XS_ISP(xs);
|
||||
uint32_t handle;
|
||||
int iok;
|
||||
|
||||
/*
|
||||
* We've decided this command is dead. Make sure we're not trying
|
||||
@ -2028,11 +2029,10 @@ isp_watchdog(void *arg)
|
||||
* and seeing whether it's still alive.
|
||||
*/
|
||||
ISP_LOCK(isp);
|
||||
iok = isp->isp_osinfo.intsok;
|
||||
isp->isp_osinfo.intsok = 0;
|
||||
handle = isp_find_handle(isp, xs);
|
||||
if (handle) {
|
||||
uint16_t isr, sema, mbox;
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
|
||||
if (XS_CMD_DONE_P(xs)) {
|
||||
isp_prt(isp, ISP_LOGDEBUG1,
|
||||
@ -2077,28 +2077,14 @@ isp_watchdog(void *arg)
|
||||
XS_CMD_C_WDOG(xs);
|
||||
isp_done(xs);
|
||||
} else {
|
||||
uint16_t nxti, optr;
|
||||
ispreq_t local, *mp= &local, *qe;
|
||||
|
||||
XS_CMD_C_WDOG(xs);
|
||||
xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz);
|
||||
if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) {
|
||||
ISP_UNLOCK(isp);
|
||||
return;
|
||||
}
|
||||
XS_CMD_S_GRACE(xs);
|
||||
MEMZERO((void *) mp, sizeof (*mp));
|
||||
mp->req_header.rqs_entry_count = 1;
|
||||
mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
|
||||
mp->req_modifier = SYNC_ALL;
|
||||
mp->req_target = XS_CHANNEL(xs) << 7;
|
||||
isp_put_request(isp, mp, qe);
|
||||
ISP_ADD_REQUEST(isp, nxti);
|
||||
isp->isp_sendmarker |= 1 << XS_CHANNEL(xs);
|
||||
}
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command");
|
||||
}
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
ISP_UNLOCK(isp);
|
||||
}
|
||||
|
||||
@ -2106,13 +2092,13 @@ static void
|
||||
isp_kthread(void *arg)
|
||||
{
|
||||
ispsoftc_t *isp = arg;
|
||||
int slp;
|
||||
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
int s;
|
||||
|
||||
s = splcam();
|
||||
isp->isp_osinfo.intsok = 1;
|
||||
#else
|
||||
#ifdef ISP_SMPLOCK
|
||||
mtx_lock(&isp->isp_lock);
|
||||
@ -2125,32 +2111,63 @@ isp_kthread(void *arg)
|
||||
* gotten good fibre channel state.
|
||||
*/
|
||||
for (;;) {
|
||||
int wasfrozen;
|
||||
int wasfrozen, lb;
|
||||
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "kthread: checking FC state");
|
||||
while (isp_fc_runstate(isp, 2 * 1000000) != 0) {
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "kthread: FC state ungood");
|
||||
if (FCPARAM(isp)->isp_fwstate != FW_READY ||
|
||||
FCPARAM(isp)->isp_loopstate < LOOP_PDB_RCVD) {
|
||||
if (FCPARAM(isp)->loop_seen_once == 0 ||
|
||||
isp->isp_osinfo.ktmature == 0) {
|
||||
break;
|
||||
}
|
||||
lb = isp_fc_runstate(isp, 250000);
|
||||
if (lb) {
|
||||
unsigned int inc = 1;
|
||||
|
||||
if (lb < 0) {
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"kthread: FC loop not up (down count %d)",
|
||||
isp->isp_osinfo.loop_down_time);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"kthread: FC got to %d (down count %d)",
|
||||
lb, isp->isp_osinfo.loop_down_time);
|
||||
}
|
||||
#ifdef ISP_SMPLOCK
|
||||
msleep(isp_kthread, &isp->isp_lock,
|
||||
PRIBIO, "isp_fcthrd", hz);
|
||||
#else
|
||||
(void) tsleep(isp_kthread, PRIBIO, "isp_fcthrd", hz);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* If we've never seen loop up and we've waited longer
|
||||
* than quickboot time, give up and go to sleep until
|
||||
* loop comes up. Otherwise, increment the loop down
|
||||
* time and figure out how long to sleep to the next
|
||||
* check.
|
||||
*/
|
||||
if (FCPARAM(isp)->loop_seen_once == 0 &&
|
||||
isp->isp_osinfo.loop_down_time >=
|
||||
isp_quickboot_time) {
|
||||
isp->isp_osinfo.loop_down_time = 0xffff;
|
||||
slp = 0;
|
||||
} else if (isp->isp_osinfo.loop_down_time > 30) {
|
||||
inc = 30;
|
||||
slp = 30 * hz;
|
||||
} else if (isp->isp_osinfo.loop_down_time > 1) {
|
||||
slp = hz;
|
||||
} else {
|
||||
slp = 1;
|
||||
}
|
||||
|
||||
inc += isp->isp_osinfo.loop_down_time;
|
||||
if (inc < 0xffff) {
|
||||
isp->isp_osinfo.loop_down_time = inc;
|
||||
} else {
|
||||
isp->isp_osinfo.loop_down_time = 0xfffe;
|
||||
}
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "kthread: FC state OK");
|
||||
isp->isp_osinfo.loop_down_time = 0;
|
||||
slp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Even if we didn't get good loop state we may be
|
||||
* unfreezing the SIMQ so that we can kill off
|
||||
* commands (if we've never seen loop before, for example).
|
||||
* If we'd frozen the simq, unfreeze it now so that CAM
|
||||
* can start sending us commands. If the FC state isn't
|
||||
* okay yet, they'll hit that in isp_start which will
|
||||
* freeze the queue again.
|
||||
*/
|
||||
isp->isp_osinfo.ktmature = 1;
|
||||
wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
|
||||
isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
|
||||
if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
|
||||
@ -2159,16 +2176,26 @@ isp_kthread(void *arg)
|
||||
xpt_release_simq(isp->isp_sim, 1);
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
}
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "kthread: waiting until called");
|
||||
#if __FreeBSD_version < 500000
|
||||
tsleep(&isp->isp_osinfo.kproc, PRIBIO, "isp_fc_worker", 0);
|
||||
tsleep(&isp->isp_osinfo.kproc, PRIBIO, "ispf", slp);
|
||||
#else
|
||||
#ifdef ISP_SMPLOCK
|
||||
cv_wait(&isp->isp_osinfo.kthread_cv, &isp->isp_lock);
|
||||
cv_timed_wait(&isp->isp_osinfo.kthread_cv, &isp->isp_lock, slp);
|
||||
#else
|
||||
(void) tsleep(&isp->isp_osinfo.kthread_cv, PRIBIO, "fc_cv", 0);
|
||||
(void) tsleep(&isp->isp_osinfo.kthread_cv, PRIBIO, "ispf", slp);
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* If slp is zero, we're waking up for the first time after
|
||||
* things have been okay. In this case, we set a deferral state
|
||||
* for all commands and delay hysteresis seconds before starting
|
||||
* the FC state evaluation. This gives the loop/fabric a chance
|
||||
* to settle.
|
||||
*/
|
||||
if (slp == 0 && isp->isp_osinfo.hysteresis) {
|
||||
(void) tsleep(&isp_fabric_hysteresis, PRIBIO, "ispT",
|
||||
(isp->isp_osinfo.hysteresis * hz));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2260,8 +2287,12 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
|
||||
* This can only happen for Fibre Channel
|
||||
*/
|
||||
KASSERT((IS_FC(isp)), ("CMD_RQLATER for FC only"));
|
||||
if (FCPARAM(isp)->loop_seen_once == 0 &&
|
||||
isp->isp_osinfo.ktmature) {
|
||||
/*
|
||||
* If we've exceeded the loop down limit start
|
||||
* failing commands.
|
||||
*/
|
||||
if (isp->isp_osinfo.loop_down_time >
|
||||
isp->isp_osinfo.loop_down_limit) {
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
XS_SETERR(ccb, CAM_SEL_TIMEOUT);
|
||||
xpt_done(ccb);
|
||||
@ -2303,25 +2334,22 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
|
||||
#ifdef ISP_TARGET_MODE
|
||||
case XPT_EN_LUN: /* Enable LUN as a target */
|
||||
{
|
||||
int seq, iok, i;
|
||||
int seq, i;
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
iok = isp->isp_osinfo.intsok;
|
||||
isp->isp_osinfo.intsok = 0;
|
||||
seq = isp_en_lun(isp, ccb);
|
||||
if (seq < 0) {
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
}
|
||||
for (i = 0; isp->isp_osinfo.leact[seq] && i < 30 * 1000; i++) {
|
||||
uint16_t isr, sema, mbox;
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
}
|
||||
DELAY(1000);
|
||||
}
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
break;
|
||||
}
|
||||
@ -2519,7 +2547,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
|
||||
else
|
||||
fc->bitrate = 100000;
|
||||
if (tgt > 0 && tgt < MAX_FC_TARG) {
|
||||
struct lportdb *lp = &fcp->portdb[tgt];
|
||||
fcportdb_t *lp = &fcp->portdb[tgt];
|
||||
fc->wwnn = lp->node_wwn;
|
||||
fc->wwpn = lp->port_wwn;
|
||||
fc->port = lp->portid;
|
||||
@ -2767,6 +2795,19 @@ int
|
||||
isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
|
||||
{
|
||||
int bus, rv = 0;
|
||||
static const char *roles[4] = {
|
||||
"(none)", "Target", "Initiator", "Target/Initiator"
|
||||
};
|
||||
static const char prom[] =
|
||||
"PortID 0x%06x handle 0x%x role %s %s\n"
|
||||
" WWNN 0x%08x%08x WWPN 0x%08x%08x";
|
||||
static const char prom2[] =
|
||||
"PortID 0x%06x handle 0x%x role %s %s tgt %u\n"
|
||||
" WWNN 0x%08x%08x WWPN 0x%08x%08x";
|
||||
target_id_t tgt;
|
||||
fcportdb_t *lp;
|
||||
struct cam_path *tmppath;
|
||||
|
||||
switch (cmd) {
|
||||
case ISPASYNC_NEW_TGT_PARAMS:
|
||||
{
|
||||
@ -2775,7 +2816,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
|
||||
int flags, tgt;
|
||||
sdparam *sdp = isp->isp_param;
|
||||
struct ccb_trans_settings cts;
|
||||
struct cam_path *tmppath;
|
||||
|
||||
memset(&cts, 0, sizeof (struct ccb_trans_settings));
|
||||
|
||||
@ -2876,59 +2916,127 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGINFO, "Loop UP");
|
||||
break;
|
||||
case ISPASYNC_PROMENADE:
|
||||
{
|
||||
const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
|
||||
"(role %s) %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
|
||||
static const char *roles[4] = {
|
||||
"(none)", "Target", "Initiator", "Target/Initiator"
|
||||
};
|
||||
fcparam *fcp = isp->isp_param;
|
||||
int tgt = *((int *) arg);
|
||||
#if __FreeBSD_version >= 500000
|
||||
int is_tgt_mask = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
|
||||
struct cam_path *tmppath;
|
||||
#endif
|
||||
struct lportdb *lp = &fcp->portdb[tgt];
|
||||
case ISPASYNC_DEV_ARRIVED:
|
||||
lp = arg;
|
||||
|
||||
isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
|
||||
roles[lp->roles & 0x3],
|
||||
(lp->valid)? "Arrived" : "Departed",
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) (lp->port_wwn & 0xffffffffLL),
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) (lp->node_wwn & 0xffffffffLL));
|
||||
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
if (lp->ini_map_idx) {
|
||||
tgt = lp->ini_map_idx - 1;
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom2,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "arrived at", tgt,
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
#if __FreeBSD_version >= 500000
|
||||
if (xpt_create_path(&tmppath, NULL, cam_sim_path(isp->isp_sim),
|
||||
(target_id_t)tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Policy: only announce targets.
|
||||
*/
|
||||
if (lp->roles & is_tgt_mask) {
|
||||
if (lp->valid) {
|
||||
xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
|
||||
} else {
|
||||
xpt_async(AC_LOST_DEVICE, tmppath, NULL);
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
if (xpt_create_path(&tmppath, NULL,
|
||||
cam_sim_path(isp->isp_sim), tgt,
|
||||
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
xpt_free_path(tmppath);
|
||||
xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
|
||||
xpt_free_path(tmppath);
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
#endif
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
break;
|
||||
}
|
||||
case ISPASYNC_CHANGE_NOTIFY:
|
||||
if (arg == ISPASYNC_CHANGE_PDB) {
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"Port Database Changed");
|
||||
} else if (arg == ISPASYNC_CHANGE_SNS) {
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"Name Server Database Changed");
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "arrived",
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
}
|
||||
break;
|
||||
case ISPASYNC_DEV_CHANGED:
|
||||
lp = arg;
|
||||
if (lp->ini_map_idx) {
|
||||
tgt = lp->ini_map_idx - 1;
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom2,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "changed at", tgt,
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "changed",
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
}
|
||||
break;
|
||||
case ISPASYNC_DEV_STAYED:
|
||||
lp = arg;
|
||||
if (lp->ini_map_idx) {
|
||||
tgt = lp->ini_map_idx - 1;
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom2,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "stayed at", tgt,
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "stayed",
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
}
|
||||
break;
|
||||
case ISPASYNC_DEV_GONE:
|
||||
lp = arg;
|
||||
if (lp->ini_map_idx) {
|
||||
tgt = lp->ini_map_idx - 1;
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom2,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "departed from", tgt,
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
#if __FreeBSD_version >= 500000
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
if (xpt_create_path(&tmppath, NULL,
|
||||
cam_sim_path(isp->isp_sim), tgt,
|
||||
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
break;
|
||||
}
|
||||
xpt_async(AC_LOST_DEVICE, tmppath, NULL);
|
||||
xpt_free_path(tmppath);
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
#endif
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom,
|
||||
lp->portid, lp->handle,
|
||||
roles[lp->roles & 0x3], "departed",
|
||||
(uint32_t) (lp->node_wwn >> 32),
|
||||
(uint32_t) lp->node_wwn,
|
||||
(uint32_t) (lp->port_wwn >> 32),
|
||||
(uint32_t) lp->port_wwn);
|
||||
}
|
||||
break;
|
||||
case ISPASYNC_CHANGE_NOTIFY:
|
||||
{
|
||||
char *msg;
|
||||
if (arg == ISPASYNC_CHANGE_PDB) {
|
||||
msg = "Port Database Changed";
|
||||
} else if (arg == ISPASYNC_CHANGE_SNS) {
|
||||
msg = "Name Server Database Changed";
|
||||
} else {
|
||||
msg = "Other Change Notify";
|
||||
}
|
||||
isp_prt(isp, ISP_LOGINFO, msg);
|
||||
isp_freeze_loopdown(isp, msg);
|
||||
#if __FreeBSD_version < 500000
|
||||
wakeup(&isp->isp_osinfo.kproc);
|
||||
#else
|
||||
@ -2939,117 +3047,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case ISPASYNC_FABRIC_DEV:
|
||||
{
|
||||
int target, base, lim;
|
||||
fcparam *fcp = isp->isp_param;
|
||||
struct lportdb *lp = NULL;
|
||||
struct lportdb *clp = (struct lportdb *) arg;
|
||||
char *pt;
|
||||
|
||||
switch (clp->port_type) {
|
||||
case 1:
|
||||
pt = " N_Port";
|
||||
break;
|
||||
case 2:
|
||||
pt = " NL_Port";
|
||||
break;
|
||||
case 3:
|
||||
pt = "F/NL_Port";
|
||||
break;
|
||||
case 0x7f:
|
||||
pt = " Nx_Port";
|
||||
break;
|
||||
case 0x81:
|
||||
pt = " F_port";
|
||||
break;
|
||||
case 0x82:
|
||||
pt = " FL_Port";
|
||||
break;
|
||||
case 0x84:
|
||||
pt = " E_port";
|
||||
break;
|
||||
default:
|
||||
pt = " ";
|
||||
break;
|
||||
}
|
||||
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"%s Fabric Device @ PortID 0x%x", pt, clp->portid);
|
||||
|
||||
/*
|
||||
* If we don't have an initiator role we bail.
|
||||
*
|
||||
* We just use ISPASYNC_FABRIC_DEV for announcement purposes.
|
||||
*/
|
||||
|
||||
if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this entry for us? If so, we bail.
|
||||
*/
|
||||
|
||||
if (fcp->isp_portid == clp->portid) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Else, the default policy is to find room for it in
|
||||
* our local port database. Later, when we execute
|
||||
* the call to isp_pdb_sync either this newly arrived
|
||||
* or already logged in device will be (re)announced.
|
||||
*/
|
||||
|
||||
if (fcp->isp_topo == TOPO_FL_PORT)
|
||||
base = FC_SNS_ID+1;
|
||||
else
|
||||
base = 0;
|
||||
|
||||
if (fcp->isp_topo == TOPO_N_PORT)
|
||||
lim = 1;
|
||||
else
|
||||
lim = MAX_FC_TARG;
|
||||
|
||||
/*
|
||||
* Is it already in our list?
|
||||
*/
|
||||
for (target = base; target < lim; target++) {
|
||||
if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
|
||||
continue;
|
||||
}
|
||||
lp = &fcp->portdb[target];
|
||||
if (lp->port_wwn == clp->port_wwn &&
|
||||
lp->node_wwn == clp->node_wwn) {
|
||||
lp->fabric_dev = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (target < lim) {
|
||||
break;
|
||||
}
|
||||
for (target = base; target < lim; target++) {
|
||||
if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
|
||||
continue;
|
||||
}
|
||||
lp = &fcp->portdb[target];
|
||||
if (lp->port_wwn == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (target == lim) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"out of space for fabric devices");
|
||||
break;
|
||||
}
|
||||
lp->port_type = clp->port_type;
|
||||
lp->fc4_type = clp->fc4_type;
|
||||
lp->node_wwn = clp->node_wwn;
|
||||
lp->port_wwn = clp->port_wwn;
|
||||
lp->portid = clp->portid;
|
||||
lp->fabric_dev = 1;
|
||||
break;
|
||||
}
|
||||
#ifdef ISP_TARGET_MODE
|
||||
case ISPASYNC_TARGET_NOTIFY:
|
||||
@ -3136,8 +3133,12 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
|
||||
void
|
||||
isp_uninit(ispsoftc_t *isp)
|
||||
{
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
|
||||
DISABLE_INTS(isp);
|
||||
if (IS_24XX(isp)) {
|
||||
ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
|
||||
} else {
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
|
||||
}
|
||||
ISP_DISABLE_INTS(isp);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -149,13 +149,16 @@ struct isposinfo {
|
||||
struct cam_sim *sim2;
|
||||
struct cam_path *path2;
|
||||
struct intr_config_hook ehook;
|
||||
uint8_t
|
||||
uint16_t loop_down_time;
|
||||
uint16_t loop_down_limit;
|
||||
uint32_t : 5,
|
||||
simqfrozen : 3,
|
||||
hysteresis : 8,
|
||||
: 4,
|
||||
disabled : 1,
|
||||
fcbsy : 1,
|
||||
ktmature : 1,
|
||||
mboxwaiting : 1,
|
||||
intsok : 1,
|
||||
simqfrozen : 3;
|
||||
mboxcmd_done : 1,
|
||||
mboxbsy : 1;
|
||||
#if __FreeBSD_version >= 500000
|
||||
struct firmware * fw;
|
||||
struct mtx lock;
|
||||
@ -211,18 +214,13 @@ struct isposinfo {
|
||||
* Required Macros/Defines
|
||||
*/
|
||||
|
||||
#define ISP2100_SCRLEN 0x800
|
||||
#define ISP2100_SCRLEN 0x1000
|
||||
|
||||
#define MEMZERO(a, b) memset(a, 0, b)
|
||||
#define MEMCPY memcpy
|
||||
#define SNPRINTF snprintf
|
||||
#define USEC_DELAY DELAY
|
||||
#define USEC_SLEEP(isp, x) \
|
||||
if (isp->isp_osinfo.intsok) \
|
||||
ISP_UNLOCK(isp); \
|
||||
DELAY(x); \
|
||||
if (isp->isp_osinfo.intsok) \
|
||||
ISP_LOCK(isp)
|
||||
#define USEC_SLEEP(isp, x) DELAY(x)
|
||||
|
||||
#define NANOTIME_T struct timespec
|
||||
#define GET_NANOTIME nanotime
|
||||
@ -247,15 +245,10 @@ default: \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define MBOX_ACQUIRE(isp)
|
||||
#define MBOX_ACQUIRE isp_mbox_acquire
|
||||
#define MBOX_WAIT_COMPLETE isp_mbox_wait_complete
|
||||
#define MBOX_NOTIFY_COMPLETE(isp) \
|
||||
if (isp->isp_osinfo.mboxwaiting) { \
|
||||
isp->isp_osinfo.mboxwaiting = 0; \
|
||||
wakeup(&isp->isp_mbxworkp); \
|
||||
} \
|
||||
isp->isp_mboxbsy = 0
|
||||
#define MBOX_RELEASE(isp)
|
||||
#define MBOX_NOTIFY_COMPLETE(isp) isp->isp_osinfo.mboxcmd_done = 1
|
||||
#define MBOX_RELEASE isp_mbox_release
|
||||
|
||||
#define FC_SCRATCH_ACQUIRE(isp) \
|
||||
if (isp->isp_osinfo.fcbsy) { \
|
||||
@ -361,7 +354,8 @@ default: \
|
||||
#define ISP_IOXGET_32(isp, s, d) \
|
||||
d = (isp->isp_bustype == ISP_BT_SBUS)? \
|
||||
*((uint32_t *)s) : bswap32(*((uint32_t *)s))
|
||||
#else
|
||||
|
||||
#else /* ISP_SBUS_SUPPORTED */
|
||||
#define ISP_IOXPUT_8(isp, s, d) *(d) = s
|
||||
#define ISP_IOXPUT_16(isp, s, d) *(d) = bswap16(s)
|
||||
#define ISP_IOXPUT_32(isp, s, d) *(d) = bswap32(s)
|
||||
@ -370,6 +364,15 @@ default: \
|
||||
#define ISP_IOXGET_32(isp, s, d) d = bswap32(*((uint32_t *)s))
|
||||
#endif
|
||||
#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = bswap16(*rp)
|
||||
|
||||
#define ISP_IOZGET_8(isp, s, d) d = (*((uint8_t *)s))
|
||||
#define ISP_IOZGET_16(isp, s, d) d = (*((uint16_t *)s))
|
||||
#define ISP_IOZGET_32(isp, s, d) d = (*((uint32_t *)s))
|
||||
#define ISP_IOZPUT_8(isp, s, d) *(d) = s
|
||||
#define ISP_IOZPUT_16(isp, s, d) *(d) = s
|
||||
#define ISP_IOZPUT_32(isp, s, d) *(d) = s
|
||||
|
||||
|
||||
#else
|
||||
#define ISP_IOXPUT_8(isp, s, d) *(d) = s
|
||||
#define ISP_IOXPUT_16(isp, s, d) *(d) = s
|
||||
@ -378,6 +381,15 @@ default: \
|
||||
#define ISP_IOXGET_16(isp, s, d) d = *(s)
|
||||
#define ISP_IOXGET_32(isp, s, d) d = *(s)
|
||||
#define ISP_SWIZZLE_NVRAM_WORD(isp, rp)
|
||||
|
||||
#define ISP_IOZPUT_8(isp, s, d) *(d) = s
|
||||
#define ISP_IOZPUT_16(isp, s, d) *(d) = bswap16(s)
|
||||
#define ISP_IOZPUT_32(isp, s, d) *(d) = bswap32(s)
|
||||
|
||||
#define ISP_IOZGET_8(isp, s, d) d = (*((uint8_t *)(s)))
|
||||
#define ISP_IOZGET_16(isp, s, d) d = bswap16(*((uint16_t *)(s)))
|
||||
#define ISP_IOZGET_32(isp, s, d) d = bswap32(*((uint32_t *)(s)))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -417,6 +429,9 @@ extern void isp_uninit(ispsoftc_t *);
|
||||
* driver global data
|
||||
*/
|
||||
extern int isp_announced;
|
||||
extern int isp_fabric_hysteresis;
|
||||
extern int isp_loop_down_limit;
|
||||
extern int isp_quickboot_time;
|
||||
|
||||
/*
|
||||
* Platform private flags
|
||||
@ -444,49 +459,61 @@ extern int isp_announced;
|
||||
* Platform specific inline functions
|
||||
*/
|
||||
|
||||
static __inline void isp_mbox_wait_complete(ispsoftc_t *);
|
||||
static __inline void
|
||||
isp_mbox_wait_complete(ispsoftc_t *isp)
|
||||
static __inline int isp_mbox_acquire(ispsoftc_t *);
|
||||
static __inline void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
|
||||
static __inline void isp_mbox_release(ispsoftc_t *);
|
||||
|
||||
static __inline int
|
||||
isp_mbox_acquire(ispsoftc_t *isp)
|
||||
{
|
||||
if (isp->isp_osinfo.intsok) {
|
||||
int lim = ((isp->isp_mbxwrk0)? 120 : 20) * hz;
|
||||
isp->isp_osinfo.mboxwaiting = 1;
|
||||
#ifdef ISP_SMPLOCK
|
||||
(void) msleep(&isp->isp_mbxworkp,
|
||||
&isp->isp_lock, PRIBIO, "isp_mboxwaiting", lim);
|
||||
#else
|
||||
(void) tsleep(&isp->isp_mbxworkp,
|
||||
PRIBIO, "isp_mboxwaiting", lim);
|
||||
#endif
|
||||
if (isp->isp_mboxbsy != 0) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Interrupting Mailbox Command (0x%x) Timeout",
|
||||
isp->isp_lastmbxcmd);
|
||||
isp->isp_mboxbsy = 0;
|
||||
}
|
||||
isp->isp_osinfo.mboxwaiting = 0;
|
||||
if (isp->isp_osinfo.mboxbsy) {
|
||||
return (1);
|
||||
} else {
|
||||
int lim = ((isp->isp_mbxwrk0)? 240 : 60) * 10000;
|
||||
int j;
|
||||
for (j = 0; j < lim; j++) {
|
||||
uint16_t isr, sema, mbox;
|
||||
if (isp->isp_mboxbsy == 0) {
|
||||
isp->isp_osinfo.mboxcmd_done = 0;
|
||||
isp->isp_osinfo.mboxbsy = 1;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
|
||||
{
|
||||
int lim = mbp->timeout;
|
||||
int j;
|
||||
|
||||
if (lim == 0) {
|
||||
lim = MBCMD_DEFAULT_TIMEOUT;
|
||||
}
|
||||
if (isp->isp_mbxwrk0) {
|
||||
lim *= isp->isp_mbxwrk0;
|
||||
}
|
||||
for (j = 0; j < lim; j += 100) {
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
if (isp->isp_osinfo.mboxcmd_done) {
|
||||
break;
|
||||
}
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
if (isp->isp_osinfo.mboxcmd_done) {
|
||||
break;
|
||||
}
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
if (isp->isp_mboxbsy == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
USEC_DELAY(500);
|
||||
}
|
||||
if (isp->isp_mboxbsy != 0) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Polled Mailbox Command (0x%x) Timeout",
|
||||
isp->isp_lastmbxcmd);
|
||||
}
|
||||
USEC_DELAY(100);
|
||||
}
|
||||
if (isp->isp_osinfo.mboxcmd_done == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Polled Mailbox Command (0x%x) Timeout",
|
||||
isp->isp_lastmbxcmd);
|
||||
mbp->param[0] = MBOX_TIMEOUT;
|
||||
isp->isp_osinfo.mboxcmd_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
isp_mbox_release(ispsoftc_t *isp)
|
||||
{
|
||||
isp->isp_osinfo.mboxbsy = 0;
|
||||
}
|
||||
|
||||
static __inline uint64_t nanotime_sub(struct timespec *, struct timespec *);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,22 +30,26 @@
|
||||
#ifndef _ISP_LIBRARY_H
|
||||
#define _ISP_LIBRARY_H
|
||||
|
||||
extern int isp_save_xs(ispsoftc_t *, XS_T *, uint16_t *);
|
||||
extern XS_T *isp_find_xs(ispsoftc_t *, uint16_t);
|
||||
extern uint16_t isp_find_handle(ispsoftc_t *, XS_T *);
|
||||
extern int isp_handle_index(uint16_t);
|
||||
extern uint16_t isp_index_handle(int);
|
||||
extern void isp_destroy_handle(ispsoftc_t *, uint16_t);
|
||||
extern int isp_getrqentry(ispsoftc_t *, uint16_t *, uint16_t *, void **);
|
||||
extern int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *);
|
||||
extern XS_T *isp_find_xs(ispsoftc_t *, uint32_t);
|
||||
extern uint32_t isp_find_handle(ispsoftc_t *, XS_T *);
|
||||
extern uint32_t isp_handle_index(uint32_t);
|
||||
extern void isp_destroy_handle(ispsoftc_t *, uint32_t);
|
||||
extern int isp_getrqentry(ispsoftc_t *, uint32_t *, uint32_t *, void **);
|
||||
extern void isp_print_qentry (ispsoftc_t *, char *, int, void *);
|
||||
extern void isp_print_bytes(ispsoftc_t *, char *, int, void *);
|
||||
extern int isp_fc_runstate(ispsoftc_t *, int);
|
||||
extern void isp_copy_out_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
extern void isp_copy_in_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
extern void isp_shutdown(ispsoftc_t *);
|
||||
extern void isp_put_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
extern void isp_get_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
extern int isp_get_response_type(ispsoftc_t *, isphdr_t *);
|
||||
extern void
|
||||
isp_put_request(ispsoftc_t *, ispreq_t *, ispreq_t *);
|
||||
extern void
|
||||
isp_put_marker(ispsoftc_t *, isp_marker_t *, isp_marker_t *);
|
||||
extern void
|
||||
isp_put_marker_24xx(ispsoftc_t *, isp_marker_24xx_t *, isp_marker_24xx_t *);
|
||||
extern void
|
||||
isp_put_request_t2(ispsoftc_t *, ispreqt2_t *, ispreqt2_t *);
|
||||
extern void
|
||||
isp_put_request_t2e(ispsoftc_t *, ispreqt2e_t *, ispreqt2e_t *);
|
||||
@ -56,21 +60,37 @@ isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
|
||||
extern void
|
||||
isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
|
||||
extern void
|
||||
isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
|
||||
extern void
|
||||
isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
extern void
|
||||
isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
|
||||
extern void
|
||||
isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
|
||||
extern void
|
||||
isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
|
||||
extern void
|
||||
isp_get_response_x(ispsoftc_t *, ispstatus_cont_t *, ispstatus_cont_t *);
|
||||
extern void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *,
|
||||
isp24xx_statusreq_t *);
|
||||
void
|
||||
isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
extern void
|
||||
isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
|
||||
extern void
|
||||
isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
|
||||
extern void
|
||||
isp_get_pdb(ispsoftc_t *, isp_pdb_t *, isp_pdb_t *);
|
||||
isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
|
||||
extern void
|
||||
isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
isp_get_pdb_21xx(ispsoftc_t *, isp_pdb_21xx_t *, isp_pdb_21xx_t *);
|
||||
extern void
|
||||
isp_get_pdb_24xx(ispsoftc_t *, isp_pdb_24xx_t *, isp_pdb_24xx_t *);
|
||||
extern void
|
||||
isp_get_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
|
||||
extern void
|
||||
isp_put_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
|
||||
extern void
|
||||
isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
|
||||
extern void
|
||||
isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
|
||||
extern void
|
||||
isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *);
|
||||
extern void
|
||||
@ -93,6 +113,17 @@ isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *,
|
||||
extern void
|
||||
isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *,
|
||||
sns_ga_nxt_rsp_t *);
|
||||
extern void
|
||||
isp_get_els(ispsoftc_t *, els_t *, els_t *);
|
||||
extern void
|
||||
isp_put_els(ispsoftc_t *, els_t *, els_t *);
|
||||
extern void
|
||||
isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
|
||||
extern void
|
||||
isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
|
||||
extern void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
|
||||
extern void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
extern void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
@ -103,10 +134,12 @@ isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *,
|
||||
#include "isp_target.h"
|
||||
#endif
|
||||
|
||||
extern int isp_save_xs_tgt(ispsoftc_t *, void *, uint16_t *);
|
||||
extern void *isp_find_xs_tgt(ispsoftc_t *, uint16_t);
|
||||
extern uint16_t isp_find_tgt_handle(ispsoftc_t *, void *);
|
||||
extern void isp_destroy_tgt_handle(ispsoftc_t *, uint16_t);
|
||||
#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
|
||||
|
||||
extern int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *);
|
||||
extern void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
|
||||
extern uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
|
||||
extern void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
|
||||
|
||||
extern void
|
||||
isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
@ -121,6 +154,8 @@ isp_get_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
|
||||
extern void
|
||||
isp_get_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
|
||||
extern void
|
||||
isp_get_atio7(ispsoftc_t *isp, at7_entry_t *, at7_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
|
||||
@ -129,10 +164,14 @@ isp_put_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
|
||||
extern void
|
||||
isp_put_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
|
||||
extern void
|
||||
isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
|
||||
extern void
|
||||
isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
|
||||
extern void
|
||||
isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
|
||||
@ -145,20 +184,36 @@ isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
|
||||
extern void
|
||||
isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
|
||||
extern void
|
||||
isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_get_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
|
||||
extern void
|
||||
isp_get_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
|
||||
extern void
|
||||
isp_get_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_put_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
|
||||
extern void
|
||||
isp_get_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
|
||||
extern void
|
||||
isp_put_notify_24xx_ack(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_put_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
|
||||
extern void
|
||||
isp_put_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
|
||||
extern void isp_put_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
|
||||
na_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_get_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
|
||||
extern void
|
||||
isp_get_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
|
||||
extern void isp_get_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
|
||||
na_fcentry_24xx_t *);
|
||||
extern void
|
||||
isp_get_abts(ispsoftc_t *, abts_t *, abts_t *);
|
||||
extern void
|
||||
isp_put_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
|
||||
extern void
|
||||
isp_get_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
|
||||
#endif /* ISP_TARGET_MODE */
|
||||
#endif /* _ISP_LIBRARY_H */
|
||||
|
@ -62,19 +62,23 @@ __FBSDID("$FreeBSD$");
|
||||
#define BUS_PROBE_DEFAULT 0
|
||||
#endif
|
||||
|
||||
static uint16_t isp_pci_rd_reg(ispsoftc_t *, int);
|
||||
static void isp_pci_wr_reg(ispsoftc_t *, int, uint16_t);
|
||||
static uint16_t isp_pci_rd_reg_1080(ispsoftc_t *, int);
|
||||
static void isp_pci_wr_reg_1080(ispsoftc_t *, int, uint16_t);
|
||||
static uint32_t isp_pci_rd_reg(ispsoftc_t *, int);
|
||||
static void isp_pci_wr_reg(ispsoftc_t *, int, uint32_t);
|
||||
static uint32_t isp_pci_rd_reg_1080(ispsoftc_t *, int);
|
||||
static void isp_pci_wr_reg_1080(ispsoftc_t *, int, uint32_t);
|
||||
static uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int);
|
||||
static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t);
|
||||
static int
|
||||
isp_pci_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
|
||||
isp_pci_rd_isr(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
|
||||
static int
|
||||
isp_pci_rd_isr_2300(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
|
||||
isp_pci_rd_isr_2300(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
|
||||
static int
|
||||
isp_pci_rd_isr_2400(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
|
||||
static int isp_pci_mbxdma(ispsoftc_t *);
|
||||
static int
|
||||
isp_pci_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint16_t *, uint16_t);
|
||||
isp_pci_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t);
|
||||
static void
|
||||
isp_pci_dmateardown(ispsoftc_t *, XS_T *, uint16_t);
|
||||
isp_pci_dmateardown(ispsoftc_t *, XS_T *, uint32_t);
|
||||
|
||||
|
||||
static void isp_pci_reset1(ispsoftc_t *);
|
||||
@ -158,6 +162,18 @@ static struct ispmdvec mdvec_2300 = {
|
||||
isp_pci_dumpregs
|
||||
};
|
||||
|
||||
static struct ispmdvec mdvec_2400 = {
|
||||
isp_pci_rd_isr_2400,
|
||||
isp_pci_rd_reg_2400,
|
||||
isp_pci_wr_reg_2400,
|
||||
isp_pci_mbxdma,
|
||||
isp_pci_dmasetup,
|
||||
isp_pci_dmateardown,
|
||||
NULL,
|
||||
isp_pci_reset1,
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifndef PCIM_CMD_INVEN
|
||||
#define PCIM_CMD_INVEN 0x10
|
||||
#endif
|
||||
@ -306,6 +322,7 @@ static struct ispmdvec mdvec_2300 = {
|
||||
|
||||
static int isp_pci_probe (device_t);
|
||||
static int isp_pci_attach (device_t);
|
||||
static int isp_pci_detach (device_t);
|
||||
|
||||
|
||||
struct isp_pcisoftc {
|
||||
@ -320,10 +337,12 @@ struct isp_pcisoftc {
|
||||
bus_dmamap_t *dmaps;
|
||||
};
|
||||
|
||||
|
||||
static device_method_t isp_pci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, isp_pci_probe),
|
||||
DEVMETHOD(device_attach, isp_pci_attach),
|
||||
DEVMETHOD(device_detach, isp_pci_detach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
static void isp_pci_intr(void *);
|
||||
@ -380,11 +399,9 @@ isp_pci_probe(device_t dev)
|
||||
case PCI_QLOGIC_ISP2322:
|
||||
device_set_desc(dev, "Qlogic ISP 2322 PCI FC-AL Adapter");
|
||||
break;
|
||||
#if 0
|
||||
case PCI_QLOGIC_ISP2422:
|
||||
device_set_desc(dev, "Qlogic ISP 2422 PCI FC-AL Adapter");
|
||||
break;
|
||||
#endif
|
||||
case PCI_QLOGIC_ISP6312:
|
||||
device_set_desc(dev, "Qlogic ISP 6312 PCI FC-AL Adapter");
|
||||
break;
|
||||
@ -487,6 +504,23 @@ isp_get_options(device_t dev, ispsoftc_t *isp)
|
||||
isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO;
|
||||
}
|
||||
|
||||
bitmap = 0;
|
||||
(void) getenv_int("isp_fabric_hysteresis", &bitmap);
|
||||
if (bitmap >= 0 && bitmap < 256) {
|
||||
isp->isp_osinfo.hysteresis = bitmap;
|
||||
} else {
|
||||
isp->isp_osinfo.hysteresis = isp_fabric_hysteresis;
|
||||
}
|
||||
|
||||
bitmap = 0;
|
||||
(void) getenv_int("isp_loop_down_limit", &bitmap);
|
||||
if (bitmap >= 0 && bitmap < 0xffff) {
|
||||
isp->isp_osinfo.loop_down_limit = bitmap;
|
||||
} else {
|
||||
isp->isp_osinfo.loop_down_limit = isp_loop_down_limit;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ISP_FW_CRASH_DUMP
|
||||
bitmap = 0;
|
||||
if (getenv_int("isp_fw_dump_enable", &bitmap)) {
|
||||
@ -690,6 +724,24 @@ isp_get_options(device_t dev, ispsoftc_t *isp)
|
||||
isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO;
|
||||
}
|
||||
|
||||
tval = 0;
|
||||
(void) resource_int_value(device_get_name(dev), device_get_unit(dev),
|
||||
"hysteresis", &tval);
|
||||
if (tval >= 0 && tval < 256) {
|
||||
isp->isp_osinfo.hysteresis = tval;
|
||||
} else {
|
||||
isp->isp_osinfo.hysteresis = isp_fabric_hysteresis;
|
||||
}
|
||||
|
||||
tval = 0;
|
||||
(void) resource_int_value(device_get_name(dev), device_get_unit(dev),
|
||||
"loop_down_limit", &tval);
|
||||
if (tval >= 0 && tval < 0xffff) {
|
||||
isp->isp_osinfo.loop_down_limit = tval;
|
||||
} else {
|
||||
isp->isp_osinfo.loop_down_limit = isp_loop_down_limit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -886,11 +938,11 @@ isp_pci_attach(device_t dev)
|
||||
PCI_MBOX_REGS2300_OFF;
|
||||
}
|
||||
if (pci_get_devid(dev) == PCI_QLOGIC_ISP2422) {
|
||||
mdvp = &mdvec_2300;
|
||||
basetype = ISP_HA_FC_2422;
|
||||
mdvp = &mdvec_2400;
|
||||
basetype = ISP_HA_FC_2400;
|
||||
psize = sizeof (fcparam);
|
||||
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
|
||||
PCI_MBOX_REGS2300_OFF;
|
||||
PCI_MBOX_REGS2400_OFF;
|
||||
}
|
||||
isp = &pcs->pci_isp;
|
||||
isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
@ -932,6 +984,9 @@ isp_pci_attach(device_t dev)
|
||||
case PCI_PRODUCT_QLOGIC_ISP6322:
|
||||
did = 0x2322;
|
||||
break;
|
||||
case PCI_PRODUCT_QLOGIC_ISP2422:
|
||||
did = 0x2400;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -976,18 +1031,42 @@ isp_pci_attach(device_t dev)
|
||||
cmd &= ~PCIM_CMD_INVEN;
|
||||
}
|
||||
|
||||
if (IS_23XX(isp)) {
|
||||
/*
|
||||
* Can't tell if ROM will hang on 'ABOUT FIRMWARE' command.
|
||||
*/
|
||||
isp->isp_touched = 1;
|
||||
|
||||
}
|
||||
|
||||
if (IS_2322(isp) || pci_get_devid(dev) == PCI_QLOGIC_ISP6312) {
|
||||
cmd &= ~PCIM_CMD_INTX_DISABLE;
|
||||
}
|
||||
|
||||
if (IS_24XX(isp)) {
|
||||
int reg;
|
||||
|
||||
cmd &= ~PCIM_CMD_INTX_DISABLE;
|
||||
|
||||
/*
|
||||
* Is this a PCI-X card? If so, set max read byte count.
|
||||
*/
|
||||
if (pci_find_extcap(dev, PCIY_PCIX, ®) == 0) {
|
||||
uint16_t pxcmd;
|
||||
reg += 2;
|
||||
|
||||
pxcmd = pci_read_config(dev, reg, 2);
|
||||
pxcmd &= ~0xc;
|
||||
pxcmd |= 0x8;
|
||||
pci_write_config(dev, reg, 2, pxcmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this a PCI Express card? If so, set max read byte count.
|
||||
*/
|
||||
if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
|
||||
uint16_t pectl;
|
||||
|
||||
reg += 0x8;
|
||||
pectl = pci_read_config(dev, reg, 2);
|
||||
pectl &= ~0x7000;
|
||||
pectl |= 0x4000;
|
||||
pci_write_config(dev, reg, 2, pectl);
|
||||
}
|
||||
}
|
||||
|
||||
pci_write_config(dev, PCIR_COMMAND, cmd, 2);
|
||||
|
||||
/*
|
||||
@ -1039,10 +1118,17 @@ isp_pci_attach(device_t dev)
|
||||
/*
|
||||
* Last minute checks...
|
||||
*/
|
||||
if (IS_23XX(isp)) {
|
||||
if (IS_23XX(isp) || IS_24XX(isp)) {
|
||||
isp->isp_port = pci_get_function(dev);
|
||||
}
|
||||
|
||||
if (IS_23XX(isp)) {
|
||||
/*
|
||||
* Can't tell if ROM will hang on 'ABOUT FIRMWARE' command.
|
||||
*/
|
||||
isp->isp_touched = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we're in reset state.
|
||||
*/
|
||||
@ -1069,6 +1155,7 @@ isp_pci_attach(device_t dev)
|
||||
* XXXX: (or decrease the reference count to it).
|
||||
*/
|
||||
ISP_UNLOCK(isp);
|
||||
|
||||
return (0);
|
||||
|
||||
bad:
|
||||
@ -1110,21 +1197,34 @@ isp_pci_attach(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
isp_pci_detach(device_t dev)
|
||||
{
|
||||
struct isp_pcisoftc *pcs;
|
||||
ispsoftc_t *isp;
|
||||
|
||||
pcs = device_get_softc(dev);
|
||||
if (pcs == NULL) {
|
||||
return (ENXIO);
|
||||
}
|
||||
isp = (ispsoftc_t *) pcs;
|
||||
ISP_DISABLE_INTS(isp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_pci_intr(void *arg)
|
||||
{
|
||||
ispsoftc_t *isp = arg;
|
||||
uint16_t isr, sema, mbox;
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
|
||||
ISP_LOCK(isp);
|
||||
isp->isp_intcnt++;
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
|
||||
isp->isp_intbogus++;
|
||||
} else {
|
||||
int iok = isp->isp_osinfo.intsok;
|
||||
isp->isp_osinfo.intsok = 0;
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
}
|
||||
ISP_UNLOCK(isp);
|
||||
}
|
||||
@ -1138,13 +1238,17 @@ isp_pci_intr(void *arg)
|
||||
bus_space_read_2(pcs->pci_st, pcs->pci_sh, off)
|
||||
#define BXW2(pcs, off, v) \
|
||||
bus_space_write_2(pcs->pci_st, pcs->pci_sh, off, v)
|
||||
#define BXR4(pcs, off) \
|
||||
bus_space_read_4(pcs->pci_st, pcs->pci_sh, off)
|
||||
#define BXW4(pcs, off, v) \
|
||||
bus_space_write_4(pcs->pci_st, pcs->pci_sh, off, v)
|
||||
|
||||
|
||||
static __inline int
|
||||
isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
uint16_t val0, val1;
|
||||
uint32_t val0, val1;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
@ -1159,7 +1263,7 @@ isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp)
|
||||
}
|
||||
|
||||
static int
|
||||
isp_pci_rd_isr(ispsoftc_t *isp, uint16_t *isrp,
|
||||
isp_pci_rd_isr(ispsoftc_t *isp, uint32_t *isrp,
|
||||
uint16_t *semap, uint16_t *mbp)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
@ -1196,19 +1300,18 @@ isp_pci_rd_isr(ispsoftc_t *isp, uint16_t *isrp,
|
||||
}
|
||||
|
||||
static int
|
||||
isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp,
|
||||
isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp,
|
||||
uint16_t *semap, uint16_t *mbox0p)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
uint16_t hccr;
|
||||
uint32_t hccr;
|
||||
uint32_t r2hisr;
|
||||
|
||||
if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR) & BIU2100_ISR_RISC_INT))) {
|
||||
*isrp = 0;
|
||||
return (0);
|
||||
}
|
||||
r2hisr = bus_space_read_4(pcs->pci_st, pcs->pci_sh,
|
||||
IspVirt2Off(pcs, BIU_R2HSTSLO));
|
||||
r2hisr = BXR4(pcs, IspVirt2Off(pcs, BIU_R2HSTSLO));
|
||||
isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
|
||||
if ((r2hisr & BIU_R2HST_INTR) == 0) {
|
||||
*isrp = 0;
|
||||
@ -1252,17 +1355,54 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp,
|
||||
"RISC paused at interrupt (%x->%x\n", hccr,
|
||||
ISP_READ(isp, HCCR));
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGERR, "unknown interrerupt 0x%x\n",
|
||||
isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n",
|
||||
r2hisr);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
static int
|
||||
isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp,
|
||||
uint16_t *semap, uint16_t *mbox0p)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
uint32_t r2hisr;
|
||||
|
||||
r2hisr = BXR4(pcs, IspVirt2Off(pcs, BIU2400_R2HSTSLO));
|
||||
isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
|
||||
if ((r2hisr & BIU2400_R2HST_INTR) == 0) {
|
||||
*isrp = 0;
|
||||
return (0);
|
||||
}
|
||||
switch (r2hisr & BIU2400_R2HST_ISTAT_MASK) {
|
||||
case ISP2400R2HST_ROM_MBX_OK:
|
||||
case ISP2400R2HST_ROM_MBX_FAIL:
|
||||
case ISP2400R2HST_MBX_OK:
|
||||
case ISP2400R2HST_MBX_FAIL:
|
||||
case ISP2400R2HST_ASYNC_EVENT:
|
||||
*isrp = r2hisr & 0xffff;
|
||||
*mbox0p = (r2hisr >> 16);
|
||||
*semap = 1;
|
||||
return (1);
|
||||
case ISP2400R2HST_RSPQ_UPDATE:
|
||||
case ISP2400R2HST_ATIO_RSPQ_UPDATE:
|
||||
case ISP2400R2HST_ATIO_RQST_UPDATE:
|
||||
*isrp = r2hisr & 0xffff;
|
||||
*mbox0p = 0;
|
||||
*semap = 0;
|
||||
return (1);
|
||||
default:
|
||||
ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
|
||||
isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
isp_pci_rd_reg(ispsoftc_t *isp, int regoff)
|
||||
{
|
||||
uint16_t rv;
|
||||
uint32_t rv;
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
int oldconf = 0;
|
||||
|
||||
@ -1282,10 +1422,11 @@ isp_pci_rd_reg(ispsoftc_t *isp, int regoff)
|
||||
}
|
||||
|
||||
static void
|
||||
isp_pci_wr_reg(ispsoftc_t *isp, int regoff, uint16_t val)
|
||||
isp_pci_wr_reg(ispsoftc_t *isp, int regoff, uint32_t val)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
int oldconf = 0;
|
||||
volatile int junk;
|
||||
|
||||
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
|
||||
/*
|
||||
@ -1294,22 +1435,25 @@ isp_pci_wr_reg(ispsoftc_t *isp, int regoff, uint16_t val)
|
||||
oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
|
||||
oldconf | BIU_PCI_CONF1_SXP);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
}
|
||||
BXW2(pcs, IspVirt2Off(isp, regoff), val);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, regoff));
|
||||
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
|
||||
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
static uint32_t
|
||||
isp_pci_rd_reg_1080(ispsoftc_t *isp, int regoff)
|
||||
{
|
||||
uint16_t rv, oc = 0;
|
||||
uint32_t rv, oc = 0;
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
|
||||
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
|
||||
(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
|
||||
uint16_t tc;
|
||||
uint32_t tc;
|
||||
/*
|
||||
* We will assume that someone has paused the RISC processor.
|
||||
*/
|
||||
@ -1333,14 +1477,15 @@ isp_pci_rd_reg_1080(ispsoftc_t *isp, int regoff)
|
||||
}
|
||||
|
||||
static void
|
||||
isp_pci_wr_reg_1080(ispsoftc_t *isp, int regoff, uint16_t val)
|
||||
isp_pci_wr_reg_1080(ispsoftc_t *isp, int regoff, uint32_t val)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
int oc = 0;
|
||||
volatile int junk;
|
||||
|
||||
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
|
||||
(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
|
||||
uint16_t tc;
|
||||
uint32_t tc;
|
||||
/*
|
||||
* We will assume that someone has paused the RISC processor.
|
||||
*/
|
||||
@ -1351,14 +1496,137 @@ isp_pci_wr_reg_1080(ispsoftc_t *isp, int regoff, uint16_t val)
|
||||
else
|
||||
tc |= BIU_PCI1080_CONF1_SXP0;
|
||||
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
|
||||
oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
|
||||
oc | BIU_PCI1080_CONF1_DMA);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
}
|
||||
BXW2(pcs, IspVirt2Off(isp, regoff), val);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, regoff));
|
||||
if (oc) {
|
||||
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
|
||||
junk = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
uint32_t rv;
|
||||
int block = regoff & _BLK_REG_MASK;
|
||||
|
||||
switch (block) {
|
||||
case BIU_BLOCK:
|
||||
break;
|
||||
case MBOX_BLOCK:
|
||||
return (BXR2(pcs, IspVirt2Off(pcs, regoff)));
|
||||
case SXP_BLOCK:
|
||||
isp_prt(isp, ISP_LOGWARN, "SXP_BLOCK read at 0x%x", regoff);
|
||||
return (0xffffffff);
|
||||
case RISC_BLOCK:
|
||||
isp_prt(isp, ISP_LOGWARN, "RISC_BLOCK read at 0x%x", regoff);
|
||||
return (0xffffffff);
|
||||
case DMA_BLOCK:
|
||||
isp_prt(isp, ISP_LOGWARN, "DMA_BLOCK read at 0x%x", regoff);
|
||||
return (0xffffffff);
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGWARN, "unknown block read at 0x%x", regoff);
|
||||
return (0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
switch (regoff) {
|
||||
case BIU2400_FLASH_ADDR:
|
||||
case BIU2400_FLASH_DATA:
|
||||
case BIU2400_ICR:
|
||||
case BIU2400_ISR:
|
||||
case BIU2400_CSR:
|
||||
case BIU2400_REQINP:
|
||||
case BIU2400_REQOUTP:
|
||||
case BIU2400_RSPINP:
|
||||
case BIU2400_RSPOUTP:
|
||||
case BIU2400_PRI_RQINP:
|
||||
case BIU2400_PRI_RSPINP:
|
||||
case BIU2400_ATIO_RSPINP:
|
||||
case BIU2400_ATIO_REQINP:
|
||||
case BIU2400_HCCR:
|
||||
case BIU2400_GPIOD:
|
||||
case BIU2400_GPIOE:
|
||||
case BIU2400_HSEMA:
|
||||
rv = BXR4(pcs, IspVirt2Off(pcs, regoff));
|
||||
break;
|
||||
case BIU2400_R2HSTSLO:
|
||||
rv = BXR4(pcs, IspVirt2Off(pcs, regoff));
|
||||
break;
|
||||
case BIU2400_R2HSTSHI:
|
||||
rv = BXR4(pcs, IspVirt2Off(pcs, regoff)) >> 16;
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"isp_pci_rd_reg_2400: unknown offset %x", regoff);
|
||||
rv = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
|
||||
int block = regoff & _BLK_REG_MASK;
|
||||
volatile int junk;
|
||||
|
||||
switch (block) {
|
||||
case BIU_BLOCK:
|
||||
break;
|
||||
case MBOX_BLOCK:
|
||||
BXW2(pcs, IspVirt2Off(pcs, regoff), val);
|
||||
junk = BXR2(pcs, IspVirt2Off(pcs, regoff));
|
||||
return;
|
||||
case SXP_BLOCK:
|
||||
isp_prt(isp, ISP_LOGWARN, "SXP_BLOCK write at 0x%x", regoff);
|
||||
return;
|
||||
case RISC_BLOCK:
|
||||
isp_prt(isp, ISP_LOGWARN, "RISC_BLOCK write at 0x%x", regoff);
|
||||
return;
|
||||
case DMA_BLOCK:
|
||||
isp_prt(isp, ISP_LOGWARN, "DMA_BLOCK write at 0x%x", regoff);
|
||||
return;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGWARN, "unknown block write at 0x%x",
|
||||
regoff);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (regoff) {
|
||||
case BIU2400_FLASH_ADDR:
|
||||
case BIU2400_FLASH_DATA:
|
||||
case BIU2400_ICR:
|
||||
case BIU2400_ISR:
|
||||
case BIU2400_CSR:
|
||||
case BIU2400_REQINP:
|
||||
case BIU2400_REQOUTP:
|
||||
case BIU2400_RSPINP:
|
||||
case BIU2400_RSPOUTP:
|
||||
case BIU2400_PRI_RQINP:
|
||||
case BIU2400_PRI_RSPINP:
|
||||
case BIU2400_ATIO_RSPINP:
|
||||
case BIU2400_ATIO_REQINP:
|
||||
case BIU2400_HCCR:
|
||||
case BIU2400_GPIOD:
|
||||
case BIU2400_GPIOE:
|
||||
case BIU2400_HSEMA:
|
||||
BXW4(pcs, IspVirt2Off(pcs, regoff), val);
|
||||
junk = BXR4(pcs, IspVirt2Off(pcs, regoff));
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"isp_pci_wr_reg_2400: bad offset 0x%x", regoff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1430,6 +1698,11 @@ isp_pci_mbxdma(ispsoftc_t *isp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (isp->isp_maxcmds == 0) {
|
||||
isp_prt(isp, ISP_LOGERR, "maxcmds not set");
|
||||
return (1);
|
||||
}
|
||||
|
||||
hlim = BUS_SPACE_MAXADDR;
|
||||
if (IS_ULTRA2(isp) || IS_FC(isp) || IS_1240(isp)) {
|
||||
slim = (bus_size_t) (1ULL << 32);
|
||||
@ -1576,8 +1849,8 @@ typedef struct {
|
||||
ispsoftc_t *isp;
|
||||
void *cmd_token;
|
||||
void *rq;
|
||||
uint16_t *nxtip;
|
||||
uint16_t optr;
|
||||
uint32_t *nxtip;
|
||||
uint32_t optr;
|
||||
int error;
|
||||
} mush_t;
|
||||
|
||||
@ -1615,7 +1888,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
bus_dmamap_t *dp;
|
||||
ct_entry_t *cto, *qe;
|
||||
uint8_t scsi_status;
|
||||
uint16_t curi, nxti, handle;
|
||||
uint32_t curi, nxti, handle;
|
||||
uint32_t sflags;
|
||||
int32_t resid;
|
||||
int nth_ctio, nctios, send_status;
|
||||
@ -1855,7 +2128,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
struct ccb_scsiio *csio;
|
||||
ispsoftc_t *isp;
|
||||
ct2_entry_t *cto, *qe;
|
||||
uint16_t curi, nxti;
|
||||
uint32_t curi, nxti;
|
||||
ispds_t *ds;
|
||||
ispds64_t *ds64;
|
||||
int segcnt, seglim;
|
||||
@ -1894,7 +2167,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
"0x%x res %d", cto->ct_rxid, csio->ccb_h.target_lun,
|
||||
cto->ct_iid, cto->ct_flags, cto->ct_status,
|
||||
cto->rsp.m1.ct_scsi_status, cto->ct_resid);
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_put_ctio2e(isp,
|
||||
(ct2e_entry_t *)cto, (ct2e_entry_t *)qe);
|
||||
} else {
|
||||
@ -1933,12 +2206,12 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
if (segcnt != nseg) {
|
||||
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO3;
|
||||
seglim = ISP_RQDSEG_T3;
|
||||
ds64 = &cto->rsp.m0.ct_dataseg64[0];
|
||||
ds64 = &cto->rsp.m0.u.ct_dataseg64[0];
|
||||
ds = NULL;
|
||||
} else {
|
||||
seglim = ISP_RQDSEG_T2;
|
||||
ds64 = NULL;
|
||||
ds = &cto->rsp.m0.ct_dataseg[0];
|
||||
ds = &cto->rsp.m0.u.ct_dataseg[0];
|
||||
}
|
||||
cto->ct_seg_count = 0;
|
||||
|
||||
@ -1973,7 +2246,7 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
}
|
||||
|
||||
while (segcnt < nseg) {
|
||||
uint16_t curip;
|
||||
uint32_t curip;
|
||||
int seg;
|
||||
ispcontreq_t local, *crq = &local, *qep;
|
||||
|
||||
@ -2044,18 +2317,127 @@ tdma_mkfc(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
cto->ct_rxid, csio->ccb_h.target_lun, (int) cto->ct_iid,
|
||||
cto->ct_flags, cto->ct_status, cto->rsp.m1.ct_scsi_status,
|
||||
cto->ct_resid);
|
||||
if (IS_2KLOGIN(isp))
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_put_ctio2e(isp, (ct2e_entry_t *)cto, (ct2e_entry_t *)qe);
|
||||
else
|
||||
} else {
|
||||
isp_put_ctio2(isp, cto, qe);
|
||||
}
|
||||
ISP_TDQE(isp, "last dma2_tgt_fc", curi, qe);
|
||||
*mp->nxtip = nxti;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dma_2400(void *, bus_dma_segment_t *, int, int);
|
||||
static void dma2_a64(void *, bus_dma_segment_t *, int, int);
|
||||
static void dma2(void *, bus_dma_segment_t *, int, int);
|
||||
|
||||
static void
|
||||
dma_2400(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
{
|
||||
mush_t *mp;
|
||||
ispsoftc_t *isp;
|
||||
struct ccb_scsiio *csio;
|
||||
struct isp_pcisoftc *pcs;
|
||||
bus_dmamap_t *dp;
|
||||
bus_dma_segment_t *eseg;
|
||||
ispreqt7_t *rq;
|
||||
int seglim, datalen;
|
||||
uint32_t nxti;
|
||||
|
||||
mp = (mush_t *) arg;
|
||||
if (error) {
|
||||
mp->error = error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (nseg < 1) {
|
||||
isp_prt(mp->isp, ISP_LOGERR, "bad segment count (%d)", nseg);
|
||||
mp->error = EFAULT;
|
||||
return;
|
||||
}
|
||||
|
||||
csio = mp->cmd_token;
|
||||
isp = mp->isp;
|
||||
rq = mp->rq;
|
||||
pcs = (struct isp_pcisoftc *)mp->isp;
|
||||
dp = &pcs->dmaps[isp_handle_index(rq->req_handle)];
|
||||
nxti = *mp->nxtip;
|
||||
|
||||
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
|
||||
bus_dmamap_sync(pcs->dmat, *dp, BUS_DMASYNC_PREREAD);
|
||||
} else {
|
||||
bus_dmamap_sync(pcs->dmat, *dp, BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
datalen = XS_XFRLEN(csio);
|
||||
|
||||
/*
|
||||
* We're passed an initial partially filled in entry that
|
||||
* has most fields filled in except for data transfer
|
||||
* related values.
|
||||
*
|
||||
* Our job is to fill in the initial request queue entry and
|
||||
* then to start allocating and filling in continuation entries
|
||||
* until we've covered the entire transfer.
|
||||
*/
|
||||
|
||||
rq->req_header.rqs_entry_type = RQSTYPE_T7RQS;
|
||||
rq->req_dl = datalen;
|
||||
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
|
||||
rq->req_alen_datadir = 0x2;
|
||||
} else {
|
||||
rq->req_alen_datadir = 0x1;
|
||||
}
|
||||
|
||||
eseg = dm_segs + nseg;
|
||||
|
||||
rq->req_dataseg.ds_base = DMA_LO32(dm_segs->ds_addr);
|
||||
rq->req_dataseg.ds_basehi = DMA_HI32(dm_segs->ds_addr);
|
||||
rq->req_dataseg.ds_count = dm_segs->ds_len;
|
||||
|
||||
datalen -= dm_segs->ds_len;
|
||||
|
||||
dm_segs++;
|
||||
rq->req_seg_count++;
|
||||
|
||||
while (datalen > 0 && dm_segs != eseg) {
|
||||
uint32_t onxti;
|
||||
ispcontreq64_t local, *crq = &local, *cqe;
|
||||
|
||||
cqe = (ispcontreq64_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
|
||||
onxti = nxti;
|
||||
nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp));
|
||||
if (nxti == mp->optr) {
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
|
||||
mp->error = MUSHERR_NOQENTRIES;
|
||||
return;
|
||||
}
|
||||
rq->req_header.rqs_entry_count++;
|
||||
MEMZERO((void *)crq, sizeof (*crq));
|
||||
crq->req_header.rqs_entry_count = 1;
|
||||
crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
|
||||
|
||||
seglim = 0;
|
||||
while (datalen > 0 && seglim < ISP_CDSEG64 && dm_segs != eseg) {
|
||||
crq->req_dataseg[seglim].ds_base =
|
||||
DMA_LO32(dm_segs->ds_addr);
|
||||
crq->req_dataseg[seglim].ds_basehi =
|
||||
DMA_HI32(dm_segs->ds_addr);
|
||||
crq->req_dataseg[seglim].ds_count =
|
||||
dm_segs->ds_len;
|
||||
rq->req_seg_count++;
|
||||
dm_segs++;
|
||||
seglim++;
|
||||
datalen -= dm_segs->ds_len;
|
||||
}
|
||||
if (isp->isp_dblev & ISP_LOGDEBUG1) {
|
||||
isp_print_bytes(isp, "Continuation", QENTRY_LEN, crq);
|
||||
}
|
||||
isp_put_cont64_req(isp, crq, cqe);
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
|
||||
}
|
||||
*mp->nxtip = nxti;
|
||||
}
|
||||
|
||||
static void
|
||||
dma2_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
{
|
||||
@ -2067,7 +2449,7 @@ dma2_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
bus_dma_segment_t *eseg;
|
||||
ispreq64_t *rq;
|
||||
int seglim, datalen;
|
||||
uint16_t nxti;
|
||||
uint32_t nxti;
|
||||
|
||||
mp = (mush_t *) arg;
|
||||
if (error) {
|
||||
@ -2152,7 +2534,7 @@ dma2_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
}
|
||||
|
||||
while (datalen > 0 && dm_segs != eseg) {
|
||||
uint16_t onxti;
|
||||
uint32_t onxti;
|
||||
ispcontreq64_t local, *crq = &local, *cqe;
|
||||
|
||||
cqe = (ispcontreq64_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
|
||||
@ -2181,6 +2563,9 @@ dma2_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
seglim++;
|
||||
datalen -= dm_segs->ds_len;
|
||||
}
|
||||
if (isp->isp_dblev & ISP_LOGDEBUG1) {
|
||||
isp_print_bytes(isp, "Continuation", QENTRY_LEN, crq);
|
||||
}
|
||||
isp_put_cont64_req(isp, crq, cqe);
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
|
||||
}
|
||||
@ -2198,7 +2583,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
bus_dma_segment_t *eseg;
|
||||
ispreq_t *rq;
|
||||
int seglim, datalen;
|
||||
uint16_t nxti;
|
||||
uint32_t nxti;
|
||||
|
||||
mp = (mush_t *) arg;
|
||||
if (error) {
|
||||
@ -2278,7 +2663,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
}
|
||||
|
||||
while (datalen > 0 && dm_segs != eseg) {
|
||||
uint16_t onxti;
|
||||
uint32_t onxti;
|
||||
ispcontreq_t local, *crq = &local, *cqe;
|
||||
|
||||
cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
|
||||
@ -2305,6 +2690,9 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
seglim++;
|
||||
datalen -= dm_segs->ds_len;
|
||||
}
|
||||
if (isp->isp_dblev & ISP_LOGDEBUG1) {
|
||||
isp_print_bytes(isp, "Continuation", QENTRY_LEN, crq);
|
||||
}
|
||||
isp_put_cont_req(isp, crq, cqe);
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
|
||||
}
|
||||
@ -2316,7 +2704,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
*/
|
||||
static int
|
||||
isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
uint16_t *nxtip, uint16_t optr)
|
||||
uint32_t *nxtip, uint32_t optr)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
|
||||
ispreq_t *qep;
|
||||
@ -2348,7 +2736,9 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (sizeof (bus_addr_t) > 4) {
|
||||
if (IS_24XX(isp)) {
|
||||
eptr = dma_2400;
|
||||
} else if (sizeof (bus_addr_t) > 4) {
|
||||
eptr = dma2_a64;
|
||||
} else {
|
||||
eptr = dma2;
|
||||
@ -2433,6 +2823,9 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
return (retval);
|
||||
}
|
||||
mbxsync:
|
||||
if (isp->isp_dblev & ISP_LOGDEBUG1) {
|
||||
isp_print_bytes(isp, "Request Queue Entry", QENTRY_LEN, rq);
|
||||
}
|
||||
switch (rq->req_header.rqs_entry_type) {
|
||||
case RQSTYPE_REQUEST:
|
||||
isp_put_request(isp, rq, qep);
|
||||
@ -2448,12 +2841,15 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
case RQSTYPE_T3RQS:
|
||||
isp_put_request_t3(isp, (ispreqt3_t *) rq, (ispreqt3_t *) qep);
|
||||
break;
|
||||
case RQSTYPE_T7RQS:
|
||||
isp_put_request_t7(isp, (ispreqt7_t *) rq, (ispreqt7_t *) qep);
|
||||
break;
|
||||
}
|
||||
return (CMD_QUEUED);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_pci_dmateardown(ispsoftc_t *isp, XS_T *xs, uint16_t handle)
|
||||
isp_pci_dmateardown(ispsoftc_t *isp, XS_T *xs, uint32_t handle)
|
||||
{
|
||||
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
|
||||
bus_dmamap_t *dp = &pcs->dmaps[isp_handle_index(handle)];
|
||||
@ -2469,10 +2865,12 @@ isp_pci_dmateardown(ispsoftc_t *isp, XS_T *xs, uint16_t handle)
|
||||
static void
|
||||
isp_pci_reset1(ispsoftc_t *isp)
|
||||
{
|
||||
/* Make sure the BIOS is disabled */
|
||||
isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
|
||||
if (!IS_24XX(isp)) {
|
||||
/* Make sure the BIOS is disabled */
|
||||
isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
|
||||
}
|
||||
/* and enable interrupts */
|
||||
ENABLE_INTS(isp);
|
||||
ISP_ENABLE_INTS(isp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -51,15 +51,17 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/isp/isp_freebsd.h>
|
||||
|
||||
static uint16_t isp_sbus_rd_reg(ispsoftc_t *, int);
|
||||
static void isp_sbus_wr_reg(ispsoftc_t *, int, uint16_t);
|
||||
static uint32_t
|
||||
isp_sbus_rd_reg(ispsoftc_t *, int);
|
||||
static void
|
||||
isp_sbus_wr_reg(ispsoftc_t *, int, uint32_t);
|
||||
static int
|
||||
isp_sbus_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
|
||||
isp_sbus_rd_isr(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
|
||||
static int isp_sbus_mbxdma(ispsoftc_t *);
|
||||
static int
|
||||
isp_sbus_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint16_t *, uint16_t);
|
||||
isp_sbus_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t);
|
||||
static void
|
||||
isp_sbus_dmateardown(ispsoftc_t *, XS_T *, uint16_t);
|
||||
isp_sbus_dmateardown(ispsoftc_t *, XS_T *, uint32_t);
|
||||
|
||||
static void isp_sbus_reset1(ispsoftc_t *);
|
||||
static void isp_sbus_dumpregs(ispsoftc_t *, const char *);
|
||||
@ -149,6 +151,7 @@ isp_sbus_attach(device_t dev)
|
||||
struct isp_sbussoftc *sbs;
|
||||
ispsoftc_t *isp = NULL;
|
||||
int locksetup = 0;
|
||||
int ints_setup = 0;
|
||||
|
||||
/*
|
||||
* Figure out if we're supposed to skip this one.
|
||||
@ -184,10 +187,8 @@ isp_sbus_attach(device_t dev)
|
||||
|
||||
regs = NULL;
|
||||
iqd = 0;
|
||||
|
||||
rid = 0;
|
||||
regs =
|
||||
bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
|
||||
regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
|
||||
if (regs == 0) {
|
||||
device_printf(dev, "unable to map registers\n");
|
||||
goto bad;
|
||||
@ -242,21 +243,19 @@ isp_sbus_attach(device_t dev)
|
||||
sbs->sbus_mdvec.dv_conf1 |= BIU_BURST_ENABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some early versions of the PTI SBus adapter
|
||||
* would fail in trying to download (via poking)
|
||||
* FW. We give up on them.
|
||||
*/
|
||||
if (strcmp("PTI,ptisp", ofw_bus_get_name(dev)) == 0 ||
|
||||
strcmp("ptisp", ofw_bus_get_name(dev)) == 0) {
|
||||
isp->isp_confopts |= ISP_CFG_NORELOAD;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't trust NVRAM on SBus cards
|
||||
*/
|
||||
isp->isp_confopts |= ISP_CFG_NONVRAM;
|
||||
|
||||
/*
|
||||
* Mark things if we're a PTI SBus adapter.
|
||||
*/
|
||||
if (strcmp("PTI,ptisp", ofw_bus_get_name(dev)) == 0 ||
|
||||
strcmp("ptisp", ofw_bus_get_name(dev)) == 0) {
|
||||
SDPARAM(isp)->isp_ptisp = 1;
|
||||
}
|
||||
|
||||
|
||||
#if __FreeBSD_version >= 700000
|
||||
isp->isp_osinfo.fw = firmware_get("isp_1000");
|
||||
@ -277,14 +276,6 @@ isp_sbus_attach(device_t dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
iqd = 0;
|
||||
sbs->sbus_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
|
||||
RF_ACTIVE | RF_SHAREABLE);
|
||||
if (sbs->sbus_ires == NULL) {
|
||||
device_printf(dev, "could not allocate interrupt\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
tval = 0;
|
||||
if (resource_int_value(device_get_name(dev), device_get_unit(dev),
|
||||
"fwload_disable", &tval) == 0 && tval != 0) {
|
||||
@ -313,11 +304,20 @@ isp_sbus_attach(device_t dev)
|
||||
mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF);
|
||||
locksetup++;
|
||||
|
||||
iqd = 0;
|
||||
sbs->sbus_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
|
||||
RF_ACTIVE | RF_SHAREABLE);
|
||||
if (sbs->sbus_ires == NULL) {
|
||||
device_printf(dev, "could not allocate interrupt\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (bus_setup_intr(dev, sbs->sbus_ires, ISP_IFLAGS,
|
||||
isp_sbus_intr, isp, &sbs->ih)) {
|
||||
device_printf(dev, "could not setup interrupt\n");
|
||||
goto bad;
|
||||
}
|
||||
ints_setup++;
|
||||
|
||||
/*
|
||||
* Set up logging levels.
|
||||
@ -327,8 +327,9 @@ isp_sbus_attach(device_t dev)
|
||||
} else {
|
||||
isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR;
|
||||
}
|
||||
if (bootverbose)
|
||||
if (bootverbose) {
|
||||
isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we're in reset state.
|
||||
@ -336,6 +337,7 @@ isp_sbus_attach(device_t dev)
|
||||
ISP_LOCK(isp);
|
||||
isp_reset(isp);
|
||||
if (isp->isp_state != ISP_RESETSTATE) {
|
||||
isp_uninit(isp);
|
||||
ISP_UNLOCK(isp);
|
||||
goto bad;
|
||||
}
|
||||
@ -351,42 +353,33 @@ isp_sbus_attach(device_t dev)
|
||||
ISP_UNLOCK(isp);
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* XXXX: Here is where we might unload the f/w module
|
||||
* XXXX: (or decrease the reference count to it).
|
||||
*/
|
||||
ISP_UNLOCK(isp);
|
||||
return (0);
|
||||
|
||||
bad:
|
||||
|
||||
if (sbs && sbs->ih) {
|
||||
if (sbs && ints_setup) {
|
||||
(void) bus_teardown_intr(dev, sbs->sbus_ires, sbs->ih);
|
||||
}
|
||||
|
||||
if (locksetup && isp) {
|
||||
mtx_destroy(&isp->isp_osinfo.lock);
|
||||
}
|
||||
|
||||
if (sbs && sbs->sbus_ires) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, iqd, sbs->sbus_ires);
|
||||
}
|
||||
|
||||
if (locksetup && isp) {
|
||||
mtx_destroy(&isp->isp_osinfo.lock);
|
||||
}
|
||||
|
||||
if (regs) {
|
||||
(void) bus_release_resource(dev, 0, 0, regs);
|
||||
}
|
||||
|
||||
if (sbs) {
|
||||
if (sbs->sbus_isp.isp_param)
|
||||
if (sbs->sbus_isp.isp_param) {
|
||||
free(sbs->sbus_isp.isp_param, M_DEVBUF);
|
||||
}
|
||||
free(sbs, M_DEVBUF);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXXX: Here is where we might unload the f/w module
|
||||
* XXXX: (or decrease the reference count to it).
|
||||
*/
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
@ -394,17 +387,15 @@ static void
|
||||
isp_sbus_intr(void *arg)
|
||||
{
|
||||
ispsoftc_t *isp = arg;
|
||||
uint16_t isr, sema, mbox;
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
|
||||
ISP_LOCK(isp);
|
||||
isp->isp_intcnt++;
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
|
||||
isp->isp_intbogus++;
|
||||
} else {
|
||||
int iok = isp->isp_osinfo.intsok;
|
||||
isp->isp_osinfo.intsok = 0;
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
}
|
||||
ISP_UNLOCK(isp);
|
||||
}
|
||||
@ -417,8 +408,7 @@ isp_sbus_intr(void *arg)
|
||||
bus_space_read_2(sbc->sbus_st, sbc->sbus_sh, off)
|
||||
|
||||
static int
|
||||
isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp,
|
||||
uint16_t *semap, uint16_t *mbp)
|
||||
isp_sbus_rd_isr(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbp)
|
||||
{
|
||||
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
|
||||
uint16_t isr, sema;
|
||||
@ -438,7 +428,7 @@ isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp,
|
||||
return (1);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
static uint32_t
|
||||
isp_sbus_rd_reg(ispsoftc_t *isp, int regoff)
|
||||
{
|
||||
uint16_t rval;
|
||||
@ -452,7 +442,7 @@ isp_sbus_rd_reg(ispsoftc_t *isp, int regoff)
|
||||
}
|
||||
|
||||
static void
|
||||
isp_sbus_wr_reg(ispsoftc_t *isp, int regoff, uint16_t val)
|
||||
isp_sbus_wr_reg(ispsoftc_t *isp, int regoff, uint32_t val)
|
||||
{
|
||||
struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp;
|
||||
int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
|
||||
@ -605,8 +595,8 @@ typedef struct {
|
||||
ispsoftc_t *isp;
|
||||
void *cmd_token;
|
||||
void *rq;
|
||||
uint16_t *nxtip;
|
||||
uint16_t optr;
|
||||
uint32_t *nxtip;
|
||||
uint32_t optr;
|
||||
int error;
|
||||
} mush_t;
|
||||
|
||||
@ -721,7 +711,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
|
||||
static int
|
||||
isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
uint16_t *nxtip, uint16_t optr)
|
||||
uint32_t *nxtip, uint32_t optr)
|
||||
{
|
||||
struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp;
|
||||
ispreq_t *qep;
|
||||
@ -809,6 +799,9 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
return (retval);
|
||||
}
|
||||
mbxsync:
|
||||
if (isp->isp_dblev & ISP_LOGDEBUG1) {
|
||||
isp_print_bytes(isp, "Request Queue Entry", QENTRY_LEN, rq);
|
||||
}
|
||||
switch (rq->req_header.rqs_entry_type) {
|
||||
case RQSTYPE_REQUEST:
|
||||
isp_put_request(isp, rq, qep);
|
||||
@ -822,7 +815,7 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq,
|
||||
}
|
||||
|
||||
static void
|
||||
isp_sbus_dmateardown(ispsoftc_t *isp, XS_T *xs, uint16_t handle)
|
||||
isp_sbus_dmateardown(ispsoftc_t *isp, XS_T *xs, uint32_t handle)
|
||||
{
|
||||
struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp;
|
||||
bus_dmamap_t *dp = &sbs->dmaps[isp_handle_index(handle)];
|
||||
@ -834,12 +827,10 @@ isp_sbus_dmateardown(ispsoftc_t *isp, XS_T *xs, uint16_t handle)
|
||||
bus_dmamap_unload(sbs->dmat, *dp);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
isp_sbus_reset1(ispsoftc_t *isp)
|
||||
{
|
||||
/* enable interrupts */
|
||||
ENABLE_INTS(isp);
|
||||
ISP_ENABLE_INTS(isp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
200
sys/dev/isp/isp_stds.h
Normal file
200
sys/dev/isp/isp_stds.h
Normal file
@ -0,0 +1,200 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
|
||||
*
|
||||
* Copyright (c) 1997-2006 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Structures that derive directly from public standards.
|
||||
*/
|
||||
#ifndef _ISP_STDS_H
|
||||
#define _ISP_STDS_H
|
||||
|
||||
/*
|
||||
* FC Frame Header
|
||||
*
|
||||
* Source: dpANS-X3.xxx-199x, section 18 (AKA FC-PH-2)
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t r_ctl;
|
||||
uint8_t d_id[3];
|
||||
uint8_t cs_ctl;
|
||||
uint8_t s_id[3];
|
||||
uint8_t type;
|
||||
uint8_t f_ctl;
|
||||
uint8_t seq_id;
|
||||
uint8_t df_ctl;
|
||||
uint16_t seq_cnt;
|
||||
uint16_t ox_id;
|
||||
uint16_t rx_id;
|
||||
uint32_t parameter;
|
||||
} fc_hdr_t;
|
||||
|
||||
/*
|
||||
* FCP_CMND_IU Payload
|
||||
*
|
||||
* Source: NICTS T10, Project 1144D, Revision 07a, Section 9 (AKA fcp2-r07a)
|
||||
*
|
||||
* Notes:
|
||||
* When additional cdb length is defined in fcp_cmnd_alen_datadir,
|
||||
* bits 2..7, the actual cdb length is 16 + ((fcp_cmnd_alen_datadir>>2)*4),
|
||||
* with the datalength following in MSB format just after.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t fcp_cmnd_lun[8];
|
||||
uint8_t fcp_cmnd_crn;
|
||||
uint8_t fcp_cmnd_task_attribute;
|
||||
uint8_t fcp_cmnd_task_management;
|
||||
uint8_t fcp_cmnd_alen_datadir;
|
||||
union {
|
||||
struct {
|
||||
uint8_t fcp_cmnd_cdb[16];
|
||||
uint32_t fcp_cmnd_dl;
|
||||
} sf;
|
||||
struct {
|
||||
uint8_t fcp_cmnd_cdb[1];
|
||||
} lf;
|
||||
} cdb_dl;
|
||||
} fcp_cmnd_iu_t;
|
||||
|
||||
|
||||
#define FCP_CMND_TASK_ATTR_SIMPLE 0x00
|
||||
#define FCP_CMND_TASK_ATTR_HEAD 0x01
|
||||
#define FCP_CMND_TASK_ATTR_ORDERED 0x02
|
||||
#define FCP_CMND_TASK_ATTR_ACA 0x04
|
||||
#define FCP_CMND_TASK_ATTR_UNTAGGED 0x05
|
||||
#define FCP_CMND_TASK_ATTR_MASK 0x07
|
||||
|
||||
#define FCP_CMND_ADDTL_CDBLEN_SHIFT 2
|
||||
|
||||
#define FCP_CMND_DATA_WRITE 0x01
|
||||
#define FCP_CMND_DATA_READ 0x02
|
||||
|
||||
#define FCP_CMND_DATA_DIR_MASK 0x03
|
||||
|
||||
#define FCP_CMND_TMF_CLEAR_ACA 0x40
|
||||
#define FCP_CMND_TMF_TGT_RESET 0x20
|
||||
#define FCP_CMND_TMF_LUN_RESET 0x10
|
||||
#define FCP_CMND_TMF_CLEAR_TASK_SET 0x04
|
||||
#define FCP_CMND_TMF_ABORT_TASK_SET 0x02
|
||||
|
||||
/*
|
||||
* Basic CT IU Header
|
||||
*
|
||||
* Source: X3.288-199x Generic Services 2 Rev 5.3 (FC-GS-2) Section 4.3.1
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t ct_revision;
|
||||
uint8_t ct_in_id[3];
|
||||
uint8_t ct_fcs_type;
|
||||
uint8_t ct_fcs_subtype;
|
||||
uint8_t ct_options;
|
||||
uint8_t ct_reserved0;
|
||||
uint16_t ct_cmd_resp;
|
||||
uint16_t ct_bcnt_resid;
|
||||
uint8_t ct_reserved1;
|
||||
uint8_t ct_reason;
|
||||
uint8_t ct_explanation;
|
||||
uint8_t ct_vunique;
|
||||
} ct_hdr_t;
|
||||
#define CT_REVISION 1
|
||||
#define CT_FC_TYPE_FC 0xFC
|
||||
#define CT_FC_SUBTYPE_NS 0x02
|
||||
|
||||
/*
|
||||
* RFT_ID Requet CT_IU
|
||||
*
|
||||
* Source: INCITS xxx-200x Generic Services- 5 Rev 8.5 Section 5.2.5.30
|
||||
*/
|
||||
typedef struct {
|
||||
ct_hdr_t rftid_hdr;
|
||||
uint8_t rftid_reserved;
|
||||
uint8_t rftid_portid[3];
|
||||
uint32_t rftid_fc4types[8];
|
||||
} rft_id_t;
|
||||
|
||||
|
||||
/* unconverted miscellany */
|
||||
/*
|
||||
* Basic FC Link Service defines
|
||||
*/
|
||||
/*
|
||||
* These are in the R_CTL field.
|
||||
*/
|
||||
#define ABTS 0x81
|
||||
#define BA_ACC 0x84 /* of ABORT SEQUENCE */
|
||||
#define BA_RJT 0x85 /* of ABORT SEQUENCE */
|
||||
|
||||
/*
|
||||
* Link Service Accept/Reject
|
||||
*/
|
||||
#define LS_ACC 0x8002
|
||||
#define LS_RJT 0x8001
|
||||
|
||||
/*
|
||||
* FC ELS Codes- bits 31-24 of the first payload word of an ELS frame.
|
||||
*/
|
||||
#define PLOGI 0x03
|
||||
#define FLOGI 0x04
|
||||
#define LOGO 0x05
|
||||
#define ABTX 0x06
|
||||
#define PRLI 0x20
|
||||
#define PRLO 0x21
|
||||
#define TPRLO 0x24
|
||||
#define RNC 0x53
|
||||
|
||||
/*
|
||||
* FC4 defines
|
||||
*/
|
||||
#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP */
|
||||
#define FC4_SCSI 8 /* SCSI-3 via Fibre Channel Protocol (FCP) */
|
||||
#define FC4_FC_SVC 0x20 /* Fibre Channel Services */
|
||||
|
||||
#ifndef MSG_ABORT
|
||||
#define MSG_ABORT 0x06
|
||||
#endif
|
||||
#ifndef MSG_BUS_DEV_RESET
|
||||
#define MSG_BUS_DEV_RESET 0x0c
|
||||
#endif
|
||||
#ifndef MSG_ABORT_TAG
|
||||
#define MSG_ABORT_TAG 0x0d
|
||||
#endif
|
||||
#ifndef MSG_CLEAR_QUEUE
|
||||
#define MSG_CLEAR_QUEUE 0x0e
|
||||
#endif
|
||||
#ifndef MSG_REL_RECOVERY
|
||||
#define MSG_REL_RECOVERY 0x10
|
||||
#endif
|
||||
#ifndef MSG_TERM_IO_PROC
|
||||
#define MSG_TERM_IO_PROC 0x11
|
||||
#endif
|
||||
#ifndef MSG_LUN_RESET
|
||||
#define MSG_LUN_RESET 0x17
|
||||
#endif
|
||||
|
||||
#endif /* _ISP_STDS_H */
|
@ -53,15 +53,17 @@ static const char atiocope[] =
|
||||
"ATIO returned for lun %d because it was in the middle of Bus Device Reset "
|
||||
"on bus %d";
|
||||
static const char atior[] =
|
||||
"ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
|
||||
"on bus %d";
|
||||
"ATIO returned on for lun %d on from loopid %d because a Bus Reset "
|
||||
"occurred on bus %d";
|
||||
|
||||
static void isp_got_msg(ispsoftc_t *, in_entry_t *);
|
||||
static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
|
||||
static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
|
||||
static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
|
||||
static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
|
||||
static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
|
||||
static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
|
||||
static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
|
||||
|
||||
/*
|
||||
* The Qlogic driver gets an interrupt to look at response queue entries.
|
||||
@ -110,42 +112,57 @@ static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
|
||||
*/
|
||||
|
||||
int
|
||||
isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
{
|
||||
uint16_t status, seqid;
|
||||
uint16_t status;
|
||||
uint32_t seqid;
|
||||
union {
|
||||
at_entry_t *atiop;
|
||||
at2_entry_t *at2iop;
|
||||
at2e_entry_t *at2eiop;
|
||||
at7_entry_t *at7iop;
|
||||
ct_entry_t *ctiop;
|
||||
ct2_entry_t *ct2iop;
|
||||
ct2e_entry_t *ct2eiop;
|
||||
ct7_entry_t *ct7iop;
|
||||
lun_entry_t *lunenp;
|
||||
in_entry_t *inotp;
|
||||
in_fcentry_t *inot_fcp;
|
||||
in_fcentry_e_t *inote_fcp;
|
||||
in_fcentry_24xx_t *inot_24xx;
|
||||
na_entry_t *nackp;
|
||||
na_fcentry_t *nack_fcp;
|
||||
na_fcentry_e_t *nacke_fcp;
|
||||
na_fcentry_24xx_t *nack_24xx;
|
||||
isphdr_t *hp;
|
||||
abts_t *abts;
|
||||
abts_rsp_t *abts_rsp;
|
||||
els_t *els;
|
||||
void * *vp;
|
||||
#define atiop unp.atiop
|
||||
#define at2iop unp.at2iop
|
||||
#define at2eiop unp.at2eiop
|
||||
#define at7iop unp.at7iop
|
||||
#define ctiop unp.ctiop
|
||||
#define ct2iop unp.ct2iop
|
||||
#define ct2eiop unp.ct2eiop
|
||||
#define ct7iop unp.ct7iop
|
||||
#define lunenp unp.lunenp
|
||||
#define inotp unp.inotp
|
||||
#define inot_fcp unp.inot_fcp
|
||||
#define inote_fcp unp.inote_fcp
|
||||
#define inot_24xx unp.inot_24xx
|
||||
#define nackp unp.nackp
|
||||
#define nack_fcp unp.nack_fcp
|
||||
#define nacke_fcp unp.nacke_fcp
|
||||
#define nack_24xx unp.nack_24xx
|
||||
#define abts unp.abts
|
||||
#define abts_rsp unp.abts_rsp
|
||||
#define els unp.els
|
||||
#define hdrp unp.hp
|
||||
} unp;
|
||||
uint8_t local[QENTRY_LEN];
|
||||
int bus, type, rval = 1;
|
||||
int bus, type, level, rval = 1;
|
||||
|
||||
type = isp_get_response_type(isp, (isphdr_t *)vptr);
|
||||
unp.vp = vptr;
|
||||
@ -154,30 +171,72 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
|
||||
switch(type) {
|
||||
case RQSTYPE_ATIO:
|
||||
isp_get_atio(isp, atiop, (at_entry_t *) local);
|
||||
isp_handle_atio(isp, (at_entry_t *) local);
|
||||
if (IS_24XX(isp)) {
|
||||
int len;
|
||||
|
||||
isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
|
||||
at7iop = (at7_entry_t *) local;
|
||||
/*
|
||||
* Check for and do something with commands whose IULEN
|
||||
* extends past a singel queue entry.
|
||||
*/
|
||||
len = at7iop->at_ta_len & 0xfffff;
|
||||
if (len > (QENTRY_LEN - 8)) {
|
||||
len -= (QENTRY_LEN - 8);
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"long IU length (%d) ignored", len);
|
||||
while (len > 0) {
|
||||
*optrp = ISP_NXT_QENTRY(*optrp,
|
||||
RESULT_QUEUE_LEN(isp));
|
||||
len -= QENTRY_LEN;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check for a task management function
|
||||
*/
|
||||
if (at7iop->at_cmnd.fcp_cmnd_task_management) {
|
||||
isp_got_tmf_24xx(isp, at7iop);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Just go straight to outer layer for this one.
|
||||
*/
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
|
||||
} else {
|
||||
isp_get_atio(isp, atiop, (at_entry_t *) local);
|
||||
isp_handle_atio(isp, (at_entry_t *) local);
|
||||
}
|
||||
break;
|
||||
|
||||
case RQSTYPE_CTIO:
|
||||
isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
|
||||
isp_handle_ctio(isp, (ct_entry_t *) local);
|
||||
break;
|
||||
|
||||
case RQSTYPE_ATIO2:
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
|
||||
} else {
|
||||
isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
|
||||
}
|
||||
}
|
||||
isp_handle_atio2(isp, (at2_entry_t *) local);
|
||||
break;
|
||||
|
||||
case RQSTYPE_CTIO3:
|
||||
case RQSTYPE_CTIO2:
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
|
||||
} else {
|
||||
isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
|
||||
}
|
||||
}
|
||||
isp_handle_ctio2(isp, (ct2_entry_t *) local);
|
||||
break;
|
||||
|
||||
case RQSTYPE_CTIO7:
|
||||
isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local);
|
||||
isp_handle_ctio7(isp, (ct7_entry_t *) local);
|
||||
break;
|
||||
|
||||
case RQSTYPE_ENABLE_LUN:
|
||||
case RQSTYPE_MODIFY_LUN:
|
||||
isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
|
||||
@ -193,8 +252,36 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
* (we set this initially in the Enable Lun entry).
|
||||
*/
|
||||
bus = 0;
|
||||
if (IS_FC(isp)) {
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (IS_24XX(isp)) {
|
||||
isp_get_notify_24xx(isp, inot_24xx,
|
||||
(in_fcentry_24xx_t *)local);
|
||||
inot_24xx = (in_fcentry_24xx_t *) local;
|
||||
status = inot_24xx->in_status;
|
||||
seqid = inot_24xx->in_rxid;
|
||||
isp_prt(isp, ISP_LOGTDEBUG0,
|
||||
"Immediate Notify status=0x%x seqid=0x%x",
|
||||
status, seqid);
|
||||
switch (status) {
|
||||
case IN24XX_LIP_RESET:
|
||||
case IN24XX_LINK_RESET:
|
||||
case IN24XX_PORT_LOGOUT:
|
||||
case IN24XX_PORT_CHANGED:
|
||||
case IN24XX_LINK_FAILED:
|
||||
case IN24XX_SRR_RCVD:
|
||||
case IN24XX_ELS_RCVD:
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_ACTION,
|
||||
&local);
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"isp_target_notify: unknown status (0x%x)",
|
||||
status);
|
||||
isp_notify_ack(isp, local);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} else if (IS_FC(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_get_notify_fc_e(isp, inote_fcp,
|
||||
(in_fcentry_e_t *)local);
|
||||
} else {
|
||||
@ -229,12 +316,28 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
}
|
||||
break;
|
||||
case IN_RSRC_UNAVAIL:
|
||||
isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
|
||||
isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
|
||||
isp_notify_ack(isp, local);
|
||||
break;
|
||||
case IN_RESET:
|
||||
(void) isp_target_async(isp, 0, ASYNC_BUS_RESET);
|
||||
{
|
||||
/*
|
||||
* We form the notify structure here because we need
|
||||
* to mark it as needing a NOTIFY ACK on return.
|
||||
*/
|
||||
tmd_notify_t notify;
|
||||
|
||||
MEMZERO(¬ify, sizeof (tmd_notify_t));
|
||||
notify.nt_hba = isp;
|
||||
notify.nt_iid = INI_ANY;
|
||||
/* nt_tgt set in outer layers */
|
||||
notify.nt_lun = LUN_ANY;
|
||||
notify.nt_tagval = TAG_ANY;
|
||||
notify.nt_ncode = NT_BUS_RESET;
|
||||
notify.nt_need_ack = 1;
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
}
|
||||
case IN_PORT_LOGOUT:
|
||||
case IN_ABORT_TASK:
|
||||
case IN_PORT_CHANGED:
|
||||
@ -242,8 +345,9 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"bad status (0x%x) in isp_target_notify", status);
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"isp_target_notify: unknown status (0x%x)",
|
||||
status);
|
||||
isp_notify_ack(isp, local);
|
||||
break;
|
||||
}
|
||||
@ -254,26 +358,68 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
* The ISP is acknowledging our acknowledgement of an
|
||||
* Immediate Notify entry for some asynchronous event.
|
||||
*/
|
||||
if (IS_FC(isp)) {
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (IS_24XX(isp)) {
|
||||
isp_get_notify_ack_24xx(isp, nack_24xx,
|
||||
(na_fcentry_24xx_t *) local);
|
||||
nack_24xx = (na_fcentry_24xx_t *) local;
|
||||
if (nack_24xx->na_status != NA_OK) {
|
||||
level = ISP_LOGINFO;
|
||||
} else {
|
||||
level = ISP_LOGTDEBUG1;
|
||||
}
|
||||
isp_prt(isp, level,
|
||||
"Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x",
|
||||
nack_24xx->na_status, nack_24xx->na_status_subcode,
|
||||
nack_24xx->na_rxid);
|
||||
} else if (IS_FC(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_get_notify_ack_fc_e(isp, nacke_fcp,
|
||||
(na_fcentry_e_t *)local);
|
||||
} else {
|
||||
isp_get_notify_ack_fc(isp, nack_fcp,
|
||||
(na_fcentry_t *)local);
|
||||
}
|
||||
}
|
||||
nack_fcp = (na_fcentry_t *)local;
|
||||
isp_prt(isp, ISP_LOGTDEBUG1,
|
||||
"Notify Ack status=0x%x seqid 0x%x",
|
||||
if (nack_fcp->na_status != NA_OK) {
|
||||
level = ISP_LOGINFO;
|
||||
} else {
|
||||
level = ISP_LOGTDEBUG1;
|
||||
}
|
||||
isp_prt(isp, level,
|
||||
"Notify Ack Status=0x%x seqid 0x%x",
|
||||
nack_fcp->na_status, nack_fcp->na_seqid);
|
||||
} else {
|
||||
isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
|
||||
nackp = (na_entry_t *)local;
|
||||
isp_prt(isp, ISP_LOGTDEBUG1,
|
||||
if (nackp->na_status != NA_OK) {
|
||||
level = ISP_LOGINFO;
|
||||
} else {
|
||||
level = ISP_LOGTDEBUG1;
|
||||
}
|
||||
isp_prt(isp, level,
|
||||
"Notify Ack event 0x%x status=0x%x seqid 0x%x",
|
||||
nackp->na_event, nackp->na_status, nackp->na_seqid);
|
||||
}
|
||||
break;
|
||||
|
||||
case RQSTYPE_ABTS_RCVD:
|
||||
isp_get_abts(isp, abts, (abts_t *)local);
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
|
||||
break;
|
||||
case RQSTYPE_ABTS_RSP:
|
||||
isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
|
||||
abts_rsp = (abts_rsp_t *) local;
|
||||
if (abts_rsp->abts_rsp_status) {
|
||||
level = ISP_LOGINFO;
|
||||
} else {
|
||||
level = ISP_LOGTDEBUG0;
|
||||
}
|
||||
isp_prt(isp, level,
|
||||
"ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)",
|
||||
abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status,
|
||||
abts_rsp->abts_rsp_payload.rsp.subcode1,
|
||||
abts_rsp->abts_rsp_payload.rsp.subcode2);
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"Unknown entry type 0x%x in isp_target_notify", type);
|
||||
@ -283,16 +429,23 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
|
||||
#undef atiop
|
||||
#undef at2iop
|
||||
#undef at2eiop
|
||||
#undef at7iop
|
||||
#undef ctiop
|
||||
#undef ct2iop
|
||||
#undef ct2eiop
|
||||
#undef ct7iop
|
||||
#undef lunenp
|
||||
#undef inotp
|
||||
#undef inot_fcp
|
||||
#undef inote_fcp
|
||||
#undef inot_24xx
|
||||
#undef nackp
|
||||
#undef nack_fcp
|
||||
#undef nacke_fcp
|
||||
#undef hack_24xx
|
||||
#undef abts
|
||||
#undef abts_rsp
|
||||
#undef els
|
||||
#undef hdrp
|
||||
return (rval);
|
||||
}
|
||||
@ -312,7 +465,7 @@ isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
|
||||
int cmd_cnt, int inot_cnt, uint32_t opaque)
|
||||
{
|
||||
lun_entry_t el;
|
||||
uint16_t nxti, optr;
|
||||
uint32_t nxti, optr;
|
||||
void *outp;
|
||||
|
||||
|
||||
@ -344,7 +497,7 @@ isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
|
||||
if (IS_SCSI(isp)) {
|
||||
el.le_tgt = tgt;
|
||||
el.le_lun = lun;
|
||||
} else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
|
||||
} else if (FCPARAM(isp)->isp_sccfw == 0) {
|
||||
el.le_lun = lun;
|
||||
}
|
||||
|
||||
@ -364,7 +517,7 @@ int
|
||||
isp_target_put_entry(ispsoftc_t *isp, void *ap)
|
||||
{
|
||||
void *outp;
|
||||
uint16_t nxti, optr;
|
||||
uint32_t nxti, optr;
|
||||
uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
|
||||
|
||||
if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
|
||||
@ -377,28 +530,34 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap)
|
||||
isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
|
||||
break;
|
||||
case RQSTYPE_ATIO2:
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp);
|
||||
} else {
|
||||
isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
|
||||
}
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_put_atio2e(isp, (at2e_entry_t *) ap,
|
||||
(at2e_entry_t *) outp);
|
||||
} else {
|
||||
isp_put_atio2(isp, (at2_entry_t *) ap,
|
||||
(at2_entry_t *) outp);
|
||||
}
|
||||
break;
|
||||
case RQSTYPE_CTIO:
|
||||
isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
|
||||
break;
|
||||
case RQSTYPE_CTIO2:
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp);
|
||||
} else {
|
||||
isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
|
||||
}
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
|
||||
(ct2e_entry_t *) outp);
|
||||
} else {
|
||||
isp_put_ctio2(isp, (ct2_entry_t *) ap,
|
||||
(ct2_entry_t *) outp);
|
||||
}
|
||||
break;
|
||||
case RQSTYPE_CTIO7:
|
||||
isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"Unknown type 0x%x in isp_put_entry", etype);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
|
||||
ISP_ADD_REQUEST(isp, nxti);
|
||||
return (0);
|
||||
@ -418,12 +577,12 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg)
|
||||
at2_entry_t *aep = arg;
|
||||
atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
|
||||
atun._atio2.at_header.rqs_entry_count = 1;
|
||||
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
|
||||
atun._atio2.at_scclun = (uint16_t) aep->at_scclun;
|
||||
if (FCPARAM(isp)->isp_sccfw) {
|
||||
atun._atio2.at_scclun = aep->at_scclun;
|
||||
} else {
|
||||
atun._atio2.at_lun = (uint8_t) aep->at_lun;
|
||||
}
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
|
||||
} else {
|
||||
atun._atio2.at_iid = aep->at_iid;
|
||||
@ -465,28 +624,56 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg)
|
||||
*/
|
||||
|
||||
int
|
||||
isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint16_t hdl)
|
||||
isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
|
||||
{
|
||||
int sts;
|
||||
union {
|
||||
ct_entry_t _ctio;
|
||||
ct2_entry_t _ctio2;
|
||||
ct2e_entry_t _ctio2e;
|
||||
ct7_entry_t _ctio7;
|
||||
} un;
|
||||
|
||||
MEMZERO(&un, sizeof un);
|
||||
sts = code & 0xff;
|
||||
|
||||
if (IS_FC(isp)) {
|
||||
if (IS_24XX(isp)) {
|
||||
at7_entry_t *aep = arg;
|
||||
ct7_entry_t *cto = &un._ctio7;
|
||||
|
||||
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
|
||||
cto->ct_header.rqs_entry_count = 1;
|
||||
/* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id;
|
||||
cto->ct_rxid = aep->at_rxid;
|
||||
cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
|
||||
aep->at_hdr.s_id[2];
|
||||
cto->ct_iid_hi = aep->at_hdr.s_id[0];
|
||||
cto->ct_oxid = aep->at_hdr.ox_id;
|
||||
cto->ct_scsi_status = sts;
|
||||
cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
|
||||
if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
|
||||
cto->rsp.m1.ct_resplen = 16;
|
||||
cto->rsp.m1.ct_resp[0] = 0xf0;
|
||||
cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
|
||||
cto->rsp.m1.ct_resp[7] = 8;
|
||||
cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
|
||||
cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
|
||||
}
|
||||
if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
|
||||
cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
|
||||
cto->ct_scsi_status |= CT2_DATA_UNDER;
|
||||
}
|
||||
cto->ct_syshandle = hdl;
|
||||
} else if (IS_FC(isp)) {
|
||||
at2_entry_t *aep = arg;
|
||||
ct2_entry_t *cto = &un._ctio2;
|
||||
|
||||
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
|
||||
cto->ct_header.rqs_entry_count = 1;
|
||||
if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
|
||||
if (FCPARAM(isp)->isp_sccfw == 0) {
|
||||
cto->ct_lun = aep->at_lun;
|
||||
}
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
|
||||
} else {
|
||||
cto->ct_iid = aep->at_iid;
|
||||
@ -565,6 +752,7 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
|
||||
notify.nt_ncode = NT_LINK_DOWN;
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
case ASYNC_LIP_ERROR:
|
||||
case ASYNC_LIP_F8:
|
||||
case ASYNC_LIP_OCCURRED:
|
||||
case ASYNC_LOOP_RESET:
|
||||
@ -584,7 +772,13 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
|
||||
{
|
||||
uint8_t storage[QENTRY_LEN];
|
||||
memset(storage, 0, QENTRY_LEN);
|
||||
if (IS_FC(isp)) {
|
||||
if (IS_24XX(isp)) {
|
||||
ct7_entry_t *ct = (ct7_entry_t *) storage;
|
||||
ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
|
||||
ct->ct_nphdl = CT7_OK;
|
||||
ct->ct_syshandle = bus;
|
||||
ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
|
||||
} else if (IS_FC(isp)) {
|
||||
/* This should also suffice for 2K login code */
|
||||
ct2_entry_t *ct = (ct2_entry_t *) storage;
|
||||
ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
|
||||
@ -599,7 +793,7 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
|
||||
ct->ct_flags = CT_SENDSTATUS;
|
||||
}
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
@ -679,14 +873,14 @@ static void
|
||||
isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
|
||||
{
|
||||
tmd_notify_t nt;
|
||||
static const char f1[] = "%s from loop id %d lun %d seq 0x%x";
|
||||
static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
|
||||
static const char f2[] =
|
||||
"unknown %s 0x%x lun %d loop id %d task flags 0x%x seq 0x%x\n";
|
||||
"unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n";
|
||||
uint16_t seqid, loopid;
|
||||
|
||||
MEMZERO(&nt, sizeof (tmd_notify_t));
|
||||
nt.nt_hba = isp;
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
|
||||
loopid = ((in_fcentry_e_t *)inp)->in_iid;
|
||||
seqid = ((in_fcentry_e_t *)inp)->in_seqid;
|
||||
@ -696,12 +890,13 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
|
||||
seqid = inp->in_seqid;
|
||||
}
|
||||
/* nt_tgt set in outer layers */
|
||||
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
|
||||
if (FCPARAM(isp)->isp_sccfw) {
|
||||
nt.nt_lun = inp->in_scclun;
|
||||
} else {
|
||||
nt.nt_lun = inp->in_lun;
|
||||
}
|
||||
IN_FC_MAKE_TAGID(nt.nt_tagval, 0, seqid);
|
||||
nt.nt_need_ack = 1;
|
||||
nt.nt_lreserved = inp;
|
||||
|
||||
if (inp->in_status != IN_MSG_RECEIVED) {
|
||||
@ -741,11 +936,69 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
|
||||
{
|
||||
tmd_notify_t nt;
|
||||
static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%x";
|
||||
static const char f2[] =
|
||||
"unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%x\n";
|
||||
uint32_t sid;
|
||||
|
||||
MEMZERO(&nt, sizeof (tmd_notify_t));
|
||||
nt.nt_hba = isp;
|
||||
nt.nt_iid = INI_ANY;
|
||||
nt.nt_lun =
|
||||
(aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
|
||||
(aep->at_cmnd.fcp_cmnd_lun[1]);
|
||||
nt.nt_tagval = aep->at_rxid;
|
||||
nt.nt_lreserved = aep;
|
||||
sid =
|
||||
(aep->at_hdr.s_id[0] << 16) |
|
||||
(aep->at_hdr.s_id[1] << 8) |
|
||||
(aep->at_hdr.s_id[2]);
|
||||
|
||||
if (aep->at_cmnd.fcp_cmnd_task_management &
|
||||
FCP_CMND_TMF_ABORT_TASK_SET) {
|
||||
isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
|
||||
sid, nt.nt_lun, nt.nt_tagval);
|
||||
nt.nt_ncode = NT_ABORT_TASK_SET;
|
||||
} else if (aep->at_cmnd.fcp_cmnd_task_management &
|
||||
FCP_CMND_TMF_CLEAR_TASK_SET) {
|
||||
isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
|
||||
sid, nt.nt_lun, nt.nt_tagval);
|
||||
nt.nt_ncode = NT_CLEAR_TASK_SET;
|
||||
} else if (aep->at_cmnd.fcp_cmnd_task_management &
|
||||
FCP_CMND_TMF_LUN_RESET) {
|
||||
isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
|
||||
sid, nt.nt_lun, nt.nt_tagval);
|
||||
nt.nt_ncode = NT_LUN_RESET;
|
||||
} else if (aep->at_cmnd.fcp_cmnd_task_management &
|
||||
FCP_CMND_TMF_TGT_RESET) {
|
||||
isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
|
||||
sid, nt.nt_lun, nt.nt_tagval);
|
||||
nt.nt_ncode = NT_TARGET_RESET;
|
||||
nt.nt_lun = LUN_ANY;
|
||||
} else if (aep->at_cmnd.fcp_cmnd_task_management &
|
||||
FCP_CMND_TMF_CLEAR_ACA) {
|
||||
isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
|
||||
sid, nt.nt_lun, nt.nt_tagval);
|
||||
nt.nt_ncode = NT_CLEAR_ACA;
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGWARN, f2,
|
||||
aep->at_cmnd.fcp_cmnd_task_management,
|
||||
nt.nt_lun, sid, nt.nt_tagval);
|
||||
isp_endcmd(isp, aep, 0, 0);
|
||||
return;
|
||||
}
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
|
||||
}
|
||||
|
||||
void
|
||||
isp_notify_ack(ispsoftc_t *isp, void *arg)
|
||||
{
|
||||
char storage[QENTRY_LEN];
|
||||
uint16_t nxti, optr;
|
||||
uint32_t nxti, optr;
|
||||
void *outp;
|
||||
|
||||
if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
|
||||
@ -756,14 +1009,49 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
|
||||
|
||||
MEMZERO(storage, QENTRY_LEN);
|
||||
|
||||
if (IS_FC(isp)) {
|
||||
if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
|
||||
at7_entry_t *aep = arg;
|
||||
isp_endcmd(isp, aep, 0, 0);
|
||||
return;
|
||||
} else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
|
||||
abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
|
||||
/*
|
||||
* The caller will have set response values as appropriate
|
||||
* in the ABTS structure just before calling us.
|
||||
*/
|
||||
MEMCPY(abts_rsp, arg, QENTRY_LEN);
|
||||
isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp);
|
||||
} else if (IS_24XX(isp)) {
|
||||
na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
|
||||
if (arg) {
|
||||
in_fcentry_24xx_t *in = arg;
|
||||
na->na_nphdl = in->in_nphdl;
|
||||
na->na_status = in->in_status;
|
||||
na->na_status_subcode = in->in_status_subcode;
|
||||
na->na_rxid = in->in_rxid;
|
||||
na->na_oxid = in->in_oxid;
|
||||
if (in->in_status == IN24XX_SRR_RCVD) {
|
||||
na->na_srr_rxid = in->in_srr_rxid;
|
||||
na->na_srr_reloff_hi = in->in_srr_reloff_hi;
|
||||
na->na_srr_reloff_lo = in->in_srr_reloff_lo;
|
||||
na->na_srr_iu = in->in_srr_iu;
|
||||
na->na_srr_flags = 1;
|
||||
na->na_srr_reject_vunique = 0;
|
||||
na->na_srr_reject_explanation = 1;
|
||||
na->na_srr_reject_code = 1;
|
||||
}
|
||||
}
|
||||
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
|
||||
na->na_header.rqs_entry_count = 1;
|
||||
isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp);
|
||||
} else if (IS_FC(isp)) {
|
||||
na_fcentry_t *na = (na_fcentry_t *) storage;
|
||||
int iid = 0;
|
||||
|
||||
if (arg) {
|
||||
in_fcentry_t *inp = arg;
|
||||
MEMCPY(storage, arg, sizeof (isphdr_t));
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
((na_fcentry_e_t *)na)->na_iid =
|
||||
((in_fcentry_e_t *)inp)->in_iid;
|
||||
iid = ((na_fcentry_e_t *)na)->na_iid;
|
||||
@ -788,14 +1076,14 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
|
||||
}
|
||||
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
|
||||
na->na_header.rqs_entry_count = 1;
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
|
||||
(na_fcentry_e_t *)outp);
|
||||
} else {
|
||||
isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
|
||||
}
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "notify ack iid %u seqid %x flags "
|
||||
"%x tflags %x response %x", iid, na->na_seqid,
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x "
|
||||
"flags %x tflags %x response %x", iid, na->na_seqid,
|
||||
na->na_flags, na->na_task_flags, na->na_response);
|
||||
} else {
|
||||
na_entry_t *na = (na_entry_t *) storage;
|
||||
@ -815,8 +1103,8 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
|
||||
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
|
||||
na->na_header.rqs_entry_count = 1;
|
||||
isp_put_notify_ack(isp, na, (na_entry_t *)outp);
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "notify ack iid %u lun %u tgt %u "
|
||||
"seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt "
|
||||
"%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
|
||||
na->na_seqid, na->na_event);
|
||||
}
|
||||
ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
|
||||
@ -897,7 +1185,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
|
||||
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"Unknown ATIO status 0x%x from initiator %d for lun %d",
|
||||
"Unknown ATIO status 0x%x from loopid %d for lun %d",
|
||||
aep->at_status, aep->at_iid, lun);
|
||||
(void) isp_target_put_atio(isp, aep);
|
||||
break;
|
||||
@ -909,13 +1197,13 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
|
||||
{
|
||||
int lun, iid;
|
||||
|
||||
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
|
||||
if (FCPARAM(isp)->isp_sccfw) {
|
||||
lun = aep->at_scclun;
|
||||
} else {
|
||||
lun = aep->at_lun;
|
||||
}
|
||||
|
||||
if (IS_2KLOGIN(isp)) {
|
||||
if (FCPARAM(isp)->isp_2klogin) {
|
||||
iid = ((at2e_entry_t *)aep)->at_iid;
|
||||
} else {
|
||||
iid = aep->at_iid;
|
||||
@ -986,7 +1274,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
|
||||
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"Unknown ATIO2 status 0x%x from initiator %d for lun %d",
|
||||
"Unknown ATIO2 status 0x%x from loopid %d for lun %d",
|
||||
aep->at_status, iid, lun);
|
||||
(void) isp_target_put_atio(isp, aep);
|
||||
break;
|
||||
@ -1002,8 +1290,9 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
|
||||
|
||||
if (ct->ct_syshandle) {
|
||||
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
|
||||
if (xs == NULL)
|
||||
if (xs == NULL) {
|
||||
pl = ISP_LOGALL;
|
||||
}
|
||||
} else {
|
||||
xs = NULL;
|
||||
}
|
||||
@ -1055,7 +1344,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
|
||||
if (fmsg == NULL)
|
||||
fmsg = "ABORT TAG message sent by Initiator";
|
||||
|
||||
isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
|
||||
break;
|
||||
|
||||
case CT_INVAL:
|
||||
@ -1156,14 +1445,15 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
|
||||
static void
|
||||
isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
{
|
||||
XS_T *xs;
|
||||
void *xs;
|
||||
int pl = ISP_LOGTDEBUG2;
|
||||
char *fmsg = NULL;
|
||||
|
||||
if (ct->ct_syshandle) {
|
||||
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
|
||||
if (xs == NULL)
|
||||
if (xs == NULL) {
|
||||
pl = ISP_LOGALL;
|
||||
}
|
||||
} else {
|
||||
xs = NULL;
|
||||
}
|
||||
@ -1193,7 +1483,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
* status. These CTIOs are handled in that same way as
|
||||
* CT_ABORTED ones, so just fall through here.
|
||||
*/
|
||||
fmsg = "TARGET RESET Task Management Function Received";
|
||||
fmsg = "TARGET RESET";
|
||||
/*FALLTHROUGH*/
|
||||
case CT_RESET:
|
||||
if (fmsg == NULL)
|
||||
@ -1205,11 +1495,12 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
* Bus Free and returns all outstanding CTIOs with the status
|
||||
* set, then sends us an Immediate Notify entry.
|
||||
*/
|
||||
if (fmsg == NULL)
|
||||
fmsg = "ABORT Task Management Function Received";
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "ABORT";
|
||||
}
|
||||
|
||||
isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s: RX_ID=0x%x",
|
||||
fmsg, ct->ct_rxid);
|
||||
isp_prt(isp, ISP_LOGTDEBUG0,
|
||||
"CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
|
||||
break;
|
||||
|
||||
case CT_INVAL:
|
||||
@ -1235,7 +1526,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
if (fmsg == NULL)
|
||||
fmsg = "Port Logout";
|
||||
/*FALLTHROUGH*/
|
||||
case CT_PORTNOTAVAIL:
|
||||
case CT_PORTUNAVAIL:
|
||||
if (fmsg == NULL)
|
||||
fmsg = "Port not available";
|
||||
/*FALLTHROUGH*/
|
||||
@ -1246,7 +1537,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
case CT_NOACK:
|
||||
if (fmsg == NULL)
|
||||
fmsg = "unacknowledged Immediate Notify pending";
|
||||
isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
|
||||
isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
|
||||
break;
|
||||
|
||||
case CT_INVRXID:
|
||||
@ -1254,7 +1545,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
* CTIO rejected by the firmware because an invalid RX_ID.
|
||||
* Just print a message.
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
|
||||
break;
|
||||
|
||||
@ -1312,4 +1603,157 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
|
||||
{
|
||||
void *xs;
|
||||
int pl = ISP_LOGTDEBUG2;
|
||||
char *fmsg = NULL;
|
||||
|
||||
if (ct->ct_syshandle) {
|
||||
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
|
||||
if (xs == NULL) {
|
||||
pl = ISP_LOGALL;
|
||||
}
|
||||
} else {
|
||||
xs = NULL;
|
||||
}
|
||||
|
||||
switch(ct->ct_nphdl) {
|
||||
case CT7_BUS_ERROR:
|
||||
isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
|
||||
/* FALL Through */
|
||||
case CT7_DATA_OVER:
|
||||
case CT7_DATA_UNDER:
|
||||
case CT7_OK:
|
||||
/*
|
||||
* There are generally 2 possibilities as to why we'd get
|
||||
* this condition:
|
||||
* We sent or received data.
|
||||
* We sent status & command complete.
|
||||
*/
|
||||
|
||||
break;
|
||||
|
||||
case CT7_RESET:
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "LIP Reset";
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
case CT7_ABORTED:
|
||||
/*
|
||||
* When an Abort message is received the firmware goes to
|
||||
* Bus Free and returns all outstanding CTIOs with the status
|
||||
* set, then sends us an Immediate Notify entry.
|
||||
*/
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "ABORT";
|
||||
}
|
||||
isp_prt(isp, ISP_LOGTDEBUG0,
|
||||
"CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
|
||||
break;
|
||||
|
||||
case CT7_TIMEOUT:
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "command";
|
||||
}
|
||||
isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
|
||||
break;
|
||||
|
||||
case CT7_ERR:
|
||||
fmsg = "Completed with Error";
|
||||
/*FALLTHROUGH*/
|
||||
case CT7_LOGOUT:
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "Port Logout";
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
case CT7_PORTUNAVAIL:
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "Port not available";
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
case CT7_PORTCHANGED:
|
||||
if (fmsg == NULL) {
|
||||
fmsg = "Port Changed";
|
||||
}
|
||||
isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
|
||||
break;
|
||||
|
||||
case CT7_INVRXID:
|
||||
/*
|
||||
* CTIO rejected by the firmware because an invalid RX_ID.
|
||||
* Just print a message.
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
|
||||
break;
|
||||
|
||||
case CT7_REASSY_ERR:
|
||||
isp_prt(isp, ISP_LOGWARN, "reassembly error");
|
||||
break;
|
||||
|
||||
case CT7_SRR:
|
||||
isp_prt(isp, ISP_LOGWARN, "SRR received");
|
||||
break;
|
||||
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
|
||||
ct->ct_nphdl);
|
||||
break;
|
||||
}
|
||||
|
||||
if (xs == NULL) {
|
||||
/*
|
||||
* There may be more than one CTIO for a data transfer,
|
||||
* or this may be a status CTIO we're not monitoring.
|
||||
*
|
||||
* The assumption is that they'll all be returned in the
|
||||
* order we got them.
|
||||
*/
|
||||
if (ct->ct_syshandle == 0) {
|
||||
if (ct->ct_flags & CT7_TERMINATE) {
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"termination of 0x%x complete",
|
||||
ct->ct_rxid);
|
||||
} else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
|
||||
isp_prt(isp, pl,
|
||||
"intermediate CTIO completed ok");
|
||||
} else {
|
||||
isp_prt(isp, pl,
|
||||
"unmonitored CTIO completed ok");
|
||||
}
|
||||
} else {
|
||||
isp_prt(isp, pl,
|
||||
"NO xs for CTIO (handle 0x%x) status 0x%x",
|
||||
ct->ct_syshandle, ct->ct_nphdl);
|
||||
}
|
||||
} else {
|
||||
if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
|
||||
ISP_DMAFREE(isp, xs, ct->ct_syshandle);
|
||||
}
|
||||
if (ct->ct_flags & CT2_SENDSTATUS) {
|
||||
/*
|
||||
* Sent status and command complete.
|
||||
*
|
||||
* We're now really done with this command, so we
|
||||
* punt to the platform dependent layers because
|
||||
* only there can we do the appropriate command
|
||||
* complete thread synchronization.
|
||||
*/
|
||||
isp_prt(isp, pl, "status CTIO complete");
|
||||
} else {
|
||||
/*
|
||||
* Final CTIO completed. Release DMA resources and
|
||||
* notify platform dependent layers.
|
||||
*/
|
||||
isp_prt(isp, pl, "data CTIO complete");
|
||||
}
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
|
||||
/*
|
||||
* The platform layer will destroy the handle if appropriate.
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -155,28 +155,48 @@ typedef struct {
|
||||
#define TASK_FLAGS_CLEAR_TASK_SET (1<<10)
|
||||
#define TASK_FLAGS_ABORT_TASK_SET (1<<9)
|
||||
|
||||
#ifndef MSG_ABORT
|
||||
#define MSG_ABORT 0x06
|
||||
#endif
|
||||
#ifndef MSG_BUS_DEV_RESET
|
||||
#define MSG_BUS_DEV_RESET 0x0c
|
||||
#endif
|
||||
#ifndef MSG_ABORT_TAG
|
||||
#define MSG_ABORT_TAG 0x0d
|
||||
#endif
|
||||
#ifndef MSG_CLEAR_QUEUE
|
||||
#define MSG_CLEAR_QUEUE 0x0e
|
||||
#endif
|
||||
#ifndef MSG_REL_RECOVERY
|
||||
#define MSG_REL_RECOVERY 0x10
|
||||
#endif
|
||||
#ifndef MSG_TERM_IO_PROC
|
||||
#define MSG_TERM_IO_PROC 0x11
|
||||
#endif
|
||||
#ifndef MSG_LUN_RESET
|
||||
#define MSG_LUN_RESET 0x17
|
||||
#endif
|
||||
/*
|
||||
* ISP24XX Immediate Notify
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t in_header;
|
||||
uint32_t in_reserved;
|
||||
uint16_t in_nphdl;
|
||||
uint16_t in_reserved1;
|
||||
uint16_t in_flags;
|
||||
uint16_t in_srr_rxid;
|
||||
uint16_t in_status;
|
||||
uint8_t in_status_subcode;
|
||||
uint8_t in_reserved2;
|
||||
uint32_t in_rxid;
|
||||
uint16_t in_srr_reloff_lo;
|
||||
uint16_t in_srr_reloff_hi;
|
||||
uint16_t in_srr_iu;
|
||||
uint16_t in_srr_oxid;
|
||||
uint8_t in_reserved3[18];
|
||||
uint8_t in_reserved4;
|
||||
uint8_t in_vpindex;
|
||||
uint32_t in_reserved5;
|
||||
uint16_t in_portid_lo;
|
||||
uint8_t in_portid_hi;
|
||||
uint8_t in_reserved6;
|
||||
uint16_t in_reserved7;
|
||||
uint16_t in_oxid;
|
||||
} in_fcentry_24xx_t;
|
||||
|
||||
#define IN24XX_FLAG_PUREX_IOCB 0x1
|
||||
#define IN24XX_FLAG_GLOBAL_LOGOUT 0x2
|
||||
|
||||
#define IN24XX_LIP_RESET 0x0E
|
||||
#define IN24XX_LINK_RESET 0x0F
|
||||
#define IN24XX_PORT_LOGOUT 0x29
|
||||
#define IN24XX_PORT_CHANGED 0x2A
|
||||
#define IN24XX_LINK_FAILED 0x2E
|
||||
#define IN24XX_SRR_RCVD 0x45
|
||||
#define IN24XX_ELS_RCVD 0x46 /*
|
||||
* login-affectin ELS received- check
|
||||
* subcode for specific opcode
|
||||
*/
|
||||
/*
|
||||
* Notify Acknowledge Entry structure
|
||||
*/
|
||||
@ -234,6 +254,36 @@ typedef struct {
|
||||
#define NAFC_RST_CLRD 0x20 /* Clear LIP Reset */
|
||||
#define NAFC_TVALID 0x10 /* task mangement response code is valid */
|
||||
|
||||
/*
|
||||
* ISP24XX Notify Acknowledge
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
isphdr_t na_header;
|
||||
uint32_t na_handle;
|
||||
uint16_t na_nphdl;
|
||||
uint16_t na_reserved1;
|
||||
uint16_t na_flags;
|
||||
uint16_t na_srr_rxid;
|
||||
uint16_t na_status;
|
||||
uint8_t na_status_subcode;
|
||||
uint8_t na_reserved2;
|
||||
uint32_t na_rxid;
|
||||
uint16_t na_srr_reloff_lo;
|
||||
uint16_t na_srr_reloff_hi;
|
||||
uint16_t na_srr_iu;
|
||||
uint16_t na_srr_flags;
|
||||
uint8_t na_reserved3[18];
|
||||
uint8_t na_reserved4;
|
||||
uint8_t na_vpindex;
|
||||
uint8_t na_srr_reject_vunique;
|
||||
uint8_t na_srr_reject_explanation;
|
||||
uint8_t na_srr_reject_code;
|
||||
uint8_t na_reserved5;
|
||||
uint8_t na_reserved6[6];
|
||||
uint16_t na_oxid;
|
||||
} na_fcentry_24xx_t;
|
||||
|
||||
/*
|
||||
* Accept Target I/O Entry structure
|
||||
*/
|
||||
@ -399,6 +449,32 @@ typedef struct {
|
||||
tid &= ~0xffff; \
|
||||
tid |= (inst << 16)
|
||||
|
||||
/*
|
||||
* 24XX ATIO Definition
|
||||
*
|
||||
* This is *quite* different from other entry types.
|
||||
* First of all, it has its own queue it comes in on.
|
||||
*
|
||||
* Secondly, it doesn't have a normal header.
|
||||
*
|
||||
* Thirdly, it's just a passthru of the FCP CMND IU
|
||||
* which is recorded in big endian mode.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t at_type;
|
||||
uint8_t at_count;
|
||||
/*
|
||||
* Task attribute in high four bits,
|
||||
* the rest is the FCP CMND IU Length.
|
||||
* NB: the command can extend past the
|
||||
* length for a single queue entry.
|
||||
*/
|
||||
uint16_t at_ta_len;
|
||||
uint32_t at_rxid;
|
||||
fc_hdr_t at_hdr;
|
||||
fcp_cmnd_iu_t at_cmnd;
|
||||
} at7_entry_t;
|
||||
|
||||
|
||||
/*
|
||||
* Continue Target I/O Entry structure
|
||||
@ -409,8 +485,7 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint16_t ct_reserved;
|
||||
#define ct_syshandle ct_reserved /* we use this */
|
||||
uint16_t ct_syshandle;
|
||||
uint16_t ct_fwhandle; /* required by f/w */
|
||||
uint8_t ct_lun; /* lun */
|
||||
uint8_t ct_iid; /* initiator id */
|
||||
@ -425,14 +500,7 @@ typedef struct {
|
||||
uint32_t ct_resid; /* residual length */
|
||||
uint16_t ct_timeout;
|
||||
uint16_t ct_seg_count;
|
||||
/*
|
||||
* This is so we can share tag name space with
|
||||
* CTIO{2,3,4} with the minimum of pain.
|
||||
*/
|
||||
union {
|
||||
ispds_t ct_a[ISP_RQDSEG];
|
||||
} _u;
|
||||
#define ct_dataseg _u.ct_a
|
||||
ispds_t ct_dataseg[ISP_RQDSEG];
|
||||
} ct_entry_t;
|
||||
|
||||
/*
|
||||
@ -481,10 +549,10 @@ typedef struct {
|
||||
#define CT_BUS_ERROR 0x10 /* (FC Only) DMA PCI Error */
|
||||
#define CT_PANIC 0x13 /* Unrecoverable Error */
|
||||
#define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */
|
||||
#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
|
||||
#define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */
|
||||
#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
|
||||
#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */
|
||||
#define CT_PORTNOTAVAIL 0x28 /* port not available */
|
||||
#define CT_PORTUNAVAIL 0x28 /* port not available */
|
||||
#define CT_LOGOUT 0x29 /* port logout */
|
||||
#define CT_PORTCHANGED 0x2A /* port changed */
|
||||
#define CT_IDE 0x33 /* Initiator Detected Error */
|
||||
@ -513,8 +581,7 @@ typedef struct {
|
||||
#define MAXRESPLEN 26
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint16_t ct_reserved;
|
||||
uint16_t ct_fwhandle; /* just to match CTIO */
|
||||
uint32_t ct_syshandle;
|
||||
uint8_t ct_lun; /* lun */
|
||||
uint8_t ct_iid; /* initiator id */
|
||||
uint16_t ct_rxid; /* response ID */
|
||||
@ -544,13 +611,10 @@ typedef struct {
|
||||
uint16_t ct_scsi_status;
|
||||
uint32_t ct_xfrlen;
|
||||
union {
|
||||
ispds_t ct_a[ISP_RQDSEG_T2]; /* CTIO2 */
|
||||
ispds64_t ct_b[ISP_RQDSEG_T3]; /* CTIO3 */
|
||||
ispdslist_t ct_c; /* CTIO4 */
|
||||
} _u;
|
||||
#define ct_dataseg _u.ct_a
|
||||
#define ct_dataseg64 _u.ct_b
|
||||
#define ct_dslist _u.ct_c
|
||||
ispds_t ct_dataseg[ISP_RQDSEG_T2];
|
||||
ispds64_t ct_dataseg64[ISP_RQDSEG_T3];
|
||||
ispdslist_t ct_dslist;
|
||||
} u;
|
||||
} m0;
|
||||
struct {
|
||||
uint16_t _reserved;
|
||||
@ -572,8 +636,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint16_t ct_reserved;
|
||||
uint16_t ct_fwhandle; /* just to match CTIO */
|
||||
uint32_t ct_syshandle;
|
||||
uint16_t ct_iid; /* initiator id */
|
||||
uint16_t ct_rxid; /* response ID */
|
||||
uint16_t ct_flags;
|
||||
@ -589,10 +652,10 @@ typedef struct {
|
||||
uint16_t ct_scsi_status;
|
||||
uint32_t ct_xfrlen;
|
||||
union {
|
||||
ispds_t ct_a[ISP_RQDSEG_T2]; /* CTIO2 */
|
||||
ispds64_t ct_b[ISP_RQDSEG_T3]; /* CTIO3 */
|
||||
ispdslist_t ct_c; /* CTIO4 */
|
||||
} _u;
|
||||
ispds_t ct_dataseg[ISP_RQDSEG_T2];
|
||||
ispds64_t ct_dataseg64[ISP_RQDSEG_T3];
|
||||
ispdslist_t ct_dslist;
|
||||
} u;
|
||||
} m0;
|
||||
struct {
|
||||
uint16_t _reserved;
|
||||
@ -615,16 +678,17 @@ typedef struct {
|
||||
/*
|
||||
* ct_flags values for CTIO2
|
||||
*/
|
||||
#define CT2_FLAG_MMASK 0x0003
|
||||
#define CT2_FLAG_MODE0 0x0000
|
||||
#define CT2_FLAG_MODE1 0x0001
|
||||
#define CT2_FLAG_MODE2 0x0002
|
||||
#define CT2_DATA_IN CT_DATA_IN
|
||||
#define CT2_DATA_OUT CT_DATA_OUT
|
||||
#define CT2_NO_DATA CT_NO_DATA
|
||||
#define CT2_DATAMASK CT_DATAMASK
|
||||
#define CT2_FLAG_MMASK 0x0003
|
||||
#define CT2_DATA_IN 0x0040
|
||||
#define CT2_DATA_OUT 0x0080
|
||||
#define CT2_NO_DATA 0x00C0
|
||||
#define CT2_DATAMASK 0x00C0
|
||||
#define CT2_CCINCR 0x0100
|
||||
#define CT2_FASTPOST 0x0200
|
||||
#define CT2_CONFIRM 0x2000
|
||||
#define CT2_TERMINATE 0x4000
|
||||
#define CT2_SENDSTATUS 0x8000
|
||||
|
||||
@ -642,6 +706,183 @@ typedef struct {
|
||||
#define CT2_DATA_OVER 0x0400
|
||||
#define CT2_DATA_UNDER 0x0800
|
||||
|
||||
/*
|
||||
* ISP24XX CTIO
|
||||
*/
|
||||
#define MAXRESPLEN_24XX 24
|
||||
typedef struct {
|
||||
isphdr_t ct_header;
|
||||
uint32_t ct_syshandle;
|
||||
uint16_t ct_nphdl; /* status on returned CTIOs */
|
||||
uint16_t ct_timeout;
|
||||
uint16_t ct_seg_count;
|
||||
uint8_t ct_vpindex;
|
||||
uint8_t ct_xflags;
|
||||
uint16_t ct_iid_lo; /* low 16 bits of portid */
|
||||
uint8_t ct_iid_hi; /* hi 8 bits of portid */
|
||||
uint8_t ct_reserved;
|
||||
uint32_t ct_rxid;
|
||||
uint16_t ct_senselen; /* mode 0 only */
|
||||
uint16_t ct_flags;
|
||||
int32_t ct_resid; /* residual length */
|
||||
uint16_t ct_oxid;
|
||||
uint16_t ct_scsi_status; /* modes 0 && 1 only */
|
||||
union {
|
||||
struct {
|
||||
uint32_t reloff;
|
||||
uint32_t reserved0;
|
||||
uint32_t ct_xfrlen;
|
||||
uint32_t reserved1;
|
||||
ispds64_t ds;
|
||||
} m0;
|
||||
struct {
|
||||
uint16_t ct_resplen;
|
||||
uint16_t reserved;
|
||||
uint8_t ct_resp[MAXRESPLEN_24XX];
|
||||
} m1;
|
||||
struct {
|
||||
uint32_t reserved0;
|
||||
uint32_t ct_datalen;
|
||||
uint32_t reserved1;
|
||||
ispds64_t ct_fcp_rsp_iudata;
|
||||
} m2;
|
||||
} rsp;
|
||||
} ct7_entry_t;
|
||||
|
||||
/*
|
||||
* ct_flags values for CTIO7
|
||||
*/
|
||||
#define CT7_DATA_IN 0x0002
|
||||
#define CT7_DATA_OUT 0x0001
|
||||
#define CT7_NO_DATA 0x0000
|
||||
#define CT7_DATAMASK 0x003
|
||||
#define CT7_DSD_ENABLE 0x0004
|
||||
#define CT7_CONF_STSFD 0x0010
|
||||
#define CT7_EXPLCT_CONF 0x0020
|
||||
#define CT7_FLAG_MODE0 0x0000
|
||||
#define CT7_FLAG_MODE1 0x0040
|
||||
#define CT7_FLAG_MODE7 0x0080
|
||||
#define CT7_FLAG_MMASK 0x00C0
|
||||
#define CT7_FASTPOST 0x0100
|
||||
#define CT7_ATTR_MASK 0x1e00 /* task attributes from atio7 */
|
||||
#define CT7_CONFIRM 0x2000
|
||||
#define CT7_TERMINATE 0x4000
|
||||
#define CT7_SENDSTATUS 0x8000
|
||||
|
||||
/*
|
||||
* Type 7 CTIO status codes
|
||||
*/
|
||||
#define CT7_OK 0x01 /* completed without error */
|
||||
#define CT7_ABORTED 0x02 /* aborted by host */
|
||||
#define CT7_ERR 0x04 /* see sense data for error */
|
||||
#define CT7_INVAL 0x06 /* request for disabled lun */
|
||||
#define CT7_INVRXID 0x08 /* (FC only) Invalid RX_ID */
|
||||
#define CT7_DATA_OVER 0x09 /* (FC only) Data Overrun */
|
||||
#define CT7_TIMEOUT 0x0B /* timed out */
|
||||
#define CT7_RESET 0x0E /* LIP Rset Received */
|
||||
#define CT7_BUS_ERROR 0x10 /* DMA PCI Error */
|
||||
#define CT7_REASSY_ERR 0x11 /* DMA reassembly error */
|
||||
#define CT7_DATA_UNDER 0x15 /* (FC only) Data Underrun */
|
||||
#define CT7_PORTUNAVAIL 0x28 /* port not available */
|
||||
#define CT7_LOGOUT 0x29 /* port logout */
|
||||
#define CT7_PORTCHANGED 0x2A /* port changed */
|
||||
#define CT7_SRR 0x45 /* SRR Received */
|
||||
|
||||
/*
|
||||
* Other 24XX related target IOCBs
|
||||
*/
|
||||
|
||||
/*
|
||||
* ABTS Received
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t abts_header;
|
||||
uint8_t abts_reserved0[6];
|
||||
uint16_t abts_nphdl;
|
||||
uint16_t abts_reserved1;
|
||||
uint16_t abts_sof;
|
||||
uint32_t abts_rxid_abts;
|
||||
uint16_t abts_did_lo;
|
||||
uint8_t abts_did_hi;
|
||||
uint8_t abts_r_ctl;
|
||||
uint16_t abts_sid_lo;
|
||||
uint8_t abts_sid_hi;
|
||||
uint8_t abts_cs_ctl;
|
||||
uint16_t abts_fs_ctl;
|
||||
uint8_t abts_f_ctl;
|
||||
uint8_t abts_type;
|
||||
uint16_t abts_seq_cnt;
|
||||
uint8_t abts_df_ctl;
|
||||
uint8_t abts_seq_id;
|
||||
uint16_t abts_rx_id;
|
||||
uint16_t abts_ox_id;
|
||||
uint32_t abts_param;
|
||||
uint8_t abts_reserved2[16];
|
||||
uint32_t abts_rxid_task;
|
||||
} abts_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t abts_rsp_header;
|
||||
uint32_t abts_rsp_handle;
|
||||
uint16_t abts_rsp_status;
|
||||
uint16_t abts_rsp_nphdl;
|
||||
uint16_t abts_rsp_ctl_flags;
|
||||
uint16_t abts_rsp_sof;
|
||||
uint32_t abts_rsp_rxid_abts;
|
||||
uint16_t abts_rsp_did_lo;
|
||||
uint8_t abts_rsp_did_hi;
|
||||
uint8_t abts_rsp_r_ctl;
|
||||
uint16_t abts_rsp_sid_lo;
|
||||
uint8_t abts_rsp_sid_hi;
|
||||
uint8_t abts_rsp_cs_ctl;
|
||||
uint16_t abts_rsp_f_ctl_lo;
|
||||
uint8_t abts_rsp_f_ctl_hi;
|
||||
uint8_t abts_rsp_type;
|
||||
uint16_t abts_rsp_seq_cnt;
|
||||
uint8_t abts_rsp_df_ctl;
|
||||
uint8_t abts_rsp_seq_id;
|
||||
uint16_t abts_rsp_rx_id;
|
||||
uint16_t abts_rsp_ox_id;
|
||||
uint32_t abts_rsp_param;
|
||||
union {
|
||||
struct {
|
||||
uint16_t reserved;
|
||||
uint8_t last_seq_id;
|
||||
uint8_t seq_id_valid;
|
||||
uint16_t aborted_rx_id;
|
||||
uint16_t aborted_ox_id;
|
||||
uint16_t high_seq_cnt;
|
||||
uint16_t low_seq_cnt;
|
||||
uint8_t reserved2[4];
|
||||
} ba_acc;
|
||||
struct {
|
||||
uint8_t vendor_unique;
|
||||
uint8_t explanation;
|
||||
uint8_t reason;
|
||||
uint8_t reserved;
|
||||
uint8_t reserved2[12];
|
||||
} ba_rjt;
|
||||
struct {
|
||||
uint8_t reserved[8];
|
||||
uint32_t subcode1;
|
||||
uint32_t subcode2;
|
||||
} rsp;
|
||||
uint8_t reserved[16];
|
||||
} abts_rsp_payload;
|
||||
uint32_t abts_rsp_rxid_task;
|
||||
} abts_rsp_t;
|
||||
|
||||
/* terminate this ABTS exchange */
|
||||
#define ISP24XX_ABTS_RSP_TERMINATE 0x01
|
||||
|
||||
#define ISP24XX_ABTS_RSP_COMPLETE 0x00
|
||||
#define ISP24XX_ABTS_RSP_RESET 0x04
|
||||
#define ISP24XX_ABTS_RSP_ABORTED 0x05
|
||||
#define ISP24XX_ABTS_RSP_TIMEOUT 0x06
|
||||
#define ISP24XX_ABTS_RSP_INVXID 0x08
|
||||
#define ISP24XX_ABTS_RSP_LOGOUT 0x29
|
||||
#define ISP24XX_ABTS_RSP_SUBCODE 0x31
|
||||
|
||||
/*
|
||||
* Debug macros
|
||||
*/
|
||||
@ -649,6 +890,7 @@ typedef struct {
|
||||
#define ISP_TDQE(isp, msg, idx, arg) \
|
||||
if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
|
||||
|
||||
#ifndef ISP_TOOLS
|
||||
/*
|
||||
* The functions below are for the publicly available
|
||||
* target mode functions that are internal to the Qlogic driver.
|
||||
@ -657,7 +899,7 @@ typedef struct {
|
||||
/*
|
||||
* This function handles new response queue entry appropriate for target mode.
|
||||
*/
|
||||
int isp_target_notify(ispsoftc_t *, void *, uint16_t *);
|
||||
int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
|
||||
|
||||
/*
|
||||
* This function externalizes the ability to acknowledge an Immediate Notify
|
||||
@ -690,7 +932,7 @@ int isp_target_put_atio(ispsoftc_t *, void *);
|
||||
* General routine to send a final CTIO for a command- used mostly for
|
||||
* local responses.
|
||||
*/
|
||||
int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint16_t);
|
||||
int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint32_t);
|
||||
#define ECMD_SVALID 0x100
|
||||
|
||||
/*
|
||||
@ -699,5 +941,5 @@ int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint16_t);
|
||||
* Return nonzero if the interrupt that generated this event has been dismissed.
|
||||
*/
|
||||
int isp_target_async(ispsoftc_t *, int, int);
|
||||
|
||||
#endif
|
||||
#endif /* _ISP_TARGET_H */
|
||||
|
@ -71,14 +71,29 @@ typedef enum {
|
||||
* in, and the external module to call back with a QIN_HBA_REG that
|
||||
* passes back the corresponding information.
|
||||
*/
|
||||
#define QR_VERSION 10
|
||||
#define QR_VERSION 13
|
||||
typedef struct {
|
||||
void * r_identity;
|
||||
void (*r_action)(qact_e, void *);
|
||||
char r_name[8];
|
||||
int r_inst;
|
||||
int r_version;
|
||||
enum { R_FC, R_SCSI } r_type;
|
||||
struct {
|
||||
enum {
|
||||
R_FC,
|
||||
R_SCSI
|
||||
} r_type;
|
||||
union {
|
||||
struct {
|
||||
uint64_t r_wwnn;
|
||||
uint64_t r_wwpn;
|
||||
} fc;
|
||||
struct {
|
||||
int r_iid;
|
||||
} scsi;
|
||||
} r_id;
|
||||
} r_info;
|
||||
void * r_private;
|
||||
} hba_register_t;
|
||||
|
||||
/*
|
||||
@ -104,7 +119,8 @@ typedef struct tmd_notify {
|
||||
uint64_t nt_iid; /* inititator id */
|
||||
uint64_t nt_tgt; /* target id */
|
||||
uint16_t nt_lun; /* logical unit */
|
||||
uint16_t nt_padding; /* padding */
|
||||
uint16_t : 15,
|
||||
nt_need_ack : 1; /* this notify needs an ACK */
|
||||
uint32_t nt_tagval; /* tag value */
|
||||
tmd_ncode_t nt_ncode; /* action */
|
||||
void * nt_lreserved;
|
||||
@ -251,7 +267,7 @@ typedef struct {
|
||||
#define TMD_SENSELEN 18
|
||||
#endif
|
||||
#ifndef QCDS
|
||||
#define QCDS 8
|
||||
#define QCDS (sizeof (void *))
|
||||
#endif
|
||||
|
||||
typedef struct tmd_cmd {
|
||||
@ -279,7 +295,7 @@ typedef struct tmd_cmd {
|
||||
uint32_t longs[QCDS / sizeof (uint32_t)];
|
||||
uint16_t shorts[QCDS / sizeof (uint16_t)];
|
||||
uint8_t bytes[QCDS];
|
||||
} cd_lreserved[3], cd_hreserved[3];
|
||||
} cd_lreserved[4], cd_hreserved[4];
|
||||
} tmd_cmd_t;
|
||||
|
||||
/* defined tags */
|
||||
|
@ -44,7 +44,7 @@
|
||||
#define MBOX_ABOUT_FIRMWARE 0x0008
|
||||
/* 9 */
|
||||
/* a */
|
||||
/* b */
|
||||
#define MBOX_LOAD_RISC_RAM 0x000b
|
||||
/* c */
|
||||
#define MBOX_WRITE_RAM_WORD_EXTENDED 0x000d
|
||||
#define MBOX_CHECK_FIRMWARE 0x000e
|
||||
@ -123,6 +123,7 @@
|
||||
#define MBOX_GET_FIRMWARE_OPTIONS 0x0028
|
||||
#define MBOX_SET_FIRMWARE_OPTIONS 0x0038
|
||||
#define MBOX_GET_RESOURCE_COUNT 0x0042
|
||||
#define MBOX_REQUEST_OFFLINE_MODE 0x0043
|
||||
#define MBOX_ENHANCED_GET_PDB 0x0047
|
||||
#define MBOX_EXEC_COMMAND_IOCB_A64 0x0054
|
||||
#define MBOX_INIT_FIRMWARE 0x0060
|
||||
@ -148,12 +149,14 @@
|
||||
#define MBOX_DRIVER_HEARTBEAT 0x005B
|
||||
#define MBOX_FW_HEARTBEAT 0x005C
|
||||
|
||||
#define MBOX_GET_SET_DATA_RATE 0x005D /* 23XX only */
|
||||
#define MBGSD_GET_RATE 0
|
||||
#define MBGSD_SET_RATE 1
|
||||
#define MBOX_GET_SET_DATA_RATE 0x005D /* 24XX/23XX only */
|
||||
#define MBGSD_GET_RATE 0
|
||||
#define MBGSD_SET_RATE 1
|
||||
#define MBGSD_SET_RATE_NOW 2 /* 24XX only */
|
||||
#define MBGSD_ONEGB 0
|
||||
#define MBGSD_TWOGB 1
|
||||
#define MBGSD_AUTO 2
|
||||
#define MBGSD_FOURGB 3 /* 24XX only */
|
||||
|
||||
|
||||
#define ISP2100_SET_PCI_PARAM 0x00ff
|
||||
@ -173,6 +176,10 @@
|
||||
#define MBOX_LOOP_ID_USED 0x4008
|
||||
#define MBOX_ALL_IDS_USED 0x4009
|
||||
#define MBOX_NOT_LOGGED_IN 0x400A
|
||||
/* pseudo mailbox completion codes */
|
||||
#define MBOX_REGS_BUSY 0x6000 /* registers in use */
|
||||
#define MBOX_TIMEOUT 0x6001 /* command timed out */
|
||||
|
||||
#define MBLOGALL 0x000f
|
||||
#define MBLOGNONE 0x0000
|
||||
#define MBLOGMASK(x) ((x) & 0xf)
|
||||
@ -199,6 +206,8 @@
|
||||
#define ASYNC_PDB_CHANGED 0x8014
|
||||
#define ASYNC_CHANGE_NOTIFY 0x8015
|
||||
#define ASYNC_LIP_F8 0x8016
|
||||
#define ASYNC_LIP_ERROR 0x8017
|
||||
#define ASYNC_SECURITY_UPDATE 0x801B
|
||||
#define ASYNC_CMD_CMPLT 0x8020
|
||||
#define ASYNC_CTIO_DONE 0x8021
|
||||
#define ASYNC_IP_XMIT_DONE 0x8022
|
||||
@ -221,6 +230,8 @@
|
||||
#define ISP_CONN_LOOPBACK 5
|
||||
#define ASYNC_RIO_RESP 0x8040
|
||||
#define ASYNC_RIO_COMP 0x8042
|
||||
#define ASYNC_RCV_ERR 0x8048
|
||||
|
||||
/*
|
||||
* 2.01.31 2200 Only. Need Bit 13 in Mailbox 1 for Set Firmware Options
|
||||
* mailbox command to enable this.
|
||||
@ -228,20 +239,14 @@
|
||||
#define ASYNC_QFULL_SENT 0x8049
|
||||
|
||||
/*
|
||||
* Mailbox Usages
|
||||
* 24XX only
|
||||
*/
|
||||
#define ASYNC_RJT_SENT 0x8049
|
||||
|
||||
#define WRITE_REQUEST_QUEUE_IN_POINTER(isp, value) \
|
||||
ISP_WRITE(isp, isp->isp_rqstinrp, value)
|
||||
|
||||
#define READ_REQUEST_QUEUE_OUT_POINTER(isp) \
|
||||
ISP_READ(isp, isp->isp_rqstoutrp)
|
||||
|
||||
#define READ_RESPONSE_QUEUE_IN_POINTER(isp) \
|
||||
ISP_READ(isp, isp->isp_respinrp)
|
||||
|
||||
#define WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, value) \
|
||||
ISP_WRITE(isp, isp->isp_respoutrp, value)
|
||||
/*
|
||||
* All IOCB Queue entries are this size
|
||||
*/
|
||||
#define QENTRY_LEN 64
|
||||
|
||||
/*
|
||||
* Command Structure Definitions
|
||||
@ -288,6 +293,7 @@ typedef struct {
|
||||
#define RQSFLAG_FULL 0x02
|
||||
#define RQSFLAG_BADHEADER 0x04
|
||||
#define RQSFLAG_BADPACKET 0x08
|
||||
#define RQSFLAG_MASK 0x0f
|
||||
|
||||
/* RQS entry_type definitions */
|
||||
#define RQSTYPE_REQUEST 0x01
|
||||
@ -307,11 +313,13 @@ typedef struct {
|
||||
#define RQSTYPE_CTIO1 0x0f /* Target Mode */
|
||||
#define RQSTYPE_STATUS_CONT 0x10
|
||||
#define RQSTYPE_T2RQS 0x11
|
||||
#define RQSTYPE_CTIO7 0x12
|
||||
#define RQSTYPE_IP_XMIT 0x13
|
||||
#define RQSTYPE_TSK_MGMT 0x14
|
||||
#define RQSTYPE_T4RQS 0x15
|
||||
#define RQSTYPE_ATIO2 0x16 /* Target Mode */
|
||||
#define RQSTYPE_CTIO2 0x17 /* Target Mode */
|
||||
#define RQSTYPE_CSET0 0x18
|
||||
#define RQSTYPE_T7RQS 0x18
|
||||
#define RQSTYPE_T3RQS 0x19
|
||||
#define RQSTYPE_IP_XMIT_64 0x1b
|
||||
#define RQSTYPE_CTIO4 0x1e /* Target Mode */
|
||||
@ -320,6 +328,12 @@ typedef struct {
|
||||
#define RQSTYPE_RIO2 0x22
|
||||
#define RQSTYPE_IP_RECV 0x23
|
||||
#define RQSTYPE_IP_RECV_CONT 0x24
|
||||
#define RQSTYPE_CT_PASSTHRU 0x29
|
||||
#define RQSTYPE_ABORT_IO 0x33
|
||||
#define RQSTYPE_T6RQS 0x48
|
||||
#define RQSTYPE_LOGIN 0x52
|
||||
#define RQSTYPE_ABTS_RCVD 0x54 /* 24XX only */
|
||||
#define RQSTYPE_ABTS_RSP 0x55 /* 24XX only */
|
||||
|
||||
|
||||
#define ISP_RQDSEG 4
|
||||
@ -329,7 +343,6 @@ typedef struct {
|
||||
uint8_t req_lun_trn;
|
||||
uint8_t req_target;
|
||||
uint16_t req_cdblen;
|
||||
#define req_modifier req_cdblen /* marker packet */
|
||||
uint16_t req_flags;
|
||||
uint16_t req_reserved;
|
||||
uint16_t req_time;
|
||||
@ -337,13 +350,33 @@ typedef struct {
|
||||
uint8_t req_cdb[12];
|
||||
ispds_t req_dataseg[ISP_RQDSEG];
|
||||
} ispreq_t;
|
||||
|
||||
#define ispreq64_t ispreqt3_t /* same as.... */
|
||||
#define ISP_RQDSEG_A64 2
|
||||
|
||||
/*
|
||||
* A request packet can also be a marker packet.
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t mrk_header;
|
||||
uint32_t mrk_handle;
|
||||
uint8_t mrk_reserved0;
|
||||
uint8_t mrk_target;
|
||||
uint16_t mrk_modifier;
|
||||
uint16_t mrk_flags;
|
||||
uint16_t mrk_lun;
|
||||
uint8_t mrk_reserved1[48];
|
||||
} isp_marker_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t mrk_header;
|
||||
uint32_t mrk_handle;
|
||||
uint16_t mrk_nphdl;
|
||||
uint8_t mrk_modifier;
|
||||
uint8_t mrk_reserved0;
|
||||
uint8_t mrk_reserved1;
|
||||
uint8_t mrk_vphdl;
|
||||
uint16_t mrk_reserved2;
|
||||
uint8_t mrk_lun[8];
|
||||
uint8_t mrk_reserved3[40];
|
||||
} isp_marker_24xx_t;
|
||||
|
||||
|
||||
#define SYNC_DEVICE 0
|
||||
#define SYNC_TARGET 1
|
||||
#define SYNC_ALL 2
|
||||
@ -357,7 +390,7 @@ typedef struct {
|
||||
uint8_t req_target;
|
||||
uint16_t req_scclun;
|
||||
uint16_t req_flags;
|
||||
uint16_t _res2;
|
||||
uint16_t req_reserved;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint8_t req_cdb[16];
|
||||
@ -371,7 +404,7 @@ typedef struct {
|
||||
uint16_t req_target;
|
||||
uint16_t req_scclun;
|
||||
uint16_t req_flags;
|
||||
uint16_t _res2;
|
||||
uint16_t req_reserved;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint8_t req_cdb[16];
|
||||
@ -387,13 +420,14 @@ typedef struct {
|
||||
uint8_t req_target;
|
||||
uint16_t req_scclun;
|
||||
uint16_t req_flags;
|
||||
uint16_t _res2;
|
||||
uint16_t req_reserved;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint8_t req_cdb[16];
|
||||
uint32_t req_totalcnt;
|
||||
ispds64_t req_dataseg[ISP_RQDSEG_T3];
|
||||
} ispreqt3_t;
|
||||
#define ispreq64_t ispreqt3_t /* same as.... */
|
||||
|
||||
typedef struct {
|
||||
isphdr_t req_header;
|
||||
@ -401,7 +435,7 @@ typedef struct {
|
||||
uint16_t req_target;
|
||||
uint16_t req_scclun;
|
||||
uint16_t req_flags;
|
||||
uint16_t _res2;
|
||||
uint16_t req_reserved;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint8_t req_cdb[16];
|
||||
@ -437,16 +471,86 @@ typedef struct {
|
||||
uint8_t req_target;
|
||||
uint16_t req_cdblen;
|
||||
uint16_t req_flags;
|
||||
uint16_t _res1;
|
||||
uint16_t req_reserved;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint8_t req_cdb[44];
|
||||
} ispextreq_t;
|
||||
|
||||
/* 24XX only */
|
||||
typedef struct {
|
||||
uint16_t fcd_length;
|
||||
uint16_t fcd_a1500;
|
||||
uint16_t fcd_a3116;
|
||||
uint16_t fcd_a4732;
|
||||
uint16_t fcd_a6348;
|
||||
} fcp_cmnd_ds_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t req_header;
|
||||
uint32_t req_handle;
|
||||
uint16_t req_nphdl;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint16_t req_fc_rsp_dsd_length;
|
||||
uint8_t req_lun[8];
|
||||
uint16_t req_flags;
|
||||
uint16_t req_fc_cmnd_dsd_length;
|
||||
uint16_t req_fc_cmnd_dsd_a1500;
|
||||
uint16_t req_fc_cmnd_dsd_a3116;
|
||||
uint16_t req_fc_cmnd_dsd_a4732;
|
||||
uint16_t req_fc_cmnd_dsd_a6348;
|
||||
uint16_t req_fc_rsp_dsd_a1500;
|
||||
uint16_t req_fc_rsp_dsd_a3116;
|
||||
uint16_t req_fc_rsp_dsd_a4732;
|
||||
uint16_t req_fc_rsp_dsd_a6348;
|
||||
uint32_t req_totalcnt;
|
||||
uint16_t req_tidlo;
|
||||
uint8_t req_tidhi;
|
||||
uint8_t req_vpidx;
|
||||
ispds64_t req_dataseg;
|
||||
} ispreqt6_t;
|
||||
|
||||
typedef struct {
|
||||
isphdr_t req_header;
|
||||
uint32_t req_handle;
|
||||
uint16_t req_nphdl;
|
||||
uint16_t req_time;
|
||||
uint16_t req_seg_count;
|
||||
uint16_t req_reserved;
|
||||
uint8_t req_lun[8];
|
||||
uint8_t req_alen_datadir;
|
||||
uint8_t req_task_management;
|
||||
uint8_t req_task_attribute;
|
||||
uint8_t req_crn;
|
||||
uint8_t req_cdb[16];
|
||||
uint32_t req_dl;
|
||||
uint16_t req_tidlo;
|
||||
uint8_t req_tidhi;
|
||||
uint8_t req_vpidx;
|
||||
ispds64_t req_dataseg;
|
||||
} ispreqt7_t;
|
||||
|
||||
/* I/O Abort Structure */
|
||||
typedef struct {
|
||||
isphdr_t abrt_header;
|
||||
uint32_t abrt_handle;
|
||||
uint16_t abrt_nphdl;
|
||||
uint16_t abrt_options;
|
||||
uint32_t abrt_cmd_handle;
|
||||
uint8_t abrt_reserved[32];
|
||||
uint16_t abrt_tidlo;
|
||||
uint8_t abrt_tidhi;
|
||||
uint8_t abrt_vpidx;
|
||||
uint8_t abrt_reserved1[12];
|
||||
} isp24xx_abrt_t;
|
||||
#define ISP24XX_ABRT_NO_ABTS 0x01 /* don't actually send an ABTS */
|
||||
#define ISP24XX_ABRT_ENXIO 0x31 /* in nphdl on return */
|
||||
|
||||
#define ISP_CDSEG 7
|
||||
typedef struct {
|
||||
isphdr_t req_header;
|
||||
uint32_t _res1;
|
||||
uint32_t req_reserved;
|
||||
ispds_t req_dataseg[ISP_CDSEG];
|
||||
} ispcontreq_t;
|
||||
|
||||
@ -471,11 +575,33 @@ typedef struct {
|
||||
uint8_t req_sense_data[32];
|
||||
} ispstatusreq_t;
|
||||
|
||||
/*
|
||||
* Status Continuation
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t req_header;
|
||||
uint8_t req_sense_data[60];
|
||||
} ispstatus_cont_t;
|
||||
|
||||
/*
|
||||
* 24XX Type 0 status
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t req_header;
|
||||
uint32_t req_handle;
|
||||
uint16_t req_completion_status;
|
||||
uint16_t req_oxid;
|
||||
uint32_t req_resid;
|
||||
uint16_t req_reserved0;
|
||||
uint16_t req_state_flags;
|
||||
uint16_t req_reserved1;
|
||||
uint16_t req_scsi_status;
|
||||
uint32_t req_fcp_residual;
|
||||
uint32_t req_sense_len;
|
||||
uint32_t req_response_len;
|
||||
uint8_t req_rsp_sense[28];
|
||||
} isp24xx_statusreq_t;
|
||||
|
||||
/*
|
||||
* For Qlogic 2X00, the high order byte of SCSI status has
|
||||
* additional meaning.
|
||||
@ -486,6 +612,25 @@ typedef struct {
|
||||
#define RQCS_SV 0x200 /* Sense Length Valid */
|
||||
#define RQCS_RV 0x100 /* FCP Response Length Valid */
|
||||
|
||||
/*
|
||||
* CT Passthru IOCB
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t ctp_header;
|
||||
uint32_t ctp_handle;
|
||||
uint16_t ctp_status;
|
||||
uint16_t ctp_nphdl; /* n-port handle */
|
||||
uint16_t ctp_cmd_cnt; /* Command DSD count */
|
||||
uint16_t ctp_vpidx; /* low 8 bits */
|
||||
uint16_t ctp_time;
|
||||
uint16_t ctp_reserved0;
|
||||
uint16_t ctp_rsp_cnt; /* Response DSD count */
|
||||
uint16_t ctp_reserved1[5];
|
||||
uint32_t ctp_rsp_bcnt; /* Response byte count */
|
||||
uint32_t ctp_cmd_bcnt; /* Command byte count */
|
||||
ispds64_t ctp_dataseg[2];
|
||||
} isp_ct_pt_t;
|
||||
|
||||
/*
|
||||
* Completion Status Codes.
|
||||
*/
|
||||
@ -530,6 +675,13 @@ typedef struct {
|
||||
#define RQCS_PORT_CHANGED 0x002A
|
||||
#define RQCS_PORT_BUSY 0x002B
|
||||
|
||||
/* 24XX Only Completion Codes */
|
||||
#define RQCS_24XX_DRE 0x0011 /* data reassembly error */
|
||||
#define RQCS_24XX_TABORT 0x0013 /* aborted by target */
|
||||
#define RQCS_24XX_ENOMEM 0x002C /* f/w resource unavailable */
|
||||
#define RQCS_24XX_TMO 0x0030 /* task management overrun */
|
||||
|
||||
|
||||
/*
|
||||
* 1X00 specific State Flags
|
||||
*/
|
||||
@ -587,6 +739,7 @@ typedef struct {
|
||||
|
||||
/*
|
||||
* About Firmware returns an 'attribute' word in mailbox 6.
|
||||
* These attributes are for 2200 and 2300.
|
||||
*/
|
||||
#define ISP_FW_ATTR_TMODE 0x01
|
||||
#define ISP_FW_ATTR_SCCLUN 0x02
|
||||
@ -598,8 +751,14 @@ typedef struct {
|
||||
#define ISP_FW_ATTR_VI_SOLARIS 0x80
|
||||
#define ISP_FW_ATTR_2KLOGINS 0x100 /* XXX: just a guess */
|
||||
|
||||
#define IS_2KLOGIN(isp) \
|
||||
(IS_FC(isp) && (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_2KLOGINS))
|
||||
/* and these are for the 2400 */
|
||||
#define ISP2400_FW_ATTR_CLASS2 (1 << 0)
|
||||
#define ISP2400_FW_ATTR_IP (1 << 1)
|
||||
#define ISP2400_FW_ATTR_MULTIID (1 << 2)
|
||||
#define ISP2400_FW_ATTR_SB2 (1 << 3)
|
||||
#define ISP2400_FW_ATTR_T10CRC (1 << 4)
|
||||
#define ISP2400_FW_ATTR_VI (1 << 5)
|
||||
#define ISP2400_FW_ATTR_EXPFW (1 << 13)
|
||||
|
||||
/*
|
||||
* Reduced Interrupt Operation Response Queue Entreis
|
||||
@ -616,7 +775,7 @@ typedef struct {
|
||||
} isp_rio2_t;
|
||||
|
||||
/*
|
||||
* FC (ISP2100) specific data structures
|
||||
* FC (ISP2100/ISP2200/ISP2300/ISP2400) specific data structures
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -624,9 +783,9 @@ typedef struct {
|
||||
*
|
||||
* Version One (prime) format.
|
||||
*/
|
||||
typedef struct isp_icb {
|
||||
typedef struct {
|
||||
uint8_t icb_version;
|
||||
uint8_t _reserved0;
|
||||
uint8_t icb_reserved0;
|
||||
uint16_t icb_fwoptions;
|
||||
uint16_t icb_maxfrmlen;
|
||||
uint16_t icb_maxalloc;
|
||||
@ -648,42 +807,48 @@ typedef struct isp_icb {
|
||||
uint8_t icb_ccnt;
|
||||
uint8_t icb_icnt;
|
||||
uint16_t icb_lunetimeout;
|
||||
uint16_t _reserved1;
|
||||
uint16_t icb_reserved1;
|
||||
uint16_t icb_xfwoptions;
|
||||
uint8_t icb_racctimer;
|
||||
uint8_t icb_idelaytimer;
|
||||
uint16_t icb_zfwoptions;
|
||||
uint16_t _reserved2[13];
|
||||
uint16_t icb_reserved2[13];
|
||||
} isp_icb_t;
|
||||
|
||||
#define ICB_VERSION1 1
|
||||
|
||||
#define ICBOPT_HARD_ADDRESS 0x0001
|
||||
#define ICBOPT_FAIRNESS 0x0002
|
||||
#define ICBOPT_FULL_DUPLEX 0x0004
|
||||
#define ICBOPT_FAST_POST 0x0008
|
||||
#define ICBOPT_TGT_ENABLE 0x0010
|
||||
#define ICBOPT_INI_DISABLE 0x0020
|
||||
#define ICBOPT_INI_ADISC 0x0040
|
||||
#define ICBOPT_INI_TGTTYPE 0x0080
|
||||
#define ICBOPT_PDBCHANGE_AE 0x0100
|
||||
#define ICBOPT_NOLIP 0x0200
|
||||
#define ICBOPT_SRCHDOWN 0x0400
|
||||
#define ICBOPT_PREVLOOP 0x0800
|
||||
#define ICBOPT_STOP_ON_QFULL 0x1000
|
||||
#define ICBOPT_FULL_LOGIN 0x2000
|
||||
#define ICBOPT_BOTH_WWNS 0x4000
|
||||
#define ICBOPT_EXTENDED 0x8000
|
||||
#define ICBOPT_BOTH_WWNS 0x4000
|
||||
#define ICBOPT_FULL_LOGIN 0x2000
|
||||
#define ICBOPT_STOP_ON_QFULL 0x1000 /* 2200/2100 only */
|
||||
#define ICBOPT_PREVLOOP 0x0800
|
||||
#define ICBOPT_SRCHDOWN 0x0400
|
||||
#define ICBOPT_NOLIP 0x0200
|
||||
#define ICBOPT_PDBCHANGE_AE 0x0100
|
||||
#define ICBOPT_INI_TGTTYPE 0x0080
|
||||
#define ICBOPT_INI_ADISC 0x0040
|
||||
#define ICBOPT_INI_DISABLE 0x0020
|
||||
#define ICBOPT_TGT_ENABLE 0x0010
|
||||
#define ICBOPT_FAST_POST 0x0008
|
||||
#define ICBOPT_FULL_DUPLEX 0x0004
|
||||
#define ICBOPT_FAIRNESS 0x0002
|
||||
#define ICBOPT_HARD_ADDRESS 0x0001
|
||||
|
||||
#define ICBXOPT_NO_LOGOUT 0x8000 /* no logout on link failure */
|
||||
#define ICBXOPT_FCTAPE_CCQ 0x4000 /* FC-Tape Command Queueing */
|
||||
#define ICBXOPT_FCTAPE_CONFIRM 0x2000
|
||||
#define ICBXOPT_FCTAPE 0x1000
|
||||
#define ICBXOPT_CLASS2_ACK0 0x0200
|
||||
#define ICBXOPT_CLASS2 0x0100
|
||||
#define ICBXOPT_LOOP_ONLY (0 << 4)
|
||||
#define ICBXOPT_PTP_ONLY (1 << 4)
|
||||
#define ICBXOPT_LOOP_2_PTP (2 << 4)
|
||||
#define ICBXOPT_PTP_2_LOOP (3 << 4)
|
||||
|
||||
#define ICBXOPT_NO_PLAY 0x0080 /* don't play if can't get hard addr */
|
||||
#define ICBXOPT_TOPO_MASK 0x0070
|
||||
#define ICBXOPT_LOOP_ONLY 0x0000
|
||||
#define ICBXOPT_PTP_ONLY 0x0010
|
||||
#define ICBXOPT_LOOP_2_PTP 0x0020
|
||||
#define ICBXOPT_PTP_2_LOOP 0x0030
|
||||
/*
|
||||
* The lower 4 bits of the xfwoptions field are the OPERATION MODE bits.
|
||||
* RIO is not defined for the 23XX cards
|
||||
* RIO is not defined for the 23XX cards (just 2200)
|
||||
*/
|
||||
#define ICBXOPT_RIO_OFF 0
|
||||
#define ICBXOPT_RIO_16BIT 1
|
||||
@ -693,14 +858,60 @@ typedef struct isp_icb {
|
||||
#define ICBXOPT_ZIO 5
|
||||
#define ICBXOPT_TIMER_MASK 0x7
|
||||
|
||||
#define ICBZOPT_ENA_RDXFR_RDY 0x01
|
||||
#define ICBZOPT_ENA_OOF (1 << 6) /* out of order frame handling */
|
||||
#define ICBZOPT_50_OHM 0x0200
|
||||
/* These 3 only apply to the 2300 */
|
||||
#define ICBZOPT_RATE_ONEGB (MBGSD_ONEGB << 14)
|
||||
#define ICBZOPT_RATE_TWOGB (MBGSD_TWOGB << 14)
|
||||
#define ICBZOPT_RATE_AUTO (MBGSD_AUTO << 14)
|
||||
#define ICBZOPT_RATE_MASK 0xC000
|
||||
#define ICBZOPT_RATE_ONEGB 0x0000
|
||||
#define ICBZOPT_RATE_AUTO 0x8000
|
||||
#define ICBZOPT_RATE_TWOGB 0x4000
|
||||
#define ICBZOPT_50_OHM 0x2000
|
||||
#define ICBZOPT_ENA_OOF 0x0040 /* out of order frame handling */
|
||||
#define ICBZOPT_RSPSZ_MASK 0x0030
|
||||
#define ICBZOPT_RSPSZ_24 0x0000
|
||||
#define ICBZOPT_RSPSZ_12 0x0010
|
||||
#define ICBZOPT_RSPSZ_24A 0x0020
|
||||
#define ICBZOPT_RSPSZ_32 0x0030
|
||||
#define ICBZOPT_SOFTID 0x0002
|
||||
#define ICBZOPT_ENA_RDXFR_RDY 0x0001
|
||||
|
||||
/* 2400 F/W options */
|
||||
#define ICB2400_OPT1_BOTH_WWNS 0x00004000
|
||||
#define ICB2400_OPT1_FULL_LOGIN 0x00002000
|
||||
#define ICB2400_OPT1_PREVLOOP 0x00000800
|
||||
#define ICB2400_OPT1_SRCHDOWN 0x00000400
|
||||
#define ICB2400_OPT1_NOLIP 0x00000200
|
||||
#define ICB2400_OPT1_INI_DISABLE 0x00000020
|
||||
#define ICB2400_OPT1_TGT_ENABLE 0x00000010
|
||||
#define ICB2400_OPT1_FULL_DUPLEX 0x00000004
|
||||
#define ICB2400_OPT1_FAIRNESS 0x00000002
|
||||
#define ICB2400_OPT1_HARD_ADDRESS 0x00000001
|
||||
|
||||
#define ICB2400_OPT2_FCTAPE 0x00001000
|
||||
#define ICB2400_OPT2_CLASS2_ACK0 0x00000200
|
||||
#define ICB2400_OPT2_CLASS2 0x00000100
|
||||
#define ICB2400_OPT2_NO_PLAY 0x00000080
|
||||
#define ICB2400_OPT2_TOPO_MASK 0x00000070
|
||||
#define ICB2400_OPT2_LOOP_ONLY 0x00000000
|
||||
#define ICB2400_OPT2_PTP_ONLY 0x00000010
|
||||
#define ICB2400_OPT2_LOOP_2_PTP 0x00000020
|
||||
#define ICB2400_OPT2_PTP_2_LOOP 0x00000030
|
||||
#define ICB2400_OPT2_TIMER_MASK 0x00000007
|
||||
#define ICB2400_OPT2_ZIO 0x00000005
|
||||
#define ICB2400_OPT2_ZIO1 0x00000006
|
||||
|
||||
#define ICB2400_OPT3_75_OHM 0x00010000
|
||||
#define ICB2400_OPT3_RATE_MASK 0x0000E000
|
||||
#define ICB2400_OPT3_RATE_ONEGB 0x00000000
|
||||
#define ICB2400_OPT3_RATE_TWOGB 0x00002000
|
||||
#define ICB2400_OPT3_RATE_AUTO 0x00004000
|
||||
#define ICB2400_OPT3_RATE_FOURGB 0x00006000
|
||||
#define ICB2400_OPT3_ENA_OOF_XFRDY 0x00000200
|
||||
#define ICB2400_OPT3_NO_LOCAL_PLOGI 0x00000080
|
||||
#define ICB2400_OPT3_ENA_OOF 0x00000040
|
||||
/* note that a response size flag of zero is reserved! */
|
||||
#define ICB2400_OPT3_RSPSZ_MASK 0x00000030
|
||||
#define ICB2400_OPT3_RSPSZ_12 0x00000010
|
||||
#define ICB2400_OPT3_RSPSZ_24 0x00000020
|
||||
#define ICB2400_OPT3_RSPSZ_32 0x00000030
|
||||
#define ICB2400_OPT3_SOFTID 0x00000002
|
||||
|
||||
#define ICB_MIN_FRMLEN 256
|
||||
#define ICB_MAX_FRMLEN 2112
|
||||
@ -714,6 +925,41 @@ typedef struct isp_icb {
|
||||
#define ICB_LUN_ENABLE_TOV 180
|
||||
|
||||
|
||||
/*
|
||||
* And somebody at QLogic had a great idea that you could just change
|
||||
* the structure *and* keep the version number the same as the other cards.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t icb_version;
|
||||
uint16_t icb_reserved0;
|
||||
uint16_t icb_maxfrmlen;
|
||||
uint16_t icb_execthrottle;
|
||||
uint16_t icb_xchgcnt;
|
||||
uint16_t icb_hardaddr;
|
||||
uint8_t icb_portname[8];
|
||||
uint8_t icb_nodename[8];
|
||||
uint16_t icb_rspnsin;
|
||||
uint16_t icb_rqstout;
|
||||
uint16_t icb_retry_count;
|
||||
uint16_t icb_priout;
|
||||
uint16_t icb_rsltqlen;
|
||||
uint16_t icb_rqstqlen;
|
||||
uint16_t icb_ldn_nols;
|
||||
uint16_t icb_prqstqlen;
|
||||
uint16_t icb_rqstaddr[4];
|
||||
uint16_t icb_respaddr[4];
|
||||
uint16_t icb_priaddr[4];
|
||||
uint16_t icb_reserved1[4];
|
||||
uint16_t icb_atio_in;
|
||||
uint16_t icb_atioqlen;
|
||||
uint16_t icb_atioqaddr[4];
|
||||
uint16_t icb_idelaytimer;
|
||||
uint16_t icb_logintime;
|
||||
uint32_t icb_fwoptions1;
|
||||
uint32_t icb_fwoptions2;
|
||||
uint32_t icb_fwoptions3;
|
||||
uint16_t icb_reserved2[12];
|
||||
} isp_icb_2400_t;
|
||||
|
||||
#define RQRSP_ADDR0015 0
|
||||
#define RQRSP_ADDR1631 1
|
||||
@ -750,22 +996,6 @@ typedef struct isp_icb {
|
||||
((uint64_t) array[ICB_NNM6] << 48) | \
|
||||
((uint64_t) array[ICB_NNM7] << 56)
|
||||
|
||||
/*
|
||||
* FC-AL Position Map
|
||||
*
|
||||
* This is an at most 128 byte map that returns either
|
||||
* the LILP or Firmware generated list of ports.
|
||||
*
|
||||
* We deviate a bit from the returned qlogic format to
|
||||
* use an extra bit to say whether this was a LILP or
|
||||
* f/w generated map.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t fwmap : 1,
|
||||
count : 7;
|
||||
uint8_t map[127];
|
||||
} fcpos_map_t;
|
||||
|
||||
/*
|
||||
* Port Data Base Element
|
||||
*/
|
||||
@ -774,7 +1004,6 @@ typedef struct {
|
||||
uint16_t pdb_options;
|
||||
uint8_t pdb_mstate;
|
||||
uint8_t pdb_sstate;
|
||||
#define BITS2WORD(x) ((x)[0] << 16 | (x)[3] << 8 | (x)[2])
|
||||
uint8_t pdb_hardaddr_bits[4];
|
||||
uint8_t pdb_portid_bits[4];
|
||||
uint8_t pdb_nodename[8];
|
||||
@ -810,7 +1039,7 @@ typedef struct {
|
||||
uint16_t pdb_loopid;
|
||||
uint16_t pdb_il_ptr;
|
||||
uint16_t pdb_sl_ptr;
|
||||
} isp_pdb_t;
|
||||
} isp_pdb_21xx_t;
|
||||
|
||||
#define PDB_OPTIONS_XMITTING (1<<11)
|
||||
#define PDB_OPTIONS_LNKXMIT (1<<10)
|
||||
@ -835,35 +1064,109 @@ typedef struct {
|
||||
#define SVC3_ROLE_MASK 0x30
|
||||
#define SVC3_ROLE_SHIFT 4
|
||||
|
||||
#define BITS2WORD(x) ((x)[0] << 16 | (x)[3] << 8 | (x)[2])
|
||||
#define BITS2WORD_24XX(x) ((x)[0] << 16 | (x)[1] << 8 | (x)[2])
|
||||
|
||||
/*
|
||||
* CT definition
|
||||
*
|
||||
* This is as the QLogic f/w documentations defines it- which is just opposite,
|
||||
* bit wise, from what the specification defines it as. Additionally, the
|
||||
* ct_response and ct_resid (really from FC-GS-2) need to be byte swapped.
|
||||
* Port Data Base Element- 24XX cards
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t ct_revision;
|
||||
uint8_t ct_portid[3];
|
||||
uint8_t ct_fcs_type;
|
||||
uint8_t ct_fcs_subtype;
|
||||
uint8_t ct_options;
|
||||
uint8_t ct_res0;
|
||||
uint16_t ct_response;
|
||||
uint16_t ct_resid;
|
||||
uint8_t ct_res1;
|
||||
uint8_t ct_reason;
|
||||
uint8_t ct_explanation;
|
||||
uint8_t ct_vunique;
|
||||
} ct_hdr_t;
|
||||
#define FS_ACC 0x8002
|
||||
#define FS_RJT 0x8001
|
||||
uint16_t pdb_flags;
|
||||
uint8_t pdb_curstate;
|
||||
uint8_t pdb_laststate;
|
||||
uint8_t pdb_hardaddr_bits[4];
|
||||
uint8_t pdb_portid_bits[4];
|
||||
#define pdb_nxt_seqid_2400 pdb_portid_bits[3]
|
||||
uint16_t pdb_retry_timer;
|
||||
uint16_t pdb_handle;
|
||||
uint16_t pdb_rcv_dsize;
|
||||
uint16_t pdb_reserved0;
|
||||
uint16_t pdb_prli_svc0;
|
||||
uint16_t pdb_prli_svc3;
|
||||
uint8_t pdb_portname[8];
|
||||
uint8_t pdb_nodename[8];
|
||||
uint8_t pdb_reserved1[24];
|
||||
} isp_pdb_24xx_t;
|
||||
|
||||
#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP "Out of Order Delivery" */
|
||||
#define FC4_SCSI 8 /* SCSI-3 via Fivre Channel Protocol (FCP) */
|
||||
#define FC4_FC_SVC 0x20 /* Fibre Channel Services */
|
||||
#define PDB2400_TID_SUPPORTED 0x4000
|
||||
#define PDB2400_FC_TAPE 0x0080
|
||||
#define PDB2400_CLASS2_ACK0 0x0040
|
||||
#define PDB2400_FCP_CONF 0x0020
|
||||
#define PDB2400_CLASS2 0x0010
|
||||
#define PDB2400_ADDR_VALID 0x0002
|
||||
|
||||
/*
|
||||
* Common elements from the above two structures that are actually useful to us.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t handle;
|
||||
uint16_t reserved;
|
||||
uint32_t s3_role : 8,
|
||||
portid : 24;
|
||||
uint8_t portname[8];
|
||||
uint8_t nodename[8];
|
||||
} isp_pdb_t;
|
||||
|
||||
/*
|
||||
* ISP24XX- Login/Logout Port IOCB
|
||||
*/
|
||||
typedef struct {
|
||||
isphdr_t plogx_header;
|
||||
uint32_t plogx_handle;
|
||||
uint16_t plogx_status;
|
||||
uint16_t plogx_nphdl;
|
||||
uint16_t plogx_flags;
|
||||
uint16_t plogx_vphdl; /* low 8 bits */
|
||||
uint16_t plogx_portlo; /* low 16 bits */
|
||||
uint16_t plogx_rspsz_porthi;
|
||||
struct {
|
||||
uint16_t lo16;
|
||||
uint16_t hi16;
|
||||
} plogx_ioparm[11];
|
||||
} isp_plogx_t;
|
||||
|
||||
#define PLOGX_STATUS_OK 0x00
|
||||
#define PLOGX_STATUS_UNAVAIL 0x28
|
||||
#define PLOGX_STATUS_LOGOUT 0x29
|
||||
#define PLOGX_STATUS_IOCBERR 0x31
|
||||
|
||||
#define PLOGX_IOCBERR_NOLINK 0x01
|
||||
#define PLOGX_IOCBERR_NOIOCB 0x02
|
||||
#define PLOGX_IOCBERR_NOXGHG 0x03
|
||||
#define PLOGX_IOCBERR_FAILED 0x04 /* further info in IOPARM 1 */
|
||||
#define PLOGX_IOCBERR_NOFABRIC 0x05
|
||||
#define PLOGX_IOCBERR_NOTREADY 0x07
|
||||
#define PLOGX_IOCBERR_NOLOGIN 0x08 /* further info in IOPARM 1 */
|
||||
#define PLOGX_IOCBERR_NOPCB 0x0a
|
||||
#define PLOGX_IOCBERR_REJECT 0x18 /* further info in IOPARM 1 */
|
||||
#define PLOGX_IOCBERR_EINVAL 0x19 /* further info in IOPARM 1 */
|
||||
#define PLOGX_IOCBERR_PORTUSED 0x1a /* further info in IOPARM 1 */
|
||||
#define PLOGX_IOCBERR_HNDLUSED 0x1b /* further info in IOPARM 1 */
|
||||
#define PLOGX_IOCBERR_NOHANDLE 0x1c
|
||||
#define PLOGX_IOCBERR_NOFLOGI 0x1f /* further info in IOPARM 1 */
|
||||
|
||||
#define PLOGX_FLG_CMD_MASK 0xf
|
||||
#define PLOGX_FLG_CMD_PLOGI 0
|
||||
#define PLOGX_FLG_CMD_PRLI 1
|
||||
#define PLOGX_FLG_CMD_PDISC 2
|
||||
#define PLOGX_FLG_CMD_LOGO 8
|
||||
#define PLOGX_FLG_CMD_PRLO 9
|
||||
#define PLOGX_FLG_CMD_TPRLO 10
|
||||
|
||||
#define PLOGX_FLG_COND_PLOGI 0x10 /* if with PLOGI */
|
||||
#define PLOGX_FLG_IMPLICIT 0x10 /* if with LOGO, PRLO, TPRLO */
|
||||
#define PLOGX_FLG_SKIP_PRLI 0x20 /* if with PLOGI */
|
||||
#define PLOGX_FLG_IMPLICIT_LOGO_ALL 0x20 /* if with LOGO */
|
||||
#define PLOGX_FLG_EXPLICIT_LOGO 0x40 /* if with LOGO */
|
||||
#define PLOGX_FLG_COMMON_FEATURES 0x80 /* if with PLOGI */
|
||||
#define PLOGX_FLG_FREE_NPHDL 0x80 /* if with with LOGO */
|
||||
|
||||
#define PLOGX_FLG_CLASS2 0x100 /* if with PLOGI */
|
||||
#define PLOGX_FLG_FCP2_OVERRIDE 0x200 /* if with PRLOG, PRLI */
|
||||
|
||||
/*
|
||||
* Simple Name Server Data Structures
|
||||
*/
|
||||
#define SNS_GA_NXT 0x100
|
||||
#define SNS_GPN_ID 0x112
|
||||
#define SNS_GNN_ID 0x113
|
||||
@ -872,61 +1175,61 @@ typedef struct {
|
||||
#define SNS_RFT_ID 0x217
|
||||
typedef struct {
|
||||
uint16_t snscb_rblen; /* response buffer length (words) */
|
||||
uint16_t snscb_res0;
|
||||
uint16_t snscb_reserved0;
|
||||
uint16_t snscb_addr[4]; /* response buffer address */
|
||||
uint16_t snscb_sblen; /* subcommand buffer length (words) */
|
||||
uint16_t snscb_res1;
|
||||
uint16_t snscb_reserved1;
|
||||
uint16_t snscb_data[1]; /* variable data */
|
||||
} sns_screq_t; /* Subcommand Request Structure */
|
||||
|
||||
typedef struct {
|
||||
uint16_t snscb_rblen; /* response buffer length (words) */
|
||||
uint16_t snscb_res0;
|
||||
uint16_t snscb_reserved0;
|
||||
uint16_t snscb_addr[4]; /* response buffer address */
|
||||
uint16_t snscb_sblen; /* subcommand buffer length (words) */
|
||||
uint16_t snscb_res1;
|
||||
uint16_t snscb_reserved1;
|
||||
uint16_t snscb_cmd;
|
||||
uint16_t snscb_res2;
|
||||
uint32_t snscb_res3;
|
||||
uint16_t snscb_reserved2;
|
||||
uint32_t snscb_reserved3;
|
||||
uint32_t snscb_port;
|
||||
} sns_ga_nxt_req_t;
|
||||
#define SNS_GA_NXT_REQ_SIZE (sizeof (sns_ga_nxt_req_t))
|
||||
|
||||
typedef struct {
|
||||
uint16_t snscb_rblen; /* response buffer length (words) */
|
||||
uint16_t snscb_res0;
|
||||
uint16_t snscb_reserved0;
|
||||
uint16_t snscb_addr[4]; /* response buffer address */
|
||||
uint16_t snscb_sblen; /* subcommand buffer length (words) */
|
||||
uint16_t snscb_res1;
|
||||
uint16_t snscb_reserved1;
|
||||
uint16_t snscb_cmd;
|
||||
uint16_t snscb_res2;
|
||||
uint32_t snscb_res3;
|
||||
uint16_t snscb_reserved2;
|
||||
uint32_t snscb_reserved3;
|
||||
uint32_t snscb_portid;
|
||||
} sns_gxn_id_req_t;
|
||||
#define SNS_GXN_ID_REQ_SIZE (sizeof (sns_gxn_id_req_t))
|
||||
|
||||
typedef struct {
|
||||
uint16_t snscb_rblen; /* response buffer length (words) */
|
||||
uint16_t snscb_res0;
|
||||
uint16_t snscb_reserved0;
|
||||
uint16_t snscb_addr[4]; /* response buffer address */
|
||||
uint16_t snscb_sblen; /* subcommand buffer length (words) */
|
||||
uint16_t snscb_res1;
|
||||
uint16_t snscb_reserved1;
|
||||
uint16_t snscb_cmd;
|
||||
uint16_t snscb_mword_div_2;
|
||||
uint32_t snscb_res3;
|
||||
uint32_t snscb_reserved3;
|
||||
uint32_t snscb_fc4_type;
|
||||
} sns_gid_ft_req_t;
|
||||
#define SNS_GID_FT_REQ_SIZE (sizeof (sns_gid_ft_req_t))
|
||||
|
||||
typedef struct {
|
||||
uint16_t snscb_rblen; /* response buffer length (words) */
|
||||
uint16_t snscb_res0;
|
||||
uint16_t snscb_reserved0;
|
||||
uint16_t snscb_addr[4]; /* response buffer address */
|
||||
uint16_t snscb_sblen; /* subcommand buffer length (words) */
|
||||
uint16_t snscb_res1;
|
||||
uint16_t snscb_reserved1;
|
||||
uint16_t snscb_cmd;
|
||||
uint16_t snscb_res2;
|
||||
uint32_t snscb_res3;
|
||||
uint16_t snscb_reserved2;
|
||||
uint32_t snscb_reserved3;
|
||||
uint32_t snscb_port;
|
||||
uint32_t snscb_fc4_types[8];
|
||||
} sns_rft_id_req_t;
|
||||
@ -980,7 +1283,68 @@ typedef struct {
|
||||
} snscb_ports[1];
|
||||
} sns_gid_ft_rsp_t;
|
||||
#define SNS_GID_FT_RESP_SIZE(x) ((sizeof (sns_gid_ft_rsp_t)) + ((x - 1) << 2))
|
||||
|
||||
#define SNS_RFT_ID_RESP_SIZE (sizeof (ct_hdr_t))
|
||||
|
||||
/*
|
||||
* Other Misc Structures
|
||||
*/
|
||||
|
||||
/* ELS Pass Through */
|
||||
typedef struct {
|
||||
isphdr_t els_hdr;
|
||||
uint32_t els_handle;
|
||||
uint16_t els_status;
|
||||
uint16_t els_nphdl;
|
||||
uint16_t els_xmit_dsd_count; /* outgoing only */
|
||||
uint8_t els_vphdl;
|
||||
uint8_t els_sof;
|
||||
uint32_t els_rxid;
|
||||
uint16_t els_recv_dsd_count; /* outgoing only */
|
||||
uint8_t els_opcode;
|
||||
uint8_t els_reserved1;
|
||||
uint8_t els_did_lo;
|
||||
uint8_t els_did_mid;
|
||||
uint8_t els_did_hi;
|
||||
uint8_t els_reserved2;
|
||||
uint16_t els_reserved3;
|
||||
uint16_t els_ctl_flags;
|
||||
union {
|
||||
struct {
|
||||
uint32_t _els_bytecnt;
|
||||
uint32_t _els_subcode1;
|
||||
uint32_t _els_subcode2;
|
||||
uint8_t _els_reserved4[20];
|
||||
} in;
|
||||
struct {
|
||||
uint32_t _els_recv_bytecnt;
|
||||
uint32_t _els_xmit_bytecnt;
|
||||
uint32_t _els_xmit_dsd_length;
|
||||
uint16_t _els_xmit_dsd_a1500;
|
||||
uint16_t _els_xmit_dsd_a3116;
|
||||
uint16_t _els_xmit_dsd_a4732;
|
||||
uint16_t _els_xmit_dsd_a6348;
|
||||
uint32_t _els_recv_dsd_length;
|
||||
uint16_t _els_recv_dsd_a1500;
|
||||
uint16_t _els_recv_dsd_a3116;
|
||||
uint16_t _els_recv_dsd_a4732;
|
||||
uint16_t _els_recv_dsd_a6348;
|
||||
} out;
|
||||
} inout;
|
||||
#define els_bytecnt inout.in._els_bytecnt
|
||||
#define els_subcode1 inout.in._els_subcode1
|
||||
#define els_subcode2 inout.in._els_subcode2
|
||||
#define els_reserved4 inout.in._els_reserved4
|
||||
#define els_recv_bytecnt inout.out._els_recv_bytecnt
|
||||
#define els_xmit_bytecnt inout.out._els_xmit_bytecnt
|
||||
#define els_xmit_dsd_length inout.out._els_xmit_dsd_length
|
||||
#define els_xmit_dsd_a1500 inout.out._els_xmit_dsd_a1500
|
||||
#define els_xmit_dsd_a3116 inout.out._els_xmit_dsd_a3116
|
||||
#define els_xmit_dsd_a4732 inout.out._els_xmit_dsd_a4732
|
||||
#define els_xmit_dsd_a6348 inout.out._els_xmit_dsd_a6348
|
||||
#define els_recv_dsd_length inout.out._els_recv_dsd_length
|
||||
#define els_recv_dsd_a1500 inout.out._els_recv_dsd_a1500
|
||||
#define els_recv_dsd_a3116 inout.out._els_recv_dsd_a3116
|
||||
#define els_recv_dsd_a4732 inout.out._els_recv_dsd_a4732
|
||||
#define els_recv_dsd_a6348 inout.out._els_recv_dsd_a6348
|
||||
} els_t;
|
||||
#endif /* _ISPMBOX_H */
|
||||
|
@ -64,6 +64,7 @@
|
||||
#define PCI_MBOX_REGS_OFF 0x70
|
||||
#define PCI_MBOX_REGS2100_OFF 0x10
|
||||
#define PCI_MBOX_REGS2300_OFF 0x40
|
||||
#define PCI_MBOX_REGS2400_OFF 0x80
|
||||
#define SBUS_MBOX_REGS_OFF 0x80
|
||||
|
||||
#define PCI_SXP_REGS_OFF 0x80
|
||||
@ -110,12 +111,6 @@
|
||||
#define BIU_NVRAM (BIU_BLOCK+0xE) /* RW : Bus NVRAM */
|
||||
/*
|
||||
* These are specific to the 2300.
|
||||
*
|
||||
* They *claim* you can read BIU_R2HSTSLO with a full 32 bit access
|
||||
* and get both registers, but I'm a bit dubious about that. But the
|
||||
* point here is that the top 16 bits are firmware defined bits that
|
||||
* the RISC processor uses to inform the host about something- usually
|
||||
* something which was nominally in a mailbox register.
|
||||
*/
|
||||
#define BIU_REQINP (BIU_BLOCK+0x10) /* Request Queue In */
|
||||
#define BIU_REQOUTP (BIU_BLOCK+0x12) /* Request Queue Out */
|
||||
@ -139,6 +134,7 @@
|
||||
#define ISPR2HST_FPOST 0x16 /* Low 16 bits fast post */
|
||||
#define ISPR2HST_FPOST_CTIO 0x17 /* Low 16 bits fast post ctio */
|
||||
|
||||
/* fifo command stuff- mostly for SPI */
|
||||
#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 */
|
||||
@ -219,6 +215,8 @@
|
||||
#define BIU_ICR_ENABLE_ALL_INTS 0x0002 /* Global enable all inter */
|
||||
#define BIU_ICR_SOFT_RESET 0x0001 /* Soft Reset of ISP */
|
||||
|
||||
#define BIU_IMASK (BIU_ICR_ENABLE_RISC_INT|BIU_ICR_ENABLE_ALL_INTS)
|
||||
|
||||
#define BIU2100_ICR_ENABLE_ALL_INTS 0x8000
|
||||
#define BIU2100_ICR_ENA_FPM_INT 0x0020
|
||||
#define BIU2100_ICR_ENA_FB_INT 0x0010
|
||||
@ -228,16 +226,7 @@
|
||||
#define BIU2100_ICR_ENABLE_TXDMA_INT 0x0001
|
||||
#define BIU2100_ICR_DISABLE_ALL_INTS 0x0000
|
||||
|
||||
#define ENABLE_INTS(isp) (IS_SCSI(isp))? \
|
||||
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) ((IS_SCSI(isp))? \
|
||||
(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)
|
||||
#define BIU2100_IMASK (BIU2100_ICR_ENA_RISC_INT|BIU2100_ICR_ENABLE_ALL_INTS)
|
||||
|
||||
/* BUS STATUS REGISTER */
|
||||
#define BIU_ISR_DMA_INT 0x0020 /* DMA interrupt pending */
|
||||
@ -254,11 +243,14 @@
|
||||
#define BIU2100_ISR_RXDMA_INT_PENDING 0x0002 /* Global interrupt pending */
|
||||
#define BIU2100_ISR_TXDMA_INT_PENDING 0x0001 /* Global interrupt pending */
|
||||
|
||||
#define INT_PENDING(isp, isr) (IS_FC(isp)? \
|
||||
((isr & BIU2100_ISR_RISC_INT) != 0) : ((isr & BIU_ISR_RISC_INT) != 0))
|
||||
#define INT_PENDING(isp, isr) \
|
||||
IS_FC(isp)? \
|
||||
(IS_24XX(isp)? (isr & BIU2400_ISR_RISC_INT) : (isr & BIU2100_ISR_RISC_INT)) :\
|
||||
(isr & BIU_ISR_RISC_INT)
|
||||
|
||||
#define INT_PENDING_MASK(isp) \
|
||||
(IS_FC(isp)? BIU2100_ISR_RISC_INT: BIU_ISR_RISC_INT)
|
||||
(IS_FC(isp)? (IS_24XX(isp)? BIU2400_ISR_RISC_INT : BIU2100_ISR_RISC_INT) : \
|
||||
(BIU_ISR_RISC_INT))
|
||||
|
||||
/* BUS SEMAPHORE REGISTER */
|
||||
#define BIU_SEMA_STATUS 0x0002 /* Semaphore Status Bit */
|
||||
@ -351,6 +343,86 @@
|
||||
#define DMA_FIFO_SBUS_COUNT_MASK 0x007F /* FIFO Byte count mask */
|
||||
#define DMA_FIFO_PCI_COUNT_MASK 0x00FF /* FIFO Byte count mask */
|
||||
|
||||
/*
|
||||
* 2400 Interface Offsets and Register Definitions
|
||||
*
|
||||
* The 2400 looks quite different in terms of registers from other QLogic cards.
|
||||
* It is getting to be a genuine pain and challenge to keep the same model
|
||||
* for all.
|
||||
*/
|
||||
#define BIU2400_FLASH_ADDR (BIU_BLOCK+0x00)
|
||||
#define BIU2400_FLASH_DATA (BIU_BLOCK+0x04)
|
||||
#define BIU2400_CSR (BIU_BLOCK+0x08)
|
||||
#define BIU2400_ICR (BIU_BLOCK+0x0C)
|
||||
#define BIU2400_ISR (BIU_BLOCK+0x10)
|
||||
|
||||
#define BIU2400_REQINP (BIU_BLOCK+0x1C) /* Request Queue In */
|
||||
#define BIU2400_REQOUTP (BIU_BLOCK+0x20) /* Request Queue Out */
|
||||
#define BIU2400_RSPINP (BIU_BLOCK+0x24) /* Response Queue In */
|
||||
#define BIU2400_RSPOUTP (BIU_BLOCK+0x28) /* Response Queue Out */
|
||||
#define BIU2400_PRI_RQINP (BIU_BLOCK+0x2C) /* Priority Request Q In */
|
||||
#define BIU2400_PRI_RSPINP (BIU_BLOCK+0x30) /* Priority Request Q Out */
|
||||
|
||||
#define BIU2400_ATIO_RSPINP (BIU_BLOCK+0x3C) /* ATIO Queue In */
|
||||
#define BIU2400_ATIO_REQINP (BIU_BLOCK+0x40) /* ATIO Queue Out */
|
||||
|
||||
#define BIU2400_R2HSTSLO (BIU_BLOCK+0x44)
|
||||
#define BIU2400_R2HSTSHI (BIU_BLOCK+0x46)
|
||||
|
||||
#define BIU2400_HCCR (BIU_BLOCK+0x48)
|
||||
#define BIU2400_GPIOD (BIU_BLOCK+0x4C)
|
||||
#define BIU2400_GPIOE (BIU_BLOCK+0x50)
|
||||
#define BIU2400_HSEMA (BIU_BLOCK+0x58)
|
||||
|
||||
/* BIU2400_FLASH_ADDR definitions */
|
||||
#define BIU2400_FLASH_DFLAG (1 << 30)
|
||||
|
||||
/* BIU2400_CSR definitions */
|
||||
#define BIU2400_NVERR (1 << 18)
|
||||
#define BIU2400_DMA_ACTIVE (1 << 17) /* RO */
|
||||
#define BIU2400_DMA_STOP (1 << 16)
|
||||
#define BIU2400_FUNCTION (1 << 15) /* RO */
|
||||
#define BIU2400_PCIX_MODE(x) (((x) >> 8) & 0xf) /* RO */
|
||||
#define BIU2400_CSR_64BIT (1 << 2) /* RO */
|
||||
#define BIU2400_FLASH_ENABLE (1 << 1)
|
||||
#define BIU2400_SOFT_RESET (1 << 0)
|
||||
|
||||
/* BIU2400_ICR definitions */
|
||||
#define BIU2400_ICR_ENA_RISC_INT 0x8
|
||||
#define BIU2400_IMASK (BIU2400_ICR_ENA_RISC_INT)
|
||||
|
||||
/* BIU2400_ISR definitions */
|
||||
#define BIU2400_ISR_RISC_INT 0x8
|
||||
|
||||
#define BIU2400_R2HST_INTR BIU_R2HST_INTR
|
||||
#define BIU2400_R2HST_PAUSED BIU_R2HST_PAUSED
|
||||
#define BIU2400_R2HST_ISTAT_MASK 0x1f
|
||||
/* interrupt status meanings */
|
||||
#define ISP2400R2HST_ROM_MBX_OK 0x1 /* ROM mailbox cmd done ok */
|
||||
#define ISP2400R2HST_ROM_MBX_FAIL 0x2 /* ROM mailbox cmd done fail */
|
||||
#define ISP2400R2HST_MBX_OK 0x10 /* mailbox cmd done ok */
|
||||
#define ISP2400R2HST_MBX_FAIL 0x11 /* mailbox cmd done fail */
|
||||
#define ISP2400R2HST_ASYNC_EVENT 0x12 /* Async Event */
|
||||
#define ISP2400R2HST_RSPQ_UPDATE 0x13 /* Response Queue Update */
|
||||
#define ISP2400R2HST_ATIO_RSPQ_UPDATE 0x1C /* ATIO Response Queue Update */
|
||||
#define ISP2400R2HST_ATIO_RQST_UPDATE 0x1D /* ATIO Request Queue Update */
|
||||
|
||||
/* BIU2400_HCCR definitions */
|
||||
|
||||
#define HCCR_2400_CMD_NOP (0x0 << 28)
|
||||
#define HCCR_2400_CMD_RESET (0x1 << 28)
|
||||
#define HCCR_2400_CMD_CLEAR_RESET (0x2 << 28)
|
||||
#define HCCR_2400_CMD_PAUSE (0x3 << 28)
|
||||
#define HCCR_2400_CMD_RELEASE (0x4 << 28)
|
||||
#define HCCR_2400_CMD_SET_HOST_INT (0x5 << 28)
|
||||
#define HCCR_2400_CMD_CLEAR_HOST_INT (0x6 << 28)
|
||||
#define HCCR_2400_CMD_CLEAR_RISC_INT (0xA << 28)
|
||||
|
||||
#define HCCR_2400_RISC_ERR(x) (((x) >> 12) & 0x7) /* RO */
|
||||
#define HCCR_2400_RISC2HOST_INT (1 << 6) /* RO */
|
||||
#define HCCR_2400_RISC_RESET (1 << 5) /* RO */
|
||||
|
||||
|
||||
/*
|
||||
* Mailbox Block Register Offsets
|
||||
*/
|
||||
@ -377,7 +449,7 @@
|
||||
* Strictly speaking, it's
|
||||
* SCSI && 2100 : 8 MBOX registers
|
||||
* 2200: 24 MBOX registers
|
||||
* 2300: 32 MBOX registers
|
||||
* 2300/2400: 32 MBOX registers
|
||||
*/
|
||||
#define MBOX_OFF(n) (MBOX_BLOCK + ((n) << 1))
|
||||
#define NMBOX(isp) \
|
||||
@ -389,9 +461,15 @@
|
||||
|
||||
#define MAX_MAILBOX(isp) ((IS_FC(isp))? 12 : 8)
|
||||
#define MAILBOX_STORAGE 12
|
||||
/* if timeout == 0, then default timeout is picked */
|
||||
#define MBCMD_DEFAULT_TIMEOUT 100000 /* 100 ms */
|
||||
typedef struct {
|
||||
uint16_t param[MAILBOX_STORAGE];
|
||||
uint16_t ibits, obits;
|
||||
uint16_t ibits;
|
||||
uint16_t obits;
|
||||
uint32_t : 28,
|
||||
logval : 4;
|
||||
uint32_t timeout;
|
||||
} mbreg_t;
|
||||
|
||||
/*
|
||||
@ -672,6 +750,7 @@ typedef struct {
|
||||
#define PCI_HCCR_CMD_PARITY_ERR 0xE000 /* Generate parity error */
|
||||
#define HCCR_CMD_TEST_MODE 0xF000 /* Set Test Mode */
|
||||
|
||||
|
||||
#define ISP2100_HCCR_PARITY_ENABLE_2 0x0400
|
||||
#define ISP2100_HCCR_PARITY_ENABLE_1 0x0200
|
||||
#define ISP2100_HCCR_PARITY_ENABLE_0 0x0100
|
||||
@ -687,6 +766,25 @@ typedef struct {
|
||||
|
||||
#define PCI_HCCR_BIOS 0x0001 /* W : BIOS enable */
|
||||
|
||||
/*
|
||||
* Defines for Interrupts
|
||||
*/
|
||||
#define ISP_INTS_ENABLED(isp) \
|
||||
((IS_SCSI(isp))? \
|
||||
(ISP_READ(isp, BIU_ICR) & BIU_IMASK) : \
|
||||
(IS_24XX(isp)? (ISP_READ(isp, BIU2400_ICR) & BIU2400_IMASK) : \
|
||||
(ISP_READ(isp, BIU_ICR) & BIU2100_IMASK)))
|
||||
|
||||
#define ISP_ENABLE_INTS(isp) \
|
||||
(IS_SCSI(isp) ? \
|
||||
ISP_WRITE(isp, BIU_ICR, BIU_IMASK) : \
|
||||
(IS_24XX(isp) ? \
|
||||
(ISP_WRITE(isp, BIU2400_ICR, BIU2400_IMASK)) : \
|
||||
(ISP_WRITE(isp, BIU_ICR, BIU2100_IMASK))))
|
||||
|
||||
#define ISP_DISABLE_INTS(isp) \
|
||||
IS_24XX(isp)? ISP_WRITE(isp, BIU2400_ICR, 0) : ISP_WRITE(isp, BIU_ICR, 0)
|
||||
|
||||
/*
|
||||
* NVRAM Definitions (PCI cards only)
|
||||
*/
|
||||
@ -736,9 +834,9 @@ typedef struct {
|
||||
#define ISP_NVRAM_FAST_MTTR_ENABLE(c) ISPBSMX(c, 22, 0, 0x01)
|
||||
|
||||
#define ISP_NVRAM_TARGOFF 28
|
||||
#define ISP_NVARM_TARGSIZE 6
|
||||
#define ISP_NVRAM_TARGSIZE 6
|
||||
#define _IxT(tgt, tidx) \
|
||||
(ISP_NVRAM_TARGOFF + (ISP_NVARM_TARGSIZE * (tgt)) + (tidx))
|
||||
(ISP_NVRAM_TARGOFF + (ISP_NVRAM_TARGSIZE * (tgt)) + (tidx))
|
||||
#define ISP_NVRAM_TGT_RENEG(c, t) ISPBSMX(c, _IxT(t, 0), 0, 0x01)
|
||||
#define ISP_NVRAM_TGT_QFRZ(c, t) ISPBSMX(c, _IxT(t, 0), 1, 0x01)
|
||||
#define ISP_NVRAM_TGT_ARQ(c, t) ISPBSMX(c, _IxT(t, 0), 2, 0x01)
|
||||
@ -937,7 +1035,7 @@ typedef struct {
|
||||
ISPBSMX(c, _IxT16(t, 4, (b)), 7, 0x01)
|
||||
|
||||
/*
|
||||
* Qlogic 2XXX NVRAM is an array of 256 bytes.
|
||||
* Qlogic 2100 thru 2300 NVRAM is an array of 256 bytes.
|
||||
*
|
||||
* Some portion of the front of this is for general RISC engine parameters,
|
||||
* mostly reflecting the state of the last INITIALIZE FIRMWARE mailbox command.
|
||||
@ -1011,6 +1109,51 @@ typedef struct {
|
||||
|
||||
#define ISP2100_HBA_FEATURES(c) ((c)[232] | ((c)[233] << 8))
|
||||
|
||||
/*
|
||||
* Qlogic 2400 NVRAM is an array of 512 bytes with a 32 bit checksum.
|
||||
*/
|
||||
#define ISP2400_NVRAM_PORT0_ADDR 0x80
|
||||
#define ISP2400_NVRAM_PORT1_ADDR 0x180
|
||||
#define ISP2400_NVRAM_SIZE 512
|
||||
|
||||
#define ISP2400_NVRAM_VERSION(c) ((c)[4] | ((c)[5] << 8))
|
||||
#define ISP2400_NVRAM_MAXFRAMELENGTH(c) (((c)[12]) | ((c)[13] << 8))
|
||||
#define ISP2400_NVRAM_EXECUTION_THROTTLE(c) (((c)[14]) | ((c)[15] << 8))
|
||||
#define ISP2400_NVRAM_EXCHANGE_COUNT(c) (((c)[16]) | ((c)[17] << 8))
|
||||
#define ISP2400_NVRAM_HARDLOOPID(c) ((c)[18] | ((c)[19] << 8))
|
||||
|
||||
#define ISP2400_NVRAM_PORT_NAME(c) (\
|
||||
(((uint64_t)(c)[20]) << 56) | \
|
||||
(((uint64_t)(c)[21]) << 48) | \
|
||||
(((uint64_t)(c)[22]) << 40) | \
|
||||
(((uint64_t)(c)[23]) << 32) | \
|
||||
(((uint64_t)(c)[24]) << 24) | \
|
||||
(((uint64_t)(c)[25]) << 16) | \
|
||||
(((uint64_t)(c)[26]) << 8) | \
|
||||
(((uint64_t)(c)[27]) << 0))
|
||||
|
||||
#define ISP2400_NVRAM_NODE_NAME(c) (\
|
||||
(((uint64_t)(c)[28]) << 56) | \
|
||||
(((uint64_t)(c)[29]) << 48) | \
|
||||
(((uint64_t)(c)[30]) << 40) | \
|
||||
(((uint64_t)(c)[31]) << 32) | \
|
||||
(((uint64_t)(c)[32]) << 24) | \
|
||||
(((uint64_t)(c)[33]) << 16) | \
|
||||
(((uint64_t)(c)[34]) << 8) | \
|
||||
(((uint64_t)(c)[35]) << 0))
|
||||
|
||||
#define ISP2400_NVRAM_LOGIN_RETRY_CNT(c) ((c)[36] | ((c)[37] << 8))
|
||||
#define ISP2400_NVRAM_LINK_DOWN_ON_NOS(c) ((c)[38] | ((c)[39] << 8))
|
||||
#define ISP2400_NVRAM_INTERRUPT_DELAY(c) ((c)[40] | ((c)[41] << 8))
|
||||
#define ISP2400_NVRAM_LOGIN_TIMEOUT(c) ((c)[42] | ((c)[43] << 8))
|
||||
|
||||
#define ISP2400_NVRAM_FIRMWARE_OPTIONS1(c) \
|
||||
((c)[44] | ((c)[45] << 8) | ((c)[46] << 16) | ((c)[47] << 24))
|
||||
#define ISP2400_NVRAM_FIRMWARE_OPTIONS2(c) \
|
||||
((c)[48] | ((c)[49] << 8) | ((c)[50] << 16) | ((c)[51] << 24))
|
||||
#define ISP2400_NVRAM_FIRMWARE_OPTIONS3(c) \
|
||||
((c)[52] | ((c)[53] << 8) | ((c)[54] << 16) | ((c)[55] << 24))
|
||||
|
||||
/*
|
||||
* Firmware Crash Dump
|
||||
*
|
||||
|
@ -31,20 +31,24 @@
|
||||
#define _ISPVAR_H
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <dev/ic/isp_stds.h>
|
||||
#include <dev/ic/ispmbox.h>
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#include <dev/isp/isp_stds.h>
|
||||
#include <dev/isp/ispmbox.h>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#include "isp_stds.h"
|
||||
#include "ispmbox.h"
|
||||
#endif
|
||||
#ifdef __svr4__
|
||||
#include "isp_stds.h"
|
||||
#include "ispmbox.h"
|
||||
#endif
|
||||
|
||||
#define ISP_CORE_VERSION_MAJOR 2
|
||||
#define ISP_CORE_VERSION_MINOR 11
|
||||
#define ISP_CORE_VERSION_MAJOR 3
|
||||
#define ISP_CORE_VERSION_MINOR 0
|
||||
|
||||
/*
|
||||
* Vector for bus specific code to provide specific services.
|
||||
@ -52,17 +56,17 @@
|
||||
typedef struct ispsoftc ispsoftc_t;
|
||||
struct ispmdvec {
|
||||
int (*dv_rd_isr)
|
||||
(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
|
||||
uint16_t (*dv_rd_reg) (ispsoftc_t *, int);
|
||||
void (*dv_wr_reg) (ispsoftc_t *, int, uint16_t);
|
||||
(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
|
||||
uint32_t (*dv_rd_reg) (ispsoftc_t *, int);
|
||||
void (*dv_wr_reg) (ispsoftc_t *, int, uint32_t);
|
||||
int (*dv_mbxdma) (ispsoftc_t *);
|
||||
int (*dv_dmaset)
|
||||
(ispsoftc_t *, XS_T *, ispreq_t *, uint16_t *, uint16_t);
|
||||
void (*dv_dmaclr) (ispsoftc_t *, XS_T *, uint16_t);
|
||||
(ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t);
|
||||
void (*dv_dmaclr) (ispsoftc_t *, XS_T *, uint32_t);
|
||||
void (*dv_reset0) (ispsoftc_t *);
|
||||
void (*dv_reset1) (ispsoftc_t *);
|
||||
void (*dv_dregs) (ispsoftc_t *, const char *);
|
||||
uint16_t *dv_ispfw; /* ptr to f/w */
|
||||
void * dv_ispfw; /* ptr to f/w */
|
||||
uint16_t dv_conf1;
|
||||
uint16_t dv_clock; /* clock frequency */
|
||||
};
|
||||
@ -122,6 +126,7 @@ struct ispmdvec {
|
||||
#define SYNC_SFORDEV 2 /* scratch, sync for ISP */
|
||||
#define SYNC_SFORCPU 3 /* scratch, sync for CPU */
|
||||
#define SYNC_REG 4 /* for registers */
|
||||
#define SYNC_ATIOQ 5 /* atio result queue (24xx) */
|
||||
|
||||
/*
|
||||
* Request/Response Queue defines and macros.
|
||||
@ -148,7 +153,7 @@ struct ispmdvec {
|
||||
|
||||
#define ISP_ADD_REQUEST(isp, nxti) \
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN); \
|
||||
WRITE_REQUEST_QUEUE_IN_POINTER(isp, nxti); \
|
||||
ISP_WRITE(isp, isp->isp_rqstinrp, nxti); \
|
||||
isp->isp_reqidx = nxti
|
||||
|
||||
/*
|
||||
@ -161,6 +166,7 @@ typedef struct {
|
||||
isp_cmd_dma_burst_enable: 1,
|
||||
isp_data_dma_burst_enabl: 1,
|
||||
isp_fifo_threshold : 3,
|
||||
isp_ptisp : 1,
|
||||
isp_ultramode : 1,
|
||||
isp_diffmode : 1,
|
||||
isp_lvdmode : 1,
|
||||
@ -222,32 +228,125 @@ typedef struct {
|
||||
/*
|
||||
* Fibre Channel Specifics
|
||||
*/
|
||||
#define FL_PORT_ID 0x7e /* FL_Port Special ID */
|
||||
#define FC_PORT_ID 0x7f /* Fabric Controller Special ID */
|
||||
#define FC_SNS_ID 0x80 /* SNS Server Special ID */
|
||||
/* These are for 2100/2200/2300 cards */
|
||||
#define FL_ID 0x7e /* FL_Port Special ID */
|
||||
#define SNS_ID 0x80 /* SNS Server Special ID */
|
||||
#define NPH_MAX 0xfe
|
||||
|
||||
/* #define ISP_USE_GA_NXT 1 */ /* Use GA_NXT with switches */
|
||||
#ifndef GA_NXT_MAX
|
||||
#define GA_NXT_MAX 256
|
||||
#endif
|
||||
/* These are for 24XX cards */
|
||||
#define NPH_RESERVED 0x7F0 /* begin of reserved N-port handles */
|
||||
#define NPH_MGT_ID 0x7FA /* Management Server Special ID */
|
||||
#define NPH_SNS_ID 0x7FC /* SNS Server Special ID */
|
||||
#define NPH_FL_ID 0x7FE /* FL Port Special ID */
|
||||
#define NPH_MAX_24XX 0x800
|
||||
|
||||
/*
|
||||
* Limit for devices on an arbitrated loop.
|
||||
*/
|
||||
#define LOCAL_LOOP_LIM 126
|
||||
|
||||
/*
|
||||
* Special Port IDs
|
||||
*/
|
||||
#define MANAGEMENT_PORT_ID 0xFFFFFA
|
||||
#define SNS_PORT_ID 0xFFFFFC
|
||||
#define FABRIC_PORT_ID 0xFFFFFE
|
||||
|
||||
|
||||
/*
|
||||
* FC Port Database entry.
|
||||
*
|
||||
* It has a handle that the f/w uses to address commands to a device.
|
||||
* This handle's value may be assigned by the firmware (e.g., for local loop
|
||||
* devices) or by the driver (e.g., for fabric devices).
|
||||
*
|
||||
* It has a state. If the state if VALID, that means that we've logged into
|
||||
* the device. We also *may* have a initiator map index entry. This is a value
|
||||
* from 0..MAX_FC_TARG that is used to index into the isp_ini_map array. If
|
||||
* the value therein is non-zero, then that value minus one is used to index
|
||||
* into the Port Database to find the handle for forming commands. There is
|
||||
* back-index minus one value within to Port Database entry that tells us
|
||||
* which entry in isp_ini_map points to us (to avoid searching).
|
||||
*
|
||||
* Local loop devices the firmware automatically performs PLOGI on for us
|
||||
* (which is why that handle is imposed upon us). Fabric devices we assign
|
||||
* a handle to and perform the PLOGI on.
|
||||
*
|
||||
* When a PORT DATABASE CHANGED asynchronous event occurs, we mark all VALID
|
||||
* entries as PROBATIONAL. This allows us, if policy says to, just keep track
|
||||
* of devices whose handles change but are otherwise the same device (and
|
||||
* thus keep 'target' constant).
|
||||
*
|
||||
* In any case, we search all possible local loop handles. For each one that
|
||||
* has a port database entity returned, we search for any PROBATIONAL entry
|
||||
* that matches it and update as appropriate. Otherwise, as a new entry, we
|
||||
* find room for it in the Port Database. We *try* and use the handle as the
|
||||
* index to put it into the Database, but that's just an optimization. We mark
|
||||
* the entry VALID and make sure that the target index is updated and correct.
|
||||
*
|
||||
* When we get done searching the local loop, we then search similarily for
|
||||
* a list of devices we've gotten from the fabric name controller (if we're
|
||||
* on a fabric). VALID marking is also done similarily.
|
||||
*
|
||||
* When all of this is done, we can march through the database and clean up
|
||||
* any entry that is still PROBATIONAL (these represent devices which have
|
||||
* departed). Then we're done and can resume normal operations.
|
||||
*
|
||||
* Negative invariants that we try and test for are:
|
||||
*
|
||||
* + There can never be two non-NIL entries with the same { Port, Node } WWN
|
||||
* duples.
|
||||
*
|
||||
* + There can never be two non-NIL entries with the same handle.
|
||||
*
|
||||
* + There can never be two non-NIL entries which have the same ini_map_idx
|
||||
* value.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t : 13,
|
||||
uint16_t handle;
|
||||
uint16_t ini_map_idx : 12,
|
||||
autologin : 1, /* F/W does PLOGI/PLOGO */
|
||||
state : 3;
|
||||
uint32_t : 6,
|
||||
roles : 2,
|
||||
portid : 24;
|
||||
uint32_t : 6,
|
||||
new_roles : 2,
|
||||
new_portid : 24;
|
||||
uint64_t node_wwn;
|
||||
uint64_t port_wwn;
|
||||
} fcportdb_t;
|
||||
|
||||
#define FC_PORTDB_STATE_NIL 0
|
||||
#define FC_PORTDB_STATE_PROBATIONAL 1
|
||||
#define FC_PORTDB_STATE_DEAD 2
|
||||
#define FC_PORTDB_STATE_CHANGED 3
|
||||
#define FC_PORTDB_STATE_NEW 4
|
||||
#define FC_PORTDB_STATE_PENDING_VALID 5
|
||||
#define FC_PORTDB_STATE_VALID 7
|
||||
|
||||
/*
|
||||
* FC card specific information
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t : 10,
|
||||
isp_tmode : 1,
|
||||
isp_2klogin : 1,
|
||||
isp_sccfw : 1,
|
||||
isp_gbspeed : 3,
|
||||
: 1,
|
||||
isp_iid_set : 1,
|
||||
loop_seen_once : 1,
|
||||
: 1,
|
||||
: 1,
|
||||
isp_loopstate : 4, /* Current Loop State */
|
||||
isp_fwstate : 4, /* ISP F/W state */
|
||||
isp_gotdparms : 1,
|
||||
isp_topo : 3,
|
||||
isp_onfabric : 1;
|
||||
loop_seen_once : 1;
|
||||
uint32_t : 8,
|
||||
isp_portid : 24; /* S_ID */
|
||||
uint16_t isp_fwoptions;
|
||||
uint16_t isp_xfwoptions;
|
||||
uint16_t isp_zfwoptions;
|
||||
uint16_t isp_iid; /* 'initiator' id */
|
||||
uint16_t isp_loopid; /* hard loop id */
|
||||
uint16_t isp_fwattr; /* firmware attributes */
|
||||
uint16_t isp_execthrottle;
|
||||
@ -258,34 +357,8 @@ typedef struct {
|
||||
uint16_t isp_maxfrmlen;
|
||||
uint64_t isp_nodewwn;
|
||||
uint64_t isp_portwwn;
|
||||
/*
|
||||
* Port Data Base. This is indexed by 'target', which is invariate.
|
||||
* However, elements within can move around due to loop changes,
|
||||
* so the actual loop ID passed to the F/W is in this structure.
|
||||
* The first time the loop is seen up, loopid will match the index
|
||||
* (except for fabric nodes which are above mapped above FC_SNS_ID
|
||||
* and are completely virtual), but subsequent LIPs can cause things
|
||||
* to move around.
|
||||
*/
|
||||
struct lportdb {
|
||||
uint32_t loopid : 16,
|
||||
: 2,
|
||||
fc4_type : 4,
|
||||
last_fabric_dev : 1,
|
||||
relogin : 1,
|
||||
force_logout : 1,
|
||||
was_fabric_dev : 1,
|
||||
fabric_dev : 1,
|
||||
loggedin : 1,
|
||||
roles : 2,
|
||||
tvalid : 1,
|
||||
valid : 1;
|
||||
uint32_t port_type : 8,
|
||||
portid : 24;
|
||||
uint64_t node_wwn;
|
||||
uint64_t port_wwn;
|
||||
} portdb[MAX_FC_TARG], tport[FC_PORT_ID];
|
||||
|
||||
fcportdb_t portdb[MAX_FC_TARG];
|
||||
uint16_t isp_ini_map[MAX_FC_TARG];
|
||||
/*
|
||||
* Scratch DMA mapped in area to fetch Port Database stuff, etc.
|
||||
*/
|
||||
@ -308,10 +381,10 @@ typedef struct {
|
||||
#define LOOP_NIL 0
|
||||
#define LOOP_LIP_RCVD 1
|
||||
#define LOOP_PDB_RCVD 2
|
||||
#define LOOP_SCANNING_FABRIC 3
|
||||
#define LOOP_FSCAN_DONE 4
|
||||
#define LOOP_SCANNING_LOOP 5
|
||||
#define LOOP_LSCAN_DONE 6
|
||||
#define LOOP_SCANNING_LOOP 3
|
||||
#define LOOP_LSCAN_DONE 4
|
||||
#define LOOP_SCANNING_FABRIC 5
|
||||
#define LOOP_FSCAN_DONE 6
|
||||
#define LOOP_SYNCING_PDB 7
|
||||
#define LOOP_READY 8
|
||||
|
||||
@ -350,7 +423,7 @@ struct ispsoftc {
|
||||
|
||||
uint32_t isp_clock : 8, /* input clock */
|
||||
: 4,
|
||||
isp_port : 1, /* 23XX only */
|
||||
isp_port : 1, /* 23XX/24XX only */
|
||||
isp_failed : 1, /* board failed */
|
||||
isp_open : 1, /* opened (ioctl) */
|
||||
isp_touched : 1, /* board ever seen? */
|
||||
@ -361,10 +434,12 @@ struct ispsoftc {
|
||||
|
||||
uint32_t isp_confopts; /* config options */
|
||||
|
||||
uint16_t isp_rqstinrp; /* register for REQINP */
|
||||
uint16_t isp_rqstoutrp; /* register for REQOUTP */
|
||||
uint16_t isp_respinrp; /* register for RESINP */
|
||||
uint16_t isp_respoutrp; /* register for RESOUTP */
|
||||
uint32_t isp_rqstinrp; /* register for REQINP */
|
||||
uint32_t isp_rqstoutrp; /* register for REQOUTP */
|
||||
uint32_t isp_respinrp; /* register for RESINP */
|
||||
uint32_t isp_respoutrp; /* register for RESOUTP */
|
||||
uint32_t isp_atioinrp; /* register for ATIOINP */
|
||||
uint32_t isp_atiooutrp; /* register for ATIOOUTP */
|
||||
|
||||
/*
|
||||
* Instrumentation
|
||||
@ -388,13 +463,13 @@ struct ispsoftc {
|
||||
isp_sendmarker : 2, /* send a marker entry */
|
||||
isp_update : 2, /* update parameters */
|
||||
isp_nactive : 16; /* how many commands active */
|
||||
volatile uint16_t isp_reqodx; /* index of last ISP pickup */
|
||||
volatile uint16_t isp_reqidx; /* index of next request */
|
||||
volatile uint16_t isp_residx; /* index of next result */
|
||||
volatile uint16_t isp_resodx; /* index of next result */
|
||||
volatile uint16_t isp_rspbsy;
|
||||
volatile uint16_t isp_lasthdls; /* last handle seed */
|
||||
volatile uint16_t isp_obits; /* mailbox command output */
|
||||
volatile uint32_t isp_reqodx; /* index of last ISP pickup */
|
||||
volatile uint32_t isp_reqidx; /* index of next request */
|
||||
volatile uint32_t isp_residx; /* index of next result */
|
||||
volatile uint32_t isp_resodx; /* index of next result */
|
||||
volatile uint32_t isp_rspbsy;
|
||||
volatile uint32_t isp_lasthdls; /* last handle seed */
|
||||
volatile uint32_t isp_obits; /* mailbox command output */
|
||||
volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE];
|
||||
volatile uint16_t isp_lastmbxcmd; /* last mbox command sent */
|
||||
volatile uint16_t isp_mbxwrk0;
|
||||
@ -422,6 +497,11 @@ struct ispsoftc {
|
||||
void * isp_result;
|
||||
XS_DMA_ADDR_T isp_rquest_dma;
|
||||
XS_DMA_ADDR_T isp_result_dma;
|
||||
#ifdef ISP_TARGET_MODE
|
||||
/* for 24XX only */
|
||||
void * isp_atioq;
|
||||
XS_DMA_ADDR_T isp_atioq_dma;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define SDPARAM(isp) ((sdparam *) (isp)->isp_param)
|
||||
@ -454,6 +534,7 @@ struct ispsoftc {
|
||||
#define ISP_CFG_OWNFSZ 0x400 /* override NVRAM frame size */
|
||||
#define ISP_CFG_OWNLOOPID 0x800 /* override NVRAM loopid */
|
||||
#define ISP_CFG_OWNEXCTHROTTLE 0x1000 /* override NVRAM execution throttle */
|
||||
#define ISP_CFG_FOURGB 0x2000 /* force 4GB connection (24XX only) */
|
||||
|
||||
/*
|
||||
* Prior to calling isp_reset for the first time, the outer layer
|
||||
@ -491,6 +572,7 @@ struct ispsoftc {
|
||||
*/
|
||||
#define ISP_CODE_ORG 0x1000 /* default f/w code start */
|
||||
#define ISP_CODE_ORG_2300 0x0800 /* ..except for 2300s */
|
||||
#define ISP_CODE_ORG_2400 0x100000 /* ..and 2400s */
|
||||
#define ISP_FW_REV(maj, min, mic) ((maj << 24) | (min << 16) | mic)
|
||||
#define ISP_FW_MAJOR(code) ((code >> 24) & 0xff)
|
||||
#define ISP_FW_MINOR(code) ((code >> 16) & 0xff)
|
||||
@ -501,6 +583,8 @@ struct ispsoftc {
|
||||
#define ISP_FW_MICROX(xp) (xp[2])
|
||||
#define ISP_FW_NEWER_THAN(i, major, minor, micro) \
|
||||
(ISP_FW_REVX((i)->isp_fwrev) > ISP_FW_REV(major, minor, micro))
|
||||
#define ISP_FW_OLDER_THAN(i, major, minor, micro) \
|
||||
(ISP_FW_REVX((i)->isp_fwrev) < ISP_FW_REV(major, minor, micro))
|
||||
|
||||
/*
|
||||
* Bus (implementation) types
|
||||
@ -539,7 +623,6 @@ struct ispsoftc {
|
||||
#define ISP_HA_FC_2312 0x40
|
||||
#define ISP_HA_FC_2322 0x50
|
||||
#define ISP_HA_FC_2400 0x60
|
||||
#define ISP_HA_FC_2422 0x61
|
||||
|
||||
#define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI)
|
||||
#define IS_1240(isp) (isp->isp_type == ISP_HA_SCSI_1240)
|
||||
@ -557,8 +640,8 @@ struct ispsoftc {
|
||||
#define IS_FC(isp) ((isp)->isp_type & ISP_HA_FC)
|
||||
#define IS_2100(isp) ((isp)->isp_type == ISP_HA_FC_2100)
|
||||
#define IS_2200(isp) ((isp)->isp_type == ISP_HA_FC_2200)
|
||||
#define IS_23XX(isp) \
|
||||
((isp)->isp_type >= ISP_HA_FC_2300 && (isp)->isp_type < ISP_HA_FC_2400)
|
||||
#define IS_23XX(isp) ((isp)->isp_type >= ISP_HA_FC_2300 && \
|
||||
(isp)->isp_type < ISP_HA_FC_2400)
|
||||
#define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300)
|
||||
#define IS_2312(isp) ((isp)->isp_type == ISP_HA_FC_2312)
|
||||
#define IS_2322(isp) ((isp)->isp_type == ISP_HA_FC_2322)
|
||||
@ -567,10 +650,10 @@ struct ispsoftc {
|
||||
/*
|
||||
* DMA related macros
|
||||
*/
|
||||
#define DMA_WD3(x) ((((uint64_t)x) >> 48) & 0xffff)
|
||||
#define DMA_WD2(x) ((((uint64_t)x) >> 32) & 0xffff)
|
||||
#define DMA_WD1(x) (((x) >> 16) & 0xffff)
|
||||
#define DMA_WD0(x) (((x) & 0xffff))
|
||||
#define DMA_WD3(x) (((uint16_t)(((uint64_t)x) >> 48)) & 0xffff)
|
||||
#define DMA_WD2(x) (((uint16_t)(((uint64_t)x) >> 32)) & 0xffff)
|
||||
#define DMA_WD1(x) ((uint16_t)((x) >> 16) & 0xffff)
|
||||
#define DMA_WD0(x) ((uint16_t)((x) & 0xffff))
|
||||
|
||||
#define DMA_LO32(x) ((uint32_t) (x))
|
||||
#define DMA_HI32(x) ((uint32_t)(((uint64_t)x) >> 32))
|
||||
@ -609,7 +692,7 @@ void isp_fw_dump(ispsoftc_t *isp);
|
||||
* semaphore register and first mailbox register (if appropriate). This also
|
||||
* means that most spurious/bogus interrupts not for us can be filtered first.
|
||||
*/
|
||||
void isp_intr(ispsoftc_t *, uint16_t, uint16_t, uint16_t);
|
||||
void isp_intr(ispsoftc_t *, uint32_t, uint16_t, uint16_t);
|
||||
|
||||
|
||||
/*
|
||||
@ -672,7 +755,7 @@ typedef enum {
|
||||
ISPCTL_SCAN_LOOP, /* (Re)scan Local Loop */
|
||||
ISPCTL_PDB_SYNC, /* Synchronize Port Database */
|
||||
ISPCTL_SEND_LIP, /* Send a LIP */
|
||||
ISPCTL_GET_POSMAP, /* Get FC-AL position map */
|
||||
ISPCTL_GET_PORTNAME, /* get portname from an N-port handle */
|
||||
ISPCTL_RUN_MBOXCMD, /* run a mailbox command */
|
||||
ISPCTL_TOGGLE_TMODE, /* toggle target mode */
|
||||
ISPCTL_GET_PDB /* get a single port database entry */
|
||||
@ -728,8 +811,10 @@ typedef enum {
|
||||
ISPASYNC_LIP, /* LIP Received */
|
||||
ISPASYNC_LOOP_RESET, /* Loop Reset Received */
|
||||
ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */
|
||||
ISPASYNC_FABRIC_DEV, /* FC Fabric Device Arrival */
|
||||
ISPASYNC_PROMENADE, /* FC Objects coming && going */
|
||||
ISPASYNC_DEV_ARRIVED, /* FC Device Arrival */
|
||||
ISPASYNC_DEV_CHANGED, /* FC Device Change */
|
||||
ISPASYNC_DEV_STAYED, /* FC Device Stayed the Same */
|
||||
ISPASYNC_DEV_GONE, /* FC Device Depart */
|
||||
ISPASYNC_TARGET_NOTIFY, /* target asynchronous notification event */
|
||||
ISPASYNC_TARGET_ACTION, /* target action requested */
|
||||
ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */
|
||||
@ -804,7 +889,7 @@ int isp_async(ispsoftc_t *, ispasync_t, void *);
|
||||
* of the same object is consistent.
|
||||
*
|
||||
* MBOX_ACQUIRE(ispsoftc_t *) acquire lock on mailbox regs
|
||||
* MBOX_WAIT_COMPLETE(ispsoftc_t *) wait for mailbox cmd to be done
|
||||
* MBOX_WAIT_COMPLETE(ispsoftc_t *, mbreg_t *) wait for cmd to be done
|
||||
* MBOX_NOTIFY_COMPLETE(ispsoftc_t *) notification of mbox cmd donee
|
||||
* MBOX_RELEASE(ispsoftc_t *) release lock on mailbox regs
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user