diff --git a/qla_isp/common/isp.c b/qla_isp/common/isp.c index b1d45df2f..9e173b2d3 100644 --- a/qla_isp/common/isp.c +++ b/qla_isp/common/isp.c @@ -1,4 +1,4 @@ -/* $Id: isp.c,v 1.181 2007/12/02 22:02:04 mjacob Exp $ */ +/* $Id: isp.c,v 1.182 2007/12/04 22:18:16 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -5711,13 +5711,23 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) break; case ASYNC_CHANGE_NOTIFY: + { + int lochan, hichan; if (IS_SCSI(isp)) { isp_prt(isp, ISP_LOGWARN, "bad CHANGE NOTIFY event for SCSI cards"); break; } - for (chan = 0; chan < isp->isp_nchan; chan++) { + if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) { + GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY"); + lochan = chan; + hichan = chan + 1; + } else { + lochan = 0; + hichan = isp->isp_nchan; + } + for (chan = lochan; chan < hichan; chan++) { fcparam *fcp = FCPARAM(isp, chan); if (fcp->role == ISP_ROLE_NONE) { @@ -5734,6 +5744,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) ISPASYNC_CHANGE_SNS); } break; + } case ASYNC_CONNMODE: /* diff --git a/qla_isp/common/isp_library.c b/qla_isp/common/isp_library.c index f0edafef1..90de9f374 100644 --- a/qla_isp/common/isp_library.c +++ b/qla_isp/common/isp_library.c @@ -1,4 +1,4 @@ -/* $Id: isp_library.c,v 1.47 2007/12/02 22:02:04 mjacob Exp $ */ +/* $Id: isp_library.c,v 1.48 2007/12/04 22:19:21 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -2690,16 +2690,20 @@ isp_put_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src, ISP_IOXPUT_16(isp, src->in_srr_reloff_lo, &dst->in_srr_reloff_lo); ISP_IOXPUT_16(isp, src->in_srr_iu, &dst->in_srr_iu); ISP_IOXPUT_16(isp, src->in_srr_oxid, &dst->in_srr_oxid); - for (i = 0; i < 18; i++) { - ISP_IOXPUT_8(isp, src->in_reserved3[i], &dst->in_reserved3[i]); + ISP_IOXPUT_16(isp, src->in_nport_id_hi, &dst->in_nport_id_hi); + ISP_IOXPUT_8(isp, src->in_nport_id_lo, &dst->in_nport_id_lo); + ISP_IOXPUT_8(isp, src->in_reserved3, &dst->in_reserved3); + ISP_IOXPUT_16(isp, src->in_np_handle, &dst->in_np_handle); + for (i = 0; i < ASIZE(src->in_reserved4); i++) { + ISP_IOXPUT_8(isp, src->in_reserved4[i], &dst->in_reserved4[i]); } - ISP_IOXPUT_8(isp, src->in_reserved4, &dst->in_reserved4); + ISP_IOXPUT_8(isp, src->in_reserved5, &dst->in_reserved5); ISP_IOXPUT_8(isp, src->in_vpindex, &dst->in_vpindex); - ISP_IOXPUT_32(isp, src->in_reserved5, &dst->in_reserved5); + ISP_IOXPUT_32(isp, src->in_reserved6, &dst->in_reserved6); ISP_IOXPUT_16(isp, src->in_portid_lo, &dst->in_portid_lo); ISP_IOXPUT_8(isp, src->in_portid_hi, &dst->in_portid_hi); - ISP_IOXPUT_8(isp, src->in_reserved6, &dst->in_reserved6); - ISP_IOXPUT_16(isp, src->in_reserved7, &dst->in_reserved7); + ISP_IOXPUT_8(isp, src->in_reserved7, &dst->in_reserved7); + ISP_IOXPUT_16(isp, src->in_reserved8, &dst->in_reserved8); ISP_IOXPUT_16(isp, src->in_oxid, &dst->in_oxid); } @@ -2752,16 +2756,20 @@ isp_get_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src, ISP_IOXGET_16(isp, &src->in_srr_reloff_lo, dst->in_srr_reloff_lo); ISP_IOXGET_16(isp, &src->in_srr_iu, dst->in_srr_iu); ISP_IOXGET_16(isp, &src->in_srr_oxid, dst->in_srr_oxid); - for (i = 0; i < 18; i++) { - ISP_IOXGET_8(isp, &src->in_reserved3[i], dst->in_reserved3[i]); + ISP_IOXGET_16(isp, &src->in_nport_id_hi, dst->in_nport_id_hi); + ISP_IOXGET_8(isp, &src->in_nport_id_lo, dst->in_nport_id_lo); + ISP_IOXGET_8(isp, &src->in_reserved3, dst->in_reserved3); + ISP_IOXGET_16(isp, &src->in_np_handle, dst->in_np_handle); + for (i = 0; i < ASIZE(src->in_reserved4); i++) { + ISP_IOXGET_8(isp, &src->in_reserved4[i], dst->in_reserved4[i]); } - ISP_IOXGET_8(isp, &src->in_reserved4, dst->in_reserved4); + ISP_IOXGET_8(isp, &src->in_reserved5, dst->in_reserved5); ISP_IOXGET_8(isp, &src->in_vpindex, dst->in_vpindex); - ISP_IOXGET_32(isp, &src->in_reserved5, dst->in_reserved5); + ISP_IOXGET_32(isp, &src->in_reserved6, dst->in_reserved6); ISP_IOXGET_16(isp, &src->in_portid_lo, dst->in_portid_lo); ISP_IOXGET_8(isp, &src->in_portid_hi, dst->in_portid_hi); - ISP_IOXGET_8(isp, &src->in_reserved6, dst->in_reserved6); - ISP_IOXGET_16(isp, &src->in_reserved7, dst->in_reserved7); + ISP_IOXGET_8(isp, &src->in_reserved7, dst->in_reserved7); + ISP_IOXGET_16(isp, &src->in_reserved8, dst->in_reserved8); ISP_IOXGET_16(isp, &src->in_oxid, dst->in_oxid); } diff --git a/qla_isp/common/isp_target.h b/qla_isp/common/isp_target.h index 3a78a9380..d475015ac 100644 --- a/qla_isp/common/isp_target.h +++ b/qla_isp/common/isp_target.h @@ -1,4 +1,4 @@ -/* $Id: isp_target.h,v 1.56 2007/12/02 22:02:04 mjacob Exp $ */ +/* $Id: isp_target.h,v 1.57 2007/12/04 22:19:15 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -196,19 +196,40 @@ typedef struct { uint16_t in_srr_reloff_hi; uint16_t in_srr_iu; uint16_t in_srr_oxid; - uint8_t in_reserved3[18]; - uint8_t in_reserved4; + /* + * If bit 2 is set in in_flags, the following + * two tags are valid. If the received ELS is + * a LOGO, then these tags contain the N Port ID + * from the LOGO payload. If the received ELS + * request is TPRLO, these tags contain the + * Third Party Originator N Port ID. + */ + uint16_t in_nport_id_hi; + uint8_t in_nport_id_lo; + uint8_t in_reserved3; + /* + * If bit 2 is set in in_flags, the following + * tag is valid. If the received ELS is a LOGO, + * then this tag contains the n-port handle + * from the LOGO payload. If the received ELS + * request is TPRLO, this tag contain the + * n-port handle for the Third Party Originator. + */ + uint16_t in_np_handle; + uint8_t in_reserved4[12]; + uint8_t in_reserved5; uint8_t in_vpindex; - uint32_t in_reserved5; + uint32_t in_reserved6; uint16_t in_portid_lo; uint8_t in_portid_hi; - uint8_t in_reserved6; - uint16_t in_reserved7; + uint8_t in_reserved7; + uint16_t in_reserved8; uint16_t in_oxid; } in_fcentry_24xx_t; #define IN24XX_FLAG_PUREX_IOCB 0x1 #define IN24XX_FLAG_GLOBAL_LOGOUT 0x2 +#define IN24XX_FLAG_NPHDL_VALID 0x4 #define IN24XX_LIP_RESET 0x0E #define IN24XX_LINK_RESET 0x0F @@ -220,6 +241,21 @@ typedef struct { * login-affectin ELS received- check * subcode for specific opcode */ + +/* + * For f/w > 4.0.25, these offsets in the Immediate Notify contain + * the WWNN/WWPN if the ELS is PLOGI, PDISC or ADISC. The WWN is in + * Big Endian format. + */ +#define IN24XX_PLOGI_WWNN_OFF 0x20 +#define IN24XX_PLOGI_WWPN_OFF 0x28 + +/* + * For f/w > 4.0.25, this offset in the Immediate Notify contain + * the WWPN if the ELS is LOGO. The WWN is in Big Endian format. + */ +#define IN24XX_LOGO_WWPN_OFF 0x28 + /* * Notify Acknowledge Entry structure */ diff --git a/qla_isp/linux/isp_linux.c b/qla_isp/linux/isp_linux.c index fccc81e6a..6ebd5e7f7 100644 --- a/qla_isp/linux/isp_linux.c +++ b/qla_isp/linux/isp_linux.c @@ -1,4 +1,4 @@ -/* $Id: isp_linux.c,v 1.210 2007/12/03 04:31:52 mjacob Exp $ */ +/* $Id: isp_linux.c,v 1.211 2007/12/04 22:20:44 mjacob Exp $ */ /* * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -3413,6 +3413,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; } else if (IS_24XX(isp)) { in_fcentry_24xx_t *inot = qe; + uint64_t wwn; nphdl = inot->in_nphdl; if (nphdl != NIL_HANDLE) { @@ -3432,14 +3433,42 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) switch (inot->in_status_subcode) { case LOGO: msg = "LOGO"; - isp_del_wwn_entry(isp, inot->in_vpindex, INI_ANY, nphdl, portid); + if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { + uint8_t *ptr = qe; /* 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, inot->in_vpindex, wwn, nphdl, portid); break; case PRLO: msg = "PRLO"; break; case PLOGI: msg = "PLOGI"; - isp_add_wwn_entry(isp, inot->in_vpindex, INI_NONE, nphdl, portid); + if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { + uint8_t *ptr = qe; /* 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, inot->in_vpindex, wwn, nphdl, portid); break; case PRLI: msg = "PRLI";