]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/sr.c
[PATCH] driver core: safely unbind drivers for devices not on a bus
[linux-2.6-omap-h63xx.git] / drivers / scsi / sr.c
index 18a3b756c63cb79409028622d8e763d73e13e142..7c80711e18ed4c87d6dd991d003822d563c0e341 100644 (file)
 #include "sr.h"
 
 
+MODULE_DESCRIPTION("SCSI cdrom (sr) driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR);
+
 #define SR_DISKS       256
 
 #define MAX_RETRIES    3
@@ -67,7 +71,7 @@
 #define SR_CAPABILITIES \
        (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
         CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
-        CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
+        CDC_PLAY_AUDIO|CDC_RESET|CDC_DRIVE_STATUS| \
         CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
         CDC_MRW|CDC_MRW_W|CDC_RAM)
 
@@ -114,7 +118,6 @@ static struct cdrom_device_ops sr_dops = {
        .get_mcn                = sr_get_mcn,
        .reset                  = sr_reset,
        .audio_ioctl            = sr_audio_ioctl,
-       .dev_ioctl              = sr_dev_ioctl,
        .capability             = SR_CAPABILITIES,
        .generic_packet         = sr_packet,
 };
@@ -151,7 +154,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
        return cd;
 }
 
-static inline void scsi_cd_put(struct scsi_cd *cd)
+static void scsi_cd_put(struct scsi_cd *cd)
 {
        struct scsi_device *sdev = cd->device;
 
@@ -238,8 +241,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
                case ILLEGAL_REQUEST:
                        if (!(SCpnt->sense_buffer[0] & 0x90))
                                break;
-                       if (!blk_fs_request(SCpnt->request))
-                               break;
                        error_sector = (SCpnt->sense_buffer[3] << 24) |
                                (SCpnt->sense_buffer[4] << 16) |
                                (SCpnt->sense_buffer[5] << 8) |
@@ -317,23 +318,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
                return 0;
        }
 
-       /*
-        * these are already setup, just copy cdb basically
-        */
-       if (SCpnt->request->flags & REQ_BLOCK_PC) {
-               scsi_setup_blk_pc_cmnd(SCpnt);
-
-               if (SCpnt->timeout_per_command)
-                       timeout = SCpnt->timeout_per_command;
-
-               goto queue;
-       }
-
-       if (!(SCpnt->request->flags & REQ_CMD)) {
-               blk_dump_rq_flags(SCpnt->request, "sr unsup command");
-               return 0;
-       }
-
        /*
         * we do lazy blocksize switching (when reading XA sectors,
         * see CDROMREADMODE2 ioctl) 
@@ -422,8 +406,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
         */
        SCpnt->transfersize = cd->device->sector_size;
        SCpnt->underflow = this_count << 9;
-
-queue:
        SCpnt->allowed = MAX_RETRIES;
        SCpnt->timeout_per_command = timeout;
 
@@ -473,17 +455,33 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
 {
        struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
        struct scsi_device *sdev = cd->device;
+       void __user *argp = (void __user *)arg;
+       int ret;
 
-        /*
-         * Send SCSI addressing ioctls directly to mid level, send other
-         * ioctls to cdrom/block level.
-         */
-        switch (cmd) {
-                case SCSI_IOCTL_GET_IDLUN:
-                case SCSI_IOCTL_GET_BUS_NUMBER:
-                        return scsi_ioctl(sdev, cmd, (void __user *)arg);
+       /*
+        * Send SCSI addressing ioctls directly to mid level, send other
+        * ioctls to cdrom/block level.
+        */
+       switch (cmd) {
+       case SCSI_IOCTL_GET_IDLUN:
+       case SCSI_IOCTL_GET_BUS_NUMBER:
+               return scsi_ioctl(sdev, cmd, argp);
        }
-       return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
+
+       ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
+       if (ret != ENOSYS)
+               return ret;
+
+       /*
+        * ENODEV means that we didn't recognise the ioctl, or that we
+        * cannot execute it in the current device state.  In either
+        * case fall through to scsi_ioctl, which will return ENDOEV again
+        * if it doesn't recognise the ioctl
+        */
+       ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL);
+       if (ret != -ENODEV)
+               return ret;
+       return scsi_ioctl(sdev, cmd, argp);
 }
 
 static int sr_block_media_changed(struct gendisk *disk)
@@ -546,10 +544,9 @@ static int sr_probe(struct device *dev)
                goto fail;
 
        error = -ENOMEM;
-       cd = kmalloc(sizeof(*cd), GFP_KERNEL);
+       cd = kzalloc(sizeof(*cd), GFP_KERNEL);
        if (!cd)
                goto fail;
-       memset(cd, 0, sizeof(*cd));
 
        kref_init(&cd->kref);
 
@@ -595,8 +592,6 @@ static int sr_probe(struct device *dev)
        get_capabilities(cd);
        sr_vendor_init(cd);
 
-       snprintf(disk->devfs_name, sizeof(disk->devfs_name),
-                       "%s/cd", sdev->devfs_name);
        disk->driverfs_dev = &sdev->sdev_gendev;
        set_capacity(disk, cd->capacity);
        disk->private_data = &cd->driver;