mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
A lot of microchanges, but actually this means that the FreeBSD port,
the SCST port, and the non-SCST Feral port are all more or less in sync. And apparently somewhat functional. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@825 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
$Id: README,v 1.30 2007/03/05 19:10:52 mjacob Exp $
|
||||
$Id: README,v 1.32 2009/05/02 23:25:49 mjacob Exp $
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Supported Cards:
|
||||
@@ -20,11 +20,13 @@ PCI Fibre Channel
|
||||
4-Gbit:
|
||||
ISP2422, ISP2432
|
||||
|
||||
8-GBit:
|
||||
ISP2532
|
||||
|
||||
You should note that some old non-Qlogic (or very old Qlogic) 2100 cards may
|
||||
have trouble loading firmware. The newer f/w for 2100s is > 0x8000 words,
|
||||
which PROM code on some cards has trouble loading- define the token
|
||||
USE_SMALLER_2100_FIRMWARE to select 1.15.37 f/w for the 2100.
|
||||
|
||||
For 23XX (but not 2322) 2K Login firmware is available and is recommended.
|
||||
|
||||
For 23XX (but not 2322) 2K Login firmware is available and is the detfault.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@@ -188,12 +188,12 @@ static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
|
||||
*/
|
||||
|
||||
void
|
||||
isp_reset(ispsoftc_t *isp)
|
||||
isp_reset(ispsoftc_t *isp, int do_load_defaults)
|
||||
{
|
||||
mbreg_t mbs;
|
||||
uint32_t code_org, val;
|
||||
int loops, i, dodnld = 1;
|
||||
static const char *btype = "????";
|
||||
const char *btype = "????";
|
||||
static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
|
||||
|
||||
isp->isp_state = ISP_NILSTATE;
|
||||
@@ -511,10 +511,8 @@ isp_reset(ispsoftc_t *isp)
|
||||
/*
|
||||
* Clear data && control DMA engines.
|
||||
*/
|
||||
ISP_WRITE(isp, CDMA_CONTROL,
|
||||
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
|
||||
ISP_WRITE(isp, DDMA_CONTROL,
|
||||
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
|
||||
ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
|
||||
ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
|
||||
|
||||
|
||||
} else if (IS_24XX(isp)) {
|
||||
@@ -537,8 +535,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
/*
|
||||
* Hold it in SOFT_RESET and STOP state for 100us.
|
||||
*/
|
||||
ISP_WRITE(isp, BIU2400_CSR,
|
||||
BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
|
||||
ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
|
||||
ISP_DELAY(100);
|
||||
for (loops = 0; loops < 10000; loops++) {
|
||||
ISP_DELAY(5);
|
||||
@@ -565,12 +562,9 @@ isp_reset(ispsoftc_t *isp)
|
||||
/*
|
||||
* Clear data && control DMA engines.
|
||||
*/
|
||||
ISP_WRITE(isp, CDMA2100_CONTROL,
|
||||
DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
ISP_WRITE(isp, TDMA2100_CONTROL,
|
||||
DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
ISP_WRITE(isp, RDMA2100_CONTROL,
|
||||
DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -728,8 +722,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
mbs.logval = MBLOGALL;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)",
|
||||
mbs.param[0]);
|
||||
isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", mbs.param[0]);
|
||||
ISP_RESET0(isp);
|
||||
return;
|
||||
}
|
||||
@@ -758,10 +751,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
|
||||
mbs.param[5] != 0xa5a5) {
|
||||
ISP_RESET0(isp);
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
|
||||
mbs.param[1], mbs.param[2], mbs.param[3],
|
||||
mbs.param[4], mbs.param[5]);
|
||||
isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -776,8 +766,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
* whether we have f/w at all and whether a config flag
|
||||
* has disabled our download.
|
||||
*/
|
||||
if ((isp->isp_mdvec->dv_ispfw == NULL) ||
|
||||
(isp->isp_confopts & ISP_CFG_NORELOAD)) {
|
||||
if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
|
||||
dodnld = 0;
|
||||
}
|
||||
|
||||
@@ -800,9 +789,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
for (;;) {
|
||||
uint32_t la, wi, wl;
|
||||
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"load 0x%x words of code at load address 0x%x",
|
||||
ptr[3], ptr[2]);
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
|
||||
|
||||
wi = 0;
|
||||
la = ptr[2];
|
||||
@@ -821,8 +808,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
ISP_IOXPUT_32(isp, ptr[wi++], &cp[i]);
|
||||
wl--;
|
||||
}
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST,
|
||||
0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
|
||||
ISP_MEMZERO(&mbs, sizeof (mbs));
|
||||
mbs.param[0] = MBOX_LOAD_RISC_RAM;
|
||||
mbs.param[1] = la;
|
||||
@@ -836,8 +822,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
mbs.logval = MBLOGALL;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"F/W Risc Ram Load Failed");
|
||||
isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
|
||||
ISP_RESET0(isp);
|
||||
return;
|
||||
}
|
||||
@@ -861,9 +846,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
for (;;) {
|
||||
uint32_t nxtaddr;
|
||||
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"load 0x%x words of code at load address 0x%x",
|
||||
ptr[3], la);
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
|
||||
|
||||
wi = 0;
|
||||
wl = ptr[3];
|
||||
@@ -884,8 +867,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
ISP_IOXPUT_16(isp, ptr[wi++], &cp[i]);
|
||||
wl--;
|
||||
}
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST,
|
||||
0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
|
||||
MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
|
||||
ISP_MEMZERO(&mbs, sizeof (mbs));
|
||||
mbs.param[0] = MBOX_LOAD_RISC_RAM;
|
||||
mbs.param[1] = la;
|
||||
@@ -898,8 +880,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
mbs.logval = MBLOGALL;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"F/W Risc Ram Load Failed");
|
||||
isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
|
||||
ISP_RESET0(isp);
|
||||
return;
|
||||
}
|
||||
@@ -943,9 +924,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
mbs.logval = MBLOGNONE;
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"F/W download failed at word %d",
|
||||
isp->isp_mbxwrk1 - code_org);
|
||||
isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
|
||||
ISP_RESET0(isp);
|
||||
return;
|
||||
}
|
||||
@@ -1075,10 +1054,8 @@ isp_reset(ispsoftc_t *isp)
|
||||
isp->isp_fwrev[2] = mbs.param[3];
|
||||
}
|
||||
|
||||
isp_prt(isp, ISP_LOGCONFIG,
|
||||
"Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
|
||||
btype, isp->isp_revision, dodnld? "loaded" : "resident",
|
||||
isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
|
||||
isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
|
||||
btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
|
||||
|
||||
if (IS_FC(isp)) {
|
||||
/*
|
||||
@@ -1118,8 +1095,7 @@ isp_reset(ispsoftc_t *isp)
|
||||
isp->isp_maxcmds = mbs.param[2];
|
||||
}
|
||||
}
|
||||
isp_prt(isp, ISP_LOGCONFIG,
|
||||
"%d max I/O command limit set", isp->isp_maxcmds);
|
||||
isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
|
||||
for (i = 0; i < isp->isp_nchan; i++) {
|
||||
isp_fw_state(isp, i);
|
||||
}
|
||||
@@ -1171,14 +1147,15 @@ isp_reset(ispsoftc_t *isp)
|
||||
* effect, NVRAM is read here (unless overriden by
|
||||
* a configuration flag).
|
||||
*/
|
||||
if (IS_SCSI(isp)) {
|
||||
isp_setdfltsdparm(isp);
|
||||
} else {
|
||||
for (i = 0; i < isp->isp_nchan; i++) {
|
||||
isp_setdfltfcparm(isp, i);
|
||||
if (do_load_defaults) {
|
||||
if (IS_SCSI(isp)) {
|
||||
isp_setdfltsdparm(isp);
|
||||
} else {
|
||||
for (i = 0; i < isp->isp_nchan; i++) {
|
||||
isp_setdfltfcparm(isp, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1799,9 +1776,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
}
|
||||
|
||||
if (ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"non-MULTIID f/w loaded, only can enable 1 of %d channels",
|
||||
isp->isp_nchan);
|
||||
isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
|
||||
nchan = 1;
|
||||
} else {
|
||||
nchan = isp->isp_nchan;
|
||||
@@ -1838,19 +1813,14 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
|
||||
icbp->icb_version = ICB_VERSION1;
|
||||
icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
|
||||
if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
|
||||
icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"bad frame length (%d) from NVRAM- using %d",
|
||||
DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
|
||||
if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
|
||||
isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
|
||||
icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
|
||||
}
|
||||
|
||||
icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
|
||||
if (icbp->icb_execthrottle < 1) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"bad execution throttle of %d- using %d",
|
||||
DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
|
||||
isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
|
||||
icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
|
||||
}
|
||||
|
||||
@@ -1914,8 +1884,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field",
|
||||
icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
|
||||
isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
|
||||
icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
|
||||
break;
|
||||
}
|
||||
@@ -1946,19 +1915,12 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
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);
|
||||
isp_prt(isp, ISP_LOGDEBUG1,
|
||||
"Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
|
||||
((uint32_t) (fcp->isp_wwnn >> 32)),
|
||||
((uint32_t) (fcp->isp_wwnn)),
|
||||
((uint32_t) (fcp->isp_wwpn >> 32)),
|
||||
((uint32_t) (fcp->isp_wwpn)));
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
|
||||
((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
|
||||
} else if (fcp->isp_wwpn) {
|
||||
icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
|
||||
MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
|
||||
isp_prt(isp, ISP_LOGDEBUG1,
|
||||
"Setting ICB Node to be same as Port 0x%08x%08x",
|
||||
((uint32_t) (fcp->isp_wwpn >> 32)),
|
||||
((uint32_t) (fcp->isp_wwpn)));
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
|
||||
return;
|
||||
@@ -1967,8 +1929,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
|
||||
icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
|
||||
if (icbp->icb_rqstqlen < 8) {
|
||||
isp_prt(isp, ISP_LOGERR, "bad request queue length %d",
|
||||
icbp->icb_rqstqlen);
|
||||
isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
|
||||
return;
|
||||
}
|
||||
icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
|
||||
@@ -1991,34 +1952,25 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
/* unconditionally set up the ATIO queue if we support target mode */
|
||||
icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
|
||||
if (icbp->icb_atioqlen < 8) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"bad ATIO queue length %d", icbp->icb_atioqlen);
|
||||
isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
|
||||
return;
|
||||
}
|
||||
icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
|
||||
icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
|
||||
icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
|
||||
icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"isp_fibre_init_2400: atioq %04x%04x%04x%04x",
|
||||
DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
|
||||
DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
|
||||
#endif
|
||||
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
|
||||
icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
|
||||
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x",
|
||||
DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
|
||||
DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma),
|
||||
DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
|
||||
DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
|
||||
DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
|
||||
|
||||
if (isp->isp_dblev & ISP_LOGDEBUG1) {
|
||||
isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp),
|
||||
icbp);
|
||||
isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
|
||||
}
|
||||
|
||||
if (FC_SCRATCH_ACQUIRE(isp, 0)) {
|
||||
@@ -2052,17 +2004,13 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
if (fcp2->role != ISP_ROLE_NONE) {
|
||||
pi.vp_port_options = ICB2400_VPOPT_ENABLED;
|
||||
if (fcp2->role & ISP_ROLE_INITIATOR) {
|
||||
pi.vp_port_options |=
|
||||
ICB2400_VPOPT_INI_ENABLE;
|
||||
pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
|
||||
}
|
||||
if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
|
||||
pi.vp_port_options |=
|
||||
ICB2400_VPOPT_TGT_DISABLE;
|
||||
pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
|
||||
}
|
||||
MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname,
|
||||
fcp2->isp_wwpn);
|
||||
MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename,
|
||||
fcp2->isp_wwnn);
|
||||
MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
|
||||
MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
|
||||
}
|
||||
off = fcp->isp_scratch;
|
||||
off += ICB2400_VPINFO_PORT_OFF(chan);
|
||||
@@ -2085,9 +2033,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
|
||||
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
|
||||
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
|
||||
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x",
|
||||
DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma),
|
||||
DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
|
||||
isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
|
||||
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
|
||||
isp_mboxcmd(isp, &mbs);
|
||||
FC_SCRATCH_RELEASE(isp, 0);
|
||||
@@ -2118,7 +2064,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_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%02x port 0x%06x", chan,
|
||||
isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
|
||||
fcp->portdb[i].handle, fcp->portdb[i].portid);
|
||||
ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
|
||||
}
|
||||
@@ -2342,7 +2288,7 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
|
||||
|
||||
case MBOX_LOOP_ID_USED:
|
||||
isp_prt(isp, ISP_LOGDEBUG0,
|
||||
"isp_port_login: handle %u in use for port id 0x%02xXXXX",
|
||||
"isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
|
||||
handle, mbs.param[1] & 0xff);
|
||||
return (MBOX_LOOP_ID_USED);
|
||||
|
||||
@@ -3191,7 +3137,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
lp->new_roles = tmp.roles;
|
||||
lp->state = FC_PORTDB_STATE_PENDING_VALID;
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d Loop Port 0x%02x@0x%x Pending "
|
||||
"Chan %d Loop Port 0x%06x@0x%04x Pending "
|
||||
"Valid", chan, tmp.portid, tmp.handle);
|
||||
break;
|
||||
}
|
||||
@@ -3207,7 +3153,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
* decide what to do.
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d Loop Port 0x%02x@0x%x changed",
|
||||
"Chan %d Loop Port 0x%06x@0x%04x changed",
|
||||
chan, tmp.portid, tmp.handle);
|
||||
lp->state = FC_PORTDB_STATE_CHANGED;
|
||||
lp->new_portid = tmp.portid;
|
||||
@@ -3250,7 +3196,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
|
||||
lp->port_wwn = tmp.port_wwn;
|
||||
lp->node_wwn = tmp.node_wwn;
|
||||
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
|
||||
"Chan %d Loop Port 0x%02x@0x%x is New Entry",
|
||||
"Chan %d Loop Port 0x%06x@0x%04x is New Entry",
|
||||
chan, tmp.portid, tmp.handle);
|
||||
}
|
||||
fcp->isp_loopstate = LOOP_LSCAN_DONE;
|
||||
@@ -7786,13 +7732,11 @@ isp_setdfltfcparm(ispsoftc_t *isp, int chan)
|
||||
*/
|
||||
|
||||
void
|
||||
isp_reinit(ispsoftc_t *isp)
|
||||
isp_reinit(ispsoftc_t *isp, int do_load_defaults)
|
||||
{
|
||||
XS_T *xs;
|
||||
int i;
|
||||
uint32_t tmp;
|
||||
|
||||
isp_reset(isp);
|
||||
isp_reset(isp, do_load_defaults);
|
||||
|
||||
if (isp->isp_state != ISP_RESETSTATE) {
|
||||
isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
|
||||
@@ -7828,36 +7772,13 @@ isp_reinit(ispsoftc_t *isp)
|
||||
cleanup:
|
||||
|
||||
isp->isp_nactive = 0;
|
||||
|
||||
isp_clear_commands(isp);
|
||||
if (IS_FC(isp)) {
|
||||
for (i = 0; i < isp->isp_nchan; i++) {
|
||||
ISP_MARK_PORTDB(isp, i, -1);
|
||||
}
|
||||
}
|
||||
|
||||
for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) {
|
||||
uint32_t handle;
|
||||
|
||||
xs = isp->isp_xflist[tmp];
|
||||
if (xs == NULL) {
|
||||
continue;
|
||||
}
|
||||
handle = isp_find_handle(isp, xs);
|
||||
if (handle == 0) {
|
||||
continue;
|
||||
}
|
||||
isp_destroy_handle(isp, handle);
|
||||
if (XS_XFRLEN(xs)) {
|
||||
ISP_DMAFREE(isp, xs, handle);
|
||||
XS_SET_RESID(xs, XS_XFRLEN(xs));
|
||||
} else {
|
||||
XS_SET_RESID(xs, 0);
|
||||
}
|
||||
XS_SETERR(xs, HBA_BUSRESET);
|
||||
isp_done(xs);
|
||||
}
|
||||
#ifdef ISP_TARGET_MODE
|
||||
ISP_MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -98,6 +98,11 @@ const char *isp_fc_loop_statename(int);
|
||||
const char *isp_fc_toponame(fcparam *);
|
||||
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
void isp_clear_commands(ispsoftc_t *);
|
||||
|
||||
/*
|
||||
* Common chip shutdown function
|
||||
*/
|
||||
@@ -182,6 +187,16 @@ void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
|
||||
uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
|
||||
void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
|
||||
|
||||
int isp_find_pdb_by_wwn(ispsoftc_t *, int, uint64_t, fcportdb_t **);
|
||||
int isp_find_pdb_by_loopid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
|
||||
int isp_find_pdb_by_sid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
|
||||
void isp_find_chan_by_did(ispsoftc_t *, uint32_t, uint16_t *);
|
||||
void isp_add_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);
|
||||
void isp_del_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);
|
||||
void isp_del_all_wwn_entries(ispsoftc_t *, int);
|
||||
void isp_del_wwn_entries(ispsoftc_t *, isp_notify_t *);
|
||||
int isp_fc_change_role(ispsoftc_t *, int, int);
|
||||
|
||||
void isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
void isp_get_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
void isp_put_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
|
||||
|
||||
@@ -280,26 +280,28 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
break;
|
||||
}
|
||||
if (IS_FC(isp)) {
|
||||
inot_fcp = (in_fcentry_t *) local;
|
||||
if (ISP_CAP_2KLOGIN(isp)) {
|
||||
in_fcentry_e_t *ecp = (in_fcentry_e_t *)local;
|
||||
isp_get_notify_fc_e(isp, inote_fcp, (in_fcentry_e_t *)local);
|
||||
isp_get_notify_fc_e(isp, inote_fcp, ecp);
|
||||
iid = ecp->in_iid;
|
||||
status = ecp->in_status;
|
||||
seqid = ecp->in_seqid;
|
||||
} else {
|
||||
isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
|
||||
iid = inot_fcp->in_iid;
|
||||
in_fcentry_t *fcp = (in_fcentry_t *)local;
|
||||
isp_get_notify_fc(isp, inot_fcp, fcp);
|
||||
iid = fcp->in_iid;
|
||||
status = fcp->in_status;
|
||||
seqid = fcp->in_seqid;
|
||||
}
|
||||
status = inot_fcp->in_status;
|
||||
seqid = inot_fcp->in_seqid;
|
||||
} else {
|
||||
isp_get_notify(isp, inotp, (in_entry_t *)local);
|
||||
inotp = (in_entry_t *) local;
|
||||
status = inotp->in_status & 0xff;
|
||||
seqid = inotp->in_seqid;
|
||||
iid = inotp->in_iid;
|
||||
in_entry_t *inp = (in_entry_t *)local;
|
||||
isp_get_notify(isp, inotp, inp);
|
||||
status = inp->in_status & 0xff;
|
||||
seqid = inp->in_seqid;
|
||||
iid = inp->in_iid;
|
||||
if (IS_DUALBUS(isp)) {
|
||||
bus = GET_BUS_VAL(inotp->in_iid);
|
||||
SET_BUS_VAL(inotp->in_iid, 0);
|
||||
bus = GET_BUS_VAL(inp->in_iid);
|
||||
SET_BUS_VAL(inp->in_iid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +320,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
|
||||
(void) isp_notify_ack(isp, local);
|
||||
break;
|
||||
|
||||
case IN_RESET:
|
||||
ISP_MEMZERO(¬ify, sizeof (isp_notify_t));
|
||||
notify.nt_hba = isp;
|
||||
@@ -334,6 +337,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
notify.nt_lreserved = local;
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
|
||||
case IN_PORT_LOGOUT:
|
||||
ISP_MEMZERO(¬ify, sizeof (isp_notify_t));
|
||||
notify.nt_hba = isp;
|
||||
@@ -346,6 +350,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
notify.nt_lreserved = local;
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
|
||||
case IN_ABORT_TASK:
|
||||
ISP_MEMZERO(¬ify, sizeof (isp_notify_t));
|
||||
notify.nt_hba = isp;
|
||||
@@ -360,12 +365,26 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
break;
|
||||
|
||||
case IN_GLOBAL_LOGO:
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__);
|
||||
ISP_MEMZERO(¬ify, sizeof (isp_notify_t));
|
||||
notify.nt_hba = isp;
|
||||
notify.nt_wwn = INI_ANY;
|
||||
notify.nt_nphdl = NIL_HANDLE;
|
||||
notify.nt_sid = PORT_ANY;
|
||||
notify.nt_did = PORT_ANY;
|
||||
notify.nt_ncode = NT_GLOBAL_LOGOUT;
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
(void) isp_notify_ack(isp, local);
|
||||
break;
|
||||
|
||||
case IN_PORT_CHANGED:
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__);
|
||||
(void) isp_notify_ack(isp, local);
|
||||
break;
|
||||
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: unknown status (0x%x)", __func__, status);
|
||||
ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status);
|
||||
isp_print_bytes(isp, local, QENTRY_LEN, vptr);
|
||||
(void) isp_notify_ack(isp, local);
|
||||
break;
|
||||
}
|
||||
@@ -426,7 +445,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
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);
|
||||
isp_prt(isp, ISP_LOGERR, "%s: unknown entry type 0x%x", __func__, type);
|
||||
rval = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1847,8 +1866,9 @@ isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
|
||||
hichan = isp->isp_nchan;
|
||||
} else {
|
||||
if (chan >= isp->isp_nchan) {
|
||||
isp_prt(isp, ISP_LOGINFO, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status);
|
||||
isp_print_bytes(isp, "XXX", QENTRY_LEN, inot_24xx);
|
||||
char buf[64];
|
||||
ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status);
|
||||
isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
|
||||
(void) isp_notify_ack(isp, inot_24xx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,9 @@ typedef enum {
|
||||
NT_LINK_UP,
|
||||
NT_LINK_DOWN,
|
||||
NT_LOGOUT,
|
||||
NT_GLOBAL_LOGOUT,
|
||||
NT_ARRIVED,
|
||||
NT_DEPARTED,
|
||||
NT_HBA_RESET
|
||||
} isp_ncode_t;
|
||||
|
||||
@@ -87,7 +90,6 @@ typedef struct isp_notify {
|
||||
uint64_t nt_tgt; /* destination (wwn) */
|
||||
uint64_t nt_tagval; /* tag value */
|
||||
uint32_t
|
||||
nt_channel : 6, /* channel id */
|
||||
nt_sid : 24; /* source port id */
|
||||
uint32_t
|
||||
nt_failed : 1, /* notify operation failed */
|
||||
@@ -96,6 +98,7 @@ typedef struct isp_notify {
|
||||
uint32_t
|
||||
nt_lun : 16, /* logical unit */
|
||||
nt_nphdl : 16; /* n-port handle */
|
||||
uint8_t nt_channel; /* channel id */
|
||||
isp_ncode_t nt_ncode; /* action */
|
||||
} isp_notify_t;
|
||||
#define MATCH_TMD(tmd, iid, lun, tag) \
|
||||
|
||||
@@ -2226,6 +2226,8 @@ typedef struct {
|
||||
#define CT_SRR 0x45 /* SRR Received */
|
||||
#define CT_LUN_RESET 0x48 /* Lun Reset Received */
|
||||
|
||||
#define CT_HBA_RESET 0xffff /* pseudo error - command destroyed by HBA reset*/
|
||||
|
||||
/*
|
||||
* When the firmware returns a CTIO entry, it may overwrite the last
|
||||
* part of the structure with sense data. This starts at offset 0x2E
|
||||
@@ -2442,13 +2444,13 @@ typedef struct {
|
||||
#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_INVRXID 0x08 /* Invalid RX_ID */
|
||||
#define CT7_DATA_OVER 0x09 /* 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_DATA_UNDER 0x15 /* Data Underrun */
|
||||
#define CT7_PORTUNAVAIL 0x28 /* port not available */
|
||||
#define CT7_LOGOUT 0x29 /* port logout */
|
||||
#define CT7_PORTCHANGED 0x2A /* port changed */
|
||||
|
||||
@@ -292,6 +292,11 @@ typedef struct {
|
||||
*/
|
||||
#define LOCAL_LOOP_LIM 126
|
||||
|
||||
/*
|
||||
* Limit for (2K login) N-port handle amounts
|
||||
*/
|
||||
#define MAX_NPORT_HANDLE 2048
|
||||
|
||||
/*
|
||||
* Special Constants
|
||||
*/
|
||||
@@ -469,6 +474,18 @@ typedef struct {
|
||||
*/
|
||||
uint16_t isp_dev_map[MAX_FC_TARG];
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
/*
|
||||
* This maps N-Port Handle to portdb entry so we
|
||||
* don't have to search for every incoming command.
|
||||
*
|
||||
* The mapping function is to take any non-zero entry and
|
||||
* subtract one to get the portdb index. This means that
|
||||
* entries which are zero are unmapped (i.e., don't exist).
|
||||
*/
|
||||
uint16_t isp_tgt_map[MAX_NPORT_HANDLE];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Scratch DMA mapped in area to fetch Port Database stuff, etc.
|
||||
*/
|
||||
@@ -782,10 +799,9 @@ struct ispsoftc {
|
||||
*/
|
||||
|
||||
/*
|
||||
* Reset Hardware. Totally. Assumes that you'll follow this with
|
||||
* a call to isp_init.
|
||||
* Reset Hardware. Totally. Assumes that you'll follow this with a call to isp_init.
|
||||
*/
|
||||
void isp_reset(ispsoftc_t *);
|
||||
void isp_reset(ispsoftc_t *, int);
|
||||
|
||||
/*
|
||||
* Initialize Hardware to known state
|
||||
@@ -795,7 +811,7 @@ void isp_init(ispsoftc_t *);
|
||||
/*
|
||||
* Reset the ISP and call completion for any orphaned commands.
|
||||
*/
|
||||
void isp_reinit(ispsoftc_t *);
|
||||
void isp_reinit(ispsoftc_t *, int);
|
||||
|
||||
/*
|
||||
* Internal Interrupt Service Routine
|
||||
|
||||
@@ -193,7 +193,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
|
||||
io = len;
|
||||
} else if (strncmp(buf, "reset", 5) == 0) {
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
isp_reinit(isp);
|
||||
isp_reinit(isp, 0);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
} else if (strncmp(buf, "bins", 4) == 0) {
|
||||
@@ -540,7 +540,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
|
||||
case ISP_RESETHBA:
|
||||
{
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
isp_reset(isp);
|
||||
isp_reset(isp, 0);
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -116,10 +116,6 @@ static char *isp_wwnns;
|
||||
|
||||
extern void ISP_PARENT_TARGET (qact_e, void *);
|
||||
static inline tmd_cmd_t *isp_find_tmd(ispsoftc_t *, uint64_t);
|
||||
static void isp_add_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);
|
||||
static void isp_del_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);
|
||||
static inline int isp_find_pdb_by_loopid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
|
||||
static inline int isp_find_pdb_by_sid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
|
||||
static void isp_taction(qact_e, void *);
|
||||
static void isp_target_start_ctio(ispsoftc_t *, tmd_xact_t *);
|
||||
static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
|
||||
@@ -772,7 +768,7 @@ isplinux_hreset(Scsi_Cmnd *Cmnd)
|
||||
isp->isp_osinfo.wqnext = NULL;
|
||||
isp->isp_nactive = 0;
|
||||
|
||||
(void) isplinux_reinit(isp);
|
||||
(void) isplinux_reinit(isp, 0);
|
||||
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
ISP_DRIVER_CTL_EXIT_LOCK(isp);
|
||||
@@ -996,162 +992,6 @@ isp_find_tmd(ispsoftc_t *isp, uint64_t tagval)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint32_t s_id)
|
||||
{
|
||||
fcparam *fcp;
|
||||
fcportdb_t *lp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Make sure the addition of a new target mode entry doesn't duplicate entries
|
||||
* with the same N-Port handles, the same portids or the same Port WWN.
|
||||
*/
|
||||
fcp = FCPARAM(isp, chan);
|
||||
for (i = 0; i < MAX_FC_TARG; i++) {
|
||||
lp = &fcp->portdb[i];
|
||||
|
||||
if (lp->target_mode == 0) {
|
||||
continue;
|
||||
}
|
||||
if (nphdl != NIL_HANDLE && lp->handle == nphdl) {
|
||||
break;
|
||||
}
|
||||
if (s_id != PORT_NONE && lp->portid == s_id) {
|
||||
break;
|
||||
}
|
||||
if (VALID_INI(ini) && lp->port_wwn == ini) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < MAX_FC_TARG) {
|
||||
if (lp->portid != s_id || (VALID_INI(lp->port_wwn) && lp->port_wwn != ini)) {
|
||||
i = ISP_LOGWARN;
|
||||
} else {
|
||||
i = ISP_LOGTINFO;
|
||||
}
|
||||
if (lp->portid == s_id && VALID_INI(lp->port_wwn) && (lp->port_wwn == ini || ini == INI_NONE) && lp->handle == nphdl) {
|
||||
isp_prt(isp, i, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x reentered", __func__, chan,
|
||||
(ull) lp->port_wwn, lp->handle, lp->portid);
|
||||
} else {
|
||||
isp_prt(isp, i, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x overwrites IID 0x%016llx N-Port Handle 0x%02x Port Id 0x%06x",
|
||||
__func__, chan, (ull) ini, nphdl, s_id, (ull) lp->port_wwn, lp->handle, lp->portid);
|
||||
}
|
||||
lp->portid = s_id;
|
||||
if (VALID_INI(ini)) {
|
||||
lp->port_wwn = ini;
|
||||
}
|
||||
lp->handle = nphdl;
|
||||
return;
|
||||
}
|
||||
while (--i >= 0) {
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x- no room in port database",
|
||||
__func__, chan, (ull) ini, nphdl, s_id);
|
||||
return;
|
||||
}
|
||||
lp = &fcp->portdb[i];
|
||||
memset(lp, 0, sizeof (fcportdb_t));
|
||||
lp->target_mode = 1;
|
||||
lp->handle = nphdl;
|
||||
lp->portid = s_id;
|
||||
lp->port_wwn = ini;
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x added",
|
||||
__func__, chan, (ull) ini, nphdl, s_id);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint32_t s_id)
|
||||
{
|
||||
fcparam *fcp;
|
||||
fcportdb_t *lp;
|
||||
int i;
|
||||
fcp = FCPARAM(isp, chan);
|
||||
for (i = 0; i < MAX_FC_TARG; i++) {
|
||||
lp = &fcp->portdb[i];
|
||||
if (lp->target_mode == 0) {
|
||||
continue;
|
||||
}
|
||||
if (ini == INI_ANY && nphdl == NIL_HANDLE && s_id == PORT_ANY) {
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cleared due to wildcard call",
|
||||
__func__, chan, (ull) lp->port_wwn, lp->handle, lp->portid);
|
||||
memset(&fcp->portdb[i], 0, sizeof (fcportdb_t));
|
||||
continue;
|
||||
}
|
||||
if ((s_id == PORT_ANY || lp->portid == s_id) && lp->handle == nphdl) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ini == INI_ANY && nphdl == NIL_HANDLE && s_id == PORT_ANY) {
|
||||
return;
|
||||
}
|
||||
if (i == MAX_FC_TARG) {
|
||||
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",
|
||||
__func__, chan, (ull) lp->port_wwn, nphdl, lp->portid);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cleared",
|
||||
__func__, chan, (ull) lp->port_wwn, nphdl, lp->portid);
|
||||
memset(&fcp->portdb[i], 0, sizeof (fcportdb_t));
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
isp_find_pdb_by_loopid(ispsoftc_t *isp, int chan, uint32_t loopid, fcportdb_t **lptr)
|
||||
{
|
||||
fcparam *fcp;
|
||||
int i;
|
||||
|
||||
fcp = FCPARAM(isp, chan);
|
||||
for (i = MAX_FC_TARG-1; i >= 0; i--) {
|
||||
fcportdb_t *lp = &fcp->portdb[i];
|
||||
|
||||
if (lp->target_mode == 0) {
|
||||
continue;
|
||||
}
|
||||
if (lp->handle == loopid) {
|
||||
*lptr = lp;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isp_find_pdb_by_sid(ispsoftc_t *isp, int chan, uint32_t sid, fcportdb_t **lptr)
|
||||
{
|
||||
fcparam *fcp;
|
||||
int i;
|
||||
|
||||
if (chan >= isp->isp_nchan) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
fcp = FCPARAM(isp, chan);
|
||||
for (i = MAX_FC_TARG-1; i >= 0; i--) {
|
||||
fcportdb_t *lp = &fcp->portdb[i];
|
||||
|
||||
if (lp->target_mode == 0) {
|
||||
continue;
|
||||
}
|
||||
if (lp->portid == sid) {
|
||||
*lptr = lp;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_tgt_dump_pdb(ispsoftc_t *isp, int chan)
|
||||
{
|
||||
@@ -2162,7 +2002,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
|
||||
CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
|
||||
} else {
|
||||
tmd->cd_portid = PORT_NONE;
|
||||
isp_add_wwn_entry(isp, 0, tmd->cd_iid, tmd->cd_nphdl, PORT_NONE);
|
||||
isp_add_wwn_entry(isp, 0, tmd->cd_iid, tmd->cd_nphdl, PORT_ANY);
|
||||
(void) isp_thread_event(isp, ISP_THREAD_FINDPORTID, tmd, 0, __func__, __LINE__);
|
||||
}
|
||||
}
|
||||
@@ -2614,95 +2454,6 @@ isp_complete_ctio(ispsoftc_t *isp, tmd_xact_t *xact)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
|
||||
{
|
||||
fcparam *fcp;
|
||||
if (IS_SCSI(isp)) {
|
||||
return (0);
|
||||
}
|
||||
if (chan >= isp->isp_nchan) {
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
|
||||
return (-ENXIO);
|
||||
}
|
||||
fcp = FCPARAM(isp, chan);
|
||||
ISP_DATA(isp, chan)->blocked = 1;
|
||||
if (chan == 0 || new_role == ISP_ROLE_NONE) {
|
||||
SET_DEFAULT_ROLE(isp, chan, new_role);
|
||||
isp_reinit(isp);
|
||||
} else {
|
||||
mbreg_t mbs;
|
||||
vp_modify_t *vp;
|
||||
uint8_t qe[QENTRY_LEN], *scp;
|
||||
|
||||
memset(qe, 0, QENTRY_LEN);
|
||||
/* Acquire Scratch */
|
||||
|
||||
if (FC_SCRATCH_ACQUIRE(isp, chan)) {
|
||||
ISP_DATA(isp, chan)->blocked = 0;
|
||||
return (-EBUSY);
|
||||
}
|
||||
scp = fcp->isp_scratch;
|
||||
|
||||
/*
|
||||
* Build a VP MODIFY command in memory
|
||||
*/
|
||||
vp = (vp_modify_t *) qe;
|
||||
vp->vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
|
||||
vp->vp_mod_hdr.rqs_entry_count = 1;
|
||||
vp->vp_mod_cnt = 1;
|
||||
vp->vp_mod_idx0 = chan;
|
||||
vp->vp_mod_cmd = VP_MODIFY_ENA;
|
||||
vp->vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED;
|
||||
if (new_role & ISP_ROLE_INITIATOR) {
|
||||
vp->vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
|
||||
}
|
||||
if ((new_role & ISP_ROLE_TARGET) == 0) {
|
||||
vp->vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
|
||||
}
|
||||
MAKE_NODE_NAME_FROM_WWN(vp->vp_mod_ports[0].wwpn, fcp->isp_wwpn);
|
||||
MAKE_NODE_NAME_FROM_WWN(vp->vp_mod_ports[0].wwnn, fcp->isp_wwnn);
|
||||
isp_put_vp_modify(isp, vp, (vp_modify_t *) scp);
|
||||
|
||||
/*
|
||||
* Build a EXEC IOCB A64 command that points to the VP MODIFY command
|
||||
*/
|
||||
memset(&mbs, 0, 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.logval = MBLOGALL;
|
||||
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
|
||||
isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
|
||||
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
ISP_DATA(isp, chan)->blocked = 0;
|
||||
return (-EIO);
|
||||
}
|
||||
MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
|
||||
isp_get_vp_modify(isp, (vp_modify_t *)&scp[QENTRY_LEN], vp);
|
||||
|
||||
/*
|
||||
* Release Scratch
|
||||
*/
|
||||
FC_SCRATCH_RELEASE(isp, chan);
|
||||
|
||||
if (vp->vp_mod_status != VP_STS_OK) {
|
||||
isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of Chan %d failed with status %d", __func__, chan, vp->vp_mod_status);
|
||||
ISP_DATA(isp, chan)->blocked = 0;
|
||||
return (-EIO);
|
||||
}
|
||||
SET_DEFAULT_ROLE(isp, chan, new_role);
|
||||
fcp->role = new_role;
|
||||
}
|
||||
ISP_DATA(isp, chan)->blocked = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
isp_enable_lun(ispsoftc_t *isp, uint16_t bus, uint16_t lun)
|
||||
{
|
||||
@@ -3263,16 +3014,28 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
mp = va_arg(ap, isp_notify_t *);
|
||||
va_end(ap);
|
||||
|
||||
if (mp == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (FCPARAM(isp, mp->nt_channel) == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isp->isp_osinfo.hcb == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "ISPASYNC_TARGET_NOTIFY with target mode not enabled");
|
||||
isp_notify_ack(isp, mp->nt_lreserved);
|
||||
if (mp->nt_need_ack && mp->nt_lreserved) {
|
||||
isp_notify_ack(isp, mp->nt_lreserved);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ins = isp->isp_osinfo.nfreelist;
|
||||
if (ins == NULL) {
|
||||
isp_prt(isp, ISP_LOGERR, "out of TMD NOTIFY structs");
|
||||
isp_notify_ack(isp, mp->nt_lreserved);
|
||||
if (mp->nt_need_ack && mp->nt_lreserved) {
|
||||
isp_notify_ack(isp, mp->nt_lreserved);
|
||||
}
|
||||
break;
|
||||
}
|
||||
isp->isp_osinfo.nfreelist = ins->notify.nt_lreserved;
|
||||
@@ -3301,6 +3064,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
case NT_LINK_UP:
|
||||
case NT_LINK_DOWN:
|
||||
break;
|
||||
case NT_DEPARTED:
|
||||
case NT_ARRIVED:
|
||||
break;
|
||||
case NT_LUN_RESET:
|
||||
case NT_TARGET_RESET:
|
||||
/*
|
||||
@@ -3339,6 +3105,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
case NT_LINK_DOWN:
|
||||
ins->notify.nt_wwn = INI_NONE;
|
||||
break;
|
||||
case NT_DEPARTED:
|
||||
case NT_ARRIVED:
|
||||
break;
|
||||
default:
|
||||
if (isp_find_pdb_by_loopid(isp, mp->nt_channel, loopid, &lp) == 0) {
|
||||
isp_prt(isp, ISP_LOGTINFO, "cannot find WWN for loopid 0x%x for notify action 0x%x", loopid, mp->nt_ncode);
|
||||
@@ -4339,7 +4108,7 @@ isplinux_common_init(ispsoftc_t *isp)
|
||||
add_timer(&isp->isp_osinfo.timer);
|
||||
isp->dogactive = 1;
|
||||
|
||||
retval = isplinux_reinit(isp);
|
||||
retval = isplinux_reinit(isp, 1);
|
||||
|
||||
if (retval) {
|
||||
isp_prt(isp, ISP_LOGERR, "failed to init HBA port- skipping it");
|
||||
@@ -4360,11 +4129,11 @@ isplinux_common_init(ispsoftc_t *isp)
|
||||
}
|
||||
|
||||
int
|
||||
isplinux_reinit(ispsoftc_t *isp)
|
||||
isplinux_reinit(ispsoftc_t *isp, int doset_defaults)
|
||||
{
|
||||
int maxluns = isp_maxluns;
|
||||
|
||||
isp_reset(isp);
|
||||
isp_reset(isp, doset_defaults);
|
||||
|
||||
if (isp->isp_state != ISP_RESETSTATE) {
|
||||
isp_prt(isp, ISP_LOGERR, "failed to enter RESET state");
|
||||
@@ -4578,7 +4347,7 @@ isp_task_thread(void *arg)
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
break;
|
||||
}
|
||||
isp_reinit(isp);
|
||||
isp_reinit(isp, 0);
|
||||
if (isp->isp_state == ISP_RUNSTATE) {
|
||||
for (i = 0; i < isp->isp_nchan; i++) {
|
||||
ISP_DATA(isp, i)->blocked = 0;
|
||||
|
||||
@@ -635,7 +635,7 @@ int isplinux_common_init(ispsoftc_t *);
|
||||
void isplinux_init_proc(ispsoftc_t *);
|
||||
void isplinux_undo_proc(ispsoftc_t *);
|
||||
#endif
|
||||
int isplinux_reinit(ispsoftc_t *);
|
||||
int isplinux_reinit(ispsoftc_t *, int);
|
||||
void isplinux_sqd(struct Scsi_Host *, struct scsi_device *);
|
||||
|
||||
int isp_thread_event(ispsoftc_t *, int, void *, int, const char *, const int line);
|
||||
|
||||
@@ -70,8 +70,7 @@ 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);
|
||||
#endif
|
||||
#if !(defined(ISP_DISABLE_1020_SUPPORT) && defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT) && \
|
||||
defined(ISP_DISABLE_2100_SUPPORT) && defined(ISP_DISABLE_2200_SUPPORT))
|
||||
#if !(defined(ISP_DISABLE_1020_SUPPORT) && defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT) && defined(ISP_DISABLE_2100_SUPPORT) && defined(ISP_DISABLE_2200_SUPPORT))
|
||||
static int isp_pci_rd_isr(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
|
||||
#endif
|
||||
#if !(defined(ISP_DISABLE_2300_SUPPORT) && defined(ISP_DISABLE_2322_SUPPORT))
|
||||
|
||||
Reference in New Issue
Block a user