]> Pileus Git - ~andy/linux/blobdiff - drivers/target/target_core_device.c
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[~andy/linux] / drivers / target / target_core_device.c
index d06de84b069bb0c283495bdf09da4b3e9b96ba2f..65001e1336702966108081443d5a44f39988d5af 100644 (file)
@@ -918,6 +918,90 @@ int se_dev_set_emulate_3pc(struct se_device *dev, int flag)
        return 0;
 }
 
+int se_dev_set_pi_prot_type(struct se_device *dev, int flag)
+{
+       int rc, old_prot = dev->dev_attrib.pi_prot_type;
+
+       if (flag != 0 && flag != 1 && flag != 2 && flag != 3) {
+               pr_err("Illegal value %d for pi_prot_type\n", flag);
+               return -EINVAL;
+       }
+       if (flag == 2) {
+               pr_err("DIF TYPE2 protection currently not supported\n");
+               return -ENOSYS;
+       }
+       if (dev->dev_attrib.hw_pi_prot_type) {
+               pr_warn("DIF protection enabled on underlying hardware,"
+                       " ignoring\n");
+               return 0;
+       }
+       if (!dev->transport->init_prot || !dev->transport->free_prot) {
+               pr_err("DIF protection not supported by backend: %s\n",
+                      dev->transport->name);
+               return -ENOSYS;
+       }
+       if (!(dev->dev_flags & DF_CONFIGURED)) {
+               pr_err("DIF protection requires device to be configured\n");
+               return -ENODEV;
+       }
+       if (dev->export_count) {
+               pr_err("dev[%p]: Unable to change SE Device PROT type while"
+                      " export_count is %d\n", dev, dev->export_count);
+               return -EINVAL;
+       }
+
+       dev->dev_attrib.pi_prot_type = flag;
+
+       if (flag && !old_prot) {
+               rc = dev->transport->init_prot(dev);
+               if (rc) {
+                       dev->dev_attrib.pi_prot_type = old_prot;
+                       return rc;
+               }
+
+       } else if (!flag && old_prot) {
+               dev->transport->free_prot(dev);
+       }
+       pr_debug("dev[%p]: SE Device Protection Type: %d\n", dev, flag);
+
+       return 0;
+}
+
+int se_dev_set_pi_prot_format(struct se_device *dev, int flag)
+{
+       int rc;
+
+       if (!flag)
+               return 0;
+
+       if (flag != 1) {
+               pr_err("Illegal value %d for pi_prot_format\n", flag);
+               return -EINVAL;
+       }
+       if (!dev->transport->format_prot) {
+               pr_err("DIF protection format not supported by backend %s\n",
+                      dev->transport->name);
+               return -ENOSYS;
+       }
+       if (!(dev->dev_flags & DF_CONFIGURED)) {
+               pr_err("DIF protection format requires device to be configured\n");
+               return -ENODEV;
+       }
+       if (dev->export_count) {
+               pr_err("dev[%p]: Unable to format SE Device PROT type while"
+                      " export_count is %d\n", dev, dev->export_count);
+               return -EINVAL;
+       }
+
+       rc = dev->transport->format_prot(dev);
+       if (rc)
+               return rc;
+
+       pr_debug("dev[%p]: SE Device Protection Format complete\n", dev);
+
+       return 0;
+}
+
 int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag)
 {
        if ((flag != 0) && (flag != 1)) {
@@ -1117,23 +1201,23 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size)
 struct se_lun *core_dev_add_lun(
        struct se_portal_group *tpg,
        struct se_device *dev,
-       u32 lun)
+       u32 unpacked_lun)
 {
-       struct se_lun *lun_p;
+       struct se_lun *lun;
        int rc;
 
-       lun_p = core_tpg_pre_addlun(tpg, lun);
-       if (IS_ERR(lun_p))
-               return lun_p;
+       lun = core_tpg_alloc_lun(tpg, unpacked_lun);
+       if (IS_ERR(lun))
+               return lun;
 
-       rc = core_tpg_post_addlun(tpg, lun_p,
+       rc = core_tpg_add_lun(tpg, lun,
                                TRANSPORT_LUNFLAGS_READ_WRITE, dev);
        if (rc < 0)
                return ERR_PTR(rc);
 
        pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from"
                " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(),
-               tpg->se_tpg_tfo->tpg_get_tag(tpg), lun_p->unpacked_lun,
+               tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun,
                tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id);
        /*
         * Update LUN maps for dynamically added initiators when
@@ -1154,7 +1238,7 @@ struct se_lun *core_dev_add_lun(
                spin_unlock_irq(&tpg->acl_node_lock);
        }
 
-       return lun_p;
+       return lun;
 }
 
 /*      core_dev_del_lun():
@@ -1420,6 +1504,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
        dev->dev_link_magic = SE_DEV_LINK_MAGIC;
        dev->se_hba = hba;
        dev->transport = hba->transport;
+       dev->prot_length = sizeof(struct se_dif_v1_tuple);
 
        INIT_LIST_HEAD(&dev->dev_list);
        INIT_LIST_HEAD(&dev->dev_sep_list);
@@ -1444,6 +1529,8 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
        spin_lock_init(&dev->t10_pr.aptpl_reg_lock);
        INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list);
        spin_lock_init(&dev->t10_alua.tg_pt_gps_lock);
+       INIT_LIST_HEAD(&dev->t10_alua.lba_map_list);
+       spin_lock_init(&dev->t10_alua.lba_map_lock);
 
        dev->t10_wwn.t10_dev = dev;
        dev->t10_alua.t10_dev = dev;
@@ -1460,6 +1547,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
        dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS;
        dev->dev_attrib.emulate_caw = DA_EMULATE_CAW;
        dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC;
+       dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT;
        dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
        dev->dev_attrib.is_nonrot = DA_IS_NONROT;
        dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD;
@@ -1588,9 +1676,13 @@ void target_free_device(struct se_device *dev)
        }
 
        core_alua_free_lu_gp_mem(dev);
+       core_alua_set_lba_map(dev, NULL, 0, 0);
        core_scsi3_free_all_registrations(dev);
        se_release_vpd_for_dev(dev);
 
+       if (dev->transport->free_prot)
+               dev->transport->free_prot(dev);
+
        dev->transport->free_device(dev);
 }