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