aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_pscsi.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2012-11-06 15:24:09 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 23:55:46 -0500
commitde103c93aff0bed0ae984274e5dc8b95899badab (patch)
tree7db9bba755fa95772052e8d31285a38ba48f1a84 /drivers/target/target_core_pscsi.c
parentfecae40abb1ae9218bdbaa8b8e30bfb5ae43f522 (diff)
target: pass sense_reason as a return value
Pass the sense reason as an explicit return value from the I/O submission path instead of storing it in struct se_cmd and using negative return values. This cleans up a lot of the code pathes, and with the sparse annotations for the new sense_reason_t type allows for much better error checking. (nab: Convert spc_emulate_modesense + spc_emulate_modeselect to use sense_reason_t with Roland's MODE SELECT changes) Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_pscsi.c')
-rw-r--r--drivers/target/target_core_pscsi.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index aa3e80a2f8db..b5c722bdd993 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -60,7 +60,7 @@ static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev)
60 60
61static struct se_subsystem_api pscsi_template; 61static struct se_subsystem_api pscsi_template;
62 62
63static int pscsi_execute_cmd(struct se_cmd *cmd); 63static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd);
64static void pscsi_req_done(struct request *, int); 64static void pscsi_req_done(struct request *, int);
65 65
66/* pscsi_attach_hba(): 66/* pscsi_attach_hba():
@@ -642,7 +642,11 @@ static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg,
642 if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && 642 if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) &&
643 (status_byte(result) << 1) == SAM_STAT_GOOD) { 643 (status_byte(result) << 1) == SAM_STAT_GOOD) {
644 if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { 644 if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) {
645 unsigned char *buf = transport_kmap_data_sg(cmd); 645 unsigned char *buf;
646
647 buf = transport_kmap_data_sg(cmd);
648 if (!buf)
649 ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */
646 650
647 if (cdb[0] == MODE_SENSE_10) { 651 if (cdb[0] == MODE_SENSE_10) {
648 if (!(buf[3] & 0x80)) 652 if (!(buf[3] & 0x80))
@@ -856,9 +860,9 @@ static inline struct bio *pscsi_get_bio(int sg_num)
856 return bio; 860 return bio;
857} 861}
858 862
859static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, 863static sense_reason_t
860 u32 sgl_nents, enum dma_data_direction data_direction, 864pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
861 struct bio **hbio) 865 enum dma_data_direction data_direction, struct bio **hbio)
862{ 866{
863 struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); 867 struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
864 struct bio *bio = NULL, *tbio = NULL; 868 struct bio *bio = NULL, *tbio = NULL;
@@ -946,7 +950,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl,
946 } 950 }
947 } 951 }
948 952
949 return sgl_nents; 953 return 0;
950fail: 954fail:
951 while (*hbio) { 955 while (*hbio) {
952 bio = *hbio; 956 bio = *hbio;
@@ -954,8 +958,7 @@ fail:
954 bio->bi_next = NULL; 958 bio->bi_next = NULL;
955 bio_endio(bio, 0); /* XXX: should be error */ 959 bio_endio(bio, 0); /* XXX: should be error */
956 } 960 }
957 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 961 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
958 return -ENOMEM;
959} 962}
960 963
961/* 964/*
@@ -982,15 +985,13 @@ static inline void pscsi_clear_cdb_lun(unsigned char *cdb)
982 } 985 }
983} 986}
984 987
985static int pscsi_parse_cdb(struct se_cmd *cmd) 988static sense_reason_t
989pscsi_parse_cdb(struct se_cmd *cmd)
986{ 990{
987 unsigned char *cdb = cmd->t_task_cdb; 991 unsigned char *cdb = cmd->t_task_cdb;
988 992
989 if (cmd->se_cmd_flags & SCF_BIDI) { 993 if (cmd->se_cmd_flags & SCF_BIDI)
990 cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; 994 return TCM_UNSUPPORTED_SCSI_OPCODE;
991 cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
992 return -EINVAL;
993 }
994 995
995 pscsi_clear_cdb_lun(cdb); 996 pscsi_clear_cdb_lun(cdb);
996 997
@@ -1020,7 +1021,8 @@ static int pscsi_parse_cdb(struct se_cmd *cmd)
1020 } 1021 }
1021} 1022}
1022 1023
1023static int pscsi_execute_cmd(struct se_cmd *cmd) 1024static sense_reason_t
1025pscsi_execute_cmd(struct se_cmd *cmd)
1024{ 1026{
1025 struct scatterlist *sgl = cmd->t_data_sg; 1027 struct scatterlist *sgl = cmd->t_data_sg;
1026 u32 sgl_nents = cmd->t_data_nents; 1028 u32 sgl_nents = cmd->t_data_nents;
@@ -1029,7 +1031,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
1029 struct pscsi_plugin_task *pt; 1031 struct pscsi_plugin_task *pt;
1030 struct request *req; 1032 struct request *req;
1031 struct bio *hbio; 1033 struct bio *hbio;
1032 int ret; 1034 sense_reason_t ret;
1033 1035
1034 /* 1036 /*
1035 * Dynamically alloc cdb space, since it may be larger than 1037 * Dynamically alloc cdb space, since it may be larger than
@@ -1037,8 +1039,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
1037 */ 1039 */
1038 pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL); 1040 pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL);
1039 if (!pt) { 1041 if (!pt) {
1040 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1042 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1041 return -ENOMEM;
1042 } 1043 }
1043 cmd->priv = pt; 1044 cmd->priv = pt;
1044 1045
@@ -1052,24 +1053,21 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
1052 if (!req || IS_ERR(req)) { 1053 if (!req || IS_ERR(req)) {
1053 pr_err("PSCSI: blk_get_request() failed: %ld\n", 1054 pr_err("PSCSI: blk_get_request() failed: %ld\n",
1054 req ? IS_ERR(req) : -ENOMEM); 1055 req ? IS_ERR(req) : -ENOMEM);
1055 cmd->scsi_sense_reason = 1056 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1056 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1057 goto fail; 1057 goto fail;
1058 } 1058 }
1059 } else { 1059 } else {
1060 BUG_ON(!cmd->data_length); 1060 BUG_ON(!cmd->data_length);
1061 1061
1062 ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio); 1062 ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio);
1063 if (ret < 0) { 1063 if (ret)
1064 cmd->scsi_sense_reason =
1065 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1066 goto fail; 1064 goto fail;
1067 }
1068 1065
1069 req = blk_make_request(pdv->pdv_sd->request_queue, hbio, 1066 req = blk_make_request(pdv->pdv_sd->request_queue, hbio,
1070 GFP_KERNEL); 1067 GFP_KERNEL);
1071 if (IS_ERR(req)) { 1068 if (IS_ERR(req)) {
1072 pr_err("pSCSI: blk_make_request() failed\n"); 1069 pr_err("pSCSI: blk_make_request() failed\n");
1070 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1073 goto fail_free_bio; 1071 goto fail_free_bio;
1074 } 1072 }
1075 } 1073 }
@@ -1100,10 +1098,10 @@ fail_free_bio:
1100 bio->bi_next = NULL; 1098 bio->bi_next = NULL;
1101 bio_endio(bio, 0); /* XXX: should be error */ 1099 bio_endio(bio, 0); /* XXX: should be error */
1102 } 1100 }
1103 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1101 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1104fail: 1102fail:
1105 kfree(pt); 1103 kfree(pt);
1106 return -ENOMEM; 1104 return ret;
1107} 1105}
1108 1106
1109/* pscsi_get_device_type(): 1107/* pscsi_get_device_type():
@@ -1152,7 +1150,6 @@ static void pscsi_req_done(struct request *req, int uptodate)
1152 pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" 1150 pr_debug("PSCSI Host Byte exception at cmd: %p CDB:"
1153 " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], 1151 " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0],
1154 pt->pscsi_result); 1152 pt->pscsi_result);
1155 cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
1156 target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); 1153 target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
1157 break; 1154 break;
1158 } 1155 }