PNPACPI: ignore the producer/consumer bit for extended IRQ descriptors
[safe/jmp/linux-2.6] / drivers / ide / ide-cd.c
index 52fe3b9..89a112d 100644 (file)
@@ -57,24 +57,32 @@ static DEFINE_MUTEX(idecd_ref_mutex);
 #define ide_cd_g(disk) \
        container_of((disk)->private_data, struct cdrom_info, driver)
 
+static void ide_cd_release(struct kref *);
+
 static struct cdrom_info *ide_cd_get(struct gendisk *disk)
 {
        struct cdrom_info *cd = NULL;
 
        mutex_lock(&idecd_ref_mutex);
        cd = ide_cd_g(disk);
-       if (cd)
-               kref_get(&cd->kref);
+       if (cd) {
+               if (ide_device_get(cd->drive))
+                       cd = NULL;
+               else
+                       kref_get(&cd->kref);
+
+       }
        mutex_unlock(&idecd_ref_mutex);
        return cd;
 }
 
-static void ide_cd_release(struct kref *);
-
 static void ide_cd_put(struct cdrom_info *cd)
 {
+       ide_drive_t *drive = cd->drive;
+
        mutex_lock(&idecd_ref_mutex);
        kref_put(&cd->kref, ide_cd_release);
+       ide_device_put(drive);
        mutex_unlock(&idecd_ref_mutex);
 }
 
@@ -1284,7 +1292,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
         */
        cmd[7] = cdi->sanyo_slot % 3;
 
-       return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET);
+       return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET);
 }
 
 static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
@@ -1292,26 +1300,45 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
                               struct request_sense *sense)
 {
        struct {
-               __u32 lba;
-               __u32 blocklen;
+               __be32 lba;
+               __be32 blocklen;
        } capbuf;
 
        int stat;
        unsigned char cmd[BLK_MAX_CDB];
        unsigned len = sizeof(capbuf);
+       u32 blocklen;
 
        memset(cmd, 0, BLK_MAX_CDB);
        cmd[0] = GPCMD_READ_CDVD_CAPACITY;
 
        stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
                               REQ_QUIET);
-       if (stat == 0) {
-               *capacity = 1 + be32_to_cpu(capbuf.lba);
-               *sectors_per_frame =
-                       be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
+       if (stat)
+               return stat;
+
+       /*
+        * Sanity check the given block size
+        */
+       blocklen = be32_to_cpu(capbuf.blocklen);
+       switch (blocklen) {
+       case 512:
+       case 1024:
+       case 2048:
+       case 4096:
+               break;
+       default:
+               printk(KERN_ERR "%s: weird block size %u\n",
+                       drive->name, blocklen);
+               printk(KERN_ERR "%s: default to 2kb block size\n",
+                       drive->name);
+               blocklen = 2048;
+               break;
        }
 
-       return stat;
+       *capacity = 1 + be32_to_cpu(capbuf.lba);
+       *sectors_per_frame = blocklen >> SECTOR_BITS;
+       return 0;
 }
 
 static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
@@ -1526,15 +1553,12 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
        struct cdrom_info *cd = drive->driver_data;
        u16 curspeed, maxspeed;
 
-       curspeed = *(u16 *)&buf[8 + 14];
-       maxspeed = *(u16 *)&buf[8 +  8];
-
        if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
-               curspeed = le16_to_cpu(curspeed);
-               maxspeed = le16_to_cpu(maxspeed);
+               curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
+               maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]);
        } else {
-               curspeed = be16_to_cpu(curspeed);
-               maxspeed = be16_to_cpu(maxspeed);
+               curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]);
+               maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
        }
 
        cd->current_speed = (curspeed + (176/2)) / 176;
@@ -1675,7 +1699,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
        else
                printk(KERN_CONT " drive");
 
-       printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(*(u16 *)&buf[8 + 12]));
+       printk(KERN_CONT ", %dkB Cache\n", be16_to_cpup((__be16 *)&buf[8 + 12]));
 
        return nslots;
 }