summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-08-14 05:42:46 +0000
committermjacob <mjacob@FreeBSD.org>2006-08-14 05:42:46 +0000
commit44c8c2fc9111b81fe22d4e0df84d975834fdfe66 (patch)
tree26d7cf9e2895a45725eaf6454af700161228d1c1 /sys/dev/isp
parent04e08ae813b583753760d5d13c6cf8974d42c62f (diff)
downloadFreeBSD-src-44c8c2fc9111b81fe22d4e0df84d975834fdfe66.zip
FreeBSD-src-44c8c2fc9111b81fe22d4e0df84d975834fdfe66.tar.gz
Fix 2KLOGIN code to specify *ibits* (not *obits*) so that the
options field in register 10 will be deterministic, not random. Correct the number of input bits for EXECUTE_FIRMWARE 0..1 to 0..2- the 2322 and 24XX cards use mailbox register 2 to specify whether the f/w being executed is freshly loaded or not. Correct the number of input bits for {READ,WRITE}_RAM_WORD_EXTENDED so that register 8 gets picked up. Fix the indexing and offset for the 2322 f/w download so that it correctly puts the different code segments where they belong. Move VERIFY_CHECKSUM to be the 'else' clause to 2322 f/w downloads- the EXECUTE_FIRMWARE command for 2322 and 24XX cards will tell you if the f/w checksum is incorrect and VERIFY_CHECKSUM only works for RISC SRAM address < 64K so you can only do a VERIFY_CHECKSUM on the first of the 3 f/w segments for the 2322. Shorten the delay for the continuation mailbox commands- 1ms is ridiculous (100us is more likely). All of the more or less is really only for the 2322/6322 cards.
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp.c137
1 files changed, 77 insertions, 60 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index c44d555..da13a73 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -160,7 +160,7 @@ void
isp_reset(ispsoftc_t *isp)
{
mbreg_t mbs;
- uint16_t code_org;
+ uint32_t code_org;
int loops, i, dodnld = 1;
char *btype = "????";
@@ -654,36 +654,27 @@ again:
}
/*
- * Verify that it downloaded correctly.
- */
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_VERIFY_CHECKSUM;
- mbs.param[1] = code_org;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
- return;
- }
-
- /*
- * If we're a 2322 or 2422, the firmware actually comes
- * in three chunks. We loaded the first at the code_org
- * address. The other two chunks, which follow right
- * after each other in memory here, get loaded at addresses
- * specfied at offset 0x9..0xB.
+ * If we're a 2322, the firmware actually comes in three chunks.
+ * We loaded the first at the code_org address. The other two
+ * chunks, which follow right after each other in memory here,
+ * get loaded at addresses specfied at offset 0x9..0xB.
*/
if (IS_2322(isp)) {
+ uint32_t nxtaddr;
+ uint32_t offset;
- ptr = &ptr[ptr[3]];
+ nxtaddr = ptr[3];
+ ptr = &ptr[nxtaddr];
+ offset = ptr[5] | (((uint32_t)(ptr[4] & 0xff)) << 16);
isp->isp_mbxworkp = &ptr[1];
- isp->isp_mbxwrk0 = ptr[3] - 1;
- isp->isp_mbxwrk1 = ptr[5] + 1;
- isp->isp_mbxwrk8 = ptr[4];
+ isp->isp_mbxwrk0 = ptr[3] + 1;
+ isp->isp_mbxwrk1 = offset + 1;
+ isp->isp_mbxwrk8 = (offset + 1) >> 16;
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
- mbs.param[1] = ptr[5];
+ mbs.param[1] = offset;
mbs.param[2] = ptr[0];
- mbs.param[8] = ptr[4];
+ mbs.param[8] = offset >> 16;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR,
@@ -691,24 +682,39 @@ again:
return;
}
- ptr = &ptr[ptr[3]];
+ nxtaddr = ptr[3];
+ ptr = &ptr[nxtaddr];
+ offset = ptr[5] | (((uint32_t)(ptr[4] & 0xff)) << 16);
isp->isp_mbxworkp = &ptr[1];
isp->isp_mbxwrk0 = ptr[3] - 1;
- isp->isp_mbxwrk1 = ptr[5] + 1;
- isp->isp_mbxwrk8 = ptr[4];
+ isp->isp_mbxwrk1 = (offset + 1);
+ isp->isp_mbxwrk8 = (offset + 1) >> 16;
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
- mbs.param[1] = ptr[5];
+ mbs.param[1] = offset;
mbs.param[2] = ptr[0];
- mbs.param[8] = ptr[4];
+ mbs.param[8] = offset >> 16;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR,
"Transmit Sequencer F/W Load Failed");
return;
}
- }
+ } else {
+ /*
+ * Verify that it downloaded correctly.
+ */
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_VERIFY_CHECKSUM;
+ mbs.param[1] = code_org;
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR,
+ "Downloaded RISC Code Checksum Failure");
+ return;
+ }
+ }
isp->isp_loaded_fw = 1;
} else {
isp->isp_loaded_fw = 0;
@@ -732,9 +738,15 @@ again:
} else {
mbs.param[2] = 1;
}
- mbs.obits |= 2;
}
isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ if (IS_2322(isp) || IS_24XX(isp)) {
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR, "EXEC F/W failed: 0x%x",
+ mbs.param[0]);
+ return;
+ }
+ }
/*
* Give it a chance to start.
@@ -1547,7 +1559,7 @@ isp_getpdb(ispsoftc_t *isp, int id, isp_pdb_t *pdbp)
mbs.param[0] = MBOX_GET_PORT_DB;
if (IS_2KLOGIN(isp)) {
mbs.param[1] = id;
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
} else {
mbs.param[1] = id << 8;
}
@@ -1577,7 +1589,7 @@ isp_get_portname(ispsoftc_t *isp, int loopid, int nodename)
mbs.param[0] = MBOX_GET_PORT_NAME;
if (IS_2KLOGIN(isp)) {
mbs.param[1] = loopid;
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
if (nodename) {
mbs.param[10] = 1;
}
@@ -2043,7 +2055,7 @@ isp_pdb_sync(ispsoftc_t *isp)
mbs.param[0] = MBOX_FABRIC_LOGOUT;
if (IS_2KLOGIN(isp)) {
mbs.param[1] = lp->loopid;
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
} else {
mbs.param[1] = lp->loopid << 8;
}
@@ -2069,7 +2081,7 @@ isp_pdb_sync(ispsoftc_t *isp)
mbs.param[0] = MBOX_FABRIC_LOGIN;
if (IS_2KLOGIN(isp)) {
mbs.param[1] = loopid;
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
} else {
mbs.param[1] = loopid << 8;
}
@@ -2195,7 +2207,7 @@ dump_em:
mbs.param[0] = MBOX_FABRIC_LOGOUT;
if (IS_2KLOGIN(isp)) {
mbs.param[1] = lp->loopid;
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
} else {
mbs.param[1] = lp->loopid << 8;
}
@@ -3488,7 +3500,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
} else {
if (IS_2KLOGIN(isp)) {
mbs.param[1] = tgt;
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
} else {
mbs.param[1] = (tgt << 8);
}
@@ -3583,7 +3595,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
if (IS_FC(isp)) {
mbs.param[0] = MBOX_INIT_LIP;
if (IS_2KLOGIN(isp)) {
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
}
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
@@ -4865,7 +4877,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs)
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_INIT_LIP;
if (IS_2KLOGIN(isp)) {
- mbs.obits |= (1 << 10);
+ mbs.ibits |= (1 << 10);
}
isp_mboxcmd_qnw(isp, &mbs, 1);
}
@@ -4946,6 +4958,7 @@ isp_mbox_continue(ispsoftc_t *isp)
{
mbreg_t mbs;
uint16_t *ptr;
+ uint32_t offset;
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
@@ -4974,33 +4987,37 @@ isp_mbox_continue(ispsoftc_t *isp)
ptr = isp->isp_mbxworkp;
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
- mbs.param[2] = *ptr++;
- mbs.param[1] = isp->isp_mbxwrk1++;
- break;
- case MBOX_WRITE_RAM_WORD_EXTENDED:
- mbs.param[2] = *ptr++;
- mbs.param[1] = isp->isp_mbxwrk1++;
- if (isp->isp_mbxwrk1 == 0) {
- isp->isp_mbxwrk8++;
- }
- mbs.param[8] = isp->isp_mbxwrk8;
+ mbs.param[1] = isp->isp_mbxwrk1++;;
+ mbs.param[2] = *ptr++;;
break;
case MBOX_READ_RAM_WORD:
*ptr++ = isp->isp_mboxtmp[2];
mbs.param[1] = isp->isp_mbxwrk1++;
break;
+ case MBOX_WRITE_RAM_WORD_EXTENDED:
+ offset = isp->isp_mbxwrk1;
+ offset |= ((uint32_t) isp->isp_mbxwrk8 << 16);
+
+ mbs.param[2] = *ptr++;;
+ mbs.param[1] = offset;
+ mbs.param[8] = offset >> 16;
+ isp->isp_mbxwrk1 = ++offset;
+ isp->isp_mbxwrk8 = offset >> 16;
+ break;
case MBOX_READ_RAM_WORD_EXTENDED:
+ offset = isp->isp_mbxwrk1;
+ offset |= ((uint32_t) isp->isp_mbxwrk8 << 16);
+
*ptr++ = isp->isp_mboxtmp[2];
- mbs.param[1] = isp->isp_mbxwrk1++;
- if (isp->isp_mbxwrk1 == 0) {
- isp->isp_mbxwrk8++;
- }
- mbs.param[8] = isp->isp_mbxwrk8;
+ mbs.param[1] = offset;
+ mbs.param[8] = offset >> 16;
+ isp->isp_mbxwrk1 = ++offset;
+ isp->isp_mbxwrk8 = offset >> 16;
break;
}
isp->isp_mbxworkp = ptr;
+ isp->isp_mbxwrk0--;
mbs.param[0] = isp->isp_lastmbxcmd;
- isp->isp_mbxwrk0 -= 1;
isp_mboxcmd_qnw(isp, &mbs, 0);
return (0);
}
@@ -5017,7 +5034,7 @@ static const uint32_t mbpscsi[] = {
ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
ISPOPMAP(0x3f, 0x3f), /* 0x06: MBOX_MAILBOX_REG_TEST */
- ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
+ ISPOPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
ISPOPMAP(0x01, 0x0f), /* 0x08: MBOX_ABOUT_FIRMWARE */
ISPOPMAP(0x00, 0x00), /* 0x09: */
ISPOPMAP(0x00, 0x00), /* 0x0a: */
@@ -5208,7 +5225,7 @@ static char *scsi_mbcmd_names[] = {
static const uint32_t mbpfc[] = {
ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
- ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
+ ISPOPMAP(0x07, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
ISPOPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */
ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
@@ -5219,9 +5236,9 @@ static const uint32_t mbpfc[] = {
ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
ISPOPMAP(0x00, 0x00), /* 0x0b: */
ISPOPMAP(0x00, 0x00), /* 0x0c: */
- ISPOPMAP(0x13, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED) */
+ ISPOPMAP(0x10f, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED) */
ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
- ISPOPMAP(0x13, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
+ ISPOPMAP(0x10f, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
@@ -5511,7 +5528,7 @@ isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
* command.
*/
if (nodelay) {
- USEC_DELAY(1000);
+ USEC_DELAY(100);
}
}
OpenPOWER on IntegriCloud