patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / scsi / sr.c
index a4db57a..9c3ddba 100644 (file)
@@ -99,7 +99,7 @@ static void get_sectorsize(struct scsi_cd *);
 static void get_capabilities(struct scsi_cd *);
 
 static int sr_media_change(struct cdrom_device_info *, int);
-static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
+static int sr_packet(struct cdrom_device_info *, struct packet_command *);
 
 static struct cdrom_device_ops sr_dops = {
        .open                   = sr_open,
@@ -138,7 +138,15 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
                goto out;
        cd = scsi_cd(disk);
        if (!kref_get(&cd->kref))
-               cd = NULL;
+               goto out_null;
+       if (scsi_device_get(cd->device))
+               goto out_put;
+       goto out;
+
+ out_put:
+       kref_put(&cd->kref);
+ out_null:
+       cd = NULL;
  out:
        up(&sr_ref_sem);
        return cd;
@@ -147,6 +155,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
 static inline void scsi_cd_put(struct scsi_cd *cd)
 {
        down(&sr_ref_sem);
+       scsi_device_put(cd->device);
        kref_put(&cd->kref);
        up(&sr_ref_sem);
 }
@@ -490,7 +499,7 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
         switch (cmd) {
                 case SCSI_IOCTL_GET_IDLUN:
                 case SCSI_IOCTL_GET_BUS_NUMBER:
-                        return scsi_ioctl(sdev, cmd, (void *)arg);
+                        return scsi_ioctl(sdev, cmd, (void __user *)arg);
        }
        return cdrom_ioctl(&cd->cdi, inode, cmd, arg);
 }
@@ -558,13 +567,10 @@ static int sr_probe(struct device *dev)
        if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
                goto fail;
 
-       if ((error = scsi_device_get(sdev)) != 0)
-               goto fail;
-
        error = -ENOMEM;
        cd = kmalloc(sizeof(*cd), GFP_KERNEL);
        if (!cd)
-               goto fail_put_sdev;
+               goto fail;
        memset(cd, 0, sizeof(*cd));
 
        kref_init(&cd->kref, sr_kref_release);
@@ -637,8 +643,6 @@ fail_put:
        put_disk(disk);
 fail_free:
        kfree(cd);
-fail_put_sdev:
-       scsi_device_put(sdev);
 fail:
        return error;
 }
@@ -904,7 +908,7 @@ static void get_capabilities(struct scsi_cd *cd)
  * by the Uniform CD-ROM layer. 
  */
 static int sr_packet(struct cdrom_device_info *cdi,
-               struct cdrom_generic_command *cgc)
+               struct packet_command *cgc)
 {
        if (cgc->timeout <= 0)
                cgc->timeout = IOCTL_TIMEOUT;
@@ -926,7 +930,6 @@ static int sr_packet(struct cdrom_device_info *cdi,
 static void sr_kref_release(struct kref *kref)
 {
        struct scsi_cd *cd = container_of(kref, struct scsi_cd, kref);
-       struct scsi_device *sdev = cd->device;
        struct gendisk *disk = cd->disk;
 
        spin_lock(&sr_index_lock);
@@ -940,8 +943,6 @@ static void sr_kref_release(struct kref *kref)
        put_disk(disk);
 
        kfree(cd);
-
-       scsi_device_put(sdev);
 }
 
 static int sr_remove(struct device *dev)
@@ -950,7 +951,9 @@ static int sr_remove(struct device *dev)
 
        del_gendisk(cd->disk);
 
-       scsi_cd_put(cd);
+       down(&sr_ref_sem);
+       kref_put(&cd->kref);
+       up(&sr_ref_sem);
 
        return 0;
 }