diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
commit | 99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch) | |
tree | 3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /drivers/scsi/scsi_debug.c | |
parent | e73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff) |
Merge with Linux 2.3.38.
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r-- | drivers/scsi/scsi_debug.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d00b0f539..925c0f8f7 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -122,6 +122,9 @@ typedef void (*done_fct_t) (Scsi_Cmnd *); static volatile done_fct_t do_done[SCSI_DEBUG_MAILBOXES] = {NULL,}; +struct Scsi_Host * SHpnt = NULL; + +static void scsi_debug_send_self_command(struct Scsi_Host * shpnt); static void scsi_debug_intr_handle(unsigned long); static struct timer_list timeout[SCSI_DEBUG_MAILBOXES]; @@ -208,6 +211,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) sgcount = 0; sgpnt = NULL; +#ifdef CONFIG_SMP /* * The io_request_lock *must* be held at this point. */ @@ -215,6 +219,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) { printk("Warning - io_request_lock is not held in queuecommand\n"); } +#endif /* * If we are being notified of the mid-level reposessing a command due to timeout, @@ -230,6 +235,17 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) buff = (unsigned char *) SCpnt->request_buffer; + /* + * If a command comes for the ID of the host itself, just print + * a silly message and return. + */ + if( target == 7 ) { + printk("How do you do!\n"); + SCpnt->result = 0; + done(SCpnt); + return 0; + } + if (target >= NR_FAKE_DISKS || SCpnt->lun != 0) { SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); @@ -293,6 +309,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) break; case READ_CAPACITY: SCSI_LOG_LLQUEUE(3, printk("Read Capacity\n")); + SHpnt = SCpnt->host; if (NR_REAL < 0) NR_REAL = (MINOR(SCpnt->request.rq_dev) >> 4) & 0x0f; memset(buff, 0, bufflen); @@ -304,6 +321,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) buff[5] = 0; buff[6] = (SIZE(target) >> 8) & 0xff; /* 512 byte sectors */ buff[7] = SIZE(target) & 0xff; + scsi_debug_errsts = 0; break; case READ_10: @@ -526,6 +544,45 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) return 0; } +static void sd_test_done(Scsi_Cmnd * SCpnt) +{ + struct request *req; + + req = &SCpnt->request; + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ + + if (req->sem != NULL) { + up(req->sem); + } +} + +static void scsi_debug_send_self_command(struct Scsi_Host * shpnt) +{ + static unsigned char cmd[6] = + {TEST_UNIT_READY, 0, 0, 0, 0, 0}; + + Scsi_Cmnd * scp; + Scsi_Device * sdev; + + printk("Allocating host dev\n"); + sdev = scsi_get_host_dev(shpnt); + printk("Got %p. Allocating command block\n", sdev); + scp = scsi_allocate_device(sdev, 1, FALSE); + printk("Got %p\n", scp); + + scp->cmd_len = 6; + scp->use_sg = 0; + + printk("Sending command\n"); + scsi_wait_cmd (scp, (void *) cmd, (void *) NULL, + 0, sd_test_done, 100, 3); + + printk("Releasing command\n"); + scsi_release_command(scp); + printk("Freeing device\n"); + scsi_free_host_dev(sdev); +} + /* A "high" level interrupt handler. This should be called once per jiffy * to simulate a regular scsi disk. We use a timer to do this. */ @@ -670,6 +727,11 @@ int scsi_debug_proc_info(char *buffer, char **start, off_t offset, * what we are supposed to do here. Simulate bus lockups * to test our reset capability. */ + if (length == 4 && strncmp(buffer, "test", length) == 0) { + printk("Testing send self command %p\n", SHpnt); + scsi_debug_send_self_command(SHpnt); + return orig_length; + } if (length == 6 && strncmp(buffer, "lockup", length) == 0) { scsi_debug_lockup = 1; return orig_length; |