(I've sent these patches before and gotten no reply. Alan won't even
look at them until you do. Help? Please??)
I am using the below patches in a production kernel that needs to open
devices with removable media (/dev/sr# and /dev/sd[a-z]) even when the
media are missing. This is of course what the O_NONBLOCK flag was
invented for. But at least with the stock 2.2 kernel, O_NONBLOCK
doesn't work with SCSI devices. (It does work with IDE devices.)
These patches make O_NONBLOCK work with SCSI devices.
The first patch is for SCSI disks; the second patch is for SCSI CDs.
------------------------------------------------------------------------
Index: drivers/scsi/sd.c
@@ -151,34 +151,41 @@ static int sd_open(struct inode * inode,
* is being re-read.
*/
-
while (rscsi_disks[target].device->busy)
barrier();
- if(rscsi_disks[target].device->removable) {
+
+ /*
+ * When opening removable disks, we check media...
+ * ... unless media don't matter, due to O_NONBLOCK.
+ */
+ if (rscsi_disks[target].device->removable
+ && !(filp->f_flags & O_NONBLOCK))
+ {
+ /*
+ * Note disk change and/or removal.
+ * Also try to read new partition table (if any).
+ */
check_disk_change(inode->i_rdev);
- /*
- * If the drive is empty, just let the open fail.
- */
- if ( !rscsi_disks[target].ready )
- return -ENXIO;
+ /*
+ * If the drive is empty, let the open fail.
+ */
+ if (rscsi_disks[target].ready)
+ return -ENXIO;
- /*
- * Similarly, if the device has the write protect tab set,
- * have the open fail if the user expects to be able to write
- * to the thing.
- */
- if ( (rscsi_disks[target].write_prot) && (filp->f_mode & 2) )
- return -EROFS;
+ /*
+ * If the device has the write protect tab set,
+ * let the open fail if the user expects to be able to write.
+ */
+ if ( (rscsi_disks[target].write_prot) && (filp->f_mode & 2) )
+ return -EROFS;
}
/*
- * It is possible that the disk changing stuff resulted in the device being taken
- * offline. If this is the case, report this to the user, and don't pretend that
- * the open actually succeeded.
+ * It is possible that the disk changing stuff (or something
+ * else?) resulted in the device being taken offline.
+ * If so, let the open fail.
*/
- if( !rscsi_disks[target].device->online )
- {
+ if (!rscsi_disks[target].device->online)
return -ENXIO;
- }
/*
@@ -1069,5 +1076,4 @@ static int check_scsidisk_media_change(k
int target;
struct inode inode;
- int flag = 0;
target = DEVICE_NR(full_dev);
@@ -1121,9 +1127,9 @@ static int check_scsidisk_media_change(k
* struct and tested at open ! Daniel Roche ( [EMAIL PROTECTED] )
*/
-
rscsi_disks[target].ready = 1; /* FLOPTICAL */
retval = rscsi_disks[target].device->changed;
- if(!flag) rscsi_disks[target].device->changed = 0;
+ rscsi_disks[target].device->changed = 0;
+
return retval;
}
------------------------------------------------------------------------
Index: drivers/scsi/sr.h
@@ -29,5 +29,5 @@
unsigned char sector_bit_size; /* sector size = 2^sector_bit_size
*/
unsigned char sector_bit_shift; /* sectors/FS block =
2^sector_bit_shift*/
- unsigned needs_sector_size:1; /* needs to get sector size */
+ unsigned :1; /* (was needs_sector_size)
+ */
unsigned ten:1; /* support ten byte commands
*/
unsigned remap:1; /* support remapping
*/
Index: drivers/scsi/sr.c
@@ -154,21 +154,17 @@ int sr_media_change(struct cdrom_device_
retval = scsi_CDs[MINOR(cdi->dev)].device->changed;
scsi_CDs[MINOR(cdi->dev)].device->changed = 0;
- /* If the disk changed, the capacity will now be different,
- * so we force a re-read of this information */
+
+ /*
+ * If the disk changed, the sector size and capacity may be
+ * different, so we force a re-read of this information.
+ */
if (retval) {
+ /* discover new sector size */
+ get_sectorsize(MINOR(cdi->dev));
+
/* check multisession offset etc */
sr_cd_check(cdi);
-
- /*
- * If the disk changed, the capacity will now be different,
- * so we force a re-read of this information
- * Force 2048 for the sector size so that filesystems won't
- * be trying to use something that is too small if the disc
- * has changed.
- */
- scsi_CDs[MINOR(cdi->dev)].needs_sector_size = 1;
-
- scsi_CDs[MINOR(cdi->dev)].sector_size = 2048;
}
+
return retval;
}
@@ -384,6 +380,4 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
static int sr_open(struct cdrom_device_info *cdi, int purpose)
{
- check_disk_change(cdi->dev);
-
if (MINOR(cdi->dev) >= sr_template.dev_max
|| !scsi_CDs[MINOR(cdi->dev)].device) {
@@ -403,12 +397,4 @@ static int sr_open(struct cdrom_device_i
__MOD_INC_USE_COUNT(sr_template.module);
- /* If this device did not have media in the drive at boot time, then
- * we would have been unable to get the sector size. Check to see if
- * this is the case, and try again.
- */
-
- if (scsi_CDs[MINOR(cdi->dev)].needs_sector_size)
- get_sectorsize(MINOR(cdi->dev));
-
return 0;
}
@@ -894,5 +880,4 @@ void get_sectorsize(int i)
scsi_CDs[i].capacity = 0x1fffff;
scsi_CDs[i].sector_size = 2048; /* A guess, just in case */
- scsi_CDs[i].needs_sector_size = 1;
} else {
#if 0
@@ -927,14 +912,14 @@ void get_sectorsize(int i)
i, scsi_CDs[i].sector_size);
scsi_CDs[i].capacity = 0;
- scsi_CDs[i].needs_sector_size = 1;
+ break;
}
+ }
+
+ /*
+ * Add this so that we have the ability to correctly gauge
+ * what the device is capable of.
+ */
+ sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
- /*
- * Add this so that we have the ability to correctly gauge
- * what the device is capable of.
- */
- scsi_CDs[i].needs_sector_size = 0;
- sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
- };
scsi_free(buffer, 512);
}
@@ -1021,5 +1006,5 @@ void get_capabilities(int i)
cdrom_number_of_slots(&(scsi_CDs[i].cdi));
if (scsi_CDs[i].cdi.capacity <= 1)
- /* not a changer */
+ /* not a changer */
scsi_CDs[i].cdi.mask |= CDC_SELECT_DISC;
/*else I don't think it can close its tray
@@ -1149,5 +1134,4 @@ void sr_finish()
scsi_CDs[i].capacity = 0x1fffff;
scsi_CDs[i].sector_size = 2048; /* A guess, just in case */
- scsi_CDs[i].needs_sector_size = 1;
scsi_CDs[i].device->changed = 1; /* force recheck CD type */
#if 0
------------------------------------------------------------------------
--
Chip Salzenberg - a.k.a. - <[EMAIL PROTECTED]>
"I wanted to play hopscotch with the impenetrable mystery of existence,
but he stepped in a wormhole and had to go in early." // MST3K
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]