* [PATCH 1/5] scsi_debug: remove temporary hack around sscanf for negative values
@ 2008-03-20 2:09 FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 2/5] scsi_debug: create new scsi_debug devices at a single place FUJITA Tomonori
2008-03-20 14:53 ` [PATCHes 1,2,3,4,5] scsi_debug Douglas Gilbert
0 siblings, 2 replies; 6+ messages in thread
From: FUJITA Tomonori @ 2008-03-20 2:09 UTC (permalink / raw)
To: linux-scsi; +Cc: tomof, FUJITA Tomonori, Douglas Gilbert, James Bottomley
sscanf can handle negative values.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Douglas Gilbert <dougg@torque.net>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/scsi/scsi_debug.c | 17 +++--------------
1 files changed, 3 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 7a2a3ed..2a388d0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -2681,21 +2681,10 @@ static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
static ssize_t sdebug_add_host_store(struct device_driver * ddp,
const char * buf, size_t count)
{
- int delta_hosts;
- char work[20];
+ int delta_hosts;
- if (1 != sscanf(buf, "%10s", work))
+ if (sscanf(buf, "%d", &delta_hosts) != 1)
return -EINVAL;
- { /* temporary hack around sscanf() problem with -ve nums */
- int neg = 0;
-
- if ('-' == *work)
- neg = 1;
- if (1 != sscanf(work + neg, "%d", &delta_hosts))
- return -EINVAL;
- if (neg)
- delta_hosts = -delta_hosts;
- }
if (delta_hosts > 0) {
do {
sdebug_add_adapter();
@@ -2707,7 +2696,7 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
}
return count;
}
-DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
+DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
sdebug_add_host_store);
static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp,
--
1.5.3.7
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] scsi_debug: create new scsi_debug devices at a single place
2008-03-20 2:09 [PATCH 1/5] scsi_debug: remove temporary hack around sscanf for negative values FUJITA Tomonori
@ 2008-03-20 2:09 ` FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 3/5] scsi_debug: remove unnecessary condition test in devInfoReg FUJITA Tomonori
2008-03-20 14:53 ` [PATCHes 1,2,3,4,5] scsi_debug Douglas Gilbert
1 sibling, 1 reply; 6+ messages in thread
From: FUJITA Tomonori @ 2008-03-20 2:09 UTC (permalink / raw)
To: linux-scsi; +Cc: tomof, FUJITA Tomonori, Douglas Gilbert, James Bottomley
Two functions, sdebug_add_adapter and devInfoReg, creates new
scsi_debug devices. To simplify the code, this patch adds a new helper
function to create new scsi_debug devices (sdebug_device_create) and
converts both functions to use it.
I plan to add more to scsi_debug devices (e.g. using a thread for a
scsi_debug device for scalability testings). This patch enable me to
add such to just the new helper function instead of touching two
functions, sdebug_add_adapter and devInfoReg.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Douglas Gilbert <dougg@torque.net>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/scsi/scsi_debug.c | 29 ++++++++++++++++++-----------
1 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 2a388d0..161af1d 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -2014,6 +2014,19 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp)
}
}
+struct sdebug_dev_info *sdebug_device_create(struct sdebug_host_info *sdbg_host,
+ gfp_t flags)
+{
+ struct sdebug_dev_info *devip;
+
+ devip = kzalloc(sizeof(*devip), flags);
+ if (devip) {
+ devip->sdbg_host = sdbg_host;
+ list_add_tail(&devip->dev_list, &sdbg_host->dev_info_list);
+ }
+ return devip;
+}
+
static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
{
struct sdebug_host_info * sdbg_host;
@@ -2038,16 +2051,13 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
open_devip = devip;
}
}
- if (NULL == open_devip) { /* try and make a new one */
- open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC);
- if (NULL == open_devip) {
+ if (!open_devip) { /* try and make a new one */
+ open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC);
+ if (!open_devip) {
printk(KERN_ERR "%s: out of memory at line %d\n",
__FUNCTION__, __LINE__);
return NULL;
}
- open_devip->sdbg_host = sdbg_host;
- list_add_tail(&open_devip->dev_list,
- &sdbg_host->dev_info_list);
}
if (open_devip) {
open_devip->channel = sdev->channel;
@@ -2935,16 +2945,13 @@ static int sdebug_add_adapter(void)
devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns;
for (k = 0; k < devs_per_host; k++) {
- sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL);
- if (NULL == sdbg_devinfo) {
+ sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL);
+ if (!sdbg_devinfo) {
printk(KERN_ERR "%s: out of memory at line %d\n",
__FUNCTION__, __LINE__);
error = -ENOMEM;
goto clean;
}
- sdbg_devinfo->sdbg_host = sdbg_host;
- list_add_tail(&sdbg_devinfo->dev_list,
- &sdbg_host->dev_info_list);
}
spin_lock(&sdebug_host_list_lock);
--
1.5.3.7
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] scsi_debug: remove unnecessary condition test in devInfoReg
2008-03-20 2:09 ` [PATCH 2/5] scsi_debug: create new scsi_debug devices at a single place FUJITA Tomonori
@ 2008-03-20 2:09 ` FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 4/5] scsi_debug: use list_for_each_entry_safe FUJITA Tomonori
0 siblings, 1 reply; 6+ messages in thread
From: FUJITA Tomonori @ 2008-03-20 2:09 UTC (permalink / raw)
To: linux-scsi; +Cc: tomof, FUJITA Tomonori, Douglas Gilbert, James Bottomley
open_devip is always non NULL.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Douglas Gilbert <dougg@torque.net>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/scsi/scsi_debug.c | 37 ++++++++++++++++++-------------------
1 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 161af1d..1a91063 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -2059,25 +2059,24 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
return NULL;
}
}
- if (open_devip) {
- open_devip->channel = sdev->channel;
- open_devip->target = sdev->id;
- open_devip->lun = sdev->lun;
- open_devip->sdbg_host = sdbg_host;
- open_devip->reset = 1;
- open_devip->used = 1;
- memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN);
- if (scsi_debug_dsense)
- open_devip->sense_buff[0] = 0x72;
- else {
- open_devip->sense_buff[0] = 0x70;
- open_devip->sense_buff[7] = 0xa;
- }
- if (sdev->lun == SAM2_WLUN_REPORT_LUNS)
- open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff;
- return open_devip;
- }
- return NULL;
+
+ open_devip->channel = sdev->channel;
+ open_devip->target = sdev->id;
+ open_devip->lun = sdev->lun;
+ open_devip->sdbg_host = sdbg_host;
+ open_devip->reset = 1;
+ open_devip->used = 1;
+ memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN);
+ if (scsi_debug_dsense)
+ open_devip->sense_buff[0] = 0x72;
+ else {
+ open_devip->sense_buff[0] = 0x70;
+ open_devip->sense_buff[7] = 0xa;
+ }
+ if (sdev->lun == SAM2_WLUN_REPORT_LUNS)
+ open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff;
+
+ return open_devip;
}
static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
--
1.5.3.7
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] scsi_debug: use list_for_each_entry_safe
2008-03-20 2:09 ` [PATCH 3/5] scsi_debug: remove unnecessary condition test in devInfoReg FUJITA Tomonori
@ 2008-03-20 2:09 ` FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 5/5] scsi_debug: remove unnecessary function declarations FUJITA Tomonori
0 siblings, 1 reply; 6+ messages in thread
From: FUJITA Tomonori @ 2008-03-20 2:09 UTC (permalink / raw)
To: linux-scsi; +Cc: tomof, FUJITA Tomonori, Douglas Gilbert, James Bottomley
This replaces list_for_each_safe and list_entry with
list_for_each_entry_safe.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Douglas Gilbert <dougg@torque.net>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/scsi/scsi_debug.c | 16 ++++++----------
1 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1a91063..681b591 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -2930,8 +2930,7 @@ static int sdebug_add_adapter(void)
int k, devs_per_host;
int error = 0;
struct sdebug_host_info *sdbg_host;
- struct sdebug_dev_info *sdbg_devinfo;
- struct list_head *lh, *lh_sf;
+ struct sdebug_dev_info *sdbg_devinfo, *tmp;
sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL);
if (NULL == sdbg_host) {
@@ -2971,9 +2970,8 @@ static int sdebug_add_adapter(void)
return error;
clean:
- list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
- sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
- dev_list);
+ list_for_each_entry_safe(sdbg_devinfo, tmp, &sdbg_host->dev_info_list,
+ dev_list) {
list_del(&sdbg_devinfo->dev_list);
kfree(sdbg_devinfo);
}
@@ -3062,9 +3060,8 @@ static int sdebug_driver_probe(struct device * dev)
static int sdebug_driver_remove(struct device * dev)
{
- struct list_head *lh, *lh_sf;
struct sdebug_host_info *sdbg_host;
- struct sdebug_dev_info *sdbg_devinfo;
+ struct sdebug_dev_info *sdbg_devinfo, *tmp;
sdbg_host = to_sdebug_host(dev);
@@ -3076,9 +3073,8 @@ static int sdebug_driver_remove(struct device * dev)
scsi_remove_host(sdbg_host->shost);
- list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
- sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
- dev_list);
+ list_for_each_entry_safe(sdbg_devinfo, tmp, &sdbg_host->dev_info_list,
+ dev_list) {
list_del(&sdbg_devinfo->dev_list);
kfree(sdbg_devinfo);
}
--
1.5.3.7
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] scsi_debug: remove unnecessary function declarations
2008-03-20 2:09 ` [PATCH 4/5] scsi_debug: use list_for_each_entry_safe FUJITA Tomonori
@ 2008-03-20 2:09 ` FUJITA Tomonori
0 siblings, 0 replies; 6+ messages in thread
From: FUJITA Tomonori @ 2008-03-20 2:09 UTC (permalink / raw)
To: linux-scsi; +Cc: tomof, FUJITA Tomonori, Douglas Gilbert, James Bottomley
This patch removes lots of function declarations with moving
scsi_debug_queuecommand. This cleans up scsi_debug_queuecommand a bit
to silence checkpatch.pl
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Douglas Gilbert <dougg@torque.net>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/scsi/scsi_debug.c | 507 +++++++++++++++++++++------------------------
1 files changed, 233 insertions(+), 274 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 681b591..4f4c5b7 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -235,56 +235,11 @@ static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
0, 0, 0x0, 0x0};
-/* function declarations */
-static int resp_inquiry(struct scsi_cmnd * SCpnt, int target,
- struct sdebug_dev_info * devip);
-static int resp_requests(struct scsi_cmnd * SCpnt,
- struct sdebug_dev_info * devip);
-static int resp_start_stop(struct scsi_cmnd * scp,
- struct sdebug_dev_info * devip);
-static int resp_report_tgtpgs(struct scsi_cmnd * scp,
- struct sdebug_dev_info * devip);
-static int resp_readcap(struct scsi_cmnd * SCpnt,
- struct sdebug_dev_info * devip);
-static int resp_readcap16(struct scsi_cmnd * SCpnt,
- struct sdebug_dev_info * devip);
-static int resp_mode_sense(struct scsi_cmnd * scp, int target,
- struct sdebug_dev_info * devip);
-static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
- struct sdebug_dev_info * devip);
-static int resp_log_sense(struct scsi_cmnd * scp,
- struct sdebug_dev_info * devip);
-static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info * devip);
-static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info * devip);
-static int resp_report_luns(struct scsi_cmnd * SCpnt,
- struct sdebug_dev_info * devip);
-static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info *devip);
-static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
- int arr_len);
-static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
- int max_arr_len);
-static void timer_intr_handler(unsigned long);
static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
int asc, int asq);
-static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only,
- struct sdebug_dev_info * devip);
-static int schedule_resp(struct scsi_cmnd * cmnd,
- struct sdebug_dev_info * devip,
- done_funct_t done, int scsi_result, int delta_jiff);
-static void __init sdebug_build_parts(unsigned char * ramp);
-static void __init init_all_queued(void);
static void stop_all_queued(void);
static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
-static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
- int target_dev_id, int dev_id_num,
- const char * dev_id_str, int dev_id_str_len);
-static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
-static int do_create_driverfs_files(void);
-static void do_remove_driverfs_files(void);
static int sdebug_add_adapter(void);
static void sdebug_remove_adapter(void);
@@ -330,235 +285,6 @@ static void get_data_transfer_info(unsigned char *cmd,
}
}
-static
-int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
-{
- unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
- int len, k;
- unsigned int num;
- unsigned long long lba;
- int errsts = 0;
- int target = SCpnt->device->id;
- struct sdebug_dev_info * devip = NULL;
- int inj_recovered = 0;
- int inj_transport = 0;
- int delay_override = 0;
-
- scsi_set_resid(SCpnt, 0);
- if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
- printk(KERN_INFO "scsi_debug: cmd ");
- for (k = 0, len = SCpnt->cmd_len; k < len; ++k)
- printk("%02x ", (int)cmd[k]);
- printk("\n");
- }
-
- if (target == SCpnt->device->host->hostt->this_id) {
- printk(KERN_INFO "scsi_debug: initiator's id used as "
- "target!\n");
- return schedule_resp(SCpnt, NULL, done,
- DID_NO_CONNECT << 16, 0);
- }
-
- if ((SCpnt->device->lun >= scsi_debug_max_luns) &&
- (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS))
- return schedule_resp(SCpnt, NULL, done,
- DID_NO_CONNECT << 16, 0);
- devip = devInfoReg(SCpnt->device);
- if (NULL == devip)
- return schedule_resp(SCpnt, NULL, done,
- DID_NO_CONNECT << 16, 0);
-
- if ((scsi_debug_every_nth != 0) &&
- (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
- scsi_debug_cmnd_count = 0;
- if (scsi_debug_every_nth < -1)
- scsi_debug_every_nth = -1;
- if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
- return 0; /* ignore command causing timeout */
- else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
- inj_recovered = 1; /* to reads and writes below */
- else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
- inj_transport = 1; /* to reads and writes below */
- }
-
- if (devip->wlun) {
- switch (*cmd) {
- case INQUIRY:
- case REQUEST_SENSE:
- case TEST_UNIT_READY:
- case REPORT_LUNS:
- break; /* only allowable wlun commands */
- default:
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: Opcode: 0x%x "
- "not supported for wlun\n", *cmd);
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
- INVALID_OPCODE, 0);
- errsts = check_condition_result;
- return schedule_resp(SCpnt, devip, done, errsts,
- 0);
- }
- }
-
- switch (*cmd) {
- case INQUIRY: /* mandatory, ignore unit attention */
- delay_override = 1;
- errsts = resp_inquiry(SCpnt, target, devip);
- break;
- case REQUEST_SENSE: /* mandatory, ignore unit attention */
- delay_override = 1;
- errsts = resp_requests(SCpnt, devip);
- break;
- case REZERO_UNIT: /* actually this is REWIND for SSC */
- case START_STOP:
- errsts = resp_start_stop(SCpnt, devip);
- break;
- case ALLOW_MEDIUM_REMOVAL:
- if ((errsts = check_readiness(SCpnt, 1, devip)))
- break;
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: Medium removal %s\n",
- cmd[4] ? "inhibited" : "enabled");
- break;
- case SEND_DIAGNOSTIC: /* mandatory */
- errsts = check_readiness(SCpnt, 1, devip);
- break;
- case TEST_UNIT_READY: /* mandatory */
- delay_override = 1;
- errsts = check_readiness(SCpnt, 0, devip);
- break;
- case RESERVE:
- errsts = check_readiness(SCpnt, 1, devip);
- break;
- case RESERVE_10:
- errsts = check_readiness(SCpnt, 1, devip);
- break;
- case RELEASE:
- errsts = check_readiness(SCpnt, 1, devip);
- break;
- case RELEASE_10:
- errsts = check_readiness(SCpnt, 1, devip);
- break;
- case READ_CAPACITY:
- errsts = resp_readcap(SCpnt, devip);
- break;
- case SERVICE_ACTION_IN:
- if (SAI_READ_CAPACITY_16 != cmd[1]) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
- INVALID_OPCODE, 0);
- errsts = check_condition_result;
- break;
- }
- errsts = resp_readcap16(SCpnt, devip);
- break;
- case MAINTENANCE_IN:
- if (MI_REPORT_TARGET_PGS != cmd[1]) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
- INVALID_OPCODE, 0);
- errsts = check_condition_result;
- break;
- }
- errsts = resp_report_tgtpgs(SCpnt, devip);
- break;
- case READ_16:
- case READ_12:
- case READ_10:
- case READ_6:
- if ((errsts = check_readiness(SCpnt, 0, devip)))
- break;
- if (scsi_debug_fake_rw)
- break;
- get_data_transfer_info(cmd, &lba, &num);
- errsts = resp_read(SCpnt, lba, num, devip);
- if (inj_recovered && (0 == errsts)) {
- mk_sense_buffer(devip, RECOVERED_ERROR,
- THRESHOLD_EXCEEDED, 0);
- errsts = check_condition_result;
- } else if (inj_transport && (0 == errsts)) {
- mk_sense_buffer(devip, ABORTED_COMMAND,
- TRANSPORT_PROBLEM, ACK_NAK_TO);
- errsts = check_condition_result;
- }
- break;
- case REPORT_LUNS: /* mandatory, ignore unit attention */
- delay_override = 1;
- errsts = resp_report_luns(SCpnt, devip);
- break;
- case VERIFY: /* 10 byte SBC-2 command */
- errsts = check_readiness(SCpnt, 0, devip);
- break;
- case WRITE_16:
- case WRITE_12:
- case WRITE_10:
- case WRITE_6:
- if ((errsts = check_readiness(SCpnt, 0, devip)))
- break;
- if (scsi_debug_fake_rw)
- break;
- get_data_transfer_info(cmd, &lba, &num);
- errsts = resp_write(SCpnt, lba, num, devip);
- if (inj_recovered && (0 == errsts)) {
- mk_sense_buffer(devip, RECOVERED_ERROR,
- THRESHOLD_EXCEEDED, 0);
- errsts = check_condition_result;
- }
- break;
- case MODE_SENSE:
- case MODE_SENSE_10:
- errsts = resp_mode_sense(SCpnt, target, devip);
- break;
- case MODE_SELECT:
- errsts = resp_mode_select(SCpnt, 1, devip);
- break;
- case MODE_SELECT_10:
- errsts = resp_mode_select(SCpnt, 0, devip);
- break;
- case LOG_SENSE:
- errsts = resp_log_sense(SCpnt, devip);
- break;
- case SYNCHRONIZE_CACHE:
- delay_override = 1;
- errsts = check_readiness(SCpnt, 0, devip);
- break;
- case WRITE_BUFFER:
- errsts = check_readiness(SCpnt, 1, devip);
- break;
- case XDWRITEREAD_10:
- if (!scsi_bidi_cmnd(SCpnt)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
- INVALID_FIELD_IN_CDB, 0);
- errsts = check_condition_result;
- break;
- }
-
- errsts = check_readiness(SCpnt, 0, devip);
- if (errsts)
- break;
- if (scsi_debug_fake_rw)
- break;
- get_data_transfer_info(cmd, &lba, &num);
- errsts = resp_read(SCpnt, lba, num, devip);
- if (errsts)
- break;
- errsts = resp_write(SCpnt, lba, num, devip);
- if (errsts)
- break;
- errsts = resp_xdwriteread(SCpnt, lba, num, devip);
- break;
- default:
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
- "supported\n", *cmd);
- if ((errsts = check_readiness(SCpnt, 1, devip)))
- break; /* Unit attention takes precedence */
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
- errsts = check_condition_result;
- break;
- }
- return schedule_resp(SCpnt, devip, done, errsts,
- (delay_override ? 0 : scsi_debug_delay));
-}
-
static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
{
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
@@ -2999,6 +2725,239 @@ static void sdebug_remove_adapter(void)
--scsi_debug_add_host;
}
+static
+int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
+{
+ unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
+ int len, k;
+ unsigned int num;
+ unsigned long long lba;
+ int errsts = 0;
+ int target = SCpnt->device->id;
+ struct sdebug_dev_info *devip = NULL;
+ int inj_recovered = 0;
+ int inj_transport = 0;
+ int delay_override = 0;
+
+ scsi_set_resid(SCpnt, 0);
+ if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
+ printk(KERN_INFO "scsi_debug: cmd ");
+ for (k = 0, len = SCpnt->cmd_len; k < len; ++k)
+ printk("%02x ", (int)cmd[k]);
+ printk("\n");
+ }
+
+ if (target == SCpnt->device->host->hostt->this_id) {
+ printk(KERN_INFO "scsi_debug: initiator's id used as "
+ "target!\n");
+ return schedule_resp(SCpnt, NULL, done,
+ DID_NO_CONNECT << 16, 0);
+ }
+
+ if ((SCpnt->device->lun >= scsi_debug_max_luns) &&
+ (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS))
+ return schedule_resp(SCpnt, NULL, done,
+ DID_NO_CONNECT << 16, 0);
+ devip = devInfoReg(SCpnt->device);
+ if (NULL == devip)
+ return schedule_resp(SCpnt, NULL, done,
+ DID_NO_CONNECT << 16, 0);
+
+ if ((scsi_debug_every_nth != 0) &&
+ (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
+ scsi_debug_cmnd_count = 0;
+ if (scsi_debug_every_nth < -1)
+ scsi_debug_every_nth = -1;
+ if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
+ return 0; /* ignore command causing timeout */
+ else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
+ inj_recovered = 1; /* to reads and writes below */
+ else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
+ inj_transport = 1; /* to reads and writes below */
+ }
+
+ if (devip->wlun) {
+ switch (*cmd) {
+ case INQUIRY:
+ case REQUEST_SENSE:
+ case TEST_UNIT_READY:
+ case REPORT_LUNS:
+ break; /* only allowable wlun commands */
+ default:
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: Opcode: 0x%x "
+ "not supported for wlun\n", *cmd);
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ INVALID_OPCODE, 0);
+ errsts = check_condition_result;
+ return schedule_resp(SCpnt, devip, done, errsts,
+ 0);
+ }
+ }
+
+ switch (*cmd) {
+ case INQUIRY: /* mandatory, ignore unit attention */
+ delay_override = 1;
+ errsts = resp_inquiry(SCpnt, target, devip);
+ break;
+ case REQUEST_SENSE: /* mandatory, ignore unit attention */
+ delay_override = 1;
+ errsts = resp_requests(SCpnt, devip);
+ break;
+ case REZERO_UNIT: /* actually this is REWIND for SSC */
+ case START_STOP:
+ errsts = resp_start_stop(SCpnt, devip);
+ break;
+ case ALLOW_MEDIUM_REMOVAL:
+ errsts = check_readiness(SCpnt, 1, devip);
+ if (errsts)
+ break;
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: Medium removal %s\n",
+ cmd[4] ? "inhibited" : "enabled");
+ break;
+ case SEND_DIAGNOSTIC: /* mandatory */
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
+ case TEST_UNIT_READY: /* mandatory */
+ delay_override = 1;
+ errsts = check_readiness(SCpnt, 0, devip);
+ break;
+ case RESERVE:
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
+ case RESERVE_10:
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
+ case RELEASE:
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
+ case RELEASE_10:
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
+ case READ_CAPACITY:
+ errsts = resp_readcap(SCpnt, devip);
+ break;
+ case SERVICE_ACTION_IN:
+ if (SAI_READ_CAPACITY_16 != cmd[1]) {
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ INVALID_OPCODE, 0);
+ errsts = check_condition_result;
+ break;
+ }
+ errsts = resp_readcap16(SCpnt, devip);
+ break;
+ case MAINTENANCE_IN:
+ if (MI_REPORT_TARGET_PGS != cmd[1]) {
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ INVALID_OPCODE, 0);
+ errsts = check_condition_result;
+ break;
+ }
+ errsts = resp_report_tgtpgs(SCpnt, devip);
+ break;
+ case READ_16:
+ case READ_12:
+ case READ_10:
+ case READ_6:
+ errsts = check_readiness(SCpnt, 0, devip);
+ if (errsts)
+ break;
+ if (scsi_debug_fake_rw)
+ break;
+ get_data_transfer_info(cmd, &lba, &num);
+ errsts = resp_read(SCpnt, lba, num, devip);
+ if (inj_recovered && (0 == errsts)) {
+ mk_sense_buffer(devip, RECOVERED_ERROR,
+ THRESHOLD_EXCEEDED, 0);
+ errsts = check_condition_result;
+ } else if (inj_transport && (0 == errsts)) {
+ mk_sense_buffer(devip, ABORTED_COMMAND,
+ TRANSPORT_PROBLEM, ACK_NAK_TO);
+ errsts = check_condition_result;
+ }
+ break;
+ case REPORT_LUNS: /* mandatory, ignore unit attention */
+ delay_override = 1;
+ errsts = resp_report_luns(SCpnt, devip);
+ break;
+ case VERIFY: /* 10 byte SBC-2 command */
+ errsts = check_readiness(SCpnt, 0, devip);
+ break;
+ case WRITE_16:
+ case WRITE_12:
+ case WRITE_10:
+ case WRITE_6:
+ errsts = check_readiness(SCpnt, 0, devip);
+ if (errsts)
+ break;
+ if (scsi_debug_fake_rw)
+ break;
+ get_data_transfer_info(cmd, &lba, &num);
+ errsts = resp_write(SCpnt, lba, num, devip);
+ if (inj_recovered && (0 == errsts)) {
+ mk_sense_buffer(devip, RECOVERED_ERROR,
+ THRESHOLD_EXCEEDED, 0);
+ errsts = check_condition_result;
+ }
+ break;
+ case MODE_SENSE:
+ case MODE_SENSE_10:
+ errsts = resp_mode_sense(SCpnt, target, devip);
+ break;
+ case MODE_SELECT:
+ errsts = resp_mode_select(SCpnt, 1, devip);
+ break;
+ case MODE_SELECT_10:
+ errsts = resp_mode_select(SCpnt, 0, devip);
+ break;
+ case LOG_SENSE:
+ errsts = resp_log_sense(SCpnt, devip);
+ break;
+ case SYNCHRONIZE_CACHE:
+ delay_override = 1;
+ errsts = check_readiness(SCpnt, 0, devip);
+ break;
+ case WRITE_BUFFER:
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
+ case XDWRITEREAD_10:
+ if (!scsi_bidi_cmnd(SCpnt)) {
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ INVALID_FIELD_IN_CDB, 0);
+ errsts = check_condition_result;
+ break;
+ }
+
+ errsts = check_readiness(SCpnt, 0, devip);
+ if (errsts)
+ break;
+ if (scsi_debug_fake_rw)
+ break;
+ get_data_transfer_info(cmd, &lba, &num);
+ errsts = resp_read(SCpnt, lba, num, devip);
+ if (errsts)
+ break;
+ errsts = resp_write(SCpnt, lba, num, devip);
+ if (errsts)
+ break;
+ errsts = resp_xdwriteread(SCpnt, lba, num, devip);
+ break;
+ default:
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
+ "supported\n", *cmd);
+ errsts = check_readiness(SCpnt, 1, devip);
+ if (errsts)
+ break; /* Unit attention takes precedence */
+ mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
+ errsts = check_condition_result;
+ break;
+ }
+ return schedule_resp(SCpnt, devip, done, errsts,
+ (delay_override ? 0 : scsi_debug_delay));
+}
+
static struct scsi_host_template sdebug_driver_template = {
.proc_info = scsi_debug_proc_info,
.proc_name = sdebug_proc_name,
--
1.5.3.7
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCHes 1,2,3,4,5] scsi_debug
2008-03-20 2:09 [PATCH 1/5] scsi_debug: remove temporary hack around sscanf for negative values FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 2/5] scsi_debug: create new scsi_debug devices at a single place FUJITA Tomonori
@ 2008-03-20 14:53 ` Douglas Gilbert
1 sibling, 0 replies; 6+ messages in thread
From: Douglas Gilbert @ 2008-03-20 14:53 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linux-scsi, tomof, James Bottomley
[-- Attachment #1: Type: text/plain, Size: 710 bytes --]
FUJITA Tomonori sent 5 patches:
1: sscanf can handle negative values.
2: create new scsi_debug devices at a single place
3: remove unnecessary condition test in devInfoReg
4: use list_for_each_entry_safe
5: remove unnecessary function declarations
Signed-off-by: Douglas Gilbert <dougg@torque.net>
Attached is a gzip of my own working copy of the scsi_debug
driver as a patch against lk 2.6.25-rc5. Mostly additions
to test new options in sg3_utils.
Also perhaps we should look at using the relatively new
NAA(3) "Locally assigned" designator, especially for LU
identification, rather than fudging NAA(5) which is
supposed to use a registered IEEE OUI.
See spc4r14.pdf section 7.7.3.6.3 .
Doug Gilbert
[-- Attachment #2: sdebug.c2625rc5_sp1.diff.gz --]
[-- Type: application/x-gzip, Size: 10324 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2008-03-20 14:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-20 2:09 [PATCH 1/5] scsi_debug: remove temporary hack around sscanf for negative values FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 2/5] scsi_debug: create new scsi_debug devices at a single place FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 3/5] scsi_debug: remove unnecessary condition test in devInfoReg FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 4/5] scsi_debug: use list_for_each_entry_safe FUJITA Tomonori
2008-03-20 2:09 ` [PATCH 5/5] scsi_debug: remove unnecessary function declarations FUJITA Tomonori
2008-03-20 14:53 ` [PATCHes 1,2,3,4,5] scsi_debug Douglas Gilbert
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.