diff options
Diffstat (limited to 'drivers/target/loopback/tcm_loop.c')
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 182 |
1 files changed, 9 insertions, 173 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 51f0c895c6a5..a556bdebd775 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -35,14 +35,11 @@ | |||
35 | #include <target/target_core_base.h> | 35 | #include <target/target_core_base.h> |
36 | #include <target/target_core_fabric.h> | 36 | #include <target/target_core_fabric.h> |
37 | #include <target/target_core_fabric_configfs.h> | 37 | #include <target/target_core_fabric_configfs.h> |
38 | #include <target/target_core_configfs.h> | ||
39 | 38 | ||
40 | #include "tcm_loop.h" | 39 | #include "tcm_loop.h" |
41 | 40 | ||
42 | #define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev) | 41 | #define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev) |
43 | 42 | ||
44 | static const struct target_core_fabric_ops loop_ops; | ||
45 | |||
46 | static struct workqueue_struct *tcm_loop_workqueue; | 43 | static struct workqueue_struct *tcm_loop_workqueue; |
47 | static struct kmem_cache *tcm_loop_cmd_cache; | 44 | static struct kmem_cache *tcm_loop_cmd_cache; |
48 | 45 | ||
@@ -165,6 +162,7 @@ static void tcm_loop_submission_work(struct work_struct *work) | |||
165 | transfer_length = scsi_bufflen(sc); | 162 | transfer_length = scsi_bufflen(sc); |
166 | } | 163 | } |
167 | 164 | ||
165 | se_cmd->tag = tl_cmd->sc_cmd_tag; | ||
168 | rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, | 166 | rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, |
169 | &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, | 167 | &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, |
170 | transfer_length, TCM_SIMPLE_TAG, | 168 | transfer_length, TCM_SIMPLE_TAG, |
@@ -217,7 +215,7 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) | |||
217 | * to struct scsi_device | 215 | * to struct scsi_device |
218 | */ | 216 | */ |
219 | static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, | 217 | static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, |
220 | int lun, int task, enum tcm_tmreq_table tmr) | 218 | u64 lun, int task, enum tcm_tmreq_table tmr) |
221 | { | 219 | { |
222 | struct se_cmd *se_cmd = NULL; | 220 | struct se_cmd *se_cmd = NULL; |
223 | struct se_session *se_sess; | 221 | struct se_session *se_sess; |
@@ -409,7 +407,7 @@ static int tcm_loop_driver_probe(struct device *dev) | |||
409 | sh->max_id = 2; | 407 | sh->max_id = 2; |
410 | sh->max_lun = 0; | 408 | sh->max_lun = 0; |
411 | sh->max_channel = 0; | 409 | sh->max_channel = 0; |
412 | sh->max_cmd_len = TL_SCSI_MAX_CMD_LEN; | 410 | sh->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE; |
413 | 411 | ||
414 | host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION | | 412 | host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION | |
415 | SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION | | 413 | SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION | |
@@ -520,147 +518,26 @@ static char *tcm_loop_get_fabric_name(void) | |||
520 | return "loopback"; | 518 | return "loopback"; |
521 | } | 519 | } |
522 | 520 | ||
523 | static u8 tcm_loop_get_fabric_proto_ident(struct se_portal_group *se_tpg) | 521 | static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg) |
524 | { | 522 | { |
525 | struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr; | 523 | return container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg); |
526 | struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; | ||
527 | /* | ||
528 | * tl_proto_id is set at tcm_loop_configfs.c:tcm_loop_make_scsi_hba() | ||
529 | * time based on the protocol dependent prefix of the passed configfs group. | ||
530 | * | ||
531 | * Based upon tl_proto_id, TCM_Loop emulates the requested fabric | ||
532 | * ProtocolID using target_core_fabric_lib.c symbols. | ||
533 | */ | ||
534 | switch (tl_hba->tl_proto_id) { | ||
535 | case SCSI_PROTOCOL_SAS: | ||
536 | return sas_get_fabric_proto_ident(se_tpg); | ||
537 | case SCSI_PROTOCOL_FCP: | ||
538 | return fc_get_fabric_proto_ident(se_tpg); | ||
539 | case SCSI_PROTOCOL_ISCSI: | ||
540 | return iscsi_get_fabric_proto_ident(se_tpg); | ||
541 | default: | ||
542 | pr_err("Unknown tl_proto_id: 0x%02x, using" | ||
543 | " SAS emulation\n", tl_hba->tl_proto_id); | ||
544 | break; | ||
545 | } | ||
546 | |||
547 | return sas_get_fabric_proto_ident(se_tpg); | ||
548 | } | 524 | } |
549 | 525 | ||
550 | static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg) | 526 | static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg) |
551 | { | 527 | { |
552 | struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr; | ||
553 | /* | 528 | /* |
554 | * Return the passed NAA identifier for the SAS Target Port | 529 | * Return the passed NAA identifier for the SAS Target Port |
555 | */ | 530 | */ |
556 | return &tl_tpg->tl_hba->tl_wwn_address[0]; | 531 | return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0]; |
557 | } | 532 | } |
558 | 533 | ||
559 | static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg) | 534 | static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg) |
560 | { | 535 | { |
561 | struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr; | ||
562 | /* | 536 | /* |
563 | * This Tag is used when forming SCSI Name identifier in EVPD=1 0x83 | 537 | * This Tag is used when forming SCSI Name identifier in EVPD=1 0x83 |
564 | * to represent the SCSI Target Port. | 538 | * to represent the SCSI Target Port. |
565 | */ | 539 | */ |
566 | return tl_tpg->tl_tpgt; | 540 | return tl_tpg(se_tpg)->tl_tpgt; |
567 | } | ||
568 | |||
569 | static u32 tcm_loop_get_default_depth(struct se_portal_group *se_tpg) | ||
570 | { | ||
571 | return 1; | ||
572 | } | ||
573 | |||
574 | static u32 tcm_loop_get_pr_transport_id( | ||
575 | struct se_portal_group *se_tpg, | ||
576 | struct se_node_acl *se_nacl, | ||
577 | struct t10_pr_registration *pr_reg, | ||
578 | int *format_code, | ||
579 | unsigned char *buf) | ||
580 | { | ||
581 | struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr; | ||
582 | struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; | ||
583 | |||
584 | switch (tl_hba->tl_proto_id) { | ||
585 | case SCSI_PROTOCOL_SAS: | ||
586 | return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
587 | format_code, buf); | ||
588 | case SCSI_PROTOCOL_FCP: | ||
589 | return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
590 | format_code, buf); | ||
591 | case SCSI_PROTOCOL_ISCSI: | ||
592 | return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
593 | format_code, buf); | ||
594 | default: | ||
595 | pr_err("Unknown tl_proto_id: 0x%02x, using" | ||
596 | " SAS emulation\n", tl_hba->tl_proto_id); | ||
597 | break; | ||
598 | } | ||
599 | |||
600 | return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
601 | format_code, buf); | ||
602 | } | ||
603 | |||
604 | static u32 tcm_loop_get_pr_transport_id_len( | ||
605 | struct se_portal_group *se_tpg, | ||
606 | struct se_node_acl *se_nacl, | ||
607 | struct t10_pr_registration *pr_reg, | ||
608 | int *format_code) | ||
609 | { | ||
610 | struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr; | ||
611 | struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; | ||
612 | |||
613 | switch (tl_hba->tl_proto_id) { | ||
614 | case SCSI_PROTOCOL_SAS: | ||
615 | return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
616 | format_code); | ||
617 | case SCSI_PROTOCOL_FCP: | ||
618 | return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
619 | format_code); | ||
620 | case SCSI_PROTOCOL_ISCSI: | ||
621 | return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
622 | format_code); | ||
623 | default: | ||
624 | pr_err("Unknown tl_proto_id: 0x%02x, using" | ||
625 | " SAS emulation\n", tl_hba->tl_proto_id); | ||
626 | break; | ||
627 | } | ||
628 | |||
629 | return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
630 | format_code); | ||
631 | } | ||
632 | |||
633 | /* | ||
634 | * Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above | ||
635 | * Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations. | ||
636 | */ | ||
637 | static char *tcm_loop_parse_pr_out_transport_id( | ||
638 | struct se_portal_group *se_tpg, | ||
639 | const char *buf, | ||
640 | u32 *out_tid_len, | ||
641 | char **port_nexus_ptr) | ||
642 | { | ||
643 | struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr; | ||
644 | struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; | ||
645 | |||
646 | switch (tl_hba->tl_proto_id) { | ||
647 | case SCSI_PROTOCOL_SAS: | ||
648 | return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
649 | port_nexus_ptr); | ||
650 | case SCSI_PROTOCOL_FCP: | ||
651 | return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
652 | port_nexus_ptr); | ||
653 | case SCSI_PROTOCOL_ISCSI: | ||
654 | return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
655 | port_nexus_ptr); | ||
656 | default: | ||
657 | pr_err("Unknown tl_proto_id: 0x%02x, using" | ||
658 | " SAS emulation\n", tl_hba->tl_proto_id); | ||
659 | break; | ||
660 | } | ||
661 | |||
662 | return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
663 | port_nexus_ptr); | ||
664 | } | 541 | } |
665 | 542 | ||
666 | /* | 543 | /* |
@@ -703,30 +580,6 @@ static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg) | |||
703 | return tl_tpg->tl_fabric_prot_type; | 580 | return tl_tpg->tl_fabric_prot_type; |
704 | } | 581 | } |
705 | 582 | ||
706 | static struct se_node_acl *tcm_loop_tpg_alloc_fabric_acl( | ||
707 | struct se_portal_group *se_tpg) | ||
708 | { | ||
709 | struct tcm_loop_nacl *tl_nacl; | ||
710 | |||
711 | tl_nacl = kzalloc(sizeof(struct tcm_loop_nacl), GFP_KERNEL); | ||
712 | if (!tl_nacl) { | ||
713 | pr_err("Unable to allocate struct tcm_loop_nacl\n"); | ||
714 | return NULL; | ||
715 | } | ||
716 | |||
717 | return &tl_nacl->se_node_acl; | ||
718 | } | ||
719 | |||
720 | static void tcm_loop_tpg_release_fabric_acl( | ||
721 | struct se_portal_group *se_tpg, | ||
722 | struct se_node_acl *se_nacl) | ||
723 | { | ||
724 | struct tcm_loop_nacl *tl_nacl = container_of(se_nacl, | ||
725 | struct tcm_loop_nacl, se_node_acl); | ||
726 | |||
727 | kfree(tl_nacl); | ||
728 | } | ||
729 | |||
730 | static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg) | 583 | static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg) |
731 | { | 584 | { |
732 | return 1; | 585 | return 1; |
@@ -742,14 +595,6 @@ static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl) | |||
742 | return; | 595 | return; |
743 | } | 596 | } |
744 | 597 | ||
745 | static u32 tcm_loop_get_task_tag(struct se_cmd *se_cmd) | ||
746 | { | ||
747 | struct tcm_loop_cmd *tl_cmd = container_of(se_cmd, | ||
748 | struct tcm_loop_cmd, tl_se_cmd); | ||
749 | |||
750 | return tl_cmd->sc_cmd_tag; | ||
751 | } | ||
752 | |||
753 | static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd) | 598 | static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd) |
754 | { | 599 | { |
755 | struct tcm_loop_cmd *tl_cmd = container_of(se_cmd, | 600 | struct tcm_loop_cmd *tl_cmd = container_of(se_cmd, |
@@ -902,7 +747,7 @@ static void tcm_loop_port_unlink( | |||
902 | se_lun->unpacked_lun); | 747 | se_lun->unpacked_lun); |
903 | if (!sd) { | 748 | if (!sd) { |
904 | pr_err("Unable to locate struct scsi_device for %d:%d:" | 749 | pr_err("Unable to locate struct scsi_device for %d:%d:" |
905 | "%d\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun); | 750 | "%llu\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun); |
906 | return; | 751 | return; |
907 | } | 752 | } |
908 | /* | 753 | /* |
@@ -1234,8 +1079,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg( | |||
1234 | /* | 1079 | /* |
1235 | * Register the tl_tpg as a emulated SAS TCM Target Endpoint | 1080 | * Register the tl_tpg as a emulated SAS TCM Target Endpoint |
1236 | */ | 1081 | */ |
1237 | ret = core_tpg_register(&loop_ops, wwn, &tl_tpg->tl_se_tpg, tl_tpg, | 1082 | ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id); |
1238 | TRANSPORT_TPG_TYPE_NORMAL); | ||
1239 | if (ret < 0) | 1083 | if (ret < 0) |
1240 | return ERR_PTR(-ENOMEM); | 1084 | return ERR_PTR(-ENOMEM); |
1241 | 1085 | ||
@@ -1386,13 +1230,8 @@ static const struct target_core_fabric_ops loop_ops = { | |||
1386 | .module = THIS_MODULE, | 1230 | .module = THIS_MODULE, |
1387 | .name = "loopback", | 1231 | .name = "loopback", |
1388 | .get_fabric_name = tcm_loop_get_fabric_name, | 1232 | .get_fabric_name = tcm_loop_get_fabric_name, |
1389 | .get_fabric_proto_ident = tcm_loop_get_fabric_proto_ident, | ||
1390 | .tpg_get_wwn = tcm_loop_get_endpoint_wwn, | 1233 | .tpg_get_wwn = tcm_loop_get_endpoint_wwn, |
1391 | .tpg_get_tag = tcm_loop_get_tag, | 1234 | .tpg_get_tag = tcm_loop_get_tag, |
1392 | .tpg_get_default_depth = tcm_loop_get_default_depth, | ||
1393 | .tpg_get_pr_transport_id = tcm_loop_get_pr_transport_id, | ||
1394 | .tpg_get_pr_transport_id_len = tcm_loop_get_pr_transport_id_len, | ||
1395 | .tpg_parse_pr_out_transport_id = tcm_loop_parse_pr_out_transport_id, | ||
1396 | .tpg_check_demo_mode = tcm_loop_check_demo_mode, | 1235 | .tpg_check_demo_mode = tcm_loop_check_demo_mode, |
1397 | .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache, | 1236 | .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache, |
1398 | .tpg_check_demo_mode_write_protect = | 1237 | .tpg_check_demo_mode_write_protect = |
@@ -1400,8 +1239,6 @@ static const struct target_core_fabric_ops loop_ops = { | |||
1400 | .tpg_check_prod_mode_write_protect = | 1239 | .tpg_check_prod_mode_write_protect = |
1401 | tcm_loop_check_prod_mode_write_protect, | 1240 | tcm_loop_check_prod_mode_write_protect, |
1402 | .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only, | 1241 | .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only, |
1403 | .tpg_alloc_fabric_acl = tcm_loop_tpg_alloc_fabric_acl, | ||
1404 | .tpg_release_fabric_acl = tcm_loop_tpg_release_fabric_acl, | ||
1405 | .tpg_get_inst_index = tcm_loop_get_inst_index, | 1242 | .tpg_get_inst_index = tcm_loop_get_inst_index, |
1406 | .check_stop_free = tcm_loop_check_stop_free, | 1243 | .check_stop_free = tcm_loop_check_stop_free, |
1407 | .release_cmd = tcm_loop_release_cmd, | 1244 | .release_cmd = tcm_loop_release_cmd, |
@@ -1411,7 +1248,6 @@ static const struct target_core_fabric_ops loop_ops = { | |||
1411 | .write_pending = tcm_loop_write_pending, | 1248 | .write_pending = tcm_loop_write_pending, |
1412 | .write_pending_status = tcm_loop_write_pending_status, | 1249 | .write_pending_status = tcm_loop_write_pending_status, |
1413 | .set_default_node_attributes = tcm_loop_set_default_node_attributes, | 1250 | .set_default_node_attributes = tcm_loop_set_default_node_attributes, |
1414 | .get_task_tag = tcm_loop_get_task_tag, | ||
1415 | .get_cmd_state = tcm_loop_get_cmd_state, | 1251 | .get_cmd_state = tcm_loop_get_cmd_state, |
1416 | .queue_data_in = tcm_loop_queue_data_in, | 1252 | .queue_data_in = tcm_loop_queue_data_in, |
1417 | .queue_status = tcm_loop_queue_status, | 1253 | .queue_status = tcm_loop_queue_status, |