diff options
author | Christoph Hellwig <hch@lst.de> | 2012-11-06 15:24:09 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-06 23:55:46 -0500 |
commit | de103c93aff0bed0ae984274e5dc8b95899badab (patch) | |
tree | 7db9bba755fa95772052e8d31285a38ba48f1a84 /drivers/target/target_core_pscsi.c | |
parent | fecae40abb1ae9218bdbaa8b8e30bfb5ae43f522 (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.c | 51 |
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 | ||
61 | static struct se_subsystem_api pscsi_template; | 61 | static struct se_subsystem_api pscsi_template; |
62 | 62 | ||
63 | static int pscsi_execute_cmd(struct se_cmd *cmd); | 63 | static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd); |
64 | static void pscsi_req_done(struct request *, int); | 64 | static 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 | ||
859 | static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, | 863 | static sense_reason_t |
860 | u32 sgl_nents, enum dma_data_direction data_direction, | 864 | pscsi_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; |
950 | fail: | 954 | fail: |
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 | ||
985 | static int pscsi_parse_cdb(struct se_cmd *cmd) | 988 | static sense_reason_t |
989 | pscsi_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 | ||
1023 | static int pscsi_execute_cmd(struct se_cmd *cmd) | 1024 | static sense_reason_t |
1025 | pscsi_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; |
1104 | fail: | 1102 | fail: |
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 | } |