14 #include <linux/kernel.h>
19 #include <scsi/scsi.h>
24 #define DEBUG_SIMSCSI 0
26 #define SIMSCSI_REQ_QUEUE_LEN 64
27 #define DEFAULT_SIMSCSI_ROOT "/var/ski-disks/sd"
35 #define SSC_GET_COMPLETION 54
36 #define SSC_WAIT_COMPLETION 55
38 #define SSC_WRITE_ACCESS 2
39 #define SSC_READ_ACCESS 1
43 # define DBG simscsi_debug
50 static void simscsi_interrupt (
unsigned long val);
63 static int desc[16] = {
64 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
67 static struct queue_entry {
77 #define MAX_ROOT_LEN 128
85 simscsi_setup (
char *
s)
89 printk(
KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
96 __setup(
"simscsi=", simscsi_setup);
99 simscsi_interrupt (
unsigned long val)
107 printk(
"simscsi_interrupt: done with %ld\n", sc->serial_number);
108 (*sc->scsi_done)(sc);
119 ip[2] = capacity >> 11;
137 printk(
"simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
138 mode ==
SSC_READ ?
"read":
"write",
req.addr, offset,
139 scsi_sg_count(sc) - i, sl->
length);
159 simscsi_readwrite6 (
struct scsi_cmnd *sc,
int mode)
163 offset = (((sc->
cmnd[1] & 0x1f) << 16) | (sc->
cmnd[2] << 8) | sc->
cmnd[3])*512;
164 simscsi_sg_readwrite(sc, mode, offset);
168 simscsi_get_disk_size (
int fd)
180 for (bit = (128
UL << 30)/512; bit != 0; bit >>= 1) {
186 if (
stat.count ==
sizeof(buf))
193 simscsi_readwrite10 (
struct scsi_cmnd *sc,
int mode)
197 offset = (((
unsigned long)sc->
cmnd[2] << 24)
198 | ((
unsigned long)sc->
cmnd[3] << 16)
201 simscsi_sg_readwrite(sc, mode, offset);
213 register long sp asm (
"sp");
216 printk(
"simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
222 if (target_id <= 15 && sc->
device->lun == 0) {
223 switch (sc->
cmnd[0]) {
225 if (scsi_bufflen(sc) < 35) {
228 sprintf (fname,
"%s%c", simscsi_root,
'a' + target_id);
231 if (
desc[target_id] < 0) {
244 memcpy(buf + 8,
"HP SIMULATED DISK 0.00", 28);
245 scsi_sg_copy_from_buffer(sc, buf, 36);
254 if (
desc[target_id] < 0 )
260 if (
desc[target_id] < 0 )
266 if (
desc[target_id] < 0)
272 if (
desc[target_id] < 0)
278 if (
desc[target_id] < 0 || scsi_bufflen(sc) < 8) {
282 disk_size = simscsi_get_disk_size(
desc[target_id]);
284 buf[0] = (disk_size >> 24) & 0xff;
285 buf[1] = (disk_size >> 16) & 0xff;
286 buf[2] = (disk_size >> 8) & 0xff;
287 buf[3] = (disk_size >> 0) & 0xff;
293 scsi_sg_copy_from_buffer(sc, buf, 8);
310 panic(
"simscsi: unknown SCSI command %u\n", sc->
cmnd[0]);
319 panic(
"Attempt to queue command while command is pending!!");
325 tasklet_schedule(&simscsi_tasklet);
339 .name =
"simulated SCSI host adapter",
340 .proc_name =
"simscsi",
341 .queuecommand = simscsi_queuecommand,
342 .eh_host_reset_handler = simscsi_host_reset,
343 .bios_param = simscsi_biosparam,
361 error = scsi_add_host(host,
NULL);