mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 05:01:27 +00:00
Synchronize with Feral CVS repository:
Don't use both WWNs in the ICB block unless they're not NAA==2. This makes us more consistent with QLogic driver setups and thus more likely to fit into the same zoning setups. If we're getting a PDB and it's for the Fabric Controller, force a login to it (just in case it logged out underneath us). Return 'not logged in' for the 24XX in case the 24XX specific login state isn't in the range of PLOGI_DONE to LOGGED IN. Don't do local loop scans if we have more than one channel (NP-IV) and we're in a FL-port topology- we just end up poking ourselves usually. Make sure we set loopstate in a couple of places we missed so that we try and get it again. Add in the RESET DEVICE and ABORT COMMAND functions for the 24XX cards (finally). Fix a longstanding bug where were passing the wrong (off by one) output pointer to isp_handle_other_response. Change isp_async...ISPASYNC_CHANGE_NOTIFY to have N-port handle, nlstate and reason included as we get these for free with PDB Changed stuff for the 24XX card. Eventually we should be able to edit single local PDB entry states instead of doing a full eval. Put in the put of a 24XX Task Management Function IOCB. There is no get because the firmware doesn't return it when done- instead a status iocb is done. There is no "FAST POST" flag for the 24XX- this is a NOACK flag which means that there is no interrupt if all goes well. Fix spelling mistakes. In isp_add_wwn_entry, ahem, don't allocate PDB entries out of the 'rexerved for chip' area. Put more comments in as to why we're terminating an exchange (and make them all ISP_LOGTINFO). Add, finally, the correct handling for a QIN_NOTIFY_ACK for a task management function- this means we construct a ct7_entry_t to get the firmware to send an FC Response IU for it. So, finally LUN RESETS and TARGET RESETS and ABORT TASK will actually work and, more importantly, be seen to be working by initiators. Fix WWN defaults/active generation and retrieval. It was broken. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@272 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp.c,v 1.188 2007/12/30 20:48:14 mjacob Exp $ */
|
||||
/* $Id: isp.c,v 1.189 2008/01/04 17:54:54 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -1718,7 +1718,7 @@ isp_fibre_init(ispsoftc_t *isp)
|
||||
icbp->icb_logintime = ICB_LOGIN_TOV;
|
||||
icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
|
||||
|
||||
if (fcp->isp_wwnn && fcp->isp_wwpn) {
|
||||
if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
|
||||
icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
|
||||
MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
|
||||
MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
|
||||
@@ -1959,7 +1959,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
}
|
||||
icbp->icb_logintime = ICB_LOGIN_TOV;
|
||||
|
||||
if (fcp->isp_wwnn && fcp->isp_wwpn) {
|
||||
if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
|
||||
icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
|
||||
MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
|
||||
MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
|
||||
@@ -2131,7 +2131,7 @@ isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
|
||||
for (i = 0; i < MAX_FC_TARG; i++) {
|
||||
if (fcp->portdb[i].target_mode) {
|
||||
if (disposition < 0) {
|
||||
isp_prt(isp, ISP_LOGDEBUG0|ISP_LOGTDEBUG0,
|
||||
isp_prt(isp, ISP_LOGTINFO,
|
||||
"%s: Chan %d zeroing handle 0x%02x port "
|
||||
"0x%06x", __FUNCTION__, chan,
|
||||
fcp->portdb[i].handle,
|
||||
@@ -2419,12 +2419,20 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
|
||||
MEMZERO(&mbs, sizeof (mbs));
|
||||
mbs.param[0] = MBOX_GET_PORT_DB;
|
||||
if (IS_24XX(isp)) {
|
||||
mbs.ibits = 0x6ff;
|
||||
mbs.ibits = (1 << 9) | (1 << 10);
|
||||
mbs.param[1] = id;
|
||||
mbs.param[9] = chan;
|
||||
if (id == NPH_FL_ID) {
|
||||
mbs.param[4] = FL_ID;
|
||||
mbs.param[10] = 1;
|
||||
}
|
||||
} else if (ISP_CAP_2KLOGIN(isp)) {
|
||||
mbs.param[1] = id;
|
||||
mbs.ibits = (1 << 10);
|
||||
if (id == NPH_FL_ID) {
|
||||
mbs.param[4] = FL_ID;
|
||||
mbs.param[10] = 1;
|
||||
}
|
||||
} else {
|
||||
mbs.param[1] = id << 8;
|
||||
}
|
||||
@@ -2443,7 +2451,7 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
|
||||
if (dolock) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
}
|
||||
return (-1);
|
||||
return (mbs.param[0]);
|
||||
}
|
||||
if (IS_24XX(isp)) {
|
||||
isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
|
||||
@@ -2452,6 +2460,18 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
|
||||
pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
|
||||
MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
|
||||
MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d Port 0x%06x flags 0x%x curstate %x",
|
||||
chan, pdb->portid, un.bill.pdb_flags,
|
||||
un.bill.pdb_curstate);
|
||||
if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE &&
|
||||
un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
|
||||
mbs.param[0] = MBOX_NOT_LOGGED_IN;
|
||||
if (dolock) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
}
|
||||
return (mbs.param[0]);
|
||||
}
|
||||
} else {
|
||||
isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
|
||||
pdb->handle = un.fred.pdb_loopid;
|
||||
@@ -2751,7 +2771,7 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
|
||||
if (chan) {
|
||||
fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
|
||||
r = isp_plogx(isp, chan, fcp->isp_sns_hdl,
|
||||
SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI |
|
||||
SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI |
|
||||
PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI,
|
||||
0);
|
||||
if (r) {
|
||||
@@ -3021,13 +3041,22 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
* Check our connection topology.
|
||||
*
|
||||
* If we're a public or private loop, we scan 0..125 as handle values.
|
||||
* The firmware has (typically) peformed a PLOGI for us.
|
||||
* The firmware has (typically) peformed a PLOGI for us. We skip this
|
||||
* step if we're a ISP_24XX in NP-IV mode.
|
||||
*
|
||||
* If we're a N-port connection, we treat this is a short loop (0..1).
|
||||
*/
|
||||
switch (fcp->isp_topo) {
|
||||
case TOPO_NL_PORT:
|
||||
lim = LOCAL_LOOP_LIM;
|
||||
break;
|
||||
case TOPO_FL_PORT:
|
||||
if (IS_24XX(isp) && isp->isp_nchan > 1) {
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d Skipping Local Loop Scan", chan);
|
||||
fcp->isp_loopstate = LOOP_LSCAN_DONE;
|
||||
return (0);
|
||||
}
|
||||
lim = LOCAL_LOOP_LIM;
|
||||
break;
|
||||
case TOPO_N_PORT:
|
||||
@@ -3050,6 +3079,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
* Run through the list and get the port database info for each one.
|
||||
*/
|
||||
for (handle = 0; handle < lim; handle++) {
|
||||
int r;
|
||||
/*
|
||||
* Don't scan "special" ids.
|
||||
*/
|
||||
@@ -3068,6 +3098,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
if (IS_2100(isp) || IS_2200(isp)) {
|
||||
uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d FC scan loop DONE (bad)", chan);
|
||||
return (-1);
|
||||
}
|
||||
if (node_wwn == INI_NONE) {
|
||||
@@ -3078,9 +3110,15 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
/*
|
||||
* Get the port database entity for this index.
|
||||
*/
|
||||
if (isp_getpdb(isp, chan, handle, &pdb, 1) != 0) {
|
||||
r = isp_getpdb(isp, chan, handle, &pdb, 1);
|
||||
if (r != 0) {
|
||||
isp_prt(isp, ISP_LOGDEBUG1,
|
||||
"Chan %d FC scan loop handle %d returned %x",
|
||||
chan, handle, r);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d FC scan loop DONE (bad)", chan);
|
||||
return (-1);
|
||||
}
|
||||
continue;
|
||||
@@ -3088,6 +3126,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d FC scan loop DONE (bad)", chan);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -3101,6 +3141,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d cannot synchronize port database", chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d FC scan loop DONE (bad)", chan);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -3123,12 +3165,23 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
a = (tmp.node_wwn == 0);
|
||||
b = (tmp.port_wwn == 0);
|
||||
c = (tmp.portid == 0);
|
||||
if (a == 0 && b == 0) {
|
||||
tmp.node_wwn =
|
||||
isp_get_wwn(isp, chan, handle, 1);
|
||||
tmp.port_wwn =
|
||||
isp_get_wwn(isp, chan, handle, 0);
|
||||
if (tmp.node_wwn && tmp.port_wwn) {
|
||||
isp_prt(isp, ISP_LOGINFO, "DODGED!");
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
|
||||
a, b, c, handle);
|
||||
isp_dump_portdb(isp, chan);
|
||||
continue;
|
||||
}
|
||||
cont:
|
||||
|
||||
/*
|
||||
* Now search the entire port database
|
||||
@@ -3158,6 +3211,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
chan, i, lp->state);
|
||||
isp_dump_portdb(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d FC scan loop DONE (bad)", chan);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -3241,6 +3296,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
chan, tmp.portid, tmp.handle);
|
||||
}
|
||||
fcp->isp_loopstate = LOOP_LSCAN_DONE;
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d FC scan loop DONE", chan);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -3428,7 +3485,8 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
{
|
||||
fcparam *fcp = FCPARAM(isp, chan);
|
||||
uint32_t portid;
|
||||
uint16_t handle, oldhandle;
|
||||
uint16_t handle, oldhandle, loopid;
|
||||
isp_pdb_t pdb;
|
||||
int portidx, portlim, r;
|
||||
sns_gid_ft_rsp_t *rs0, *rs1;
|
||||
|
||||
@@ -3448,8 +3506,28 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
return (0);
|
||||
}
|
||||
|
||||
FC_SCRATCH_ACQUIRE(isp, chan);
|
||||
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
|
||||
FC_SCRATCH_ACQUIRE(isp, chan);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we still are logged into the fabric controller.
|
||||
*/
|
||||
if (IS_24XX(isp)) {
|
||||
loopid = NPH_FL_ID;
|
||||
} else {
|
||||
loopid = FL_ID;
|
||||
}
|
||||
if (isp_getpdb(isp, chan, loopid, &pdb, 0)) {
|
||||
fcp->isp_loopstate = LOOP_PDB_RCVD;
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (IS_24XX(isp)) {
|
||||
r = isp_gid_ft_ct_passthru(isp, chan);
|
||||
@@ -3457,6 +3535,12 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
r = isp_gid_ft_sns(isp, chan);
|
||||
}
|
||||
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (r > 0) {
|
||||
fcp->isp_loopstate = LOOP_FSCAN_DONE;
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
@@ -3466,15 +3550,16 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
return (0);
|
||||
}
|
||||
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
|
||||
rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
|
||||
rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
|
||||
isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
return (-1);
|
||||
}
|
||||
if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
|
||||
int level;
|
||||
if (rs1->snscb_cthdr.ct_reason == 9 &&
|
||||
@@ -3711,6 +3796,11 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
return (-1);
|
||||
}
|
||||
FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
|
||||
MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
|
||||
MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
|
||||
@@ -3828,6 +3918,11 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
return (-1);
|
||||
}
|
||||
FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
|
||||
|
||||
handle = pdb.handle;
|
||||
@@ -3844,7 +3939,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
if (dbidx >= FL_ID && dbidx <= SNS_ID) {
|
||||
continue;
|
||||
}
|
||||
if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) {
|
||||
if (fcp->portdb[dbidx].target_mode) {
|
||||
continue;
|
||||
}
|
||||
if (fcp->portdb[dbidx].node_wwn == wwnn &&
|
||||
@@ -4517,7 +4612,74 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
|
||||
tgt = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
if (IS_24XX(isp)) {
|
||||
isp_prt(isp, ISP_LOGWARN, "RESET DEV NOT IMPLEMENTED");
|
||||
uint8_t local[QENTRY_LEN];
|
||||
isp24xx_tmf_t *tmf;
|
||||
isp24xx_statusreq_t *sp;
|
||||
fcparam *fcp = FCPARAM(isp, chan);
|
||||
fcportdb_t *lp;
|
||||
int hdlidx;
|
||||
|
||||
hdlidx = fcp->isp_ini_map[tgt] - 1;
|
||||
if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d bad handle %d trying to reset"
|
||||
"target %d", chan, hdlidx, tgt);
|
||||
break;
|
||||
}
|
||||
lp = &fcp->portdb[hdlidx];
|
||||
if (lp->state != FC_PORTDB_STATE_VALID) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d handle %d for abort of target %d "
|
||||
"no longer valid", chan,
|
||||
hdlidx, tgt);
|
||||
break;
|
||||
}
|
||||
|
||||
tmf = (isp24xx_tmf_t *) local;
|
||||
MEMZERO(tmf, QENTRY_LEN);
|
||||
tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
|
||||
tmf->tmf_header.rqs_entry_count = 1;
|
||||
tmf->tmf_nphdl = lp->handle;
|
||||
tmf->tmf_delay = 2;
|
||||
tmf->tmf_timeout = 2;
|
||||
tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
|
||||
tmf->tmf_tidlo = lp->portid;
|
||||
tmf->tmf_tidhi = lp->portid >> 16;
|
||||
tmf->tmf_vpidx = chan;
|
||||
isp_prt(isp, ISP_LOGALL,
|
||||
"Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x",
|
||||
chan, lp->handle, lp->portid);
|
||||
MEMZERO(&mbs, sizeof (mbs));
|
||||
mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
|
||||
mbs.param[1] = QENTRY_LEN;
|
||||
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
|
||||
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
|
||||
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
|
||||
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
|
||||
mbs.timeout = 5000000;
|
||||
mbs.logval = MBLOGALL;
|
||||
|
||||
FC_SCRATCH_ACQUIRE(isp, chan);
|
||||
isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
|
||||
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
|
||||
fcp->sendmarker = 1;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
break;
|
||||
}
|
||||
MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
|
||||
QENTRY_LEN);
|
||||
sp = (isp24xx_statusreq_t *) local;
|
||||
isp_get_24xx_response(isp,
|
||||
&((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
if (sp->req_completion_status == 0) {
|
||||
return (0);
|
||||
}
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d reset of target %d returned 0x%x",
|
||||
chan, tgt, sp->req_completion_status);
|
||||
break;
|
||||
} else if (IS_FC(isp)) {
|
||||
if (ISP_CAP_2KLOGIN(isp)) {
|
||||
@@ -4545,7 +4707,9 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
|
||||
va_start(ap, ctl);
|
||||
xs = va_arg(ap, XS_T *);
|
||||
va_end(ap);
|
||||
|
||||
tgt = XS_TGT(xs);
|
||||
chan = XS_CHANNEL(xs);
|
||||
|
||||
handle = isp_find_handle(isp, xs);
|
||||
if (handle == 0) {
|
||||
@@ -4554,7 +4718,69 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
|
||||
break;
|
||||
}
|
||||
if (IS_24XX(isp)) {
|
||||
isp_prt(isp, ISP_LOGWARN, "ABORT CMD NOT IMPLEMENTED");
|
||||
isp24xx_abrt_t local, *ab = &local, *ab2;
|
||||
fcparam *fcp;
|
||||
fcportdb_t *lp;
|
||||
int hdlidx;
|
||||
|
||||
fcp = FCPARAM(isp, chan);
|
||||
hdlidx = fcp->isp_ini_map[tgt] - 1;
|
||||
if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d bad handle %d trying to abort"
|
||||
"target %d", chan, hdlidx, tgt);
|
||||
break;
|
||||
}
|
||||
lp = &fcp->portdb[hdlidx];
|
||||
if (lp->state != FC_PORTDB_STATE_VALID) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d handle %d for abort of target %d "
|
||||
"no longer valid", chan, hdlidx, tgt);
|
||||
break;
|
||||
}
|
||||
isp_prt(isp, ISP_LOGALL,
|
||||
"Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x %p",
|
||||
chan, lp->handle, lp->portid, xs);
|
||||
MEMZERO(ab, QENTRY_LEN);
|
||||
ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
|
||||
ab->abrt_header.rqs_entry_count = 1;
|
||||
ab->abrt_handle = lp->handle;
|
||||
ab->abrt_cmd_handle = handle;
|
||||
ab->abrt_tidlo = lp->portid;
|
||||
ab->abrt_tidhi = lp->portid >> 16;
|
||||
ab->abrt_vpidx = chan;
|
||||
|
||||
MEMZERO(&mbs, sizeof (mbs));
|
||||
mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
|
||||
mbs.param[1] = QENTRY_LEN;
|
||||
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
|
||||
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
|
||||
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
|
||||
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
|
||||
mbs.timeout = 5000000;
|
||||
mbs.logval = MBLOGALL;
|
||||
|
||||
FC_SCRATCH_ACQUIRE(isp, chan);
|
||||
isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
|
||||
ab2 = (isp24xx_abrt_t *)
|
||||
&((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
|
||||
ab2->abrt_nphdl = 0xdeaf;
|
||||
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
break;
|
||||
}
|
||||
MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
|
||||
QENTRY_LEN);
|
||||
isp_get_24xx_abrt(isp, ab2, ab);
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
|
||||
return (0);
|
||||
}
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"Chan %d handle %d abort returned 0x%x", chan,
|
||||
hdlidx, ab->abrt_nphdl);
|
||||
break;
|
||||
} else if (IS_FC(isp)) {
|
||||
if (ISP_CAP_SCCFW(isp)) {
|
||||
@@ -4568,7 +4794,6 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
|
||||
mbs.param[1] = tgt << 8 | XS_LUN(xs);
|
||||
}
|
||||
} else {
|
||||
chan = XS_CHANNEL(xs);
|
||||
mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
|
||||
}
|
||||
mbs.param[0] = MBOX_ABORT;
|
||||
@@ -5008,13 +5233,20 @@ again:
|
||||
* may have updated the response queue pointers for
|
||||
* us, so we reload our goal index.
|
||||
*/
|
||||
int r;
|
||||
r = isp_handle_other_response(isp, etype, hp, &optr);
|
||||
int r, tsto = oop;
|
||||
r = isp_handle_other_response(isp, etype, hp, &tsto);
|
||||
if (r < 0) {
|
||||
goto read_again;
|
||||
}
|
||||
/*
|
||||
* If somebody updated the output pointer, then reset
|
||||
* optr to be one more than the updated amount.
|
||||
*/
|
||||
while (tsto != oop) {
|
||||
optr = ISP_NXT_QENTRY(tsto, RESULT_QUEUE_LEN(isp));
|
||||
}
|
||||
if (r > 0) {
|
||||
iptr = isp->isp_resodx;
|
||||
ISP_WRITE(isp, isp->isp_respoutrp, optr);
|
||||
MEMZERO(hp, QENTRY_LEN); /* PERF */
|
||||
continue;
|
||||
}
|
||||
@@ -5704,6 +5936,8 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
|
||||
break;
|
||||
|
||||
case ASYNC_PDB_CHANGED:
|
||||
{
|
||||
int nphdl, nlstate, reason;
|
||||
if (IS_SCSI(isp)) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"bad PDB CHANGED event for SCSI cards");
|
||||
@@ -5714,6 +5948,14 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
|
||||
* to get more than a PDB CHANGED on channel 0, so turn it into
|
||||
* a broadcast event.
|
||||
*/
|
||||
if (IS_24XX(isp)) {
|
||||
nphdl = ISP_READ(isp, OUTMAILBOX1);
|
||||
nlstate = ISP_READ(isp, OUTMAILBOX2);
|
||||
reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
|
||||
} else {
|
||||
nphdl = NIL_HANDLE;
|
||||
nlstate = reason = 0;
|
||||
}
|
||||
for (chan = 0; chan < isp->isp_nchan; chan++) {
|
||||
fcparam *fcp = FCPARAM(isp, chan);
|
||||
|
||||
@@ -5724,10 +5966,10 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
|
||||
fcp->isp_loopstate = LOOP_PDB_RCVD;
|
||||
ISP_MARK_PORTDB(isp, chan, 1);
|
||||
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
|
||||
ISPASYNC_CHANGE_PDB);
|
||||
ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case ASYNC_CHANGE_NOTIFY:
|
||||
{
|
||||
int lochan, hichan;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_library.c,v 1.48 2007/12/04 22:19:21 mjacob Exp $ */
|
||||
/* $Id: isp_library.c,v 1.49 2008/01/04 16:48:57 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -651,6 +651,40 @@ isp_put_request_t7(ispsoftc_t *isp, ispreqt7_t *src, ispreqt7_t *dst)
|
||||
&dst->req_dataseg.ds_count);
|
||||
}
|
||||
|
||||
void
|
||||
isp_put_24xx_tmf(ispsoftc_t *isp, isp24xx_tmf_t *src, isp24xx_tmf_t *dst)
|
||||
{
|
||||
int i;
|
||||
uint32_t *a, *b;
|
||||
|
||||
isp_put_hdr(isp, &src->tmf_header, &dst->tmf_header);
|
||||
ISP_IOXPUT_32(isp, src->tmf_handle, &dst->tmf_handle);
|
||||
ISP_IOXPUT_16(isp, src->tmf_nphdl, &dst->tmf_nphdl);
|
||||
ISP_IOXPUT_16(isp, src->tmf_delay, &dst->tmf_delay);
|
||||
ISP_IOXPUT_16(isp, src->tmf_timeout, &dst->tmf_timeout);
|
||||
for (i = 0; i < ASIZE(src->tmf_reserved0); i++) {
|
||||
ISP_IOXPUT_8(isp, src->tmf_reserved0[i],
|
||||
&dst->tmf_reserved0[i]);
|
||||
}
|
||||
a = (uint32_t *) src->tmf_lun;
|
||||
b = (uint32_t *) dst->tmf_lun;
|
||||
for (i = 0; i < (ASIZE(src->tmf_lun) >> 2); i++ ) {
|
||||
*b++ = ISP_SWAP32(isp, *a++);
|
||||
}
|
||||
ISP_IOXPUT_32(isp, src->tmf_flags, &dst->tmf_flags);
|
||||
for (i = 0; i < ASIZE(src->tmf_reserved1); i++) {
|
||||
ISP_IOXPUT_8(isp, src->tmf_reserved1[i],
|
||||
&dst->tmf_reserved1[i]);
|
||||
}
|
||||
ISP_IOXPUT_16(isp, src->tmf_tidlo, &dst->tmf_tidlo);
|
||||
ISP_IOXPUT_8(isp, src->tmf_tidhi, &dst->tmf_tidhi);
|
||||
ISP_IOXPUT_8(isp, src->tmf_vpidx, &dst->tmf_vpidx);
|
||||
for (i = 0; i < ASIZE(src->tmf_reserved2); i++) {
|
||||
ISP_IOXPUT_8(isp, src->tmf_reserved2[i],
|
||||
&dst->tmf_reserved2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isp_put_24xx_abrt(ispsoftc_t *isp, isp24xx_abrt_t *src, isp24xx_abrt_t *dst)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_library.h,v 1.26 2007/12/02 22:02:04 mjacob Exp $ */
|
||||
/* $Id: isp_library.h,v 1.27 2008/01/04 16:48:57 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -81,6 +81,7 @@ void isp_put_request_t3(ispsoftc_t *, ispreqt3_t *, ispreqt3_t *);
|
||||
void isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
|
||||
void isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
|
||||
void isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
|
||||
void isp_put_24xx_tmf(ispsoftc_t *, isp24xx_tmf_t *, isp24xx_tmf_t *);
|
||||
void isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
void isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
|
||||
void isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_target.c,v 1.73 2007/12/20 18:23:45 mjacob Exp $ */
|
||||
/* $Id: isp_target.c,v 1.74 2008/01/04 16:47:18 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -812,7 +812,7 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
|
||||
ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
|
||||
ct->ct_nphdl = CT7_OK;
|
||||
ct->ct_syshandle = bus;
|
||||
ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
|
||||
ct->ct_flags = CT7_SENDSTATUS;
|
||||
} else if (IS_FC(isp)) {
|
||||
/* This should also suffice for 2K login code */
|
||||
ct2_entry_t *ct = (ct2_entry_t *) storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_target.h,v 1.58 2007/12/20 18:24:40 mjacob Exp $ */
|
||||
/* $Id: isp_target.h,v 1.59 2008/01/04 16:47:18 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -827,7 +827,7 @@ typedef struct {
|
||||
#define CT7_FLAG_MODE1 0x0040
|
||||
#define CT7_FLAG_MODE2 0x0080
|
||||
#define CT7_FLAG_MMASK 0x00C0
|
||||
#define CT7_FASTPOST 0x0100
|
||||
#define CT7_NOACK 0x0100
|
||||
#define CT7_TASK_ATTR_SHIFT 9
|
||||
#define CT7_CONFIRM 0x2000
|
||||
#define CT7_TERMINATE 0x4000
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: ispmbox.h,v 1.68 2007/12/05 00:42:02 mjacob Exp $ */
|
||||
/* $Id: ispmbox.h,v 1.69 2008/01/04 17:46:10 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -572,6 +572,31 @@ typedef struct {
|
||||
ispds64_t req_dataseg;
|
||||
} ispreqt7_t;
|
||||
|
||||
/* Task Management Request Function */
|
||||
typedef struct {
|
||||
isphdr_t tmf_header;
|
||||
uint32_t tmf_handle;
|
||||
uint16_t tmf_nphdl;
|
||||
uint8_t tmf_reserved0[2];
|
||||
uint16_t tmf_delay;
|
||||
uint16_t tmf_timeout;
|
||||
uint8_t tmf_lun[8];
|
||||
uint32_t tmf_flags;
|
||||
uint8_t tmf_reserved1[20];
|
||||
uint16_t tmf_tidlo;
|
||||
uint8_t tmf_tidhi;
|
||||
uint8_t tmf_vpidx;
|
||||
uint8_t tmf_reserved2[12];
|
||||
} isp24xx_tmf_t;
|
||||
|
||||
#define ISP24XX_TMF_NOSEND 0x80000000
|
||||
|
||||
#define ISP24XX_TMF_LUN_RESET 0x00000010
|
||||
#define ISP24XX_TMF_ABORT_TASK_SET 0x00000008
|
||||
#define ISP24XX_TMF_CLEAR_TASK_SET 0x00000004
|
||||
#define ISP24XX_TMF_TARGET_RESET 0x00000002
|
||||
#define ISP24XX_TMF_CLEAR_ACA 0x00000001
|
||||
|
||||
/* I/O Abort Structure */
|
||||
typedef struct {
|
||||
isphdr_t abrt_header;
|
||||
@@ -585,7 +610,9 @@ typedef struct {
|
||||
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_NOSEND 0x01 /* don't actually send ABTS */
|
||||
#define ISP24XX_ABRT_OKAY 0x00 /* in nphdl on return */
|
||||
#define ISP24XX_ABRT_ENXIO 0x31 /* in nphdl on return */
|
||||
|
||||
#define ISP_CDSEG 7
|
||||
@@ -1258,6 +1285,14 @@ typedef struct {
|
||||
#define PDB2400_CLASS2 0x0010
|
||||
#define PDB2400_ADDR_VALID 0x0002
|
||||
|
||||
#define PDB2400_STATE_PLOGI_PEND 0x03
|
||||
#define PDB2400_STATE_PLOGI_DONE 0x04
|
||||
#define PDB2400_STATE_PRLI_PEND 0x05
|
||||
#define PDB2400_STATE_LOGGED_IN 0x06
|
||||
#define PDB2400_STATE_PORT_UNAVAIL 0x07
|
||||
#define PDB2400_STATE_PRLO_PEND 0x09
|
||||
#define PDB2400_STATE_LOGO_PEND 0x0B
|
||||
|
||||
/*
|
||||
* Common elements from the above two structures that are actually useful to us.
|
||||
*/
|
||||
@@ -1270,6 +1305,35 @@ typedef struct {
|
||||
uint8_t nodename[8];
|
||||
} isp_pdb_t;
|
||||
|
||||
/*
|
||||
* Port Database Changed Async Event information for 24XX cards
|
||||
*/
|
||||
#define PDB24XX_AE_OK 0x00
|
||||
#define PDB24XX_AE_IMPL_LOGO_1 0x01
|
||||
#define PDB24XX_AE_IMPL_LOGO_2 0x02
|
||||
#define PDB24XX_AE_IMPL_LOGO_3 0x03
|
||||
#define PDB24XX_AE_PLOGI_RCVD 0x04
|
||||
#define PDB24XX_AE_PLOGI_RJT 0x05
|
||||
#define PDB24XX_AE_PRLI_RCVD 0x06
|
||||
#define PDB24XX_AE_PRLI_RJT 0x07
|
||||
#define PDB24XX_AE_TPRLO 0x08
|
||||
#define PDB24XX_AE_TPRLO_RJT 0x09
|
||||
#define PDB24XX_AE_PRLO_RCVD 0x0a
|
||||
#define PDB24XX_AE_LOGO_RCVD 0x0b
|
||||
#define PDB24XX_AE_TOPO_CHG 0x0c
|
||||
#define PDB24XX_AE_NPORT_CHG 0x0d
|
||||
#define PDB24XX_AE_FLOGI_RJT 0x0e
|
||||
#define PDB24XX_AE_BAD_FANN 0x0f
|
||||
#define PDB24XX_AE_FLOGI_TIMO 0x10
|
||||
#define PDB24XX_AE_ABX_LOGO 0x11
|
||||
#define PDB24XX_AE_PLOGI_DONE 0x12
|
||||
#define PDB24XX_AE_PRLI_DONJE 0x13
|
||||
#define PDB24XX_AE_OPN_1 0x14
|
||||
#define PDB24XX_AE_OPN_2 0x15
|
||||
#define PDB24XX_AE_TXERR 0x16
|
||||
#define PDB24XX_AE_FORCED_LOGO 0x17
|
||||
#define PDB24XX_AE_DISC_TIMO 0x18
|
||||
|
||||
/*
|
||||
* Genericized Port Login/Logout software structure
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: ispvar.h,v 1.89 2007/12/20 18:26:46 mjacob Exp $ */
|
||||
/* $Id: ispvar.h,v 1.90 2008/01/04 16:46:10 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -302,6 +302,8 @@ typedef struct {
|
||||
#define FABRIC_PORT_ID 0xFFFFFE
|
||||
#define PORT_ANY 0xFFFFFF
|
||||
#define PORT_NONE 0
|
||||
#define DOMAIN_CONTROLLER_BASE 0xFFFC00
|
||||
#define DOMAIN_CONTROLLER_END 0xFFFCFF
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_linux.c,v 1.215 2007/12/20 18:28:00 mjacob Exp $ */
|
||||
/* $Id: isp_linux.c,v 1.216 2008/01/04 18:00:20 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -682,7 +682,7 @@ isplinux_bdr(Scsi_Cmnd *Cmnd)
|
||||
r = isp_control(isp, ISPCTL_RESET_DEV, XS_CHANNEL(Cmnd), XS_TGT(Cmnd));
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
ISP_DRIVER_CTL_EXIT_LOCK(isp);
|
||||
isp_prt(isp, ISP_LOGINFO, "Bus Device Reset %succesfully sent to %d.%d.%d",
|
||||
isp_prt(isp, ISP_LOGINFO, "Bus Device Reset %successfully sent to %d.%d.%d",
|
||||
r == 0? "s" : "uns", XS_CHANNEL(Cmnd), XS_TGT(Cmnd), XS_LUN(Cmnd));
|
||||
return ((r == 0)? SUCCESS : FAILED);
|
||||
}
|
||||
@@ -712,7 +712,7 @@ isplinux_sreset(Scsi_Cmnd *Cmnd)
|
||||
r = isp_control(isp, ISPCTL_RESET_DEV, XS_CHANNEL(Cmnd), XS_TGT(Cmnd));
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
ISP_DRIVER_CTL_EXIT_LOCK(isp);
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d SCSI Bus Reset %succesful", XS_CHANNEL(Cmnd), r == 0? "s" : "uns");
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d SCSI Bus Reset %successful", XS_CHANNEL(Cmnd), r == 0? "s" : "uns");
|
||||
return ((r == 0)? SUCCESS : FAILED);
|
||||
}
|
||||
|
||||
@@ -1035,7 +1035,10 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3
|
||||
return;
|
||||
}
|
||||
while (--i >= 0) {
|
||||
if (i == FL_ID) {
|
||||
if (i >= FL_ID && i <= SNS_ID) {
|
||||
continue;
|
||||
}
|
||||
if (fcp->portdb[i].target_mode == 1) {
|
||||
continue;
|
||||
}
|
||||
if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
|
||||
@@ -1083,7 +1086,7 @@ isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3
|
||||
return;
|
||||
}
|
||||
if (i == MAX_FC_TARG) {
|
||||
isp_prt(isp, ISP_LOGINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cannot be found to be cleared",
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cannot be found to be cleared",
|
||||
__FUNCTION__, chan, (unsigned long long) lp->port_wwn, nphdl, lp->portid);
|
||||
} else {
|
||||
#if 0
|
||||
@@ -1324,6 +1327,7 @@ isp_taction(qact_e action, void *arg)
|
||||
}
|
||||
if (tmd->cd_lflags & CDFL_NEED_CLNUP) {
|
||||
tmd->cd_lflags &= ~CDFL_NEED_CLNUP;
|
||||
isp_prt(isp, ISP_LOGTINFO, "Terminating [%llx] on FIN", (unsigned long long) tmd->cd_tagval);
|
||||
(void) isp_terminate_cmd(isp, tmd);
|
||||
}
|
||||
tmd->cd_next = NULL;
|
||||
@@ -1357,6 +1361,31 @@ isp_taction(qact_e action, void *arg)
|
||||
if (isp->isp_state != ISP_RUNSTATE) {
|
||||
isp_prt(isp, ISP_LOGINFO, "[%llx] Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)",
|
||||
ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid);
|
||||
} else if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ATIO) {
|
||||
ct7_entry_t local, *cto = &local;
|
||||
at7_entry_t *aep = (at7_entry_t *)ins->qentry;
|
||||
fcportdb_t *lp;
|
||||
uint32_t sid;
|
||||
uint16_t nphdl;
|
||||
|
||||
sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
|
||||
if (isp_find_pdb_sid(isp, ins->notify.nt_channel, sid, &lp)) {
|
||||
nphdl = lp->handle;
|
||||
} else {
|
||||
nphdl = NIL_HANDLE;
|
||||
}
|
||||
MEMZERO(&local, sizeof (local));
|
||||
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
|
||||
cto->ct_header.rqs_entry_count = 1;
|
||||
cto->ct_nphdl = nphdl;
|
||||
cto->ct_rxid = aep->at_rxid;
|
||||
cto->ct_vpindex = ins->notify.nt_channel;
|
||||
cto->ct_iid_lo = sid;
|
||||
cto->ct_iid_hi = sid >> 16;
|
||||
cto->ct_oxid = aep->at_hdr.ox_id;
|
||||
cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1;
|
||||
cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT;
|
||||
(void) isp_target_put_entry(isp, &local);
|
||||
} else if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ABTS_RSP) {
|
||||
abts_t *abt = (abts_t *)ins->qentry;
|
||||
abts_rsp_t *rsp = (abts_rsp_t *)ins->qentry;
|
||||
@@ -2283,8 +2312,8 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
|
||||
sstr = "BIDIR";
|
||||
break;
|
||||
}
|
||||
isp_prt(isp, ISP_LOGALL, "ATIO7[%llx] Chan %d cdb0=0x%x from 0x%016llx/0x%06x ox_id 0x%x N-Port Handle 0x%02x for lun %u dlen %d %s", tmd->cd_tagval,
|
||||
tmd->cd_channel, tmd->cd_cdb[0] & 0xff, (unsigned long long) tmd->cd_iid, tmd->cd_portid, tmd->cd_oxid, tmd->cd_nphdl, lun, tmd->cd_totlen, sstr);
|
||||
isp_prt(isp, ISP_LOGALL, "ATIO7[%llx] cdb0=0x%x from 0x%016llx/0x%06x ox_id 0x%x N-Port Handle 0x%02x for lun %u dlen %d %s", tmd->cd_tagval,
|
||||
tmd->cd_cdb[0] & 0xff, (unsigned long long) tmd->cd_iid, tmd->cd_portid, tmd->cd_oxid, tmd->cd_nphdl, lun, tmd->cd_totlen, sstr);
|
||||
}
|
||||
|
||||
if (isp->isp_osinfo.hcb == 0) {
|
||||
@@ -2314,10 +2343,10 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
|
||||
static int
|
||||
isp_terminate_cmd(ispsoftc_t *isp, tmd_cmd_t *tmd)
|
||||
{
|
||||
ct7_entry_t local, *cto = &local;;
|
||||
ct7_entry_t local, *cto = &local;
|
||||
|
||||
if (IS_24XX(isp)) {
|
||||
isp_prt(isp, ISP_LOGINFO, "isp_terminate_cmd: Chan %d [%llx] is being terminated", (int) AT2_GET_BUS(tmd->cd_tagval), (unsigned long long) tmd->cd_tagval);
|
||||
isp_prt(isp, ISP_LOGTINFO, "isp_terminate_cmd: [%llx] is being terminated", (unsigned long long) tmd->cd_tagval);
|
||||
MEMZERO(&local, sizeof (local));
|
||||
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
|
||||
cto->ct_header.rqs_entry_count = 1;
|
||||
@@ -3143,15 +3172,27 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
break;
|
||||
case ISPASYNC_CHANGE_NOTIFY:
|
||||
{
|
||||
int chg;
|
||||
int chg, nphdl, nlstate, reason;
|
||||
|
||||
va_start(ap, cmd);
|
||||
bus = va_arg(ap, int);
|
||||
chg = va_arg(ap, int);
|
||||
if (chg == ISPASYNC_CHANGE_PDB) {
|
||||
nphdl = va_arg(ap, int);
|
||||
nlstate = va_arg(ap, int);
|
||||
reason = va_arg(ap, int);
|
||||
} else {
|
||||
nphdl = NIL_HANDLE;
|
||||
nlstate = reason = 0;
|
||||
}
|
||||
va_end(ap);
|
||||
fcp = FCPARAM(isp, bus);
|
||||
if (chg == ISPASYNC_CHANGE_PDB) {
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d Port Database Changed", bus);
|
||||
if (IS_24XX(isp)) {
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d Port Database Changed, N-Port Handle 0x%04x nlstate %x reason 0x%02x", bus, nphdl, nlstate, reason);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d Port Database Changed", bus);
|
||||
}
|
||||
} else if (chg == ISPASYNC_CHANGE_SNS) {
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d Name Server Database Changed", bus);
|
||||
} else {
|
||||
@@ -3371,8 +3412,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
tmd_cmd_t *tmd = &isp->isp_osinfo.pool[i];
|
||||
if (tmd->cd_lflags & CDFL_BUSY) {
|
||||
if (ins->notify.nt_tagval == tmd->cd_tagval && ins->notify.nt_channel == tmd->cd_channel) {
|
||||
tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP;
|
||||
break;
|
||||
isp_prt(isp, ISP_LOGTINFO, "[0x%llx] marked as aborted", (unsigned long long) tmd->cd_tagval);
|
||||
tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3759,62 +3801,76 @@ isplinux_default_wwn(ispsoftc_t *isp, int chan, int isactive, int iswwnn)
|
||||
uint64_t seed;
|
||||
isp_data *fc = ISP_DATA(isp, chan);
|
||||
|
||||
/*
|
||||
* If we're asking for a active WWN, the default overrides get returned,
|
||||
* otherwise the NVRAM value is picked.
|
||||
*
|
||||
* If we're asking for a default WWN, we just pick the default override.
|
||||
*/
|
||||
if (isactive) {
|
||||
seed = iswwnn? fc->def_wwnn : fc->def_wwpn;
|
||||
if (seed) {
|
||||
return (seed);
|
||||
}
|
||||
seed = iswwnn? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram;
|
||||
if (seed == 0) {
|
||||
seed = iswwnn? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
|
||||
}
|
||||
} else {
|
||||
seed = iswwnn? fc->def_wwnn : fc->def_wwpn;
|
||||
if (seed == 0) {
|
||||
seed = iswwnn? ISP_DATA(isp, 0)->def_wwnn : ISP_DATA(isp, 0)->def_wwpn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For channel zero, we just return right away.
|
||||
* For channel zero just return what we have. For either ACIIVE or DEFAULT cases,
|
||||
* we depend on default override of NVRAM values for channel zero.
|
||||
*/
|
||||
if (chan == 0) {
|
||||
return (seed);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we aren't a type 2 NAA or the chan in range, forget it.
|
||||
* Look out for zeroed WWNNs.
|
||||
* For other channels, we are doing one of three things:
|
||||
*
|
||||
* 1. If what we have now is non-zero, return it. Otherwise
|
||||
* we morph values from channel 0.
|
||||
* 2. If we're here for a WWPN we synthesize it if
|
||||
* Channel 0's wwpn has a type 2 NAA.
|
||||
* 3. If we're here for a WWNN we synthesize it if
|
||||
* Channel 0's wwnn has a type 2 NAA.
|
||||
*/
|
||||
if ((seed >> 60) != 2ULL || chan < 0 || chan > 255) {
|
||||
if (seed == 0 && iswwnn) {
|
||||
uint64_t wwpn = isplinux_default_wwn(isp, chan, isactive, 0);
|
||||
if (wwpn) {
|
||||
seed = wwpn & ~(255ULL << 52);
|
||||
}
|
||||
}
|
||||
|
||||
if (seed) {
|
||||
return (seed);
|
||||
}
|
||||
if (isactive) {
|
||||
seed = iswwnn? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
|
||||
} else {
|
||||
seed = iswwnn? ISP_DATA(isp, 0)->def_wwnn : ISP_DATA(isp, 0)->def_wwpn;
|
||||
}
|
||||
|
||||
/*
|
||||
* The type 2 NAA fields for QLogic cards appear be laid out thusly:
|
||||
*
|
||||
* bits 63..61 unused/zero
|
||||
* bit 60 port or node WWN distinguishor
|
||||
* bits 59..49 unused/zero
|
||||
* bit 48 physical port on dual-port chips (23XX/24XX)
|
||||
*
|
||||
* This is somewhat nutty, particularly since bit 48 is irrelevant
|
||||
* as they seem to assign seperate serial numbers to different
|
||||
* physical ports :-).
|
||||
*
|
||||
* We'll stick our channel number first into bits 59..56 and thence
|
||||
* into bits 55..52.
|
||||
*/
|
||||
seed &= ~(255ULL << 52);
|
||||
seed |= ((uint64_t) (chan+1) & 0xf) << 56;
|
||||
seed |= ((uint64_t) ((chan+1) >> 8) & 0xf) << 52;
|
||||
if (((seed >> 60) & 0xf) == 2) {
|
||||
/*
|
||||
* The type 2 NAA fields for QLogic cards appear be laid out thusly:
|
||||
*
|
||||
* bits 63..60 NAA == 2
|
||||
* bits 59..57 unused/zero
|
||||
* bit 56 port (1) or node (0) WWN distinguishor
|
||||
* bit 48 physical port on dual-port chips (23XX/24XX)
|
||||
*
|
||||
* This is somewhat nutty, particularly since bit 48 is irrelevant
|
||||
* as they assign seperate serial numbers to different physical ports
|
||||
* anyway.
|
||||
*
|
||||
* We'll stick our channel number plus one first into bits 57..59 and
|
||||
* thence into bits 52..55 which allows for 8 bits of channel which is
|
||||
* comfortably more than our maximum (126) now.
|
||||
*/
|
||||
seed &= ~0x0FF0000000000000ULL;
|
||||
if (iswwnn == 0) {
|
||||
seed |= ((uint64_t) (chan+1) & 0xf) << 56;
|
||||
seed |= ((uint64_t) ((chan+1) >> 4) & 0xf) << 52;
|
||||
}
|
||||
} else {
|
||||
seed = 0;
|
||||
}
|
||||
return (seed);
|
||||
}
|
||||
|
||||
@@ -4582,6 +4638,7 @@ isp_task_thread(void *arg)
|
||||
uint16_t nphdl = NIL_HANDLE;
|
||||
|
||||
if (tmd->cd_lflags & CDFL_ABORTED) {
|
||||
isp_prt(isp, ISP_LOGTINFO, "[%llx] asking thread to terminate because it was marked aborted", (unsigned long long) tmd->cd_tagval);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
|
||||
break;
|
||||
}
|
||||
@@ -4604,7 +4661,7 @@ isp_task_thread(void *arg)
|
||||
* has cleared it out. The command is probably already dead due to initiator port logout.
|
||||
*/
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "%s: Chan %d [0x%llx] terminating command because PortID 0x%06x no longer in port database", __FUNCTION__, tmd->cd_channel, tmd->cd_tagval, tmd->cd_portid);
|
||||
isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate command because PortID 0x%06x no longer in port database", tmd->cd_tagval, tmd->cd_portid);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
|
||||
break;
|
||||
}
|
||||
@@ -4641,7 +4698,7 @@ isp_task_thread(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d Terminating %llx from 0x%06x", (int) AT2_GET_BUS(tmd->cd_tagval), (unsigned long long) tmd->cd_tagval, tmd->cd_portid);
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s now terminating [%llx] from 0x%06x", __FUNCTION__, (unsigned long long) tmd->cd_tagval, tmd->cd_portid);
|
||||
if (isp_terminate_cmd(isp, tmd)) {
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
|
||||
@@ -4678,7 +4735,7 @@ isp_task_thread(void *arg)
|
||||
{
|
||||
tmd_cmd_t *tmd = tap->arg;
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
isp_prt(isp, ISP_LOGINFO, "%s: [%llx] calling putback", __FUNCTION__, tmd->cd_tagval);
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: [%llx] calling putback", __FUNCTION__, tmd->cd_tagval);
|
||||
if (isp_target_putback_atio(isp, tmd)) {
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__);
|
||||
@@ -4686,6 +4743,7 @@ isp_task_thread(void *arg)
|
||||
}
|
||||
if (tmd->cd_lflags & CDFL_NEED_CLNUP) {
|
||||
tmd->cd_lflags ^= CDFL_NEED_CLNUP;
|
||||
isp_prt(isp, ISP_LOGTINFO, "Terminating %llx too", (unsigned long long) tmd->cd_tagval);
|
||||
(void) isp_terminate_cmd(isp, tmd);
|
||||
}
|
||||
MEMZERO(tmd, sizeof (tmd_cmd_t));
|
||||
|
||||
Reference in New Issue
Block a user