aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDouglas Gilbert <dougg@torque.net>2007-01-05 00:05:25 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-01-13 14:52:37 -0500
commit6f3cbf552e0557a463ad421f07b2e873a608406f (patch)
tree150e99a4d625ede99cb8356932f85ae726510304 /drivers
parentd780c3bf2150264947870bb68c057c26c2aff7cc (diff)
[SCSI] scsi_debug: error processing
After discussions in the thread titled: [PATCH] scsi_debug: illegal blocking memory allocation here is a patch containing the discussed fix and some other fixes and additions. The patch is against lk 2.6.20-rc3 . The version is bumped to 1.81 . ChangeLog: - Change several GFP_KERNEL allocations to GFP_ATOMIC as they can be called from queuecommand() context - check above allocation returns and if out of memory report DID_REQUEUE in two cases, DID_NO_CONNECT in another, and fail slave configure() in another - add support for WRITE BUFFER command - add aborted_command error injection support (opts mask 0x10), similar mechanism to recovered_error injection. Signed-off-by: Douglas Gilbert <dougg@torque.net> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_debug.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 30ee3d72c021..5adbbeedec38 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -51,10 +51,10 @@
51#include "scsi_logging.h" 51#include "scsi_logging.h"
52#include "scsi_debug.h" 52#include "scsi_debug.h"
53 53
54#define SCSI_DEBUG_VERSION "1.80" 54#define SCSI_DEBUG_VERSION "1.81"
55static const char * scsi_debug_version_date = "20061018"; 55static const char * scsi_debug_version_date = "20070104";
56 56
57/* Additional Sense Code (ASC) used */ 57/* Additional Sense Code (ASC) */
58#define NO_ADDITIONAL_SENSE 0x0 58#define NO_ADDITIONAL_SENSE 0x0
59#define LOGICAL_UNIT_NOT_READY 0x4 59#define LOGICAL_UNIT_NOT_READY 0x4
60#define UNRECOVERED_READ_ERR 0x11 60#define UNRECOVERED_READ_ERR 0x11
@@ -65,9 +65,13 @@ static const char * scsi_debug_version_date = "20061018";
65#define INVALID_FIELD_IN_PARAM_LIST 0x26 65#define INVALID_FIELD_IN_PARAM_LIST 0x26
66#define POWERON_RESET 0x29 66#define POWERON_RESET 0x29
67#define SAVING_PARAMS_UNSUP 0x39 67#define SAVING_PARAMS_UNSUP 0x39
68#define TRANSPORT_PROBLEM 0x4b
68#define THRESHOLD_EXCEEDED 0x5d 69#define THRESHOLD_EXCEEDED 0x5d
69#define LOW_POWER_COND_ON 0x5e 70#define LOW_POWER_COND_ON 0x5e
70 71
72/* Additional Sense Code Qualifier (ASCQ) */
73#define ACK_NAK_TO 0x3
74
71#define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ 75#define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
72 76
73/* Default values for driver parameters */ 77/* Default values for driver parameters */
@@ -95,15 +99,20 @@ static const char * scsi_debug_version_date = "20061018";
95#define SCSI_DEBUG_OPT_MEDIUM_ERR 2 99#define SCSI_DEBUG_OPT_MEDIUM_ERR 2
96#define SCSI_DEBUG_OPT_TIMEOUT 4 100#define SCSI_DEBUG_OPT_TIMEOUT 4
97#define SCSI_DEBUG_OPT_RECOVERED_ERR 8 101#define SCSI_DEBUG_OPT_RECOVERED_ERR 8
102#define SCSI_DEBUG_OPT_TRANSPORT_ERR 16
98/* When "every_nth" > 0 then modulo "every_nth" commands: 103/* When "every_nth" > 0 then modulo "every_nth" commands:
99 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set 104 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
100 * - a RECOVERED_ERROR is simulated on successful read and write 105 * - a RECOVERED_ERROR is simulated on successful read and write
101 * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set. 106 * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
107 * - a TRANSPORT_ERROR is simulated on successful read and write
108 * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
102 * 109 *
103 * When "every_nth" < 0 then after "- every_nth" commands: 110 * When "every_nth" < 0 then after "- every_nth" commands:
104 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set 111 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
105 * - a RECOVERED_ERROR is simulated on successful read and write 112 * - a RECOVERED_ERROR is simulated on successful read and write
106 * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set. 113 * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
114 * - a TRANSPORT_ERROR is simulated on successful read and write
115 * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
107 * This will continue until some other action occurs (e.g. the user 116 * This will continue until some other action occurs (e.g. the user
108 * writing a new value (other than -1 or 1) to every_nth via sysfs). 117 * writing a new value (other than -1 or 1) to every_nth via sysfs).
109 */ 118 */
@@ -315,6 +324,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
315 int target = SCpnt->device->id; 324 int target = SCpnt->device->id;
316 struct sdebug_dev_info * devip = NULL; 325 struct sdebug_dev_info * devip = NULL;
317 int inj_recovered = 0; 326 int inj_recovered = 0;
327 int inj_transport = 0;
318 int delay_override = 0; 328 int delay_override = 0;
319 329
320 if (done == NULL) 330 if (done == NULL)
@@ -352,6 +362,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
352 return 0; /* ignore command causing timeout */ 362 return 0; /* ignore command causing timeout */
353 else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) 363 else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
354 inj_recovered = 1; /* to reads and writes below */ 364 inj_recovered = 1; /* to reads and writes below */
365 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
366 inj_transport = 1; /* to reads and writes below */
355 } 367 }
356 368
357 if (devip->wlun) { 369 if (devip->wlun) {
@@ -468,7 +480,11 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
468 mk_sense_buffer(devip, RECOVERED_ERROR, 480 mk_sense_buffer(devip, RECOVERED_ERROR,
469 THRESHOLD_EXCEEDED, 0); 481 THRESHOLD_EXCEEDED, 0);
470 errsts = check_condition_result; 482 errsts = check_condition_result;
471 } 483 } else if (inj_transport && (0 == errsts)) {
484 mk_sense_buffer(devip, ABORTED_COMMAND,
485 TRANSPORT_PROBLEM, ACK_NAK_TO);
486 errsts = check_condition_result;
487 }
472 break; 488 break;
473 case REPORT_LUNS: /* mandatory, ignore unit attention */ 489 case REPORT_LUNS: /* mandatory, ignore unit attention */
474 delay_override = 1; 490 delay_override = 1;
@@ -531,6 +547,9 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
531 delay_override = 1; 547 delay_override = 1;
532 errsts = check_readiness(SCpnt, 0, devip); 548 errsts = check_readiness(SCpnt, 0, devip);
533 break; 549 break;
550 case WRITE_BUFFER:
551 errsts = check_readiness(SCpnt, 1, devip);
552 break;
534 default: 553 default:
535 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 554 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
536 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " 555 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
@@ -954,7 +973,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
954 int alloc_len, n, ret; 973 int alloc_len, n, ret;
955 974
956 alloc_len = (cmd[3] << 8) + cmd[4]; 975 alloc_len = (cmd[3] << 8) + cmd[4];
957 arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL); 976 arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
977 if (! arr)
978 return DID_REQUEUE << 16;
958 if (devip->wlun) 979 if (devip->wlun)
959 pq_pdt = 0x1e; /* present, wlun */ 980 pq_pdt = 0x1e; /* present, wlun */
960 else if (scsi_debug_no_lun_0 && (0 == devip->lun)) 981 else if (scsi_debug_no_lun_0 && (0 == devip->lun))
@@ -1217,7 +1238,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd * scp,
1217 alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8) 1238 alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
1218 + cmd[9]); 1239 + cmd[9]);
1219 1240
1220 arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL); 1241 arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC);
1242 if (! arr)
1243 return DID_REQUEUE << 16;
1221 /* 1244 /*
1222 * EVPD page 0x88 states we have two ports, one 1245 * EVPD page 0x88 states we have two ports, one
1223 * real and a fake port with no device connected. 1246 * real and a fake port with no device connected.
@@ -1996,6 +2019,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp)
1996 if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) 2019 if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
1997 sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; 2020 sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
1998 devip = devInfoReg(sdp); 2021 devip = devInfoReg(sdp);
2022 if (NULL == devip)
2023 return 1; /* no resources, will be marked offline */
1999 sdp->hostdata = devip; 2024 sdp->hostdata = devip;
2000 if (sdp->host->cmd_per_lun) 2025 if (sdp->host->cmd_per_lun)
2001 scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, 2026 scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
@@ -2044,7 +2069,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
2044 } 2069 }
2045 } 2070 }
2046 if (NULL == open_devip) { /* try and make a new one */ 2071 if (NULL == open_devip) { /* try and make a new one */
2047 open_devip = kzalloc(sizeof(*open_devip),GFP_KERNEL); 2072 open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC);
2048 if (NULL == open_devip) { 2073 if (NULL == open_devip) {
2049 printk(KERN_ERR "%s: out of memory at line %d\n", 2074 printk(KERN_ERR "%s: out of memory at line %d\n",
2050 __FUNCTION__, __LINE__); 2075 __FUNCTION__, __LINE__);
@@ -2388,7 +2413,7 @@ MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)");
2388MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); 2413MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
2389MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); 2414MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
2390MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); 2415MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)");
2391MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)"); 2416MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)");
2392MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); 2417MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
2393MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); 2418MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
2394MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); 2419MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
@@ -2943,7 +2968,6 @@ static int sdebug_add_adapter(void)
2943 struct list_head *lh, *lh_sf; 2968 struct list_head *lh, *lh_sf;
2944 2969
2945 sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); 2970 sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL);
2946
2947 if (NULL == sdbg_host) { 2971 if (NULL == sdbg_host) {
2948 printk(KERN_ERR "%s: out of memory at line %d\n", 2972 printk(KERN_ERR "%s: out of memory at line %d\n",
2949 __FUNCTION__, __LINE__); 2973 __FUNCTION__, __LINE__);