aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2014-05-01 10:51:04 -0400
committerChristoph Hellwig <hch@lst.de>2014-05-19 06:35:09 -0400
commita1b73fc194e73ed33c8b77bf09374cb05b58151b (patch)
tree6487feb93c538ca97313408dabdb1f957d6246fe
parentbc85dc500f9df9b2eec15077e5046672c46adeaa (diff)
scsi: reintroduce scsi_driver.init_command
Instead of letting the ULD play games with the prep_fn move back to the model of a central prep_fn with a callback to the ULD. This already cleans up and shortens the code by itself, and will be required to properly support blk-mq in the SCSI midlayer. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Nicholas Bellinger <nab@linux-iscsi.org> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Reviewed-by: Hannes Reinecke <hare@suse.de>
-rw-r--r--drivers/scsi/scsi_lib.c66
-rw-r--r--drivers/scsi/sd.c44
-rw-r--r--drivers/scsi/sr.c19
-rw-r--r--include/scsi/scsi_driver.h9
4 files changed, 62 insertions, 76 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 045822befad9..9f841df6add8 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1073,15 +1073,7 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
1073 1073
1074int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) 1074int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1075{ 1075{
1076 struct scsi_cmnd *cmd; 1076 struct scsi_cmnd *cmd = req->special;
1077 int ret = scsi_prep_state_check(sdev, req);
1078
1079 if (ret != BLKPREP_OK)
1080 return ret;
1081
1082 cmd = scsi_get_cmd_from_req(sdev, req);
1083 if (unlikely(!cmd))
1084 return BLKPREP_DEFER;
1085 1077
1086 /* 1078 /*
1087 * BLOCK_PC requests may transfer data, in which case they must 1079 * BLOCK_PC requests may transfer data, in which case they must
@@ -1125,15 +1117,11 @@ EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
1125 */ 1117 */
1126int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) 1118int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
1127{ 1119{
1128 struct scsi_cmnd *cmd; 1120 struct scsi_cmnd *cmd = req->special;
1129 int ret = scsi_prep_state_check(sdev, req);
1130
1131 if (ret != BLKPREP_OK)
1132 return ret;
1133 1121
1134 if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh 1122 if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh
1135 && sdev->scsi_dh_data->scsi_dh->prep_fn)) { 1123 && sdev->scsi_dh_data->scsi_dh->prep_fn)) {
1136 ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req); 1124 int ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req);
1137 if (ret != BLKPREP_OK) 1125 if (ret != BLKPREP_OK)
1138 return ret; 1126 return ret;
1139 } 1127 }
@@ -1143,16 +1131,13 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
1143 */ 1131 */
1144 BUG_ON(!req->nr_phys_segments); 1132 BUG_ON(!req->nr_phys_segments);
1145 1133
1146 cmd = scsi_get_cmd_from_req(sdev, req);
1147 if (unlikely(!cmd))
1148 return BLKPREP_DEFER;
1149
1150 memset(cmd->cmnd, 0, BLK_MAX_CDB); 1134 memset(cmd->cmnd, 0, BLK_MAX_CDB);
1151 return scsi_init_io(cmd, GFP_ATOMIC); 1135 return scsi_init_io(cmd, GFP_ATOMIC);
1152} 1136}
1153EXPORT_SYMBOL(scsi_setup_fs_cmnd); 1137EXPORT_SYMBOL(scsi_setup_fs_cmnd);
1154 1138
1155int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) 1139static int
1140scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
1156{ 1141{
1157 int ret = BLKPREP_OK; 1142 int ret = BLKPREP_OK;
1158 1143
@@ -1204,9 +1189,9 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
1204 } 1189 }
1205 return ret; 1190 return ret;
1206} 1191}
1207EXPORT_SYMBOL(scsi_prep_state_check);
1208 1192
1209int scsi_prep_return(struct request_queue *q, struct request *req, int ret) 1193static int
1194scsi_prep_return(struct request_queue *q, struct request *req, int ret)
1210{ 1195{
1211 struct scsi_device *sdev = q->queuedata; 1196 struct scsi_device *sdev = q->queuedata;
1212 1197
@@ -1237,18 +1222,44 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret)
1237 1222
1238 return ret; 1223 return ret;
1239} 1224}
1240EXPORT_SYMBOL(scsi_prep_return);
1241 1225
1242int scsi_prep_fn(struct request_queue *q, struct request *req) 1226static int scsi_prep_fn(struct request_queue *q, struct request *req)
1243{ 1227{
1244 struct scsi_device *sdev = q->queuedata; 1228 struct scsi_device *sdev = q->queuedata;
1245 int ret = BLKPREP_KILL; 1229 struct scsi_cmnd *cmd;
1230 int ret;
1246 1231
1247 if (req->cmd_type == REQ_TYPE_BLOCK_PC) 1232 ret = scsi_prep_state_check(sdev, req);
1233 if (ret != BLKPREP_OK)
1234 goto out;
1235
1236 cmd = scsi_get_cmd_from_req(sdev, req);
1237 if (unlikely(!cmd)) {
1238 ret = BLKPREP_DEFER;
1239 goto out;
1240 }
1241
1242 if (req->cmd_type == REQ_TYPE_FS)
1243 ret = scsi_cmd_to_driver(cmd)->init_command(cmd);
1244 else if (req->cmd_type == REQ_TYPE_BLOCK_PC)
1248 ret = scsi_setup_blk_pc_cmnd(sdev, req); 1245 ret = scsi_setup_blk_pc_cmnd(sdev, req);
1246 else
1247 ret = BLKPREP_KILL;
1248
1249out:
1249 return scsi_prep_return(q, req, ret); 1250 return scsi_prep_return(q, req, ret);
1250} 1251}
1251EXPORT_SYMBOL(scsi_prep_fn); 1252
1253static void scsi_unprep_fn(struct request_queue *q, struct request *req)
1254{
1255 if (req->cmd_type == REQ_TYPE_FS) {
1256 struct scsi_cmnd *cmd = req->special;
1257 struct scsi_driver *drv = scsi_cmd_to_driver(cmd);
1258
1259 if (drv->uninit_command)
1260 drv->uninit_command(cmd);
1261 }
1262}
1252 1263
1253/* 1264/*
1254 * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else 1265 * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else
@@ -1669,6 +1680,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
1669 return NULL; 1680 return NULL;
1670 1681
1671 blk_queue_prep_rq(q, scsi_prep_fn); 1682 blk_queue_prep_rq(q, scsi_prep_fn);
1683 blk_queue_unprep_rq(q, scsi_unprep_fn);
1672 blk_queue_softirq_done(q, scsi_softirq_done); 1684 blk_queue_softirq_done(q, scsi_softirq_done);
1673 blk_queue_rq_timed_out(q, scsi_times_out); 1685 blk_queue_rq_timed_out(q, scsi_times_out);
1674 blk_queue_lld_busy(q, scsi_lld_busy); 1686 blk_queue_lld_busy(q, scsi_lld_busy);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index efcbcd182863..aa028d8ae774 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -109,6 +109,8 @@ static int sd_suspend_system(struct device *);
109static int sd_suspend_runtime(struct device *); 109static int sd_suspend_runtime(struct device *);
110static int sd_resume(struct device *); 110static int sd_resume(struct device *);
111static void sd_rescan(struct device *); 111static void sd_rescan(struct device *);
112static int sd_init_command(struct scsi_cmnd *SCpnt);
113static void sd_uninit_command(struct scsi_cmnd *SCpnt);
112static int sd_done(struct scsi_cmnd *); 114static int sd_done(struct scsi_cmnd *);
113static int sd_eh_action(struct scsi_cmnd *, int); 115static int sd_eh_action(struct scsi_cmnd *, int);
114static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); 116static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
@@ -503,6 +505,8 @@ static struct scsi_driver sd_template = {
503 .pm = &sd_pm_ops, 505 .pm = &sd_pm_ops,
504 }, 506 },
505 .rescan = sd_rescan, 507 .rescan = sd_rescan,
508 .init_command = sd_init_command,
509 .uninit_command = sd_uninit_command,
506 .done = sd_done, 510 .done = sd_done,
507 .eh_action = sd_eh_action, 511 .eh_action = sd_eh_action,
508}; 512};
@@ -838,9 +842,9 @@ static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
838 return scsi_setup_blk_pc_cmnd(sdp, rq); 842 return scsi_setup_blk_pc_cmnd(sdp, rq);
839} 843}
840 844
841static void sd_unprep_fn(struct request_queue *q, struct request *rq) 845static void sd_uninit_command(struct scsi_cmnd *SCpnt)
842{ 846{
843 struct scsi_cmnd *SCpnt = rq->special; 847 struct request *rq = SCpnt->request;
844 848
845 if (rq->cmd_flags & REQ_DISCARD) { 849 if (rq->cmd_flags & REQ_DISCARD) {
846 free_page((unsigned long)rq->buffer); 850 free_page((unsigned long)rq->buffer);
@@ -853,18 +857,10 @@ static void sd_unprep_fn(struct request_queue *q, struct request *rq)
853 } 857 }
854} 858}
855 859
856/** 860static int sd_init_command(struct scsi_cmnd *SCpnt)
857 * sd_prep_fn - build a scsi (read or write) command from
858 * information in the request structure.
859 * @SCpnt: pointer to mid-level's per scsi command structure that
860 * contains request and into which the scsi command is written
861 *
862 * Returns 1 if successful and 0 if error (or cannot be done now).
863 **/
864static int sd_prep_fn(struct request_queue *q, struct request *rq)
865{ 861{
866 struct scsi_cmnd *SCpnt; 862 struct request *rq = SCpnt->request;
867 struct scsi_device *sdp = q->queuedata; 863 struct scsi_device *sdp = SCpnt->device;
868 struct gendisk *disk = rq->rq_disk; 864 struct gendisk *disk = rq->rq_disk;
869 struct scsi_disk *sdkp; 865 struct scsi_disk *sdkp;
870 sector_t block = blk_rq_pos(rq); 866 sector_t block = blk_rq_pos(rq);
@@ -886,12 +882,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
886 } else if (rq->cmd_flags & REQ_FLUSH) { 882 } else if (rq->cmd_flags & REQ_FLUSH) {
887 ret = scsi_setup_flush_cmnd(sdp, rq); 883 ret = scsi_setup_flush_cmnd(sdp, rq);
888 goto out; 884 goto out;
889 } else if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
890 ret = scsi_setup_blk_pc_cmnd(sdp, rq);
891 goto out;
892 } else if (rq->cmd_type != REQ_TYPE_FS) {
893 ret = BLKPREP_KILL;
894 goto out;
895 } 885 }
896 ret = scsi_setup_fs_cmnd(sdp, rq); 886 ret = scsi_setup_fs_cmnd(sdp, rq);
897 if (ret != BLKPREP_OK) 887 if (ret != BLKPREP_OK)
@@ -903,11 +893,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
903 * is used for a killable error condition */ 893 * is used for a killable error condition */
904 ret = BLKPREP_KILL; 894 ret = BLKPREP_KILL;
905 895
906 SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, 896 SCSI_LOG_HLQUEUE(1,
907 "sd_prep_fn: block=%llu, " 897 scmd_printk(KERN_INFO, SCpnt,
908 "count=%d\n", 898 "%s: block=%llu, count=%d\n",
909 (unsigned long long)block, 899 __func__, (unsigned long long)block, this_count));
910 this_count));
911 900
912 if (!sdp || !scsi_device_online(sdp) || 901 if (!sdp || !scsi_device_online(sdp) ||
913 block + blk_rq_sectors(rq) > get_capacity(disk)) { 902 block + blk_rq_sectors(rq) > get_capacity(disk)) {
@@ -1127,7 +1116,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
1127 */ 1116 */
1128 ret = BLKPREP_OK; 1117 ret = BLKPREP_OK;
1129 out: 1118 out:
1130 return scsi_prep_return(q, rq, ret); 1119 return ret;
1131} 1120}
1132 1121
1133/** 1122/**
@@ -2878,9 +2867,6 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
2878 2867
2879 sd_revalidate_disk(gd); 2868 sd_revalidate_disk(gd);
2880 2869
2881 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
2882 blk_queue_unprep_rq(sdp->request_queue, sd_unprep_fn);
2883
2884 gd->driverfs_dev = &sdp->sdev_gendev; 2870 gd->driverfs_dev = &sdp->sdev_gendev;
2885 gd->flags = GENHD_FL_EXT_DEVT; 2871 gd->flags = GENHD_FL_EXT_DEVT;
2886 if (sdp->removable) { 2872 if (sdp->removable) {
@@ -3028,8 +3014,6 @@ static int sd_remove(struct device *dev)
3028 3014
3029 async_synchronize_full_domain(&scsi_sd_pm_domain); 3015 async_synchronize_full_domain(&scsi_sd_pm_domain);
3030 async_synchronize_full_domain(&scsi_sd_probe_domain); 3016 async_synchronize_full_domain(&scsi_sd_probe_domain);
3031 blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn);
3032 blk_queue_unprep_rq(sdkp->device->request_queue, NULL);
3033 device_del(&sdkp->dev); 3017 device_del(&sdkp->dev);
3034 del_gendisk(sdkp->disk); 3018 del_gendisk(sdkp->disk);
3035 sd_shutdown(dev); 3019 sd_shutdown(dev);
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 40d85929aefe..93cbd36c990b 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -79,6 +79,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
79static DEFINE_MUTEX(sr_mutex); 79static DEFINE_MUTEX(sr_mutex);
80static int sr_probe(struct device *); 80static int sr_probe(struct device *);
81static int sr_remove(struct device *); 81static int sr_remove(struct device *);
82static int sr_init_command(struct scsi_cmnd *SCpnt);
82static int sr_done(struct scsi_cmnd *); 83static int sr_done(struct scsi_cmnd *);
83static int sr_runtime_suspend(struct device *dev); 84static int sr_runtime_suspend(struct device *dev);
84 85
@@ -94,6 +95,7 @@ static struct scsi_driver sr_template = {
94 .remove = sr_remove, 95 .remove = sr_remove,
95 .pm = &sr_pm_ops, 96 .pm = &sr_pm_ops,
96 }, 97 },
98 .init_command = sr_init_command,
97 .done = sr_done, 99 .done = sr_done,
98}; 100};
99 101
@@ -378,21 +380,14 @@ static int sr_done(struct scsi_cmnd *SCpnt)
378 return good_bytes; 380 return good_bytes;
379} 381}
380 382
381static int sr_prep_fn(struct request_queue *q, struct request *rq) 383static int sr_init_command(struct scsi_cmnd *SCpnt)
382{ 384{
383 int block = 0, this_count, s_size; 385 int block = 0, this_count, s_size;
384 struct scsi_cd *cd; 386 struct scsi_cd *cd;
385 struct scsi_cmnd *SCpnt; 387 struct request *rq = SCpnt->request;
386 struct scsi_device *sdp = q->queuedata; 388 struct scsi_device *sdp = SCpnt->device;
387 int ret; 389 int ret;
388 390
389 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
390 ret = scsi_setup_blk_pc_cmnd(sdp, rq);
391 goto out;
392 } else if (rq->cmd_type != REQ_TYPE_FS) {
393 ret = BLKPREP_KILL;
394 goto out;
395 }
396 ret = scsi_setup_fs_cmnd(sdp, rq); 391 ret = scsi_setup_fs_cmnd(sdp, rq);
397 if (ret != BLKPREP_OK) 392 if (ret != BLKPREP_OK)
398 goto out; 393 goto out;
@@ -517,7 +512,7 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
517 */ 512 */
518 ret = BLKPREP_OK; 513 ret = BLKPREP_OK;
519 out: 514 out:
520 return scsi_prep_return(q, rq, ret); 515 return ret;
521} 516}
522 517
523static int sr_block_open(struct block_device *bdev, fmode_t mode) 518static int sr_block_open(struct block_device *bdev, fmode_t mode)
@@ -718,7 +713,6 @@ static int sr_probe(struct device *dev)
718 713
719 /* FIXME: need to handle a get_capabilities failure properly ?? */ 714 /* FIXME: need to handle a get_capabilities failure properly ?? */
720 get_capabilities(cd); 715 get_capabilities(cd);
721 blk_queue_prep_rq(sdev->request_queue, sr_prep_fn);
722 sr_vendor_init(cd); 716 sr_vendor_init(cd);
723 717
724 disk->driverfs_dev = &sdev->sdev_gendev; 718 disk->driverfs_dev = &sdev->sdev_gendev;
@@ -993,7 +987,6 @@ static int sr_remove(struct device *dev)
993 987
994 scsi_autopm_get_device(cd->device); 988 scsi_autopm_get_device(cd->device);
995 989
996 blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn);
997 del_gendisk(cd->disk); 990 del_gendisk(cd->disk);
998 991
999 mutex_lock(&sr_ref_mutex); 992 mutex_lock(&sr_ref_mutex);
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index 20fdfc2526ad..36c4114ed9bc 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -4,17 +4,17 @@
4#include <linux/device.h> 4#include <linux/device.h>
5 5
6struct module; 6struct module;
7struct request;
7struct scsi_cmnd; 8struct scsi_cmnd;
8struct scsi_device; 9struct scsi_device;
9struct request;
10struct request_queue;
11
12 10
13struct scsi_driver { 11struct scsi_driver {
14 struct module *owner; 12 struct module *owner;
15 struct device_driver gendrv; 13 struct device_driver gendrv;
16 14
17 void (*rescan)(struct device *); 15 void (*rescan)(struct device *);
16 int (*init_command)(struct scsi_cmnd *);
17 void (*uninit_command)(struct scsi_cmnd *);
18 int (*done)(struct scsi_cmnd *); 18 int (*done)(struct scsi_cmnd *);
19 int (*eh_action)(struct scsi_cmnd *, int); 19 int (*eh_action)(struct scsi_cmnd *, int);
20}; 20};
@@ -31,8 +31,5 @@ extern int scsi_register_interface(struct class_interface *);
31 31
32int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req); 32int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req);
33int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); 33int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req);
34int scsi_prep_state_check(struct scsi_device *sdev, struct request *req);
35int scsi_prep_return(struct request_queue *q, struct request *req, int ret);
36int scsi_prep_fn(struct request_queue *, struct request *);
37 34
38#endif /* _SCSI_SCSI_DRIVER_H */ 35#endif /* _SCSI_SCSI_DRIVER_H */