Commit 534a4bf2 authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley

[PATCH] scsi_debug new scan fix

If you use scsi_debug the patch below fixes a problem that has existed
since the updated scan code was merged in. scsi_debug previously assumed
that the scsi_device used to probe and the device permanently added to the
host_queue would be the same. This caused scsi_debug to allocate some
internal data and key it off the scsi_device pointer for later use.  This
resulted in scsi_debug failing all IO post scanning. This patch corrects
this problem.

Note:
	Douglas Gilbert is the maintainer of this driver.
	dougg@gear.torque.net
	http://www.torque.net/sg/

	During Douglas Gilbert's time-off he connects when he can so it
	maybe a bit until he can address this.

	In the interim this patch makes scsi_debug functional.


The full patch is available at:
http://www-124.ibm.com/storageio/patches/2.5/scsi-debug
-andmike
--
Michael Anderson
andmike@us.ibm.com

 scsi_debug.c |   59 +++++++++++++++++++++++++++++++----------------------------
 1 files changed, 31 insertions(+), 28 deletions(-)
parent 489f597d
...@@ -108,9 +108,13 @@ static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB; ...@@ -108,9 +108,13 @@ static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
#define SDEBUG_SENSE_LEN 32 #define SDEBUG_SENSE_LEN 32
struct sdebug_dev_info { struct sdebug_dev_info {
Scsi_Device * sdp;
unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */
unsigned int channel;
unsigned int target;
unsigned int lun;
struct Scsi_Host *host;
char reset; char reset;
char used;
}; };
static struct sdebug_dev_info * devInfop; static struct sdebug_dev_info * devInfop;
...@@ -154,7 +158,7 @@ static int resp_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num, ...@@ -154,7 +158,7 @@ static int resp_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num,
static int resp_report_luns(unsigned char * cmd, unsigned char * buff, static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
int bufflen, struct sdebug_dev_info * devip); int bufflen, struct sdebug_dev_info * devip);
static void timer_intr_handler(unsigned long); static void timer_intr_handler(unsigned long);
static struct sdebug_dev_info * devInfoReg(Scsi_Device * sdp); static struct sdebug_dev_info * devInfoReg(Scsi_Cmnd *scmd);
static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
int asc, int asq, int inbandLen); int asc, int asq, int inbandLen);
static int check_reset(Scsi_Cmnd * SCpnt, struct sdebug_dev_info * devip); static int check_reset(Scsi_Cmnd * SCpnt, struct sdebug_dev_info * devip);
...@@ -222,7 +226,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, done_funct_t done) ...@@ -222,7 +226,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, done_funct_t done)
return schedule_resp(SCpnt, NULL, done, 0, 0); return schedule_resp(SCpnt, NULL, done, 0, 0);
} }
if ((target > driver_template.this_id) || (SCpnt->lun != 0)) if (SCpnt->lun != 0)
return schedule_resp(SCpnt, NULL, done, return schedule_resp(SCpnt, NULL, done,
DID_NO_CONNECT << 16, 0); DID_NO_CONNECT << 16, 0);
#if 0 #if 0
...@@ -230,14 +234,10 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, done_funct_t done) ...@@ -230,14 +234,10 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, done_funct_t done)
(int)SCpnt->device->host->host_no, (int)SCpnt->device->id, (int)SCpnt->device->host->host_no, (int)SCpnt->device->id,
SCpnt->device, (int)*cmd); SCpnt->device, (int)*cmd);
#endif #endif
if (NULL == SCpnt->device->hostdata) { devip = devInfoReg(SCpnt);
devip = devInfoReg(SCpnt->device); if (NULL == devip)
if (NULL == devip) return schedule_resp(SCpnt, NULL, done,
return schedule_resp(SCpnt, NULL, done, DID_NO_CONNECT << 16, 0);
DID_NO_CONNECT << 16, 0);
SCpnt->device->hostdata = devip;
}
devip = SCpnt->device->hostdata;
if ((SCSI_DEBUG_OPT_EVERY_NTH & scsi_debug_opts) && if ((SCSI_DEBUG_OPT_EVERY_NTH & scsi_debug_opts) &&
(scsi_debug_every_nth > 0) && (scsi_debug_every_nth > 0) &&
...@@ -474,8 +474,8 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff, ...@@ -474,8 +474,8 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
int dev_id_num, len; int dev_id_num, len;
char dev_id_str[6]; char dev_id_str[6];
dev_id_num = ((devip->sdp->host->host_no + 1) * 1000) + dev_id_num = ((devip->host->host_no + 1) * 1000) +
devip->sdp->id; devip->target;
len = snprintf(dev_id_str, 6, "%d", dev_id_num); len = snprintf(dev_id_str, 6, "%d", dev_id_num);
len = (len > 6) ? 6 : len; len = (len > 6) ? 6 : len;
if (0 == cmd[2]) { /* supported vital product data pages */ if (0 == cmd[2]) { /* supported vital product data pages */
...@@ -870,21 +870,28 @@ static int scsi_debug_release(struct Scsi_Host * hpnt) ...@@ -870,21 +870,28 @@ static int scsi_debug_release(struct Scsi_Host * hpnt)
return 0; return 0;
} }
static struct sdebug_dev_info * devInfoReg(Scsi_Device * sdp) static struct sdebug_dev_info * devInfoReg(Scsi_Cmnd *scmd)
{ {
int k; int k;
struct sdebug_dev_info * devip; struct sdebug_dev_info * devip;
for (k = 0; k < scsi_debug_num_devs; ++k) { for (k = 0; k < scsi_debug_num_devs; ++k) {
devip = &devInfop[k]; devip = &devInfop[k];
if (devip->sdp == sdp) if ((devip->channel == scmd->channel) &&
(devip->target == scmd->target) &&
(devip->lun == scmd->lun) &&
(devip->host == scmd->host))
return devip; return devip;
} }
for (k = 0; k < scsi_debug_num_devs; ++k) { for (k = 0; k < scsi_debug_num_devs; ++k) {
devip = &devInfop[k]; devip = &devInfop[k];
if (NULL == devip->sdp) { if (!devip->used) {
devip->sdp = sdp; devip->channel = scmd->channel;
devip->target = scmd->target;
devip->lun = scmd->lun;
devip->host = scmd->host;
devip->reset = 1; devip->reset = 1;
devip->used = 1;
memset(devip->sense_buff, 0, SDEBUG_SENSE_LEN); memset(devip->sense_buff, 0, SDEBUG_SENSE_LEN);
devip->sense_buff[0] = 0x70; devip->sense_buff[0] = 0x70;
return devip; return devip;
...@@ -934,19 +941,15 @@ static int scsi_debug_biosparam(Disk * disk, struct block_device * bdev, ...@@ -934,19 +941,15 @@ static int scsi_debug_biosparam(Disk * disk, struct block_device * bdev,
static int scsi_debug_device_reset(Scsi_Cmnd * SCpnt) static int scsi_debug_device_reset(Scsi_Cmnd * SCpnt)
{ {
Scsi_Device * sdp; struct sdebug_dev_info * devip;
int k;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: device_reset\n"); printk(KERN_INFO "scsi_debug: device_reset\n");
++num_dev_resets; ++num_dev_resets;
if (SCpnt && ((sdp = SCpnt->device))) { if (SCpnt) {
for (k = 0; k < scsi_debug_num_devs; ++k) { devip = devInfoReg(SCpnt);
if (sdp->hostdata == (devInfop + k)) if (devip)
break; devip->reset = 1;
}
if (k < scsi_debug_num_devs)
devInfop[k].reset = 1;
} }
return SUCCESS; return SUCCESS;
} }
...@@ -960,9 +963,9 @@ static int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt) ...@@ -960,9 +963,9 @@ static int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt)
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: bus_reset\n"); printk(KERN_INFO "scsi_debug: bus_reset\n");
++num_bus_resets; ++num_bus_resets;
if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { if (SCpnt && ((sdp = SCpnt->device)) && ((hp = SCpnt->host))) {
for (k = 0; k < scsi_debug_num_devs; ++k) { for (k = 0; k < scsi_debug_num_devs; ++k) {
if (hp == devInfop[k].sdp->host) if (hp == devInfop[k].host)
devInfop[k].reset = 1; devInfop[k].reset = 1;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment