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) |
