aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r--drivers/scsi/sr.c43
1 files changed, 12 insertions, 31 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index a4d9be7c6874..dd8050392d01 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -44,6 +44,7 @@
44#include <linux/interrupt.h> 44#include <linux/interrupt.h>
45#include <linux/init.h> 45#include <linux/init.h>
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/mutex.h>
47#include <asm/uaccess.h> 48#include <asm/uaccess.h>
48 49
49#include <scsi/scsi.h> 50#include <scsi/scsi.h>
@@ -90,7 +91,7 @@ static DEFINE_SPINLOCK(sr_index_lock);
90/* This semaphore is used to mediate the 0->1 reference get in the 91/* This semaphore is used to mediate the 0->1 reference get in the
91 * face of object destruction (i.e. we can't allow a get on an 92 * face of object destruction (i.e. we can't allow a get on an
92 * object after last put) */ 93 * object after last put) */
93static DECLARE_MUTEX(sr_ref_sem); 94static DEFINE_MUTEX(sr_ref_mutex);
94 95
95static int sr_open(struct cdrom_device_info *, int); 96static int sr_open(struct cdrom_device_info *, int);
96static void sr_release(struct cdrom_device_info *); 97static void sr_release(struct cdrom_device_info *);
@@ -133,7 +134,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
133{ 134{
134 struct scsi_cd *cd = NULL; 135 struct scsi_cd *cd = NULL;
135 136
136 down(&sr_ref_sem); 137 mutex_lock(&sr_ref_mutex);
137 if (disk->private_data == NULL) 138 if (disk->private_data == NULL)
138 goto out; 139 goto out;
139 cd = scsi_cd(disk); 140 cd = scsi_cd(disk);
@@ -146,7 +147,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
146 kref_put(&cd->kref, sr_kref_release); 147 kref_put(&cd->kref, sr_kref_release);
147 cd = NULL; 148 cd = NULL;
148 out: 149 out:
149 up(&sr_ref_sem); 150 mutex_unlock(&sr_ref_mutex);
150 return cd; 151 return cd;
151} 152}
152 153
@@ -154,10 +155,10 @@ static inline void scsi_cd_put(struct scsi_cd *cd)
154{ 155{
155 struct scsi_device *sdev = cd->device; 156 struct scsi_device *sdev = cd->device;
156 157
157 down(&sr_ref_sem); 158 mutex_lock(&sr_ref_mutex);
158 kref_put(&cd->kref, sr_kref_release); 159 kref_put(&cd->kref, sr_kref_release);
159 scsi_device_put(sdev); 160 scsi_device_put(sdev);
160 up(&sr_ref_sem); 161 mutex_unlock(&sr_ref_mutex);
161} 162}
162 163
163/* 164/*
@@ -237,8 +238,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
237 case ILLEGAL_REQUEST: 238 case ILLEGAL_REQUEST:
238 if (!(SCpnt->sense_buffer[0] & 0x90)) 239 if (!(SCpnt->sense_buffer[0] & 0x90))
239 break; 240 break;
240 if (!blk_fs_request(SCpnt->request))
241 break;
242 error_sector = (SCpnt->sense_buffer[3] << 24) | 241 error_sector = (SCpnt->sense_buffer[3] << 24) |
243 (SCpnt->sense_buffer[4] << 16) | 242 (SCpnt->sense_buffer[4] << 16) |
244 (SCpnt->sense_buffer[5] << 8) | 243 (SCpnt->sense_buffer[5] << 8) |
@@ -317,23 +316,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
317 } 316 }
318 317
319 /* 318 /*
320 * these are already setup, just copy cdb basically
321 */
322 if (SCpnt->request->flags & REQ_BLOCK_PC) {
323 scsi_setup_blk_pc_cmnd(SCpnt);
324
325 if (SCpnt->timeout_per_command)
326 timeout = SCpnt->timeout_per_command;
327
328 goto queue;
329 }
330
331 if (!(SCpnt->request->flags & REQ_CMD)) {
332 blk_dump_rq_flags(SCpnt->request, "sr unsup command");
333 return 0;
334 }
335
336 /*
337 * we do lazy blocksize switching (when reading XA sectors, 319 * we do lazy blocksize switching (when reading XA sectors,
338 * see CDROMREADMODE2 ioctl) 320 * see CDROMREADMODE2 ioctl)
339 */ 321 */
@@ -421,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
421 */ 403 */
422 SCpnt->transfersize = cd->device->sector_size; 404 SCpnt->transfersize = cd->device->sector_size;
423 SCpnt->underflow = this_count << 9; 405 SCpnt->underflow = this_count << 9;
424
425queue:
426 SCpnt->allowed = MAX_RETRIES; 406 SCpnt->allowed = MAX_RETRIES;
427 SCpnt->timeout_per_command = timeout; 407 SCpnt->timeout_per_command = timeout;
428 408
@@ -762,8 +742,9 @@ static void get_capabilities(struct scsi_cd *cd)
762 /* failed, drive doesn't have capabilities mode page */ 742 /* failed, drive doesn't have capabilities mode page */
763 cd->cdi.speed = 1; 743 cd->cdi.speed = 1;
764 cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | 744 cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
765 CDC_DVD | CDC_DVD_RAM | 745 CDC_DVD | CDC_DVD_RAM |
766 CDC_SELECT_DISC | CDC_SELECT_SPEED); 746 CDC_SELECT_DISC | CDC_SELECT_SPEED |
747 CDC_MRW | CDC_MRW_W | CDC_RAM);
767 kfree(buffer); 748 kfree(buffer);
768 printk("%s: scsi-1 drive\n", cd->cdi.name); 749 printk("%s: scsi-1 drive\n", cd->cdi.name);
769 return; 750 return;
@@ -845,7 +826,7 @@ static int sr_packet(struct cdrom_device_info *cdi,
845 * sr_kref_release - Called to free the scsi_cd structure 826 * sr_kref_release - Called to free the scsi_cd structure
846 * @kref: pointer to embedded kref 827 * @kref: pointer to embedded kref
847 * 828 *
848 * sr_ref_sem must be held entering this routine. Because it is 829 * sr_ref_mutex must be held entering this routine. Because it is
849 * called on last put, you should always use the scsi_cd_get() 830 * called on last put, you should always use the scsi_cd_get()
850 * scsi_cd_put() helpers which manipulate the semaphore directly 831 * scsi_cd_put() helpers which manipulate the semaphore directly
851 * and never do a direct kref_put(). 832 * and never do a direct kref_put().
@@ -874,9 +855,9 @@ static int sr_remove(struct device *dev)
874 855
875 del_gendisk(cd->disk); 856 del_gendisk(cd->disk);
876 857
877 down(&sr_ref_sem); 858 mutex_lock(&sr_ref_mutex);
878 kref_put(&cd->kref, sr_kref_release); 859 kref_put(&cd->kref, sr_kref_release);
879 up(&sr_ref_sem); 860 mutex_unlock(&sr_ref_mutex);
880 861
881 return 0; 862 return 0;
882} 863}