0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/module.h>
0024 #include <linux/moduleparam.h>
0025 #include <linux/init.h>
0026 #include <linux/slab.h>
0027 #include <linux/types.h>
0028 #include <linux/configfs.h>
0029 #include <scsi/scsi.h>
0030 #include <scsi/scsi_tcq.h>
0031 #include <scsi/scsi_host.h>
0032 #include <scsi/scsi_device.h>
0033 #include <scsi/scsi_cmnd.h>
0034
0035 #include <target/target_core_base.h>
0036 #include <target/target_core_fabric.h>
0037
0038 #include "tcm_loop.h"
0039
0040 #define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
0041
0042 static struct kmem_cache *tcm_loop_cmd_cache;
0043
0044 static int tcm_loop_hba_no_cnt;
0045
0046 static int tcm_loop_queue_status(struct se_cmd *se_cmd);
0047
0048 static unsigned int tcm_loop_nr_hw_queues = 1;
0049 module_param_named(nr_hw_queues, tcm_loop_nr_hw_queues, uint, 0644);
0050
0051 static unsigned int tcm_loop_can_queue = 1024;
0052 module_param_named(can_queue, tcm_loop_can_queue, uint, 0644);
0053
0054 static unsigned int tcm_loop_cmd_per_lun = 1024;
0055 module_param_named(cmd_per_lun, tcm_loop_cmd_per_lun, uint, 0644);
0056
0057
0058
0059
0060 static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
0061 {
0062 return transport_generic_free_cmd(se_cmd, 0);
0063 }
0064
0065 static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
0066 {
0067 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
0068 struct tcm_loop_cmd, tl_se_cmd);
0069 struct scsi_cmnd *sc = tl_cmd->sc;
0070
0071 if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
0072 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
0073 else
0074 scsi_done(sc);
0075 }
0076
0077 static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host)
0078 {
0079 seq_puts(m, "tcm_loop_proc_info()\n");
0080 return 0;
0081 }
0082
0083 static int tcm_loop_driver_probe(struct device *);
0084 static void tcm_loop_driver_remove(struct device *);
0085
0086 static int pseudo_lld_bus_match(struct device *dev,
0087 struct device_driver *dev_driver)
0088 {
0089 return 1;
0090 }
0091
0092 static struct bus_type tcm_loop_lld_bus = {
0093 .name = "tcm_loop_bus",
0094 .match = pseudo_lld_bus_match,
0095 .probe = tcm_loop_driver_probe,
0096 .remove = tcm_loop_driver_remove,
0097 };
0098
0099 static struct device_driver tcm_loop_driverfs = {
0100 .name = "tcm_loop",
0101 .bus = &tcm_loop_lld_bus,
0102 };
0103
0104
0105
0106 static struct device *tcm_loop_primary;
0107
0108 static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd)
0109 {
0110 struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd;
0111 struct scsi_cmnd *sc = tl_cmd->sc;
0112 struct tcm_loop_nexus *tl_nexus;
0113 struct tcm_loop_hba *tl_hba;
0114 struct tcm_loop_tpg *tl_tpg;
0115 struct scatterlist *sgl_bidi = NULL;
0116 u32 sgl_bidi_count = 0, transfer_length;
0117
0118 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
0119 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
0120
0121
0122
0123
0124
0125 if (!tl_tpg->tl_hba) {
0126 set_host_byte(sc, DID_NO_CONNECT);
0127 goto out_done;
0128 }
0129 if (tl_tpg->tl_transport_status == TCM_TRANSPORT_OFFLINE) {
0130 set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
0131 goto out_done;
0132 }
0133 tl_nexus = tl_tpg->tl_nexus;
0134 if (!tl_nexus) {
0135 scmd_printk(KERN_ERR, sc,
0136 "TCM_Loop I_T Nexus does not exist\n");
0137 set_host_byte(sc, DID_ERROR);
0138 goto out_done;
0139 }
0140
0141 transfer_length = scsi_transfer_length(sc);
0142 if (!scsi_prot_sg_count(sc) &&
0143 scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) {
0144 se_cmd->prot_pto = true;
0145
0146
0147
0148
0149
0150 transfer_length = scsi_bufflen(sc);
0151 }
0152
0153 se_cmd->tag = tl_cmd->sc_cmd_tag;
0154 target_init_cmd(se_cmd, tl_nexus->se_sess, &tl_cmd->tl_sense_buf[0],
0155 tl_cmd->sc->device->lun, transfer_length,
0156 TCM_SIMPLE_TAG, sc->sc_data_direction, 0);
0157
0158 if (target_submit_prep(se_cmd, sc->cmnd, scsi_sglist(sc),
0159 scsi_sg_count(sc), sgl_bidi, sgl_bidi_count,
0160 scsi_prot_sglist(sc), scsi_prot_sg_count(sc),
0161 GFP_ATOMIC))
0162 return;
0163
0164 target_queue_submission(se_cmd);
0165 return;
0166
0167 out_done:
0168 scsi_done(sc);
0169 }
0170
0171
0172
0173
0174
0175 static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
0176 {
0177 struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc);
0178
0179 pr_debug("%s() %d:%d:%d:%llu got CDB: 0x%02x scsi_buf_len: %u\n",
0180 __func__, sc->device->host->host_no, sc->device->id,
0181 sc->device->channel, sc->device->lun, sc->cmnd[0],
0182 scsi_bufflen(sc));
0183
0184 memset(tl_cmd, 0, sizeof(*tl_cmd));
0185 tl_cmd->sc = sc;
0186 tl_cmd->sc_cmd_tag = scsi_cmd_to_rq(sc)->tag;
0187
0188 tcm_loop_target_queue_cmd(tl_cmd);
0189 return 0;
0190 }
0191
0192
0193
0194
0195
0196 static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
0197 u64 lun, int task, enum tcm_tmreq_table tmr)
0198 {
0199 struct se_cmd *se_cmd;
0200 struct se_session *se_sess;
0201 struct tcm_loop_nexus *tl_nexus;
0202 struct tcm_loop_cmd *tl_cmd;
0203 int ret = TMR_FUNCTION_FAILED, rc;
0204
0205
0206
0207
0208 tl_nexus = tl_tpg->tl_nexus;
0209 if (!tl_nexus) {
0210 pr_err("Unable to perform device reset without active I_T Nexus\n");
0211 return ret;
0212 }
0213
0214 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
0215 if (!tl_cmd)
0216 return ret;
0217
0218 init_completion(&tl_cmd->tmr_done);
0219
0220 se_cmd = &tl_cmd->tl_se_cmd;
0221 se_sess = tl_tpg->tl_nexus->se_sess;
0222
0223 rc = target_submit_tmr(se_cmd, se_sess, tl_cmd->tl_sense_buf, lun,
0224 NULL, tmr, GFP_KERNEL, task,
0225 TARGET_SCF_ACK_KREF);
0226 if (rc < 0)
0227 goto release;
0228 wait_for_completion(&tl_cmd->tmr_done);
0229 ret = se_cmd->se_tmr_req->response;
0230 target_put_sess_cmd(se_cmd);
0231
0232 out:
0233 return ret;
0234
0235 release:
0236 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
0237 goto out;
0238 }
0239
0240 static int tcm_loop_abort_task(struct scsi_cmnd *sc)
0241 {
0242 struct tcm_loop_hba *tl_hba;
0243 struct tcm_loop_tpg *tl_tpg;
0244 int ret;
0245
0246
0247
0248
0249 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
0250 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
0251 ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
0252 scsi_cmd_to_rq(sc)->tag, TMR_ABORT_TASK);
0253 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
0254 }
0255
0256
0257
0258
0259
0260 static int tcm_loop_device_reset(struct scsi_cmnd *sc)
0261 {
0262 struct tcm_loop_hba *tl_hba;
0263 struct tcm_loop_tpg *tl_tpg;
0264 int ret;
0265
0266
0267
0268
0269 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
0270 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
0271
0272 ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
0273 0, TMR_LUN_RESET);
0274 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
0275 }
0276
0277 static int tcm_loop_target_reset(struct scsi_cmnd *sc)
0278 {
0279 struct tcm_loop_hba *tl_hba;
0280 struct tcm_loop_tpg *tl_tpg;
0281
0282
0283
0284
0285 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
0286 if (!tl_hba) {
0287 pr_err("Unable to perform device reset without active I_T Nexus\n");
0288 return FAILED;
0289 }
0290
0291
0292
0293 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
0294 if (tl_tpg) {
0295 tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
0296 return SUCCESS;
0297 }
0298 return FAILED;
0299 }
0300
0301 static struct scsi_host_template tcm_loop_driver_template = {
0302 .show_info = tcm_loop_show_info,
0303 .proc_name = "tcm_loopback",
0304 .name = "TCM_Loopback",
0305 .queuecommand = tcm_loop_queuecommand,
0306 .change_queue_depth = scsi_change_queue_depth,
0307 .eh_abort_handler = tcm_loop_abort_task,
0308 .eh_device_reset_handler = tcm_loop_device_reset,
0309 .eh_target_reset_handler = tcm_loop_target_reset,
0310 .this_id = -1,
0311 .sg_tablesize = 256,
0312 .max_sectors = 0xFFFF,
0313 .dma_boundary = PAGE_SIZE - 1,
0314 .module = THIS_MODULE,
0315 .track_queue_depth = 1,
0316 .cmd_size = sizeof(struct tcm_loop_cmd),
0317 };
0318
0319 static int tcm_loop_driver_probe(struct device *dev)
0320 {
0321 struct tcm_loop_hba *tl_hba;
0322 struct Scsi_Host *sh;
0323 int error, host_prot;
0324
0325 tl_hba = to_tcm_loop_hba(dev);
0326
0327 sh = scsi_host_alloc(&tcm_loop_driver_template,
0328 sizeof(struct tcm_loop_hba));
0329 if (!sh) {
0330 pr_err("Unable to allocate struct scsi_host\n");
0331 return -ENODEV;
0332 }
0333 tl_hba->sh = sh;
0334
0335
0336
0337
0338 *((struct tcm_loop_hba **)sh->hostdata) = tl_hba;
0339
0340
0341
0342 sh->max_id = 2;
0343 sh->max_lun = 0;
0344 sh->max_channel = 0;
0345 sh->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE;
0346 sh->nr_hw_queues = tcm_loop_nr_hw_queues;
0347 sh->can_queue = tcm_loop_can_queue;
0348 sh->cmd_per_lun = tcm_loop_cmd_per_lun;
0349
0350 host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION |
0351 SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION |
0352 SHOST_DIX_TYPE2_PROTECTION | SHOST_DIX_TYPE3_PROTECTION;
0353
0354 scsi_host_set_prot(sh, host_prot);
0355 scsi_host_set_guard(sh, SHOST_DIX_GUARD_CRC);
0356
0357 error = scsi_add_host(sh, &tl_hba->dev);
0358 if (error) {
0359 pr_err("%s: scsi_add_host failed\n", __func__);
0360 scsi_host_put(sh);
0361 return -ENODEV;
0362 }
0363 return 0;
0364 }
0365
0366 static void tcm_loop_driver_remove(struct device *dev)
0367 {
0368 struct tcm_loop_hba *tl_hba;
0369 struct Scsi_Host *sh;
0370
0371 tl_hba = to_tcm_loop_hba(dev);
0372 sh = tl_hba->sh;
0373
0374 scsi_remove_host(sh);
0375 scsi_host_put(sh);
0376 }
0377
0378 static void tcm_loop_release_adapter(struct device *dev)
0379 {
0380 struct tcm_loop_hba *tl_hba = to_tcm_loop_hba(dev);
0381
0382 kfree(tl_hba);
0383 }
0384
0385
0386
0387
0388 static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host_id)
0389 {
0390 int ret;
0391
0392 tl_hba->dev.bus = &tcm_loop_lld_bus;
0393 tl_hba->dev.parent = tcm_loop_primary;
0394 tl_hba->dev.release = &tcm_loop_release_adapter;
0395 dev_set_name(&tl_hba->dev, "tcm_loop_adapter_%d", tcm_loop_host_id);
0396
0397 ret = device_register(&tl_hba->dev);
0398 if (ret) {
0399 pr_err("device_register() failed for tl_hba->dev: %d\n", ret);
0400 return -ENODEV;
0401 }
0402
0403 return 0;
0404 }
0405
0406
0407
0408
0409
0410 static int tcm_loop_alloc_core_bus(void)
0411 {
0412 int ret;
0413
0414 tcm_loop_primary = root_device_register("tcm_loop_0");
0415 if (IS_ERR(tcm_loop_primary)) {
0416 pr_err("Unable to allocate tcm_loop_primary\n");
0417 return PTR_ERR(tcm_loop_primary);
0418 }
0419
0420 ret = bus_register(&tcm_loop_lld_bus);
0421 if (ret) {
0422 pr_err("bus_register() failed for tcm_loop_lld_bus\n");
0423 goto dev_unreg;
0424 }
0425
0426 ret = driver_register(&tcm_loop_driverfs);
0427 if (ret) {
0428 pr_err("driver_register() failed for tcm_loop_driverfs\n");
0429 goto bus_unreg;
0430 }
0431
0432 pr_debug("Initialized TCM Loop Core Bus\n");
0433 return ret;
0434
0435 bus_unreg:
0436 bus_unregister(&tcm_loop_lld_bus);
0437 dev_unreg:
0438 root_device_unregister(tcm_loop_primary);
0439 return ret;
0440 }
0441
0442 static void tcm_loop_release_core_bus(void)
0443 {
0444 driver_unregister(&tcm_loop_driverfs);
0445 bus_unregister(&tcm_loop_lld_bus);
0446 root_device_unregister(tcm_loop_primary);
0447
0448 pr_debug("Releasing TCM Loop Core BUS\n");
0449 }
0450
0451 static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg)
0452 {
0453 return container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg);
0454 }
0455
0456 static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg)
0457 {
0458
0459
0460
0461 return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0];
0462 }
0463
0464 static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg)
0465 {
0466
0467
0468
0469
0470 return tl_tpg(se_tpg)->tl_tpgt;
0471 }
0472
0473
0474
0475
0476
0477 static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg)
0478 {
0479 return 1;
0480 }
0481
0482 static int tcm_loop_check_demo_mode_cache(struct se_portal_group *se_tpg)
0483 {
0484 return 0;
0485 }
0486
0487
0488
0489
0490
0491 static int tcm_loop_check_demo_mode_write_protect(struct se_portal_group *se_tpg)
0492 {
0493 return 0;
0494 }
0495
0496
0497
0498
0499
0500
0501 static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg)
0502 {
0503 return 0;
0504 }
0505
0506 static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
0507 {
0508 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
0509 tl_se_tpg);
0510 return tl_tpg->tl_fabric_prot_type;
0511 }
0512
0513 static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
0514 {
0515 return 1;
0516 }
0517
0518 static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
0519 {
0520 return 1;
0521 }
0522
0523 static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
0524 {
0525 return;
0526 }
0527
0528 static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
0529 {
0530 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
0531 struct tcm_loop_cmd, tl_se_cmd);
0532
0533 return tl_cmd->sc_cmd_state;
0534 }
0535
0536 static int tcm_loop_write_pending(struct se_cmd *se_cmd)
0537 {
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547 target_execute_cmd(se_cmd);
0548 return 0;
0549 }
0550
0551 static int tcm_loop_queue_data_or_status(const char *func,
0552 struct se_cmd *se_cmd, u8 scsi_status)
0553 {
0554 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
0555 struct tcm_loop_cmd, tl_se_cmd);
0556 struct scsi_cmnd *sc = tl_cmd->sc;
0557
0558 pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
0559 func, sc, sc->cmnd[0]);
0560
0561 if (se_cmd->sense_buffer &&
0562 ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
0563 (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
0564
0565 memcpy(sc->sense_buffer, se_cmd->sense_buffer,
0566 SCSI_SENSE_BUFFERSIZE);
0567 sc->result = SAM_STAT_CHECK_CONDITION;
0568 } else
0569 sc->result = scsi_status;
0570
0571 set_host_byte(sc, DID_OK);
0572 if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) ||
0573 (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT))
0574 scsi_set_resid(sc, se_cmd->residual_count);
0575 return 0;
0576 }
0577
0578 static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
0579 {
0580 return tcm_loop_queue_data_or_status(__func__, se_cmd, SAM_STAT_GOOD);
0581 }
0582
0583 static int tcm_loop_queue_status(struct se_cmd *se_cmd)
0584 {
0585 return tcm_loop_queue_data_or_status(__func__,
0586 se_cmd, se_cmd->scsi_status);
0587 }
0588
0589 static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
0590 {
0591 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
0592 struct tcm_loop_cmd, tl_se_cmd);
0593
0594
0595 complete(&tl_cmd->tmr_done);
0596 }
0597
0598 static void tcm_loop_aborted_task(struct se_cmd *se_cmd)
0599 {
0600 return;
0601 }
0602
0603 static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
0604 {
0605 switch (tl_hba->tl_proto_id) {
0606 case SCSI_PROTOCOL_SAS:
0607 return "SAS";
0608 case SCSI_PROTOCOL_FCP:
0609 return "FCP";
0610 case SCSI_PROTOCOL_ISCSI:
0611 return "iSCSI";
0612 default:
0613 break;
0614 }
0615
0616 return "Unknown";
0617 }
0618
0619
0620
0621 static int tcm_loop_port_link(
0622 struct se_portal_group *se_tpg,
0623 struct se_lun *lun)
0624 {
0625 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0626 struct tcm_loop_tpg, tl_se_tpg);
0627 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
0628
0629 atomic_inc_mb(&tl_tpg->tl_tpg_port_count);
0630
0631
0632
0633 scsi_add_device(tl_hba->sh, 0, tl_tpg->tl_tpgt, lun->unpacked_lun);
0634
0635 pr_debug("TCM_Loop_ConfigFS: Port Link Successful\n");
0636 return 0;
0637 }
0638
0639 static void tcm_loop_port_unlink(
0640 struct se_portal_group *se_tpg,
0641 struct se_lun *se_lun)
0642 {
0643 struct scsi_device *sd;
0644 struct tcm_loop_hba *tl_hba;
0645 struct tcm_loop_tpg *tl_tpg;
0646
0647 tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg);
0648 tl_hba = tl_tpg->tl_hba;
0649
0650 sd = scsi_device_lookup(tl_hba->sh, 0, tl_tpg->tl_tpgt,
0651 se_lun->unpacked_lun);
0652 if (!sd) {
0653 pr_err("Unable to locate struct scsi_device for %d:%d:%llu\n",
0654 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
0655 return;
0656 }
0657
0658
0659
0660 scsi_remove_device(sd);
0661 scsi_device_put(sd);
0662
0663 atomic_dec_mb(&tl_tpg->tl_tpg_port_count);
0664
0665 pr_debug("TCM_Loop_ConfigFS: Port Unlink Successful\n");
0666 }
0667
0668
0669
0670 static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_show(
0671 struct config_item *item, char *page)
0672 {
0673 struct se_portal_group *se_tpg = attrib_to_tpg(item);
0674 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
0675 tl_se_tpg);
0676
0677 return sprintf(page, "%d\n", tl_tpg->tl_fabric_prot_type);
0678 }
0679
0680 static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_store(
0681 struct config_item *item, const char *page, size_t count)
0682 {
0683 struct se_portal_group *se_tpg = attrib_to_tpg(item);
0684 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
0685 tl_se_tpg);
0686 unsigned long val;
0687 int ret = kstrtoul(page, 0, &val);
0688
0689 if (ret) {
0690 pr_err("kstrtoul() returned %d for fabric_prot_type\n", ret);
0691 return ret;
0692 }
0693 if (val != 0 && val != 1 && val != 3) {
0694 pr_err("Invalid qla2xxx fabric_prot_type: %lu\n", val);
0695 return -EINVAL;
0696 }
0697 tl_tpg->tl_fabric_prot_type = val;
0698
0699 return count;
0700 }
0701
0702 CONFIGFS_ATTR(tcm_loop_tpg_attrib_, fabric_prot_type);
0703
0704 static struct configfs_attribute *tcm_loop_tpg_attrib_attrs[] = {
0705 &tcm_loop_tpg_attrib_attr_fabric_prot_type,
0706 NULL,
0707 };
0708
0709
0710
0711 static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
0712 struct se_session *se_sess, void *p)
0713 {
0714 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0715 struct tcm_loop_tpg, tl_se_tpg);
0716
0717 tl_tpg->tl_nexus = p;
0718 return 0;
0719 }
0720
0721 static int tcm_loop_make_nexus(
0722 struct tcm_loop_tpg *tl_tpg,
0723 const char *name)
0724 {
0725 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
0726 struct tcm_loop_nexus *tl_nexus;
0727 int ret;
0728
0729 if (tl_tpg->tl_nexus) {
0730 pr_debug("tl_tpg->tl_nexus already exists\n");
0731 return -EEXIST;
0732 }
0733
0734 tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
0735 if (!tl_nexus)
0736 return -ENOMEM;
0737
0738 tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
0739 TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
0740 name, tl_nexus, tcm_loop_alloc_sess_cb);
0741 if (IS_ERR(tl_nexus->se_sess)) {
0742 ret = PTR_ERR(tl_nexus->se_sess);
0743 kfree(tl_nexus);
0744 return ret;
0745 }
0746
0747 pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated %s Initiator Port: %s\n",
0748 tcm_loop_dump_proto_id(tl_hba), name);
0749 return 0;
0750 }
0751
0752 static int tcm_loop_drop_nexus(
0753 struct tcm_loop_tpg *tpg)
0754 {
0755 struct se_session *se_sess;
0756 struct tcm_loop_nexus *tl_nexus;
0757
0758 tl_nexus = tpg->tl_nexus;
0759 if (!tl_nexus)
0760 return -ENODEV;
0761
0762 se_sess = tl_nexus->se_sess;
0763 if (!se_sess)
0764 return -ENODEV;
0765
0766 if (atomic_read(&tpg->tl_tpg_port_count)) {
0767 pr_err("Unable to remove TCM_Loop I_T Nexus with active TPG port count: %d\n",
0768 atomic_read(&tpg->tl_tpg_port_count));
0769 return -EPERM;
0770 }
0771
0772 pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated %s Initiator Port: %s\n",
0773 tcm_loop_dump_proto_id(tpg->tl_hba),
0774 tl_nexus->se_sess->se_node_acl->initiatorname);
0775
0776
0777
0778 target_remove_session(se_sess);
0779 tpg->tl_nexus = NULL;
0780 kfree(tl_nexus);
0781 return 0;
0782 }
0783
0784
0785
0786 static ssize_t tcm_loop_tpg_nexus_show(struct config_item *item, char *page)
0787 {
0788 struct se_portal_group *se_tpg = to_tpg(item);
0789 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0790 struct tcm_loop_tpg, tl_se_tpg);
0791 struct tcm_loop_nexus *tl_nexus;
0792 ssize_t ret;
0793
0794 tl_nexus = tl_tpg->tl_nexus;
0795 if (!tl_nexus)
0796 return -ENODEV;
0797
0798 ret = snprintf(page, PAGE_SIZE, "%s\n",
0799 tl_nexus->se_sess->se_node_acl->initiatorname);
0800
0801 return ret;
0802 }
0803
0804 static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
0805 const char *page, size_t count)
0806 {
0807 struct se_portal_group *se_tpg = to_tpg(item);
0808 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0809 struct tcm_loop_tpg, tl_se_tpg);
0810 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
0811 unsigned char i_port[TL_WWN_ADDR_LEN], *ptr, *port_ptr;
0812 int ret;
0813
0814
0815
0816 if (!strncmp(page, "NULL", 4)) {
0817 ret = tcm_loop_drop_nexus(tl_tpg);
0818 return (!ret) ? count : ret;
0819 }
0820
0821
0822
0823
0824
0825 if (strlen(page) >= TL_WWN_ADDR_LEN) {
0826 pr_err("Emulated NAA Sas Address: %s, exceeds max: %d\n",
0827 page, TL_WWN_ADDR_LEN);
0828 return -EINVAL;
0829 }
0830 snprintf(&i_port[0], TL_WWN_ADDR_LEN, "%s", page);
0831
0832 ptr = strstr(i_port, "naa.");
0833 if (ptr) {
0834 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) {
0835 pr_err("Passed SAS Initiator Port %s does not match target port protoid: %s\n",
0836 i_port, tcm_loop_dump_proto_id(tl_hba));
0837 return -EINVAL;
0838 }
0839 port_ptr = &i_port[0];
0840 goto check_newline;
0841 }
0842 ptr = strstr(i_port, "fc.");
0843 if (ptr) {
0844 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) {
0845 pr_err("Passed FCP Initiator Port %s does not match target port protoid: %s\n",
0846 i_port, tcm_loop_dump_proto_id(tl_hba));
0847 return -EINVAL;
0848 }
0849 port_ptr = &i_port[3];
0850 goto check_newline;
0851 }
0852 ptr = strstr(i_port, "iqn.");
0853 if (ptr) {
0854 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) {
0855 pr_err("Passed iSCSI Initiator Port %s does not match target port protoid: %s\n",
0856 i_port, tcm_loop_dump_proto_id(tl_hba));
0857 return -EINVAL;
0858 }
0859 port_ptr = &i_port[0];
0860 goto check_newline;
0861 }
0862 pr_err("Unable to locate prefix for emulated Initiator Port: %s\n",
0863 i_port);
0864 return -EINVAL;
0865
0866
0867
0868 check_newline:
0869 if (i_port[strlen(i_port)-1] == '\n')
0870 i_port[strlen(i_port)-1] = '\0';
0871
0872 ret = tcm_loop_make_nexus(tl_tpg, port_ptr);
0873 if (ret < 0)
0874 return ret;
0875
0876 return count;
0877 }
0878
0879 static ssize_t tcm_loop_tpg_transport_status_show(struct config_item *item,
0880 char *page)
0881 {
0882 struct se_portal_group *se_tpg = to_tpg(item);
0883 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0884 struct tcm_loop_tpg, tl_se_tpg);
0885 const char *status = NULL;
0886 ssize_t ret = -EINVAL;
0887
0888 switch (tl_tpg->tl_transport_status) {
0889 case TCM_TRANSPORT_ONLINE:
0890 status = "online";
0891 break;
0892 case TCM_TRANSPORT_OFFLINE:
0893 status = "offline";
0894 break;
0895 default:
0896 break;
0897 }
0898
0899 if (status)
0900 ret = snprintf(page, PAGE_SIZE, "%s\n", status);
0901
0902 return ret;
0903 }
0904
0905 static ssize_t tcm_loop_tpg_transport_status_store(struct config_item *item,
0906 const char *page, size_t count)
0907 {
0908 struct se_portal_group *se_tpg = to_tpg(item);
0909 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0910 struct tcm_loop_tpg, tl_se_tpg);
0911
0912 if (!strncmp(page, "online", 6)) {
0913 tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
0914 return count;
0915 }
0916 if (!strncmp(page, "offline", 7)) {
0917 tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE;
0918 if (tl_tpg->tl_nexus) {
0919 struct se_session *tl_sess = tl_tpg->tl_nexus->se_sess;
0920
0921 core_allocate_nexus_loss_ua(tl_sess->se_node_acl);
0922 }
0923 return count;
0924 }
0925 return -EINVAL;
0926 }
0927
0928 static ssize_t tcm_loop_tpg_address_show(struct config_item *item,
0929 char *page)
0930 {
0931 struct se_portal_group *se_tpg = to_tpg(item);
0932 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0933 struct tcm_loop_tpg, tl_se_tpg);
0934 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
0935
0936 return snprintf(page, PAGE_SIZE, "%d:0:%d\n",
0937 tl_hba->sh->host_no, tl_tpg->tl_tpgt);
0938 }
0939
0940 CONFIGFS_ATTR(tcm_loop_tpg_, nexus);
0941 CONFIGFS_ATTR(tcm_loop_tpg_, transport_status);
0942 CONFIGFS_ATTR_RO(tcm_loop_tpg_, address);
0943
0944 static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
0945 &tcm_loop_tpg_attr_nexus,
0946 &tcm_loop_tpg_attr_transport_status,
0947 &tcm_loop_tpg_attr_address,
0948 NULL,
0949 };
0950
0951
0952
0953 static struct se_portal_group *tcm_loop_make_naa_tpg(struct se_wwn *wwn,
0954 const char *name)
0955 {
0956 struct tcm_loop_hba *tl_hba = container_of(wwn,
0957 struct tcm_loop_hba, tl_hba_wwn);
0958 struct tcm_loop_tpg *tl_tpg;
0959 int ret;
0960 unsigned long tpgt;
0961
0962 if (strstr(name, "tpgt_") != name) {
0963 pr_err("Unable to locate \"tpgt_#\" directory group\n");
0964 return ERR_PTR(-EINVAL);
0965 }
0966 if (kstrtoul(name+5, 10, &tpgt))
0967 return ERR_PTR(-EINVAL);
0968
0969 if (tpgt >= TL_TPGS_PER_HBA) {
0970 pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA: %u\n",
0971 tpgt, TL_TPGS_PER_HBA);
0972 return ERR_PTR(-EINVAL);
0973 }
0974 tl_tpg = &tl_hba->tl_hba_tpgs[tpgt];
0975 tl_tpg->tl_hba = tl_hba;
0976 tl_tpg->tl_tpgt = tpgt;
0977
0978
0979
0980 ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id);
0981 if (ret < 0)
0982 return ERR_PTR(-ENOMEM);
0983
0984 pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s Target Port %s,t,0x%04lx\n",
0985 tcm_loop_dump_proto_id(tl_hba),
0986 config_item_name(&wwn->wwn_group.cg_item), tpgt);
0987 return &tl_tpg->tl_se_tpg;
0988 }
0989
0990 static void tcm_loop_drop_naa_tpg(
0991 struct se_portal_group *se_tpg)
0992 {
0993 struct se_wwn *wwn = se_tpg->se_tpg_wwn;
0994 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
0995 struct tcm_loop_tpg, tl_se_tpg);
0996 struct tcm_loop_hba *tl_hba;
0997 unsigned short tpgt;
0998
0999 tl_hba = tl_tpg->tl_hba;
1000 tpgt = tl_tpg->tl_tpgt;
1001
1002
1003
1004 tcm_loop_drop_nexus(tl_tpg);
1005
1006
1007
1008 core_tpg_deregister(se_tpg);
1009
1010 tl_tpg->tl_hba = NULL;
1011 tl_tpg->tl_tpgt = 0;
1012
1013 pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s Target Port %s,t,0x%04x\n",
1014 tcm_loop_dump_proto_id(tl_hba),
1015 config_item_name(&wwn->wwn_group.cg_item), tpgt);
1016 }
1017
1018
1019
1020
1021
1022 static struct se_wwn *tcm_loop_make_scsi_hba(
1023 struct target_fabric_configfs *tf,
1024 struct config_group *group,
1025 const char *name)
1026 {
1027 struct tcm_loop_hba *tl_hba;
1028 struct Scsi_Host *sh;
1029 char *ptr;
1030 int ret, off = 0;
1031
1032 tl_hba = kzalloc(sizeof(*tl_hba), GFP_KERNEL);
1033 if (!tl_hba)
1034 return ERR_PTR(-ENOMEM);
1035
1036
1037
1038
1039
1040 ptr = strstr(name, "naa.");
1041 if (ptr) {
1042 tl_hba->tl_proto_id = SCSI_PROTOCOL_SAS;
1043 goto check_len;
1044 }
1045 ptr = strstr(name, "fc.");
1046 if (ptr) {
1047 tl_hba->tl_proto_id = SCSI_PROTOCOL_FCP;
1048 off = 3;
1049 goto check_len;
1050 }
1051 ptr = strstr(name, "iqn.");
1052 if (!ptr) {
1053 pr_err("Unable to locate prefix for emulated Target Port: %s\n",
1054 name);
1055 ret = -EINVAL;
1056 goto out;
1057 }
1058 tl_hba->tl_proto_id = SCSI_PROTOCOL_ISCSI;
1059
1060 check_len:
1061 if (strlen(name) >= TL_WWN_ADDR_LEN) {
1062 pr_err("Emulated NAA %s Address: %s, exceeds max: %d\n",
1063 name, tcm_loop_dump_proto_id(tl_hba), TL_WWN_ADDR_LEN);
1064 ret = -EINVAL;
1065 goto out;
1066 }
1067 snprintf(&tl_hba->tl_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]);
1068
1069
1070
1071
1072
1073
1074 ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
1075 if (ret)
1076 goto out;
1077
1078 sh = tl_hba->sh;
1079 tcm_loop_hba_no_cnt++;
1080 pr_debug("TCM_Loop_ConfigFS: Allocated emulated Target %s Address: %s at Linux/SCSI Host ID: %d\n",
1081 tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);
1082 return &tl_hba->tl_hba_wwn;
1083 out:
1084 kfree(tl_hba);
1085 return ERR_PTR(ret);
1086 }
1087
1088 static void tcm_loop_drop_scsi_hba(
1089 struct se_wwn *wwn)
1090 {
1091 struct tcm_loop_hba *tl_hba = container_of(wwn,
1092 struct tcm_loop_hba, tl_hba_wwn);
1093
1094 pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target %s Address: %s at Linux/SCSI Host ID: %d\n",
1095 tcm_loop_dump_proto_id(tl_hba), tl_hba->tl_wwn_address,
1096 tl_hba->sh->host_no);
1097
1098
1099
1100
1101
1102 device_unregister(&tl_hba->dev);
1103 }
1104
1105
1106 static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
1107 {
1108 return sprintf(page, "TCM Loopback Fabric module %s\n", TCM_LOOP_VERSION);
1109 }
1110
1111 CONFIGFS_ATTR_RO(tcm_loop_wwn_, version);
1112
1113 static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
1114 &tcm_loop_wwn_attr_version,
1115 NULL,
1116 };
1117
1118
1119
1120 static const struct target_core_fabric_ops loop_ops = {
1121 .module = THIS_MODULE,
1122 .fabric_name = "loopback",
1123 .tpg_get_wwn = tcm_loop_get_endpoint_wwn,
1124 .tpg_get_tag = tcm_loop_get_tag,
1125 .tpg_check_demo_mode = tcm_loop_check_demo_mode,
1126 .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache,
1127 .tpg_check_demo_mode_write_protect =
1128 tcm_loop_check_demo_mode_write_protect,
1129 .tpg_check_prod_mode_write_protect =
1130 tcm_loop_check_prod_mode_write_protect,
1131 .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only,
1132 .tpg_get_inst_index = tcm_loop_get_inst_index,
1133 .check_stop_free = tcm_loop_check_stop_free,
1134 .release_cmd = tcm_loop_release_cmd,
1135 .sess_get_index = tcm_loop_sess_get_index,
1136 .write_pending = tcm_loop_write_pending,
1137 .set_default_node_attributes = tcm_loop_set_default_node_attributes,
1138 .get_cmd_state = tcm_loop_get_cmd_state,
1139 .queue_data_in = tcm_loop_queue_data_in,
1140 .queue_status = tcm_loop_queue_status,
1141 .queue_tm_rsp = tcm_loop_queue_tm_rsp,
1142 .aborted_task = tcm_loop_aborted_task,
1143 .fabric_make_wwn = tcm_loop_make_scsi_hba,
1144 .fabric_drop_wwn = tcm_loop_drop_scsi_hba,
1145 .fabric_make_tpg = tcm_loop_make_naa_tpg,
1146 .fabric_drop_tpg = tcm_loop_drop_naa_tpg,
1147 .fabric_post_link = tcm_loop_port_link,
1148 .fabric_pre_unlink = tcm_loop_port_unlink,
1149 .tfc_wwn_attrs = tcm_loop_wwn_attrs,
1150 .tfc_tpg_base_attrs = tcm_loop_tpg_attrs,
1151 .tfc_tpg_attrib_attrs = tcm_loop_tpg_attrib_attrs,
1152 };
1153
1154 static int __init tcm_loop_fabric_init(void)
1155 {
1156 int ret = -ENOMEM;
1157
1158 tcm_loop_cmd_cache = kmem_cache_create("tcm_loop_cmd_cache",
1159 sizeof(struct tcm_loop_cmd),
1160 __alignof__(struct tcm_loop_cmd),
1161 0, NULL);
1162 if (!tcm_loop_cmd_cache) {
1163 pr_debug("kmem_cache_create() for tcm_loop_cmd_cache failed\n");
1164 goto out;
1165 }
1166
1167 ret = tcm_loop_alloc_core_bus();
1168 if (ret)
1169 goto out_destroy_cache;
1170
1171 ret = target_register_template(&loop_ops);
1172 if (ret)
1173 goto out_release_core_bus;
1174
1175 return 0;
1176
1177 out_release_core_bus:
1178 tcm_loop_release_core_bus();
1179 out_destroy_cache:
1180 kmem_cache_destroy(tcm_loop_cmd_cache);
1181 out:
1182 return ret;
1183 }
1184
1185 static void __exit tcm_loop_fabric_exit(void)
1186 {
1187 target_unregister_template(&loop_ops);
1188 tcm_loop_release_core_bus();
1189 kmem_cache_destroy(tcm_loop_cmd_cache);
1190 }
1191
1192 MODULE_DESCRIPTION("TCM loopback virtual Linux/SCSI fabric module");
1193 MODULE_AUTHOR("Nicholas A. Bellinger <nab@risingtidesystems.com>");
1194 MODULE_LICENSE("GPL");
1195 module_init(tcm_loop_fabric_init);
1196 module_exit(tcm_loop_fabric_exit);