target: pass sense_reason as a return value
[cascardo/linux.git] / drivers / target / target_core_pscsi.c
index 617c086..b5c722b 100644 (file)
 
 #define ISPRINT(a)  ((a >= ' ') && (a <= '~'))
 
+static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev)
+{
+       return container_of(dev, struct pscsi_dev_virt, dev);
+}
+
 static struct se_subsystem_api pscsi_template;
 
-static int pscsi_execute_cmd(struct se_cmd *cmd);
+static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd);
 static void pscsi_req_done(struct request *, int);
 
 /*     pscsi_attach_hba():
@@ -219,7 +224,7 @@ pscsi_get_inquiry_vpd_serial(struct scsi_device *sdev, struct t10_wwn *wwn)
 
        snprintf(&wwn->unit_serial[0], INQUIRY_VPD_SERIAL_LEN, "%s", &buf[4]);
 
-       wwn->t10_sub_dev->su_dev_flags |= SDF_FIRMWARE_VPD_UNIT_SERIAL;
+       wwn->t10_dev->dev_flags |= DF_FIRMWARE_VPD_UNIT_SERIAL;
 
        kfree(buf);
        return 0;
@@ -299,23 +304,13 @@ out:
        kfree(buf);
 }
 
-/*     pscsi_add_device_to_list():
- *
- *
- */
-static struct se_device *pscsi_add_device_to_list(
-       struct se_hba *hba,
-       struct se_subsystem_dev *se_dev,
-       struct pscsi_dev_virt *pdv,
-       struct scsi_device *sd,
-       int dev_flags)
+static int pscsi_add_device_to_list(struct se_device *dev,
+               struct scsi_device *sd)
 {
-       struct se_device *dev;
-       struct se_dev_limits dev_limits;
-       struct request_queue *q;
-       struct queue_limits *limits;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
+       struct request_queue *q = sd->request_queue;
 
-       memset(&dev_limits, 0, sizeof(struct se_dev_limits));
+       pdv->pdv_sd = sd;
 
        if (!sd->queue_depth) {
                sd->queue_depth = PSCSI_DEFAULT_QUEUEDEPTH;
@@ -324,54 +319,27 @@ static struct se_device *pscsi_add_device_to_list(
                        " queue_depth to %d\n", sd->channel, sd->id,
                                sd->lun, sd->queue_depth);
        }
-       /*
-        * Setup the local scope queue_limits from struct request_queue->limits
-        * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
-        */
-       q = sd->request_queue;
-       limits = &dev_limits.limits;
-       limits->logical_block_size = sd->sector_size;
-       limits->max_hw_sectors = min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q));
-       limits->max_sectors = min_t(int, sd->host->max_sectors, queue_max_sectors(q));
-       dev_limits.hw_queue_depth = sd->queue_depth;
-       dev_limits.queue_depth = sd->queue_depth;
-       /*
-        * Setup our standard INQUIRY info into se_dev->t10_wwn
-        */
-       pscsi_set_inquiry_info(sd, &se_dev->t10_wwn);
+
+       dev->dev_attrib.hw_block_size = sd->sector_size;
+       dev->dev_attrib.hw_max_sectors =
+               min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q));
+       dev->dev_attrib.hw_queue_depth = sd->queue_depth;
 
        /*
-        * Set the pointer pdv->pdv_sd to from passed struct scsi_device,
-        * which has already been referenced with Linux SCSI code with
-        * scsi_device_get() in this file's pscsi_create_virtdevice().
-        *
-        * The passthrough operations called by the transport_add_device_*
-        * function below will require this pointer to be set for passthroug
-        *  ops.
-        *
-        * For the shutdown case in pscsi_free_device(), this struct
-        * scsi_device  reference is released with Linux SCSI code
-        * scsi_device_put() and the pdv->pdv_sd cleared.
+        * Setup our standard INQUIRY info into se_dev->t10_wwn
         */
-       pdv->pdv_sd = sd;
-       dev = transport_add_device_to_core_hba(hba, &pscsi_template,
-                               se_dev, dev_flags, pdv,
-                               &dev_limits, NULL, NULL);
-       if (!dev) {
-               pdv->pdv_sd = NULL;
-               return NULL;
-       }
+       pscsi_set_inquiry_info(sd, &dev->t10_wwn);
 
        /*
         * Locate VPD WWN Information used for various purposes within
         * the Storage Engine.
         */
-       if (!pscsi_get_inquiry_vpd_serial(sd, &se_dev->t10_wwn)) {
+       if (!pscsi_get_inquiry_vpd_serial(sd, &dev->t10_wwn)) {
                /*
                 * If VPD Unit Serial returned GOOD status, try
                 * VPD Device Identification page (0x83).
                 */
-               pscsi_get_inquiry_vpd_device_ident(sd, &se_dev->t10_wwn);
+               pscsi_get_inquiry_vpd_device_ident(sd, &dev->t10_wwn);
        }
 
        /*
@@ -379,10 +347,11 @@ static struct se_device *pscsi_add_device_to_list(
         */
        if (sd->type == TYPE_TAPE)
                pscsi_tape_read_blocksize(dev, sd);
-       return dev;
+       return 0;
 }
 
-static void *pscsi_allocate_virtdevice(struct se_hba *hba, const char *name)
+static struct se_device *pscsi_alloc_device(struct se_hba *hba,
+               const char *name)
 {
        struct pscsi_dev_virt *pdv;
 
@@ -391,139 +360,125 @@ static void *pscsi_allocate_virtdevice(struct se_hba *hba, const char *name)
                pr_err("Unable to allocate memory for struct pscsi_dev_virt\n");
                return NULL;
        }
-       pdv->pdv_se_hba = hba;
 
        pr_debug("PSCSI: Allocated pdv: %p for %s\n", pdv, name);
-       return pdv;
+       return &pdv->dev;
 }
 
 /*
  * Called with struct Scsi_Host->host_lock called.
  */
-static struct se_device *pscsi_create_type_disk(
-       struct scsi_device *sd,
-       struct pscsi_dev_virt *pdv,
-       struct se_subsystem_dev *se_dev,
-       struct se_hba *hba)
+static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd)
        __releases(sh->host_lock)
 {
-       struct se_device *dev;
-       struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
        struct Scsi_Host *sh = sd->host;
        struct block_device *bd;
-       u32 dev_flags = 0;
+       int ret;
 
        if (scsi_device_get(sd)) {
                pr_err("scsi_device_get() failed for %d:%d:%d:%d\n",
                        sh->host_no, sd->channel, sd->id, sd->lun);
                spin_unlock_irq(sh->host_lock);
-               return NULL;
+               return -EIO;
        }
        spin_unlock_irq(sh->host_lock);
        /*
         * Claim exclusive struct block_device access to struct scsi_device
         * for TYPE_DISK using supplied udev_path
         */
-       bd = blkdev_get_by_path(se_dev->se_dev_udev_path,
+       bd = blkdev_get_by_path(dev->udev_path,
                                FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv);
        if (IS_ERR(bd)) {
                pr_err("pSCSI: blkdev_get_by_path() failed\n");
                scsi_device_put(sd);
-               return NULL;
+               return PTR_ERR(bd);
        }
        pdv->pdv_bd = bd;
 
-       dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags);
-       if (!dev) {
+       ret = pscsi_add_device_to_list(dev, sd);
+       if (ret) {
                blkdev_put(pdv->pdv_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
                scsi_device_put(sd);
-               return NULL;
+               return ret;
        }
+
        pr_debug("CORE_PSCSI[%d] - Added TYPE_DISK for %d:%d:%d:%d\n",
                phv->phv_host_id, sh->host_no, sd->channel, sd->id, sd->lun);
-
-       return dev;
+       return 0;
 }
 
 /*
  * Called with struct Scsi_Host->host_lock called.
  */
-static struct se_device *pscsi_create_type_rom(
-       struct scsi_device *sd,
-       struct pscsi_dev_virt *pdv,
-       struct se_subsystem_dev *se_dev,
-       struct se_hba *hba)
+static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd)
        __releases(sh->host_lock)
 {
-       struct se_device *dev;
-       struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
        struct Scsi_Host *sh = sd->host;
-       u32 dev_flags = 0;
+       int ret;
 
        if (scsi_device_get(sd)) {
                pr_err("scsi_device_get() failed for %d:%d:%d:%d\n",
                        sh->host_no, sd->channel, sd->id, sd->lun);
                spin_unlock_irq(sh->host_lock);
-               return NULL;
+               return -EIO;
        }
        spin_unlock_irq(sh->host_lock);
 
-       dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags);
-       if (!dev) {
+       ret = pscsi_add_device_to_list(dev, sd);
+       if (ret) {
                scsi_device_put(sd);
-               return NULL;
+               return ret;
        }
        pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n",
                phv->phv_host_id, scsi_device_type(sd->type), sh->host_no,
                sd->channel, sd->id, sd->lun);
 
-       return dev;
+       return 0;
 }
 
 /*
- *Called with struct Scsi_Host->host_lock called.
+ * Called with struct Scsi_Host->host_lock called.
  */
-static struct se_device *pscsi_create_type_other(
-       struct scsi_device *sd,
-       struct pscsi_dev_virt *pdv,
-       struct se_subsystem_dev *se_dev,
-       struct se_hba *hba)
+static int pscsi_create_type_other(struct se_device *dev,
+               struct scsi_device *sd)
        __releases(sh->host_lock)
 {
-       struct se_device *dev;
-       struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
        struct Scsi_Host *sh = sd->host;
-       u32 dev_flags = 0;
+       int ret;
 
        spin_unlock_irq(sh->host_lock);
-       dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags);
-       if (!dev)
-               return NULL;
+       ret = pscsi_add_device_to_list(dev, sd);
+       if (ret)
+               return ret;
 
        pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n",
                phv->phv_host_id, scsi_device_type(sd->type), sh->host_no,
                sd->channel, sd->id, sd->lun);
-
-       return dev;
+       return 0;
 }
 
-static struct se_device *pscsi_create_virtdevice(
-       struct se_hba *hba,
-       struct se_subsystem_dev *se_dev,
-       void *p)
+static int pscsi_configure_device(struct se_device *dev)
 {
-       struct pscsi_dev_virt *pdv = p;
-       struct se_device *dev;
+       struct se_hba *hba = dev->se_hba;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
        struct scsi_device *sd;
-       struct pscsi_hba_virt *phv = hba->hba_ptr;
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
        struct Scsi_Host *sh = phv->phv_lld_host;
        int legacy_mode_enable = 0;
+       int ret;
 
-       if (!pdv) {
-               pr_err("Unable to locate struct pscsi_dev_virt"
-                               " parameter\n");
-               return ERR_PTR(-EINVAL);
+       if (!(pdv->pdv_flags & PDF_HAS_CHANNEL_ID) ||
+           !(pdv->pdv_flags & PDF_HAS_TARGET_ID) ||
+           !(pdv->pdv_flags & PDF_HAS_LUN_ID)) {
+               pr_err("Missing scsi_channel_id=, scsi_target_id= and"
+                       " scsi_lun_id= parameters\n");
+               return -EINVAL;
        }
+
        /*
         * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the
         * struct Scsi_Host we will need to bring the TCM/pSCSI object online
@@ -532,16 +487,16 @@ static struct se_device *pscsi_create_virtdevice(
                if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) {
                        pr_err("pSCSI: Unable to locate struct"
                                " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n");
-                       return ERR_PTR(-ENODEV);
+                       return -ENODEV;
                }
                /*
                 * For the newer PHV_VIRTUAL_HOST_ID struct scsi_device
                 * reference, we enforce that udev_path has been set
                 */
-               if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) {
+               if (!(dev->dev_flags & DF_USING_UDEV_PATH)) {
                        pr_err("pSCSI: udev_path attribute has not"
                                " been set before ENABLE=1\n");
-                       return ERR_PTR(-EINVAL);
+                       return -EINVAL;
                }
                /*
                 * If no scsi_host_id= was passed for PHV_VIRTUAL_HOST_ID,
@@ -549,17 +504,14 @@ static struct se_device *pscsi_create_virtdevice(
                 * and enable for PHV_LLD_SCSI_HOST_NO mode.
                 */
                if (!(pdv->pdv_flags & PDF_HAS_VIRT_HOST_ID)) {
-                       spin_lock(&hba->device_lock);
-                       if (!list_empty(&hba->hba_dev_list)) {
+                       if (hba->dev_count) {
                                pr_err("pSCSI: Unable to set hba_mode"
                                        " with active devices\n");
-                               spin_unlock(&hba->device_lock);
-                               return ERR_PTR(-EEXIST);
+                               return -EEXIST;
                        }
-                       spin_unlock(&hba->device_lock);
 
                        if (pscsi_pmode_enable_hba(hba, 1) != 1)
-                               return ERR_PTR(-ENODEV);
+                               return -ENODEV;
 
                        legacy_mode_enable = 1;
                        hba->hba_flags |= HBA_FLAGS_PSCSI_MODE;
@@ -569,14 +521,14 @@ static struct se_device *pscsi_create_virtdevice(
                        if (IS_ERR(sh)) {
                                pr_err("pSCSI: Unable to locate"
                                        " pdv_host_id: %d\n", pdv->pdv_host_id);
-                               return ERR_CAST(sh);
+                               return PTR_ERR(sh);
                        }
                }
        } else {
                if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) {
                        pr_err("pSCSI: PHV_VIRTUAL_HOST_ID set while"
                                " struct Scsi_Host exists\n");
-                       return ERR_PTR(-EEXIST);
+                       return -EEXIST;
                }
        }
 
@@ -593,17 +545,17 @@ static struct se_device *pscsi_create_virtdevice(
                 */
                switch (sd->type) {
                case TYPE_DISK:
-                       dev = pscsi_create_type_disk(sd, pdv, se_dev, hba);
+                       ret = pscsi_create_type_disk(dev, sd);
                        break;
                case TYPE_ROM:
-                       dev = pscsi_create_type_rom(sd, pdv, se_dev, hba);
+                       ret = pscsi_create_type_rom(dev, sd);
                        break;
                default:
-                       dev = pscsi_create_type_other(sd, pdv, se_dev, hba);
+                       ret = pscsi_create_type_other(dev, sd);
                        break;
                }
 
-               if (!dev) {
+               if (ret) {
                        if (phv->phv_mode == PHV_VIRTUAL_HOST_ID)
                                scsi_host_put(sh);
                        else if (legacy_mode_enable) {
@@ -611,9 +563,9 @@ static struct se_device *pscsi_create_virtdevice(
                                hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
                        }
                        pdv->pdv_sd = NULL;
-                       return ERR_PTR(-ENODEV);
+                       return ret;
                }
-               return dev;
+               return 0;
        }
        spin_unlock_irq(sh->host_lock);
 
@@ -627,17 +579,13 @@ static struct se_device *pscsi_create_virtdevice(
                hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
        }
 
-       return ERR_PTR(-ENODEV);
+       return -ENODEV;
 }
 
-/*     pscsi_free_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void pscsi_free_device(void *p)
+static void pscsi_free_device(struct se_device *dev)
 {
-       struct pscsi_dev_virt *pdv = p;
-       struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
        struct scsi_device *sd = pdv->pdv_sd;
 
        if (sd) {
@@ -670,7 +618,7 @@ static void pscsi_free_device(void *p)
 static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg,
                                     unsigned char *sense_buffer)
 {
-       struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
        struct scsi_device *sd = pdv->pdv_sd;
        int result;
        struct pscsi_plugin_task *pt = cmd->priv;
@@ -694,7 +642,11 @@ static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg,
        if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) &&
             (status_byte(result) << 1) == SAM_STAT_GOOD) {
                if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) {
-                       unsigned char *buf = transport_kmap_data_sg(cmd);
+                       unsigned char *buf;
+
+                       buf = transport_kmap_data_sg(cmd);
+                       if (!buf)
+                               ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */
 
                        if (cdb[0] == MODE_SENSE_10) {
                                if (!(buf[3] & 0x80))
@@ -770,13 +722,11 @@ static match_table_t tokens = {
        {Opt_err, NULL}
 };
 
-static ssize_t pscsi_set_configfs_dev_params(struct se_hba *hba,
-       struct se_subsystem_dev *se_dev,
-       const char *page,
-       ssize_t count)
+static ssize_t pscsi_set_configfs_dev_params(struct se_device *dev,
+               const char *page, ssize_t count)
 {
-       struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr;
-       struct pscsi_hba_virt *phv = hba->hba_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
        char *orig, *ptr, *opts;
        substring_t args[MAX_OPT_ARGS];
        int ret = 0, arg, token;
@@ -841,29 +791,10 @@ out:
        return (!ret) ? count : ret;
 }
 
-static ssize_t pscsi_check_configfs_dev_params(
-       struct se_hba *hba,
-       struct se_subsystem_dev *se_dev)
+static ssize_t pscsi_show_configfs_dev_params(struct se_device *dev, char *b)
 {
-       struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr;
-
-       if (!(pdv->pdv_flags & PDF_HAS_CHANNEL_ID) ||
-           !(pdv->pdv_flags & PDF_HAS_TARGET_ID) ||
-           !(pdv->pdv_flags & PDF_HAS_LUN_ID)) {
-               pr_err("Missing scsi_channel_id=, scsi_target_id= and"
-                       " scsi_lun_id= parameters\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static ssize_t pscsi_show_configfs_dev_params(struct se_hba *hba,
-                                             struct se_subsystem_dev *se_dev,
-                                             char *b)
-{
-       struct pscsi_hba_virt *phv = hba->hba_ptr;
-        struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr;
+       struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
        struct scsi_device *sd = pdv->pdv_sd;
        unsigned char host_id[16];
        ssize_t bl;
@@ -929,11 +860,11 @@ static inline struct bio *pscsi_get_bio(int sg_num)
        return bio;
 }
 
-static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl,
-               u32 sgl_nents, enum dma_data_direction data_direction,
-               struct bio **hbio)
+static sense_reason_t
+pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
+               enum dma_data_direction data_direction, struct bio **hbio)
 {
-       struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
        struct bio *bio = NULL, *tbio = NULL;
        struct page *page;
        struct scatterlist *sg;
@@ -1019,7 +950,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl,
                }
        }
 
-       return sgl_nents;
+       return 0;
 fail:
        while (*hbio) {
                bio = *hbio;
@@ -1027,8 +958,7 @@ fail:
                bio->bi_next = NULL;
                bio_endio(bio, 0);      /* XXX: should be error */
        }
-       cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-       return -ENOMEM;
+       return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 }
 
 /*
@@ -1055,17 +985,13 @@ static inline void pscsi_clear_cdb_lun(unsigned char *cdb)
        }
 }
 
-static int pscsi_parse_cdb(struct se_cmd *cmd)
+static sense_reason_t
+pscsi_parse_cdb(struct se_cmd *cmd)
 {
        unsigned char *cdb = cmd->t_task_cdb;
-       unsigned int dummy_size;
-       int ret;
 
-       if (cmd->se_cmd_flags & SCF_BIDI) {
-               cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
-               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
-               return -EINVAL;
-       }
+       if (cmd->se_cmd_flags & SCF_BIDI)
+               return TCM_UNSUPPORTED_SCSI_OPCODE;
 
        pscsi_clear_cdb_lun(cdb);
 
@@ -1076,10 +1002,8 @@ static int pscsi_parse_cdb(struct se_cmd *cmd)
         */
        switch (cdb[0]) {
        case REPORT_LUNS:
-               ret = spc_parse_cdb(cmd, &dummy_size);
-               if (ret)
-                       return ret;
-               break;
+               cmd->execute_cmd = spc_emulate_report_luns;
+               return 0;
        case READ_6:
        case READ_10:
        case READ_12:
@@ -1093,22 +1017,21 @@ static int pscsi_parse_cdb(struct se_cmd *cmd)
                /* FALLTHROUGH*/
        default:
                cmd->execute_cmd = pscsi_execute_cmd;
-               break;
+               return 0;
        }
-
-       return 0;
 }
 
-static int pscsi_execute_cmd(struct se_cmd *cmd)
+static sense_reason_t
+pscsi_execute_cmd(struct se_cmd *cmd)
 {
        struct scatterlist *sgl = cmd->t_data_sg;
        u32 sgl_nents = cmd->t_data_nents;
        enum dma_data_direction data_direction = cmd->data_direction;
-       struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
        struct pscsi_plugin_task *pt;
        struct request *req;
        struct bio *hbio;
-       int ret;
+       sense_reason_t ret;
 
        /*
         * Dynamically alloc cdb space, since it may be larger than
@@ -1116,8 +1039,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
         */
        pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL);
        if (!pt) {
-               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-               return -ENOMEM;
+               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
        }
        cmd->priv = pt;
 
@@ -1131,24 +1053,21 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
                if (!req || IS_ERR(req)) {
                        pr_err("PSCSI: blk_get_request() failed: %ld\n",
                                        req ? IS_ERR(req) : -ENOMEM);
-                       cmd->scsi_sense_reason =
-                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                        goto fail;
                }
        } else {
                BUG_ON(!cmd->data_length);
 
                ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio);
-               if (ret < 0) {
-                       cmd->scsi_sense_reason =
-                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               if (ret)
                        goto fail;
-               }
 
                req = blk_make_request(pdv->pdv_sd->request_queue, hbio,
                                       GFP_KERNEL);
                if (IS_ERR(req)) {
                        pr_err("pSCSI: blk_make_request() failed\n");
+                       ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                        goto fail_free_bio;
                }
        }
@@ -1179,22 +1098,10 @@ fail_free_bio:
                bio->bi_next = NULL;
                bio_endio(bio, 0);      /* XXX: should be error */
        }
-       cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 fail:
        kfree(pt);
-       return -ENOMEM;
-}
-
-/*     pscsi_get_device_rev():
- *
- *
- */
-static u32 pscsi_get_device_rev(struct se_device *dev)
-{
-       struct pscsi_dev_virt *pdv = dev->dev_ptr;
-       struct scsi_device *sd = pdv->pdv_sd;
-
-       return (sd->scsi_level - 1) ? sd->scsi_level - 1 : 1;
+       return ret;
 }
 
 /*     pscsi_get_device_type():
@@ -1203,7 +1110,7 @@ static u32 pscsi_get_device_rev(struct se_device *dev)
  */
 static u32 pscsi_get_device_type(struct se_device *dev)
 {
-       struct pscsi_dev_virt *pdv = dev->dev_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
        struct scsi_device *sd = pdv->pdv_sd;
 
        return sd->type;
@@ -1211,7 +1118,7 @@ static u32 pscsi_get_device_type(struct se_device *dev)
 
 static sector_t pscsi_get_blocks(struct se_device *dev)
 {
-       struct pscsi_dev_virt *pdv = dev->dev_ptr;
+       struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 
        if (pdv->pdv_bd && pdv->pdv_bd->bd_part)
                return pdv->pdv_bd->bd_part->nr_sects;
@@ -1243,7 +1150,6 @@ static void pscsi_req_done(struct request *req, int uptodate)
                pr_debug("PSCSI Host Byte exception at cmd: %p CDB:"
                        " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0],
                        pt->pscsi_result);
-               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
                target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
                break;
        }
@@ -1259,15 +1165,13 @@ static struct se_subsystem_api pscsi_template = {
        .attach_hba             = pscsi_attach_hba,
        .detach_hba             = pscsi_detach_hba,
        .pmode_enable_hba       = pscsi_pmode_enable_hba,
-       .allocate_virtdevice    = pscsi_allocate_virtdevice,
-       .create_virtdevice      = pscsi_create_virtdevice,
+       .alloc_device           = pscsi_alloc_device,
+       .configure_device       = pscsi_configure_device,
        .free_device            = pscsi_free_device,
        .transport_complete     = pscsi_transport_complete,
        .parse_cdb              = pscsi_parse_cdb,
-       .check_configfs_dev_params = pscsi_check_configfs_dev_params,
        .set_configfs_dev_params = pscsi_set_configfs_dev_params,
        .show_configfs_dev_params = pscsi_show_configfs_dev_params,
-       .get_device_rev         = pscsi_get_device_rev,
        .get_device_type        = pscsi_get_device_type,
        .get_blocks             = pscsi_get_blocks,
 };