From 891c7d5b03f6a7979e96cbdfc5b84af7414b5209 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 20 Jul 2010 17:51:19 +0000 Subject: [PATCH] Fix BUG while enabling target mode remote port disappear: In case if ELS LOGO command received on the target port, the firmware can notify the driver about it in 3 different ways, which handled differently by the driver (it doesn't clear when it use each way): 1. Immediate notify of login-affecting ELS command received (status code 0x46). The target driver terminate all commands received for the specified initiator (N_Port handle). 2. Asynchroneus event of port update. The target driver only print message, and in remark it's written that /* .mark_all_devices_lost() is handled by the initiator driver */ 3. Immediate notify of port logged out (status code 0x29). The target driver terminate all commands received for the specified initiator (N_Port handle), and also mark all devices as lost. In 1 and 2 everthing is OK. In 3 the target driver mark all devices as lost, but never retrigger rescanning. There are 2 solutions: 1. Not marking the devices as lost base on written in the async event case, and also base on the spec which says to only terminate all commands. 2. Mark all devices as lost and retrigger rescanning. 1 was implemented; delete all calls to mark_all_devices_lost() in qla2x00t.c, and unexport symbol of this function in qla_os.c Signed-off-by: Gal Rosen git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1844 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t/qla2x00-target/qla2x00t.c | 34 +++++++++++++++++++++--------- qla2x00t/qla_os.c | 1 - 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index bf7dfb744..dc05456a3 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -440,8 +440,14 @@ static int q2t_reset(scsi_qla_host_t *ha, void *iocb, int mcmd) goto out; } - TRACE_MGMT_DBG("scsi(%ld): resetting (session %p, " - "mcmd %x, loop_id %d)", ha->host_no, sess, mcmd, loop_id); + TRACE_MGMT_DBG("scsi(%ld): resetting (session %p from port " + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, " + "mcmd %x, loop_id %d)", ha->host_no, sess, + sess->port_name[0], sess->port_name[1], + sess->port_name[2], sess->port_name[3], + sess->port_name[4], sess->port_name[5], + sess->port_name[6], sess->port_name[7], + mcmd, loop_id); res = q2t_issue_task_mgmt(sess, (uint8_t *)&lun, sizeof(lun), mcmd, iocb, Q24_MGMT_SEND_NACK); @@ -465,7 +471,13 @@ static void q2t_clear_tgt_db(struct q2t_tgt *tgt, bool local_only) if (local_only && !sess->local) continue; if (local_only && sess->local) - TRACE_MGMT_DBG("Putting local session %p", sess); + TRACE_MGMT_DBG("Putting local session %p from port " + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + sess, + sess->port_name[0], sess->port_name[1], + sess->port_name[2], sess->port_name[3], + sess->port_name[4], sess->port_name[5], + sess->port_name[6], sess->port_name[7]); q2t_sess_put(sess); } @@ -4020,7 +4032,6 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, void *iocb) /* set the Clear LIP reset event flag */ add_flags |= NOTIFY_ACK_CLEAR_LIP_RESET; } - qla2x00_mark_all_devices_lost(ha, 1); if (q2t_reset(ha, iocb, Q2T_ABORT_ALL) == 0) send_notify_ack = 0; break; @@ -4045,9 +4056,15 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, void *iocb) } case IMM_NTFY_PORT_LOGOUT: - TRACE(TRACE_MGMT, "Port logout (S %08x -> L %#x)", - le16_to_cpu(iocb2x->seq_id), le16_to_cpu(iocb2x->lun)); - qla2x00_mark_all_devices_lost(ha, 1); + if (IS_FWI2_CAPABLE(ha)) { + TRACE(TRACE_MGMT, "Port logout (loop %#x, subcode %x)", + le16_to_cpu(iocb24->nport_handle), + iocb24->status_subcode); + } else { + TRACE(TRACE_MGMT, "Port logout (S %08x -> L %#x)", + le16_to_cpu(iocb2x->seq_id), + le16_to_cpu(iocb2x->lun)); + } if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS_SESS) == 0) send_notify_ack = 0; /* The sessions will be cleared in the callback, if needed */ @@ -4055,7 +4072,6 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, void *iocb) case IMM_NTFY_GLBL_TPRLO: TRACE(TRACE_MGMT, "Global TPRLO (%x)", status); - qla2x00_mark_all_devices_lost(ha, 1); if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS) == 0) send_notify_ack = 0; /* The sessions will be cleared in the callback, if needed */ @@ -4063,7 +4079,6 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, void *iocb) case IMM_NTFY_PORT_CONFIG: TRACE(TRACE_MGMT, "Port config changed (%x)", status); - qla2x00_mark_all_devices_lost(ha, 1); if (q2t_reset(ha, iocb, Q2T_ABORT_ALL) == 0) send_notify_ack = 0; /* The sessions will be cleared in the callback, if needed */ @@ -4073,7 +4088,6 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, void *iocb) PRINT_ERROR("qla2x00t(%ld): Link failure detected", ha->instance); /* I_T nexus loss */ - qla2x00_mark_all_devices_lost(ha, 1); if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS) == 0) send_notify_ack = 0; break; diff --git a/qla2x00t/qla_os.c b/qla2x00t/qla_os.c index 6dae1d3d7..fdcf9699f 100644 --- a/qla2x00t/qla_os.c +++ b/qla2x00t/qla_os.c @@ -2146,7 +2146,6 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) if (defer) qla2xxx_wake_dpc(ha); } -EXPORT_SYMBOL(qla2x00_mark_all_devices_lost); /* * qla2x00_mem_alloc