Hi
This is a small patch I made for 2.3.39. It adds a generic IOCTL to the scsi
layer that supports ejecting removable media like mo or scsi-zip.
"eject /dev/sdd" works fine for me and my Fujitsu mo drive.
It also cleans up sd_init_onedisk() when it try to scan a drive without
medium in it.
Everyone with a removeable scsi disk (mo/zip), please test it and report
success/failure. If you like this patch, I will send it to Linus and I hope
it will make it into 2.4.
If nobody is interessed in a eject feature for his /dev/sd?, I would like
to see the fix for sd_init_onedisk() in 2.4.
Sincerly,
Michael
-------------------------------------8<-----------------------------------
diff -r -u linux-2.3-orig/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- linux-2.3-orig/drivers/scsi/scsi_ioctl.c Mon Jan 17 01:07:33 2000
+++ linux/drivers/scsi/scsi_ioctl.c Mon Jan 17 01:13:26 2000
@@ -457,11 +457,24 @@
scsi_cmd[4] = 0;
return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
START_STOP_TIMEOUT, NORMAL_RETRIES);
- break;
+ break;
+ case SCSI_IOCTL_EJECT:
+ if (!dev->removable ) return -EINVAL;
+ /* allow 1 for access count for auto-eject feature */
+ if( dev->access_count > 1 )
+ return -EBUSY;
+ scsi_ioctl((Scsi_Device *)dev, SCSI_IOCTL_DOORUNLOCK, 0);
+ scsi_cmd[0] = START_STOP;
+ scsi_cmd[1] = dev->lun << 5;
+ scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
+ scsi_cmd[4] = 0x02 /* eject */;
+ return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+ START_STOP_TIMEOUT, NORMAL_RETRIES);
+ break;
default:
if (dev->host->hostt->ioctl)
return dev->host->hostt->ioctl(dev, cmd, arg);
- return -EINVAL;
+ return -EINVAL;
}
return -EINVAL;
}
diff -r -u linux-2.3-orig/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux-2.3-orig/drivers/scsi/sd.c Mon Jan 17 01:07:33 2000
+++ linux/drivers/scsi/sd.c Mon Jan 17 01:20:26 2000
@@ -410,9 +410,10 @@
/*
* If the drive is empty, just let the open fail.
+ * and return the same error as returned by "sr.c".
*/
if (!rscsi_disks[target].ready)
- return -ENXIO;
+ return -ENOMEDIUM;
/*
* Similarly, if the device has the write protect tab set,
@@ -767,6 +768,18 @@
printk("ready\n");
}
retries = 3;
+ /* if there is no medium present in a removable drive
+ * do not do a READ_CAPACITY (becaus this will fail)
+ */
+ if(the_result && rscsi_disks[i].device->removable &&
+ SCpnt->sense_buffer[2] == NOT_READY) {
+
+ /* magic, to show we have no partition */
+ sd[i << 4].start_sect = -1;
+ rscsi_disks[i].device->changed = 1;
+ rscsi_disks[i].has_part_table = 0;
+ goto no_medium_present;
+ }
do {
cmd[0] = READ_CAPACITY;
cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
@@ -945,6 +958,8 @@
SCpnt->device->ten = 1;
SCpnt->device->remap = 1;
SCpnt->device->sector_size = sector_size;
+
+ no_medium_present:
/* Wake up a process waiting for device */
scsi_release_command(SCpnt);
SCpnt = NULL;
diff -r -u linux-2.3-orig/include/scsi/scsi_ioctl.h linux/include/scsi/scsi_ioctl.h
--- linux-2.3-orig/include/scsi/scsi_ioctl.h Mon Jan 17 01:07:03 2000
+++ linux/include/scsi/scsi_ioctl.h Mon Jan 17 01:22:07 2000
@@ -11,6 +11,10 @@
the cdrom */
#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */
#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */
+/* eject (same as in /usr/src/linux/include/linux/cdrom.h),
+ * so "eject(1)" will work.
+*/
+#define SCSI_IOCTL_EJECT 0x5309
#define SCSI_REMOVAL_PREVENT 1
#define SCSI_REMOVAL_ALLOW 0
-- GPG Fingerprint = EA71 B296 4597 4D8B 343E 821E 9624 83E1 5662 C734 /"\ o \ / ASCII RIBBON CAMPAIGN /|\ X AGAINST HTML MAIL >> / \ o- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:14 EST