diff options
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 997f8e30509b..7c80711e18ed 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -60,6 +60,10 @@ #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, }; @@ -452,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) @@ -525,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); @@ -574,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; |