patch-2.3.32 linux/drivers/scsi/scsi_debug.c

Next file: linux/drivers/scsi/scsi_debug.h
Previous file: linux/drivers/scsi/scsi.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.31/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
@@ -7,6 +7,7 @@
  *  anything out of the ordinary is seen.
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -32,16 +33,18 @@
 
 /* A few options that we want selected */
 
-#define NR_HOSTS_PRESENT 20
-#define NR_FAKE_DISKS   6
-#define N_HEAD          32
-#define N_SECTOR        64
-#define DISK_READONLY(TGT)      (1)
+#define NR_HOSTS_PRESENT 1
+#define NR_FAKE_DISKS   3
+#define N_HEAD          255
+#define N_SECTOR        63
+#define N_CYLINDER      524
+#define DISK_READONLY(TGT)      (0)
 #define DISK_REMOVEABLE(TGT)    (1)
+#define DEVICE_TYPE(TGT) (TGT == 2 ? TYPE_TAPE : TYPE_DISK);
 
 /* Do not attempt to use a timer to simulate a real disk with latency */
 /* Only use this in the actual kernel, not in the simulator. */
-/* #define IMMEDIATE */
+#define IMMEDIATE
 
 /* Skip some consistency checking.  Good for benchmarking */
 #define SPEEDY
@@ -58,11 +61,15 @@
 #define START_PARTITION 4
 
 /* Time to wait before completing a command */
-#define DISK_SPEED     (HZ/10)   /* 100ms */
-#define CAPACITY (0x80000)
+#define DISK_SPEED     (HZ/10)	/* 100ms */
+#define CAPACITY (N_HEAD * N_SECTOR * N_CYLINDER)
+#define SIZE(TGT) (TGT == 2 ? 2248 : 512)
 
 static int starts[] =
-{N_HEAD, N_HEAD * N_SECTOR, 50000, CAPACITY, 0};
+{N_SECTOR,
+ N_HEAD * N_SECTOR,		/* Single cylinder */
+ N_HEAD * N_SECTOR * 4,
+ CAPACITY, 0};
 static int npart = 0;
 
 #include "scsi_debug.h"
@@ -112,21 +119,25 @@
 
 typedef void (*done_fct_t) (Scsi_Cmnd *);
 
-static volatile done_fct_t do_done[SCSI_DEBUG_MAILBOXES] = {NULL,};
+static volatile done_fct_t do_done[SCSI_DEBUG_MAILBOXES] =
+{NULL,};
 
 static void scsi_debug_intr_handle(unsigned long);
 
 static struct timer_list timeout[SCSI_DEBUG_MAILBOXES];
 
-Scsi_Cmnd *SCint[SCSI_DEBUG_MAILBOXES]  = {NULL,};
-static char SCrst[SCSI_DEBUG_MAILBOXES] = {0,};
+Scsi_Cmnd *SCint[SCSI_DEBUG_MAILBOXES] =
+{NULL,};
+static char SCrst[SCSI_DEBUG_MAILBOXES] =
+{0,};
 
 /*
  * Semaphore used to simulate bus lockups.
  */
 static int scsi_debug_lockup = 0;
 
-static char sense_buffer[128] = {0,};
+static char sense_buffer[128] =
+{0,};
 
 static void scsi_dump(Scsi_Cmnd * SCpnt, int flag)
 {
@@ -197,6 +208,14 @@
 	sgcount = 0;
 	sgpnt = NULL;
 
+        /*
+         * The io_request_lock *must* be held at this point.
+         */
+        if( io_request_lock.lock == 0 )
+        {
+                printk("Warning - io_request_lock is not held in queuecommand\n");
+        }
+
 	/*
 	 * If we are being notified of the mid-level reposessing a command due to timeout,
 	 * just return.
@@ -242,6 +261,10 @@
 		SCpnt->result = 0;
 		done(SCpnt);
 		return 0;
+	case START_STOP:
+		SCSI_LOG_LLQUEUE(3, printk("START_STOP\n"));
+		scsi_debug_errsts = 0;
+		break;
 	case ALLOW_MEDIUM_REMOVAL:
 		if (cmd[4]) {
 			SCSI_LOG_LLQUEUE(2, printk("Medium removal inhibited..."));
@@ -253,7 +276,7 @@
 	case INQUIRY:
 		SCSI_LOG_LLQUEUE(3, printk("Inquiry...(%p %d)\n", buff, bufflen));
 		memset(buff, 0, bufflen);
-		buff[0] = TYPE_DISK;
+		buff[0] = DEVICE_TYPE(target);
 		buff[1] = DISK_REMOVEABLE(target) ? 0x80 : 0;	/* Removable disk */
 		buff[2] = 1;
 		buff[4] = 33 - 5;
@@ -277,7 +300,10 @@
 		buff[1] = (CAPACITY >> 16) & 0xff;
 		buff[2] = (CAPACITY >> 8) & 0xff;
 		buff[3] = CAPACITY & 0xff;
-		buff[6] = 2;	/* 512 byte sectors */
+		buff[4] = 0;
+		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:
@@ -327,15 +353,23 @@
 				p = (struct partition *) (buff + 0x1be);
 				i = 0;
 				while (starts[i + 1]) {
+					int start_cyl, end_cyl;
+
+					start_cyl = starts[i] / N_HEAD / N_SECTOR;
+					end_cyl = (starts[i + 1] - 1) / N_HEAD / N_SECTOR;
+					p->boot_ind = 0;
+
+					p->head = (i == 0 ? 1 : 0);
+					p->sector = 1 | ((start_cyl >> 8) << 6);
+					p->cyl = (start_cyl & 0xff);
+
+					p->end_head = N_HEAD - 1;
+					p->end_sector = N_SECTOR | ((end_cyl >> 8) << 6);
+					p->end_cyl = (end_cyl & 0xff);
+
 					p->start_sect = starts[i];
 					p->nr_sects = starts[i + 1] - starts[i];
 					p->sys_ind = 0x81;	/* Linux partition */
-					p->head = (i == 0 ? 1 : 0);
-					p->sector = 1;
-					p->cyl = starts[i] / N_HEAD / N_SECTOR;
-					p->end_head = N_HEAD - 1;
-					p->end_sector = N_SECTOR;
-					p->end_cyl = starts[i + 1] / N_HEAD / N_SECTOR;
 					p++;
 					i++;
 				};
@@ -465,6 +499,8 @@
 #ifdef IMMEDIATE
 	if (!scsi_debug_lockup) {
 		SCpnt->result = scsi_debug_errsts;
+		SCint[i] = SCpnt;
+		do_done[i] = done;
 		scsi_debug_intr_handle(i);	/* No timer - do this one right away */
 	}
 	restore_flags(flags);
@@ -490,24 +526,6 @@
 	return 0;
 }
 
-volatile static int internal_done_flag = 0;
-volatile static int internal_done_errcode = 0;
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	internal_done_errcode = SCpnt->result;
-	++internal_done_flag;
-}
-
-int scsi_debug_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("scsi_debug_command: ..calling scsi_debug_queuecommand\n"));
-	scsi_debug_queuecommand(SCpnt, internal_done);
-
-	while (!internal_done_flag);
-	internal_done_flag = 0;
-	return internal_done_errcode;
-}
-
 /* 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. */
 
@@ -589,7 +607,7 @@
 	int size = disk->capacity;
 	info[0] = N_HEAD;
 	info[1] = N_SECTOR;
-	info[2] = (size + 2047) >> 11;
+	info[2] = N_CYLINDER;
 	if (info[2] >= 1024)
 		info[2] = 1024;
 	return 0;
@@ -683,6 +701,21 @@
 
 	return (len);
 }
+
+#ifdef CONFIG_USER_DEBUG
+/*
+ * This is a hack for the user space emulator.  It allows us to
+ * "insert" arbitrary numbers of additional drivers.
+ */
+void *scsi_debug_get_handle(void)
+{
+	static Scsi_Host_Template driver_copy = SCSI_DEBUG;
+	void *rtn;
+	rtn = kmalloc(sizeof(driver_copy), GFP_ATOMIC);
+	memcpy(rtn, (void *) &driver_copy, sizeof(driver_copy));
+	return rtn;
+}
+#endif
 
 #ifdef MODULE
 /* Eventually this will go into an include file, but this will be later */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)