diff options
author | mjacob <mjacob@FreeBSD.org> | 2001-02-23 05:35:50 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2001-02-23 05:35:50 +0000 |
commit | 2b7de3529ca70b7e4a27431edb43ea93b2118123 (patch) | |
tree | 4df3d0641119ffd783bc763d20af960168c2f1fb /sys | |
parent | 63ed3e92a93db5d5076a050b2288f3503183e68c (diff) | |
download | FreeBSD-src-2b7de3529ca70b7e4a27431edb43ea93b2118123.zip FreeBSD-src-2b7de3529ca70b7e4a27431edb43ea93b2118123.tar.gz |
Fix a longstanding bug- we had the sense of what bit 14
for the ICB firmware options meant- *I* had taken it to
mean that if you set it, Node Name would be ignored and
derived from Port Name. Actually, it meant the opposite.
As a consequence- change ICBOPT_USE_PORTNAME to the
define ICBOPT_BOTH_WWNS- makes more sense.
Fix wrong input bitmap for MBOX_DUMP_RAM command. Call
ISP_DUMPREGS if we get a f/w crash. Add ISPCTL_RUN_MBOXCMD
control command (so outer layers can run a mailbox command
directly) and add a ISPASYNC_UNHANDLED_RESPONSE hook so
outer layers can understand response queue entries we
might not know about.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/isp/isp.c | 27 | ||||
-rw-r--r-- | sys/dev/isp/ispmbox.h | 2 | ||||
-rw-r--r-- | sys/dev/isp/ispvar.h | 10 |
3 files changed, 27 insertions, 12 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 201997c..6b14f12 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -1076,11 +1076,6 @@ isp_fibre_init(isp) */ fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE; - /* - * We don't set ICBOPT_PORTNAME because we want our - * Node Name && Port Names to be distinct. - */ - /* * Make sure that target role reflects into fwoptions. @@ -1148,6 +1143,7 @@ isp_fibre_init(isp) nwwn = ISP_NODEWWN(isp); pwwn = ISP_PORTWWN(isp); if (nwwn && pwwn) { + icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS; MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn); MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); isp_prt(isp, ISP_LOGDEBUG1, @@ -1158,7 +1154,7 @@ isp_fibre_init(isp) ((u_int32_t) (pwwn & 0xffffffff))); } else { isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs"); - fcp->isp_fwoptions &= ~(ICBOPT_USE_PORTNAME|ICBOPT_FULL_LOGIN); + icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN); } icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); @@ -2734,6 +2730,11 @@ isp_control(isp, ctl, arg) } break; + case ISPCTL_RUN_MBOXCMD: + + isp_mboxcmd(isp, arg, MBLOGALL); + return(0); + #ifdef ISP_TARGET_MODE case ISPCTL_TOGGLE_TMODE: { @@ -2990,7 +2991,9 @@ isp_intr(arg) if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) { MEMZERO(sp, sizeof (isphdr_t)); isp_prt(isp, ISP_LOGERR, - "bad request handle %d", sp->req_handle); + "bad request handle %d (type 0x%x, flags 0x%x)", + sp->req_handle, sp->req_header.rqs_entry_type, + sp->req_header.rqs_flags); ISP_WRITE(isp, INMAILBOX5, optr); continue; } @@ -3085,7 +3088,7 @@ isp_intr(arg) break; default: isp_prt(isp, ISP_LOGWARN, - "unhandled respose queue type 0x%x", + "unhandled response queue type 0x%x", sp->req_header.rqs_entry_type); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_BOTCH); @@ -3178,7 +3181,8 @@ isp_parse_async(isp, mbox) case ASYNC_SYSTEM_ERROR: mbox = ISP_READ(isp, OUTMAILBOX1); isp_prt(isp, ISP_LOGERR, - "Internal FW Error @ RISC Addr 0x%x", mbox); + "Internal Firmware Error @ RISC Addr 0x%x", mbox); + ISP_DUMPREGS(isp, "Firmware Error"); isp_reinit(isp); #ifdef ISP_TARGET_MODE isp_target_async(isp, bus, ASYNC_SYSTEM_ERROR); @@ -3452,6 +3456,9 @@ isp_handle_other_response(isp, sp, optrp) #endif case RQSTYPE_REQUEST: default: + if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, sp)) { + return (0); + } isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x", sp->req_header.rqs_entry_type); return (-1); @@ -4030,7 +4037,7 @@ static u_int16_t mbpfc[] = { ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */ - ISPOPMAP(0x1f, 0x01), /* 0x03: MBOX_DUMP_RAM */ + ISPOPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */ ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */ ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */ ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */ diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index bf0fc35..ce2fe06 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -537,7 +537,7 @@ typedef struct isp_icb { #define ICBOPT_PREVLOOP 0x0800 #define ICBOPT_STOP_ON_QFULL 0x1000 #define ICBOPT_FULL_LOGIN 0x2000 -#define ICBOPT_USE_PORTNAME 0x4000 +#define ICBOPT_BOTH_WWNS 0x4000 #define ICBOPT_EXTENDED 0x8000 #define ICBXOPT_CLASS2_ACK0 0x0200 diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 39f0f58..de9b3fa 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -576,6 +576,7 @@ typedef enum { ISPCTL_PDB_SYNC, /* Synchronize Port Database */ ISPCTL_SEND_LIP, /* Send a LIP */ ISPCTL_GET_POSMAP, /* Get FC-AL position map */ + ISPCTL_RUN_MBOXCMD, /* run a mailbox command */ ISPCTL_TOGGLE_TMODE /* toggle target mode */ } ispctl_t; int isp_control __P((struct ispsoftc *, ispctl_t, void *)); @@ -614,6 +615,12 @@ int isp_control __P((struct ispsoftc *, ispctl_t, void *)); * valid tag is set or not says whether something has arrived or departed. * The name refers to a favorite pastime of many city dwellers- watching * people come and go, talking of Michaelangelo, and so on.. + * + * ISPASYNC_UNHANDLED_RESPONSE gives outer layers a chance to parse a + * response queue entry not otherwise handled. The outer layer should + * return non-zero if it handled it. The 'arg' points to a (possibly only + * partially) massaged response queue entry (see the platform's + * ISP_UNSWIZZLE_RESPONSE macro). */ typedef enum { @@ -627,7 +634,8 @@ typedef enum { ISPASYNC_TARGET_MESSAGE, /* target message */ ISPASYNC_TARGET_EVENT, /* target asynchronous event */ ISPASYNC_TARGET_ACTION, /* other target command action */ - ISPASYNC_CONF_CHANGE /* Platform Configuration Change */ + ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */ + ISPASYNC_UNHANDLED_RESPONSE /* Unhandled Response Entry */ } ispasync_t; int isp_async __P((struct ispsoftc *, ispasync_t, void *)); |