aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h20
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c192
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c11
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_nx2.c13
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c19
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c827
-rw-r--r--drivers/scsi/qla2xxx/qla_target.h73
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c256
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.h6
15 files changed, 1016 insertions, 424 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 82b92c414a9c..437254e1c4de 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -738,7 +738,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
738 ql_log(ql_log_info, vha, 0x706f, 738 ql_log(ql_log_info, vha, 0x706f,
739 "Issuing MPI reset.\n"); 739 "Issuing MPI reset.\n");
740 740
741 if (IS_QLA83XX(ha)) { 741 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
742 uint32_t idc_control; 742 uint32_t idc_control;
743 743
744 qla83xx_idc_lock(vha, 0); 744 qla83xx_idc_lock(vha, 0);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 0e6ee3ca30e6..8b011aef12bd 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -67,10 +67,10 @@
67 * | | | 0xd031-0xd0ff | 67 * | | | 0xd031-0xd0ff |
68 * | | | 0xd101-0xd1fe | 68 * | | | 0xd101-0xd1fe |
69 * | | | 0xd214-0xd2fe | 69 * | | | 0xd214-0xd2fe |
70 * | Target Mode | 0xe079 | | 70 * | Target Mode | 0xe080 | |
71 * | Target Mode Management | 0xf072 | 0xf002 | 71 * | Target Mode Management | 0xf096 | 0xf002 |
72 * | | | 0xf046-0xf049 | 72 * | | | 0xf046-0xf049 |
73 * | Target Mode Task Management | 0x1000b | | 73 * | Target Mode Task Management | 0x1000d | |
74 * ---------------------------------------------------------------------- 74 * ----------------------------------------------------------------------
75 */ 75 */
76 76
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index e86201d3b8c6..9ad819edcd67 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -274,6 +274,7 @@
274#define RESPONSE_ENTRY_CNT_FX00 256 /* Number of response entries.*/ 274#define RESPONSE_ENTRY_CNT_FX00 256 /* Number of response entries.*/
275 275
276struct req_que; 276struct req_que;
277struct qla_tgt_sess;
277 278
278/* 279/*
279 * (sd.h is not exported, hence local inclusion) 280 * (sd.h is not exported, hence local inclusion)
@@ -2026,6 +2027,7 @@ typedef struct fc_port {
2026 uint16_t port_id; 2027 uint16_t port_id;
2027 2028
2028 unsigned long retry_delay_timestamp; 2029 unsigned long retry_delay_timestamp;
2030 struct qla_tgt_sess *tgt_session;
2029} fc_port_t; 2031} fc_port_t;
2030 2032
2031#include "qla_mr.h" 2033#include "qla_mr.h"
@@ -3154,13 +3156,13 @@ struct qla_hw_data {
3154/* Bit 21 of fw_attributes decides the MCTP capabilities */ 3156/* Bit 21 of fw_attributes decides the MCTP capabilities */
3155#define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \ 3157#define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \
3156 ((ha)->fw_attributes_ext[0] & BIT_0)) 3158 ((ha)->fw_attributes_ext[0] & BIT_0))
3157#define IS_PI_UNINIT_CAPABLE(ha) (IS_QLA83XX(ha)) 3159#define IS_PI_UNINIT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
3158#define IS_PI_IPGUARD_CAPABLE(ha) (IS_QLA83XX(ha)) 3160#define IS_PI_IPGUARD_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
3159#define IS_PI_DIFB_DIX0_CAPABLE(ha) (0) 3161#define IS_PI_DIFB_DIX0_CAPABLE(ha) (0)
3160#define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha)) 3162#define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
3161#define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \ 3163#define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \
3162 (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22)) 3164 (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22))
3163#define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha)) 3165#define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
3164#define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length) 3166#define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length)
3165#define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha)) 3167#define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha))
3166#define IS_DPORT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) 3168#define IS_DPORT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
@@ -3579,6 +3581,16 @@ typedef struct scsi_qla_host {
3579 uint16_t fcoe_fcf_idx; 3581 uint16_t fcoe_fcf_idx;
3580 uint8_t fcoe_vn_port_mac[6]; 3582 uint8_t fcoe_vn_port_mac[6];
3581 3583
3584 /* list of commands waiting on workqueue */
3585 struct list_head qla_cmd_list;
3586 struct list_head qla_sess_op_cmd_list;
3587 spinlock_t cmd_list_lock;
3588
3589 /* Counter to detect races between ELS and RSCN events */
3590 atomic_t generation_tick;
3591 /* Time when global fcport update has been scheduled */
3592 int total_fcport_update_gen;
3593
3582 uint32_t vp_abort_cnt; 3594 uint32_t vp_abort_cnt;
3583 3595
3584 struct fc_vport *fc_vport; /* holds fc_vport * for each vport */ 3596 struct fc_vport *fc_vport; /* holds fc_vport * for each vport */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 285cb204f300..11f2f3279eab 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -115,6 +115,8 @@ qla2x00_async_iocb_timeout(void *data)
115 QLA_LOGIO_LOGIN_RETRIED : 0; 115 QLA_LOGIO_LOGIN_RETRIED : 0;
116 qla2x00_post_async_login_done_work(fcport->vha, fcport, 116 qla2x00_post_async_login_done_work(fcport->vha, fcport,
117 lio->u.logio.data); 117 lio->u.logio.data);
118 } else if (sp->type == SRB_LOGOUT_CMD) {
119 qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
118 } 120 }
119} 121}
120 122
@@ -497,7 +499,10 @@ void
497qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, 499qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
498 uint16_t *data) 500 uint16_t *data)
499{ 501{
500 qla2x00_mark_device_lost(vha, fcport, 1, 0); 502 /* Don't re-login in target mode */
503 if (!fcport->tgt_session)
504 qla2x00_mark_device_lost(vha, fcport, 1, 0);
505 qlt_logo_completion_handler(fcport, data[0]);
501 return; 506 return;
502} 507}
503 508
@@ -708,7 +713,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
708 if (rval != QLA_SUCCESS) { 713 if (rval != QLA_SUCCESS) {
709 ql_log(ql_log_warn, vha, 0x00d4, 714 ql_log(ql_log_warn, vha, 0x00d4,
710 "Unable to initialize ISP84XX.\n"); 715 "Unable to initialize ISP84XX.\n");
711 qla84xx_put_chip(vha); 716 qla84xx_put_chip(vha);
712 } 717 }
713 } 718 }
714 719
@@ -1538,7 +1543,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
1538 mem_size = (ha->fw_memory_size - 0x11000 + 1) * 1543 mem_size = (ha->fw_memory_size - 0x11000 + 1) *
1539 sizeof(uint16_t); 1544 sizeof(uint16_t);
1540 } else if (IS_FWI2_CAPABLE(ha)) { 1545 } else if (IS_FWI2_CAPABLE(ha)) {
1541 if (IS_QLA83XX(ha)) 1546 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
1542 fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem); 1547 fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem);
1543 else if (IS_QLA81XX(ha)) 1548 else if (IS_QLA81XX(ha))
1544 fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem); 1549 fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem);
@@ -1550,7 +1555,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
1550 mem_size = (ha->fw_memory_size - 0x100000 + 1) * 1555 mem_size = (ha->fw_memory_size - 0x100000 + 1) *
1551 sizeof(uint32_t); 1556 sizeof(uint32_t);
1552 if (ha->mqenable) { 1557 if (ha->mqenable) {
1553 if (!IS_QLA83XX(ha)) 1558 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
1554 mq_size = sizeof(struct qla2xxx_mq_chain); 1559 mq_size = sizeof(struct qla2xxx_mq_chain);
1555 /* 1560 /*
1556 * Allocate maximum buffer size for all queues. 1561 * Allocate maximum buffer size for all queues.
@@ -2922,21 +2927,14 @@ qla2x00_rport_del(void *data)
2922{ 2927{
2923 fc_port_t *fcport = data; 2928 fc_port_t *fcport = data;
2924 struct fc_rport *rport; 2929 struct fc_rport *rport;
2925 scsi_qla_host_t *vha = fcport->vha;
2926 unsigned long flags; 2930 unsigned long flags;
2927 2931
2928 spin_lock_irqsave(fcport->vha->host->host_lock, flags); 2932 spin_lock_irqsave(fcport->vha->host->host_lock, flags);
2929 rport = fcport->drport ? fcport->drport: fcport->rport; 2933 rport = fcport->drport ? fcport->drport: fcport->rport;
2930 fcport->drport = NULL; 2934 fcport->drport = NULL;
2931 spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); 2935 spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
2932 if (rport) { 2936 if (rport)
2933 fc_remote_port_delete(rport); 2937 fc_remote_port_delete(rport);
2934 /*
2935 * Release the target mode FC NEXUS in qla_target.c code
2936 * if target mod is enabled.
2937 */
2938 qlt_fc_port_deleted(vha, fcport);
2939 }
2940} 2938}
2941 2939
2942/** 2940/**
@@ -3303,6 +3301,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
3303 * Create target mode FC NEXUS in qla_target.c if target mode is 3301 * Create target mode FC NEXUS in qla_target.c if target mode is
3304 * enabled.. 3302 * enabled..
3305 */ 3303 */
3304
3306 qlt_fc_port_added(vha, fcport); 3305 qlt_fc_port_added(vha, fcport);
3307 3306
3308 spin_lock_irqsave(fcport->vha->host->host_lock, flags); 3307 spin_lock_irqsave(fcport->vha->host->host_lock, flags);
@@ -3341,8 +3340,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
3341 3340
3342 if (IS_QLAFX00(vha->hw)) { 3341 if (IS_QLAFX00(vha->hw)) {
3343 qla2x00_set_fcport_state(fcport, FCS_ONLINE); 3342 qla2x00_set_fcport_state(fcport, FCS_ONLINE);
3344 qla2x00_reg_remote_port(vha, fcport); 3343 goto reg_port;
3345 return;
3346 } 3344 }
3347 fcport->login_retry = 0; 3345 fcport->login_retry = 0;
3348 fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); 3346 fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
@@ -3350,7 +3348,16 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
3350 qla2x00_set_fcport_state(fcport, FCS_ONLINE); 3348 qla2x00_set_fcport_state(fcport, FCS_ONLINE);
3351 qla2x00_iidma_fcport(vha, fcport); 3349 qla2x00_iidma_fcport(vha, fcport);
3352 qla24xx_update_fcport_fcp_prio(vha, fcport); 3350 qla24xx_update_fcport_fcp_prio(vha, fcport);
3353 qla2x00_reg_remote_port(vha, fcport); 3351
3352reg_port:
3353 if (qla_ini_mode_enabled(vha))
3354 qla2x00_reg_remote_port(vha, fcport);
3355 else {
3356 /*
3357 * Create target mode FC NEXUS in qla_target.c
3358 */
3359 qlt_fc_port_added(vha, fcport);
3360 }
3354} 3361}
3355 3362
3356/* 3363/*
@@ -3375,6 +3382,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
3375 LIST_HEAD(new_fcports); 3382 LIST_HEAD(new_fcports);
3376 struct qla_hw_data *ha = vha->hw; 3383 struct qla_hw_data *ha = vha->hw;
3377 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 3384 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
3385 int discovery_gen;
3378 3386
3379 /* If FL port exists, then SNS is present */ 3387 /* If FL port exists, then SNS is present */
3380 if (IS_FWI2_CAPABLE(ha)) 3388 if (IS_FWI2_CAPABLE(ha))
@@ -3445,6 +3453,14 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
3445 fcport->scan_state = QLA_FCPORT_SCAN; 3453 fcport->scan_state = QLA_FCPORT_SCAN;
3446 } 3454 }
3447 3455
3456 /* Mark the time right before querying FW for connected ports.
3457 * This process is long, asynchronous and by the time it's done,
3458 * collected information might not be accurate anymore. E.g.
3459 * disconnected port might have re-connected and a brand new
3460 * session has been created. In this case session's generation
3461 * will be newer than discovery_gen. */
3462 qlt_do_generation_tick(vha, &discovery_gen);
3463
3448 rval = qla2x00_find_all_fabric_devs(vha, &new_fcports); 3464 rval = qla2x00_find_all_fabric_devs(vha, &new_fcports);
3449 if (rval != QLA_SUCCESS) 3465 if (rval != QLA_SUCCESS)
3450 break; 3466 break;
@@ -3460,20 +3476,44 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
3460 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) 3476 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
3461 continue; 3477 continue;
3462 3478
3463 if (fcport->scan_state == QLA_FCPORT_SCAN && 3479 if (fcport->scan_state == QLA_FCPORT_SCAN) {
3464 atomic_read(&fcport->state) == FCS_ONLINE) { 3480 if (qla_ini_mode_enabled(base_vha) &&
3465 qla2x00_mark_device_lost(vha, fcport, 3481 atomic_read(&fcport->state) == FCS_ONLINE) {
3466 ql2xplogiabsentdevice, 0); 3482 qla2x00_mark_device_lost(vha, fcport,
3467 if (fcport->loop_id != FC_NO_LOOP_ID && 3483 ql2xplogiabsentdevice, 0);
3468 (fcport->flags & FCF_FCP2_DEVICE) == 0 && 3484 if (fcport->loop_id != FC_NO_LOOP_ID &&
3469 fcport->port_type != FCT_INITIATOR && 3485 (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
3470 fcport->port_type != FCT_BROADCAST) { 3486 fcport->port_type != FCT_INITIATOR &&
3471 ha->isp_ops->fabric_logout(vha, 3487 fcport->port_type != FCT_BROADCAST) {
3472 fcport->loop_id, 3488 ha->isp_ops->fabric_logout(vha,
3473 fcport->d_id.b.domain, 3489 fcport->loop_id,
3474 fcport->d_id.b.area, 3490 fcport->d_id.b.domain,
3475 fcport->d_id.b.al_pa); 3491 fcport->d_id.b.area,
3476 qla2x00_clear_loop_id(fcport); 3492 fcport->d_id.b.al_pa);
3493 qla2x00_clear_loop_id(fcport);
3494 }
3495 } else if (!qla_ini_mode_enabled(base_vha)) {
3496 /*
3497 * In target mode, explicitly kill
3498 * sessions and log out of devices
3499 * that are gone, so that we don't
3500 * end up with an initiator using the
3501 * wrong ACL (if the fabric recycles
3502 * an FC address and we have a stale
3503 * session around) and so that we don't
3504 * report initiators that are no longer
3505 * on the fabric.
3506 */
3507 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf077,
3508 "port gone, logging out/killing session: "
3509 "%8phC state 0x%x flags 0x%x fc4_type 0x%x "
3510 "scan_state %d\n",
3511 fcport->port_name,
3512 atomic_read(&fcport->state),
3513 fcport->flags, fcport->fc4_type,
3514 fcport->scan_state);
3515 qlt_fc_port_deleted(vha, fcport,
3516 discovery_gen);
3477 } 3517 }
3478 } 3518 }
3479 } 3519 }
@@ -3494,6 +3534,28 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
3494 (fcport->flags & FCF_LOGIN_NEEDED) == 0) 3534 (fcport->flags & FCF_LOGIN_NEEDED) == 0)
3495 continue; 3535 continue;
3496 3536
3537 /*
3538 * If we're not an initiator, skip looking for devices
3539 * and logging in. There's no reason for us to do it,
3540 * and it seems to actively cause problems in target
3541 * mode if we race with the initiator logging into us
3542 * (we might get the "port ID used" status back from
3543 * our login command and log out the initiator, which
3544 * seems to cause havoc).
3545 */
3546 if (!qla_ini_mode_enabled(base_vha)) {
3547 if (fcport->scan_state == QLA_FCPORT_FOUND) {
3548 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf078,
3549 "port %8phC state 0x%x flags 0x%x fc4_type 0x%x "
3550 "scan_state %d (initiator mode disabled; skipping "
3551 "login)\n", fcport->port_name,
3552 atomic_read(&fcport->state),
3553 fcport->flags, fcport->fc4_type,
3554 fcport->scan_state);
3555 }
3556 continue;
3557 }
3558
3497 if (fcport->loop_id == FC_NO_LOOP_ID) { 3559 if (fcport->loop_id == FC_NO_LOOP_ID) {
3498 fcport->loop_id = next_loopid; 3560 fcport->loop_id = next_loopid;
3499 rval = qla2x00_find_new_loop_id( 3561 rval = qla2x00_find_new_loop_id(
@@ -3520,16 +3582,38 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
3520 test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) 3582 test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
3521 break; 3583 break;
3522 3584
3523 /* Find a new loop ID to use. */ 3585 /*
3524 fcport->loop_id = next_loopid; 3586 * If we're not an initiator, skip looking for devices
3525 rval = qla2x00_find_new_loop_id(base_vha, fcport); 3587 * and logging in. There's no reason for us to do it,
3526 if (rval != QLA_SUCCESS) { 3588 * and it seems to actively cause problems in target
3527 /* Ran out of IDs to use */ 3589 * mode if we race with the initiator logging into us
3528 break; 3590 * (we might get the "port ID used" status back from
3529 } 3591 * our login command and log out the initiator, which
3592 * seems to cause havoc).
3593 */
3594 if (qla_ini_mode_enabled(base_vha)) {
3595 /* Find a new loop ID to use. */
3596 fcport->loop_id = next_loopid;
3597 rval = qla2x00_find_new_loop_id(base_vha,
3598 fcport);
3599 if (rval != QLA_SUCCESS) {
3600 /* Ran out of IDs to use */
3601 break;
3602 }
3530 3603
3531 /* Login and update database */ 3604 /* Login and update database */
3532 qla2x00_fabric_dev_login(vha, fcport, &next_loopid); 3605 qla2x00_fabric_dev_login(vha, fcport,
3606 &next_loopid);
3607 } else {
3608 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf079,
3609 "new port %8phC state 0x%x flags 0x%x fc4_type "
3610 "0x%x scan_state %d (initiator mode disabled; "
3611 "skipping login)\n",
3612 fcport->port_name,
3613 atomic_read(&fcport->state),
3614 fcport->flags, fcport->fc4_type,
3615 fcport->scan_state);
3616 }
3533 3617
3534 list_move_tail(&fcport->list, &vha->vp_fcports); 3618 list_move_tail(&fcport->list, &vha->vp_fcports);
3535 } 3619 }
@@ -3725,11 +3809,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3725 fcport->fp_speed = new_fcport->fp_speed; 3809 fcport->fp_speed = new_fcport->fp_speed;
3726 3810
3727 /* 3811 /*
3728 * If address the same and state FCS_ONLINE, nothing 3812 * If address the same and state FCS_ONLINE
3729 * changed. 3813 * (or in target mode), nothing changed.
3730 */ 3814 */
3731 if (fcport->d_id.b24 == new_fcport->d_id.b24 && 3815 if (fcport->d_id.b24 == new_fcport->d_id.b24 &&
3732 atomic_read(&fcport->state) == FCS_ONLINE) { 3816 (atomic_read(&fcport->state) == FCS_ONLINE ||
3817 !qla_ini_mode_enabled(base_vha))) {
3733 break; 3818 break;
3734 } 3819 }
3735 3820
@@ -3749,6 +3834,22 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3749 * Log it out if still logged in and mark it for 3834 * Log it out if still logged in and mark it for
3750 * relogin later. 3835 * relogin later.
3751 */ 3836 */
3837 if (!qla_ini_mode_enabled(base_vha)) {
3838 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf080,
3839 "port changed FC ID, %8phC"
3840 " old %x:%x:%x (loop_id 0x%04x)-> new %x:%x:%x\n",
3841 fcport->port_name,
3842 fcport->d_id.b.domain,
3843 fcport->d_id.b.area,
3844 fcport->d_id.b.al_pa,
3845 fcport->loop_id,
3846 new_fcport->d_id.b.domain,
3847 new_fcport->d_id.b.area,
3848 new_fcport->d_id.b.al_pa);
3849 fcport->d_id.b24 = new_fcport->d_id.b24;
3850 break;
3851 }
3852
3752 fcport->d_id.b24 = new_fcport->d_id.b24; 3853 fcport->d_id.b24 = new_fcport->d_id.b24;
3753 fcport->flags |= FCF_LOGIN_NEEDED; 3854 fcport->flags |= FCF_LOGIN_NEEDED;
3754 if (fcport->loop_id != FC_NO_LOOP_ID && 3855 if (fcport->loop_id != FC_NO_LOOP_ID &&
@@ -3768,6 +3869,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3768 if (found) 3869 if (found)
3769 continue; 3870 continue;
3770 /* If device was not in our fcports list, then add it. */ 3871 /* If device was not in our fcports list, then add it. */
3872 new_fcport->scan_state = QLA_FCPORT_FOUND;
3771 list_add_tail(&new_fcport->list, new_fcports); 3873 list_add_tail(&new_fcport->list, new_fcports);
3772 3874
3773 /* Allocate a new replacement fcport. */ 3875 /* Allocate a new replacement fcport. */
@@ -4188,6 +4290,14 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
4188 atomic_read(&fcport->state) != FCS_UNCONFIGURED) { 4290 atomic_read(&fcport->state) != FCS_UNCONFIGURED) {
4189 spin_unlock_irqrestore(&ha->vport_slock, flags); 4291 spin_unlock_irqrestore(&ha->vport_slock, flags);
4190 qla2x00_rport_del(fcport); 4292 qla2x00_rport_del(fcport);
4293
4294 /*
4295 * Release the target mode FC NEXUS in
4296 * qla_target.c, if target mod is enabled.
4297 */
4298 qlt_fc_port_deleted(vha, fcport,
4299 base_vha->total_fcport_update_gen);
4300
4191 spin_lock_irqsave(&ha->vport_slock, flags); 4301 spin_lock_irqsave(&ha->vport_slock, flags);
4192 } 4302 }
4193 } 4303 }
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index a1ab25fca874..6f02b26a35cf 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1943,6 +1943,9 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
1943 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; 1943 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1944 logio->control_flags = 1944 logio->control_flags =
1945 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO); 1945 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
1946 if (!sp->fcport->tgt_session ||
1947 !sp->fcport->tgt_session->keep_nport_handle)
1948 logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
1946 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); 1949 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
1947 logio->port_id[0] = sp->fcport->d_id.b.al_pa; 1950 logio->port_id[0] = sp->fcport->d_id.b.al_pa;
1948 logio->port_id[1] = sp->fcport->d_id.b.area; 1951 logio->port_id[1] = sp->fcport->d_id.b.area;
@@ -2797,10 +2800,10 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
2797 handle = req->current_outstanding_cmd; 2800 handle = req->current_outstanding_cmd;
2798 for (index = 1; index < req->num_outstanding_cmds; index++) { 2801 for (index = 1; index < req->num_outstanding_cmds; index++) {
2799 handle++; 2802 handle++;
2800 if (handle == req->num_outstanding_cmds) 2803 if (handle == req->num_outstanding_cmds)
2801 handle = 1; 2804 handle = 1;
2802 if (!req->outstanding_cmds[handle]) 2805 if (!req->outstanding_cmds[handle])
2803 break; 2806 break;
2804 } 2807 }
2805 2808
2806 if (index == req->num_outstanding_cmds) { 2809 if (index == req->num_outstanding_cmds) {
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6dc14cd782b2..5559d5e75bbf 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1580,7 +1580,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
1580 ql_log(ql_log_warn, fcport->vha, 0x503c, 1580 ql_log(ql_log_warn, fcport->vha, 0x503c,
1581 "Async-%s error - hdl=%x response(%x).\n", 1581 "Async-%s error - hdl=%x response(%x).\n",
1582 type, sp->handle, sts->data[3]); 1582 type, sp->handle, sts->data[3]);
1583 iocb->u.tmf.data = QLA_FUNCTION_FAILED; 1583 iocb->u.tmf.data = QLA_FUNCTION_FAILED;
1584 } 1584 }
1585 } 1585 }
1586 1586
@@ -1979,7 +1979,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
1979 rval = EXT_STATUS_ERR; 1979 rval = EXT_STATUS_ERR;
1980 break; 1980 break;
1981 } 1981 }
1982 bsg_job->reply->reply_payload_rcv_len = 0; 1982 bsg_job->reply->reply_payload_rcv_len = 0;
1983 1983
1984done: 1984done:
1985 /* Return the vendor specific reply to API */ 1985 /* Return the vendor specific reply to API */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 02b1c1c5355b..b2f713ad9034 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2415,7 +2415,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
2415 *orig_iocb_cnt = mcp->mb[10]; 2415 *orig_iocb_cnt = mcp->mb[10];
2416 if (vha->hw->flags.npiv_supported && max_npiv_vports) 2416 if (vha->hw->flags.npiv_supported && max_npiv_vports)
2417 *max_npiv_vports = mcp->mb[11]; 2417 *max_npiv_vports = mcp->mb[11];
2418 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs) 2418 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) ||
2419 IS_QLA27XX(vha->hw)) && max_fcfs)
2419 *max_fcfs = mcp->mb[12]; 2420 *max_fcfs = mcp->mb[12];
2420 } 2421 }
2421 2422
@@ -3898,7 +3899,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
3898 spin_lock_irqsave(&ha->hardware_lock, flags); 3899 spin_lock_irqsave(&ha->hardware_lock, flags);
3899 if (!(rsp->options & BIT_0)) { 3900 if (!(rsp->options & BIT_0)) {
3900 WRT_REG_DWORD(rsp->rsp_q_out, 0); 3901 WRT_REG_DWORD(rsp->rsp_q_out, 0);
3901 if (!IS_QLA83XX(ha)) 3902 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
3902 WRT_REG_DWORD(rsp->rsp_q_in, 0); 3903 WRT_REG_DWORD(rsp->rsp_q_in, 0);
3903 } 3904 }
3904 3905
@@ -5345,7 +5346,7 @@ qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5345 mbx_cmd_t *mcp = &mc; 5346 mbx_cmd_t *mcp = &mc;
5346 struct qla_hw_data *ha = vha->hw; 5347 struct qla_hw_data *ha = vha->hw;
5347 5348
5348 if (!IS_QLA83XX(ha)) 5349 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
5349 return QLA_FUNCTION_FAILED; 5350 return QLA_FUNCTION_FAILED;
5350 5351
5351 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__); 5352 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 7d2b18f2675c..1620b0ec977b 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1843,7 +1843,7 @@ qla82xx_set_product_offset(struct qla_hw_data *ha)
1843 1843
1844 ptab_desc = qla82xx_get_table_desc(unirom, 1844 ptab_desc = qla82xx_get_table_desc(unirom,
1845 QLA82XX_URI_DIR_SECT_PRODUCT_TBL); 1845 QLA82XX_URI_DIR_SECT_PRODUCT_TBL);
1846 if (!ptab_desc) 1846 if (!ptab_desc)
1847 return -1; 1847 return -1;
1848 1848
1849 entries = cpu_to_le32(ptab_desc->num_entries); 1849 entries = cpu_to_le32(ptab_desc->num_entries);
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
index ed4d6b6b53e3..000c57e4d033 100644
--- a/drivers/scsi/qla2xxx/qla_nx2.c
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -397,11 +397,11 @@ qla8044_idc_lock(struct qla_hw_data *ha)
397 * has the lock, wait for 2secs 397 * has the lock, wait for 2secs
398 * and retry 398 * and retry
399 */ 399 */
400 ql_dbg(ql_dbg_p3p, vha, 0xb08a, 400 ql_dbg(ql_dbg_p3p, vha, 0xb08a,
401 "%s: IDC lock Recovery by %d " 401 "%s: IDC lock Recovery by %d "
402 "failed, Retrying timeout\n", __func__, 402 "failed, Retrying timeout\n", __func__,
403 ha->portnum); 403 ha->portnum);
404 timeout = 0; 404 timeout = 0;
405 } 405 }
406 } 406 }
407 msleep(QLA8044_DRV_LOCK_MSLEEP); 407 msleep(QLA8044_DRV_LOCK_MSLEEP);
@@ -3141,8 +3141,7 @@ qla8044_minidump_process_rdmdio(struct scsi_qla_host *vha,
3141 goto error; 3141 goto error;
3142 3142
3143 addr7 = addr2 - (4 * stride1); 3143 addr7 = addr2 - (4 * stride1);
3144 data = qla8044_ipmdio_rd_reg(vha, addr1, addr3, 3144 data = qla8044_ipmdio_rd_reg(vha, addr1, addr3, mask, addr7);
3145 mask, addr7);
3146 if (data == -1) 3145 if (data == -1)
3147 goto error; 3146 goto error;
3148 3147
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7462dd70b150..8a5cac8448c7 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2504,6 +2504,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2504 ha->mbx_count = MAILBOX_REGISTER_COUNT; 2504 ha->mbx_count = MAILBOX_REGISTER_COUNT;
2505 req_length = REQUEST_ENTRY_CNT_24XX; 2505 req_length = REQUEST_ENTRY_CNT_24XX;
2506 rsp_length = RESPONSE_ENTRY_CNT_2300; 2506 rsp_length = RESPONSE_ENTRY_CNT_2300;
2507 ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
2507 ha->max_loop_id = SNS_LAST_LOOP_ID_2300; 2508 ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
2508 ha->init_cb_size = sizeof(struct mid_init_cb_81xx); 2509 ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
2509 ha->gid_list_info_size = 8; 2510 ha->gid_list_info_size = 8;
@@ -3229,11 +3230,15 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
3229 spin_lock_irqsave(vha->host->host_lock, flags); 3230 spin_lock_irqsave(vha->host->host_lock, flags);
3230 fcport->drport = rport; 3231 fcport->drport = rport;
3231 spin_unlock_irqrestore(vha->host->host_lock, flags); 3232 spin_unlock_irqrestore(vha->host->host_lock, flags);
3233 qlt_do_generation_tick(vha, &base_vha->total_fcport_update_gen);
3232 set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); 3234 set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
3233 qla2xxx_wake_dpc(base_vha); 3235 qla2xxx_wake_dpc(base_vha);
3234 } else { 3236 } else {
3235 fc_remote_port_delete(rport); 3237 int now;
3236 qlt_fc_port_deleted(vha, fcport); 3238 if (rport)
3239 fc_remote_port_delete(rport);
3240 qlt_do_generation_tick(vha, &now);
3241 qlt_fc_port_deleted(vha, fcport, now);
3237 } 3242 }
3238} 3243}
3239 3244
@@ -3763,8 +3768,11 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
3763 INIT_LIST_HEAD(&vha->vp_fcports); 3768 INIT_LIST_HEAD(&vha->vp_fcports);
3764 INIT_LIST_HEAD(&vha->work_list); 3769 INIT_LIST_HEAD(&vha->work_list);
3765 INIT_LIST_HEAD(&vha->list); 3770 INIT_LIST_HEAD(&vha->list);
3771 INIT_LIST_HEAD(&vha->qla_cmd_list);
3772 INIT_LIST_HEAD(&vha->qla_sess_op_cmd_list);
3766 3773
3767 spin_lock_init(&vha->work_lock); 3774 spin_lock_init(&vha->work_lock);
3775 spin_lock_init(&vha->cmd_list_lock);
3768 3776
3769 sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); 3777 sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
3770 ql_dbg(ql_dbg_init, vha, 0x0041, 3778 ql_dbg(ql_dbg_init, vha, 0x0041,
@@ -4418,7 +4426,10 @@ retry_lock2:
4418void 4426void
4419qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id) 4427qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
4420{ 4428{
4421 uint16_t options = (requester_id << 15) | BIT_7, retry; 4429#if 0
4430 uint16_t options = (requester_id << 15) | BIT_7;
4431#endif
4432 uint16_t retry;
4422 uint32_t data; 4433 uint32_t data;
4423 struct qla_hw_data *ha = base_vha->hw; 4434 struct qla_hw_data *ha = base_vha->hw;
4424 4435
@@ -4454,6 +4465,7 @@ retry_unlock:
4454 4465
4455 return; 4466 return;
4456 4467
4468#if 0
4457 /* XXX: IDC-unlock implementation using access-control mbx */ 4469 /* XXX: IDC-unlock implementation using access-control mbx */
4458 retry = 0; 4470 retry = 0;
4459retry_unlock2: 4471retry_unlock2:
@@ -4469,6 +4481,7 @@ retry_unlock2:
4469 } 4481 }
4470 4482
4471 return; 4483 return;
4484#endif
4472} 4485}
4473 4486
4474int 4487int
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 028e8c8a7de9..2feb5f38edcd 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -1697,7 +1697,7 @@ qla83xx_select_led_port(struct qla_hw_data *ha)
1697{ 1697{
1698 uint32_t led_select_value = 0; 1698 uint32_t led_select_value = 0;
1699 1699
1700 if (!IS_QLA83XX(ha)) 1700 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
1701 goto out; 1701 goto out;
1702 1702
1703 if (ha->port_no == 0) 1703 if (ha->port_no == 0)
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index fe8a8d157e22..58651ecbd88c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -113,6 +113,11 @@ static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
113static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, 113static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
114 struct atio_from_isp *atio, uint16_t status, int qfull); 114 struct atio_from_isp *atio, uint16_t status, int qfull);
115static void qlt_disable_vha(struct scsi_qla_host *vha); 115static void qlt_disable_vha(struct scsi_qla_host *vha);
116static void qlt_clear_tgt_db(struct qla_tgt *tgt);
117static void qlt_send_notify_ack(struct scsi_qla_host *vha,
118 struct imm_ntfy_from_isp *ntfy,
119 uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
120 uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan);
116/* 121/*
117 * Global Variables 122 * Global Variables
118 */ 123 */
@@ -122,6 +127,16 @@ static struct workqueue_struct *qla_tgt_wq;
122static DEFINE_MUTEX(qla_tgt_mutex); 127static DEFINE_MUTEX(qla_tgt_mutex);
123static LIST_HEAD(qla_tgt_glist); 128static LIST_HEAD(qla_tgt_glist);
124 129
130/* This API intentionally takes dest as a parameter, rather than returning
131 * int value to avoid caller forgetting to issue wmb() after the store */
132void qlt_do_generation_tick(struct scsi_qla_host *vha, int *dest)
133{
134 scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);
135 *dest = atomic_inc_return(&base_vha->generation_tick);
136 /* memory barrier */
137 wmb();
138}
139
125/* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */ 140/* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */
126static struct qla_tgt_sess *qlt_find_sess_by_port_name( 141static struct qla_tgt_sess *qlt_find_sess_by_port_name(
127 struct qla_tgt *tgt, 142 struct qla_tgt *tgt,
@@ -381,14 +396,73 @@ static void qlt_free_session_done(struct work_struct *work)
381 struct qla_tgt *tgt = sess->tgt; 396 struct qla_tgt *tgt = sess->tgt;
382 struct scsi_qla_host *vha = sess->vha; 397 struct scsi_qla_host *vha = sess->vha;
383 struct qla_hw_data *ha = vha->hw; 398 struct qla_hw_data *ha = vha->hw;
399 unsigned long flags;
400 bool logout_started = false;
401 fc_port_t fcport;
402
403 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084,
404 "%s: se_sess %p / sess %p from port %8phC loop_id %#04x"
405 " s_id %02x:%02x:%02x logout %d keep %d plogi %d\n",
406 __func__, sess->se_sess, sess, sess->port_name, sess->loop_id,
407 sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
408 sess->logout_on_delete, sess->keep_nport_handle,
409 sess->plogi_ack_needed);
384 410
385 BUG_ON(!tgt); 411 BUG_ON(!tgt);
412
413 if (sess->logout_on_delete) {
414 int rc;
415
416 memset(&fcport, 0, sizeof(fcport));
417 fcport.loop_id = sess->loop_id;
418 fcport.d_id = sess->s_id;
419 memcpy(fcport.port_name, sess->port_name, WWN_SIZE);
420 fcport.vha = vha;
421 fcport.tgt_session = sess;
422
423 rc = qla2x00_post_async_logout_work(vha, &fcport, NULL);
424 if (rc != QLA_SUCCESS)
425 ql_log(ql_log_warn, vha, 0xf085,
426 "Schedule logo failed sess %p rc %d\n",
427 sess, rc);
428 else
429 logout_started = true;
430 }
431
386 /* 432 /*
387 * Release the target session for FC Nexus from fabric module code. 433 * Release the target session for FC Nexus from fabric module code.
388 */ 434 */
389 if (sess->se_sess != NULL) 435 if (sess->se_sess != NULL)
390 ha->tgt.tgt_ops->free_session(sess); 436 ha->tgt.tgt_ops->free_session(sess);
391 437
438 if (logout_started) {
439 bool traced = false;
440
441 while (!ACCESS_ONCE(sess->logout_completed)) {
442 if (!traced) {
443 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086,
444 "%s: waiting for sess %p logout\n",
445 __func__, sess);
446 traced = true;
447 }
448 msleep(100);
449 }
450
451 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf087,
452 "%s: sess %p logout completed\n",
453 __func__, sess);
454 }
455
456 spin_lock_irqsave(&ha->hardware_lock, flags);
457
458 if (sess->plogi_ack_needed)
459 qlt_send_notify_ack(vha, &sess->tm_iocb,
460 0, 0, 0, 0, 0, 0);
461
462 list_del(&sess->sess_list_entry);
463
464 spin_unlock_irqrestore(&ha->hardware_lock, flags);
465
392 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, 466 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
393 "Unregistration of sess %p finished\n", sess); 467 "Unregistration of sess %p finished\n", sess);
394 468
@@ -409,9 +483,9 @@ void qlt_unreg_sess(struct qla_tgt_sess *sess)
409 483
410 vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); 484 vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
411 485
412 list_del(&sess->sess_list_entry); 486 if (!list_empty(&sess->del_list_entry))
413 if (sess->deleted) 487 list_del_init(&sess->del_list_entry);
414 list_del(&sess->del_list_entry); 488 sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
415 489
416 INIT_WORK(&sess->free_work, qlt_free_session_done); 490 INIT_WORK(&sess->free_work, qlt_free_session_done);
417 schedule_work(&sess->free_work); 491 schedule_work(&sess->free_work);
@@ -431,10 +505,10 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
431 505
432 loop_id = le16_to_cpu(n->u.isp24.nport_handle); 506 loop_id = le16_to_cpu(n->u.isp24.nport_handle);
433 if (loop_id == 0xFFFF) { 507 if (loop_id == 0xFFFF) {
434#if 0 /* FIXME: Re-enable Global event handling.. */
435 /* Global event */ 508 /* Global event */
436 atomic_inc(&ha->tgt.qla_tgt->tgt_global_resets_count); 509 atomic_inc(&vha->vha_tgt.qla_tgt->tgt_global_resets_count);
437 qlt_clear_tgt_db(ha->tgt.qla_tgt); 510 qlt_clear_tgt_db(vha->vha_tgt.qla_tgt);
511#if 0 /* FIXME: do we need to choose a session here? */
438 if (!list_empty(&ha->tgt.qla_tgt->sess_list)) { 512 if (!list_empty(&ha->tgt.qla_tgt->sess_list)) {
439 sess = list_entry(ha->tgt.qla_tgt->sess_list.next, 513 sess = list_entry(ha->tgt.qla_tgt->sess_list.next,
440 typeof(*sess), sess_list_entry); 514 typeof(*sess), sess_list_entry);
@@ -489,27 +563,38 @@ static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
489 struct qla_tgt *tgt = sess->tgt; 563 struct qla_tgt *tgt = sess->tgt;
490 uint32_t dev_loss_tmo = tgt->ha->port_down_retry_count + 5; 564 uint32_t dev_loss_tmo = tgt->ha->port_down_retry_count + 5;
491 565
492 if (sess->deleted) 566 if (sess->deleted) {
493 return; 567 /* Upgrade to unconditional deletion in case it was temporary */
568 if (immediate && sess->deleted == QLA_SESS_DELETION_PENDING)
569 list_del(&sess->del_list_entry);
570 else
571 return;
572 }
494 573
495 ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, 574 ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
496 "Scheduling sess %p for deletion\n", sess); 575 "Scheduling sess %p for deletion\n", sess);
497 list_add_tail(&sess->del_list_entry, &tgt->del_sess_list);
498 sess->deleted = 1;
499 576
500 if (immediate) 577 if (immediate) {
501 dev_loss_tmo = 0; 578 dev_loss_tmo = 0;
579 sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
580 list_add(&sess->del_list_entry, &tgt->del_sess_list);
581 } else {
582 sess->deleted = QLA_SESS_DELETION_PENDING;
583 list_add_tail(&sess->del_list_entry, &tgt->del_sess_list);
584 }
502 585
503 sess->expires = jiffies + dev_loss_tmo * HZ; 586 sess->expires = jiffies + dev_loss_tmo * HZ;
504 587
505 ql_dbg(ql_dbg_tgt, sess->vha, 0xe048, 588 ql_dbg(ql_dbg_tgt, sess->vha, 0xe048,
506 "qla_target(%d): session for port %8phC (loop ID %d) scheduled for " 589 "qla_target(%d): session for port %8phC (loop ID %d s_id %02x:%02x:%02x)"
507 "deletion in %u secs (expires: %lu) immed: %d\n", 590 " scheduled for deletion in %u secs (expires: %lu) immed: %d, logout: %d, gen: %#x\n",
508 sess->vha->vp_idx, sess->port_name, sess->loop_id, dev_loss_tmo, 591 sess->vha->vp_idx, sess->port_name, sess->loop_id,
509 sess->expires, immediate); 592 sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
593 dev_loss_tmo, sess->expires, immediate, sess->logout_on_delete,
594 sess->generation);
510 595
511 if (immediate) 596 if (immediate)
512 schedule_delayed_work(&tgt->sess_del_work, 0); 597 mod_delayed_work(system_wq, &tgt->sess_del_work, 0);
513 else 598 else
514 schedule_delayed_work(&tgt->sess_del_work, 599 schedule_delayed_work(&tgt->sess_del_work,
515 sess->expires - jiffies); 600 sess->expires - jiffies);
@@ -578,9 +663,9 @@ out_free_id_list:
578/* ha->hardware_lock supposed to be held on entry */ 663/* ha->hardware_lock supposed to be held on entry */
579static void qlt_undelete_sess(struct qla_tgt_sess *sess) 664static void qlt_undelete_sess(struct qla_tgt_sess *sess)
580{ 665{
581 BUG_ON(!sess->deleted); 666 BUG_ON(sess->deleted != QLA_SESS_DELETION_PENDING);
582 667
583 list_del(&sess->del_list_entry); 668 list_del_init(&sess->del_list_entry);
584 sess->deleted = 0; 669 sess->deleted = 0;
585} 670}
586 671
@@ -599,7 +684,9 @@ static void qlt_del_sess_work_fn(struct delayed_work *work)
599 del_list_entry); 684 del_list_entry);
600 elapsed = jiffies; 685 elapsed = jiffies;
601 if (time_after_eq(elapsed, sess->expires)) { 686 if (time_after_eq(elapsed, sess->expires)) {
602 qlt_undelete_sess(sess); 687 /* No turning back */
688 list_del_init(&sess->del_list_entry);
689 sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
603 690
604 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, 691 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004,
605 "Timeout: sess %p about to be deleted\n", 692 "Timeout: sess %p about to be deleted\n",
@@ -643,6 +730,13 @@ static struct qla_tgt_sess *qlt_create_sess(
643 fcport->d_id.b.al_pa, fcport->d_id.b.area, 730 fcport->d_id.b.al_pa, fcport->d_id.b.area,
644 fcport->loop_id); 731 fcport->loop_id);
645 732
733 /* Cannot undelete at this point */
734 if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
735 spin_unlock_irqrestore(&ha->hardware_lock,
736 flags);
737 return NULL;
738 }
739
646 if (sess->deleted) 740 if (sess->deleted)
647 qlt_undelete_sess(sess); 741 qlt_undelete_sess(sess);
648 742
@@ -652,6 +746,9 @@ static struct qla_tgt_sess *qlt_create_sess(
652 746
653 if (sess->local && !local) 747 if (sess->local && !local)
654 sess->local = 0; 748 sess->local = 0;
749
750 qlt_do_generation_tick(vha, &sess->generation);
751
655 spin_unlock_irqrestore(&ha->hardware_lock, flags); 752 spin_unlock_irqrestore(&ha->hardware_lock, flags);
656 753
657 return sess; 754 return sess;
@@ -673,6 +770,14 @@ static struct qla_tgt_sess *qlt_create_sess(
673 sess->s_id = fcport->d_id; 770 sess->s_id = fcport->d_id;
674 sess->loop_id = fcport->loop_id; 771 sess->loop_id = fcport->loop_id;
675 sess->local = local; 772 sess->local = local;
773 INIT_LIST_HEAD(&sess->del_list_entry);
774
775 /* Under normal circumstances we want to logout from firmware when
776 * session eventually ends and release corresponding nport handle.
777 * In the exception cases (e.g. when new PLOGI is waiting) corresponding
778 * code will adjust these flags as necessary. */
779 sess->logout_on_delete = 1;
780 sess->keep_nport_handle = 0;
676 781
677 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006, 782 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006,
678 "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n", 783 "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n",
@@ -705,6 +810,7 @@ static struct qla_tgt_sess *qlt_create_sess(
705 spin_lock_irqsave(&ha->hardware_lock, flags); 810 spin_lock_irqsave(&ha->hardware_lock, flags);
706 list_add_tail(&sess->sess_list_entry, &vha->vha_tgt.qla_tgt->sess_list); 811 list_add_tail(&sess->sess_list_entry, &vha->vha_tgt.qla_tgt->sess_list);
707 vha->vha_tgt.qla_tgt->sess_count++; 812 vha->vha_tgt.qla_tgt->sess_count++;
813 qlt_do_generation_tick(vha, &sess->generation);
708 spin_unlock_irqrestore(&ha->hardware_lock, flags); 814 spin_unlock_irqrestore(&ha->hardware_lock, flags);
709 815
710 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b, 816 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b,
@@ -718,7 +824,7 @@ static struct qla_tgt_sess *qlt_create_sess(
718} 824}
719 825
720/* 826/*
721 * Called from drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() 827 * Called from qla2x00_reg_remote_port()
722 */ 828 */
723void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) 829void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
724{ 830{
@@ -750,6 +856,10 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
750 mutex_unlock(&vha->vha_tgt.tgt_mutex); 856 mutex_unlock(&vha->vha_tgt.tgt_mutex);
751 857
752 spin_lock_irqsave(&ha->hardware_lock, flags); 858 spin_lock_irqsave(&ha->hardware_lock, flags);
859 } else if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
860 /* Point of no return */
861 spin_unlock_irqrestore(&ha->hardware_lock, flags);
862 return;
753 } else { 863 } else {
754 kref_get(&sess->se_sess->sess_kref); 864 kref_get(&sess->se_sess->sess_kref);
755 865
@@ -780,27 +890,36 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
780 spin_unlock_irqrestore(&ha->hardware_lock, flags); 890 spin_unlock_irqrestore(&ha->hardware_lock, flags);
781} 891}
782 892
783void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) 893/*
894 * max_gen - specifies maximum session generation
895 * at which this deletion requestion is still valid
896 */
897void
898qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen)
784{ 899{
785 struct qla_hw_data *ha = vha->hw;
786 struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 900 struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
787 struct qla_tgt_sess *sess; 901 struct qla_tgt_sess *sess;
788 unsigned long flags;
789 902
790 if (!vha->hw->tgt.tgt_ops) 903 if (!vha->hw->tgt.tgt_ops)
791 return; 904 return;
792 905
793 if (!tgt || (fcport->port_type != FCT_INITIATOR)) 906 if (!tgt)
794 return; 907 return;
795 908
796 spin_lock_irqsave(&ha->hardware_lock, flags);
797 if (tgt->tgt_stop) { 909 if (tgt->tgt_stop) {
798 spin_unlock_irqrestore(&ha->hardware_lock, flags);
799 return; 910 return;
800 } 911 }
801 sess = qlt_find_sess_by_port_name(tgt, fcport->port_name); 912 sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
802 if (!sess) { 913 if (!sess) {
803 spin_unlock_irqrestore(&ha->hardware_lock, flags); 914 return;
915 }
916
917 if (max_gen - sess->generation < 0) {
918 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf092,
919 "Ignoring stale deletion request for se_sess %p / sess %p"
920 " for port %8phC, req_gen %d, sess_gen %d\n",
921 sess->se_sess, sess, sess->port_name, max_gen,
922 sess->generation);
804 return; 923 return;
805 } 924 }
806 925
@@ -808,7 +927,6 @@ void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
808 927
809 sess->local = 1; 928 sess->local = 1;
810 qlt_schedule_sess_for_deletion(sess, false); 929 qlt_schedule_sess_for_deletion(sess, false);
811 spin_unlock_irqrestore(&ha->hardware_lock, flags);
812} 930}
813 931
814static inline int test_tgt_sess_count(struct qla_tgt *tgt) 932static inline int test_tgt_sess_count(struct qla_tgt *tgt)
@@ -1175,6 +1293,70 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
1175 FCP_TMF_CMPL, true); 1293 FCP_TMF_CMPL, true);
1176} 1294}
1177 1295
1296static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
1297{
1298 struct qla_tgt_sess_op *op;
1299 struct qla_tgt_cmd *cmd;
1300
1301 spin_lock(&vha->cmd_list_lock);
1302
1303 list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
1304 if (tag == op->atio.u.isp24.exchange_addr) {
1305 op->aborted = true;
1306 spin_unlock(&vha->cmd_list_lock);
1307 return 1;
1308 }
1309 }
1310
1311 list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
1312 if (tag == cmd->atio.u.isp24.exchange_addr) {
1313 cmd->state = QLA_TGT_STATE_ABORTED;
1314 spin_unlock(&vha->cmd_list_lock);
1315 return 1;
1316 }
1317 }
1318
1319 spin_unlock(&vha->cmd_list_lock);
1320 return 0;
1321}
1322
1323/* drop cmds for the given lun
1324 * XXX only looks for cmds on the port through which lun reset was recieved
1325 * XXX does not go through the list of other port (which may have cmds
1326 * for the same lun)
1327 */
1328static void abort_cmds_for_lun(struct scsi_qla_host *vha,
1329 uint32_t lun, uint8_t *s_id)
1330{
1331 struct qla_tgt_sess_op *op;
1332 struct qla_tgt_cmd *cmd;
1333 uint32_t key;
1334
1335 key = sid_to_key(s_id);
1336 spin_lock(&vha->cmd_list_lock);
1337 list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
1338 uint32_t op_key;
1339 uint32_t op_lun;
1340
1341 op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
1342 op_lun = scsilun_to_int(
1343 (struct scsi_lun *)&op->atio.u.isp24.fcp_cmnd.lun);
1344 if (op_key == key && op_lun == lun)
1345 op->aborted = true;
1346 }
1347 list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
1348 uint32_t cmd_key;
1349 uint32_t cmd_lun;
1350
1351 cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
1352 cmd_lun = scsilun_to_int(
1353 (struct scsi_lun *)&cmd->atio.u.isp24.fcp_cmnd.lun);
1354 if (cmd_key == key && cmd_lun == lun)
1355 cmd->state = QLA_TGT_STATE_ABORTED;
1356 }
1357 spin_unlock(&vha->cmd_list_lock);
1358}
1359
1178/* ha->hardware_lock supposed to be held on entry */ 1360/* ha->hardware_lock supposed to be held on entry */
1179static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, 1361static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
1180 struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess) 1362 struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess)
@@ -1191,7 +1373,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
1191 list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) { 1373 list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
1192 struct qla_tgt_cmd *cmd = 1374 struct qla_tgt_cmd *cmd =
1193 container_of(se_cmd, struct qla_tgt_cmd, se_cmd); 1375 container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
1194 if (cmd->tag == abts->exchange_addr_to_abort) { 1376 if (se_cmd->tag == abts->exchange_addr_to_abort) {
1195 lun = cmd->unpacked_lun; 1377 lun = cmd->unpacked_lun;
1196 found_lun = true; 1378 found_lun = true;
1197 break; 1379 break;
@@ -1199,8 +1381,19 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
1199 } 1381 }
1200 spin_unlock(&se_sess->sess_cmd_lock); 1382 spin_unlock(&se_sess->sess_cmd_lock);
1201 1383
1202 if (!found_lun) 1384 /* cmd not in LIO lists, look in qla list */
1203 return -ENOENT; 1385 if (!found_lun) {
1386 if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
1387 /* send TASK_ABORT response immediately */
1388 qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
1389 return 0;
1390 } else {
1391 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
1392 "unable to find cmd in driver or LIO for tag 0x%x\n",
1393 abts->exchange_addr_to_abort);
1394 return -ENOENT;
1395 }
1396 }
1204 1397
1205 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f, 1398 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
1206 "qla_target(%d): task abort (tag=%d)\n", 1399 "qla_target(%d): task abort (tag=%d)\n",
@@ -1284,6 +1477,11 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
1284 return; 1477 return;
1285 } 1478 }
1286 1479
1480 if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
1481 qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
1482 return;
1483 }
1484
1287 rc = __qlt_24xx_handle_abts(vha, abts, sess); 1485 rc = __qlt_24xx_handle_abts(vha, abts, sess);
1288 if (rc != 0) { 1486 if (rc != 0) {
1289 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054, 1487 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054,
@@ -1726,21 +1924,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
1726 struct qla_hw_data *ha = vha->hw; 1924 struct qla_hw_data *ha = vha->hw;
1727 struct se_cmd *se_cmd = &cmd->se_cmd; 1925 struct se_cmd *se_cmd = &cmd->se_cmd;
1728 1926
1729 if (unlikely(cmd->aborted)) {
1730 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
1731 "qla_target(%d): terminating exchange "
1732 "for aborted cmd=%p (se_cmd=%p, tag=%d)", vha->vp_idx, cmd,
1733 se_cmd, cmd->tag);
1734
1735 cmd->state = QLA_TGT_STATE_ABORTED;
1736 cmd->cmd_flags |= BIT_6;
1737
1738 qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);
1739
1740 /* !! At this point cmd could be already freed !! */
1741 return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED;
1742 }
1743
1744 prm->cmd = cmd; 1927 prm->cmd = cmd;
1745 prm->tgt = tgt; 1928 prm->tgt = tgt;
1746 prm->rq_result = scsi_status; 1929 prm->rq_result = scsi_status;
@@ -1765,18 +1948,17 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
1765 if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { 1948 if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
1766 prm->residual = se_cmd->residual_count; 1949 prm->residual = se_cmd->residual_count;
1767 ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x305c, 1950 ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x305c,
1768 "Residual underflow: %d (tag %d, " 1951 "Residual underflow: %d (tag %lld, op %x, bufflen %d, rq_result %x)\n",
1769 "op %x, bufflen %d, rq_result %x)\n", prm->residual, 1952 prm->residual, se_cmd->tag,
1770 cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, 1953 se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0,
1771 cmd->bufflen, prm->rq_result); 1954 cmd->bufflen, prm->rq_result);
1772 prm->rq_result |= SS_RESIDUAL_UNDER; 1955 prm->rq_result |= SS_RESIDUAL_UNDER;
1773 } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { 1956 } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
1774 prm->residual = se_cmd->residual_count; 1957 prm->residual = se_cmd->residual_count;
1775 ql_dbg(ql_dbg_io, vha, 0x305d, 1958 ql_dbg(ql_dbg_io, vha, 0x305d,
1776 "Residual overflow: %d (tag %d, " 1959 "Residual overflow: %d (tag %lld, op %x, bufflen %d, rq_result %x)\n",
1777 "op %x, bufflen %d, rq_result %x)\n", prm->residual, 1960 prm->residual, se_cmd->tag, se_cmd->t_task_cdb ?
1778 cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, 1961 se_cmd->t_task_cdb[0] : 0, cmd->bufflen, prm->rq_result);
1779 cmd->bufflen, prm->rq_result);
1780 prm->rq_result |= SS_RESIDUAL_OVER; 1962 prm->rq_result |= SS_RESIDUAL_OVER;
1781 } 1963 }
1782 1964
@@ -1849,7 +2031,7 @@ static void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type)
1849 == 50) { 2031 == 50) {
1850 *xmit_type &= ~QLA_TGT_XMIT_STATUS; 2032 *xmit_type &= ~QLA_TGT_XMIT_STATUS;
1851 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf015, 2033 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf015,
1852 "Dropping cmd %p (tag %d) status", cmd, cmd->tag); 2034 "Dropping cmd %p (tag %d) status", cmd, se_cmd->tag);
1853 } 2035 }
1854#endif 2036#endif
1855 /* 2037 /*
@@ -1873,7 +2055,7 @@ static void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type)
1873 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf016, 2055 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf016,
1874 "Cutting cmd %p (tag %d) buffer" 2056 "Cutting cmd %p (tag %d) buffer"
1875 " tail to len %d, sg_cnt %d (cmd->bufflen %d," 2057 " tail to len %d, sg_cnt %d (cmd->bufflen %d,"
1876 " cmd->sg_cnt %d)", cmd, cmd->tag, tot_len, leave, 2058 " cmd->sg_cnt %d)", cmd, se_cmd->tag, tot_len, leave,
1877 cmd->bufflen, cmd->sg_cnt); 2059 cmd->bufflen, cmd->sg_cnt);
1878 2060
1879 cmd->bufflen = tot_len; 2061 cmd->bufflen = tot_len;
@@ -1885,13 +2067,13 @@ static void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type)
1885 2067
1886 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf017, 2068 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf017,
1887 "Cutting cmd %p (tag %d) buffer head " 2069 "Cutting cmd %p (tag %d) buffer head "
1888 "to offset %d (cmd->bufflen %d)", cmd, cmd->tag, offset, 2070 "to offset %d (cmd->bufflen %d)", cmd, se_cmd->tag, offset,
1889 cmd->bufflen); 2071 cmd->bufflen);
1890 if (offset == 0) 2072 if (offset == 0)
1891 *xmit_type &= ~QLA_TGT_XMIT_DATA; 2073 *xmit_type &= ~QLA_TGT_XMIT_DATA;
1892 else if (qlt_set_data_offset(cmd, offset)) { 2074 else if (qlt_set_data_offset(cmd, offset)) {
1893 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf018, 2075 ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf018,
1894 "qlt_set_data_offset() failed (tag %d)", cmd->tag); 2076 "qlt_set_data_offset() failed (tag %d)", se_cmd->tag);
1895 } 2077 }
1896 } 2078 }
1897} 2079}
@@ -2303,6 +2485,19 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2303 unsigned long flags = 0; 2485 unsigned long flags = 0;
2304 int res; 2486 int res;
2305 2487
2488 spin_lock_irqsave(&ha->hardware_lock, flags);
2489 if (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
2490 cmd->state = QLA_TGT_STATE_PROCESSED;
2491 if (cmd->sess->logout_completed)
2492 /* no need to terminate. FW already freed exchange. */
2493 qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
2494 else
2495 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1);
2496 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2497 return 0;
2498 }
2499 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2500
2306 memset(&prm, 0, sizeof(prm)); 2501 memset(&prm, 0, sizeof(prm));
2307 qlt_check_srr_debug(cmd, &xmit_type); 2502 qlt_check_srr_debug(cmd, &xmit_type);
2308 2503
@@ -2315,9 +2510,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2315 res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, 2510 res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
2316 &full_req_cnt); 2511 &full_req_cnt);
2317 if (unlikely(res != 0)) { 2512 if (unlikely(res != 0)) {
2318 if (res == QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED)
2319 return 0;
2320
2321 return res; 2513 return res;
2322 } 2514 }
2323 2515
@@ -2347,9 +2539,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2347 res = qlt_build_ctio_crc2_pkt(&prm, vha); 2539 res = qlt_build_ctio_crc2_pkt(&prm, vha);
2348 else 2540 else
2349 res = qlt_24xx_build_ctio_pkt(&prm, vha); 2541 res = qlt_24xx_build_ctio_pkt(&prm, vha);
2350 if (unlikely(res != 0)) 2542 if (unlikely(res != 0)) {
2543 vha->req->cnt += full_req_cnt;
2351 goto out_unmap_unlock; 2544 goto out_unmap_unlock;
2352 2545 }
2353 2546
2354 pkt = (struct ctio7_to_24xx *)prm.pkt; 2547 pkt = (struct ctio7_to_24xx *)prm.pkt;
2355 2548
@@ -2463,7 +2656,8 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
2463 2656
2464 spin_lock_irqsave(&ha->hardware_lock, flags); 2657 spin_lock_irqsave(&ha->hardware_lock, flags);
2465 2658
2466 if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) { 2659 if (qla2x00_reset_active(vha) || (cmd->reset_count != ha->chip_reset) ||
2660 (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)) {
2467 /* 2661 /*
2468 * Either a chip reset is active or this request was from 2662 * Either a chip reset is active or this request was from
2469 * previous life, just abort the processing. 2663 * previous life, just abort the processing.
@@ -2487,8 +2681,11 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
2487 else 2681 else
2488 res = qlt_24xx_build_ctio_pkt(&prm, vha); 2682 res = qlt_24xx_build_ctio_pkt(&prm, vha);
2489 2683
2490 if (unlikely(res != 0)) 2684 if (unlikely(res != 0)) {
2685 vha->req->cnt += prm.req_cnt;
2491 goto out_unlock_free_unmap; 2686 goto out_unlock_free_unmap;
2687 }
2688
2492 pkt = (struct ctio7_to_24xx *)prm.pkt; 2689 pkt = (struct ctio7_to_24xx *)prm.pkt;
2493 pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT | 2690 pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT |
2494 CTIO7_FLAGS_STATUS_MODE_0); 2691 CTIO7_FLAGS_STATUS_MODE_0);
@@ -2653,6 +2850,89 @@ out:
2653 2850
2654/* If hardware_lock held on entry, might drop it, then reaquire */ 2851/* If hardware_lock held on entry, might drop it, then reaquire */
2655/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ 2852/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
2853static int __qlt_send_term_imm_notif(struct scsi_qla_host *vha,
2854 struct imm_ntfy_from_isp *ntfy)
2855{
2856 struct nack_to_isp *nack;
2857 struct qla_hw_data *ha = vha->hw;
2858 request_t *pkt;
2859 int ret = 0;
2860
2861 ql_dbg(ql_dbg_tgt_tmr, vha, 0xe01c,
2862 "Sending TERM ELS CTIO (ha=%p)\n", ha);
2863
2864 pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL);
2865 if (pkt == NULL) {
2866 ql_dbg(ql_dbg_tgt, vha, 0xe080,
2867 "qla_target(%d): %s failed: unable to allocate "
2868 "request packet\n", vha->vp_idx, __func__);
2869 return -ENOMEM;
2870 }
2871
2872 pkt->entry_type = NOTIFY_ACK_TYPE;
2873 pkt->entry_count = 1;
2874 pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
2875
2876 nack = (struct nack_to_isp *)pkt;
2877 nack->ox_id = ntfy->ox_id;
2878
2879 nack->u.isp24.nport_handle = ntfy->u.isp24.nport_handle;
2880 if (le16_to_cpu(ntfy->u.isp24.status) == IMM_NTFY_ELS) {
2881 nack->u.isp24.flags = ntfy->u.isp24.flags &
2882 __constant_cpu_to_le32(NOTIFY24XX_FLAGS_PUREX_IOCB);
2883 }
2884
2885 /* terminate */
2886 nack->u.isp24.flags |=
2887 __constant_cpu_to_le16(NOTIFY_ACK_FLAGS_TERMINATE);
2888
2889 nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id;
2890 nack->u.isp24.status = ntfy->u.isp24.status;
2891 nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode;
2892 nack->u.isp24.fw_handle = ntfy->u.isp24.fw_handle;
2893 nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address;
2894 nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs;
2895 nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui;
2896 nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
2897
2898 qla2x00_start_iocbs(vha, vha->req);
2899 return ret;
2900}
2901
2902static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
2903 struct imm_ntfy_from_isp *imm, int ha_locked)
2904{
2905 unsigned long flags = 0;
2906 int rc;
2907
2908 if (qlt_issue_marker(vha, ha_locked) < 0)
2909 return;
2910
2911 if (ha_locked) {
2912 rc = __qlt_send_term_imm_notif(vha, imm);
2913
2914#if 0 /* Todo */
2915 if (rc == -ENOMEM)
2916 qlt_alloc_qfull_cmd(vha, imm, 0, 0);
2917#endif
2918 goto done;
2919 }
2920
2921 spin_lock_irqsave(&vha->hw->hardware_lock, flags);
2922 rc = __qlt_send_term_imm_notif(vha, imm);
2923
2924#if 0 /* Todo */
2925 if (rc == -ENOMEM)
2926 qlt_alloc_qfull_cmd(vha, imm, 0, 0);
2927#endif
2928
2929done:
2930 if (!ha_locked)
2931 spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
2932}
2933
2934/* If hardware_lock held on entry, might drop it, then reaquire */
2935/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
2656static int __qlt_send_term_exchange(struct scsi_qla_host *vha, 2936static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
2657 struct qla_tgt_cmd *cmd, 2937 struct qla_tgt_cmd *cmd,
2658 struct atio_from_isp *atio) 2938 struct atio_from_isp *atio)
@@ -2717,7 +2997,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
2717static void qlt_send_term_exchange(struct scsi_qla_host *vha, 2997static void qlt_send_term_exchange(struct scsi_qla_host *vha,
2718 struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) 2998 struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked)
2719{ 2999{
2720 unsigned long flags; 3000 unsigned long flags = 0;
2721 int rc; 3001 int rc;
2722 3002
2723 if (qlt_issue_marker(vha, ha_locked) < 0) 3003 if (qlt_issue_marker(vha, ha_locked) < 0)
@@ -2733,17 +3013,18 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
2733 rc = __qlt_send_term_exchange(vha, cmd, atio); 3013 rc = __qlt_send_term_exchange(vha, cmd, atio);
2734 if (rc == -ENOMEM) 3014 if (rc == -ENOMEM)
2735 qlt_alloc_qfull_cmd(vha, atio, 0, 0); 3015 qlt_alloc_qfull_cmd(vha, atio, 0, 0);
2736 spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
2737 3016
2738done: 3017done:
2739 if (cmd && ((cmd->state != QLA_TGT_STATE_ABORTED) || 3018 if (cmd && ((cmd->state != QLA_TGT_STATE_ABORTED) ||
2740 !cmd->cmd_sent_to_fw)) { 3019 !cmd->cmd_sent_to_fw)) {
2741 if (!ha_locked && !in_interrupt()) 3020 if (cmd->sg_mapped)
2742 msleep(250); /* just in case */ 3021 qlt_unmap_sg(vha, cmd);
2743
2744 qlt_unmap_sg(vha, cmd);
2745 vha->hw->tgt.tgt_ops->free_cmd(cmd); 3022 vha->hw->tgt.tgt_ops->free_cmd(cmd);
2746 } 3023 }
3024
3025 if (!ha_locked)
3026 spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
3027
2747 return; 3028 return;
2748} 3029}
2749 3030
@@ -2794,6 +3075,24 @@ static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
2794 3075
2795} 3076}
2796 3077
3078void qlt_abort_cmd(struct qla_tgt_cmd *cmd)
3079{
3080 struct qla_tgt *tgt = cmd->tgt;
3081 struct scsi_qla_host *vha = tgt->vha;
3082 struct se_cmd *se_cmd = &cmd->se_cmd;
3083
3084 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
3085 "qla_target(%d): terminating exchange for aborted cmd=%p "
3086 "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
3087 se_cmd->tag);
3088
3089 cmd->state = QLA_TGT_STATE_ABORTED;
3090 cmd->cmd_flags |= BIT_6;
3091
3092 qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);
3093}
3094EXPORT_SYMBOL(qlt_abort_cmd);
3095
2797void qlt_free_cmd(struct qla_tgt_cmd *cmd) 3096void qlt_free_cmd(struct qla_tgt_cmd *cmd)
2798{ 3097{
2799 struct qla_tgt_sess *sess = cmd->sess; 3098 struct qla_tgt_sess *sess = cmd->sess;
@@ -3017,7 +3316,7 @@ qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
3017 dump_stack(); 3316 dump_stack();
3018 } 3317 }
3019 3318
3020 cmd->cmd_flags |= BIT_12; 3319 cmd->cmd_flags |= BIT_17;
3021 ha->tgt.tgt_ops->free_cmd(cmd); 3320 ha->tgt.tgt_ops->free_cmd(cmd);
3022} 3321}
3023 3322
@@ -3179,7 +3478,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
3179skip_term: 3478skip_term:
3180 3479
3181 if (cmd->state == QLA_TGT_STATE_PROCESSED) { 3480 if (cmd->state == QLA_TGT_STATE_PROCESSED) {
3182 ; 3481 cmd->cmd_flags |= BIT_12;
3183 } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 3482 } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
3184 int rx_status = 0; 3483 int rx_status = 0;
3185 3484
@@ -3193,9 +3492,11 @@ skip_term:
3193 ha->tgt.tgt_ops->handle_data(cmd); 3492 ha->tgt.tgt_ops->handle_data(cmd);
3194 return; 3493 return;
3195 } else if (cmd->state == QLA_TGT_STATE_ABORTED) { 3494 } else if (cmd->state == QLA_TGT_STATE_ABORTED) {
3495 cmd->cmd_flags |= BIT_18;
3196 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e, 3496 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e,
3197 "Aborted command %p (tag %d) finished\n", cmd, cmd->tag); 3497 "Aborted command %p (tag %lld) finished\n", cmd, se_cmd->tag);
3198 } else { 3498 } else {
3499 cmd->cmd_flags |= BIT_19;
3199 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05c, 3500 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05c,
3200 "qla_target(%d): A command in state (%d) should " 3501 "qla_target(%d): A command in state (%d) should "
3201 "not return a CTIO complete\n", vha->vp_idx, cmd->state); 3502 "not return a CTIO complete\n", vha->vp_idx, cmd->state);
@@ -3207,7 +3508,6 @@ skip_term:
3207 dump_stack(); 3508 dump_stack();
3208 } 3509 }
3209 3510
3210
3211 ha->tgt.tgt_ops->free_cmd(cmd); 3511 ha->tgt.tgt_ops->free_cmd(cmd);
3212} 3512}
3213 3513
@@ -3265,8 +3565,15 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3265 if (tgt->tgt_stop) 3565 if (tgt->tgt_stop)
3266 goto out_term; 3566 goto out_term;
3267 3567
3568 if (cmd->state == QLA_TGT_STATE_ABORTED) {
3569 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf082,
3570 "cmd with tag %u is aborted\n",
3571 cmd->atio.u.isp24.exchange_addr);
3572 goto out_term;
3573 }
3574
3268 cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; 3575 cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
3269 cmd->tag = atio->u.isp24.exchange_addr; 3576 cmd->se_cmd.tag = atio->u.isp24.exchange_addr;
3270 cmd->unpacked_lun = scsilun_to_int( 3577 cmd->unpacked_lun = scsilun_to_int(
3271 (struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun); 3578 (struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun);
3272 3579
@@ -3318,6 +3625,12 @@ out_term:
3318static void qlt_do_work(struct work_struct *work) 3625static void qlt_do_work(struct work_struct *work)
3319{ 3626{
3320 struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); 3627 struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
3628 scsi_qla_host_t *vha = cmd->vha;
3629 unsigned long flags;
3630
3631 spin_lock_irqsave(&vha->cmd_list_lock, flags);
3632 list_del(&cmd->cmd_list);
3633 spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
3321 3634
3322 __qlt_do_work(cmd); 3635 __qlt_do_work(cmd);
3323} 3636}
@@ -3347,6 +3660,11 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
3347 cmd->loop_id = sess->loop_id; 3660 cmd->loop_id = sess->loop_id;
3348 cmd->conf_compl_supported = sess->conf_compl_supported; 3661 cmd->conf_compl_supported = sess->conf_compl_supported;
3349 3662
3663 cmd->cmd_flags = 0;
3664 cmd->jiffies_at_alloc = get_jiffies_64();
3665
3666 cmd->reset_count = vha->hw->chip_reset;
3667
3350 return cmd; 3668 return cmd;
3351} 3669}
3352 3670
@@ -3364,14 +3682,25 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
3364 unsigned long flags; 3682 unsigned long flags;
3365 uint8_t *s_id = op->atio.u.isp24.fcp_hdr.s_id; 3683 uint8_t *s_id = op->atio.u.isp24.fcp_hdr.s_id;
3366 3684
3685 spin_lock_irqsave(&vha->cmd_list_lock, flags);
3686 list_del(&op->cmd_list);
3687 spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
3688
3689 if (op->aborted) {
3690 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf083,
3691 "sess_op with tag %u is aborted\n",
3692 op->atio.u.isp24.exchange_addr);
3693 goto out_term;
3694 }
3695
3367 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf022, 3696 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf022,
3368 "qla_target(%d): Unable to find wwn login" 3697 "qla_target(%d): Unable to find wwn login"
3369 " (s_id %x:%x:%x), trying to create it manually\n", 3698 " (s_id %x:%x:%x), trying to create it manually\n",
3370 vha->vp_idx, s_id[0], s_id[1], s_id[2]); 3699 vha->vp_idx, s_id[0], s_id[1], s_id[2]);
3371 3700
3372 if (op->atio.u.raw.entry_count > 1) { 3701 if (op->atio.u.raw.entry_count > 1) {
3373 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023, 3702 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023,
3374 "Dropping multy entry atio %p\n", &op->atio); 3703 "Dropping multy entry atio %p\n", &op->atio);
3375 goto out_term; 3704 goto out_term;
3376 } 3705 }
3377 3706
@@ -3436,10 +3765,25 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
3436 3765
3437 memcpy(&op->atio, atio, sizeof(*atio)); 3766 memcpy(&op->atio, atio, sizeof(*atio));
3438 op->vha = vha; 3767 op->vha = vha;
3768
3769 spin_lock(&vha->cmd_list_lock);
3770 list_add_tail(&op->cmd_list, &vha->qla_sess_op_cmd_list);
3771 spin_unlock(&vha->cmd_list_lock);
3772
3439 INIT_WORK(&op->work, qlt_create_sess_from_atio); 3773 INIT_WORK(&op->work, qlt_create_sess_from_atio);
3440 queue_work(qla_tgt_wq, &op->work); 3774 queue_work(qla_tgt_wq, &op->work);
3441 return 0; 3775 return 0;
3442 } 3776 }
3777
3778 /* Another WWN used to have our s_id. Our PLOGI scheduled its
3779 * session deletion, but it's still in sess_del_work wq */
3780 if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
3781 ql_dbg(ql_dbg_io, vha, 0x3061,
3782 "New command while old session %p is being deleted\n",
3783 sess);
3784 return -EFAULT;
3785 }
3786
3443 /* 3787 /*
3444 * Do kref_get() before returning + dropping qla_hw_data->hardware_lock. 3788 * Do kref_get() before returning + dropping qla_hw_data->hardware_lock.
3445 */ 3789 */
@@ -3453,13 +3797,13 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
3453 return -ENOMEM; 3797 return -ENOMEM;
3454 } 3798 }
3455 3799
3456 cmd->cmd_flags = 0;
3457 cmd->jiffies_at_alloc = get_jiffies_64();
3458
3459 cmd->reset_count = vha->hw->chip_reset;
3460
3461 cmd->cmd_in_wq = 1; 3800 cmd->cmd_in_wq = 1;
3462 cmd->cmd_flags |= BIT_0; 3801 cmd->cmd_flags |= BIT_0;
3802
3803 spin_lock(&vha->cmd_list_lock);
3804 list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
3805 spin_unlock(&vha->cmd_list_lock);
3806
3463 INIT_WORK(&cmd->work, qlt_do_work); 3807 INIT_WORK(&cmd->work, qlt_do_work);
3464 queue_work(qla_tgt_wq, &cmd->work); 3808 queue_work(qla_tgt_wq, &cmd->work);
3465 return 0; 3809 return 0;
@@ -3473,6 +3817,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
3473 struct scsi_qla_host *vha = sess->vha; 3817 struct scsi_qla_host *vha = sess->vha;
3474 struct qla_hw_data *ha = vha->hw; 3818 struct qla_hw_data *ha = vha->hw;
3475 struct qla_tgt_mgmt_cmd *mcmd; 3819 struct qla_tgt_mgmt_cmd *mcmd;
3820 struct atio_from_isp *a = (struct atio_from_isp *)iocb;
3476 int res; 3821 int res;
3477 uint8_t tmr_func; 3822 uint8_t tmr_func;
3478 3823
@@ -3513,6 +3858,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
3513 ql_dbg(ql_dbg_tgt_tmr, vha, 0x10002, 3858 ql_dbg(ql_dbg_tgt_tmr, vha, 0x10002,
3514 "qla_target(%d): LUN_RESET received\n", sess->vha->vp_idx); 3859 "qla_target(%d): LUN_RESET received\n", sess->vha->vp_idx);
3515 tmr_func = TMR_LUN_RESET; 3860 tmr_func = TMR_LUN_RESET;
3861 abort_cmds_for_lun(vha, lun, a->u.isp24.fcp_hdr.s_id);
3516 break; 3862 break;
3517 3863
3518 case QLA_TGT_CLEAR_TS: 3864 case QLA_TGT_CLEAR_TS:
@@ -3601,6 +3947,9 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb)
3601 sizeof(struct atio_from_isp)); 3947 sizeof(struct atio_from_isp));
3602 } 3948 }
3603 3949
3950 if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)
3951 return -EFAULT;
3952
3604 return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); 3953 return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
3605} 3954}
3606 3955
@@ -3666,22 +4015,280 @@ static int qlt_abort_task(struct scsi_qla_host *vha,
3666 return __qlt_abort_task(vha, iocb, sess); 4015 return __qlt_abort_task(vha, iocb, sess);
3667} 4016}
3668 4017
4018void qlt_logo_completion_handler(fc_port_t *fcport, int rc)
4019{
4020 if (fcport->tgt_session) {
4021 if (rc != MBS_COMMAND_COMPLETE) {
4022 ql_dbg(ql_dbg_tgt_mgt, fcport->vha, 0xf093,
4023 "%s: se_sess %p / sess %p from"
4024 " port %8phC loop_id %#04x s_id %02x:%02x:%02x"
4025 " LOGO failed: %#x\n",
4026 __func__,
4027 fcport->tgt_session->se_sess,
4028 fcport->tgt_session,
4029 fcport->port_name, fcport->loop_id,
4030 fcport->d_id.b.domain, fcport->d_id.b.area,
4031 fcport->d_id.b.al_pa, rc);
4032 }
4033
4034 fcport->tgt_session->logout_completed = 1;
4035 }
4036}
4037
4038static void qlt_swap_imm_ntfy_iocb(struct imm_ntfy_from_isp *a,
4039 struct imm_ntfy_from_isp *b)
4040{
4041 struct imm_ntfy_from_isp tmp;
4042 memcpy(&tmp, a, sizeof(struct imm_ntfy_from_isp));
4043 memcpy(a, b, sizeof(struct imm_ntfy_from_isp));
4044 memcpy(b, &tmp, sizeof(struct imm_ntfy_from_isp));
4045}
4046
4047/*
4048* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list)
4049*
4050* Schedules sessions with matching port_id/loop_id but different wwn for
4051* deletion. Returns existing session with matching wwn if present.
4052* Null otherwise.
4053*/
4054static struct qla_tgt_sess *
4055qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn,
4056 port_id_t port_id, uint16_t loop_id)
4057{
4058 struct qla_tgt_sess *sess = NULL, *other_sess;
4059 uint64_t other_wwn;
4060
4061 list_for_each_entry(other_sess, &tgt->sess_list, sess_list_entry) {
4062
4063 other_wwn = wwn_to_u64(other_sess->port_name);
4064
4065 if (wwn == other_wwn) {
4066 WARN_ON(sess);
4067 sess = other_sess;
4068 continue;
4069 }
4070
4071 /* find other sess with nport_id collision */
4072 if (port_id.b24 == other_sess->s_id.b24) {
4073 if (loop_id != other_sess->loop_id) {
4074 ql_dbg(ql_dbg_tgt_tmr, tgt->vha, 0x1000c,
4075 "Invalidating sess %p loop_id %d wwn %llx.\n",
4076 other_sess, other_sess->loop_id, other_wwn);
4077
4078 /*
4079 * logout_on_delete is set by default, but another
4080 * session that has the same s_id/loop_id combo
4081 * might have cleared it when requested this session
4082 * deletion, so don't touch it
4083 */
4084 qlt_schedule_sess_for_deletion(other_sess, true);
4085 } else {
4086 /*
4087 * Another wwn used to have our s_id/loop_id
4088 * combo - kill the session, but don't log out
4089 */
4090 sess->logout_on_delete = 0;
4091 qlt_schedule_sess_for_deletion(other_sess,
4092 true);
4093 }
4094 continue;
4095 }
4096
4097 /* find other sess with nport handle collision */
4098 if (loop_id == other_sess->loop_id) {
4099 ql_dbg(ql_dbg_tgt_tmr, tgt->vha, 0x1000d,
4100 "Invalidating sess %p loop_id %d wwn %llx.\n",
4101 other_sess, other_sess->loop_id, other_wwn);
4102
4103 /* Same loop_id but different s_id
4104 * Ok to kill and logout */
4105 qlt_schedule_sess_for_deletion(other_sess, true);
4106 }
4107 }
4108
4109 return sess;
4110}
4111
4112/* Abort any commands for this s_id waiting on qla_tgt_wq workqueue */
4113static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id)
4114{
4115 struct qla_tgt_sess_op *op;
4116 struct qla_tgt_cmd *cmd;
4117 uint32_t key;
4118 int count = 0;
4119
4120 key = (((u32)s_id->b.domain << 16) |
4121 ((u32)s_id->b.area << 8) |
4122 ((u32)s_id->b.al_pa));
4123
4124 spin_lock(&vha->cmd_list_lock);
4125 list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
4126 uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
4127 if (op_key == key) {
4128 op->aborted = true;
4129 count++;
4130 }
4131 }
4132 list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
4133 uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
4134 if (cmd_key == key) {
4135 cmd->state = QLA_TGT_STATE_ABORTED;
4136 count++;
4137 }
4138 }
4139 spin_unlock(&vha->cmd_list_lock);
4140
4141 return count;
4142}
4143
3669/* 4144/*
3670 * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 4145 * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
3671 */ 4146 */
3672static int qlt_24xx_handle_els(struct scsi_qla_host *vha, 4147static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
3673 struct imm_ntfy_from_isp *iocb) 4148 struct imm_ntfy_from_isp *iocb)
3674{ 4149{
4150 struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
4151 struct qla_hw_data *ha = vha->hw;
4152 struct qla_tgt_sess *sess = NULL;
4153 uint64_t wwn;
4154 port_id_t port_id;
4155 uint16_t loop_id;
4156 uint16_t wd3_lo;
3675 int res = 0; 4157 int res = 0;
3676 4158
4159 wwn = wwn_to_u64(iocb->u.isp24.port_name);
4160
4161 port_id.b.domain = iocb->u.isp24.port_id[2];
4162 port_id.b.area = iocb->u.isp24.port_id[1];
4163 port_id.b.al_pa = iocb->u.isp24.port_id[0];
4164 port_id.b.rsvd_1 = 0;
4165
4166 loop_id = le16_to_cpu(iocb->u.isp24.nport_handle);
4167
3677 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026, 4168 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026,
3678 "qla_target(%d): Port ID: 0x%3phC ELS opcode: 0x%02x\n", 4169 "qla_target(%d): Port ID: 0x%3phC ELS opcode: 0x%02x\n",
3679 vha->vp_idx, iocb->u.isp24.port_id, iocb->u.isp24.status_subcode); 4170 vha->vp_idx, iocb->u.isp24.port_id, iocb->u.isp24.status_subcode);
3680 4171
4172 /* res = 1 means ack at the end of thread
4173 * res = 0 means ack async/later.
4174 */
3681 switch (iocb->u.isp24.status_subcode) { 4175 switch (iocb->u.isp24.status_subcode) {
3682 case ELS_PLOGI: 4176 case ELS_PLOGI:
3683 case ELS_FLOGI: 4177
4178 /* Mark all stale commands in qla_tgt_wq for deletion */
4179 abort_cmds_for_s_id(vha, &port_id);
4180
4181 if (wwn)
4182 sess = qlt_find_sess_invalidate_other(tgt, wwn,
4183 port_id, loop_id);
4184
4185 if (!sess || IS_SW_RESV_ADDR(sess->s_id)) {
4186 res = 1;
4187 break;
4188 }
4189
4190 if (sess->plogi_ack_needed) {
4191 /*
4192 * Initiator sent another PLOGI before last PLOGI could
4193 * finish. Swap plogi iocbs and terminate old one
4194 * without acking, new one will get acked when session
4195 * deletion completes.
4196 */
4197 ql_log(ql_log_warn, sess->vha, 0xf094,
4198 "sess %p received double plogi.\n", sess);
4199
4200 qlt_swap_imm_ntfy_iocb(iocb, &sess->tm_iocb);
4201
4202 qlt_send_term_imm_notif(vha, iocb, 1);
4203
4204 res = 0;
4205 break;
4206 }
4207
4208 res = 0;
4209
4210 /*
4211 * Save immediate Notif IOCB for Ack when sess is done
4212 * and being deleted.
4213 */
4214 memcpy(&sess->tm_iocb, iocb, sizeof(sess->tm_iocb));
4215 sess->plogi_ack_needed = 1;
4216
4217 /*
4218 * Under normal circumstances we want to release nport handle
4219 * during LOGO process to avoid nport handle leaks inside FW.
4220 * The exception is when LOGO is done while another PLOGI with
4221 * the same nport handle is waiting as might be the case here.
4222 * Note: there is always a possibily of a race where session
4223 * deletion has already started for other reasons (e.g. ACL
4224 * removal) and now PLOGI arrives:
4225 * 1. if PLOGI arrived in FW after nport handle has been freed,
4226 * FW must have assigned this PLOGI a new/same handle and we
4227 * can proceed ACK'ing it as usual when session deletion
4228 * completes.
4229 * 2. if PLOGI arrived in FW before LOGO with LCF_FREE_NPORT
4230 * bit reached it, the handle has now been released. We'll
4231 * get an error when we ACK this PLOGI. Nothing will be sent
4232 * back to initiator. Initiator should eventually retry
4233 * PLOGI and situation will correct itself.
4234 */
4235 sess->keep_nport_handle = ((sess->loop_id == loop_id) &&
4236 (sess->s_id.b24 == port_id.b24));
4237 qlt_schedule_sess_for_deletion(sess, true);
4238 break;
4239
3684 case ELS_PRLI: 4240 case ELS_PRLI:
4241 wd3_lo = le16_to_cpu(iocb->u.isp24.u.prli.wd3_lo);
4242
4243 if (wwn)
4244 sess = qlt_find_sess_invalidate_other(tgt, wwn, port_id,
4245 loop_id);
4246
4247 if (sess != NULL) {
4248 if (sess->deleted) {
4249 /*
4250 * Impatient initiator sent PRLI before last
4251 * PLOGI could finish. Will force him to re-try,
4252 * while last one finishes.
4253 */
4254 ql_log(ql_log_warn, sess->vha, 0xf095,
4255 "sess %p PRLI received, before plogi ack.\n",
4256 sess);
4257 qlt_send_term_imm_notif(vha, iocb, 1);
4258 res = 0;
4259 break;
4260 }
4261
4262 /*
4263 * This shouldn't happen under normal circumstances,
4264 * since we have deleted the old session during PLOGI
4265 */
4266 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf096,
4267 "PRLI (loop_id %#04x) for existing sess %p (loop_id %#04x)\n",
4268 sess->loop_id, sess, iocb->u.isp24.nport_handle);
4269
4270 sess->local = 0;
4271 sess->loop_id = loop_id;
4272 sess->s_id = port_id;
4273
4274 if (wd3_lo & BIT_7)
4275 sess->conf_compl_supported = 1;
4276
4277 }
4278 res = 1; /* send notify ack */
4279
4280 /* Make session global (not used in fabric mode) */
4281 if (ha->current_topology != ISP_CFG_F) {
4282 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4283 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
4284 qla2xxx_wake_dpc(vha);
4285 } else {
4286 /* todo: else - create sess here. */
4287 res = 1; /* send notify ack */
4288 }
4289
4290 break;
4291
3685 case ELS_LOGO: 4292 case ELS_LOGO:
3686 case ELS_PRLO: 4293 case ELS_PRLO:
3687 res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS); 4294 res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS);
@@ -3699,6 +4306,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
3699 break; 4306 break;
3700 } 4307 }
3701 4308
4309 case ELS_FLOGI: /* should never happen */
3702 default: 4310 default:
3703 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf061, 4311 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf061,
3704 "qla_target(%d): Unsupported ELS command %x " 4312 "qla_target(%d): Unsupported ELS command %x "
@@ -3712,6 +4320,14 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
3712 4320
3713static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset) 4321static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
3714{ 4322{
4323#if 1
4324 /*
4325 * FIXME: Reject non zero SRR relative offset until we can test
4326 * this code properly.
4327 */
4328 pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset);
4329 return -1;
4330#else
3715 struct scatterlist *sg, *sgp, *sg_srr, *sg_srr_start = NULL; 4331 struct scatterlist *sg, *sgp, *sg_srr, *sg_srr_start = NULL;
3716 size_t first_offset = 0, rem_offset = offset, tmp = 0; 4332 size_t first_offset = 0, rem_offset = offset, tmp = 0;
3717 int i, sg_srr_cnt, bufflen = 0; 4333 int i, sg_srr_cnt, bufflen = 0;
@@ -3721,13 +4337,6 @@ static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
3721 "cmd->sg_cnt: %u, direction: %d\n", 4337 "cmd->sg_cnt: %u, direction: %d\n",
3722 cmd, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); 4338 cmd, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
3723 4339
3724 /*
3725 * FIXME: Reject non zero SRR relative offset until we can test
3726 * this code properly.
3727 */
3728 pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset);
3729 return -1;
3730
3731 if (!cmd->sg || !cmd->sg_cnt) { 4340 if (!cmd->sg || !cmd->sg_cnt) {
3732 ql_dbg(ql_dbg_tgt, cmd->vha, 0xe055, 4341 ql_dbg(ql_dbg_tgt, cmd->vha, 0xe055,
3733 "Missing cmd->sg or zero cmd->sg_cnt in" 4342 "Missing cmd->sg or zero cmd->sg_cnt in"
@@ -3810,6 +4419,7 @@ static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
3810 BUG(); 4419 BUG();
3811 4420
3812 return 0; 4421 return 0;
4422#endif
3813} 4423}
3814 4424
3815static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd, 4425static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd,
@@ -3891,9 +4501,8 @@ static void qlt_handle_srr(struct scsi_qla_host *vha,
3891 resp = 1; 4501 resp = 1;
3892 } else { 4502 } else {
3893 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf064, 4503 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf064,
3894 "qla_target(%d): SRR for in data for cmd " 4504 "qla_target(%d): SRR for in data for cmd without them (tag %lld, SCSI status %d), reject",
3895 "without them (tag %d, SCSI status %d), " 4505 vha->vp_idx, se_cmd->tag,
3896 "reject", vha->vp_idx, cmd->tag,
3897 cmd->se_cmd.scsi_status); 4506 cmd->se_cmd.scsi_status);
3898 goto out_reject; 4507 goto out_reject;
3899 } 4508 }
@@ -3927,10 +4536,8 @@ static void qlt_handle_srr(struct scsi_qla_host *vha,
3927 } 4536 }
3928 } else { 4537 } else {
3929 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf066, 4538 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf066,
3930 "qla_target(%d): SRR for out data for cmd " 4539 "qla_target(%d): SRR for out data for cmd without them (tag %lld, SCSI status %d), reject",
3931 "without them (tag %d, SCSI status %d), " 4540 vha->vp_idx, se_cmd->tag, cmd->se_cmd.scsi_status);
3932 "reject", vha->vp_idx, cmd->tag,
3933 cmd->se_cmd.scsi_status);
3934 goto out_reject; 4541 goto out_reject;
3935 } 4542 }
3936 break; 4543 break;
@@ -4051,10 +4658,9 @@ restart:
4051 cmd->sg = se_cmd->t_data_sg; 4658 cmd->sg = se_cmd->t_data_sg;
4052 4659
4053 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, 4660 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c,
4054 "SRR cmd %p (se_cmd %p, tag %d, op %x), " 4661 "SRR cmd %p (se_cmd %p, tag %lld, op %x), sg_cnt=%d, offset=%d",
4055 "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, 4662 cmd, &cmd->se_cmd, se_cmd->tag, se_cmd->t_task_cdb ?
4056 se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, 4663 se_cmd->t_task_cdb[0] : 0, cmd->sg_cnt, cmd->offset);
4057 cmd->sg_cnt, cmd->offset);
4058 4664
4059 qlt_handle_srr(vha, sctio, imm); 4665 qlt_handle_srr(vha, sctio, imm);
4060 4666
@@ -5016,6 +5622,11 @@ static void qlt_abort_work(struct qla_tgt *tgt,
5016 if (!sess) 5622 if (!sess)
5017 goto out_term; 5623 goto out_term;
5018 } else { 5624 } else {
5625 if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
5626 sess = NULL;
5627 goto out_term;
5628 }
5629
5019 kref_get(&sess->se_sess->sess_kref); 5630 kref_get(&sess->se_sess->sess_kref);
5020 } 5631 }
5021 5632
@@ -5070,6 +5681,11 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
5070 if (!sess) 5681 if (!sess)
5071 goto out_term; 5682 goto out_term;
5072 } else { 5683 } else {
5684 if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
5685 sess = NULL;
5686 goto out_term;
5687 }
5688
5073 kref_get(&sess->se_sess->sess_kref); 5689 kref_get(&sess->se_sess->sess_kref);
5074 } 5690 }
5075 5691
@@ -5556,6 +6172,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
5556 6172
5557 /* Adjust ring index */ 6173 /* Adjust ring index */
5558 WRT_REG_DWORD(ISP_ATIO_Q_OUT(vha), ha->tgt.atio_ring_index); 6174 WRT_REG_DWORD(ISP_ATIO_Q_OUT(vha), ha->tgt.atio_ring_index);
6175 RD_REG_DWORD_RELAXED(ISP_ATIO_Q_OUT(vha));
5559} 6176}
5560 6177
5561void 6178void
@@ -5797,7 +6414,7 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
5797 if (!QLA_TGT_MODE_ENABLED()) 6414 if (!QLA_TGT_MODE_ENABLED())
5798 return; 6415 return;
5799 6416
5800 if (ha->mqenable || IS_QLA83XX(ha)) { 6417 if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
5801 ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in; 6418 ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in;
5802 ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out; 6419 ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out;
5803 } else { 6420 } else {
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 332086776dfe..bca584ae45b7 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -167,7 +167,24 @@ struct imm_ntfy_from_isp {
167 uint32_t srr_rel_offs; 167 uint32_t srr_rel_offs;
168 uint16_t srr_ui; 168 uint16_t srr_ui;
169 uint16_t srr_ox_id; 169 uint16_t srr_ox_id;
170 uint8_t reserved_4[19]; 170 union {
171 struct {
172 uint8_t node_name[8];
173 } plogi; /* PLOGI/ADISC/PDISC */
174 struct {
175 /* PRLI word 3 bit 0-15 */
176 uint16_t wd3_lo;
177 uint8_t resv0[6];
178 } prli;
179 struct {
180 uint8_t port_id[3];
181 uint8_t resv1;
182 uint16_t nport_handle;
183 uint16_t resv2;
184 } req_els;
185 } u;
186 uint8_t port_name[8];
187 uint8_t resv3[3];
171 uint8_t vp_index; 188 uint8_t vp_index;
172 uint32_t reserved_5; 189 uint32_t reserved_5;
173 uint8_t port_id[3]; 190 uint8_t port_id[3];
@@ -234,6 +251,7 @@ struct nack_to_isp {
234 uint8_t reserved[2]; 251 uint8_t reserved[2];
235 uint16_t ox_id; 252 uint16_t ox_id;
236} __packed; 253} __packed;
254#define NOTIFY_ACK_FLAGS_TERMINATE BIT_3
237#define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0 255#define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0
238#define NOTIFY_ACK_SRR_FLAGS_REJECT 1 256#define NOTIFY_ACK_SRR_FLAGS_REJECT 1
239 257
@@ -790,13 +808,6 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
790#define FC_TM_REJECT 4 808#define FC_TM_REJECT 4
791#define FC_TM_FAILED 5 809#define FC_TM_FAILED 5
792 810
793/*
794 * Error code of qlt_pre_xmit_response() meaning that cmd's exchange was
795 * terminated, so no more actions is needed and success should be returned
796 * to target.
797 */
798#define QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED 0x1717
799
800#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G) 811#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)
801#define pci_dma_lo32(a) (a & 0xffffffff) 812#define pci_dma_lo32(a) (a & 0xffffffff)
802#define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff) 813#define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff)
@@ -874,6 +885,15 @@ struct qla_tgt_sess_op {
874 struct scsi_qla_host *vha; 885 struct scsi_qla_host *vha;
875 struct atio_from_isp atio; 886 struct atio_from_isp atio;
876 struct work_struct work; 887 struct work_struct work;
888 struct list_head cmd_list;
889 bool aborted;
890};
891
892enum qla_sess_deletion {
893 QLA_SESS_DELETION_NONE = 0,
894 QLA_SESS_DELETION_PENDING = 1, /* hopefully we can get rid of
895 * this one */
896 QLA_SESS_DELETION_IN_PROGRESS = 2,
877}; 897};
878 898
879/* 899/*
@@ -884,8 +904,15 @@ struct qla_tgt_sess {
884 port_id_t s_id; 904 port_id_t s_id;
885 905
886 unsigned int conf_compl_supported:1; 906 unsigned int conf_compl_supported:1;
887 unsigned int deleted:1; 907 unsigned int deleted:2;
888 unsigned int local:1; 908 unsigned int local:1;
909 unsigned int logout_on_delete:1;
910 unsigned int plogi_ack_needed:1;
911 unsigned int keep_nport_handle:1;
912
913 unsigned char logout_completed;
914
915 int generation;
889 916
890 struct se_session *se_sess; 917 struct se_session *se_sess;
891 struct scsi_qla_host *vha; 918 struct scsi_qla_host *vha;
@@ -897,6 +924,10 @@ struct qla_tgt_sess {
897 924
898 uint8_t port_name[WWN_SIZE]; 925 uint8_t port_name[WWN_SIZE];
899 struct work_struct free_work; 926 struct work_struct free_work;
927
928 union {
929 struct imm_ntfy_from_isp tm_iocb;
930 };
900}; 931};
901 932
902struct qla_tgt_cmd { 933struct qla_tgt_cmd {
@@ -912,7 +943,6 @@ struct qla_tgt_cmd {
912 unsigned int conf_compl_supported:1; 943 unsigned int conf_compl_supported:1;
913 unsigned int sg_mapped:1; 944 unsigned int sg_mapped:1;
914 unsigned int free_sg:1; 945 unsigned int free_sg:1;
915 unsigned int aborted:1; /* Needed in case of SRR */
916 unsigned int write_data_transferred:1; 946 unsigned int write_data_transferred:1;
917 unsigned int ctx_dsd_alloced:1; 947 unsigned int ctx_dsd_alloced:1;
918 unsigned int q_full:1; 948 unsigned int q_full:1;
@@ -924,7 +954,6 @@ struct qla_tgt_cmd {
924 int sg_cnt; /* SG segments count */ 954 int sg_cnt; /* SG segments count */
925 int bufflen; /* cmd buffer length */ 955 int bufflen; /* cmd buffer length */
926 int offset; 956 int offset;
927 uint32_t tag;
928 uint32_t unpacked_lun; 957 uint32_t unpacked_lun;
929 enum dma_data_direction dma_data_direction; 958 enum dma_data_direction dma_data_direction;
930 uint32_t reset_count; 959 uint32_t reset_count;
@@ -962,6 +991,9 @@ struct qla_tgt_cmd {
962 * BIT_14 - Back end data received/sent. 991 * BIT_14 - Back end data received/sent.
963 * BIT_15 - SRR prepare ctio 992 * BIT_15 - SRR prepare ctio
964 * BIT_16 - complete free 993 * BIT_16 - complete free
994 * BIT_17 - flush - qlt_abort_cmd_on_host_reset
995 * BIT_18 - completion w/abort status
996 * BIT_19 - completion w/unknown status
965 */ 997 */
966 uint32_t cmd_flags; 998 uint32_t cmd_flags;
967}; 999};
@@ -1027,6 +1059,10 @@ struct qla_tgt_srr_ctio {
1027 struct qla_tgt_cmd *cmd; 1059 struct qla_tgt_cmd *cmd;
1028}; 1060};
1029 1061
1062/* Check for Switch reserved address */
1063#define IS_SW_RESV_ADDR(_s_id) \
1064 ((_s_id.b.domain == 0xff) && (_s_id.b.area == 0xfc))
1065
1030#define QLA_TGT_XMIT_DATA 1 1066#define QLA_TGT_XMIT_DATA 1
1031#define QLA_TGT_XMIT_STATUS 2 1067#define QLA_TGT_XMIT_STATUS 2
1032#define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA) 1068#define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA)
@@ -1044,7 +1080,7 @@ extern int qlt_lport_register(void *, u64, u64, u64,
1044extern void qlt_lport_deregister(struct scsi_qla_host *); 1080extern void qlt_lport_deregister(struct scsi_qla_host *);
1045extern void qlt_unreg_sess(struct qla_tgt_sess *); 1081extern void qlt_unreg_sess(struct qla_tgt_sess *);
1046extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *); 1082extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *);
1047extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *); 1083extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int);
1048extern int __init qlt_init(void); 1084extern int __init qlt_init(void);
1049extern void qlt_exit(void); 1085extern void qlt_exit(void);
1050extern void qlt_update_vp_map(struct scsi_qla_host *, int); 1086extern void qlt_update_vp_map(struct scsi_qla_host *, int);
@@ -1074,12 +1110,23 @@ static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha)
1074 ha->host->active_mode |= MODE_INITIATOR; 1110 ha->host->active_mode |= MODE_INITIATOR;
1075} 1111}
1076 1112
1113static inline uint32_t sid_to_key(const uint8_t *s_id)
1114{
1115 uint32_t key;
1116
1117 key = (((unsigned long)s_id[0] << 16) |
1118 ((unsigned long)s_id[1] << 8) |
1119 (unsigned long)s_id[2]);
1120 return key;
1121}
1122
1077/* 1123/*
1078 * Exported symbols from qla_target.c LLD logic used by qla2xxx code.. 1124 * Exported symbols from qla_target.c LLD logic used by qla2xxx code..
1079 */ 1125 */
1080extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); 1126extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
1081extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); 1127extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
1082extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); 1128extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
1129extern void qlt_abort_cmd(struct qla_tgt_cmd *);
1083extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); 1130extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
1084extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); 1131extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
1085extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); 1132extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
@@ -1110,5 +1157,7 @@ extern void qlt_stop_phase2(struct qla_tgt *);
1110extern irqreturn_t qla83xx_msix_atio_q(int, void *); 1157extern irqreturn_t qla83xx_msix_atio_q(int, void *);
1111extern void qlt_83xx_iospace_config(struct qla_hw_data *); 1158extern void qlt_83xx_iospace_config(struct qla_hw_data *);
1112extern int qlt_free_qfull_cmds(struct scsi_qla_host *); 1159extern int qlt_free_qfull_cmds(struct scsi_qla_host *);
1160extern void qlt_logo_completion_handler(fc_port_t *, int);
1161extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
1113 1162
1114#endif /* __QLA_TARGET_H */ 1163#endif /* __QLA_TARGET_H */
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 5c9e680aa375..9224a06646e6 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -27,6 +27,7 @@
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <generated/utsrelease.h> 28#include <generated/utsrelease.h>
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/vmalloc.h>
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/list.h> 32#include <linux/list.h>
32#include <linux/slab.h> 33#include <linux/slab.h>
@@ -43,7 +44,6 @@
43#include <target/target_core_base.h> 44#include <target/target_core_base.h>
44#include <target/target_core_fabric.h> 45#include <target/target_core_fabric.h>
45#include <target/target_core_fabric_configfs.h> 46#include <target/target_core_fabric_configfs.h>
46#include <target/target_core_configfs.h>
47#include <target/configfs_macros.h> 47#include <target/configfs_macros.h>
48 48
49#include "qla_def.h" 49#include "qla_def.h"
@@ -53,9 +53,6 @@
53static struct workqueue_struct *tcm_qla2xxx_free_wq; 53static struct workqueue_struct *tcm_qla2xxx_free_wq;
54static struct workqueue_struct *tcm_qla2xxx_cmd_wq; 54static struct workqueue_struct *tcm_qla2xxx_cmd_wq;
55 55
56static const struct target_core_fabric_ops tcm_qla2xxx_ops;
57static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops;
58
59/* 56/*
60 * Parse WWN. 57 * Parse WWN.
61 * If strict, we require lower-case hex and colon separators to be sure 58 * If strict, we require lower-case hex and colon separators to be sure
@@ -190,23 +187,6 @@ static char *tcm_qla2xxx_npiv_get_fabric_name(void)
190 return "qla2xxx_npiv"; 187 return "qla2xxx_npiv";
191} 188}
192 189
193static u8 tcm_qla2xxx_get_fabric_proto_ident(struct se_portal_group *se_tpg)
194{
195 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
196 struct tcm_qla2xxx_tpg, se_tpg);
197 struct tcm_qla2xxx_lport *lport = tpg->lport;
198 u8 proto_id;
199
200 switch (lport->lport_proto_id) {
201 case SCSI_PROTOCOL_FCP:
202 default:
203 proto_id = fc_get_fabric_proto_ident(se_tpg);
204 break;
205 }
206
207 return proto_id;
208}
209
210static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) 190static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg)
211{ 191{
212 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 192 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
@@ -223,78 +203,6 @@ static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg)
223 return tpg->lport_tpgt; 203 return tpg->lport_tpgt;
224} 204}
225 205
226static u32 tcm_qla2xxx_get_default_depth(struct se_portal_group *se_tpg)
227{
228 return 1;
229}
230
231static u32 tcm_qla2xxx_get_pr_transport_id(
232 struct se_portal_group *se_tpg,
233 struct se_node_acl *se_nacl,
234 struct t10_pr_registration *pr_reg,
235 int *format_code,
236 unsigned char *buf)
237{
238 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
239 struct tcm_qla2xxx_tpg, se_tpg);
240 struct tcm_qla2xxx_lport *lport = tpg->lport;
241 int ret = 0;
242
243 switch (lport->lport_proto_id) {
244 case SCSI_PROTOCOL_FCP:
245 default:
246 ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
247 format_code, buf);
248 break;
249 }
250
251 return ret;
252}
253
254static u32 tcm_qla2xxx_get_pr_transport_id_len(
255 struct se_portal_group *se_tpg,
256 struct se_node_acl *se_nacl,
257 struct t10_pr_registration *pr_reg,
258 int *format_code)
259{
260 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
261 struct tcm_qla2xxx_tpg, se_tpg);
262 struct tcm_qla2xxx_lport *lport = tpg->lport;
263 int ret = 0;
264
265 switch (lport->lport_proto_id) {
266 case SCSI_PROTOCOL_FCP:
267 default:
268 ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
269 format_code);
270 break;
271 }
272
273 return ret;
274}
275
276static char *tcm_qla2xxx_parse_pr_out_transport_id(
277 struct se_portal_group *se_tpg,
278 const char *buf,
279 u32 *out_tid_len,
280 char **port_nexus_ptr)
281{
282 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
283 struct tcm_qla2xxx_tpg, se_tpg);
284 struct tcm_qla2xxx_lport *lport = tpg->lport;
285 char *tid = NULL;
286
287 switch (lport->lport_proto_id) {
288 case SCSI_PROTOCOL_FCP:
289 default:
290 tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
291 port_nexus_ptr);
292 break;
293 }
294
295 return tid;
296}
297
298static int tcm_qla2xxx_check_demo_mode(struct se_portal_group *se_tpg) 206static int tcm_qla2xxx_check_demo_mode(struct se_portal_group *se_tpg)
299{ 207{
300 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 208 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
@@ -343,29 +251,6 @@ static int tcm_qla2xxx_check_prot_fabric_only(struct se_portal_group *se_tpg)
343 return tpg->tpg_attrib.fabric_prot_type; 251 return tpg->tpg_attrib.fabric_prot_type;
344} 252}
345 253
346static struct se_node_acl *tcm_qla2xxx_alloc_fabric_acl(
347 struct se_portal_group *se_tpg)
348{
349 struct tcm_qla2xxx_nacl *nacl;
350
351 nacl = kzalloc(sizeof(struct tcm_qla2xxx_nacl), GFP_KERNEL);
352 if (!nacl) {
353 pr_err("Unable to allocate struct tcm_qla2xxx_nacl\n");
354 return NULL;
355 }
356
357 return &nacl->se_node_acl;
358}
359
360static void tcm_qla2xxx_release_fabric_acl(
361 struct se_portal_group *se_tpg,
362 struct se_node_acl *se_nacl)
363{
364 struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
365 struct tcm_qla2xxx_nacl, se_node_acl);
366 kfree(nacl);
367}
368
369static u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg) 254static u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg)
370{ 255{
371 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 256 struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
@@ -429,7 +314,7 @@ static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
429 cmd->cmd_flags |= BIT_14; 314 cmd->cmd_flags |= BIT_14;
430 } 315 }
431 316
432 return target_put_sess_cmd(se_cmd->se_sess, se_cmd); 317 return target_put_sess_cmd(se_cmd);
433} 318}
434 319
435/* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying 320/* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying
@@ -489,7 +374,7 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
489{ 374{
490 struct qla_tgt_cmd *cmd = container_of(se_cmd, 375 struct qla_tgt_cmd *cmd = container_of(se_cmd,
491 struct qla_tgt_cmd, se_cmd); 376 struct qla_tgt_cmd, se_cmd);
492 377 cmd->cmd_flags |= BIT_3;
493 cmd->bufflen = se_cmd->data_length; 378 cmd->bufflen = se_cmd->data_length;
494 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); 379 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
495 380
@@ -520,7 +405,7 @@ static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd)
520 se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) { 405 se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
521 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 406 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
522 wait_for_completion_timeout(&se_cmd->t_transport_stop_comp, 407 wait_for_completion_timeout(&se_cmd->t_transport_stop_comp,
523 3000); 408 3 * HZ);
524 return 0; 409 return 0;
525 } 410 }
526 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 411 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
@@ -533,19 +418,6 @@ static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl)
533 return; 418 return;
534} 419}
535 420
536static u32 tcm_qla2xxx_get_task_tag(struct se_cmd *se_cmd)
537{
538 struct qla_tgt_cmd *cmd;
539
540 /* check for task mgmt cmd */
541 if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
542 return 0xffffffff;
543
544 cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
545
546 return cmd->tag;
547}
548
549static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd) 421static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd)
550{ 422{
551 return 0; 423 return 0;
@@ -669,12 +541,10 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
669 cmd->cmd_flags |= BIT_4; 541 cmd->cmd_flags |= BIT_4;
670 cmd->bufflen = se_cmd->data_length; 542 cmd->bufflen = se_cmd->data_length;
671 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); 543 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
672 cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
673 544
674 cmd->sg_cnt = se_cmd->t_data_nents; 545 cmd->sg_cnt = se_cmd->t_data_nents;
675 cmd->sg = se_cmd->t_data_sg; 546 cmd->sg = se_cmd->t_data_sg;
676 cmd->offset = 0; 547 cmd->offset = 0;
677 cmd->cmd_flags |= BIT_3;
678 548
679 cmd->prot_sg_cnt = se_cmd->t_prot_nents; 549 cmd->prot_sg_cnt = se_cmd->t_prot_nents;
680 cmd->prot_sg = se_cmd->t_prot_sg; 550 cmd->prot_sg = se_cmd->t_prot_sg;
@@ -699,7 +569,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
699 cmd->sg_cnt = 0; 569 cmd->sg_cnt = 0;
700 cmd->offset = 0; 570 cmd->offset = 0;
701 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); 571 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
702 cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
703 if (cmd->cmd_flags & BIT_5) { 572 if (cmd->cmd_flags & BIT_5) {
704 pr_crit("Bit_5 already set for cmd = %p.\n", cmd); 573 pr_crit("Bit_5 already set for cmd = %p.\n", cmd);
705 dump_stack(); 574 dump_stack();
@@ -764,14 +633,7 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
764{ 633{
765 struct qla_tgt_cmd *cmd = container_of(se_cmd, 634 struct qla_tgt_cmd *cmd = container_of(se_cmd,
766 struct qla_tgt_cmd, se_cmd); 635 struct qla_tgt_cmd, se_cmd);
767 struct scsi_qla_host *vha = cmd->vha; 636 qlt_abort_cmd(cmd);
768 struct qla_hw_data *ha = vha->hw;
769
770 if (!cmd->sg_mapped)
771 return;
772
773 pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
774 cmd->sg_mapped = 0;
775} 637}
776 638
777static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, 639static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
@@ -826,17 +688,6 @@ static void tcm_qla2xxx_release_session(struct kref *kref)
826 qlt_unreg_sess(se_sess->fabric_sess_ptr); 688 qlt_unreg_sess(se_sess->fabric_sess_ptr);
827} 689}
828 690
829static void tcm_qla2xxx_put_session(struct se_session *se_sess)
830{
831 struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr;
832 struct qla_hw_data *ha = sess->vha->hw;
833 unsigned long flags;
834
835 spin_lock_irqsave(&ha->hardware_lock, flags);
836 kref_put(&se_sess->sess_kref, tcm_qla2xxx_release_session);
837 spin_unlock_irqrestore(&ha->hardware_lock, flags);
838}
839
840static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) 691static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess)
841{ 692{
842 if (!sess) 693 if (!sess)
@@ -852,53 +703,20 @@ static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess)
852 target_sess_cmd_list_set_waiting(sess->se_sess); 703 target_sess_cmd_list_set_waiting(sess->se_sess);
853} 704}
854 705
855static struct se_node_acl *tcm_qla2xxx_make_nodeacl( 706static int tcm_qla2xxx_init_nodeacl(struct se_node_acl *se_nacl,
856 struct se_portal_group *se_tpg, 707 const char *name)
857 struct config_group *group,
858 const char *name)
859{ 708{
860 struct se_node_acl *se_nacl, *se_nacl_new; 709 struct tcm_qla2xxx_nacl *nacl =
861 struct tcm_qla2xxx_nacl *nacl; 710 container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
862 u64 wwnn; 711 u64 wwnn;
863 u32 qla2xxx_nexus_depth;
864 712
865 if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0) 713 if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0)
866 return ERR_PTR(-EINVAL); 714 return -EINVAL;
867
868 se_nacl_new = tcm_qla2xxx_alloc_fabric_acl(se_tpg);
869 if (!se_nacl_new)
870 return ERR_PTR(-ENOMEM);
871/* #warning FIXME: Hardcoded qla2xxx_nexus depth in tcm_qla2xxx_make_nodeacl */
872 qla2xxx_nexus_depth = 1;
873 715
874 /*
875 * se_nacl_new may be released by core_tpg_add_initiator_node_acl()
876 * when converting a NodeACL from demo mode -> explict
877 */
878 se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
879 name, qla2xxx_nexus_depth);
880 if (IS_ERR(se_nacl)) {
881 tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new);
882 return se_nacl;
883 }
884 /*
885 * Locate our struct tcm_qla2xxx_nacl and set the FC Nport WWPN
886 */
887 nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
888 nacl->nport_wwnn = wwnn; 716 nacl->nport_wwnn = wwnn;
889 tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn); 717 tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn);
890 718
891 return se_nacl; 719 return 0;
892}
893
894static void tcm_qla2xxx_drop_nodeacl(struct se_node_acl *se_acl)
895{
896 struct se_portal_group *se_tpg = se_acl->se_tpg;
897 struct tcm_qla2xxx_nacl *nacl = container_of(se_acl,
898 struct tcm_qla2xxx_nacl, se_node_acl);
899
900 core_tpg_del_initiator_node_acl(se_tpg, se_acl, 1);
901 kfree(nacl);
902} 720}
903 721
904/* Start items for tcm_qla2xxx_tpg_attrib_cit */ 722/* Start items for tcm_qla2xxx_tpg_attrib_cit */
@@ -1174,8 +992,7 @@ static struct se_portal_group *tcm_qla2xxx_make_tpg(
1174 tpg->tpg_attrib.cache_dynamic_acls = 1; 992 tpg->tpg_attrib.cache_dynamic_acls = 1;
1175 tpg->tpg_attrib.demo_mode_login_only = 1; 993 tpg->tpg_attrib.demo_mode_login_only = 1;
1176 994
1177 ret = core_tpg_register(&tcm_qla2xxx_ops, wwn, 995 ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);
1178 &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL);
1179 if (ret < 0) { 996 if (ret < 0) {
1180 kfree(tpg); 997 kfree(tpg);
1181 return NULL; 998 return NULL;
@@ -1294,8 +1111,7 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg(
1294 tpg->tpg_attrib.cache_dynamic_acls = 1; 1111 tpg->tpg_attrib.cache_dynamic_acls = 1;
1295 tpg->tpg_attrib.demo_mode_login_only = 1; 1112 tpg->tpg_attrib.demo_mode_login_only = 1;
1296 1113
1297 ret = core_tpg_register(&tcm_qla2xxx_npiv_ops, wwn, 1114 ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);
1298 &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL);
1299 if (ret < 0) { 1115 if (ret < 0) {
1300 kfree(tpg); 1116 kfree(tpg);
1301 return NULL; 1117 return NULL;
@@ -1323,9 +1139,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
1323 return NULL; 1139 return NULL;
1324 } 1140 }
1325 1141
1326 key = (((unsigned long)s_id[0] << 16) | 1142 key = sid_to_key(s_id);
1327 ((unsigned long)s_id[1] << 8) |
1328 (unsigned long)s_id[2]);
1329 pr_debug("find_sess_by_s_id: 0x%06x\n", key); 1143 pr_debug("find_sess_by_s_id: 0x%06x\n", key);
1330 1144
1331 se_nacl = btree_lookup32(&lport->lport_fcport_map, key); 1145 se_nacl = btree_lookup32(&lport->lport_fcport_map, key);
@@ -1360,9 +1174,7 @@ static void tcm_qla2xxx_set_sess_by_s_id(
1360 void *slot; 1174 void *slot;
1361 int rc; 1175 int rc;
1362 1176
1363 key = (((unsigned long)s_id[0] << 16) | 1177 key = sid_to_key(s_id);
1364 ((unsigned long)s_id[1] << 8) |
1365 (unsigned long)s_id[2]);
1366 pr_debug("set_sess_by_s_id: %06x\n", key); 1178 pr_debug("set_sess_by_s_id: %06x\n", key);
1367 1179
1368 slot = btree_lookup32(&lport->lport_fcport_map, key); 1180 slot = btree_lookup32(&lport->lport_fcport_map, key);
@@ -1718,6 +1530,10 @@ static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id,
1718 } 1530 }
1719 1531
1720 sess->conf_compl_supported = conf_compl_supported; 1532 sess->conf_compl_supported = conf_compl_supported;
1533
1534 /* Reset logout parameters to default */
1535 sess->logout_on_delete = 1;
1536 sess->keep_nport_handle = 0;
1721} 1537}
1722 1538
1723/* 1539/*
@@ -1987,14 +1803,10 @@ static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = {
1987static const struct target_core_fabric_ops tcm_qla2xxx_ops = { 1803static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
1988 .module = THIS_MODULE, 1804 .module = THIS_MODULE,
1989 .name = "qla2xxx", 1805 .name = "qla2xxx",
1806 .node_acl_size = sizeof(struct tcm_qla2xxx_nacl),
1990 .get_fabric_name = tcm_qla2xxx_get_fabric_name, 1807 .get_fabric_name = tcm_qla2xxx_get_fabric_name,
1991 .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident,
1992 .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, 1808 .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn,
1993 .tpg_get_tag = tcm_qla2xxx_get_tag, 1809 .tpg_get_tag = tcm_qla2xxx_get_tag,
1994 .tpg_get_default_depth = tcm_qla2xxx_get_default_depth,
1995 .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id,
1996 .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len,
1997 .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id,
1998 .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode, 1810 .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode,
1999 .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache, 1811 .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache,
2000 .tpg_check_demo_mode_write_protect = 1812 .tpg_check_demo_mode_write_protect =
@@ -2003,12 +1815,9 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
2003 tcm_qla2xxx_check_prod_write_protect, 1815 tcm_qla2xxx_check_prod_write_protect,
2004 .tpg_check_prot_fabric_only = tcm_qla2xxx_check_prot_fabric_only, 1816 .tpg_check_prot_fabric_only = tcm_qla2xxx_check_prot_fabric_only,
2005 .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only, 1817 .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only,
2006 .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl,
2007 .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl,
2008 .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, 1818 .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index,
2009 .check_stop_free = tcm_qla2xxx_check_stop_free, 1819 .check_stop_free = tcm_qla2xxx_check_stop_free,
2010 .release_cmd = tcm_qla2xxx_release_cmd, 1820 .release_cmd = tcm_qla2xxx_release_cmd,
2011 .put_session = tcm_qla2xxx_put_session,
2012 .shutdown_session = tcm_qla2xxx_shutdown_session, 1821 .shutdown_session = tcm_qla2xxx_shutdown_session,
2013 .close_session = tcm_qla2xxx_close_session, 1822 .close_session = tcm_qla2xxx_close_session,
2014 .sess_get_index = tcm_qla2xxx_sess_get_index, 1823 .sess_get_index = tcm_qla2xxx_sess_get_index,
@@ -2016,7 +1825,6 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
2016 .write_pending = tcm_qla2xxx_write_pending, 1825 .write_pending = tcm_qla2xxx_write_pending,
2017 .write_pending_status = tcm_qla2xxx_write_pending_status, 1826 .write_pending_status = tcm_qla2xxx_write_pending_status,
2018 .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, 1827 .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs,
2019 .get_task_tag = tcm_qla2xxx_get_task_tag,
2020 .get_cmd_state = tcm_qla2xxx_get_cmd_state, 1828 .get_cmd_state = tcm_qla2xxx_get_cmd_state,
2021 .queue_data_in = tcm_qla2xxx_queue_data_in, 1829 .queue_data_in = tcm_qla2xxx_queue_data_in,
2022 .queue_status = tcm_qla2xxx_queue_status, 1830 .queue_status = tcm_qla2xxx_queue_status,
@@ -2030,12 +1838,7 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
2030 .fabric_drop_wwn = tcm_qla2xxx_drop_lport, 1838 .fabric_drop_wwn = tcm_qla2xxx_drop_lport,
2031 .fabric_make_tpg = tcm_qla2xxx_make_tpg, 1839 .fabric_make_tpg = tcm_qla2xxx_make_tpg,
2032 .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, 1840 .fabric_drop_tpg = tcm_qla2xxx_drop_tpg,
2033 .fabric_post_link = NULL, 1841 .fabric_init_nodeacl = tcm_qla2xxx_init_nodeacl,
2034 .fabric_pre_unlink = NULL,
2035 .fabric_make_np = NULL,
2036 .fabric_drop_np = NULL,
2037 .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl,
2038 .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl,
2039 1842
2040 .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs, 1843 .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs,
2041 .tfc_tpg_base_attrs = tcm_qla2xxx_tpg_attrs, 1844 .tfc_tpg_base_attrs = tcm_qla2xxx_tpg_attrs,
@@ -2045,26 +1848,19 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
2045static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { 1848static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
2046 .module = THIS_MODULE, 1849 .module = THIS_MODULE,
2047 .name = "qla2xxx_npiv", 1850 .name = "qla2xxx_npiv",
1851 .node_acl_size = sizeof(struct tcm_qla2xxx_nacl),
2048 .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, 1852 .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name,
2049 .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident,
2050 .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, 1853 .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn,
2051 .tpg_get_tag = tcm_qla2xxx_get_tag, 1854 .tpg_get_tag = tcm_qla2xxx_get_tag,
2052 .tpg_get_default_depth = tcm_qla2xxx_get_default_depth,
2053 .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id,
2054 .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len,
2055 .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id,
2056 .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode, 1855 .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode,
2057 .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache, 1856 .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache,
2058 .tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_demo_mode, 1857 .tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_demo_mode,
2059 .tpg_check_prod_mode_write_protect = 1858 .tpg_check_prod_mode_write_protect =
2060 tcm_qla2xxx_check_prod_write_protect, 1859 tcm_qla2xxx_check_prod_write_protect,
2061 .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only, 1860 .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only,
2062 .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl,
2063 .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl,
2064 .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, 1861 .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index,
2065 .check_stop_free = tcm_qla2xxx_check_stop_free, 1862 .check_stop_free = tcm_qla2xxx_check_stop_free,
2066 .release_cmd = tcm_qla2xxx_release_cmd, 1863 .release_cmd = tcm_qla2xxx_release_cmd,
2067 .put_session = tcm_qla2xxx_put_session,
2068 .shutdown_session = tcm_qla2xxx_shutdown_session, 1864 .shutdown_session = tcm_qla2xxx_shutdown_session,
2069 .close_session = tcm_qla2xxx_close_session, 1865 .close_session = tcm_qla2xxx_close_session,
2070 .sess_get_index = tcm_qla2xxx_sess_get_index, 1866 .sess_get_index = tcm_qla2xxx_sess_get_index,
@@ -2072,7 +1868,6 @@ static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
2072 .write_pending = tcm_qla2xxx_write_pending, 1868 .write_pending = tcm_qla2xxx_write_pending,
2073 .write_pending_status = tcm_qla2xxx_write_pending_status, 1869 .write_pending_status = tcm_qla2xxx_write_pending_status,
2074 .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, 1870 .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs,
2075 .get_task_tag = tcm_qla2xxx_get_task_tag,
2076 .get_cmd_state = tcm_qla2xxx_get_cmd_state, 1871 .get_cmd_state = tcm_qla2xxx_get_cmd_state,
2077 .queue_data_in = tcm_qla2xxx_queue_data_in, 1872 .queue_data_in = tcm_qla2xxx_queue_data_in,
2078 .queue_status = tcm_qla2xxx_queue_status, 1873 .queue_status = tcm_qla2xxx_queue_status,
@@ -2086,12 +1881,7 @@ static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
2086 .fabric_drop_wwn = tcm_qla2xxx_npiv_drop_lport, 1881 .fabric_drop_wwn = tcm_qla2xxx_npiv_drop_lport,
2087 .fabric_make_tpg = tcm_qla2xxx_npiv_make_tpg, 1882 .fabric_make_tpg = tcm_qla2xxx_npiv_make_tpg,
2088 .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, 1883 .fabric_drop_tpg = tcm_qla2xxx_drop_tpg,
2089 .fabric_post_link = NULL, 1884 .fabric_init_nodeacl = tcm_qla2xxx_init_nodeacl,
2090 .fabric_pre_unlink = NULL,
2091 .fabric_make_np = NULL,
2092 .fabric_drop_np = NULL,
2093 .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl,
2094 .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl,
2095 1885
2096 .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs, 1886 .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs,
2097 .tfc_tpg_base_attrs = tcm_qla2xxx_npiv_tpg_attrs, 1887 .tfc_tpg_base_attrs = tcm_qla2xxx_npiv_tpg_attrs,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h
index 23295115c9fc..3bbf4cb6fd97 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h
@@ -13,6 +13,8 @@
13#include "qla_target.h" 13#include "qla_target.h"
14 14
15struct tcm_qla2xxx_nacl { 15struct tcm_qla2xxx_nacl {
16 struct se_node_acl se_node_acl;
17
16 /* From libfc struct fc_rport->port_id */ 18 /* From libfc struct fc_rport->port_id */
17 u32 nport_id; 19 u32 nport_id;
18 /* Binary World Wide unique Node Name for remote FC Initiator Nport */ 20 /* Binary World Wide unique Node Name for remote FC Initiator Nport */
@@ -23,8 +25,6 @@ struct tcm_qla2xxx_nacl {
23 struct qla_tgt_sess *qla_tgt_sess; 25 struct qla_tgt_sess *qla_tgt_sess;
24 /* Pointer to TCM FC nexus */ 26 /* Pointer to TCM FC nexus */
25 struct se_session *nport_nexus; 27 struct se_session *nport_nexus;
26 /* Returned by tcm_qla2xxx_make_nodeacl() */
27 struct se_node_acl se_node_acl;
28}; 28};
29 29
30struct tcm_qla2xxx_tpg_attrib { 30struct tcm_qla2xxx_tpg_attrib {
@@ -57,8 +57,6 @@ struct tcm_qla2xxx_fc_loopid {
57}; 57};
58 58
59struct tcm_qla2xxx_lport { 59struct tcm_qla2xxx_lport {
60 /* SCSI protocol the lport is providing */
61 u8 lport_proto_id;
62 /* Binary World Wide unique Port Name for FC Target Lport */ 60 /* Binary World Wide unique Port Name for FC Target Lport */
63 u64 lport_wwpn; 61 u64 lport_wwpn;
64 /* Binary World Wide unique Port Name for FC NPIV Target Lport */ 62 /* Binary World Wide unique Port Name for FC NPIV Target Lport */