diff options
author | mav <mav@FreeBSD.org> | 2015-11-13 19:45:15 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-11-13 19:45:15 +0000 |
commit | 11a2cbd392eb50f8e99810766bca1c9fc74ee79b (patch) | |
tree | b86ddefc56bd155857eb117e85953c7a16a72ddc /sys | |
parent | 91c252f3d0bf80eb5f1511a357184a499b5e4b28 (diff) | |
download | FreeBSD-src-11a2cbd392eb50f8e99810766bca1c9fc74ee79b.zip FreeBSD-src-11a2cbd392eb50f8e99810766bca1c9fc74ee79b.tar.gz |
MFC r289838: Improve INOTs handling for 24xx and above chips.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 106 | ||||
-rw-r--r-- | sys/dev/isp/isp_library.c | 60 | ||||
-rw-r--r-- | sys/dev/isp/isp_library.h | 2 | ||||
-rw-r--r-- | sys/dev/isp/isp_target.c | 1 | ||||
-rw-r--r-- | sys/dev/isp/ispmbox.h | 8 |
5 files changed, 87 insertions, 90 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 85ac00f..2b60419 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -2480,12 +2480,13 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) else { if ((isp_find_pdb_by_handle(isp, 0, nphdl, &lp) == 0 || lp->state == FC_PORTDB_STATE_ZOMBIE)) { - uint64_t iid = + uint64_t wwpn = (((uint64_t) aep->at_wwpn[0]) << 48) | (((uint64_t) aep->at_wwpn[1]) << 32) | (((uint64_t) aep->at_wwpn[2]) << 16) | (((uint64_t) aep->at_wwpn[3]) << 0); - isp_add_wwn_entry(isp, 0, iid, nphdl, PORT_ANY, 0); + isp_add_wwn_entry(isp, 0, wwpn, INI_NONE, + nphdl, PORT_ANY, 0); isp_find_pdb_by_handle(isp, 0, nphdl, &lp); } atiop->init_id = FC_PORTDB_TGT(isp, 0, lp); @@ -3195,8 +3196,9 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) uint16_t prli_options = 0; uint32_t portid; fcportdb_t *lp; - uint8_t *ptr = NULL; - uint64_t wwn; + char *msg = NULL; + uint8_t *ptr = (uint8_t *)inot; + uint64_t wwpn = INI_NONE, wwnn = INI_NONE; nphdl = inot->in_nphdl; if (nphdl != NIL_HANDLE) { @@ -3208,7 +3210,7 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) switch (inot->in_status) { case IN24XX_ELS_RCVD: { - char buf[16], *msg; + char buf[16]; int chan = ISP_GET_VPIDX(isp, inot->in_vpidx); /* @@ -3219,49 +3221,27 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) switch (inot->in_status_subcode) { case LOGO: msg = "LOGO"; - if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { - ptr = (uint8_t *)inot; /* point to unswizzled entry! */ - wwn = (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF]) << 56) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+1]) << 48) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+2]) << 40) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+3]) << 32) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+4]) << 24) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+5]) << 16) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+6]) << 8) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+7])); - } else { - wwn = INI_ANY; - } - isp_del_wwn_entry(isp, chan, wwn, nphdl, portid); + wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]); + isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid); break; case PRLO: msg = "PRLO"; break; case PLOGI: + msg = "PLOGI"; + wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]); + wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]); + isp_add_wwn_entry(isp, chan, wwpn, wwnn, + nphdl, portid, prli_options); + break; case PRLI: - /* - * Treat PRLI the same as PLOGI and make a database entry for it. - */ - if (inot->in_status_subcode == PLOGI) { - msg = "PLOGI"; - } else { - prli_options = inot->in_prli_options; - msg = "PRLI"; - } - if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { - ptr = (uint8_t *)inot; /* point to unswizzled entry! */ - wwn = (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF]) << 56) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+1]) << 48) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+2]) << 40) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+3]) << 32) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+4]) << 24) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+5]) << 16) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+6]) << 8) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+7])); - } else { - wwn = INI_NONE; - } - isp_add_wwn_entry(isp, chan, wwn, nphdl, portid, prli_options); + msg = "PRLI"; + prli_options = inot->in_prli_options; + if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID) + wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]); + wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]); + isp_add_wwn_entry(isp, chan, wwpn, wwnn, + nphdl, portid, prli_options); break; case PDISC: msg = "PDISC"; @@ -3285,21 +3265,19 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) } case IN24XX_PORT_LOGOUT: - ptr = "PORT LOGOUT"; + msg = "PORT LOGOUT"; if (isp_find_pdb_by_handle(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) { isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid); } /* FALLTHROUGH */ case IN24XX_PORT_CHANGED: - if (ptr == NULL) { - ptr = "PORT CHANGED"; - } + if (msg == NULL) + msg = "PORT CHANGED"; /* FALLTHROUGH */ - case IN24XX_LIP_RESET: - if (ptr == NULL) { - ptr = "LIP RESET"; - } - isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr, inot->in_status_subcode, nphdl); + case IN24XX_LIP_RESET: + if (msg == NULL) + msg = "LIP RESET"; + isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), msg, inot->in_status_subcode, nphdl); /* * All subcodes here are irrelevant. What is relevant @@ -3315,21 +3293,18 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) isp_handle_srr_notify(isp, inot); break; #else - if (ptr == NULL) { - ptr = "SRR RCVD"; - } + if (msg == NULL) + msg = "SRR RCVD"; /* FALLTHROUGH */ #endif case IN24XX_LINK_RESET: - if (ptr == NULL) { - ptr = "LINK RESET"; - } + if (msg == NULL) + msg = "LINK RESET"; case IN24XX_LINK_FAILED: - if (ptr == NULL) { - ptr = "LINK FAILED"; - } + if (msg == NULL) + msg = "LINK FAILED"; default: - isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr); + isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), msg); isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); break; } @@ -5704,20 +5679,17 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; } case ISPASYNC_LIP: - if (msg == NULL) { + if (msg == NULL) msg = "LIP Received"; - } /* FALLTHROUGH */ case ISPASYNC_LOOP_RESET: - if (msg == NULL) { + if (msg == NULL) msg = "LOOP Reset"; - } /* FALLTHROUGH */ case ISPASYNC_LOOP_DOWN: { - if (msg == NULL) { + if (msg == NULL) msg = "LOOP Down"; - } va_start(ap, cmd); bus = va_arg(ap, int); va_end(ap); diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index f7ee7bb..8d031b1 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -2421,7 +2421,8 @@ isp_find_chan_by_did(ispsoftc_t *isp, uint32_t did, uint16_t *cp) * Add an initiator device to the port database */ void -isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint32_t s_id, uint16_t prli_params) +isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t wwpn, uint64_t wwnn, + uint16_t nphdl, uint32_t s_id, uint16_t prli_params) { char buf[64]; fcparam *fcp; @@ -2432,7 +2433,7 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 if (nphdl >= MAX_NPORT_HANDLE) { isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN, "Chan %d WWPN 0x%016llx " "PortID 0x%06x handle 0x%x -- bad handle", - chan, (unsigned long long) ini, s_id, nphdl); + chan, (unsigned long long) wwpn, s_id, nphdl); return; } @@ -2441,7 +2442,7 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 * with new parameters. Some cases of update can be suspicious, * so log them verbosely and dump the whole port database. */ - if ((VALID_INI(ini) && isp_find_pdb_by_wwn(isp, chan, ini, &lp)) || + if ((VALID_INI(wwpn) && isp_find_pdb_by_wwn(isp, chan, wwpn, &lp)) || (s_id != PORT_NONE && isp_find_pdb_by_sid(isp, chan, s_id, &lp))) { change = 0; lp->new_portid = lp->portid; @@ -2465,24 +2466,42 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 lp->new_portid = s_id; change++; } - if (VALID_INI(ini) && lp->port_wwn != ini) { + if (VALID_INI(wwpn) && lp->port_wwn != wwpn) { if (!VALID_INI(lp->port_wwn)) { isp_prt(isp, ISP_LOGTINFO, "Chan %d PortID 0x%06x handle 0x%x " - "gets WWN 0x%016llxx", + "gets WWPN 0x%016llxx", chan, lp->portid, nphdl, - (unsigned long long) ini); - } else if (lp->port_wwn != ini) { + (unsigned long long) wwpn); + } else if (lp->port_wwn != wwpn) { isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN, "Chan %d PortID 0x%06x handle 0x%x " - "changes WWN 0x%016llx to 0x%016llx", + "changes WWPN 0x%016llx to 0x%016llx", chan, lp->portid, nphdl, (unsigned long long) lp->port_wwn, - (unsigned long long) ini); + (unsigned long long) wwpn); if (isp->isp_dblev & (ISP_LOGTINFO|ISP_LOGWARN)) isp_dump_portdb(isp, chan); } - lp->port_wwn = ini; + lp->port_wwn = wwpn; + change++; + } + if (VALID_INI(wwnn) && lp->node_wwn != wwnn) { + if (!VALID_INI(lp->node_wwn)) { + isp_prt(isp, ISP_LOGTINFO, + "Chan %d PortID 0x%06x handle 0x%x " + "gets WWNN 0x%016llxx", + chan, lp->portid, nphdl, + (unsigned long long) wwnn); + } else if (lp->port_wwn != wwnn) { + isp_prt(isp, ISP_LOGTINFO, + "Chan %d PortID 0x%06x handle 0x%x " + "changes WWNN 0x%016llx to 0x%016llx", + chan, lp->portid, nphdl, + (unsigned long long) lp->node_wwn, + (unsigned long long) wwnn); + } + lp->node_wwn = wwnn; change++; } if (prli_params != 0 && lp->prli_word3 != prli_params) { @@ -2531,7 +2550,7 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 isp_prt(isp, ISP_LOGTINFO|ISP_LOGWARN, "Chan %d WWPN 0x%016llx PortID 0x%06x handle 0x%x " "-- no room in port database", - chan, (unsigned long long) ini, s_id, nphdl); + chan, (unsigned long long) wwpn, s_id, nphdl); if (isp->isp_dblev & (ISP_LOGTINFO|ISP_LOGWARN)) isp_dump_portdb(isp, chan); return; @@ -2542,14 +2561,15 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 ISP_MEMZERO(lp, sizeof (fcportdb_t)); lp->handle = nphdl; lp->portid = s_id; - lp->port_wwn = ini; + lp->port_wwn = wwpn; + lp->node_wwn = wwnn; lp->prli_word3 = (prli_params != 0) ? prli_params : PRLI_WD3_INITIATOR_FUNCTION; lp->state = FC_PORTDB_STATE_VALID; isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); isp_prt(isp, ISP_LOGTINFO, "Chan %d WWPN 0x%016llx " "PortID 0x%06x handle 0x%x vtgt %d %s added", chan, - (unsigned long long) ini, s_id, nphdl, i, buf); + (unsigned long long) wwpn, s_id, nphdl, i, buf); /* Notify above levels about new port arrival. */ isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp); @@ -2559,21 +2579,21 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 * Remove a target device to the port database */ void -isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint32_t s_id) +isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t wwpn, uint16_t nphdl, uint32_t s_id) { fcparam *fcp; fcportdb_t *lp; if (nphdl >= MAX_NPORT_HANDLE) { isp_prt(isp, ISP_LOGWARN, "Chan %d WWPN 0x%016llx PortID 0x%06x bad handle 0x%x", - chan, (unsigned long long) ini, s_id, nphdl); + chan, (unsigned long long) wwpn, s_id, nphdl); return; } fcp = FCPARAM(isp, chan); if (isp_find_pdb_by_handle(isp, chan, nphdl, &lp) == 0) { isp_prt(isp, ISP_LOGWARN, "Chan %d WWPN 0x%016llx PortID 0x%06x handle 0x%x cannot be found to be deleted", - chan, (unsigned long long) ini, s_id, nphdl); + chan, (unsigned long long) wwpn, s_id, nphdl); isp_dump_portdb(isp, chan); return; } @@ -3468,7 +3488,7 @@ isp_put_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src, in_fcentry_24xx_t * ISP_IOXPUT_16(isp, src->in_srr_rxid, &dst->in_srr_rxid); ISP_IOXPUT_16(isp, src->in_status, &dst->in_status); ISP_IOXPUT_8(isp, src->in_status_subcode, &dst->in_status_subcode); - ISP_IOXPUT_16(isp, src->in_reserved2, &dst->in_reserved2); + ISP_IOXPUT_8(isp, src->in_fwhandle, &dst->in_fwhandle); ISP_IOXPUT_32(isp, src->in_rxid, &dst->in_rxid); ISP_IOXPUT_16(isp, src->in_srr_reloff_hi, &dst->in_srr_reloff_hi); ISP_IOXPUT_16(isp, src->in_srr_reloff_lo, &dst->in_srr_reloff_lo); @@ -3531,7 +3551,7 @@ isp_get_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src, in_fcentry_24xx_t * ISP_IOXGET_16(isp, &src->in_srr_rxid, dst->in_srr_rxid); ISP_IOXGET_16(isp, &src->in_status, dst->in_status); ISP_IOXGET_8(isp, &src->in_status_subcode, dst->in_status_subcode); - ISP_IOXGET_16(isp, &src->in_reserved2, dst->in_reserved2); + ISP_IOXGET_8(isp, &src->in_fwhandle, dst->in_fwhandle); ISP_IOXGET_32(isp, &src->in_rxid, dst->in_rxid); ISP_IOXGET_16(isp, &src->in_srr_reloff_hi, dst->in_srr_reloff_hi); ISP_IOXGET_16(isp, &src->in_srr_reloff_lo, dst->in_srr_reloff_lo); @@ -3650,7 +3670,7 @@ isp_put_notify_24xx_ack(ispsoftc_t *isp, na_fcentry_24xx_t *src, na_fcentry_24xx ISP_IOXPUT_16(isp, src->na_srr_rxid, &dst->na_srr_rxid); ISP_IOXPUT_16(isp, src->na_status, &dst->na_status); ISP_IOXPUT_8(isp, src->na_status_subcode, &dst->na_status_subcode); - ISP_IOXPUT_16(isp, src->na_reserved2, &dst->na_reserved2); + ISP_IOXPUT_8(isp, src->na_fwhandle, &dst->na_fwhandle); ISP_IOXPUT_32(isp, src->na_rxid, &dst->na_rxid); ISP_IOXPUT_16(isp, src->na_srr_reloff_hi, &dst->na_srr_reloff_hi); ISP_IOXPUT_16(isp, src->na_srr_reloff_lo, &dst->na_srr_reloff_lo); @@ -3721,7 +3741,7 @@ isp_get_notify_ack_24xx(ispsoftc_t *isp, na_fcentry_24xx_t *src, na_fcentry_24xx ISP_IOXGET_16(isp, &src->na_srr_rxid, dst->na_srr_rxid); ISP_IOXGET_16(isp, &src->na_status, dst->na_status); ISP_IOXGET_8(isp, &src->na_status_subcode, dst->na_status_subcode); - ISP_IOXGET_16(isp, &src->na_reserved2, dst->na_reserved2); + ISP_IOXGET_8(isp, &src->na_fwhandle, dst->na_fwhandle); ISP_IOXGET_32(isp, &src->na_rxid, dst->na_rxid); ISP_IOXGET_16(isp, &src->na_srr_reloff_hi, dst->na_srr_reloff_hi); ISP_IOXGET_16(isp, &src->na_srr_reloff_lo, dst->na_srr_reloff_lo); diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h index cc0cfaa..8ff4b70 100644 --- a/sys/dev/isp/isp_library.h +++ b/sys/dev/isp/isp_library.h @@ -171,7 +171,7 @@ int isp_find_pdb_by_wwn(ispsoftc_t *, int, uint64_t, fcportdb_t **); int isp_find_pdb_by_handle(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, uint16_t); +void isp_add_wwn_entry(ispsoftc_t *, int, uint64_t, uint64_t, uint16_t, uint32_t, uint16_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 *); diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c index 7e4c600..629bac8 100644 --- a/sys/dev/isp/isp_target.c +++ b/sys/dev/isp/isp_target.c @@ -1085,6 +1085,7 @@ isp_notify_ack(ispsoftc_t *isp, void *arg) na->na_flags = in->in_flags; na->na_status = in->in_status; na->na_status_subcode = in->in_status_subcode; + na->na_fwhandle = in->in_fwhandle; na->na_rxid = in->in_rxid; na->na_oxid = in->in_oxid; na->na_vpidx = in->in_vpidx; diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index ee67781..86b4987 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -1812,7 +1812,7 @@ typedef struct { uint16_t in_srr_rxid; uint16_t in_status; uint8_t in_status_subcode; - uint8_t in_reserved2; + uint8_t in_fwhandle; uint32_t in_rxid; uint16_t in_srr_reloff_lo; uint16_t in_srr_reloff_hi; @@ -1845,6 +1845,8 @@ typedef struct { #define IN24XX_FLAG_PUREX_IOCB 0x1 #define IN24XX_FLAG_GLOBAL_LOGOUT 0x2 #define IN24XX_FLAG_NPHDL_VALID 0x4 +#define IN24XX_FLAG_N2N_PRLI 0x8 +#define IN24XX_FLAG_PN_NN_VALID 0x10 #define IN24XX_LIP_RESET 0x0E #define IN24XX_LINK_RESET 0x0F @@ -1862,6 +1864,8 @@ typedef struct { * the WWNN/WWPN if the ELS is PLOGI, PDISC or ADISC. The WWN is in * Big Endian format. */ +#define IN24XX_PRLI_WWNN_OFF 0x18 +#define IN24XX_PRLI_WWPN_OFF 0x28 #define IN24XX_PLOGI_WWNN_OFF 0x20 #define IN24XX_PLOGI_WWPN_OFF 0x28 @@ -1965,7 +1969,7 @@ typedef struct { uint16_t na_srr_rxid; uint16_t na_status; uint8_t na_status_subcode; - uint8_t na_reserved2; + uint8_t na_fwhandle; uint32_t na_rxid; uint16_t na_srr_reloff_lo; uint16_t na_srr_reloff_hi; |