diff options
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 25 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 77 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.h | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_sbc.c | 18 | ||||
| -rw-r--r-- | drivers/target/target_core_transport.c | 1 |
7 files changed, 111 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index bd4708a422cd..20fd974f903a 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
| @@ -149,6 +149,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | |||
| 149 | int | 149 | int |
| 150 | qla24xx_disable_vp(scsi_qla_host_t *vha) | 150 | qla24xx_disable_vp(scsi_qla_host_t *vha) |
| 151 | { | 151 | { |
| 152 | unsigned long flags; | ||
| 152 | int ret; | 153 | int ret; |
| 153 | 154 | ||
| 154 | ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); | 155 | ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); |
| @@ -156,7 +157,9 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) | |||
| 156 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 157 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
| 157 | 158 | ||
| 158 | /* Remove port id from vp target map */ | 159 | /* Remove port id from vp target map */ |
| 160 | spin_lock_irqsave(&vha->hw->vport_slock, flags); | ||
| 159 | qlt_update_vp_map(vha, RESET_AL_PA); | 161 | qlt_update_vp_map(vha, RESET_AL_PA); |
| 162 | spin_unlock_irqrestore(&vha->hw->vport_slock, flags); | ||
| 160 | 163 | ||
| 161 | qla2x00_mark_vp_devices_dead(vha); | 164 | qla2x00_mark_vp_devices_dead(vha); |
| 162 | atomic_set(&vha->vp_state, VP_FAILED); | 165 | atomic_set(&vha->vp_state, VP_FAILED); |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 0e09d8f433d1..62aa5584f644 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
| @@ -557,6 +557,7 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, | |||
| 557 | int pmap_len; | 557 | int pmap_len; |
| 558 | fc_port_t *fcport; | 558 | fc_port_t *fcport; |
| 559 | int global_resets; | 559 | int global_resets; |
| 560 | unsigned long flags; | ||
| 560 | 561 | ||
| 561 | retry: | 562 | retry: |
| 562 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); | 563 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); |
| @@ -625,10 +626,10 @@ retry: | |||
| 625 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, | 626 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, |
| 626 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); | 627 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); |
| 627 | 628 | ||
| 628 | sess->s_id = fcport->d_id; | 629 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 629 | sess->loop_id = fcport->loop_id; | 630 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
| 630 | sess->conf_compl_supported = !!(fcport->flags & | 631 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
| 631 | FCF_CONF_COMP_SUPPORTED); | 632 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 632 | 633 | ||
| 633 | res = true; | 634 | res = true; |
| 634 | 635 | ||
| @@ -740,10 +741,9 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
| 740 | qlt_undelete_sess(sess); | 741 | qlt_undelete_sess(sess); |
| 741 | 742 | ||
| 742 | kref_get(&sess->se_sess->sess_kref); | 743 | kref_get(&sess->se_sess->sess_kref); |
| 743 | sess->s_id = fcport->d_id; | 744 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
| 744 | sess->loop_id = fcport->loop_id; | 745 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
| 745 | sess->conf_compl_supported = !!(fcport->flags & | 746 | |
| 746 | FCF_CONF_COMP_SUPPORTED); | ||
| 747 | if (sess->local && !local) | 747 | if (sess->local && !local) |
| 748 | sess->local = 0; | 748 | sess->local = 0; |
| 749 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 749 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| @@ -796,8 +796,7 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
| 796 | */ | 796 | */ |
| 797 | kref_get(&sess->se_sess->sess_kref); | 797 | kref_get(&sess->se_sess->sess_kref); |
| 798 | 798 | ||
| 799 | sess->conf_compl_supported = !!(fcport->flags & | 799 | sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED); |
| 800 | FCF_CONF_COMP_SUPPORTED); | ||
| 801 | BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); | 800 | BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); |
| 802 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); | 801 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); |
| 803 | 802 | ||
| @@ -869,10 +868,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 869 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, | 868 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, |
| 870 | "Reappeared sess %p\n", sess); | 869 | "Reappeared sess %p\n", sess); |
| 871 | } | 870 | } |
| 872 | sess->s_id = fcport->d_id; | 871 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, |
| 873 | sess->loop_id = fcport->loop_id; | 872 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); |
| 874 | sess->conf_compl_supported = !!(fcport->flags & | ||
| 875 | FCF_CONF_COMP_SUPPORTED); | ||
| 876 | } | 873 | } |
| 877 | 874 | ||
| 878 | if (sess && sess->local) { | 875 | if (sess && sess->local) { |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 170af1571214..bad749561ec2 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
| @@ -648,6 +648,7 @@ struct qla_tgt_func_tmpl { | |||
| 648 | 648 | ||
| 649 | int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, | 649 | int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, |
| 650 | void *, uint8_t *, uint16_t); | 650 | void *, uint8_t *, uint16_t); |
| 651 | void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool); | ||
| 651 | struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, | 652 | struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, |
| 652 | const uint16_t); | 653 | const uint16_t); |
| 653 | struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, | 654 | struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 2358c16c4c8e..3d74f2f39ae1 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
| @@ -237,7 +237,7 @@ static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) | |||
| 237 | struct tcm_qla2xxx_tpg, se_tpg); | 237 | struct tcm_qla2xxx_tpg, se_tpg); |
| 238 | struct tcm_qla2xxx_lport *lport = tpg->lport; | 238 | struct tcm_qla2xxx_lport *lport = tpg->lport; |
| 239 | 239 | ||
| 240 | return &lport->lport_name[0]; | 240 | return lport->lport_naa_name; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) | 243 | static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) |
| @@ -1457,6 +1457,78 @@ static int tcm_qla2xxx_check_initiator_node_acl( | |||
| 1457 | return 0; | 1457 | return 0; |
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
| 1460 | static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, | ||
| 1461 | uint16_t loop_id, bool conf_compl_supported) | ||
| 1462 | { | ||
| 1463 | struct qla_tgt *tgt = sess->tgt; | ||
| 1464 | struct qla_hw_data *ha = tgt->ha; | ||
| 1465 | struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; | ||
| 1466 | struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; | ||
| 1467 | struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, | ||
| 1468 | struct tcm_qla2xxx_nacl, se_node_acl); | ||
| 1469 | u32 key; | ||
| 1470 | |||
| 1471 | |||
| 1472 | if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24) | ||
| 1473 | pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n", | ||
| 1474 | sess, | ||
| 1475 | sess->port_name[0], sess->port_name[1], | ||
| 1476 | sess->port_name[2], sess->port_name[3], | ||
| 1477 | sess->port_name[4], sess->port_name[5], | ||
| 1478 | sess->port_name[6], sess->port_name[7], | ||
| 1479 | sess->loop_id, loop_id, | ||
| 1480 | sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, | ||
| 1481 | s_id.b.domain, s_id.b.area, s_id.b.al_pa); | ||
| 1482 | |||
| 1483 | if (sess->loop_id != loop_id) { | ||
| 1484 | /* | ||
| 1485 | * Because we can shuffle loop IDs around and we | ||
| 1486 | * update different sessions non-atomically, we might | ||
| 1487 | * have overwritten this session's old loop ID | ||
| 1488 | * already, and we might end up overwriting some other | ||
| 1489 | * session that will be updated later. So we have to | ||
| 1490 | * be extra careful and we can't warn about those things... | ||
| 1491 | */ | ||
| 1492 | if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl) | ||
| 1493 | lport->lport_loopid_map[sess->loop_id].se_nacl = NULL; | ||
| 1494 | |||
| 1495 | lport->lport_loopid_map[loop_id].se_nacl = se_nacl; | ||
| 1496 | |||
| 1497 | sess->loop_id = loop_id; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | if (sess->s_id.b24 != s_id.b24) { | ||
| 1501 | key = (((u32) sess->s_id.b.domain << 16) | | ||
| 1502 | ((u32) sess->s_id.b.area << 8) | | ||
| 1503 | ((u32) sess->s_id.b.al_pa)); | ||
| 1504 | |||
| 1505 | if (btree_lookup32(&lport->lport_fcport_map, key)) | ||
| 1506 | WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl, | ||
| 1507 | "Found wrong se_nacl when updating s_id %x:%x:%x\n", | ||
| 1508 | sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); | ||
| 1509 | else | ||
| 1510 | WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n", | ||
| 1511 | sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); | ||
| 1512 | |||
| 1513 | key = (((u32) s_id.b.domain << 16) | | ||
| 1514 | ((u32) s_id.b.area << 8) | | ||
| 1515 | ((u32) s_id.b.al_pa)); | ||
| 1516 | |||
| 1517 | if (btree_lookup32(&lport->lport_fcport_map, key)) { | ||
| 1518 | WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n", | ||
| 1519 | s_id.b.domain, s_id.b.area, s_id.b.al_pa); | ||
| 1520 | btree_update32(&lport->lport_fcport_map, key, se_nacl); | ||
| 1521 | } else { | ||
| 1522 | btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC); | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | sess->s_id = s_id; | ||
| 1526 | nacl->nport_id = key; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | sess->conf_compl_supported = conf_compl_supported; | ||
| 1530 | } | ||
| 1531 | |||
| 1460 | /* | 1532 | /* |
| 1461 | * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. | 1533 | * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. |
| 1462 | */ | 1534 | */ |
| @@ -1467,6 +1539,7 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { | |||
| 1467 | .free_cmd = tcm_qla2xxx_free_cmd, | 1539 | .free_cmd = tcm_qla2xxx_free_cmd, |
| 1468 | .free_mcmd = tcm_qla2xxx_free_mcmd, | 1540 | .free_mcmd = tcm_qla2xxx_free_mcmd, |
| 1469 | .free_session = tcm_qla2xxx_free_session, | 1541 | .free_session = tcm_qla2xxx_free_session, |
| 1542 | .update_sess = tcm_qla2xxx_update_sess, | ||
| 1470 | .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, | 1543 | .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, |
| 1471 | .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, | 1544 | .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, |
| 1472 | .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, | 1545 | .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, |
| @@ -1534,6 +1607,7 @@ static struct se_wwn *tcm_qla2xxx_make_lport( | |||
| 1534 | lport->lport_wwpn = wwpn; | 1607 | lport->lport_wwpn = wwpn; |
| 1535 | tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, | 1608 | tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, |
| 1536 | wwpn); | 1609 | wwpn); |
| 1610 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) wwpn); | ||
| 1537 | 1611 | ||
| 1538 | ret = tcm_qla2xxx_init_lport(lport); | 1612 | ret = tcm_qla2xxx_init_lport(lport); |
| 1539 | if (ret != 0) | 1613 | if (ret != 0) |
| @@ -1601,6 +1675,7 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( | |||
| 1601 | lport->lport_npiv_wwnn = npiv_wwnn; | 1675 | lport->lport_npiv_wwnn = npiv_wwnn; |
| 1602 | tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], | 1676 | tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], |
| 1603 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); | 1677 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); |
| 1678 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); | ||
| 1604 | 1679 | ||
| 1605 | /* FIXME: tcm_qla2xxx_npiv_make_lport */ | 1680 | /* FIXME: tcm_qla2xxx_npiv_make_lport */ |
| 1606 | ret = -ENOSYS; | 1681 | ret = -ENOSYS; |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 825498103352..9ba075fe9781 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h | |||
| @@ -61,6 +61,8 @@ struct tcm_qla2xxx_lport { | |||
| 61 | u64 lport_npiv_wwnn; | 61 | u64 lport_npiv_wwnn; |
| 62 | /* ASCII formatted WWPN for FC Target Lport */ | 62 | /* ASCII formatted WWPN for FC Target Lport */ |
| 63 | char lport_name[TCM_QLA2XXX_NAMELEN]; | 63 | char lport_name[TCM_QLA2XXX_NAMELEN]; |
| 64 | /* ASCII formatted naa WWPN for VPD page 83 etc */ | ||
| 65 | char lport_naa_name[TCM_QLA2XXX_NAMELEN]; | ||
| 64 | /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ | 66 | /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ |
| 65 | char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; | 67 | char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; |
| 66 | /* map for fc_port pointers in 24-bit FC Port ID space */ | 68 | /* map for fc_port pointers in 24-bit FC Port ID space */ |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 868f8aa04f13..a6e27d967c7b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
| @@ -135,6 +135,12 @@ static int sbc_emulate_verify(struct se_cmd *cmd) | |||
| 135 | return 0; | 135 | return 0; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int sbc_emulate_noop(struct se_cmd *cmd) | ||
| 139 | { | ||
| 140 | target_complete_cmd(cmd, GOOD); | ||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 138 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) | 144 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) |
| 139 | { | 145 | { |
| 140 | return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; | 146 | return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; |
| @@ -531,6 +537,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
| 531 | size = 0; | 537 | size = 0; |
| 532 | cmd->execute_cmd = sbc_emulate_verify; | 538 | cmd->execute_cmd = sbc_emulate_verify; |
| 533 | break; | 539 | break; |
| 540 | case REZERO_UNIT: | ||
| 541 | case SEEK_6: | ||
| 542 | case SEEK_10: | ||
| 543 | /* | ||
| 544 | * There are still clients out there which use these old SCSI-2 | ||
| 545 | * commands. This mainly happens when running VMs with legacy | ||
| 546 | * guest systems, connected via SCSI command pass-through to | ||
| 547 | * iSCSI targets. Make them happy and return status GOOD. | ||
| 548 | */ | ||
| 549 | size = 0; | ||
| 550 | cmd->execute_cmd = sbc_emulate_noop; | ||
| 551 | break; | ||
| 534 | default: | 552 | default: |
| 535 | ret = spc_parse_cdb(cmd, &size); | 553 | ret = spc_parse_cdb(cmd, &size); |
| 536 | if (ret) | 554 | if (ret) |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c33baff86aa6..9097155e9ebe 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -1616,7 +1616,6 @@ static void target_complete_tmr_failure(struct work_struct *work) | |||
| 1616 | 1616 | ||
| 1617 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; | 1617 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; |
| 1618 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); | 1618 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); |
| 1619 | transport_generic_free_cmd(se_cmd, 0); | ||
| 1620 | } | 1619 | } |
| 1621 | 1620 | ||
| 1622 | /** | 1621 | /** |
