diff options
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r-- | drivers/scsi/scsi_debug.c | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3e10c306de94..a783cd33a3e4 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * SAS disks. | 12 | * SAS disks. |
13 | * | 13 | * |
14 | * | 14 | * |
15 | * For documentation see http://www.torque.net/sg/sdebug26.html | 15 | * For documentation see http://sg.danny.cz/sg/sdebug26.html |
16 | * | 16 | * |
17 | * D. Gilbert (dpg) work for Magneto-Optical device test [20010421] | 17 | * D. Gilbert (dpg) work for Magneto-Optical device test [20010421] |
18 | * dpg: work for devfs large number of disks [20010809] | 18 | * dpg: work for devfs large number of disks [20010809] |
@@ -58,8 +58,8 @@ | |||
58 | #include "sd.h" | 58 | #include "sd.h" |
59 | #include "scsi_logging.h" | 59 | #include "scsi_logging.h" |
60 | 60 | ||
61 | #define SCSI_DEBUG_VERSION "1.81" | 61 | #define SCSI_DEBUG_VERSION "1.82" |
62 | static const char * scsi_debug_version_date = "20070104"; | 62 | static const char * scsi_debug_version_date = "20100324"; |
63 | 63 | ||
64 | /* Additional Sense Code (ASC) */ | 64 | /* Additional Sense Code (ASC) */ |
65 | #define NO_ADDITIONAL_SENSE 0x0 | 65 | #define NO_ADDITIONAL_SENSE 0x0 |
@@ -147,12 +147,18 @@ static const char * scsi_debug_version_date = "20070104"; | |||
147 | #define SAM2_LUN_ADDRESS_METHOD 0 | 147 | #define SAM2_LUN_ADDRESS_METHOD 0 |
148 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | 148 | #define SAM2_WLUN_REPORT_LUNS 0xc101 |
149 | 149 | ||
150 | /* Can queue up to this number of commands. Typically commands that | ||
151 | * that have a non-zero delay are queued. */ | ||
152 | #define SCSI_DEBUG_CANQUEUE 255 | ||
153 | |||
150 | static int scsi_debug_add_host = DEF_NUM_HOST; | 154 | static int scsi_debug_add_host = DEF_NUM_HOST; |
151 | static int scsi_debug_delay = DEF_DELAY; | 155 | static int scsi_debug_delay = DEF_DELAY; |
152 | static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB; | 156 | static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB; |
153 | static int scsi_debug_every_nth = DEF_EVERY_NTH; | 157 | static int scsi_debug_every_nth = DEF_EVERY_NTH; |
154 | static int scsi_debug_max_luns = DEF_MAX_LUNS; | 158 | static int scsi_debug_max_luns = DEF_MAX_LUNS; |
159 | static int scsi_debug_max_queue = SCSI_DEBUG_CANQUEUE; | ||
155 | static int scsi_debug_num_parts = DEF_NUM_PARTS; | 160 | static int scsi_debug_num_parts = DEF_NUM_PARTS; |
161 | static int scsi_debug_no_uld = 0; | ||
156 | static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */ | 162 | static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */ |
157 | static int scsi_debug_opts = DEF_OPTS; | 163 | static int scsi_debug_opts = DEF_OPTS; |
158 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; | 164 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; |
@@ -192,7 +198,6 @@ static int sdebug_sectors_per; /* sectors per cylinder */ | |||
192 | 198 | ||
193 | #define SDEBUG_SENSE_LEN 32 | 199 | #define SDEBUG_SENSE_LEN 32 |
194 | 200 | ||
195 | #define SCSI_DEBUG_CANQUEUE 255 | ||
196 | #define SCSI_DEBUG_MAX_CMD_LEN 32 | 201 | #define SCSI_DEBUG_MAX_CMD_LEN 32 |
197 | 202 | ||
198 | struct sdebug_dev_info { | 203 | struct sdebug_dev_info { |
@@ -2265,7 +2270,7 @@ static void timer_intr_handler(unsigned long indx) | |||
2265 | struct sdebug_queued_cmd * sqcp; | 2270 | struct sdebug_queued_cmd * sqcp; |
2266 | unsigned long iflags; | 2271 | unsigned long iflags; |
2267 | 2272 | ||
2268 | if (indx >= SCSI_DEBUG_CANQUEUE) { | 2273 | if (indx >= scsi_debug_max_queue) { |
2269 | printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too " | 2274 | printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too " |
2270 | "large\n"); | 2275 | "large\n"); |
2271 | return; | 2276 | return; |
@@ -2379,6 +2384,8 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp) | |||
2379 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 2384 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, |
2380 | sdp->host->cmd_per_lun); | 2385 | sdp->host->cmd_per_lun); |
2381 | blk_queue_max_segment_size(sdp->request_queue, 256 * 1024); | 2386 | blk_queue_max_segment_size(sdp->request_queue, 256 * 1024); |
2387 | if (scsi_debug_no_uld) | ||
2388 | sdp->no_uld_attach = 1; | ||
2382 | return 0; | 2389 | return 0; |
2383 | } | 2390 | } |
2384 | 2391 | ||
@@ -2405,7 +2412,7 @@ static int stop_queued_cmnd(struct scsi_cmnd *cmnd) | |||
2405 | struct sdebug_queued_cmd *sqcp; | 2412 | struct sdebug_queued_cmd *sqcp; |
2406 | 2413 | ||
2407 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2414 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2408 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | 2415 | for (k = 0; k < scsi_debug_max_queue; ++k) { |
2409 | sqcp = &queued_arr[k]; | 2416 | sqcp = &queued_arr[k]; |
2410 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { | 2417 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { |
2411 | del_timer_sync(&sqcp->cmnd_timer); | 2418 | del_timer_sync(&sqcp->cmnd_timer); |
@@ -2415,7 +2422,7 @@ static int stop_queued_cmnd(struct scsi_cmnd *cmnd) | |||
2415 | } | 2422 | } |
2416 | } | 2423 | } |
2417 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 2424 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2418 | return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0; | 2425 | return (k < scsi_debug_max_queue) ? 1 : 0; |
2419 | } | 2426 | } |
2420 | 2427 | ||
2421 | /* Deletes (stops) timers of all queued commands */ | 2428 | /* Deletes (stops) timers of all queued commands */ |
@@ -2426,7 +2433,7 @@ static void stop_all_queued(void) | |||
2426 | struct sdebug_queued_cmd *sqcp; | 2433 | struct sdebug_queued_cmd *sqcp; |
2427 | 2434 | ||
2428 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2435 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2429 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | 2436 | for (k = 0; k < scsi_debug_max_queue; ++k) { |
2430 | sqcp = &queued_arr[k]; | 2437 | sqcp = &queued_arr[k]; |
2431 | if (sqcp->in_use && sqcp->a_cmnd) { | 2438 | if (sqcp->in_use && sqcp->a_cmnd) { |
2432 | del_timer_sync(&sqcp->cmnd_timer); | 2439 | del_timer_sync(&sqcp->cmnd_timer); |
@@ -2532,7 +2539,7 @@ static void __init init_all_queued(void) | |||
2532 | struct sdebug_queued_cmd * sqcp; | 2539 | struct sdebug_queued_cmd * sqcp; |
2533 | 2540 | ||
2534 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2541 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2535 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | 2542 | for (k = 0; k < scsi_debug_max_queue; ++k) { |
2536 | sqcp = &queued_arr[k]; | 2543 | sqcp = &queued_arr[k]; |
2537 | init_timer(&sqcp->cmnd_timer); | 2544 | init_timer(&sqcp->cmnd_timer); |
2538 | sqcp->in_use = 0; | 2545 | sqcp->in_use = 0; |
@@ -2624,12 +2631,12 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
2624 | struct sdebug_queued_cmd * sqcp = NULL; | 2631 | struct sdebug_queued_cmd * sqcp = NULL; |
2625 | 2632 | ||
2626 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2633 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2627 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | 2634 | for (k = 0; k < scsi_debug_max_queue; ++k) { |
2628 | sqcp = &queued_arr[k]; | 2635 | sqcp = &queued_arr[k]; |
2629 | if (! sqcp->in_use) | 2636 | if (! sqcp->in_use) |
2630 | break; | 2637 | break; |
2631 | } | 2638 | } |
2632 | if (k >= SCSI_DEBUG_CANQUEUE) { | 2639 | if (k >= scsi_debug_max_queue) { |
2633 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 2640 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2634 | printk(KERN_WARNING "scsi_debug: can_queue exceeded\n"); | 2641 | printk(KERN_WARNING "scsi_debug: can_queue exceeded\n"); |
2635 | return 1; /* report busy to mid level */ | 2642 | return 1; /* report busy to mid level */ |
@@ -2661,7 +2668,9 @@ module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR); | |||
2661 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); | 2668 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); |
2662 | module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR); | 2669 | module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR); |
2663 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); | 2670 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); |
2671 | module_param_named(max_queue, scsi_debug_max_queue, int, S_IRUGO | S_IWUSR); | ||
2664 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); | 2672 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); |
2673 | module_param_named(no_uld, scsi_debug_no_uld, int, S_IRUGO); | ||
2665 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); | 2674 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); |
2666 | module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR); | 2675 | module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR); |
2667 | module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR); | 2676 | module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR); |
@@ -2694,7 +2703,9 @@ MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); | |||
2694 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=0)"); | 2703 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=0)"); |
2695 | MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)"); | 2704 | MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)"); |
2696 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); | 2705 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
2706 | MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to 255(def))"); | ||
2697 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | 2707 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); |
2708 | MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); | ||
2698 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 2709 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
2699 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); | 2710 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); |
2700 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)"); | 2711 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)"); |
@@ -2969,6 +2980,31 @@ static ssize_t sdebug_max_luns_store(struct device_driver * ddp, | |||
2969 | DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show, | 2980 | DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show, |
2970 | sdebug_max_luns_store); | 2981 | sdebug_max_luns_store); |
2971 | 2982 | ||
2983 | static ssize_t sdebug_max_queue_show(struct device_driver * ddp, char * buf) | ||
2984 | { | ||
2985 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_queue); | ||
2986 | } | ||
2987 | static ssize_t sdebug_max_queue_store(struct device_driver * ddp, | ||
2988 | const char * buf, size_t count) | ||
2989 | { | ||
2990 | int n; | ||
2991 | |||
2992 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) && | ||
2993 | (n <= SCSI_DEBUG_CANQUEUE)) { | ||
2994 | scsi_debug_max_queue = n; | ||
2995 | return count; | ||
2996 | } | ||
2997 | return -EINVAL; | ||
2998 | } | ||
2999 | DRIVER_ATTR(max_queue, S_IRUGO | S_IWUSR, sdebug_max_queue_show, | ||
3000 | sdebug_max_queue_store); | ||
3001 | |||
3002 | static ssize_t sdebug_no_uld_show(struct device_driver * ddp, char * buf) | ||
3003 | { | ||
3004 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_uld); | ||
3005 | } | ||
3006 | DRIVER_ATTR(no_uld, S_IRUGO, sdebug_no_uld_show, NULL); | ||
3007 | |||
2972 | static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) | 3008 | static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) |
2973 | { | 3009 | { |
2974 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level); | 3010 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level); |
@@ -3106,7 +3142,9 @@ static int do_create_driverfs_files(void) | |||
3106 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); | 3142 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); |
3107 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_fake_rw); | 3143 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_fake_rw); |
3108 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); | 3144 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); |
3145 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_queue); | ||
3109 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0); | 3146 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0); |
3147 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_uld); | ||
3110 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); | 3148 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); |
3111 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); | 3149 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); |
3112 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); | 3150 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); |
@@ -3138,7 +3176,9 @@ static void do_remove_driverfs_files(void) | |||
3138 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype); | 3176 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype); |
3139 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); | 3177 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); |
3140 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts); | 3178 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts); |
3179 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_uld); | ||
3141 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0); | 3180 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0); |
3181 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_queue); | ||
3142 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns); | 3182 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns); |
3143 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_fake_rw); | 3183 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_fake_rw); |
3144 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth); | 3184 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth); |
@@ -3829,12 +3869,13 @@ static int sdebug_driver_probe(struct device * dev) | |||
3829 | 3869 | ||
3830 | sdbg_host = to_sdebug_host(dev); | 3870 | sdbg_host = to_sdebug_host(dev); |
3831 | 3871 | ||
3832 | hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); | 3872 | sdebug_driver_template.can_queue = scsi_debug_max_queue; |
3833 | if (NULL == hpnt) { | 3873 | hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); |
3834 | printk(KERN_ERR "%s: scsi_register failed\n", __func__); | 3874 | if (NULL == hpnt) { |
3835 | error = -ENODEV; | 3875 | printk(KERN_ERR "%s: scsi_register failed\n", __func__); |
3876 | error = -ENODEV; | ||
3836 | return error; | 3877 | return error; |
3837 | } | 3878 | } |
3838 | 3879 | ||
3839 | sdbg_host->shost = hpnt; | 3880 | sdbg_host->shost = hpnt; |
3840 | *((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host; | 3881 | *((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host; |