diff --git a/qla2x00t/qla2x00-target/README b/qla2x00t/qla2x00-target/README index 8183952f6..393a57917 100644 --- a/qla2x00t/qla2x00-target/README +++ b/qla2x00t/qla2x00-target/README @@ -81,6 +81,10 @@ subdirectory. The target driver will be installed in /lib/modules/`you_kernel_version`/extra. To uninstall it, type 'make uninstall'. + +Usage +----- + After the drivers are loaded and adapters successfully initialized by the initiator driver, including firmware image load, you should configure exported devices using the corresponding interface of SCST @@ -103,11 +107,31 @@ You can find some installation and configuration HOWTOs in http://scst.sourceforge.net/qla2x00t-howto.html and https://forums.openfiler.com/viewtopic.php?id=3422. -It is strongly recommended to use firmware version 5.x or higher for -24xx/25xx adapters. See + +IMPORTANT USAGE NOTES +--------------------- + +1. It is strongly recommended to use firmware version 5.x or higher +for 24xx/25xx adapters. See http://sourceforge.net/mailarchive/forum.php?thread_name=4B4CD39F.6020401%40vlnb.net&forum_name=scst-devel for more details why. +2. If you reload qla2x00tgt module, you should also reload qla2xxx +module, otherwise your initiators could not see the target, when it is +enabled after qla2x00tgt module load. + +3. If you delete and then add back with the same WWN an NPIV initiator +on the initiator side, make sure it has the same port_id as well. In +Fibre Channel initiators identified by port_id (s_id in FC terms), so if +the recreated NPIV initiator has another port_id, which was already used +by another (NPIV) initiator, those initiators could be confused by the +target and assigned to incorrect security groups, hence they could see +incorrect LUNs. + +If you can't ensure the same port_id's for recreated initiators, it is +safer to restart qla2x00tgt and qla2xxx modules on the target to make +sure the target doesn't have any initiator port_id cached. + Initiator and target modes -------------------------- @@ -124,21 +148,29 @@ enabled back. - "enabled" - initiator mode will always stay enabled. -Usage of mode "disabled" is recommended if you have incorrectly -functioning remote for your target initiators, which if they once seen a -port in initiator mode, later refuse to see it as a target. +Usage of mode "disabled" is recommended, if you have incorrectly +functioning your target's initiators, which if once seen a port in +initiator mode, later refuse to see it as a target. Although this mode +does make a noticeable difference, it isn't absolutely strong, since the +firmware once initialized requires a HBA to be in either initiator, or +target mode, so until you enable target mode on a port, your initiators +will report this port as working in initiator mode. If you need +absolutely strong assurance that initiator mode never enabled, you can +consider using patch +unsupported-patches/qla_delayed_hw_init_tgt_mode_from_the_beginning.diff. +See description of it inside the patch. Use mode "enabled" if you need your QLA adapters to work in both initiator and target modes at the same time. +You can always see which modes are currently active in active_mode sysfs +attribute. + In all the modes you can at any time use sysfs attribute ini_mode_force_reverse to force enable or disable initiator mode on any particular port. Setting this attribute to 1 will reverse current status of the initiator mode from enabled to disabled and vice versa. -You can always see which modes are currently active in active_mode sysfs -attribute. - Explicit conformation --------------------- diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index a7e85efae..3d361fbc2 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -556,6 +556,12 @@ static void q2t_del_sess_timer_fn(unsigned long arg) return; } +static void q2t_undelete_sess(struct q2t_sess *sess) +{ + list_del(&sess->del_list_entry); + sess->deleted = 0; +} + /* * Must be called under tgt_mutex. * @@ -585,16 +591,14 @@ static struct q2t_sess *q2t_create_sess(scsi_qla_host_t *ha, fc_port_t *fcport, (sess->port_name[7] == fcport->port_name[7])) { TRACE_MGMT_DBG("Double sess %p found (s_id %x:%x:%x, " "loop_id %d), updating to d_id %x:%x:%x, " - "loop_id %d", sess, sess->s_id.b.al_pa, - sess->s_id.b.area, sess->s_id.b.domain, - sess->loop_id, fcport->d_id.b.al_pa, - fcport->d_id.b.area, fcport->d_id.b.domain, + "loop_id %d", sess, sess->s_id.b.domain, + sess->s_id.b.al_pa, sess->s_id.b.area, + sess->loop_id, fcport->d_id.b.domain, + fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); - if (sess->deleted) { - list_del(&sess->del_list_entry); - sess->deleted = 0; - } + if (sess->deleted) + q2t_undelete_sess(sess); q2t_sess_get(sess); sess->s_id = fcport->d_id; @@ -653,7 +657,7 @@ static struct q2t_sess *q2t_create_sess(scsi_qla_host_t *ha, fc_port_t *fcport, sess->scst_sess = scst_register_session(tgt->scst_tgt, 1, wwn_str, sess, sess, q2t_alloc_session_done); if (sess->scst_sess == NULL) { - PRINT_CRIT_ERROR("qla2x00t(%ld): scst_register_session() " + PRINT_ERROR("qla2x00t(%ld): scst_register_session() " "failed for host %ld (wwn %s, loop_id %d), all " "commands from it will be refused", ha->instance, ha->host_no, wwn_str, fcport->loop_id); @@ -669,7 +673,7 @@ static struct q2t_sess *q2t_create_sess(scsi_qla_host_t *ha, fc_port_t *fcport, PRINT_INFO("qla2x00t(%ld): %ssession for wwn %s (loop_id %d, " "s_id %x:%x:%x, confirmed completion %ssupported) added", ha->instance, local ? "local " : "", wwn_str, fcport->loop_id, - sess->s_id.b.al_pa, sess->s_id.b.area, sess->s_id.b.domain, + sess->s_id.b.domain, sess->s_id.b.al_pa, sess->s_id.b.area, sess->conf_compl_supported ? "" : "not "); kfree(wwn_str); @@ -688,6 +692,20 @@ out_free_sess: goto out; } +static void q2t_reappear_sess(struct q2t_sess *sess, const char *reason) +{ + q2t_undelete_sess(sess); + + PRINT_INFO("qla2x00t(%ld): session for port %02x:" + "%02x:%02x:%02x:%02x:%02x:%02x:%02x (loop ID %d) " + "reappeared%s", sess->tgt->ha->instance, 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], sess->loop_id, reason); + TRACE_MGMT_DBG("Appeared sess %p", sess); +} + static void q2t_fc_port_added(scsi_qla_host_t *ha, fc_port_t *fcport) { struct q2t_tgt *tgt; @@ -715,19 +733,9 @@ static void q2t_fc_port_added(scsi_qla_host_t *ha, fc_port_t *fcport) if (sess != NULL) q2t_sess_put(sess); /* put the extra creation ref */ } else { - if (sess->deleted) { - list_del(&sess->del_list_entry); - sess->deleted = 0; - - PRINT_INFO("qla2x00t(%ld): session for port %02x:" - "%02x:%02x:%02x:%02x:%02x:%02x:%02x (loop ID %d) " - "reappeared", ha->instance, fcport->port_name[0], - fcport->port_name[1], fcport->port_name[2], - fcport->port_name[3], fcport->port_name[4], - fcport->port_name[5], fcport->port_name[6], - fcport->port_name[7], sess->loop_id); - TRACE_MGMT_DBG("Appeared sess %p", sess); - } else if (sess->local) { + if (sess->deleted) + q2t_reappear_sess(sess, ""); + else if (sess->local) { TRACE(TRACE_MGMT, "qla2x00t(%ld): local session for " "port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " "(loop ID %d) became global", ha->instance, @@ -737,9 +745,10 @@ static void q2t_fc_port_added(scsi_qla_host_t *ha, fc_port_t *fcport) fcport->port_name[6], fcport->port_name[7], sess->loop_id); } - sess->local = 0; } + sess->local = 0; + spin_unlock_irq(&ha->hardware_lock); out_unlock: @@ -1188,8 +1197,8 @@ static void q24_handle_abts(scsi_qla_host_t *ha, abts24_recv_entry_t *abts) } TRACE(TRACE_MGMT, "qla2x00t(%ld): task abort (s_id=%x:%x:%x, " - "tag=%d, param=%x)", ha->instance, abts->fcp_hdr_le.s_id[0], - abts->fcp_hdr_le.s_id[1], abts->fcp_hdr_le.s_id[2], tag, + "tag=%d, param=%x)", ha->instance, abts->fcp_hdr_le.s_id[2], + abts->fcp_hdr_le.s_id[1], abts->fcp_hdr_le.s_id[0], tag, le32_to_cpu(abts->fcp_hdr_le.parameter)); sess = q2t_find_sess_by_s_id_le(ha->tgt, abts->fcp_hdr_le.s_id); @@ -1424,6 +1433,9 @@ static int q2t_pci_map_calc_cnt(struct q2t_prm *prm) prm->cmd->sg_cnt, prm->cmd->dma_data_direction); if (unlikely(prm->seg_cnt == 0)) goto out_err; + + prm->cmd->sg_mapped = 1; + /* * If greater than four sg entries then we need to allocate * the continuation entries @@ -1449,6 +1461,13 @@ out_err: goto out; } +static inline void q2t_unmap_sg(scsi_qla_host_t *ha, struct q2t_cmd *cmd) +{ + EXTRACHECKS_BUG_ON(!cmd->sg_mapped); + pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); + cmd->sg_mapped = 0; +} + static int q2t_check_reserve_free_req(scsi_qla_host_t *ha, uint32_t req_cnt) { int res = SCST_TGT_RES_SUCCESS; @@ -1936,9 +1955,8 @@ out: return res; out_unlock_free_unmap: - if (q2t_has_data(cmd)) - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); + if (cmd->sg_mapped) + q2t_unmap_sg(ha, cmd); /* Release ring specific lock */ spin_unlock_irqrestore(&ha->hardware_lock, *flags); @@ -2312,9 +2330,8 @@ out: return res; out_unmap_unlock: - if (q2t_has_data(cmd)) - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); + if (cmd->sg_mapped) + q2t_unmap_sg(ha, cmd); goto out_unlock; } @@ -2392,10 +2409,8 @@ out: return res; out_unlock_free_unmap: - if (q2t_has_data(cmd)) { - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - } + if (cmd->sg_mapped) + q2t_unmap_sg(ha, cmd); goto out_unlock; } @@ -2570,6 +2585,8 @@ out: static inline void q2t_free_cmd(struct q2t_cmd *cmd) { + EXTRACHECKS_BUG_ON(cmd->sg_mapped); + if (unlikely(cmd->free_sg)) kfree(cmd->sg); kmem_cache_free(q2t_cmd_cachep, cmd); @@ -2656,8 +2673,8 @@ static int q2t_prepare_srr_ctio(scsi_qla_host_t *ha, struct q2t_cmd *cmd, spin_unlock(&tgt->srr_lock); } else { struct srr_imm *ti; - PRINT_CRIT_ERROR("qla2x00t(%ld): Unable to " - "allocate SRR CTIO entry", ha->instance); + PRINT_ERROR("qla2x00t(%ld): Unable to allocate SRR CTIO entry", + ha->instance); spin_lock(&tgt->srr_lock); list_for_each_entry_safe(imm, ti, &tgt->srr_imm_list, srr_list_entry) { @@ -2838,6 +2855,9 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha, uint32_t handle, scst_cmd = cmd->scst_cmd; + if (cmd->sg_mapped) + q2t_unmap_sg(ha, cmd); + if (unlikely(status != CTIO_SUCCESS)) { switch (status & 0xFFFF) { case CTIO_LIP_RESET: @@ -2884,10 +2904,6 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha, uint32_t handle, if (cmd->state == Q2T_STATE_PROCESSED) { TRACE_DBG("Command %p finished", cmd); - if (q2t_has_data(cmd)) { - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - } } else if (cmd->state == Q2T_STATE_NEED_DATA) { int rx_status = SCST_RX_STATUS_SUCCESS; @@ -2901,9 +2917,6 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha, uint32_t handle, TRACE_DBG("Data received, context %x, rx_status %d", context, rx_status); - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - scst_rx_data(scst_cmd, rx_status, context); goto out; } else if (cmd->state == Q2T_STATE_ABORTED) { @@ -3173,6 +3186,9 @@ static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_t *atio) } } + if (unlikely(sess->deleted)) + q2t_reappear_sess(sess, " by new commands"); + res = q2t_do_send_cmd_to_scst(ha, cmd, sess); if (unlikely(res != 0)) goto out_free_cmd; @@ -3522,7 +3538,7 @@ static int q2t_cut_cmd_data_head(struct q2t_cmd *cmd, unsigned int offset) sg = kmalloc(cnt * sizeof(sg[0]), GFP_KERNEL); if (sg == NULL) { - PRINT_CRIT_ERROR("qla2x00t(%ld): Unable to allocate cut " + PRINT_ERROR("qla2x00t(%ld): Unable to allocate cut " "SG (len %zd)", cmd->tgt->ha->instance, cnt * sizeof(sg[0])); res = -ENOMEM; @@ -3634,8 +3650,6 @@ static void q24_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, if (q2t_has_data(cmd)) { uint32_t offset; int xmit_type; - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); offset = le32_to_cpu(imm->imm.notify_entry24.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -3658,8 +3672,6 @@ static void q24_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, if (q2t_has_data(cmd)) { uint32_t offset; int xmit_type; - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); offset = le32_to_cpu(imm->imm.notify_entry24.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -3667,7 +3679,8 @@ static void q24_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, q24_send_notify_ack(ha, ntfy, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); spin_unlock_irq(&ha->hardware_lock); - __q2t_rdy_to_xfer(cmd); + if (xmit_type & Q2T_XMIT_DATA) + __q2t_rdy_to_xfer(cmd); } else { PRINT_ERROR("qla2x00t(%ld): SRR for out data for cmd " "without them (tag %d, SCSI status %d), " @@ -3679,19 +3692,13 @@ static void q24_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, default: PRINT_ERROR("qla2x00t(%ld): Unknown srr_ui value %x", ha->instance, ntfy->srr_ui); - goto out_unmap_reject; + goto out_reject; } out: TRACE_EXIT(); return; -out_unmap_reject: - if (q2t_has_data(sctio->cmd)) { - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - } - out_reject: spin_lock_irq(&ha->hardware_lock); q24_send_notify_ack(ha, ntfy, NOTIFY_ACK_SRR_FLAGS_REJECT, @@ -3699,10 +3706,6 @@ out_reject: NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); if (cmd->state == Q2T_STATE_NEED_DATA) { cmd->state = Q2T_STATE_DATA_IN; - - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - scst_rx_data(cmd->scst_cmd, SCST_RX_STATUS_ERROR, SCST_CONTEXT_THREAD); } else @@ -3735,8 +3738,6 @@ static void q2x_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, if (q2t_has_data(cmd)) { uint32_t offset; int xmit_type; - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); offset = le32_to_cpu(imm->imm.notify_entry.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -3759,8 +3760,6 @@ static void q2x_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, if (q2t_has_data(cmd)) { uint32_t offset; int xmit_type; - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); offset = le32_to_cpu(imm->imm.notify_entry.srr_rel_offs); if (q2t_srr_adjust_data(cmd, offset, &xmit_type) != 0) goto out_reject; @@ -3768,7 +3767,8 @@ static void q2x_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, q2x_send_notify_ack(ha, ntfy, 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); spin_unlock_irq(&ha->hardware_lock); - __q2t_rdy_to_xfer(cmd); + if (xmit_type & Q2T_XMIT_DATA) + __q2t_rdy_to_xfer(cmd); } else { PRINT_ERROR("qla2x00t(%ld): SRR for out data for cmd " "without them (tag %d, SCSI status %d), " @@ -3780,19 +3780,13 @@ static void q2x_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio, default: PRINT_ERROR("qla2x00t(%ld): Unknown srr_ui value %x", ha->instance, ntfy->srr_ui); - goto out_unmap_reject; + goto out_reject; } out: TRACE_EXIT(); return; -out_unmap_reject: - if (q2t_has_data(sctio->cmd)) { - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - } - out_reject: spin_lock_irq(&ha->hardware_lock); q2x_send_notify_ack(ha, ntfy, 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_REJECT, @@ -3800,10 +3794,6 @@ out_reject: NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); if (cmd->state == Q2T_STATE_NEED_DATA) { cmd->state = Q2T_STATE_DATA_IN; - - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - scst_rx_data(cmd->scst_cmd, SCST_RX_STATUS_ERROR, SCST_CONTEXT_THREAD); } else @@ -3968,7 +3958,7 @@ static void q2t_prepare_srr_imm(scsi_qla_host_t *ha, void *iocb) } else { struct srr_ctio *ts; - PRINT_CRIT_ERROR("qla2x00t(%ld): Unable to allocate SRR IMM " + PRINT_ERROR("qla2x00t(%ld): Unable to allocate SRR IMM " "entry, SRR request will be rejected", ha->instance); /* IRQ is already OFF */ @@ -4095,7 +4085,7 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, void *iocb) break; case IMM_NTFY_GLBL_LOGO: - PRINT_ERROR("qla2x00t(%ld): Link failure detected", + PRINT_WARNING("qla2x00t(%ld): Link failure detected", ha->instance); /* I_T nexus loss */ if (q2t_reset(ha, iocb, Q2T_NEXUS_LOSS) == 0) @@ -4293,14 +4283,13 @@ static void q24_atio_pkt(scsi_qla_host_t *ha, atio7_entry_t *atio) atio->fcp_cmnd.add_cdb_len); break; } - TRACE_DBG("ATIO_TYPE7 instance %ld " - "lun %Lx read/write %d/%d data_length %04x " - "s_id %x:%x:%x", - ha->instance, atio->fcp_cmnd.lun, - atio->fcp_cmnd.rddata, atio->fcp_cmnd.wrdata, - be32_to_cpu(atio->fcp_cmnd.data_length), - atio->fcp_hdr.s_id[0], atio->fcp_hdr.s_id[1], - atio->fcp_hdr.s_id[2]); + TRACE_DBG("ATIO_TYPE7 instance %ld, lun %Lx, read/write %d/%d, " + "data_length %04x, s_id %x:%x:%x", ha->instance, + atio->fcp_cmnd.lun, atio->fcp_cmnd.rddata, + atio->fcp_cmnd.wrdata, + be32_to_cpu(atio->fcp_cmnd.data_length), + atio->fcp_hdr.s_id[0], atio->fcp_hdr.s_id[1], + atio->fcp_hdr.s_id[2]); TRACE_BUFFER("Incoming ATIO7 packet data", atio, REQUEST_ENTRY_SIZE); PRINT_BUFF_FLAG(TRACE_SCSI, "FCP CDB", atio->fcp_cmnd.cdb, @@ -4753,9 +4742,19 @@ static int q24_get_loop_id(scsi_qla_host_t *ha, atio7_entry_t *atio7, } if (res != 0) { - PRINT_ERROR("Unable to find initiator with S_ID %x:%x:%x", - atio7->fcp_hdr.s_id[2], atio7->fcp_hdr.s_id[1], - atio7->fcp_hdr.s_id[0]); + if ((atio7->fcp_hdr.s_id[0] == 0xFF) && + (atio7->fcp_hdr.s_id[1] == 0xFC)) { + /* + * This is Domain Controller. It should be OK to drop + * SCSI commands from it. + */ + TRACE_MGMT_DBG("Unable to find initiator with S_ID " + "%x:%x:%x", atio7->fcp_hdr.s_id[0], + atio7->fcp_hdr.s_id[1], atio7->fcp_hdr.s_id[2]); + } else + PRINT_ERROR("Unable to find initiator with S_ID " + "%x:%x:%x", atio7->fcp_hdr.s_id[0], + atio7->fcp_hdr.s_id[1], atio7->fcp_hdr.s_id[2]); } out_free_id_list: @@ -4858,8 +4857,8 @@ send: } else { /* * Cmd might be already aborted behind us, so be safe and - * abort it. It was not sent to SCST yet, so pass NULL as - * the second argument. + * abort it. It should be OK, initiator will retry it. It has + * not sent to SCST yet, so pass NULL as the second argument. */ TRACE_MGMT_DBG("Terminating work cmd %p", cmd); if (IS_FWI2_CAPABLE(ha)) @@ -4907,7 +4906,8 @@ static void q2t_sess_work_fn(struct work_struct *work) spin_lock_irq(&tgt->sess_work_lock); if (rc != 0) { - PRINT_CRIT_ERROR("%s", "Unable to complete sess work"); + TRACE_MGMT_DBG("Unable to complete sess work (tgt %p), " + "freeing cmd %p", tgt, prm->cmd); q2t_free_cmd(prm->cmd); } @@ -4957,20 +4957,16 @@ static void q2t_on_hw_pending_cmd_timeout(struct scst_cmd *scst_cmd) spin_lock_irqsave(&ha->hardware_lock, flags); + if (cmd->sg_mapped) + q2t_unmap_sg(ha, cmd); + if (cmd->state == Q2T_STATE_PROCESSED) { TRACE_MGMT_DBG("Force finishing cmd %p", cmd); - if (q2t_has_data(cmd)) { - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - } } else if (cmd->state == Q2T_STATE_NEED_DATA) { TRACE_MGMT_DBG("Force rx_data cmd %p", cmd); q2t_cleanup_hw_pending_cmd(ha, cmd); - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, - cmd->dma_data_direction); - scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR_FATAL, SCST_CONTEXT_THREAD); goto out_unlock; diff --git a/qla2x00t/qla2x00-target/qla2x00t.h b/qla2x00t/qla2x00-target/qla2x00t.h index 589ed2238..7582f49d2 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.h +++ b/qla2x00t/qla2x00-target/qla2x00t.h @@ -196,6 +196,7 @@ struct q2t_cmd { struct scst_cmd *scst_cmd; unsigned int conf_compl_supported:1;/* to save extra sess dereferences */ + unsigned int sg_mapped:1; unsigned int free_sg:1; unsigned int aborted:1; /* Needed in case of SRR */ unsigned int write_data_transferred:1; diff --git a/qla2x00t/qla2x_tgt_def.h b/qla2x00t/qla2x_tgt_def.h index d1f1233e9..9e5b30a87 100644 --- a/qla2x00t/qla2x_tgt_def.h +++ b/qla2x00t/qla2x_tgt_def.h @@ -50,7 +50,7 @@ * Must be changed on any change in any target visible interfaces or * data in the initiator */ -#define QLA2X_INITIATOR_MAGIC 57219 +#define QLA2X_INITIATOR_MAGIC 57319 #define QLA2X_INI_MODE_STR_EXCLUSIVE "exclusive" #define QLA2X_INI_MODE_STR_DISABLED "disabled" diff --git a/qla2x00t/qla_attr.c b/qla2x00t/qla_attr.c index 51d1c8364..241b6d4d5 100644 --- a/qla2x00t/qla_attr.c +++ b/qla2x00t/qla_attr.c @@ -1607,6 +1607,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) * Transport has effectively 'deleted' the rport, clear * all local references. */ +#ifdef CONFIG_SCSI_QLA2XXX_TARGET + if (qla_target.tgt_fc_port_deleted) + qla_target.tgt_fc_port_deleted(fcport->ha, fcport); +#endif spin_lock_irq(host->host_lock); fcport->rport = NULL; *((fc_port_t **)rport->dd_data) = NULL; diff --git a/qla2x00t/qla_mbx.c b/qla2x00t/qla_mbx.c index 3017ff62d..8de1f9977 100644 --- a/qla2x00t/qla_mbx.c +++ b/qla2x00t/qla_mbx.c @@ -1931,7 +1931,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; } mcp->in_mb = MBX_1|MBX_0; - mcp->tov = MBX_TOV_SECONDS; + mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp);