1diff -ur linuxorig/drivers/scsi/sd.c linux-2.4.23/drivers/scsi/sd.c
2--- linuxorig/drivers/scsi/sd.c	2003-12-15 18:32:06.000000000 -0500
3+++ linux-2.4.23/drivers/scsi/sd.c	2003-12-15 18:35:18.000000000 -0500
4@@ -108,6 +108,8 @@
5 static int sd_detect(Scsi_Device *);
6 static void sd_detach(Scsi_Device *);
7 static int sd_init_command(Scsi_Cmnd *);
8+static void sd_start (Scsi_Cmnd * SCpnt);
9+static void sd_devname(unsigned int disknum, char *buffer);
10 
11 static struct Scsi_Device_Template sd_template = {
12 	name:"disk",
13@@ -154,6 +156,7 @@
14 	struct Scsi_Host * host;
15 	Scsi_Device * SDev;
16 	int diskinfo[4];
17+        char nbuf[6];
18     
19 	SDev = rscsi_disks[DEVICE_NR(dev)].device;
20 	if (!SDev)
21@@ -238,6 +241,8 @@
22 				return -EFAULT;
23 			return 0;
24 		}
25+		case SD_IOCTL_IDLE:
26+			return (jiffies - rscsi_disks[DEVICE_NR(dev)].idle) / HZ + 1;
27 		case BLKGETSIZE:
28 		case BLKGETSIZE64:
29 		case BLKROSET:
30@@ -259,6 +264,16 @@
31 			return revalidate_scsidisk(dev, 1);
32 
33 		default:
34+			if (cmd == SCSI_IOCTL_STOP_UNIT) {
35+				rscsi_disks[DEVICE_NR(dev)].spindown = 1;
36+        			sd_devname(DEVICE_NR(dev), nbuf);
37+/*				printk(KERN_INFO "%s: Spinning down disk.\n",nbuf); */
38+			}
39+			if (cmd == SCSI_IOCTL_START_UNIT) {
40+				rscsi_disks[DEVICE_NR(dev)].spindown = 0;
41+        			sd_devname(DEVICE_NR(dev), nbuf);
42+				printk(KERN_INFO "%s: Spinning up disk.\n",nbuf);
43+			}
44 			return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg);
45 	}
46 }
47@@ -311,6 +326,14 @@
48 	    SCpnt->request.rq_dev, block));
49 
50 	dpnt = &rscsi_disks[dev];
51+
52+	/* Update idle-since time */
53+	rscsi_disks[dev].idle = jiffies;
54+
55+	/* Spin up */
56+	if (dpnt->spindown) {
57+	   sd_start(SCpnt);
58+	}
59 	if (dev >= sd_template.dev_max ||
60 	    !dpnt->device ||
61 	    !dpnt->device->online ||
62@@ -700,6 +723,20 @@
63  * them to SCSI commands.
64  */
65 
66+/*
67+ * handle spinup of idle disks
68+ */
69+
70+static void sd_start (Scsi_Cmnd * SCpnt)
71+{
72+    unsigned char cmd[12];
73+    int old_use_sg = SCpnt->use_sg, oldbufflen = SCpnt->bufflen;
74+    Scsi_Device * dev = rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device;
75+    sd_init_onedisk(DEVICE_NR(SCpnt->request.rq_dev));
76+    rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].spindown = 0;
77+    SCpnt->use_sg  = old_use_sg;
78+    SCpnt->bufflen = oldbufflen;
79+}
80 
81 static int check_scsidisk_media_change(kdev_t full_dev)
82 {
83diff -ur linuxorig/drivers/scsi/sd.h linux-2.4.23/drivers/scsi/sd.h
84--- linuxorig/drivers/scsi/sd.h	2003-12-15 18:32:15.000000000 -0500
85+++ linux-2.4.23/drivers/scsi/sd.h	2003-12-15 18:35:18.000000000 -0500
86@@ -26,6 +26,8 @@
87 typedef struct scsi_disk {
88 	unsigned capacity;	/* size in blocks */
89 	Scsi_Device *device;
90+        unsigned long idle;     /* idle time in jiffies */
91+        unsigned char spindown; /* is down */
92 	unsigned char ready;	/* flag ready for FLOPTICAL */
93 	unsigned char write_prot;	/* flag write_protect for rmvable dev */
94 	unsigned char sector_bit_size;	/* sector_size = 2 to the  bit size power */
95diff -ur linuxorig/include/scsi/scsi_ioctl.h linux-2.4.23/include/scsi/scsi_ioctl.h
96--- linuxorig/include/scsi/scsi_ioctl.h	2003-12-15 18:33:30.000000000 -0500
97+++ linux-2.4.23/include/scsi/scsi_ioctl.h	2003-12-15 18:35:18.000000000 -0500
98@@ -14,6 +14,7 @@
99 
100 #define	SCSI_REMOVAL_PREVENT	1
101 #define	SCSI_REMOVAL_ALLOW	0
102+#define SD_IOCTL_IDLE 4746
103 
104 #ifdef __KERNEL__
105 
106