diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2014-07-26 11:55:35 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-07-26 11:55:35 -0400 |
commit | cbf67842c3d9e7af8ccc031332b79e88d9cca592 (patch) | |
tree | e7dd418f136d8be28b432d295f371ad8a17d523a | |
parent | f3cfabce7a2e92564d380de3aad4b43901fb7ae6 (diff) |
scsi_debug: support scsi-mq, queues and locks
- add host_lock option whose default value is 0 which removes the
host_lock around all queued commands
- accept delay=-1 (_hi_) or -2 which use a tasklet to invoke
the scsi_done callback into the mid-layer. The default
is still delay=1 which uses a timer to delay 1 jiffy
- wire .change_queue_depth and .change_queue_type
functions to better simulate queueing in a modern LLD
- add SCSI_DEBUG_OPT_Q_NOISE (0x200) mask to only produce
debug output associated with queue full, plus from
.change_queue_depth and .change_queue_type functions
- add SCSI_DEBUG_OPT_ALL_TSF (0x400) mask which reports
all queued_arr fulls at TASK_SET_FULL, otherwise
SCSI_MLQUEUE_HOST_BUSY is returned
- add SCSI_DEBUG_OPT_RARE_TSF (0x800) mask which works
together with the every_nth option (> 0) to count
occurrences of num_in_q==queue_depth. When every_nth
is reached the victim (a command) yields TASK SET FULL
- clean up many debug messages.
- add ndelay=<nanosecs> option that uses high resolution
timers; active if > 0 and then overrides delay= option
- expand Unit Attention handling: POR, BUS_RESET and
MODE PARAMETERS CHANGED
- support .eh_target_reset_handler and drop .bios_param
- add OPT_N_WCE mask so caching page yields WCE=0
- add OPT_RESET_NOISE mask to log aborts and resets
- add OPT_NO_CDB_NOISE mask to not log each cdb
- MODE SELECT support for changing caching page's WCE
- name common ioctls in log
- when fake_rw=1, do not vmalloc fake store; make
UNMAP and WRITE SAME obey fake_rw
- more logging and code improvements including better
sense buffer handling
With fio and four (pseudo) devices I have observed 1.2 M IOPS
on my equipment. Rob Elliott who has done much testing and made
numerous suggestions, has better IOPS results than mine.
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Reviewed-by: Robert Elliott <elliott@hp.com>
Tested-by: Robert Elliott <elliott@hp.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | drivers/scsi/scsi_debug.c | 1464 |
1 files changed, 1047 insertions, 417 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 6ed43fd19a22..d19c0e3c7f48 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -42,6 +42,10 @@ | |||
42 | #include <linux/scatterlist.h> | 42 | #include <linux/scatterlist.h> |
43 | #include <linux/blkdev.h> | 43 | #include <linux/blkdev.h> |
44 | #include <linux/crc-t10dif.h> | 44 | #include <linux/crc-t10dif.h> |
45 | #include <linux/spinlock.h> | ||
46 | #include <linux/interrupt.h> | ||
47 | #include <linux/atomic.h> | ||
48 | #include <linux/hrtimer.h> | ||
45 | 49 | ||
46 | #include <net/checksum.h> | 50 | #include <net/checksum.h> |
47 | 51 | ||
@@ -53,13 +57,16 @@ | |||
53 | #include <scsi/scsi_host.h> | 57 | #include <scsi/scsi_host.h> |
54 | #include <scsi/scsicam.h> | 58 | #include <scsi/scsicam.h> |
55 | #include <scsi/scsi_eh.h> | 59 | #include <scsi/scsi_eh.h> |
60 | #include <scsi/scsi_tcq.h> | ||
56 | #include <scsi/scsi_dbg.h> | 61 | #include <scsi/scsi_dbg.h> |
57 | 62 | ||
58 | #include "sd.h" | 63 | #include "sd.h" |
59 | #include "scsi_logging.h" | 64 | #include "scsi_logging.h" |
60 | 65 | ||
61 | #define SCSI_DEBUG_VERSION "1.82" | 66 | #define SCSI_DEBUG_VERSION "1.84" |
62 | static const char * scsi_debug_version_date = "20100324"; | 67 | static const char *scsi_debug_version_date = "20140706"; |
68 | |||
69 | #define MY_NAME "scsi_debug" | ||
63 | 70 | ||
64 | /* Additional Sense Code (ASC) */ | 71 | /* Additional Sense Code (ASC) */ |
65 | #define NO_ADDITIONAL_SENSE 0x0 | 72 | #define NO_ADDITIONAL_SENSE 0x0 |
@@ -72,7 +79,11 @@ static const char * scsi_debug_version_date = "20100324"; | |||
72 | #define INVALID_COMMAND_OPCODE 0x20 | 79 | #define INVALID_COMMAND_OPCODE 0x20 |
73 | #define INVALID_FIELD_IN_CDB 0x24 | 80 | #define INVALID_FIELD_IN_CDB 0x24 |
74 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 | 81 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 |
75 | #define POWERON_RESET 0x29 | 82 | #define UA_RESET_ASC 0x29 |
83 | #define UA_CHANGED_ASC 0x2a | ||
84 | #define POWER_ON_RESET_ASCQ 0x0 | ||
85 | #define BUS_RESET_ASCQ 0x2 /* scsi bus reset occurred */ | ||
86 | #define MODE_CHANGED_ASCQ 0x1 /* mode parameters changed */ | ||
76 | #define SAVING_PARAMS_UNSUP 0x39 | 87 | #define SAVING_PARAMS_UNSUP 0x39 |
77 | #define TRANSPORT_PROBLEM 0x4b | 88 | #define TRANSPORT_PROBLEM 0x4b |
78 | #define THRESHOLD_EXCEEDED 0x5d | 89 | #define THRESHOLD_EXCEEDED 0x5d |
@@ -81,7 +92,6 @@ static const char * scsi_debug_version_date = "20100324"; | |||
81 | /* Additional Sense Code Qualifier (ASCQ) */ | 92 | /* Additional Sense Code Qualifier (ASCQ) */ |
82 | #define ACK_NAK_TO 0x3 | 93 | #define ACK_NAK_TO 0x3 |
83 | 94 | ||
84 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | ||
85 | 95 | ||
86 | /* Default values for driver parameters */ | 96 | /* Default values for driver parameters */ |
87 | #define DEF_NUM_HOST 1 | 97 | #define DEF_NUM_HOST 1 |
@@ -91,7 +101,7 @@ static const char * scsi_debug_version_date = "20100324"; | |||
91 | * (id 0) containing 1 logical unit (lun 0). That is 1 device. | 101 | * (id 0) containing 1 logical unit (lun 0). That is 1 device. |
92 | */ | 102 | */ |
93 | #define DEF_ATO 1 | 103 | #define DEF_ATO 1 |
94 | #define DEF_DELAY 1 | 104 | #define DEF_DELAY 1 /* if > 0 unit is a jiffy */ |
95 | #define DEF_DEV_SIZE_MB 8 | 105 | #define DEF_DEV_SIZE_MB 8 |
96 | #define DEF_DIF 0 | 106 | #define DEF_DIF 0 |
97 | #define DEF_DIX 0 | 107 | #define DEF_DIX 0 |
@@ -99,11 +109,13 @@ static const char * scsi_debug_version_date = "20100324"; | |||
99 | #define DEF_EVERY_NTH 0 | 109 | #define DEF_EVERY_NTH 0 |
100 | #define DEF_FAKE_RW 0 | 110 | #define DEF_FAKE_RW 0 |
101 | #define DEF_GUARD 0 | 111 | #define DEF_GUARD 0 |
112 | #define DEF_HOST_LOCK 0 | ||
102 | #define DEF_LBPU 0 | 113 | #define DEF_LBPU 0 |
103 | #define DEF_LBPWS 0 | 114 | #define DEF_LBPWS 0 |
104 | #define DEF_LBPWS10 0 | 115 | #define DEF_LBPWS10 0 |
105 | #define DEF_LBPRZ 1 | 116 | #define DEF_LBPRZ 1 |
106 | #define DEF_LOWEST_ALIGNED 0 | 117 | #define DEF_LOWEST_ALIGNED 0 |
118 | #define DEF_NDELAY 0 /* if > 0 unit is a nanosecond */ | ||
107 | #define DEF_NO_LUN_0 0 | 119 | #define DEF_NO_LUN_0 0 |
108 | #define DEF_NUM_PARTS 0 | 120 | #define DEF_NUM_PARTS 0 |
109 | #define DEF_OPTS 0 | 121 | #define DEF_OPTS 0 |
@@ -113,6 +125,7 @@ static const char * scsi_debug_version_date = "20100324"; | |||
113 | #define DEF_REMOVABLE false | 125 | #define DEF_REMOVABLE false |
114 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ | 126 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ |
115 | #define DEF_SECTOR_SIZE 512 | 127 | #define DEF_SECTOR_SIZE 512 |
128 | #define DEF_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | ||
116 | #define DEF_UNMAP_ALIGNMENT 0 | 129 | #define DEF_UNMAP_ALIGNMENT 0 |
117 | #define DEF_UNMAP_GRANULARITY 1 | 130 | #define DEF_UNMAP_GRANULARITY 1 |
118 | #define DEF_UNMAP_MAX_BLOCKS 0xFFFFFFFF | 131 | #define DEF_UNMAP_MAX_BLOCKS 0xFFFFFFFF |
@@ -120,6 +133,7 @@ static const char * scsi_debug_version_date = "20100324"; | |||
120 | #define DEF_VIRTUAL_GB 0 | 133 | #define DEF_VIRTUAL_GB 0 |
121 | #define DEF_VPD_USE_HOSTNO 1 | 134 | #define DEF_VPD_USE_HOSTNO 1 |
122 | #define DEF_WRITESAME_LENGTH 0xFFFF | 135 | #define DEF_WRITESAME_LENGTH 0xFFFF |
136 | #define DELAY_OVERRIDDEN -9999 | ||
123 | 137 | ||
124 | /* bit mask values for scsi_debug_opts */ | 138 | /* bit mask values for scsi_debug_opts */ |
125 | #define SCSI_DEBUG_OPT_NOISE 1 | 139 | #define SCSI_DEBUG_OPT_NOISE 1 |
@@ -130,7 +144,14 @@ static const char * scsi_debug_version_date = "20100324"; | |||
130 | #define SCSI_DEBUG_OPT_DIF_ERR 32 | 144 | #define SCSI_DEBUG_OPT_DIF_ERR 32 |
131 | #define SCSI_DEBUG_OPT_DIX_ERR 64 | 145 | #define SCSI_DEBUG_OPT_DIX_ERR 64 |
132 | #define SCSI_DEBUG_OPT_MAC_TIMEOUT 128 | 146 | #define SCSI_DEBUG_OPT_MAC_TIMEOUT 128 |
133 | #define SCSI_DEBUG_OPT_SHORT_TRANSFER 256 | 147 | #define SCSI_DEBUG_OPT_SHORT_TRANSFER 0x100 |
148 | #define SCSI_DEBUG_OPT_Q_NOISE 0x200 | ||
149 | #define SCSI_DEBUG_OPT_ALL_TSF 0x400 | ||
150 | #define SCSI_DEBUG_OPT_RARE_TSF 0x800 | ||
151 | #define SCSI_DEBUG_OPT_N_WCE 0x1000 | ||
152 | #define SCSI_DEBUG_OPT_RESET_NOISE 0x2000 | ||
153 | #define SCSI_DEBUG_OPT_NO_CDB_NOISE 0x4000 | ||
154 | #define SCSI_DEBUG_OPT_ALL_NOISE (0x1 | 0x200 | 0x2000) | ||
134 | /* When "every_nth" > 0 then modulo "every_nth" commands: | 155 | /* When "every_nth" > 0 then modulo "every_nth" commands: |
135 | * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set | 156 | * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set |
136 | * - a RECOVERED_ERROR is simulated on successful read and write | 157 | * - a RECOVERED_ERROR is simulated on successful read and write |
@@ -148,6 +169,19 @@ static const char * scsi_debug_version_date = "20100324"; | |||
148 | * writing a new value (other than -1 or 1) to every_nth via sysfs). | 169 | * writing a new value (other than -1 or 1) to every_nth via sysfs). |
149 | */ | 170 | */ |
150 | 171 | ||
172 | /* As indicated in SAM-5 and SPC-4 Unit Attentions (UAs)are returned in | ||
173 | * priority order. In the subset implemented here lower numbers have higher | ||
174 | * priority. The UA numbers should be a sequence starting from 0 with | ||
175 | * SDEBUG_NUM_UAS being 1 higher than the highest numbered UA. */ | ||
176 | #define SDEBUG_UA_POR 0 /* Power on, reset, or bus device reset */ | ||
177 | #define SDEBUG_UA_BUS_RESET 1 | ||
178 | #define SDEBUG_UA_MODE_CHANGED 2 | ||
179 | #define SDEBUG_NUM_UAS 3 | ||
180 | |||
181 | /* for check_readiness() */ | ||
182 | #define UAS_ONLY 1 | ||
183 | #define UAS_TUR 0 | ||
184 | |||
151 | /* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this | 185 | /* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this |
152 | * sector on read commands: */ | 186 | * sector on read commands: */ |
153 | #define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */ | 187 | #define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */ |
@@ -158,9 +192,19 @@ static const char * scsi_debug_version_date = "20100324"; | |||
158 | #define SAM2_LUN_ADDRESS_METHOD 0 | 192 | #define SAM2_LUN_ADDRESS_METHOD 0 |
159 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | 193 | #define SAM2_WLUN_REPORT_LUNS 0xc101 |
160 | 194 | ||
161 | /* Can queue up to this number of commands. Typically commands that | 195 | /* SCSI_DEBUG_CANQUEUE is the maximum number of commands that can be queued |
162 | * that have a non-zero delay are queued. */ | 196 | * (for response) at one time. Can be reduced by max_queue option. Command |
163 | #define SCSI_DEBUG_CANQUEUE 255 | 197 | * responses are not queued when delay=0 and ndelay=0. The per-device |
198 | * DEF_CMD_PER_LUN can be changed via sysfs: | ||
199 | * /sys/class/scsi_device/<h:c:t:l>/device/queue_depth but cannot exceed | ||
200 | * SCSI_DEBUG_CANQUEUE. */ | ||
201 | #define SCSI_DEBUG_CANQUEUE_WORDS 9 /* a WORD is bits in a long */ | ||
202 | #define SCSI_DEBUG_CANQUEUE (SCSI_DEBUG_CANQUEUE_WORDS * BITS_PER_LONG) | ||
203 | #define DEF_CMD_PER_LUN 255 | ||
204 | |||
205 | #if DEF_CMD_PER_LUN > SCSI_DEBUG_CANQUEUE | ||
206 | #warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE" | ||
207 | #endif | ||
164 | 208 | ||
165 | static int scsi_debug_add_host = DEF_NUM_HOST; | 209 | static int scsi_debug_add_host = DEF_NUM_HOST; |
166 | static int scsi_debug_ato = DEF_ATO; | 210 | static int scsi_debug_ato = DEF_ATO; |
@@ -175,6 +219,8 @@ static unsigned int scsi_debug_guard = DEF_GUARD; | |||
175 | static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED; | 219 | static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED; |
176 | static int scsi_debug_max_luns = DEF_MAX_LUNS; | 220 | static int scsi_debug_max_luns = DEF_MAX_LUNS; |
177 | static int scsi_debug_max_queue = SCSI_DEBUG_CANQUEUE; | 221 | static int scsi_debug_max_queue = SCSI_DEBUG_CANQUEUE; |
222 | static atomic_t retired_max_queue; /* if > 0 then was prior max_queue */ | ||
223 | static int scsi_debug_ndelay = DEF_NDELAY; | ||
178 | static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; | 224 | static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; |
179 | static int scsi_debug_no_uld = 0; | 225 | static int scsi_debug_no_uld = 0; |
180 | static int scsi_debug_num_parts = DEF_NUM_PARTS; | 226 | static int scsi_debug_num_parts = DEF_NUM_PARTS; |
@@ -198,8 +244,11 @@ static unsigned int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC; | |||
198 | static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH; | 244 | static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH; |
199 | static bool scsi_debug_removable = DEF_REMOVABLE; | 245 | static bool scsi_debug_removable = DEF_REMOVABLE; |
200 | static bool scsi_debug_clustering; | 246 | static bool scsi_debug_clustering; |
247 | static bool scsi_debug_host_lock = DEF_HOST_LOCK; | ||
201 | 248 | ||
202 | static int scsi_debug_cmnd_count = 0; | 249 | static atomic_t sdebug_cmnd_count; |
250 | static atomic_t sdebug_completions; | ||
251 | static atomic_t sdebug_a_tsf; /* counter of 'almost' TSFs */ | ||
203 | 252 | ||
204 | #define DEV_READONLY(TGT) (0) | 253 | #define DEV_READONLY(TGT) (0) |
205 | 254 | ||
@@ -214,24 +263,23 @@ static int sdebug_sectors_per; /* sectors per cylinder */ | |||
214 | 263 | ||
215 | #define SDEBUG_MAX_PARTS 4 | 264 | #define SDEBUG_MAX_PARTS 4 |
216 | 265 | ||
217 | #define SDEBUG_SENSE_LEN 32 | ||
218 | |||
219 | #define SCSI_DEBUG_MAX_CMD_LEN 32 | 266 | #define SCSI_DEBUG_MAX_CMD_LEN 32 |
220 | 267 | ||
221 | static unsigned int scsi_debug_lbp(void) | 268 | static unsigned int scsi_debug_lbp(void) |
222 | { | 269 | { |
223 | return scsi_debug_lbpu | scsi_debug_lbpws | scsi_debug_lbpws10; | 270 | return ((0 == scsi_debug_fake_rw) && |
271 | (scsi_debug_lbpu | scsi_debug_lbpws | scsi_debug_lbpws10)); | ||
224 | } | 272 | } |
225 | 273 | ||
226 | struct sdebug_dev_info { | 274 | struct sdebug_dev_info { |
227 | struct list_head dev_list; | 275 | struct list_head dev_list; |
228 | unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ | ||
229 | unsigned int channel; | 276 | unsigned int channel; |
230 | unsigned int target; | 277 | unsigned int target; |
231 | u64 lun; | 278 | u64 lun; |
232 | struct sdebug_host_info *sdbg_host; | 279 | struct sdebug_host_info *sdbg_host; |
233 | u64 wlun; | 280 | u64 wlun; |
234 | char reset; | 281 | unsigned long uas_bm[1]; |
282 | atomic_t num_in_q; | ||
235 | char stopped; | 283 | char stopped; |
236 | char used; | 284 | char used; |
237 | }; | 285 | }; |
@@ -249,26 +297,33 @@ struct sdebug_host_info { | |||
249 | static LIST_HEAD(sdebug_host_list); | 297 | static LIST_HEAD(sdebug_host_list); |
250 | static DEFINE_SPINLOCK(sdebug_host_list_lock); | 298 | static DEFINE_SPINLOCK(sdebug_host_list_lock); |
251 | 299 | ||
252 | typedef void (* done_funct_t) (struct scsi_cmnd *); | 300 | |
301 | struct sdebug_hrtimer { /* ... is derived from hrtimer */ | ||
302 | struct hrtimer hrt; /* must be first element */ | ||
303 | int qa_indx; | ||
304 | }; | ||
253 | 305 | ||
254 | struct sdebug_queued_cmd { | 306 | struct sdebug_queued_cmd { |
255 | int in_use; | 307 | /* in_use flagged by a bit in queued_in_use_bm[] */ |
256 | struct timer_list cmnd_timer; | 308 | struct timer_list *cmnd_timerp; |
257 | done_funct_t done_funct; | 309 | struct tasklet_struct *tletp; |
310 | struct sdebug_hrtimer *sd_hrtp; | ||
258 | struct scsi_cmnd * a_cmnd; | 311 | struct scsi_cmnd * a_cmnd; |
259 | int scsi_result; | ||
260 | }; | 312 | }; |
261 | static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; | 313 | static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; |
314 | static unsigned long queued_in_use_bm[SCSI_DEBUG_CANQUEUE_WORDS]; | ||
315 | |||
262 | 316 | ||
263 | static unsigned char * fake_storep; /* ramdisk storage */ | 317 | static unsigned char * fake_storep; /* ramdisk storage */ |
264 | static struct sd_dif_tuple *dif_storep; /* protection info */ | 318 | static struct sd_dif_tuple *dif_storep; /* protection info */ |
265 | static void *map_storep; /* provisioning map */ | 319 | static void *map_storep; /* provisioning map */ |
266 | 320 | ||
267 | static unsigned long map_size; | 321 | static unsigned long map_size; |
268 | static int num_aborts = 0; | 322 | static int num_aborts; |
269 | static int num_dev_resets = 0; | 323 | static int num_dev_resets; |
270 | static int num_bus_resets = 0; | 324 | static int num_target_resets; |
271 | static int num_host_resets = 0; | 325 | static int num_bus_resets; |
326 | static int num_host_resets; | ||
272 | static int dix_writes; | 327 | static int dix_writes; |
273 | static int dix_reads; | 328 | static int dix_reads; |
274 | static int dif_errors; | 329 | static int dif_errors; |
@@ -276,7 +331,8 @@ static int dif_errors; | |||
276 | static DEFINE_SPINLOCK(queued_arr_lock); | 331 | static DEFINE_SPINLOCK(queued_arr_lock); |
277 | static DEFINE_RWLOCK(atomic_rw); | 332 | static DEFINE_RWLOCK(atomic_rw); |
278 | 333 | ||
279 | static char sdebug_proc_name[] = "scsi_debug"; | 334 | static char sdebug_proc_name[] = MY_NAME; |
335 | static const char *my_name = MY_NAME; | ||
280 | 336 | ||
281 | static struct bus_type pseudo_lld_bus; | 337 | static struct bus_type pseudo_lld_bus; |
282 | 338 | ||
@@ -291,6 +347,12 @@ static const int check_condition_result = | |||
291 | static const int illegal_condition_result = | 347 | static const int illegal_condition_result = |
292 | (DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION; | 348 | (DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION; |
293 | 349 | ||
350 | static const int device_qfull_result = | ||
351 | (DID_OK << 16) | (COMMAND_COMPLETE << 8) | SAM_STAT_TASK_SET_FULL; | ||
352 | |||
353 | static unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, | ||
354 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, | ||
355 | 0, 0, 0, 0}; | ||
294 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | 356 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, |
295 | 0, 0, 0x2, 0x4b}; | 357 | 0, 0, 0x2, 0x4b}; |
296 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 358 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, |
@@ -332,19 +394,24 @@ static void sdebug_max_tgts_luns(void) | |||
332 | spin_unlock(&sdebug_host_list_lock); | 394 | spin_unlock(&sdebug_host_list_lock); |
333 | } | 395 | } |
334 | 396 | ||
335 | static void mk_sense_buffer(struct sdebug_dev_info *devip, int key, | 397 | static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq) |
336 | int asc, int asq) | ||
337 | { | 398 | { |
338 | unsigned char *sbuff; | 399 | unsigned char *sbuff; |
339 | 400 | ||
340 | sbuff = devip->sense_buff; | 401 | sbuff = scp->sense_buffer; |
341 | memset(sbuff, 0, SDEBUG_SENSE_LEN); | 402 | if (!sbuff) { |
403 | sdev_printk(KERN_ERR, scp->device, | ||
404 | "%s: sense_buffer is NULL\n", __func__); | ||
405 | return; | ||
406 | } | ||
407 | memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE); | ||
342 | 408 | ||
343 | scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq); | 409 | scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq); |
344 | 410 | ||
345 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 411 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
346 | printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: " | 412 | sdev_printk(KERN_INFO, scp->device, |
347 | "[0x%x,0x%x,0x%x]\n", key, asc, asq); | 413 | "%s: [sense_key,asc,ascq]: [0x%x,0x%x,0x%x]\n", |
414 | my_name, key, asc, asq); | ||
348 | } | 415 | } |
349 | 416 | ||
350 | static void get_data_transfer_info(unsigned char *cmd, | 417 | static void get_data_transfer_info(unsigned char *cmd, |
@@ -409,29 +476,71 @@ static void get_data_transfer_info(unsigned char *cmd, | |||
409 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 476 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
410 | { | 477 | { |
411 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { | 478 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { |
412 | printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd); | 479 | if (0x1261 == cmd) |
480 | sdev_printk(KERN_INFO, dev, | ||
481 | "%s: BLKFLSBUF [0x1261]\n", __func__); | ||
482 | else if (0x5331 == cmd) | ||
483 | sdev_printk(KERN_INFO, dev, | ||
484 | "%s: CDROM_GET_CAPABILITY [0x5331]\n", | ||
485 | __func__); | ||
486 | else | ||
487 | sdev_printk(KERN_INFO, dev, "%s: cmd=0x%x\n", | ||
488 | __func__, cmd); | ||
413 | } | 489 | } |
414 | return -EINVAL; | 490 | return -EINVAL; |
415 | /* return -ENOTTY; // correct return but upsets fdisk */ | 491 | /* return -ENOTTY; // correct return but upsets fdisk */ |
416 | } | 492 | } |
417 | 493 | ||
418 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, | 494 | static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only, |
419 | struct sdebug_dev_info * devip) | 495 | struct sdebug_dev_info * devip) |
420 | { | 496 | { |
421 | if (devip->reset) { | 497 | int k; |
422 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 498 | bool debug = !!(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts); |
423 | printk(KERN_INFO "scsi_debug: Reporting Unit " | 499 | |
424 | "attention: power on reset\n"); | 500 | k = find_first_bit(devip->uas_bm, SDEBUG_NUM_UAS); |
425 | devip->reset = 0; | 501 | if (k != SDEBUG_NUM_UAS) { |
426 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); | 502 | const char *cp = NULL; |
503 | |||
504 | switch (k) { | ||
505 | case SDEBUG_UA_POR: | ||
506 | mk_sense_buffer(SCpnt, UNIT_ATTENTION, | ||
507 | UA_RESET_ASC, POWER_ON_RESET_ASCQ); | ||
508 | if (debug) | ||
509 | cp = "power on reset"; | ||
510 | break; | ||
511 | case SDEBUG_UA_BUS_RESET: | ||
512 | mk_sense_buffer(SCpnt, UNIT_ATTENTION, | ||
513 | UA_RESET_ASC, BUS_RESET_ASCQ); | ||
514 | if (debug) | ||
515 | cp = "bus reset"; | ||
516 | break; | ||
517 | case SDEBUG_UA_MODE_CHANGED: | ||
518 | mk_sense_buffer(SCpnt, UNIT_ATTENTION, | ||
519 | UA_CHANGED_ASC, MODE_CHANGED_ASCQ); | ||
520 | if (debug) | ||
521 | cp = "mode parameters changed"; | ||
522 | break; | ||
523 | default: | ||
524 | pr_warn("%s: unexpected unit attention code=%d\n", | ||
525 | __func__, k); | ||
526 | if (debug) | ||
527 | cp = "unknown"; | ||
528 | break; | ||
529 | } | ||
530 | clear_bit(k, devip->uas_bm); | ||
531 | if (debug) | ||
532 | sdev_printk(KERN_INFO, SCpnt->device, | ||
533 | "%s reports: Unit attention: %s\n", | ||
534 | my_name, cp); | ||
427 | return check_condition_result; | 535 | return check_condition_result; |
428 | } | 536 | } |
429 | if ((0 == reset_only) && devip->stopped) { | 537 | if ((UAS_TUR == uas_only) && devip->stopped) { |
430 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 538 | mk_sense_buffer(SCpnt, NOT_READY, LOGICAL_UNIT_NOT_READY, |
431 | printk(KERN_INFO "scsi_debug: Reporting Not " | ||
432 | "ready: initializing command required\n"); | ||
433 | mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY, | ||
434 | 0x2); | 539 | 0x2); |
540 | if (debug) | ||
541 | sdev_printk(KERN_INFO, SCpnt->device, | ||
542 | "%s reports: Not ready: %s\n", my_name, | ||
543 | "initializing command required"); | ||
435 | return check_condition_result; | 544 | return check_condition_result; |
436 | } | 545 | } |
437 | return 0; | 546 | return 0; |
@@ -471,8 +580,9 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr, | |||
471 | 580 | ||
472 | static const char * inq_vendor_id = "Linux "; | 581 | static const char * inq_vendor_id = "Linux "; |
473 | static const char * inq_product_id = "scsi_debug "; | 582 | static const char * inq_product_id = "scsi_debug "; |
474 | static const char * inq_product_rev = "0004"; | 583 | static const char *inq_product_rev = "0184"; /* version less '.' */ |
475 | 584 | ||
585 | /* Device identification VPD page. Returns number of bytes placed in arr */ | ||
476 | static int inquiry_evpd_83(unsigned char * arr, int port_group_id, | 586 | static int inquiry_evpd_83(unsigned char * arr, int port_group_id, |
477 | int target_dev_id, int dev_id_num, | 587 | int target_dev_id, int dev_id_num, |
478 | const char * dev_id_str, | 588 | const char * dev_id_str, |
@@ -573,12 +683,14 @@ static unsigned char vpd84_data[] = { | |||
573 | 0x22,0x22,0x22,0x0,0xbb,0x2, | 683 | 0x22,0x22,0x22,0x0,0xbb,0x2, |
574 | }; | 684 | }; |
575 | 685 | ||
686 | /* Software interface identification VPD page */ | ||
576 | static int inquiry_evpd_84(unsigned char * arr) | 687 | static int inquiry_evpd_84(unsigned char * arr) |
577 | { | 688 | { |
578 | memcpy(arr, vpd84_data, sizeof(vpd84_data)); | 689 | memcpy(arr, vpd84_data, sizeof(vpd84_data)); |
579 | return sizeof(vpd84_data); | 690 | return sizeof(vpd84_data); |
580 | } | 691 | } |
581 | 692 | ||
693 | /* Management network addresses VPD page */ | ||
582 | static int inquiry_evpd_85(unsigned char * arr) | 694 | static int inquiry_evpd_85(unsigned char * arr) |
583 | { | 695 | { |
584 | int num = 0; | 696 | int num = 0; |
@@ -713,6 +825,7 @@ static unsigned char vpd89_data[] = { | |||
713 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51, | 825 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51, |
714 | }; | 826 | }; |
715 | 827 | ||
828 | /* ATA Information VPD page */ | ||
716 | static int inquiry_evpd_89(unsigned char * arr) | 829 | static int inquiry_evpd_89(unsigned char * arr) |
717 | { | 830 | { |
718 | memcpy(arr, vpd89_data, sizeof(vpd89_data)); | 831 | memcpy(arr, vpd89_data, sizeof(vpd89_data)); |
@@ -720,7 +833,6 @@ static int inquiry_evpd_89(unsigned char * arr) | |||
720 | } | 833 | } |
721 | 834 | ||
722 | 835 | ||
723 | /* Block limits VPD page (SBC-3) */ | ||
724 | static unsigned char vpdb0_data[] = { | 836 | static unsigned char vpdb0_data[] = { |
725 | /* from 4th byte */ 0,0,0,4, 0,0,0x4,0, 0,0,0,64, | 837 | /* from 4th byte */ 0,0,0,4, 0,0,0x4,0, 0,0,0,64, |
726 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 838 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
@@ -728,6 +840,7 @@ static unsigned char vpdb0_data[] = { | |||
728 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 840 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
729 | }; | 841 | }; |
730 | 842 | ||
843 | /* Block limits VPD page (SBC-3) */ | ||
731 | static int inquiry_evpd_b0(unsigned char * arr) | 844 | static int inquiry_evpd_b0(unsigned char * arr) |
732 | { | 845 | { |
733 | unsigned int gran; | 846 | unsigned int gran; |
@@ -811,7 +924,7 @@ static int inquiry_evpd_b2(unsigned char *arr) | |||
811 | #define SDEBUG_LONG_INQ_SZ 96 | 924 | #define SDEBUG_LONG_INQ_SZ 96 |
812 | #define SDEBUG_MAX_INQ_ARR_SZ 584 | 925 | #define SDEBUG_MAX_INQ_ARR_SZ 584 |
813 | 926 | ||
814 | static int resp_inquiry(struct scsi_cmnd * scp, int target, | 927 | static int resp_inquiry(struct scsi_cmnd *scp, int target, |
815 | struct sdebug_dev_info * devip) | 928 | struct sdebug_dev_info * devip) |
816 | { | 929 | { |
817 | unsigned char pq_pdt; | 930 | unsigned char pq_pdt; |
@@ -831,7 +944,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
831 | pq_pdt = (scsi_debug_ptype & 0x1f); | 944 | pq_pdt = (scsi_debug_ptype & 0x1f); |
832 | arr[0] = pq_pdt; | 945 | arr[0] = pq_pdt; |
833 | if (0x2 & cmd[1]) { /* CMDDT bit set */ | 946 | if (0x2 & cmd[1]) { /* CMDDT bit set */ |
834 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 947 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
835 | 0); | 948 | 0); |
836 | kfree(arr); | 949 | kfree(arr); |
837 | return check_condition_result; | 950 | return check_condition_result; |
@@ -917,7 +1030,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
917 | arr[3] = inquiry_evpd_b2(&arr[4]); | 1030 | arr[3] = inquiry_evpd_b2(&arr[4]); |
918 | } else { | 1031 | } else { |
919 | /* Illegal request, invalid field in cdb */ | 1032 | /* Illegal request, invalid field in cdb */ |
920 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1033 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
921 | INVALID_FIELD_IN_CDB, 0); | 1034 | INVALID_FIELD_IN_CDB, 0); |
922 | kfree(arr); | 1035 | kfree(arr); |
923 | return check_condition_result; | 1036 | return check_condition_result; |
@@ -963,15 +1076,13 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
963 | { | 1076 | { |
964 | unsigned char * sbuff; | 1077 | unsigned char * sbuff; |
965 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1078 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
966 | unsigned char arr[SDEBUG_SENSE_LEN]; | 1079 | unsigned char arr[SCSI_SENSE_BUFFERSIZE]; |
967 | int want_dsense; | 1080 | int want_dsense; |
968 | int len = 18; | 1081 | int len = 18; |
969 | 1082 | ||
970 | memset(arr, 0, sizeof(arr)); | 1083 | memset(arr, 0, sizeof(arr)); |
971 | if (devip->reset == 1) | ||
972 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); | ||
973 | want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; | 1084 | want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; |
974 | sbuff = devip->sense_buff; | 1085 | sbuff = scp->sense_buffer; |
975 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { | 1086 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { |
976 | if (want_dsense) { | 1087 | if (want_dsense) { |
977 | arr[0] = 0x72; | 1088 | arr[0] = 0x72; |
@@ -986,7 +1097,7 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
986 | arr[13] = 0xff; /* TEST set and MRIE==6 */ | 1097 | arr[13] = 0xff; /* TEST set and MRIE==6 */ |
987 | } | 1098 | } |
988 | } else { | 1099 | } else { |
989 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); | 1100 | memcpy(arr, sbuff, SCSI_SENSE_BUFFERSIZE); |
990 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { | 1101 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { |
991 | /* DESC bit set and sense_buff in fixed format */ | 1102 | /* DESC bit set and sense_buff in fixed format */ |
992 | memset(arr, 0, sizeof(arr)); | 1103 | memset(arr, 0, sizeof(arr)); |
@@ -997,7 +1108,7 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
997 | len = 8; | 1108 | len = 8; |
998 | } | 1109 | } |
999 | } | 1110 | } |
1000 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); | 1111 | mk_sense_buffer(scp, 0, NO_ADDITIONAL_SENSE, 0); |
1001 | return fill_from_dev_buffer(scp, arr, len); | 1112 | return fill_from_dev_buffer(scp, arr, len); |
1002 | } | 1113 | } |
1003 | 1114 | ||
@@ -1007,11 +1118,12 @@ static int resp_start_stop(struct scsi_cmnd * scp, | |||
1007 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1118 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
1008 | int power_cond, errsts, start; | 1119 | int power_cond, errsts, start; |
1009 | 1120 | ||
1010 | if ((errsts = check_readiness(scp, 1, devip))) | 1121 | errsts = check_readiness(scp, UAS_ONLY, devip); |
1122 | if (errsts) | ||
1011 | return errsts; | 1123 | return errsts; |
1012 | power_cond = (cmd[4] & 0xf0) >> 4; | 1124 | power_cond = (cmd[4] & 0xf0) >> 4; |
1013 | if (power_cond) { | 1125 | if (power_cond) { |
1014 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1126 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
1015 | 0); | 1127 | 0); |
1016 | return check_condition_result; | 1128 | return check_condition_result; |
1017 | } | 1129 | } |
@@ -1038,7 +1150,8 @@ static int resp_readcap(struct scsi_cmnd * scp, | |||
1038 | unsigned int capac; | 1150 | unsigned int capac; |
1039 | int errsts; | 1151 | int errsts; |
1040 | 1152 | ||
1041 | if ((errsts = check_readiness(scp, 1, devip))) | 1153 | errsts = check_readiness(scp, UAS_ONLY, devip); |
1154 | if (errsts) | ||
1042 | return errsts; | 1155 | return errsts; |
1043 | /* following just in case virtual_gb changed */ | 1156 | /* following just in case virtual_gb changed */ |
1044 | sdebug_capacity = get_sdebug_capacity(); | 1157 | sdebug_capacity = get_sdebug_capacity(); |
@@ -1069,7 +1182,8 @@ static int resp_readcap16(struct scsi_cmnd * scp, | |||
1069 | unsigned long long capac; | 1182 | unsigned long long capac; |
1070 | int errsts, k, alloc_len; | 1183 | int errsts, k, alloc_len; |
1071 | 1184 | ||
1072 | if ((errsts = check_readiness(scp, 1, devip))) | 1185 | errsts = check_readiness(scp, UAS_ONLY, devip); |
1186 | if (errsts) | ||
1073 | return errsts; | 1187 | return errsts; |
1074 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | 1188 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) |
1075 | + cmd[13]); | 1189 | + cmd[13]); |
@@ -1230,12 +1344,18 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target) | |||
1230 | 1344 | ||
1231 | static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | 1345 | static int resp_caching_pg(unsigned char * p, int pcontrol, int target) |
1232 | { /* Caching page for mode_sense */ | 1346 | { /* Caching page for mode_sense */ |
1233 | unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, | 1347 | unsigned char ch_caching_pg[] = {/* 0x8, 18, */ 0x4, 0, 0, 0, 0, 0, |
1348 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
1349 | unsigned char d_caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, | ||
1234 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; | 1350 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; |
1235 | 1351 | ||
1352 | if (SCSI_DEBUG_OPT_N_WCE & scsi_debug_opts) | ||
1353 | caching_pg[2] &= ~0x4; /* set WCE=0 (default WCE=1) */ | ||
1236 | memcpy(p, caching_pg, sizeof(caching_pg)); | 1354 | memcpy(p, caching_pg, sizeof(caching_pg)); |
1237 | if (1 == pcontrol) | 1355 | if (1 == pcontrol) |
1238 | memset(p + 2, 0, sizeof(caching_pg) - 2); | 1356 | memcpy(p + 2, ch_caching_pg, sizeof(ch_caching_pg)); |
1357 | else if (2 == pcontrol) | ||
1358 | memcpy(p, d_caching_pg, sizeof(d_caching_pg)); | ||
1239 | return sizeof(caching_pg); | 1359 | return sizeof(caching_pg); |
1240 | } | 1360 | } |
1241 | 1361 | ||
@@ -1350,7 +1470,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1350 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; | 1470 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; |
1351 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1471 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
1352 | 1472 | ||
1353 | if ((errsts = check_readiness(scp, 1, devip))) | 1473 | errsts = check_readiness(scp, UAS_ONLY, devip); |
1474 | if (errsts) | ||
1354 | return errsts; | 1475 | return errsts; |
1355 | dbd = !!(cmd[1] & 0x8); | 1476 | dbd = !!(cmd[1] & 0x8); |
1356 | pcontrol = (cmd[2] & 0xc0) >> 6; | 1477 | pcontrol = (cmd[2] & 0xc0) >> 6; |
@@ -1365,8 +1486,7 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1365 | alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]); | 1486 | alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]); |
1366 | memset(arr, 0, SDEBUG_MAX_MSENSE_SZ); | 1487 | memset(arr, 0, SDEBUG_MAX_MSENSE_SZ); |
1367 | if (0x3 == pcontrol) { /* Saving values not supported */ | 1488 | if (0x3 == pcontrol) { /* Saving values not supported */ |
1368 | mk_sense_buffer(devip, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP, | 1489 | mk_sense_buffer(scp, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP, 0); |
1369 | 0); | ||
1370 | return check_condition_result; | 1490 | return check_condition_result; |
1371 | } | 1491 | } |
1372 | target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | 1492 | target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + |
@@ -1422,7 +1542,7 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1422 | 1542 | ||
1423 | if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) { | 1543 | if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) { |
1424 | /* TODO: Control Extension page */ | 1544 | /* TODO: Control Extension page */ |
1425 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1545 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
1426 | 0); | 1546 | 0); |
1427 | return check_condition_result; | 1547 | return check_condition_result; |
1428 | } | 1548 | } |
@@ -1449,7 +1569,7 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1449 | break; | 1569 | break; |
1450 | case 0x19: /* if spc==1 then sas phy, control+discover */ | 1570 | case 0x19: /* if spc==1 then sas phy, control+discover */ |
1451 | if ((subpcode > 0x2) && (subpcode < 0xff)) { | 1571 | if ((subpcode > 0x2) && (subpcode < 0xff)) { |
1452 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1572 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1453 | INVALID_FIELD_IN_CDB, 0); | 1573 | INVALID_FIELD_IN_CDB, 0); |
1454 | return check_condition_result; | 1574 | return check_condition_result; |
1455 | } | 1575 | } |
@@ -1482,14 +1602,14 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1482 | } | 1602 | } |
1483 | len += resp_iec_m_pg(ap + len, pcontrol, target); | 1603 | len += resp_iec_m_pg(ap + len, pcontrol, target); |
1484 | } else { | 1604 | } else { |
1485 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1605 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1486 | INVALID_FIELD_IN_CDB, 0); | 1606 | INVALID_FIELD_IN_CDB, 0); |
1487 | return check_condition_result; | 1607 | return check_condition_result; |
1488 | } | 1608 | } |
1489 | offset += len; | 1609 | offset += len; |
1490 | break; | 1610 | break; |
1491 | default: | 1611 | default: |
1492 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1612 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
1493 | 0); | 1613 | 0); |
1494 | return check_condition_result; | 1614 | return check_condition_result; |
1495 | } | 1615 | } |
@@ -1512,14 +1632,15 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | |||
1512 | unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; | 1632 | unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; |
1513 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1633 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
1514 | 1634 | ||
1515 | if ((errsts = check_readiness(scp, 1, devip))) | 1635 | errsts = check_readiness(scp, UAS_ONLY, devip); |
1636 | if (errsts) | ||
1516 | return errsts; | 1637 | return errsts; |
1517 | memset(arr, 0, sizeof(arr)); | 1638 | memset(arr, 0, sizeof(arr)); |
1518 | pf = cmd[1] & 0x10; | 1639 | pf = cmd[1] & 0x10; |
1519 | sp = cmd[1] & 0x1; | 1640 | sp = cmd[1] & 0x1; |
1520 | param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]); | 1641 | param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]); |
1521 | if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) { | 1642 | if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) { |
1522 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1643 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1523 | INVALID_FIELD_IN_CDB, 0); | 1644 | INVALID_FIELD_IN_CDB, 0); |
1524 | return check_condition_result; | 1645 | return check_condition_result; |
1525 | } | 1646 | } |
@@ -1528,12 +1649,13 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | |||
1528 | return (DID_ERROR << 16); | 1649 | return (DID_ERROR << 16); |
1529 | else if ((res < param_len) && | 1650 | else if ((res < param_len) && |
1530 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1651 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
1531 | printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, " | 1652 | sdev_printk(KERN_INFO, scp->device, |
1532 | " IO sent=%d bytes\n", param_len, res); | 1653 | "%s: cdb indicated=%d, IO sent=%d bytes\n", |
1654 | __func__, param_len, res); | ||
1533 | md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2); | 1655 | md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2); |
1534 | bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]); | 1656 | bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]); |
1535 | if (md_len > 2) { | 1657 | if (md_len > 2) { |
1536 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1658 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1537 | INVALID_FIELD_IN_PARAM_LIST, 0); | 1659 | INVALID_FIELD_IN_PARAM_LIST, 0); |
1538 | return check_condition_result; | 1660 | return check_condition_result; |
1539 | } | 1661 | } |
@@ -1541,7 +1663,7 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | |||
1541 | mpage = arr[off] & 0x3f; | 1663 | mpage = arr[off] & 0x3f; |
1542 | ps = !!(arr[off] & 0x80); | 1664 | ps = !!(arr[off] & 0x80); |
1543 | if (ps) { | 1665 | if (ps) { |
1544 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1666 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1545 | INVALID_FIELD_IN_PARAM_LIST, 0); | 1667 | INVALID_FIELD_IN_PARAM_LIST, 0); |
1546 | return check_condition_result; | 1668 | return check_condition_result; |
1547 | } | 1669 | } |
@@ -1549,32 +1671,42 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | |||
1549 | pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) : | 1671 | pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) : |
1550 | (arr[off + 1] + 2); | 1672 | (arr[off + 1] + 2); |
1551 | if ((pg_len + off) > param_len) { | 1673 | if ((pg_len + off) > param_len) { |
1552 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1674 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1553 | PARAMETER_LIST_LENGTH_ERR, 0); | 1675 | PARAMETER_LIST_LENGTH_ERR, 0); |
1554 | return check_condition_result; | 1676 | return check_condition_result; |
1555 | } | 1677 | } |
1556 | switch (mpage) { | 1678 | switch (mpage) { |
1679 | case 0x8: /* Caching Mode page */ | ||
1680 | if (caching_pg[1] == arr[off + 1]) { | ||
1681 | memcpy(caching_pg + 2, arr + off + 2, | ||
1682 | sizeof(caching_pg) - 2); | ||
1683 | goto set_mode_changed_ua; | ||
1684 | } | ||
1685 | break; | ||
1557 | case 0xa: /* Control Mode page */ | 1686 | case 0xa: /* Control Mode page */ |
1558 | if (ctrl_m_pg[1] == arr[off + 1]) { | 1687 | if (ctrl_m_pg[1] == arr[off + 1]) { |
1559 | memcpy(ctrl_m_pg + 2, arr + off + 2, | 1688 | memcpy(ctrl_m_pg + 2, arr + off + 2, |
1560 | sizeof(ctrl_m_pg) - 2); | 1689 | sizeof(ctrl_m_pg) - 2); |
1561 | scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4); | 1690 | scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4); |
1562 | return 0; | 1691 | goto set_mode_changed_ua; |
1563 | } | 1692 | } |
1564 | break; | 1693 | break; |
1565 | case 0x1c: /* Informational Exceptions Mode page */ | 1694 | case 0x1c: /* Informational Exceptions Mode page */ |
1566 | if (iec_m_pg[1] == arr[off + 1]) { | 1695 | if (iec_m_pg[1] == arr[off + 1]) { |
1567 | memcpy(iec_m_pg + 2, arr + off + 2, | 1696 | memcpy(iec_m_pg + 2, arr + off + 2, |
1568 | sizeof(iec_m_pg) - 2); | 1697 | sizeof(iec_m_pg) - 2); |
1569 | return 0; | 1698 | goto set_mode_changed_ua; |
1570 | } | 1699 | } |
1571 | break; | 1700 | break; |
1572 | default: | 1701 | default: |
1573 | break; | 1702 | break; |
1574 | } | 1703 | } |
1575 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1704 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1576 | INVALID_FIELD_IN_PARAM_LIST, 0); | 1705 | INVALID_FIELD_IN_PARAM_LIST, 0); |
1577 | return check_condition_result; | 1706 | return check_condition_result; |
1707 | set_mode_changed_ua: | ||
1708 | set_bit(SDEBUG_UA_MODE_CHANGED, devip->uas_bm); | ||
1709 | return 0; | ||
1578 | } | 1710 | } |
1579 | 1711 | ||
1580 | static int resp_temp_l_pg(unsigned char * arr) | 1712 | static int resp_temp_l_pg(unsigned char * arr) |
@@ -1609,13 +1741,14 @@ static int resp_log_sense(struct scsi_cmnd * scp, | |||
1609 | unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; | 1741 | unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; |
1610 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1742 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
1611 | 1743 | ||
1612 | if ((errsts = check_readiness(scp, 1, devip))) | 1744 | errsts = check_readiness(scp, UAS_ONLY, devip); |
1745 | if (errsts) | ||
1613 | return errsts; | 1746 | return errsts; |
1614 | memset(arr, 0, sizeof(arr)); | 1747 | memset(arr, 0, sizeof(arr)); |
1615 | ppc = cmd[1] & 0x2; | 1748 | ppc = cmd[1] & 0x2; |
1616 | sp = cmd[1] & 0x1; | 1749 | sp = cmd[1] & 0x1; |
1617 | if (ppc || sp) { | 1750 | if (ppc || sp) { |
1618 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1751 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1619 | INVALID_FIELD_IN_CDB, 0); | 1752 | INVALID_FIELD_IN_CDB, 0); |
1620 | return check_condition_result; | 1753 | return check_condition_result; |
1621 | } | 1754 | } |
@@ -1640,7 +1773,7 @@ static int resp_log_sense(struct scsi_cmnd * scp, | |||
1640 | arr[3] = resp_ie_l_pg(arr + 4); | 1773 | arr[3] = resp_ie_l_pg(arr + 4); |
1641 | break; | 1774 | break; |
1642 | default: | 1775 | default: |
1643 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1776 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1644 | INVALID_FIELD_IN_CDB, 0); | 1777 | INVALID_FIELD_IN_CDB, 0); |
1645 | return check_condition_result; | 1778 | return check_condition_result; |
1646 | } | 1779 | } |
@@ -1673,12 +1806,12 @@ static int resp_log_sense(struct scsi_cmnd * scp, | |||
1673 | arr[3] = n - 4; | 1806 | arr[3] = n - 4; |
1674 | break; | 1807 | break; |
1675 | default: | 1808 | default: |
1676 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1809 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1677 | INVALID_FIELD_IN_CDB, 0); | 1810 | INVALID_FIELD_IN_CDB, 0); |
1678 | return check_condition_result; | 1811 | return check_condition_result; |
1679 | } | 1812 | } |
1680 | } else { | 1813 | } else { |
1681 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1814 | mk_sense_buffer(scp, ILLEGAL_REQUEST, |
1682 | INVALID_FIELD_IN_CDB, 0); | 1815 | INVALID_FIELD_IN_CDB, 0); |
1683 | return check_condition_result; | 1816 | return check_condition_result; |
1684 | } | 1817 | } |
@@ -1687,16 +1820,16 @@ static int resp_log_sense(struct scsi_cmnd * scp, | |||
1687 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | 1820 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
1688 | } | 1821 | } |
1689 | 1822 | ||
1690 | static int check_device_access_params(struct sdebug_dev_info *devi, | 1823 | static int check_device_access_params(struct scsi_cmnd *scp, |
1691 | unsigned long long lba, unsigned int num) | 1824 | unsigned long long lba, unsigned int num) |
1692 | { | 1825 | { |
1693 | if (lba + num > sdebug_capacity) { | 1826 | if (lba + num > sdebug_capacity) { |
1694 | mk_sense_buffer(devi, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0); | 1827 | mk_sense_buffer(scp, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0); |
1695 | return check_condition_result; | 1828 | return check_condition_result; |
1696 | } | 1829 | } |
1697 | /* transfer length excessive (tie in to block limits VPD page) */ | 1830 | /* transfer length excessive (tie in to block limits VPD page) */ |
1698 | if (num > sdebug_store_sectors) { | 1831 | if (num > sdebug_store_sectors) { |
1699 | mk_sense_buffer(devi, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); | 1832 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); |
1700 | return check_condition_result; | 1833 | return check_condition_result; |
1701 | } | 1834 | } |
1702 | return 0; | 1835 | return 0; |
@@ -1704,7 +1837,6 @@ static int check_device_access_params(struct sdebug_dev_info *devi, | |||
1704 | 1837 | ||
1705 | /* Returns number of bytes copied or -1 if error. */ | 1838 | /* Returns number of bytes copied or -1 if error. */ |
1706 | static int do_device_access(struct scsi_cmnd *scmd, | 1839 | static int do_device_access(struct scsi_cmnd *scmd, |
1707 | struct sdebug_dev_info *devi, | ||
1708 | unsigned long long lba, unsigned int num, int write) | 1840 | unsigned long long lba, unsigned int num, int write) |
1709 | { | 1841 | { |
1710 | int ret; | 1842 | int ret; |
@@ -1861,13 +1993,12 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, | |||
1861 | } | 1993 | } |
1862 | 1994 | ||
1863 | static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, | 1995 | static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, |
1864 | unsigned int num, struct sdebug_dev_info *devip, | 1996 | unsigned int num, u32 ei_lba) |
1865 | u32 ei_lba) | ||
1866 | { | 1997 | { |
1867 | unsigned long iflags; | 1998 | unsigned long iflags; |
1868 | int ret; | 1999 | int ret; |
1869 | 2000 | ||
1870 | ret = check_device_access_params(devip, lba, num); | 2001 | ret = check_device_access_params(SCpnt, lba, num); |
1871 | if (ret) | 2002 | if (ret) |
1872 | return ret; | 2003 | return ret; |
1873 | 2004 | ||
@@ -1875,16 +2006,16 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, | |||
1875 | (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) && | 2006 | (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) && |
1876 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { | 2007 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
1877 | /* claim unrecoverable read error */ | 2008 | /* claim unrecoverable read error */ |
1878 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); | 2009 | mk_sense_buffer(SCpnt, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); |
1879 | /* set info field and valid bit for fixed descriptor */ | 2010 | /* set info field and valid bit for fixed descriptor */ |
1880 | if (0x70 == (devip->sense_buff[0] & 0x7f)) { | 2011 | if (0x70 == (SCpnt->sense_buffer[0] & 0x7f)) { |
1881 | devip->sense_buff[0] |= 0x80; /* Valid bit */ | 2012 | SCpnt->sense_buffer[0] |= 0x80; /* Valid bit */ |
1882 | ret = (lba < OPT_MEDIUM_ERR_ADDR) | 2013 | ret = (lba < OPT_MEDIUM_ERR_ADDR) |
1883 | ? OPT_MEDIUM_ERR_ADDR : (int)lba; | 2014 | ? OPT_MEDIUM_ERR_ADDR : (int)lba; |
1884 | devip->sense_buff[3] = (ret >> 24) & 0xff; | 2015 | SCpnt->sense_buffer[3] = (ret >> 24) & 0xff; |
1885 | devip->sense_buff[4] = (ret >> 16) & 0xff; | 2016 | SCpnt->sense_buffer[4] = (ret >> 16) & 0xff; |
1886 | devip->sense_buff[5] = (ret >> 8) & 0xff; | 2017 | SCpnt->sense_buffer[5] = (ret >> 8) & 0xff; |
1887 | devip->sense_buff[6] = ret & 0xff; | 2018 | SCpnt->sense_buffer[6] = ret & 0xff; |
1888 | } | 2019 | } |
1889 | scsi_set_resid(SCpnt, scsi_bufflen(SCpnt)); | 2020 | scsi_set_resid(SCpnt, scsi_bufflen(SCpnt)); |
1890 | return check_condition_result; | 2021 | return check_condition_result; |
@@ -1898,12 +2029,12 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, | |||
1898 | 2029 | ||
1899 | if (prot_ret) { | 2030 | if (prot_ret) { |
1900 | read_unlock_irqrestore(&atomic_rw, iflags); | 2031 | read_unlock_irqrestore(&atomic_rw, iflags); |
1901 | mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret); | 2032 | mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, prot_ret); |
1902 | return illegal_condition_result; | 2033 | return illegal_condition_result; |
1903 | } | 2034 | } |
1904 | } | 2035 | } |
1905 | 2036 | ||
1906 | ret = do_device_access(SCpnt, devip, lba, num, 0); | 2037 | ret = do_device_access(SCpnt, lba, num, 0); |
1907 | read_unlock_irqrestore(&atomic_rw, iflags); | 2038 | read_unlock_irqrestore(&atomic_rw, iflags); |
1908 | if (ret == -1) | 2039 | if (ret == -1) |
1909 | return DID_ERROR << 16; | 2040 | return DID_ERROR << 16; |
@@ -1915,22 +2046,23 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, | |||
1915 | 2046 | ||
1916 | void dump_sector(unsigned char *buf, int len) | 2047 | void dump_sector(unsigned char *buf, int len) |
1917 | { | 2048 | { |
1918 | int i, j; | 2049 | int i, j, n; |
1919 | |||
1920 | printk(KERN_ERR ">>> Sector Dump <<<\n"); | ||
1921 | 2050 | ||
2051 | pr_err(">>> Sector Dump <<<\n"); | ||
1922 | for (i = 0 ; i < len ; i += 16) { | 2052 | for (i = 0 ; i < len ; i += 16) { |
1923 | printk(KERN_ERR "%04d: ", i); | 2053 | char b[128]; |
1924 | 2054 | ||
1925 | for (j = 0 ; j < 16 ; j++) { | 2055 | for (j = 0, n = 0; j < 16; j++) { |
1926 | unsigned char c = buf[i+j]; | 2056 | unsigned char c = buf[i+j]; |
2057 | |||
1927 | if (c >= 0x20 && c < 0x7e) | 2058 | if (c >= 0x20 && c < 0x7e) |
1928 | printk(" %c ", buf[i+j]); | 2059 | n += scnprintf(b + n, sizeof(b) - n, |
2060 | " %c ", buf[i+j]); | ||
1929 | else | 2061 | else |
1930 | printk("%02x ", buf[i+j]); | 2062 | n += scnprintf(b + n, sizeof(b) - n, |
2063 | "%02x ", buf[i+j]); | ||
1931 | } | 2064 | } |
1932 | 2065 | pr_err("%04d: %s\n", i, b); | |
1933 | printk("\n"); | ||
1934 | } | 2066 | } |
1935 | } | 2067 | } |
1936 | 2068 | ||
@@ -2092,13 +2224,12 @@ static void unmap_region(sector_t lba, unsigned int len) | |||
2092 | } | 2224 | } |
2093 | 2225 | ||
2094 | static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, | 2226 | static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, |
2095 | unsigned int num, struct sdebug_dev_info *devip, | 2227 | unsigned int num, u32 ei_lba) |
2096 | u32 ei_lba) | ||
2097 | { | 2228 | { |
2098 | unsigned long iflags; | 2229 | unsigned long iflags; |
2099 | int ret; | 2230 | int ret; |
2100 | 2231 | ||
2101 | ret = check_device_access_params(devip, lba, num); | 2232 | ret = check_device_access_params(SCpnt, lba, num); |
2102 | if (ret) | 2233 | if (ret) |
2103 | return ret; | 2234 | return ret; |
2104 | 2235 | ||
@@ -2110,12 +2241,13 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, | |||
2110 | 2241 | ||
2111 | if (prot_ret) { | 2242 | if (prot_ret) { |
2112 | write_unlock_irqrestore(&atomic_rw, iflags); | 2243 | write_unlock_irqrestore(&atomic_rw, iflags); |
2113 | mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret); | 2244 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, |
2245 | prot_ret); | ||
2114 | return illegal_condition_result; | 2246 | return illegal_condition_result; |
2115 | } | 2247 | } |
2116 | } | 2248 | } |
2117 | 2249 | ||
2118 | ret = do_device_access(SCpnt, devip, lba, num, 1); | 2250 | ret = do_device_access(SCpnt, lba, num, 1); |
2119 | if (scsi_debug_lbp()) | 2251 | if (scsi_debug_lbp()) |
2120 | map_region(lba, num); | 2252 | map_region(lba, num); |
2121 | write_unlock_irqrestore(&atomic_rw, iflags); | 2253 | write_unlock_irqrestore(&atomic_rw, iflags); |
@@ -2123,26 +2255,26 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, | |||
2123 | return (DID_ERROR << 16); | 2255 | return (DID_ERROR << 16); |
2124 | else if ((ret < (num * scsi_debug_sector_size)) && | 2256 | else if ((ret < (num * scsi_debug_sector_size)) && |
2125 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 2257 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
2126 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " | 2258 | sdev_printk(KERN_INFO, SCpnt->device, |
2127 | " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret); | 2259 | "%s: write: cdb indicated=%u, IO sent=%d bytes\n", |
2260 | my_name, num * scsi_debug_sector_size, ret); | ||
2128 | 2261 | ||
2129 | return 0; | 2262 | return 0; |
2130 | } | 2263 | } |
2131 | 2264 | ||
2132 | static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, | 2265 | static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, |
2133 | unsigned int num, struct sdebug_dev_info *devip, | 2266 | unsigned int num, u32 ei_lba, unsigned int unmap) |
2134 | u32 ei_lba, unsigned int unmap) | ||
2135 | { | 2267 | { |
2136 | unsigned long iflags; | 2268 | unsigned long iflags; |
2137 | unsigned long long i; | 2269 | unsigned long long i; |
2138 | int ret; | 2270 | int ret; |
2139 | 2271 | ||
2140 | ret = check_device_access_params(devip, lba, num); | 2272 | ret = check_device_access_params(scmd, lba, num); |
2141 | if (ret) | 2273 | if (ret) |
2142 | return ret; | 2274 | return ret; |
2143 | 2275 | ||
2144 | if (num > scsi_debug_write_same_length) { | 2276 | if (num > scsi_debug_write_same_length) { |
2145 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 2277 | mk_sense_buffer(scmd, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
2146 | 0); | 2278 | 0); |
2147 | return check_condition_result; | 2279 | return check_condition_result; |
2148 | } | 2280 | } |
@@ -2164,8 +2296,10 @@ static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, | |||
2164 | return (DID_ERROR << 16); | 2296 | return (DID_ERROR << 16); |
2165 | } else if ((ret < (num * scsi_debug_sector_size)) && | 2297 | } else if ((ret < (num * scsi_debug_sector_size)) && |
2166 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 2298 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
2167 | printk(KERN_INFO "scsi_debug: write same: cdb indicated=%u, " | 2299 | sdev_printk(KERN_INFO, scmd->device, |
2168 | " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret); | 2300 | "%s: %s: cdb indicated=%u, IO sent=%d bytes\n", |
2301 | my_name, "write same", | ||
2302 | num * scsi_debug_sector_size, ret); | ||
2169 | 2303 | ||
2170 | /* Copy first sector to remaining blocks */ | 2304 | /* Copy first sector to remaining blocks */ |
2171 | for (i = 1 ; i < num ; i++) | 2305 | for (i = 1 ; i < num ; i++) |
@@ -2195,7 +2329,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip) | |||
2195 | int ret; | 2329 | int ret; |
2196 | unsigned long iflags; | 2330 | unsigned long iflags; |
2197 | 2331 | ||
2198 | ret = check_readiness(scmd, 1, devip); | 2332 | ret = check_readiness(scmd, UAS_ONLY, devip); |
2199 | if (ret) | 2333 | if (ret) |
2200 | return ret; | 2334 | return ret; |
2201 | 2335 | ||
@@ -2221,7 +2355,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip) | |||
2221 | unsigned long long lba = get_unaligned_be64(&desc[i].lba); | 2355 | unsigned long long lba = get_unaligned_be64(&desc[i].lba); |
2222 | unsigned int num = get_unaligned_be32(&desc[i].blocks); | 2356 | unsigned int num = get_unaligned_be32(&desc[i].blocks); |
2223 | 2357 | ||
2224 | ret = check_device_access_params(devip, lba, num); | 2358 | ret = check_device_access_params(scmd, lba, num); |
2225 | if (ret) | 2359 | if (ret) |
2226 | goto out; | 2360 | goto out; |
2227 | 2361 | ||
@@ -2247,7 +2381,7 @@ static int resp_get_lba_status(struct scsi_cmnd * scmd, | |||
2247 | unsigned char arr[SDEBUG_GET_LBA_STATUS_LEN]; | 2381 | unsigned char arr[SDEBUG_GET_LBA_STATUS_LEN]; |
2248 | int ret; | 2382 | int ret; |
2249 | 2383 | ||
2250 | ret = check_readiness(scmd, 1, devip); | 2384 | ret = check_readiness(scmd, UAS_ONLY, devip); |
2251 | if (ret) | 2385 | if (ret) |
2252 | return ret; | 2386 | return ret; |
2253 | 2387 | ||
@@ -2257,7 +2391,7 @@ static int resp_get_lba_status(struct scsi_cmnd * scmd, | |||
2257 | if (alloc_len < 24) | 2391 | if (alloc_len < 24) |
2258 | return 0; | 2392 | return 0; |
2259 | 2393 | ||
2260 | ret = check_device_access_params(devip, lba, 1); | 2394 | ret = check_device_access_params(scmd, lba, 1); |
2261 | if (ret) | 2395 | if (ret) |
2262 | return ret; | 2396 | return ret; |
2263 | 2397 | ||
@@ -2288,7 +2422,7 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
2288 | 2422 | ||
2289 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 2423 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); |
2290 | if ((alloc_len < 4) || (select_report > 2)) { | 2424 | if ((alloc_len < 4) || (select_report > 2)) { |
2291 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 2425 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
2292 | 0); | 2426 | 0); |
2293 | return check_condition_result; | 2427 | return check_condition_result; |
2294 | } | 2428 | } |
@@ -2342,7 +2476,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | |||
2342 | /* better not to use temporary buffer. */ | 2476 | /* better not to use temporary buffer. */ |
2343 | buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC); | 2477 | buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC); |
2344 | if (!buf) { | 2478 | if (!buf) { |
2345 | mk_sense_buffer(devip, NOT_READY, | 2479 | mk_sense_buffer(scp, NOT_READY, |
2346 | LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); | 2480 | LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); |
2347 | return check_condition_result; | 2481 | return check_condition_result; |
2348 | } | 2482 | } |
@@ -2366,34 +2500,125 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | |||
2366 | return 0; | 2500 | return 0; |
2367 | } | 2501 | } |
2368 | 2502 | ||
2369 | /* When timer goes off this function is called. */ | 2503 | /* When timer or tasklet goes off this function is called. */ |
2370 | static void timer_intr_handler(unsigned long indx) | 2504 | static void sdebug_q_cmd_complete(unsigned long indx) |
2371 | { | 2505 | { |
2372 | struct sdebug_queued_cmd * sqcp; | 2506 | int qa_indx; |
2507 | int retiring = 0; | ||
2373 | unsigned long iflags; | 2508 | unsigned long iflags; |
2509 | struct sdebug_queued_cmd *sqcp; | ||
2510 | struct scsi_cmnd *scp; | ||
2511 | struct sdebug_dev_info *devip; | ||
2374 | 2512 | ||
2375 | if (indx >= scsi_debug_max_queue) { | 2513 | atomic_inc(&sdebug_completions); |
2376 | printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too " | 2514 | qa_indx = indx; |
2377 | "large\n"); | 2515 | if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) { |
2516 | pr_err("%s: wild qa_indx=%d\n", __func__, qa_indx); | ||
2378 | return; | 2517 | return; |
2379 | } | 2518 | } |
2380 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2519 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2381 | sqcp = &queued_arr[(int)indx]; | 2520 | sqcp = &queued_arr[qa_indx]; |
2382 | if (! sqcp->in_use) { | 2521 | scp = sqcp->a_cmnd; |
2383 | printk(KERN_ERR "scsi_debug:timer_intr_handler: Unexpected " | 2522 | if (NULL == scp) { |
2384 | "interrupt\n"); | 2523 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2524 | pr_err("%s: scp is NULL\n", __func__); | ||
2525 | return; | ||
2526 | } | ||
2527 | devip = (struct sdebug_dev_info *)scp->device->hostdata; | ||
2528 | if (devip) | ||
2529 | atomic_dec(&devip->num_in_q); | ||
2530 | else | ||
2531 | pr_err("%s: devip=NULL\n", __func__); | ||
2532 | if (atomic_read(&retired_max_queue) > 0) | ||
2533 | retiring = 1; | ||
2534 | |||
2535 | sqcp->a_cmnd = NULL; | ||
2536 | if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) { | ||
2385 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 2537 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2538 | pr_err("%s: Unexpected completion\n", __func__); | ||
2386 | return; | 2539 | return; |
2387 | } | 2540 | } |
2388 | sqcp->in_use = 0; | 2541 | |
2389 | if (sqcp->done_funct) { | 2542 | if (unlikely(retiring)) { /* user has reduced max_queue */ |
2390 | sqcp->a_cmnd->result = sqcp->scsi_result; | 2543 | int k, retval; |
2391 | sqcp->done_funct(sqcp->a_cmnd); /* callback to mid level */ | 2544 | |
2545 | retval = atomic_read(&retired_max_queue); | ||
2546 | if (qa_indx >= retval) { | ||
2547 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2548 | pr_err("%s: index %d too large\n", __func__, retval); | ||
2549 | return; | ||
2550 | } | ||
2551 | k = find_last_bit(queued_in_use_bm, retval); | ||
2552 | if ((k < scsi_debug_max_queue) || (k == retval)) | ||
2553 | atomic_set(&retired_max_queue, 0); | ||
2554 | else | ||
2555 | atomic_set(&retired_max_queue, k + 1); | ||
2392 | } | 2556 | } |
2393 | sqcp->done_funct = NULL; | ||
2394 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 2557 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2558 | scp->scsi_done(scp); /* callback to mid level */ | ||
2395 | } | 2559 | } |
2396 | 2560 | ||
2561 | /* When high resolution timer goes off this function is called. */ | ||
2562 | static enum hrtimer_restart | ||
2563 | sdebug_q_cmd_hrt_complete(struct hrtimer *timer) | ||
2564 | { | ||
2565 | int qa_indx; | ||
2566 | int retiring = 0; | ||
2567 | unsigned long iflags; | ||
2568 | struct sdebug_hrtimer *sd_hrtp = (struct sdebug_hrtimer *)timer; | ||
2569 | struct sdebug_queued_cmd *sqcp; | ||
2570 | struct scsi_cmnd *scp; | ||
2571 | struct sdebug_dev_info *devip; | ||
2572 | |||
2573 | atomic_inc(&sdebug_completions); | ||
2574 | qa_indx = sd_hrtp->qa_indx; | ||
2575 | if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) { | ||
2576 | pr_err("%s: wild qa_indx=%d\n", __func__, qa_indx); | ||
2577 | goto the_end; | ||
2578 | } | ||
2579 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
2580 | sqcp = &queued_arr[qa_indx]; | ||
2581 | scp = sqcp->a_cmnd; | ||
2582 | if (NULL == scp) { | ||
2583 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2584 | pr_err("%s: scp is NULL\n", __func__); | ||
2585 | goto the_end; | ||
2586 | } | ||
2587 | devip = (struct sdebug_dev_info *)scp->device->hostdata; | ||
2588 | if (devip) | ||
2589 | atomic_dec(&devip->num_in_q); | ||
2590 | else | ||
2591 | pr_err("%s: devip=NULL\n", __func__); | ||
2592 | if (atomic_read(&retired_max_queue) > 0) | ||
2593 | retiring = 1; | ||
2594 | |||
2595 | sqcp->a_cmnd = NULL; | ||
2596 | if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) { | ||
2597 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2598 | pr_err("%s: Unexpected completion\n", __func__); | ||
2599 | goto the_end; | ||
2600 | } | ||
2601 | |||
2602 | if (unlikely(retiring)) { /* user has reduced max_queue */ | ||
2603 | int k, retval; | ||
2604 | |||
2605 | retval = atomic_read(&retired_max_queue); | ||
2606 | if (qa_indx >= retval) { | ||
2607 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2608 | pr_err("%s: index %d too large\n", __func__, retval); | ||
2609 | goto the_end; | ||
2610 | } | ||
2611 | k = find_last_bit(queued_in_use_bm, retval); | ||
2612 | if ((k < scsi_debug_max_queue) || (k == retval)) | ||
2613 | atomic_set(&retired_max_queue, 0); | ||
2614 | else | ||
2615 | atomic_set(&retired_max_queue, k + 1); | ||
2616 | } | ||
2617 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2618 | scp->scsi_done(scp); /* callback to mid level */ | ||
2619 | the_end: | ||
2620 | return HRTIMER_NORESTART; | ||
2621 | } | ||
2397 | 2622 | ||
2398 | static struct sdebug_dev_info * | 2623 | static struct sdebug_dev_info * |
2399 | sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags) | 2624 | sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags) |
@@ -2419,7 +2644,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
2419 | return devip; | 2644 | return devip; |
2420 | sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); | 2645 | sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); |
2421 | if (!sdbg_host) { | 2646 | if (!sdbg_host) { |
2422 | printk(KERN_ERR "Host info NULL\n"); | 2647 | pr_err("%s: Host info NULL\n", __func__); |
2423 | return NULL; | 2648 | return NULL; |
2424 | } | 2649 | } |
2425 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { | 2650 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { |
@@ -2445,15 +2670,9 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
2445 | open_devip->target = sdev->id; | 2670 | open_devip->target = sdev->id; |
2446 | open_devip->lun = sdev->lun; | 2671 | open_devip->lun = sdev->lun; |
2447 | open_devip->sdbg_host = sdbg_host; | 2672 | open_devip->sdbg_host = sdbg_host; |
2448 | open_devip->reset = 1; | 2673 | atomic_set(&open_devip->num_in_q, 0); |
2674 | set_bit(SDEBUG_UA_POR, open_devip->uas_bm); | ||
2449 | open_devip->used = 1; | 2675 | open_devip->used = 1; |
2450 | memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN); | ||
2451 | if (scsi_debug_dsense) | ||
2452 | open_devip->sense_buff[0] = 0x72; | ||
2453 | else { | ||
2454 | open_devip->sense_buff[0] = 0x70; | ||
2455 | open_devip->sense_buff[7] = 0xa; | ||
2456 | } | ||
2457 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | 2676 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) |
2458 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | 2677 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; |
2459 | 2678 | ||
@@ -2482,9 +2701,10 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp) | |||
2482 | if (NULL == devip) | 2701 | if (NULL == devip) |
2483 | return 1; /* no resources, will be marked offline */ | 2702 | return 1; /* no resources, will be marked offline */ |
2484 | sdp->hostdata = devip; | 2703 | sdp->hostdata = devip; |
2704 | sdp->tagged_supported = 1; | ||
2485 | if (sdp->host->cmd_per_lun) | 2705 | if (sdp->host->cmd_per_lun) |
2486 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 2706 | scsi_adjust_queue_depth(sdp, DEF_TAGGED_QUEUING, |
2487 | sdp->host->cmd_per_lun); | 2707 | DEF_CMD_PER_LUN); |
2488 | blk_queue_max_segment_size(sdp->request_queue, -1U); | 2708 | blk_queue_max_segment_size(sdp->request_queue, -1U); |
2489 | if (scsi_debug_no_uld) | 2709 | if (scsi_debug_no_uld) |
2490 | sdp->no_uld_attach = 1; | 2710 | sdp->no_uld_attach = 1; |
@@ -2506,150 +2726,230 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp) | |||
2506 | } | 2726 | } |
2507 | } | 2727 | } |
2508 | 2728 | ||
2509 | /* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */ | 2729 | /* Returns 1 if cmnd found (deletes its timer or tasklet), else returns 0 */ |
2510 | static int stop_queued_cmnd(struct scsi_cmnd *cmnd) | 2730 | static int stop_queued_cmnd(struct scsi_cmnd *cmnd) |
2511 | { | 2731 | { |
2512 | unsigned long iflags; | 2732 | unsigned long iflags; |
2513 | int k; | 2733 | int k, qmax, r_qmax; |
2514 | struct sdebug_queued_cmd *sqcp; | 2734 | struct sdebug_queued_cmd *sqcp; |
2735 | struct sdebug_dev_info *devip; | ||
2515 | 2736 | ||
2516 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2737 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2517 | for (k = 0; k < scsi_debug_max_queue; ++k) { | 2738 | qmax = scsi_debug_max_queue; |
2518 | sqcp = &queued_arr[k]; | 2739 | r_qmax = atomic_read(&retired_max_queue); |
2519 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { | 2740 | if (r_qmax > qmax) |
2520 | del_timer_sync(&sqcp->cmnd_timer); | 2741 | qmax = r_qmax; |
2521 | sqcp->in_use = 0; | 2742 | for (k = 0; k < qmax; ++k) { |
2522 | sqcp->a_cmnd = NULL; | 2743 | if (test_bit(k, queued_in_use_bm)) { |
2523 | break; | 2744 | sqcp = &queued_arr[k]; |
2745 | if (cmnd == sqcp->a_cmnd) { | ||
2746 | if (scsi_debug_ndelay > 0) { | ||
2747 | if (sqcp->sd_hrtp) | ||
2748 | hrtimer_cancel( | ||
2749 | &sqcp->sd_hrtp->hrt); | ||
2750 | } else if (scsi_debug_delay > 0) { | ||
2751 | if (sqcp->cmnd_timerp) | ||
2752 | del_timer_sync( | ||
2753 | sqcp->cmnd_timerp); | ||
2754 | } else if (scsi_debug_delay < 0) { | ||
2755 | if (sqcp->tletp) | ||
2756 | tasklet_kill(sqcp->tletp); | ||
2757 | } | ||
2758 | __clear_bit(k, queued_in_use_bm); | ||
2759 | devip = (struct sdebug_dev_info *) | ||
2760 | cmnd->device->hostdata; | ||
2761 | if (devip) | ||
2762 | atomic_dec(&devip->num_in_q); | ||
2763 | sqcp->a_cmnd = NULL; | ||
2764 | break; | ||
2765 | } | ||
2524 | } | 2766 | } |
2525 | } | 2767 | } |
2526 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 2768 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2527 | return (k < scsi_debug_max_queue) ? 1 : 0; | 2769 | return (k < qmax) ? 1 : 0; |
2528 | } | 2770 | } |
2529 | 2771 | ||
2530 | /* Deletes (stops) timers of all queued commands */ | 2772 | /* Deletes (stops) timers or tasklets of all queued commands */ |
2531 | static void stop_all_queued(void) | 2773 | static void stop_all_queued(void) |
2532 | { | 2774 | { |
2533 | unsigned long iflags; | 2775 | unsigned long iflags; |
2534 | int k; | 2776 | int k; |
2535 | struct sdebug_queued_cmd *sqcp; | 2777 | struct sdebug_queued_cmd *sqcp; |
2778 | struct sdebug_dev_info *devip; | ||
2536 | 2779 | ||
2537 | spin_lock_irqsave(&queued_arr_lock, iflags); | 2780 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2538 | for (k = 0; k < scsi_debug_max_queue; ++k) { | 2781 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { |
2539 | sqcp = &queued_arr[k]; | 2782 | if (test_bit(k, queued_in_use_bm)) { |
2540 | if (sqcp->in_use && sqcp->a_cmnd) { | 2783 | sqcp = &queued_arr[k]; |
2541 | del_timer_sync(&sqcp->cmnd_timer); | 2784 | if (sqcp->a_cmnd) { |
2542 | sqcp->in_use = 0; | 2785 | if (scsi_debug_ndelay > 0) { |
2543 | sqcp->a_cmnd = NULL; | 2786 | if (sqcp->sd_hrtp) |
2787 | hrtimer_cancel( | ||
2788 | &sqcp->sd_hrtp->hrt); | ||
2789 | } else if (scsi_debug_delay > 0) { | ||
2790 | if (sqcp->cmnd_timerp) | ||
2791 | del_timer_sync( | ||
2792 | sqcp->cmnd_timerp); | ||
2793 | } else if (scsi_debug_delay < 0) { | ||
2794 | if (sqcp->tletp) | ||
2795 | tasklet_kill(sqcp->tletp); | ||
2796 | } | ||
2797 | __clear_bit(k, queued_in_use_bm); | ||
2798 | devip = (struct sdebug_dev_info *) | ||
2799 | sqcp->a_cmnd->device->hostdata; | ||
2800 | if (devip) | ||
2801 | atomic_dec(&devip->num_in_q); | ||
2802 | sqcp->a_cmnd = NULL; | ||
2803 | } | ||
2544 | } | 2804 | } |
2545 | } | 2805 | } |
2546 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 2806 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2547 | } | 2807 | } |
2548 | 2808 | ||
2549 | static int scsi_debug_abort(struct scsi_cmnd * SCpnt) | 2809 | /* Free queued command memory on heap */ |
2810 | static void free_all_queued(void) | ||
2550 | { | 2811 | { |
2551 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 2812 | unsigned long iflags; |
2552 | printk(KERN_INFO "scsi_debug: abort\n"); | 2813 | int k; |
2553 | ++num_aborts; | 2814 | struct sdebug_queued_cmd *sqcp; |
2554 | stop_queued_cmnd(SCpnt); | 2815 | |
2555 | return SUCCESS; | 2816 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2817 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | ||
2818 | sqcp = &queued_arr[k]; | ||
2819 | kfree(sqcp->cmnd_timerp); | ||
2820 | sqcp->cmnd_timerp = NULL; | ||
2821 | kfree(sqcp->tletp); | ||
2822 | sqcp->tletp = NULL; | ||
2823 | kfree(sqcp->sd_hrtp); | ||
2824 | sqcp->sd_hrtp = NULL; | ||
2825 | } | ||
2826 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2556 | } | 2827 | } |
2557 | 2828 | ||
2558 | static int scsi_debug_biosparam(struct scsi_device *sdev, | 2829 | static int scsi_debug_abort(struct scsi_cmnd *SCpnt) |
2559 | struct block_device * bdev, sector_t capacity, int *info) | ||
2560 | { | 2830 | { |
2561 | int res; | 2831 | ++num_aborts; |
2562 | unsigned char *buf; | 2832 | if (SCpnt) { |
2563 | 2833 | if (SCpnt->device && | |
2564 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 2834 | (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts)) |
2565 | printk(KERN_INFO "scsi_debug: biosparam\n"); | 2835 | sdev_printk(KERN_INFO, SCpnt->device, "%s\n", |
2566 | buf = scsi_bios_ptable(bdev); | 2836 | __func__); |
2567 | if (buf) { | 2837 | stop_queued_cmnd(SCpnt); |
2568 | res = scsi_partsize(buf, capacity, | 2838 | } |
2569 | &info[2], &info[0], &info[1]); | 2839 | return SUCCESS; |
2570 | kfree(buf); | ||
2571 | if (! res) | ||
2572 | return res; | ||
2573 | } | ||
2574 | info[0] = sdebug_heads; | ||
2575 | info[1] = sdebug_sectors_per; | ||
2576 | info[2] = sdebug_cylinders_per; | ||
2577 | return 0; | ||
2578 | } | 2840 | } |
2579 | 2841 | ||
2580 | static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt) | 2842 | static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt) |
2581 | { | 2843 | { |
2582 | struct sdebug_dev_info * devip; | 2844 | struct sdebug_dev_info * devip; |
2583 | 2845 | ||
2584 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2585 | printk(KERN_INFO "scsi_debug: device_reset\n"); | ||
2586 | ++num_dev_resets; | 2846 | ++num_dev_resets; |
2587 | if (SCpnt) { | 2847 | if (SCpnt && SCpnt->device) { |
2588 | devip = devInfoReg(SCpnt->device); | 2848 | struct scsi_device *sdp = SCpnt->device; |
2849 | |||
2850 | if (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts) | ||
2851 | sdev_printk(KERN_INFO, sdp, "%s\n", __func__); | ||
2852 | devip = devInfoReg(sdp); | ||
2589 | if (devip) | 2853 | if (devip) |
2590 | devip->reset = 1; | 2854 | set_bit(SDEBUG_UA_POR, devip->uas_bm); |
2855 | } | ||
2856 | return SUCCESS; | ||
2857 | } | ||
2858 | |||
2859 | static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt) | ||
2860 | { | ||
2861 | struct sdebug_host_info *sdbg_host; | ||
2862 | struct sdebug_dev_info *devip; | ||
2863 | struct scsi_device *sdp; | ||
2864 | struct Scsi_Host *hp; | ||
2865 | int k = 0; | ||
2866 | |||
2867 | ++num_target_resets; | ||
2868 | if (!SCpnt) | ||
2869 | goto lie; | ||
2870 | sdp = SCpnt->device; | ||
2871 | if (!sdp) | ||
2872 | goto lie; | ||
2873 | if (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts) | ||
2874 | sdev_printk(KERN_INFO, sdp, "%s\n", __func__); | ||
2875 | hp = sdp->host; | ||
2876 | if (!hp) | ||
2877 | goto lie; | ||
2878 | sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); | ||
2879 | if (sdbg_host) { | ||
2880 | list_for_each_entry(devip, | ||
2881 | &sdbg_host->dev_info_list, | ||
2882 | dev_list) | ||
2883 | if (devip->target == sdp->id) { | ||
2884 | set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); | ||
2885 | ++k; | ||
2886 | } | ||
2591 | } | 2887 | } |
2888 | if (SCSI_DEBUG_OPT_RESET_NOISE & scsi_debug_opts) | ||
2889 | sdev_printk(KERN_INFO, sdp, | ||
2890 | "%s: %d device(s) found in target\n", __func__, k); | ||
2891 | lie: | ||
2592 | return SUCCESS; | 2892 | return SUCCESS; |
2593 | } | 2893 | } |
2594 | 2894 | ||
2595 | static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt) | 2895 | static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt) |
2596 | { | 2896 | { |
2597 | struct sdebug_host_info *sdbg_host; | 2897 | struct sdebug_host_info *sdbg_host; |
2598 | struct sdebug_dev_info * dev_info; | 2898 | struct sdebug_dev_info *devip; |
2599 | struct scsi_device * sdp; | 2899 | struct scsi_device * sdp; |
2600 | struct Scsi_Host * hp; | 2900 | struct Scsi_Host * hp; |
2901 | int k = 0; | ||
2601 | 2902 | ||
2602 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2603 | printk(KERN_INFO "scsi_debug: bus_reset\n"); | ||
2604 | ++num_bus_resets; | 2903 | ++num_bus_resets; |
2605 | if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { | 2904 | if (!(SCpnt && SCpnt->device)) |
2905 | goto lie; | ||
2906 | sdp = SCpnt->device; | ||
2907 | if (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts) | ||
2908 | sdev_printk(KERN_INFO, sdp, "%s\n", __func__); | ||
2909 | hp = sdp->host; | ||
2910 | if (hp) { | ||
2606 | sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); | 2911 | sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); |
2607 | if (sdbg_host) { | 2912 | if (sdbg_host) { |
2608 | list_for_each_entry(dev_info, | 2913 | list_for_each_entry(devip, |
2609 | &sdbg_host->dev_info_list, | 2914 | &sdbg_host->dev_info_list, |
2610 | dev_list) | 2915 | dev_list) { |
2611 | dev_info->reset = 1; | 2916 | set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); |
2917 | ++k; | ||
2918 | } | ||
2612 | } | 2919 | } |
2613 | } | 2920 | } |
2921 | if (SCSI_DEBUG_OPT_RESET_NOISE & scsi_debug_opts) | ||
2922 | sdev_printk(KERN_INFO, sdp, | ||
2923 | "%s: %d device(s) found in host\n", __func__, k); | ||
2924 | lie: | ||
2614 | return SUCCESS; | 2925 | return SUCCESS; |
2615 | } | 2926 | } |
2616 | 2927 | ||
2617 | static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt) | 2928 | static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt) |
2618 | { | 2929 | { |
2619 | struct sdebug_host_info * sdbg_host; | 2930 | struct sdebug_host_info * sdbg_host; |
2620 | struct sdebug_dev_info * dev_info; | 2931 | struct sdebug_dev_info *devip; |
2932 | int k = 0; | ||
2621 | 2933 | ||
2622 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2623 | printk(KERN_INFO "scsi_debug: host_reset\n"); | ||
2624 | ++num_host_resets; | 2934 | ++num_host_resets; |
2935 | if ((SCpnt->device) && (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts)) | ||
2936 | sdev_printk(KERN_INFO, SCpnt->device, "%s\n", __func__); | ||
2625 | spin_lock(&sdebug_host_list_lock); | 2937 | spin_lock(&sdebug_host_list_lock); |
2626 | list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { | 2938 | list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { |
2627 | list_for_each_entry(dev_info, &sdbg_host->dev_info_list, | 2939 | list_for_each_entry(devip, &sdbg_host->dev_info_list, |
2628 | dev_list) | 2940 | dev_list) { |
2629 | dev_info->reset = 1; | 2941 | set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); |
2942 | ++k; | ||
2943 | } | ||
2630 | } | 2944 | } |
2631 | spin_unlock(&sdebug_host_list_lock); | 2945 | spin_unlock(&sdebug_host_list_lock); |
2632 | stop_all_queued(); | 2946 | stop_all_queued(); |
2947 | if (SCSI_DEBUG_OPT_RESET_NOISE & scsi_debug_opts) | ||
2948 | sdev_printk(KERN_INFO, SCpnt->device, | ||
2949 | "%s: %d device(s) found\n", __func__, k); | ||
2633 | return SUCCESS; | 2950 | return SUCCESS; |
2634 | } | 2951 | } |
2635 | 2952 | ||
2636 | /* Initializes timers in queued array */ | ||
2637 | static void __init init_all_queued(void) | ||
2638 | { | ||
2639 | unsigned long iflags; | ||
2640 | int k; | ||
2641 | struct sdebug_queued_cmd * sqcp; | ||
2642 | |||
2643 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
2644 | for (k = 0; k < scsi_debug_max_queue; ++k) { | ||
2645 | sqcp = &queued_arr[k]; | ||
2646 | init_timer(&sqcp->cmnd_timer); | ||
2647 | sqcp->in_use = 0; | ||
2648 | sqcp->a_cmnd = NULL; | ||
2649 | } | ||
2650 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2651 | } | ||
2652 | |||
2653 | static void __init sdebug_build_parts(unsigned char *ramp, | 2953 | static void __init sdebug_build_parts(unsigned char *ramp, |
2654 | unsigned long store_size) | 2954 | unsigned long store_size) |
2655 | { | 2955 | { |
@@ -2663,8 +2963,8 @@ static void __init sdebug_build_parts(unsigned char *ramp, | |||
2663 | return; | 2963 | return; |
2664 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { | 2964 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { |
2665 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; | 2965 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; |
2666 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " | 2966 | pr_warn("%s: reducing partitions to %d\n", __func__, |
2667 | "partitions to %d\n", SDEBUG_MAX_PARTS); | 2967 | SDEBUG_MAX_PARTS); |
2668 | } | 2968 | } |
2669 | num_sectors = (int)sdebug_store_sectors; | 2969 | num_sectors = (int)sdebug_store_sectors; |
2670 | sectors_per_part = (num_sectors - sdebug_sectors_per) | 2970 | sectors_per_part = (num_sectors - sdebug_sectors_per) |
@@ -2701,62 +3001,130 @@ static void __init sdebug_build_parts(unsigned char *ramp, | |||
2701 | } | 3001 | } |
2702 | } | 3002 | } |
2703 | 3003 | ||
2704 | static int schedule_resp(struct scsi_cmnd * cmnd, | 3004 | static int |
2705 | struct sdebug_dev_info * devip, | 3005 | schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, |
2706 | done_funct_t done, int scsi_result, int delta_jiff) | 3006 | int scsi_result, int delta_jiff) |
2707 | { | 3007 | { |
2708 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmnd) { | 3008 | unsigned long iflags; |
2709 | if (scsi_result) { | 3009 | int k, num_in_q, tsf, qdepth, inject; |
2710 | struct scsi_device * sdp = cmnd->device; | 3010 | struct sdebug_queued_cmd *sqcp = NULL; |
3011 | struct scsi_device *sdp = cmnd->device; | ||
3012 | |||
3013 | if (NULL == cmnd || NULL == devip) { | ||
3014 | pr_warn("%s: called with NULL cmnd or devip pointer\n", | ||
3015 | __func__); | ||
3016 | /* no particularly good error to report back */ | ||
3017 | return SCSI_MLQUEUE_HOST_BUSY; | ||
3018 | } | ||
3019 | if ((scsi_result) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | ||
3020 | sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n", | ||
3021 | __func__, scsi_result); | ||
3022 | if (delta_jiff == 0) { | ||
3023 | /* using same thread to call back mid-layer */ | ||
3024 | cmnd->result = scsi_result; | ||
3025 | cmnd->scsi_done(cmnd); | ||
3026 | return 0; | ||
3027 | } | ||
2711 | 3028 | ||
2712 | printk(KERN_INFO "scsi_debug: <%u %u %u %llu> " | 3029 | /* deferred response cases */ |
2713 | "non-zero result=0x%x\n", sdp->host->host_no, | 3030 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2714 | sdp->channel, sdp->id, sdp->lun, scsi_result); | 3031 | num_in_q = atomic_read(&devip->num_in_q); |
3032 | qdepth = cmnd->device->queue_depth; | ||
3033 | k = find_first_zero_bit(queued_in_use_bm, scsi_debug_max_queue); | ||
3034 | tsf = 0; | ||
3035 | inject = 0; | ||
3036 | if ((qdepth > 0) && (num_in_q >= qdepth)) | ||
3037 | tsf = 1; | ||
3038 | else if ((scsi_debug_every_nth != 0) && | ||
3039 | (SCSI_DEBUG_OPT_RARE_TSF & scsi_debug_opts)) { | ||
3040 | if ((num_in_q == (qdepth - 1)) && | ||
3041 | (atomic_inc_return(&sdebug_a_tsf) >= | ||
3042 | abs(scsi_debug_every_nth))) { | ||
3043 | atomic_set(&sdebug_a_tsf, 0); | ||
3044 | inject = 1; | ||
3045 | tsf = 1; | ||
2715 | } | 3046 | } |
2716 | } | 3047 | } |
2717 | if (cmnd && devip) { | ||
2718 | /* simulate autosense by this driver */ | ||
2719 | if (SAM_STAT_CHECK_CONDITION == (scsi_result & 0xff)) | ||
2720 | memcpy(cmnd->sense_buffer, devip->sense_buff, | ||
2721 | (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ? | ||
2722 | SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE); | ||
2723 | } | ||
2724 | if (delta_jiff <= 0) { | ||
2725 | if (cmnd) | ||
2726 | cmnd->result = scsi_result; | ||
2727 | if (done) | ||
2728 | done(cmnd); | ||
2729 | return 0; | ||
2730 | } else { | ||
2731 | unsigned long iflags; | ||
2732 | int k; | ||
2733 | struct sdebug_queued_cmd * sqcp = NULL; | ||
2734 | 3048 | ||
2735 | spin_lock_irqsave(&queued_arr_lock, iflags); | 3049 | /* if (tsf) simulate device reporting SCSI status of TASK SET FULL. |
2736 | for (k = 0; k < scsi_debug_max_queue; ++k) { | 3050 | * Might override existing CHECK CONDITION. */ |
2737 | sqcp = &queued_arr[k]; | 3051 | if (tsf) |
2738 | if (! sqcp->in_use) | 3052 | scsi_result = device_qfull_result; |
2739 | break; | 3053 | if (k >= scsi_debug_max_queue) { |
3054 | if (SCSI_DEBUG_OPT_ALL_TSF & scsi_debug_opts) | ||
3055 | tsf = 1; | ||
3056 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
3057 | if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) | ||
3058 | sdev_printk(KERN_INFO, sdp, | ||
3059 | "%s: num_in_q=%d, bypass q, %s%s\n", | ||
3060 | __func__, num_in_q, | ||
3061 | (inject ? "<inject> " : ""), | ||
3062 | (tsf ? "status: TASK SET FULL" : | ||
3063 | "report: host busy")); | ||
3064 | if (tsf) { | ||
3065 | /* queued_arr full so respond in same thread */ | ||
3066 | cmnd->result = scsi_result; | ||
3067 | cmnd->scsi_done(cmnd); | ||
3068 | /* As scsi_done() is called "inline" must return 0 */ | ||
3069 | return 0; | ||
3070 | } else | ||
3071 | return SCSI_MLQUEUE_HOST_BUSY; | ||
3072 | } | ||
3073 | __set_bit(k, queued_in_use_bm); | ||
3074 | atomic_inc(&devip->num_in_q); | ||
3075 | sqcp = &queued_arr[k]; | ||
3076 | sqcp->a_cmnd = cmnd; | ||
3077 | cmnd->result = scsi_result; | ||
3078 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
3079 | if (delta_jiff > 0) { | ||
3080 | if (NULL == sqcp->cmnd_timerp) { | ||
3081 | sqcp->cmnd_timerp = kmalloc(sizeof(struct timer_list), | ||
3082 | GFP_ATOMIC); | ||
3083 | if (NULL == sqcp->cmnd_timerp) | ||
3084 | return SCSI_MLQUEUE_HOST_BUSY; | ||
3085 | init_timer(sqcp->cmnd_timerp); | ||
2740 | } | 3086 | } |
2741 | if (k >= scsi_debug_max_queue) { | 3087 | sqcp->cmnd_timerp->function = sdebug_q_cmd_complete; |
2742 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3088 | sqcp->cmnd_timerp->data = k; |
2743 | printk(KERN_WARNING "scsi_debug: can_queue exceeded\n"); | 3089 | sqcp->cmnd_timerp->expires = get_jiffies_64() + delta_jiff; |
2744 | return 1; /* report busy to mid level */ | 3090 | add_timer(sqcp->cmnd_timerp); |
3091 | } else if (scsi_debug_ndelay > 0) { | ||
3092 | ktime_t kt = ktime_set(0, scsi_debug_ndelay); | ||
3093 | struct sdebug_hrtimer *sd_hp = sqcp->sd_hrtp; | ||
3094 | |||
3095 | if (NULL == sd_hp) { | ||
3096 | sd_hp = kmalloc(sizeof(*sd_hp), GFP_ATOMIC); | ||
3097 | if (NULL == sd_hp) | ||
3098 | return SCSI_MLQUEUE_HOST_BUSY; | ||
3099 | sqcp->sd_hrtp = sd_hp; | ||
3100 | hrtimer_init(&sd_hp->hrt, CLOCK_MONOTONIC, | ||
3101 | HRTIMER_MODE_REL); | ||
3102 | sd_hp->hrt.function = sdebug_q_cmd_hrt_complete; | ||
3103 | sd_hp->qa_indx = k; | ||
2745 | } | 3104 | } |
2746 | sqcp->in_use = 1; | 3105 | hrtimer_start(&sd_hp->hrt, kt, HRTIMER_MODE_REL); |
2747 | sqcp->a_cmnd = cmnd; | 3106 | } else { /* delay < 0 */ |
2748 | sqcp->scsi_result = scsi_result; | 3107 | if (NULL == sqcp->tletp) { |
2749 | sqcp->done_funct = done; | 3108 | sqcp->tletp = kmalloc(sizeof(*sqcp->tletp), |
2750 | sqcp->cmnd_timer.function = timer_intr_handler; | 3109 | GFP_ATOMIC); |
2751 | sqcp->cmnd_timer.data = k; | 3110 | if (NULL == sqcp->tletp) |
2752 | sqcp->cmnd_timer.expires = jiffies + delta_jiff; | 3111 | return SCSI_MLQUEUE_HOST_BUSY; |
2753 | add_timer(&sqcp->cmnd_timer); | 3112 | tasklet_init(sqcp->tletp, |
2754 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3113 | sdebug_q_cmd_complete, k); |
2755 | if (cmnd) | 3114 | } |
2756 | cmnd->result = 0; | 3115 | if (-1 == delta_jiff) |
2757 | return 0; | 3116 | tasklet_hi_schedule(sqcp->tletp); |
3117 | else | ||
3118 | tasklet_schedule(sqcp->tletp); | ||
2758 | } | 3119 | } |
3120 | if (tsf && (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts)) | ||
3121 | sdev_printk(KERN_INFO, sdp, | ||
3122 | "%s: num_in_q=%d +1, %s%s\n", __func__, | ||
3123 | num_in_q, (inject ? "<inject> " : ""), | ||
3124 | "status: TASK SET FULL"); | ||
3125 | return 0; | ||
2759 | } | 3126 | } |
3127 | |||
2760 | /* Note: The following macros create attribute files in the | 3128 | /* Note: The following macros create attribute files in the |
2761 | /sys/module/scsi_debug/parameters directory. Unfortunately this | 3129 | /sys/module/scsi_debug/parameters directory. Unfortunately this |
2762 | driver is unaware of a change and cannot trigger auxiliary actions | 3130 | driver is unaware of a change and cannot trigger auxiliary actions |
@@ -2774,6 +3142,7 @@ module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR); | |||
2774 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); | 3142 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); |
2775 | module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR); | 3143 | module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR); |
2776 | module_param_named(guard, scsi_debug_guard, uint, S_IRUGO); | 3144 | module_param_named(guard, scsi_debug_guard, uint, S_IRUGO); |
3145 | module_param_named(host_lock, scsi_debug_host_lock, bool, S_IRUGO | S_IWUSR); | ||
2777 | module_param_named(lbpu, scsi_debug_lbpu, int, S_IRUGO); | 3146 | module_param_named(lbpu, scsi_debug_lbpu, int, S_IRUGO); |
2778 | module_param_named(lbpws, scsi_debug_lbpws, int, S_IRUGO); | 3147 | module_param_named(lbpws, scsi_debug_lbpws, int, S_IRUGO); |
2779 | module_param_named(lbpws10, scsi_debug_lbpws10, int, S_IRUGO); | 3148 | module_param_named(lbpws10, scsi_debug_lbpws10, int, S_IRUGO); |
@@ -2781,6 +3150,7 @@ module_param_named(lbprz, scsi_debug_lbprz, int, S_IRUGO); | |||
2781 | module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO); | 3150 | module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO); |
2782 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); | 3151 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); |
2783 | module_param_named(max_queue, scsi_debug_max_queue, int, S_IRUGO | S_IWUSR); | 3152 | module_param_named(max_queue, scsi_debug_max_queue, int, S_IRUGO | S_IWUSR); |
3153 | module_param_named(ndelay, scsi_debug_ndelay, int, S_IRUGO | S_IWUSR); | ||
2784 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); | 3154 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); |
2785 | module_param_named(no_uld, scsi_debug_no_uld, int, S_IRUGO); | 3155 | module_param_named(no_uld, scsi_debug_no_uld, int, S_IRUGO); |
2786 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); | 3156 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); |
@@ -2810,7 +3180,7 @@ MODULE_VERSION(SCSI_DEBUG_VERSION); | |||
2810 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); | 3180 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); |
2811 | MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)"); | 3181 | MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)"); |
2812 | MODULE_PARM_DESC(clustering, "when set enables larger transfers (def=0)"); | 3182 | MODULE_PARM_DESC(clustering, "when set enables larger transfers (def=0)"); |
2813 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); | 3183 | MODULE_PARM_DESC(delay, "response delay (def=1 jiffy); 0:imm, -1,-2:tiny"); |
2814 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); | 3184 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); |
2815 | MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)"); | 3185 | MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)"); |
2816 | MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)"); | 3186 | MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)"); |
@@ -2818,13 +3188,15 @@ MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); | |||
2818 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=0)"); | 3188 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=0)"); |
2819 | MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)"); | 3189 | MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)"); |
2820 | MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)"); | 3190 | MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)"); |
3191 | MODULE_PARM_DESC(host_lock, "use host_lock around all commands (def=0)"); | ||
2821 | MODULE_PARM_DESC(lbpu, "enable LBP, support UNMAP command (def=0)"); | 3192 | MODULE_PARM_DESC(lbpu, "enable LBP, support UNMAP command (def=0)"); |
2822 | MODULE_PARM_DESC(lbpws, "enable LBP, support WRITE SAME(16) with UNMAP bit (def=0)"); | 3193 | MODULE_PARM_DESC(lbpws, "enable LBP, support WRITE SAME(16) with UNMAP bit (def=0)"); |
2823 | MODULE_PARM_DESC(lbpws10, "enable LBP, support WRITE SAME(10) with UNMAP bit (def=0)"); | 3194 | MODULE_PARM_DESC(lbpws10, "enable LBP, support WRITE SAME(10) with UNMAP bit (def=0)"); |
2824 | MODULE_PARM_DESC(lbprz, "unmapped blocks return 0 on read (def=1)"); | 3195 | MODULE_PARM_DESC(lbprz, "unmapped blocks return 0 on read (def=1)"); |
2825 | MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)"); | 3196 | MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)"); |
2826 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); | 3197 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
2827 | MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to 255(def))"); | 3198 | MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to max(def))"); |
3199 | MODULE_PARM_DESC(ndelay, "response delay in nanoseconds (def=0 -> ignore)"); | ||
2828 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | 3200 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); |
2829 | MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); | 3201 | MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); |
2830 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 3202 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
@@ -2855,9 +3227,7 @@ static const char * scsi_debug_info(struct Scsi_Host * shp) | |||
2855 | return sdebug_info; | 3227 | return sdebug_info; |
2856 | } | 3228 | } |
2857 | 3229 | ||
2858 | /* scsi_debug_proc_info | 3230 | /* 'echo <val> > /proc/scsi/scsi_debug/<host_id>' writes to opts */ |
2859 | * Used if the driver currently has no own support for /proc/scsi | ||
2860 | */ | ||
2861 | static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int length) | 3231 | static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int length) |
2862 | { | 3232 | { |
2863 | char arr[16]; | 3233 | char arr[16]; |
@@ -2872,27 +3242,49 @@ static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int lengt | |||
2872 | return -EINVAL; | 3242 | return -EINVAL; |
2873 | scsi_debug_opts = opts; | 3243 | scsi_debug_opts = opts; |
2874 | if (scsi_debug_every_nth != 0) | 3244 | if (scsi_debug_every_nth != 0) |
2875 | scsi_debug_cmnd_count = 0; | 3245 | atomic_set(&sdebug_cmnd_count, 0); |
2876 | return length; | 3246 | return length; |
2877 | } | 3247 | } |
2878 | 3248 | ||
3249 | /* Output seen with 'cat /proc/scsi/scsi_debug/<host_id>'. It will be the | ||
3250 | * same for each scsi_debug host (if more than one). Some of the counters | ||
3251 | * output are not atomics so might be inaccurate in a busy system. */ | ||
2879 | static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) | 3252 | static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) |
2880 | { | 3253 | { |
2881 | seq_printf(m, "scsi_debug adapter driver, version " | 3254 | int f, l; |
2882 | "%s [%s]\n" | 3255 | char b[32]; |
2883 | "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, " | 3256 | |
2884 | "every_nth=%d(curr:%d)\n" | 3257 | if (scsi_debug_every_nth > 0) |
2885 | "delay=%d, max_luns=%d, scsi_level=%d\n" | 3258 | snprintf(b, sizeof(b), " (curr:%d)", |
2886 | "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n" | 3259 | ((SCSI_DEBUG_OPT_RARE_TSF & scsi_debug_opts) ? |
2887 | "number of aborts=%d, device_reset=%d, bus_resets=%d, " | 3260 | atomic_read(&sdebug_a_tsf) : |
2888 | "host_resets=%d\ndix_reads=%d dix_writes=%d dif_errors=%d\n", | 3261 | atomic_read(&sdebug_cmnd_count))); |
2889 | SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts, | 3262 | else |
2890 | scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth, | 3263 | b[0] = '\0'; |
2891 | scsi_debug_cmnd_count, scsi_debug_delay, | 3264 | |
2892 | scsi_debug_max_luns, scsi_debug_scsi_level, | 3265 | seq_printf(m, "scsi_debug adapter driver, version %s [%s]\n" |
2893 | scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads, | 3266 | "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, " |
2894 | sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets, | 3267 | "every_nth=%d%s\n" |
2895 | num_host_resets, dix_reads, dix_writes, dif_errors); | 3268 | "delay=%d, ndelay=%d, max_luns=%d, q_completions=%d\n" |
3269 | "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n" | ||
3270 | "command aborts=%d; RESETs: device=%d, target=%d, bus=%d, " | ||
3271 | "host=%d\ndix_reads=%d dix_writes=%d dif_errors=%d " | ||
3272 | "usec_in_jiffy=%lu\n", | ||
3273 | SCSI_DEBUG_VERSION, scsi_debug_version_date, | ||
3274 | scsi_debug_num_tgts, scsi_debug_dev_size_mb, scsi_debug_opts, | ||
3275 | scsi_debug_every_nth, b, scsi_debug_delay, scsi_debug_ndelay, | ||
3276 | scsi_debug_max_luns, atomic_read(&sdebug_completions), | ||
3277 | scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads, | ||
3278 | sdebug_sectors_per, num_aborts, num_dev_resets, | ||
3279 | num_target_resets, num_bus_resets, num_host_resets, | ||
3280 | dix_reads, dix_writes, dif_errors, TICK_NSEC / 1000); | ||
3281 | |||
3282 | f = find_first_bit(queued_in_use_bm, scsi_debug_max_queue); | ||
3283 | if (f != scsi_debug_max_queue) { | ||
3284 | l = find_last_bit(queued_in_use_bm, scsi_debug_max_queue); | ||
3285 | seq_printf(m, " %s BUSY: first,last bits set: %d,%d\n", | ||
3286 | "queued_in_use_bm", f, l); | ||
3287 | } | ||
2896 | return 0; | 3288 | return 0; |
2897 | } | 3289 | } |
2898 | 3290 | ||
@@ -2900,23 +3292,69 @@ static ssize_t delay_show(struct device_driver *ddp, char *buf) | |||
2900 | { | 3292 | { |
2901 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay); | 3293 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay); |
2902 | } | 3294 | } |
2903 | 3295 | /* Returns -EBUSY if delay is being changed and commands are queued */ | |
2904 | static ssize_t delay_store(struct device_driver *ddp, const char *buf, | 3296 | static ssize_t delay_store(struct device_driver *ddp, const char *buf, |
2905 | size_t count) | 3297 | size_t count) |
2906 | { | 3298 | { |
2907 | int delay; | 3299 | int delay, res; |
2908 | char work[20]; | 3300 | |
2909 | 3301 | if ((count > 0) && (1 == sscanf(buf, "%d", &delay))) { | |
2910 | if (1 == sscanf(buf, "%10s", work)) { | 3302 | res = count; |
2911 | if ((1 == sscanf(work, "%d", &delay)) && (delay >= 0)) { | 3303 | if (scsi_debug_delay != delay) { |
2912 | scsi_debug_delay = delay; | 3304 | unsigned long iflags; |
2913 | return count; | 3305 | int k; |
3306 | |||
3307 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
3308 | k = find_first_bit(queued_in_use_bm, | ||
3309 | scsi_debug_max_queue); | ||
3310 | if (k != scsi_debug_max_queue) | ||
3311 | res = -EBUSY; /* have queued commands */ | ||
3312 | else { | ||
3313 | scsi_debug_delay = delay; | ||
3314 | scsi_debug_ndelay = 0; | ||
3315 | } | ||
3316 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2914 | } | 3317 | } |
3318 | return res; | ||
2915 | } | 3319 | } |
2916 | return -EINVAL; | 3320 | return -EINVAL; |
2917 | } | 3321 | } |
2918 | static DRIVER_ATTR_RW(delay); | 3322 | static DRIVER_ATTR_RW(delay); |
2919 | 3323 | ||
3324 | static ssize_t ndelay_show(struct device_driver *ddp, char *buf) | ||
3325 | { | ||
3326 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ndelay); | ||
3327 | } | ||
3328 | /* Returns -EBUSY if ndelay is being changed and commands are queued */ | ||
3329 | /* If > 0 and accepted then scsi_debug_delay is set to DELAY_OVERRIDDEN */ | ||
3330 | static ssize_t ndelay_store(struct device_driver *ddp, const char *buf, | ||
3331 | size_t count) | ||
3332 | { | ||
3333 | unsigned long iflags; | ||
3334 | int ndelay, res, k; | ||
3335 | |||
3336 | if ((count > 0) && (1 == sscanf(buf, "%d", &ndelay)) && | ||
3337 | (ndelay >= 0) && (ndelay < 1000000000)) { | ||
3338 | res = count; | ||
3339 | if (scsi_debug_ndelay != ndelay) { | ||
3340 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
3341 | k = find_first_bit(queued_in_use_bm, | ||
3342 | scsi_debug_max_queue); | ||
3343 | if (k != scsi_debug_max_queue) | ||
3344 | res = -EBUSY; /* have queued commands */ | ||
3345 | else { | ||
3346 | scsi_debug_ndelay = ndelay; | ||
3347 | scsi_debug_delay = ndelay ? DELAY_OVERRIDDEN | ||
3348 | : DEF_DELAY; | ||
3349 | } | ||
3350 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
3351 | } | ||
3352 | return res; | ||
3353 | } | ||
3354 | return -EINVAL; | ||
3355 | } | ||
3356 | static DRIVER_ATTR_RW(ndelay); | ||
3357 | |||
2920 | static ssize_t opts_show(struct device_driver *ddp, char *buf) | 3358 | static ssize_t opts_show(struct device_driver *ddp, char *buf) |
2921 | { | 3359 | { |
2922 | return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts); | 3360 | return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts); |
@@ -2940,7 +3378,8 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf, | |||
2940 | return -EINVAL; | 3378 | return -EINVAL; |
2941 | opts_done: | 3379 | opts_done: |
2942 | scsi_debug_opts = opts; | 3380 | scsi_debug_opts = opts; |
2943 | scsi_debug_cmnd_count = 0; | 3381 | atomic_set(&sdebug_cmnd_count, 0); |
3382 | atomic_set(&sdebug_a_tsf, 0); | ||
2944 | return count; | 3383 | return count; |
2945 | } | 3384 | } |
2946 | static DRIVER_ATTR_RW(opts); | 3385 | static DRIVER_ATTR_RW(opts); |
@@ -2989,7 +3428,24 @@ static ssize_t fake_rw_store(struct device_driver *ddp, const char *buf, | |||
2989 | int n; | 3428 | int n; |
2990 | 3429 | ||
2991 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | 3430 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { |
2992 | scsi_debug_fake_rw = n; | 3431 | n = (n > 0); |
3432 | scsi_debug_fake_rw = (scsi_debug_fake_rw > 0); | ||
3433 | if (scsi_debug_fake_rw != n) { | ||
3434 | if ((0 == n) && (NULL == fake_storep)) { | ||
3435 | unsigned long sz = | ||
3436 | (unsigned long)scsi_debug_dev_size_mb * | ||
3437 | 1048576; | ||
3438 | |||
3439 | fake_storep = vmalloc(sz); | ||
3440 | if (NULL == fake_storep) { | ||
3441 | pr_err("%s: out of memory, 9\n", | ||
3442 | __func__); | ||
3443 | return -ENOMEM; | ||
3444 | } | ||
3445 | memset(fake_storep, 0, sz); | ||
3446 | } | ||
3447 | scsi_debug_fake_rw = n; | ||
3448 | } | ||
2993 | return count; | 3449 | return count; |
2994 | } | 3450 | } |
2995 | return -EINVAL; | 3451 | return -EINVAL; |
@@ -3054,7 +3510,7 @@ static ssize_t every_nth_store(struct device_driver *ddp, const char *buf, | |||
3054 | 3510 | ||
3055 | if ((count > 0) && (1 == sscanf(buf, "%d", &nth))) { | 3511 | if ((count > 0) && (1 == sscanf(buf, "%d", &nth))) { |
3056 | scsi_debug_every_nth = nth; | 3512 | scsi_debug_every_nth = nth; |
3057 | scsi_debug_cmnd_count = 0; | 3513 | atomic_set(&sdebug_cmnd_count, 0); |
3058 | return count; | 3514 | return count; |
3059 | } | 3515 | } |
3060 | return -EINVAL; | 3516 | return -EINVAL; |
@@ -3083,14 +3539,26 @@ static ssize_t max_queue_show(struct device_driver *ddp, char *buf) | |||
3083 | { | 3539 | { |
3084 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_queue); | 3540 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_queue); |
3085 | } | 3541 | } |
3542 | /* N.B. max_queue can be changed while there are queued commands. In flight | ||
3543 | * commands beyond the new max_queue will be completed. */ | ||
3086 | static ssize_t max_queue_store(struct device_driver *ddp, const char *buf, | 3544 | static ssize_t max_queue_store(struct device_driver *ddp, const char *buf, |
3087 | size_t count) | 3545 | size_t count) |
3088 | { | 3546 | { |
3089 | int n; | 3547 | unsigned long iflags; |
3548 | int n, k; | ||
3090 | 3549 | ||
3091 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) && | 3550 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) && |
3092 | (n <= SCSI_DEBUG_CANQUEUE)) { | 3551 | (n <= SCSI_DEBUG_CANQUEUE)) { |
3552 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
3553 | k = find_last_bit(queued_in_use_bm, SCSI_DEBUG_CANQUEUE); | ||
3093 | scsi_debug_max_queue = n; | 3554 | scsi_debug_max_queue = n; |
3555 | if (SCSI_DEBUG_CANQUEUE == k) | ||
3556 | atomic_set(&retired_max_queue, 0); | ||
3557 | else if (k >= n) | ||
3558 | atomic_set(&retired_max_queue, k + 1); | ||
3559 | else | ||
3560 | atomic_set(&retired_max_queue, 0); | ||
3561 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
3094 | return count; | 3562 | return count; |
3095 | } | 3563 | } |
3096 | return -EINVAL; | 3564 | return -EINVAL; |
@@ -3235,6 +3703,40 @@ static ssize_t removable_store(struct device_driver *ddp, const char *buf, | |||
3235 | } | 3703 | } |
3236 | static DRIVER_ATTR_RW(removable); | 3704 | static DRIVER_ATTR_RW(removable); |
3237 | 3705 | ||
3706 | static ssize_t host_lock_show(struct device_driver *ddp, char *buf) | ||
3707 | { | ||
3708 | return scnprintf(buf, PAGE_SIZE, "%d\n", !!scsi_debug_host_lock); | ||
3709 | } | ||
3710 | /* Returns -EBUSY if host_lock is being changed and commands are queued */ | ||
3711 | static ssize_t host_lock_store(struct device_driver *ddp, const char *buf, | ||
3712 | size_t count) | ||
3713 | { | ||
3714 | int n, res; | ||
3715 | |||
3716 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
3717 | bool new_host_lock = (n > 0); | ||
3718 | |||
3719 | res = count; | ||
3720 | if (new_host_lock != scsi_debug_host_lock) { | ||
3721 | unsigned long iflags; | ||
3722 | int k; | ||
3723 | |||
3724 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
3725 | k = find_first_bit(queued_in_use_bm, | ||
3726 | scsi_debug_max_queue); | ||
3727 | if (k != scsi_debug_max_queue) | ||
3728 | res = -EBUSY; /* have queued commands */ | ||
3729 | else | ||
3730 | scsi_debug_host_lock = new_host_lock; | ||
3731 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
3732 | } | ||
3733 | return res; | ||
3734 | } | ||
3735 | return -EINVAL; | ||
3736 | } | ||
3737 | static DRIVER_ATTR_RW(host_lock); | ||
3738 | |||
3739 | |||
3238 | /* Note: The following array creates attribute files in the | 3740 | /* Note: The following array creates attribute files in the |
3239 | /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these | 3741 | /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these |
3240 | files (over those found in the /sys/module/scsi_debug/parameters | 3742 | files (over those found in the /sys/module/scsi_debug/parameters |
@@ -3267,6 +3769,8 @@ static struct attribute *sdebug_drv_attrs[] = { | |||
3267 | &driver_attr_ato.attr, | 3769 | &driver_attr_ato.attr, |
3268 | &driver_attr_map.attr, | 3770 | &driver_attr_map.attr, |
3269 | &driver_attr_removable.attr, | 3771 | &driver_attr_removable.attr, |
3772 | &driver_attr_host_lock.attr, | ||
3773 | &driver_attr_ndelay.attr, | ||
3270 | NULL, | 3774 | NULL, |
3271 | }; | 3775 | }; |
3272 | ATTRIBUTE_GROUPS(sdebug_drv); | 3776 | ATTRIBUTE_GROUPS(sdebug_drv); |
@@ -3280,6 +3784,17 @@ static int __init scsi_debug_init(void) | |||
3280 | int k; | 3784 | int k; |
3281 | int ret; | 3785 | int ret; |
3282 | 3786 | ||
3787 | atomic_set(&sdebug_cmnd_count, 0); | ||
3788 | atomic_set(&sdebug_completions, 0); | ||
3789 | atomic_set(&retired_max_queue, 0); | ||
3790 | |||
3791 | if (scsi_debug_ndelay >= 1000000000) { | ||
3792 | pr_warn("%s: ndelay must be less than 1 second, ignored\n", | ||
3793 | __func__); | ||
3794 | scsi_debug_ndelay = 0; | ||
3795 | } else if (scsi_debug_ndelay > 0) | ||
3796 | scsi_debug_delay = DELAY_OVERRIDDEN; | ||
3797 | |||
3283 | switch (scsi_debug_sector_size) { | 3798 | switch (scsi_debug_sector_size) { |
3284 | case 512: | 3799 | case 512: |
3285 | case 1024: | 3800 | case 1024: |
@@ -3287,7 +3802,7 @@ static int __init scsi_debug_init(void) | |||
3287 | case 4096: | 3802 | case 4096: |
3288 | break; | 3803 | break; |
3289 | default: | 3804 | default: |
3290 | printk(KERN_ERR "scsi_debug_init: invalid sector_size %d\n", | 3805 | pr_err("%s: invalid sector_size %d\n", __func__, |
3291 | scsi_debug_sector_size); | 3806 | scsi_debug_sector_size); |
3292 | return -EINVAL; | 3807 | return -EINVAL; |
3293 | } | 3808 | } |
@@ -3301,28 +3816,28 @@ static int __init scsi_debug_init(void) | |||
3301 | break; | 3816 | break; |
3302 | 3817 | ||
3303 | default: | 3818 | default: |
3304 | printk(KERN_ERR "scsi_debug_init: dif must be 0, 1, 2 or 3\n"); | 3819 | pr_err("%s: dif must be 0, 1, 2 or 3\n", __func__); |
3305 | return -EINVAL; | 3820 | return -EINVAL; |
3306 | } | 3821 | } |
3307 | 3822 | ||
3308 | if (scsi_debug_guard > 1) { | 3823 | if (scsi_debug_guard > 1) { |
3309 | printk(KERN_ERR "scsi_debug_init: guard must be 0 or 1\n"); | 3824 | pr_err("%s: guard must be 0 or 1\n", __func__); |
3310 | return -EINVAL; | 3825 | return -EINVAL; |
3311 | } | 3826 | } |
3312 | 3827 | ||
3313 | if (scsi_debug_ato > 1) { | 3828 | if (scsi_debug_ato > 1) { |
3314 | printk(KERN_ERR "scsi_debug_init: ato must be 0 or 1\n"); | 3829 | pr_err("%s: ato must be 0 or 1\n", __func__); |
3315 | return -EINVAL; | 3830 | return -EINVAL; |
3316 | } | 3831 | } |
3317 | 3832 | ||
3318 | if (scsi_debug_physblk_exp > 15) { | 3833 | if (scsi_debug_physblk_exp > 15) { |
3319 | printk(KERN_ERR "scsi_debug_init: invalid physblk_exp %u\n", | 3834 | pr_err("%s: invalid physblk_exp %u\n", __func__, |
3320 | scsi_debug_physblk_exp); | 3835 | scsi_debug_physblk_exp); |
3321 | return -EINVAL; | 3836 | return -EINVAL; |
3322 | } | 3837 | } |
3323 | 3838 | ||
3324 | if (scsi_debug_lowest_aligned > 0x3fff) { | 3839 | if (scsi_debug_lowest_aligned > 0x3fff) { |
3325 | printk(KERN_ERR "scsi_debug_init: lowest_aligned too big: %u\n", | 3840 | pr_err("%s: lowest_aligned too big: %u\n", __func__, |
3326 | scsi_debug_lowest_aligned); | 3841 | scsi_debug_lowest_aligned); |
3327 | return -EINVAL; | 3842 | return -EINVAL; |
3328 | } | 3843 | } |
@@ -3350,14 +3865,16 @@ static int __init scsi_debug_init(void) | |||
3350 | (sdebug_sectors_per * sdebug_heads); | 3865 | (sdebug_sectors_per * sdebug_heads); |
3351 | } | 3866 | } |
3352 | 3867 | ||
3353 | fake_storep = vmalloc(sz); | 3868 | if (0 == scsi_debug_fake_rw) { |
3354 | if (NULL == fake_storep) { | 3869 | fake_storep = vmalloc(sz); |
3355 | printk(KERN_ERR "scsi_debug_init: out of memory, 1\n"); | 3870 | if (NULL == fake_storep) { |
3356 | return -ENOMEM; | 3871 | pr_err("%s: out of memory, 1\n", __func__); |
3872 | return -ENOMEM; | ||
3873 | } | ||
3874 | memset(fake_storep, 0, sz); | ||
3875 | if (scsi_debug_num_parts > 0) | ||
3876 | sdebug_build_parts(fake_storep, sz); | ||
3357 | } | 3877 | } |
3358 | memset(fake_storep, 0, sz); | ||
3359 | if (scsi_debug_num_parts > 0) | ||
3360 | sdebug_build_parts(fake_storep, sz); | ||
3361 | 3878 | ||
3362 | if (scsi_debug_dix) { | 3879 | if (scsi_debug_dix) { |
3363 | int dif_size; | 3880 | int dif_size; |
@@ -3365,11 +3882,11 @@ static int __init scsi_debug_init(void) | |||
3365 | dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple); | 3882 | dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple); |
3366 | dif_storep = vmalloc(dif_size); | 3883 | dif_storep = vmalloc(dif_size); |
3367 | 3884 | ||
3368 | printk(KERN_ERR "scsi_debug_init: dif_storep %u bytes @ %p\n", | 3885 | pr_err("%s: dif_storep %u bytes @ %p\n", __func__, dif_size, |
3369 | dif_size, dif_storep); | 3886 | dif_storep); |
3370 | 3887 | ||
3371 | if (dif_storep == NULL) { | 3888 | if (dif_storep == NULL) { |
3372 | printk(KERN_ERR "scsi_debug_init: out of mem. (DIX)\n"); | 3889 | pr_err("%s: out of mem. (DIX)\n", __func__); |
3373 | ret = -ENOMEM; | 3890 | ret = -ENOMEM; |
3374 | goto free_vm; | 3891 | goto free_vm; |
3375 | } | 3892 | } |
@@ -3391,8 +3908,7 @@ static int __init scsi_debug_init(void) | |||
3391 | if (scsi_debug_unmap_alignment && | 3908 | if (scsi_debug_unmap_alignment && |
3392 | scsi_debug_unmap_granularity <= | 3909 | scsi_debug_unmap_granularity <= |
3393 | scsi_debug_unmap_alignment) { | 3910 | scsi_debug_unmap_alignment) { |
3394 | printk(KERN_ERR | 3911 | pr_err("%s: ERR: unmap_granularity <= unmap_alignment\n", |
3395 | "%s: ERR: unmap_granularity <= unmap_alignment\n", | ||
3396 | __func__); | 3912 | __func__); |
3397 | return -EINVAL; | 3913 | return -EINVAL; |
3398 | } | 3914 | } |
@@ -3400,11 +3916,10 @@ static int __init scsi_debug_init(void) | |||
3400 | map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1; | 3916 | map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1; |
3401 | map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long)); | 3917 | map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long)); |
3402 | 3918 | ||
3403 | printk(KERN_INFO "scsi_debug_init: %lu provisioning blocks\n", | 3919 | pr_info("%s: %lu provisioning blocks\n", __func__, map_size); |
3404 | map_size); | ||
3405 | 3920 | ||
3406 | if (map_storep == NULL) { | 3921 | if (map_storep == NULL) { |
3407 | printk(KERN_ERR "scsi_debug_init: out of mem. (MAP)\n"); | 3922 | pr_err("%s: out of mem. (MAP)\n", __func__); |
3408 | ret = -ENOMEM; | 3923 | ret = -ENOMEM; |
3409 | goto free_vm; | 3924 | goto free_vm; |
3410 | } | 3925 | } |
@@ -3418,39 +3933,35 @@ static int __init scsi_debug_init(void) | |||
3418 | 3933 | ||
3419 | pseudo_primary = root_device_register("pseudo_0"); | 3934 | pseudo_primary = root_device_register("pseudo_0"); |
3420 | if (IS_ERR(pseudo_primary)) { | 3935 | if (IS_ERR(pseudo_primary)) { |
3421 | printk(KERN_WARNING "scsi_debug: root_device_register() error\n"); | 3936 | pr_warn("%s: root_device_register() error\n", __func__); |
3422 | ret = PTR_ERR(pseudo_primary); | 3937 | ret = PTR_ERR(pseudo_primary); |
3423 | goto free_vm; | 3938 | goto free_vm; |
3424 | } | 3939 | } |
3425 | ret = bus_register(&pseudo_lld_bus); | 3940 | ret = bus_register(&pseudo_lld_bus); |
3426 | if (ret < 0) { | 3941 | if (ret < 0) { |
3427 | printk(KERN_WARNING "scsi_debug: bus_register error: %d\n", | 3942 | pr_warn("%s: bus_register error: %d\n", __func__, ret); |
3428 | ret); | ||
3429 | goto dev_unreg; | 3943 | goto dev_unreg; |
3430 | } | 3944 | } |
3431 | ret = driver_register(&sdebug_driverfs_driver); | 3945 | ret = driver_register(&sdebug_driverfs_driver); |
3432 | if (ret < 0) { | 3946 | if (ret < 0) { |
3433 | printk(KERN_WARNING "scsi_debug: driver_register error: %d\n", | 3947 | pr_warn("%s: driver_register error: %d\n", __func__, ret); |
3434 | ret); | ||
3435 | goto bus_unreg; | 3948 | goto bus_unreg; |
3436 | } | 3949 | } |
3437 | 3950 | ||
3438 | init_all_queued(); | ||
3439 | |||
3440 | host_to_add = scsi_debug_add_host; | 3951 | host_to_add = scsi_debug_add_host; |
3441 | scsi_debug_add_host = 0; | 3952 | scsi_debug_add_host = 0; |
3442 | 3953 | ||
3443 | for (k = 0; k < host_to_add; k++) { | 3954 | for (k = 0; k < host_to_add; k++) { |
3444 | if (sdebug_add_adapter()) { | 3955 | if (sdebug_add_adapter()) { |
3445 | printk(KERN_ERR "scsi_debug_init: " | 3956 | pr_err("%s: sdebug_add_adapter failed k=%d\n", |
3446 | "sdebug_add_adapter failed k=%d\n", k); | 3957 | __func__, k); |
3447 | break; | 3958 | break; |
3448 | } | 3959 | } |
3449 | } | 3960 | } |
3450 | 3961 | ||
3451 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { | 3962 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { |
3452 | printk(KERN_INFO "scsi_debug_init: built %d host(s)\n", | 3963 | pr_info("%s: built %d host(s)\n", __func__, |
3453 | scsi_debug_add_host); | 3964 | scsi_debug_add_host); |
3454 | } | 3965 | } |
3455 | return 0; | 3966 | return 0; |
3456 | 3967 | ||
@@ -3473,6 +3984,7 @@ static void __exit scsi_debug_exit(void) | |||
3473 | int k = scsi_debug_add_host; | 3984 | int k = scsi_debug_add_host; |
3474 | 3985 | ||
3475 | stop_all_queued(); | 3986 | stop_all_queued(); |
3987 | free_all_queued(); | ||
3476 | for (; k; k--) | 3988 | for (; k; k--) |
3477 | sdebug_remove_adapter(); | 3989 | sdebug_remove_adapter(); |
3478 | driver_unregister(&sdebug_driverfs_driver); | 3990 | driver_unregister(&sdebug_driverfs_driver); |
@@ -3570,8 +4082,8 @@ static void sdebug_remove_adapter(void) | |||
3570 | --scsi_debug_add_host; | 4082 | --scsi_debug_add_host; |
3571 | } | 4083 | } |
3572 | 4084 | ||
3573 | static | 4085 | static int |
3574 | int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | 4086 | scsi_debug_queuecommand(struct scsi_cmnd *SCpnt) |
3575 | { | 4087 | { |
3576 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | 4088 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; |
3577 | int len, k; | 4089 | int len, k; |
@@ -3590,32 +4102,34 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3590 | int unmap = 0; | 4102 | int unmap = 0; |
3591 | 4103 | ||
3592 | scsi_set_resid(SCpnt, 0); | 4104 | scsi_set_resid(SCpnt, 0); |
3593 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | 4105 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && |
3594 | printk(KERN_INFO "scsi_debug: cmd "); | 4106 | !(SCSI_DEBUG_OPT_NO_CDB_NOISE & scsi_debug_opts) && cmd) { |
3595 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) | 4107 | char b[120]; |
3596 | printk("%02x ", (int)cmd[k]); | 4108 | int n; |
3597 | printk("\n"); | 4109 | |
3598 | } | 4110 | len = SCpnt->cmd_len; |
3599 | 4111 | if (len > 32) | |
3600 | if (target == SCpnt->device->host->hostt->this_id) { | 4112 | strcpy(b, "too long, over 32 bytes"); |
3601 | printk(KERN_INFO "scsi_debug: initiator's id used as " | 4113 | else { |
3602 | "target!\n"); | 4114 | for (k = 0, n = 0; k < len; ++k) |
3603 | return schedule_resp(SCpnt, NULL, done, | 4115 | n += scnprintf(b + n, sizeof(b) - n, "%02x ", |
3604 | DID_NO_CONNECT << 16, 0); | 4116 | (unsigned int)cmd[k]); |
4117 | } | ||
4118 | sdev_printk(KERN_INFO, SCpnt->device, "%s: cmd %s\n", my_name, | ||
4119 | b); | ||
3605 | } | 4120 | } |
3606 | 4121 | ||
3607 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && | 4122 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && |
3608 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | 4123 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) |
3609 | return schedule_resp(SCpnt, NULL, done, | 4124 | return schedule_resp(SCpnt, NULL, DID_NO_CONNECT << 16, 0); |
3610 | DID_NO_CONNECT << 16, 0); | ||
3611 | devip = devInfoReg(SCpnt->device); | 4125 | devip = devInfoReg(SCpnt->device); |
3612 | if (NULL == devip) | 4126 | if (NULL == devip) |
3613 | return schedule_resp(SCpnt, NULL, done, | 4127 | return schedule_resp(SCpnt, NULL, DID_NO_CONNECT << 16, 0); |
3614 | DID_NO_CONNECT << 16, 0); | ||
3615 | 4128 | ||
3616 | if ((scsi_debug_every_nth != 0) && | 4129 | if ((scsi_debug_every_nth != 0) && |
3617 | (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) { | 4130 | (atomic_inc_return(&sdebug_cmnd_count) >= |
3618 | scsi_debug_cmnd_count = 0; | 4131 | abs(scsi_debug_every_nth))) { |
4132 | atomic_set(&sdebug_cmnd_count, 0); | ||
3619 | if (scsi_debug_every_nth < -1) | 4133 | if (scsi_debug_every_nth < -1) |
3620 | scsi_debug_every_nth = -1; | 4134 | scsi_debug_every_nth = -1; |
3621 | if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) | 4135 | if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) |
@@ -3646,11 +4160,10 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3646 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 4160 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
3647 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | 4161 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " |
3648 | "not supported for wlun\n", *cmd); | 4162 | "not supported for wlun\n", *cmd); |
3649 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4163 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3650 | INVALID_OPCODE, 0); | 4164 | INVALID_OPCODE, 0); |
3651 | errsts = check_condition_result; | 4165 | errsts = check_condition_result; |
3652 | return schedule_resp(SCpnt, devip, done, errsts, | 4166 | return schedule_resp(SCpnt, devip, errsts, 0); |
3653 | 0); | ||
3654 | } | 4167 | } |
3655 | } | 4168 | } |
3656 | 4169 | ||
@@ -3668,7 +4181,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3668 | errsts = resp_start_stop(SCpnt, devip); | 4181 | errsts = resp_start_stop(SCpnt, devip); |
3669 | break; | 4182 | break; |
3670 | case ALLOW_MEDIUM_REMOVAL: | 4183 | case ALLOW_MEDIUM_REMOVAL: |
3671 | errsts = check_readiness(SCpnt, 1, devip); | 4184 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3672 | if (errsts) | 4185 | if (errsts) |
3673 | break; | 4186 | break; |
3674 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 4187 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
@@ -3676,23 +4189,23 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3676 | cmd[4] ? "inhibited" : "enabled"); | 4189 | cmd[4] ? "inhibited" : "enabled"); |
3677 | break; | 4190 | break; |
3678 | case SEND_DIAGNOSTIC: /* mandatory */ | 4191 | case SEND_DIAGNOSTIC: /* mandatory */ |
3679 | errsts = check_readiness(SCpnt, 1, devip); | 4192 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3680 | break; | 4193 | break; |
3681 | case TEST_UNIT_READY: /* mandatory */ | 4194 | case TEST_UNIT_READY: /* mandatory */ |
3682 | delay_override = 1; | 4195 | /* delay_override = 1; */ |
3683 | errsts = check_readiness(SCpnt, 0, devip); | 4196 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3684 | break; | 4197 | break; |
3685 | case RESERVE: | 4198 | case RESERVE: |
3686 | errsts = check_readiness(SCpnt, 1, devip); | 4199 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3687 | break; | 4200 | break; |
3688 | case RESERVE_10: | 4201 | case RESERVE_10: |
3689 | errsts = check_readiness(SCpnt, 1, devip); | 4202 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3690 | break; | 4203 | break; |
3691 | case RELEASE: | 4204 | case RELEASE: |
3692 | errsts = check_readiness(SCpnt, 1, devip); | 4205 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3693 | break; | 4206 | break; |
3694 | case RELEASE_10: | 4207 | case RELEASE_10: |
3695 | errsts = check_readiness(SCpnt, 1, devip); | 4208 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3696 | break; | 4209 | break; |
3697 | case READ_CAPACITY: | 4210 | case READ_CAPACITY: |
3698 | errsts = resp_readcap(SCpnt, devip); | 4211 | errsts = resp_readcap(SCpnt, devip); |
@@ -3703,20 +4216,20 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3703 | else if (cmd[1] == SAI_GET_LBA_STATUS) { | 4216 | else if (cmd[1] == SAI_GET_LBA_STATUS) { |
3704 | 4217 | ||
3705 | if (scsi_debug_lbp() == 0) { | 4218 | if (scsi_debug_lbp() == 0) { |
3706 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4219 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3707 | INVALID_COMMAND_OPCODE, 0); | 4220 | INVALID_COMMAND_OPCODE, 0); |
3708 | errsts = check_condition_result; | 4221 | errsts = check_condition_result; |
3709 | } else | 4222 | } else |
3710 | errsts = resp_get_lba_status(SCpnt, devip); | 4223 | errsts = resp_get_lba_status(SCpnt, devip); |
3711 | } else { | 4224 | } else { |
3712 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4225 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3713 | INVALID_OPCODE, 0); | 4226 | INVALID_OPCODE, 0); |
3714 | errsts = check_condition_result; | 4227 | errsts = check_condition_result; |
3715 | } | 4228 | } |
3716 | break; | 4229 | break; |
3717 | case MAINTENANCE_IN: | 4230 | case MAINTENANCE_IN: |
3718 | if (MI_REPORT_TARGET_PGS != cmd[1]) { | 4231 | if (MI_REPORT_TARGET_PGS != cmd[1]) { |
3719 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4232 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3720 | INVALID_OPCODE, 0); | 4233 | INVALID_OPCODE, 0); |
3721 | errsts = check_condition_result; | 4234 | errsts = check_condition_result; |
3722 | break; | 4235 | break; |
@@ -3729,7 +4242,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3729 | /* READ{10,12,16} and DIF Type 2 are natural enemies */ | 4242 | /* READ{10,12,16} and DIF Type 2 are natural enemies */ |
3730 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && | 4243 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && |
3731 | cmd[1] & 0xe0) { | 4244 | cmd[1] & 0xe0) { |
3732 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4245 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3733 | INVALID_COMMAND_OPCODE, 0); | 4246 | INVALID_COMMAND_OPCODE, 0); |
3734 | errsts = check_condition_result; | 4247 | errsts = check_condition_result; |
3735 | break; | 4248 | break; |
@@ -3743,7 +4256,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done) | |||
3743 | /* fall through */ | 4256 | /* fall through */ |
3744 | case READ_6: | 4257 | case READ_6: |
3745 | read: | 4258 | read: |
3746 | errsts = check_readiness(SCpnt, 0, devip); | 4259 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3747 | if (errsts) | 4260 | if (errsts) |
3748 | break; | 4261 | break; |
3749 | if (scsi_debug_fake_rw) | 4262 | if (scsi_debug_fake_rw) |
@@ -3753,20 +4266,21 @@ read: | |||
3753 | if (inj_short) | 4266 | if (inj_short) |
3754 | num /= 2; | 4267 | num /= 2; |
3755 | 4268 | ||
3756 | errsts = resp_read(SCpnt, lba, num, devip, ei_lba); | 4269 | errsts = resp_read(SCpnt, lba, num, ei_lba); |
3757 | if (inj_recovered && (0 == errsts)) { | 4270 | if (inj_recovered && (0 == errsts)) { |
3758 | mk_sense_buffer(devip, RECOVERED_ERROR, | 4271 | mk_sense_buffer(SCpnt, RECOVERED_ERROR, |
3759 | THRESHOLD_EXCEEDED, 0); | 4272 | THRESHOLD_EXCEEDED, 0); |
3760 | errsts = check_condition_result; | 4273 | errsts = check_condition_result; |
3761 | } else if (inj_transport && (0 == errsts)) { | 4274 | } else if (inj_transport && (0 == errsts)) { |
3762 | mk_sense_buffer(devip, ABORTED_COMMAND, | 4275 | mk_sense_buffer(SCpnt, ABORTED_COMMAND, |
3763 | TRANSPORT_PROBLEM, ACK_NAK_TO); | 4276 | TRANSPORT_PROBLEM, ACK_NAK_TO); |
3764 | errsts = check_condition_result; | 4277 | errsts = check_condition_result; |
3765 | } else if (inj_dif && (0 == errsts)) { | 4278 | } else if (inj_dif && (0 == errsts)) { |
3766 | mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, 1); | 4279 | /* Logical block guard check failed */ |
4280 | mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, 1); | ||
3767 | errsts = illegal_condition_result; | 4281 | errsts = illegal_condition_result; |
3768 | } else if (inj_dix && (0 == errsts)) { | 4282 | } else if (inj_dix && (0 == errsts)) { |
3769 | mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, 1); | 4283 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 1); |
3770 | errsts = illegal_condition_result; | 4284 | errsts = illegal_condition_result; |
3771 | } | 4285 | } |
3772 | break; | 4286 | break; |
@@ -3775,7 +4289,7 @@ read: | |||
3775 | errsts = resp_report_luns(SCpnt, devip); | 4289 | errsts = resp_report_luns(SCpnt, devip); |
3776 | break; | 4290 | break; |
3777 | case VERIFY: /* 10 byte SBC-2 command */ | 4291 | case VERIFY: /* 10 byte SBC-2 command */ |
3778 | errsts = check_readiness(SCpnt, 0, devip); | 4292 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3779 | break; | 4293 | break; |
3780 | case WRITE_16: | 4294 | case WRITE_16: |
3781 | case WRITE_12: | 4295 | case WRITE_12: |
@@ -3783,7 +4297,7 @@ read: | |||
3783 | /* WRITE{10,12,16} and DIF Type 2 are natural enemies */ | 4297 | /* WRITE{10,12,16} and DIF Type 2 are natural enemies */ |
3784 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && | 4298 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && |
3785 | cmd[1] & 0xe0) { | 4299 | cmd[1] & 0xe0) { |
3786 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4300 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3787 | INVALID_COMMAND_OPCODE, 0); | 4301 | INVALID_COMMAND_OPCODE, 0); |
3788 | errsts = check_condition_result; | 4302 | errsts = check_condition_result; |
3789 | break; | 4303 | break; |
@@ -3797,22 +4311,22 @@ read: | |||
3797 | /* fall through */ | 4311 | /* fall through */ |
3798 | case WRITE_6: | 4312 | case WRITE_6: |
3799 | write: | 4313 | write: |
3800 | errsts = check_readiness(SCpnt, 0, devip); | 4314 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3801 | if (errsts) | 4315 | if (errsts) |
3802 | break; | 4316 | break; |
3803 | if (scsi_debug_fake_rw) | 4317 | if (scsi_debug_fake_rw) |
3804 | break; | 4318 | break; |
3805 | get_data_transfer_info(cmd, &lba, &num, &ei_lba); | 4319 | get_data_transfer_info(cmd, &lba, &num, &ei_lba); |
3806 | errsts = resp_write(SCpnt, lba, num, devip, ei_lba); | 4320 | errsts = resp_write(SCpnt, lba, num, ei_lba); |
3807 | if (inj_recovered && (0 == errsts)) { | 4321 | if (inj_recovered && (0 == errsts)) { |
3808 | mk_sense_buffer(devip, RECOVERED_ERROR, | 4322 | mk_sense_buffer(SCpnt, RECOVERED_ERROR, |
3809 | THRESHOLD_EXCEEDED, 0); | 4323 | THRESHOLD_EXCEEDED, 0); |
3810 | errsts = check_condition_result; | 4324 | errsts = check_condition_result; |
3811 | } else if (inj_dif && (0 == errsts)) { | 4325 | } else if (inj_dif && (0 == errsts)) { |
3812 | mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, 1); | 4326 | mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, 1); |
3813 | errsts = illegal_condition_result; | 4327 | errsts = illegal_condition_result; |
3814 | } else if (inj_dix && (0 == errsts)) { | 4328 | } else if (inj_dix && (0 == errsts)) { |
3815 | mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, 1); | 4329 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 1); |
3816 | errsts = illegal_condition_result; | 4330 | errsts = illegal_condition_result; |
3817 | } | 4331 | } |
3818 | break; | 4332 | break; |
@@ -3821,7 +4335,7 @@ write: | |||
3821 | if (cmd[1] & 0x8) { | 4335 | if (cmd[1] & 0x8) { |
3822 | if ((*cmd == WRITE_SAME_16 && scsi_debug_lbpws == 0) || | 4336 | if ((*cmd == WRITE_SAME_16 && scsi_debug_lbpws == 0) || |
3823 | (*cmd == WRITE_SAME && scsi_debug_lbpws10 == 0)) { | 4337 | (*cmd == WRITE_SAME && scsi_debug_lbpws10 == 0)) { |
3824 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4338 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3825 | INVALID_FIELD_IN_CDB, 0); | 4339 | INVALID_FIELD_IN_CDB, 0); |
3826 | errsts = check_condition_result; | 4340 | errsts = check_condition_result; |
3827 | } else | 4341 | } else |
@@ -3829,19 +4343,23 @@ write: | |||
3829 | } | 4343 | } |
3830 | if (errsts) | 4344 | if (errsts) |
3831 | break; | 4345 | break; |
3832 | errsts = check_readiness(SCpnt, 0, devip); | 4346 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3833 | if (errsts) | 4347 | if (errsts) |
3834 | break; | 4348 | break; |
4349 | if (scsi_debug_fake_rw) | ||
4350 | break; | ||
3835 | get_data_transfer_info(cmd, &lba, &num, &ei_lba); | 4351 | get_data_transfer_info(cmd, &lba, &num, &ei_lba); |
3836 | errsts = resp_write_same(SCpnt, lba, num, devip, ei_lba, unmap); | 4352 | errsts = resp_write_same(SCpnt, lba, num, ei_lba, unmap); |
3837 | break; | 4353 | break; |
3838 | case UNMAP: | 4354 | case UNMAP: |
3839 | errsts = check_readiness(SCpnt, 0, devip); | 4355 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3840 | if (errsts) | 4356 | if (errsts) |
3841 | break; | 4357 | break; |
4358 | if (scsi_debug_fake_rw) | ||
4359 | break; | ||
3842 | 4360 | ||
3843 | if (scsi_debug_unmap_max_desc == 0 || scsi_debug_lbpu == 0) { | 4361 | if (scsi_debug_unmap_max_desc == 0 || scsi_debug_lbpu == 0) { |
3844 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4362 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3845 | INVALID_COMMAND_OPCODE, 0); | 4363 | INVALID_COMMAND_OPCODE, 0); |
3846 | errsts = check_condition_result; | 4364 | errsts = check_condition_result; |
3847 | } else | 4365 | } else |
@@ -3862,29 +4380,29 @@ write: | |||
3862 | break; | 4380 | break; |
3863 | case SYNCHRONIZE_CACHE: | 4381 | case SYNCHRONIZE_CACHE: |
3864 | delay_override = 1; | 4382 | delay_override = 1; |
3865 | errsts = check_readiness(SCpnt, 0, devip); | 4383 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3866 | break; | 4384 | break; |
3867 | case WRITE_BUFFER: | 4385 | case WRITE_BUFFER: |
3868 | errsts = check_readiness(SCpnt, 1, devip); | 4386 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); |
3869 | break; | 4387 | break; |
3870 | case XDWRITEREAD_10: | 4388 | case XDWRITEREAD_10: |
3871 | if (!scsi_bidi_cmnd(SCpnt)) { | 4389 | if (!scsi_bidi_cmnd(SCpnt)) { |
3872 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4390 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3873 | INVALID_FIELD_IN_CDB, 0); | 4391 | INVALID_FIELD_IN_CDB, 0); |
3874 | errsts = check_condition_result; | 4392 | errsts = check_condition_result; |
3875 | break; | 4393 | break; |
3876 | } | 4394 | } |
3877 | 4395 | ||
3878 | errsts = check_readiness(SCpnt, 0, devip); | 4396 | errsts = check_readiness(SCpnt, UAS_TUR, devip); |
3879 | if (errsts) | 4397 | if (errsts) |
3880 | break; | 4398 | break; |
3881 | if (scsi_debug_fake_rw) | 4399 | if (scsi_debug_fake_rw) |
3882 | break; | 4400 | break; |
3883 | get_data_transfer_info(cmd, &lba, &num, &ei_lba); | 4401 | get_data_transfer_info(cmd, &lba, &num, &ei_lba); |
3884 | errsts = resp_read(SCpnt, lba, num, devip, ei_lba); | 4402 | errsts = resp_read(SCpnt, lba, num, ei_lba); |
3885 | if (errsts) | 4403 | if (errsts) |
3886 | break; | 4404 | break; |
3887 | errsts = resp_write(SCpnt, lba, num, devip, ei_lba); | 4405 | errsts = resp_write(SCpnt, lba, num, ei_lba); |
3888 | if (errsts) | 4406 | if (errsts) |
3889 | break; | 4407 | break; |
3890 | errsts = resp_xdwriteread(SCpnt, lba, num, devip); | 4408 | errsts = resp_xdwriteread(SCpnt, lba, num, devip); |
@@ -3907,27 +4425,138 @@ write: | |||
3907 | } | 4425 | } |
3908 | } | 4426 | } |
3909 | 4427 | ||
3910 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 4428 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, |
3911 | INVALID_FIELD_IN_CDB, 0); | 4429 | INVALID_FIELD_IN_CDB, 0); |
3912 | errsts = check_condition_result; | 4430 | errsts = check_condition_result; |
3913 | break; | 4431 | break; |
3914 | 4432 | case 0x85: | |
4433 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
4434 | sdev_printk(KERN_INFO, SCpnt->device, | ||
4435 | "%s: ATA PASS-THROUGH(16) not supported\n", my_name); | ||
4436 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, | ||
4437 | INVALID_OPCODE, 0); | ||
4438 | errsts = check_condition_result; | ||
4439 | break; | ||
3915 | default: | 4440 | default: |
3916 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 4441 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
3917 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 4442 | sdev_printk(KERN_INFO, SCpnt->device, |
3918 | "supported\n", *cmd); | 4443 | "%s: Opcode: 0x%x not supported\n", |
3919 | errsts = check_readiness(SCpnt, 1, devip); | 4444 | my_name, *cmd); |
4445 | errsts = check_readiness(SCpnt, UAS_ONLY, devip); | ||
3920 | if (errsts) | 4446 | if (errsts) |
3921 | break; /* Unit attention takes precedence */ | 4447 | break; /* Unit attention takes precedence */ |
3922 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | 4448 | mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, INVALID_OPCODE, 0); |
3923 | errsts = check_condition_result; | 4449 | errsts = check_condition_result; |
3924 | break; | 4450 | break; |
3925 | } | 4451 | } |
3926 | return schedule_resp(SCpnt, devip, done, errsts, | 4452 | return schedule_resp(SCpnt, devip, errsts, |
3927 | (delay_override ? 0 : scsi_debug_delay)); | 4453 | (delay_override ? 0 : scsi_debug_delay)); |
3928 | } | 4454 | } |
3929 | 4455 | ||
3930 | static DEF_SCSI_QCMD(scsi_debug_queuecommand) | 4456 | static int |
4457 | sdebug_queuecommand_lock_or_not(struct Scsi_Host *shost, struct scsi_cmnd *cmd) | ||
4458 | { | ||
4459 | if (scsi_debug_host_lock) { | ||
4460 | unsigned long iflags; | ||
4461 | int rc; | ||
4462 | |||
4463 | spin_lock_irqsave(shost->host_lock, iflags); | ||
4464 | rc = scsi_debug_queuecommand(cmd); | ||
4465 | spin_unlock_irqrestore(shost->host_lock, iflags); | ||
4466 | return rc; | ||
4467 | } else | ||
4468 | return scsi_debug_queuecommand(cmd); | ||
4469 | } | ||
4470 | |||
4471 | static int | ||
4472 | sdebug_change_qdepth(struct scsi_device *sdev, int qdepth, int reason) | ||
4473 | { | ||
4474 | int num_in_q = 0; | ||
4475 | int bad = 0; | ||
4476 | unsigned long iflags; | ||
4477 | struct sdebug_dev_info *devip; | ||
4478 | |||
4479 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
4480 | devip = (struct sdebug_dev_info *)sdev->hostdata; | ||
4481 | if (NULL == devip) { | ||
4482 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
4483 | return -ENODEV; | ||
4484 | } | ||
4485 | num_in_q = atomic_read(&devip->num_in_q); | ||
4486 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
4487 | if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) { | ||
4488 | if (qdepth < 1) | ||
4489 | qdepth = 1; | ||
4490 | /* allow to exceed max host queued_arr elements for testing */ | ||
4491 | if (qdepth > SCSI_DEBUG_CANQUEUE + 10) | ||
4492 | qdepth = SCSI_DEBUG_CANQUEUE + 10; | ||
4493 | scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); | ||
4494 | } else if (reason == SCSI_QDEPTH_QFULL) | ||
4495 | scsi_track_queue_full(sdev, qdepth); | ||
4496 | else | ||
4497 | bad = 1; | ||
4498 | if (bad) | ||
4499 | sdev_printk(KERN_WARNING, sdev, | ||
4500 | "%s: unknown reason=0x%x\n", __func__, reason); | ||
4501 | if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) { | ||
4502 | if (SCSI_QDEPTH_QFULL == reason) | ||
4503 | sdev_printk(KERN_INFO, sdev, | ||
4504 | "%s: -> %d, num_in_q=%d, reason: queue full\n", | ||
4505 | __func__, qdepth, num_in_q); | ||
4506 | else { | ||
4507 | const char *cp; | ||
4508 | |||
4509 | switch (reason) { | ||
4510 | case SCSI_QDEPTH_DEFAULT: | ||
4511 | cp = "default (sysfs ?)"; | ||
4512 | break; | ||
4513 | case SCSI_QDEPTH_RAMP_UP: | ||
4514 | cp = "ramp up"; | ||
4515 | break; | ||
4516 | default: | ||
4517 | cp = "unknown"; | ||
4518 | break; | ||
4519 | } | ||
4520 | sdev_printk(KERN_INFO, sdev, | ||
4521 | "%s: qdepth=%d, num_in_q=%d, reason: %s\n", | ||
4522 | __func__, qdepth, num_in_q, cp); | ||
4523 | } | ||
4524 | } | ||
4525 | return sdev->queue_depth; | ||
4526 | } | ||
4527 | |||
4528 | static int | ||
4529 | sdebug_change_qtype(struct scsi_device *sdev, int qtype) | ||
4530 | { | ||
4531 | if (sdev->tagged_supported) { | ||
4532 | scsi_set_tag_type(sdev, qtype); | ||
4533 | if (qtype) | ||
4534 | scsi_activate_tcq(sdev, sdev->queue_depth); | ||
4535 | else | ||
4536 | scsi_deactivate_tcq(sdev, sdev->queue_depth); | ||
4537 | } else | ||
4538 | qtype = 0; | ||
4539 | if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) { | ||
4540 | const char *cp; | ||
4541 | |||
4542 | switch (qtype) { | ||
4543 | case 0: | ||
4544 | cp = "untagged"; | ||
4545 | break; | ||
4546 | case MSG_SIMPLE_TAG: | ||
4547 | cp = "simple tags"; | ||
4548 | break; | ||
4549 | case MSG_ORDERED_TAG: | ||
4550 | cp = "ordered tags"; | ||
4551 | break; | ||
4552 | default: | ||
4553 | cp = "unknown"; | ||
4554 | break; | ||
4555 | } | ||
4556 | sdev_printk(KERN_INFO, sdev, "%s: to %s\n", __func__, cp); | ||
4557 | } | ||
4558 | return qtype; | ||
4559 | } | ||
3931 | 4560 | ||
3932 | static struct scsi_host_template sdebug_driver_template = { | 4561 | static struct scsi_host_template sdebug_driver_template = { |
3933 | .show_info = scsi_debug_show_info, | 4562 | .show_info = scsi_debug_show_info, |
@@ -3939,16 +4568,18 @@ static struct scsi_host_template sdebug_driver_template = { | |||
3939 | .slave_configure = scsi_debug_slave_configure, | 4568 | .slave_configure = scsi_debug_slave_configure, |
3940 | .slave_destroy = scsi_debug_slave_destroy, | 4569 | .slave_destroy = scsi_debug_slave_destroy, |
3941 | .ioctl = scsi_debug_ioctl, | 4570 | .ioctl = scsi_debug_ioctl, |
3942 | .queuecommand = scsi_debug_queuecommand, | 4571 | .queuecommand = sdebug_queuecommand_lock_or_not, |
4572 | .change_queue_depth = sdebug_change_qdepth, | ||
4573 | .change_queue_type = sdebug_change_qtype, | ||
3943 | .eh_abort_handler = scsi_debug_abort, | 4574 | .eh_abort_handler = scsi_debug_abort, |
3944 | .eh_bus_reset_handler = scsi_debug_bus_reset, | ||
3945 | .eh_device_reset_handler = scsi_debug_device_reset, | 4575 | .eh_device_reset_handler = scsi_debug_device_reset, |
4576 | .eh_target_reset_handler = scsi_debug_target_reset, | ||
4577 | .eh_bus_reset_handler = scsi_debug_bus_reset, | ||
3946 | .eh_host_reset_handler = scsi_debug_host_reset, | 4578 | .eh_host_reset_handler = scsi_debug_host_reset, |
3947 | .bios_param = scsi_debug_biosparam, | ||
3948 | .can_queue = SCSI_DEBUG_CANQUEUE, | 4579 | .can_queue = SCSI_DEBUG_CANQUEUE, |
3949 | .this_id = 7, | 4580 | .this_id = 7, |
3950 | .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, | 4581 | .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, |
3951 | .cmd_per_lun = 16, | 4582 | .cmd_per_lun = DEF_CMD_PER_LUN, |
3952 | .max_sectors = -1U, | 4583 | .max_sectors = -1U, |
3953 | .use_clustering = DISABLE_CLUSTERING, | 4584 | .use_clustering = DISABLE_CLUSTERING, |
3954 | .module = THIS_MODULE, | 4585 | .module = THIS_MODULE, |
@@ -4033,8 +4664,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
4033 | } else | 4664 | } else |
4034 | scsi_scan_host(hpnt); | 4665 | scsi_scan_host(hpnt); |
4035 | 4666 | ||
4036 | 4667 | return error; | |
4037 | return error; | ||
4038 | } | 4668 | } |
4039 | 4669 | ||
4040 | static int sdebug_driver_remove(struct device * dev) | 4670 | static int sdebug_driver_remove(struct device * dev) |