diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4e73aeee4053..e617cf08aef6 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -57,23 +57,29 @@ static DEFINE_MUTEX(idecd_ref_mutex); | |||
57 | #define ide_cd_g(disk) \ | 57 | #define ide_cd_g(disk) \ |
58 | container_of((disk)->private_data, struct cdrom_info, driver) | 58 | container_of((disk)->private_data, struct cdrom_info, driver) |
59 | 59 | ||
60 | static void ide_cd_release(struct kref *); | ||
61 | |||
60 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) | 62 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) |
61 | { | 63 | { |
62 | struct cdrom_info *cd = NULL; | 64 | struct cdrom_info *cd = NULL; |
63 | 65 | ||
64 | mutex_lock(&idecd_ref_mutex); | 66 | mutex_lock(&idecd_ref_mutex); |
65 | cd = ide_cd_g(disk); | 67 | cd = ide_cd_g(disk); |
66 | if (cd) | 68 | if (cd) { |
67 | kref_get(&cd->kref); | 69 | kref_get(&cd->kref); |
70 | if (ide_device_get(cd->drive)) { | ||
71 | kref_put(&cd->kref, ide_cd_release); | ||
72 | cd = NULL; | ||
73 | } | ||
74 | } | ||
68 | mutex_unlock(&idecd_ref_mutex); | 75 | mutex_unlock(&idecd_ref_mutex); |
69 | return cd; | 76 | return cd; |
70 | } | 77 | } |
71 | 78 | ||
72 | static void ide_cd_release(struct kref *); | ||
73 | |||
74 | static void ide_cd_put(struct cdrom_info *cd) | 79 | static void ide_cd_put(struct cdrom_info *cd) |
75 | { | 80 | { |
76 | mutex_lock(&idecd_ref_mutex); | 81 | mutex_lock(&idecd_ref_mutex); |
82 | ide_device_put(cd->drive); | ||
77 | kref_put(&cd->kref, ide_cd_release); | 83 | kref_put(&cd->kref, ide_cd_release); |
78 | mutex_unlock(&idecd_ref_mutex); | 84 | mutex_unlock(&idecd_ref_mutex); |
79 | } | 85 | } |
@@ -1305,13 +1311,30 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
1305 | 1311 | ||
1306 | stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, | 1312 | stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, |
1307 | REQ_QUIET); | 1313 | REQ_QUIET); |
1308 | if (stat == 0) { | 1314 | if (stat) |
1309 | *capacity = 1 + be32_to_cpu(capbuf.lba); | 1315 | return stat; |
1310 | *sectors_per_frame = | 1316 | |
1311 | be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS; | 1317 | /* |
1318 | * Sanity check the given block size | ||
1319 | */ | ||
1320 | switch (capbuf.blocklen) { | ||
1321 | case __constant_cpu_to_be32(512): | ||
1322 | case __constant_cpu_to_be32(1024): | ||
1323 | case __constant_cpu_to_be32(2048): | ||
1324 | case __constant_cpu_to_be32(4096): | ||
1325 | break; | ||
1326 | default: | ||
1327 | printk(KERN_ERR "%s: weird block size %u\n", | ||
1328 | drive->name, capbuf.blocklen); | ||
1329 | printk(KERN_ERR "%s: default to 2kb block size\n", | ||
1330 | drive->name); | ||
1331 | capbuf.blocklen = __constant_cpu_to_be32(2048); | ||
1332 | break; | ||
1312 | } | 1333 | } |
1313 | 1334 | ||
1314 | return stat; | 1335 | *capacity = 1 + be32_to_cpu(capbuf.lba); |
1336 | *sectors_per_frame = be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS; | ||
1337 | return 0; | ||
1315 | } | 1338 | } |
1316 | 1339 | ||
1317 | static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, | 1340 | static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, |