]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/target/target_core_pscsi.c
Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[karo-tx-linux.git] / drivers / target / target_core_pscsi.c
index dc10e29934d7ec65373b442bda34e232e451b9b3..2bcfd79cf59556d46199e4bac2d2f18694f6cc87 100644 (file)
@@ -3,10 +3,7 @@
  *
  * This file contains the generic target mode <-> Linux SCSI subsystem plugin.
  *
- * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc.
- * Copyright (c) 2005, 2006, 2007 SBE, Inc.
- * Copyright (c) 2007-2010 Rising Tide Systems
- * Copyright (c) 2008-2010 Linux-iSCSI.org
+ * (c) Copyright 2003-2012 RisingTide Systems LLC.
  *
  * Nicholas A. Bellinger <nab@kernel.org>
  *
@@ -60,7 +57,7 @@ static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *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():
@@ -461,7 +458,7 @@ static int pscsi_create_type_other(struct se_device *dev,
        return 0;
 }
 
-int pscsi_configure_device(struct se_device *dev)
+static int pscsi_configure_device(struct se_device *dev)
 {
        struct se_hba *hba = dev->se_hba;
        struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
@@ -642,7 +639,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))
@@ -856,9 +857,9 @@ 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 = PSCSI_DEV(cmd->se_dev);
        struct bio *bio = NULL, *tbio = NULL;
@@ -946,7 +947,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl,
                }
        }
 
-       return sgl_nents;
+       return 0;
 fail:
        while (*hbio) {
                bio = *hbio;
@@ -954,8 +955,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;
 }
 
 /*
@@ -982,15 +982,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;
 
-       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);
 
@@ -1001,7 +999,8 @@ static int pscsi_parse_cdb(struct se_cmd *cmd)
         */
        switch (cdb[0]) {
        case REPORT_LUNS:
-               return spc_emulate_report_luns(cmd);
+               cmd->execute_cmd = spc_emulate_report_luns;
+               return 0;
        case READ_6:
        case READ_10:
        case READ_12:
@@ -1019,7 +1018,8 @@ static int pscsi_parse_cdb(struct se_cmd *cmd)
        }
 }
 
-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;
@@ -1028,7 +1028,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
        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
@@ -1036,8 +1036,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;
 
@@ -1051,24 +1050,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;
                }
        }
@@ -1099,22 +1095,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 = PSCSI_DEV(dev);
-       struct scsi_device *sd = pdv->pdv_sd;
-
-       return (sd->scsi_level - 1) ? sd->scsi_level - 1 : 1;
+       return ret;
 }
 
 /*     pscsi_get_device_type():
@@ -1163,7 +1147,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;
        }
@@ -1186,7 +1169,6 @@ static struct se_subsystem_api pscsi_template = {
        .parse_cdb              = pscsi_parse_cdb,
        .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,
 };