ide-cd: remove struct atapi_capabilities_page (take 2)
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 1 Feb 2008 22:09:21 +0000 (23:09 +0100)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 1 Feb 2008 22:09:21 +0000 (23:09 +0100)
* Remove struct atapi_capabilities_page.

* Add ATAPI_CAPABILITIES_PAGE[_PAD]_SIZE define.

v2:
* The buf[] array access indexes were swapped between 'curspeed'/'maxspeed'.
  (Noticed by Borislav Petkov).

Cc: Borislav Petkov <bbpetkov@yahoo.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
drivers/ide/ide-cd.c
drivers/ide/ide-cd.h

index 59981a0431824b8dc87194635d09ee28c3a265c7..ab1cdce806ec59b5e5e09b19f941ddad097da2b1 100644 (file)
@@ -2394,13 +2394,12 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
        return cdrom_lockdoor(drive, lock, NULL);
 }
 
-static
-int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
+static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
 {
        struct cdrom_info *info = drive->driver_data;
        struct cdrom_device_info *cdi = &info->devinfo;
        struct packet_command cgc;
-       int stat, attempts = 3, size = sizeof(*cap);
+       int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
 
        /*
         * ACER50 (and others?) require the full spec length mode sense
@@ -2408,9 +2407,9 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_pag
         */
        if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
            !strcmp(drive->id->model, "WPI CDS-32X")))
-               size -= sizeof(cap->pad);
+               size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
 
-       init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
+       init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
        do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
                stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
                if (!stat)
@@ -2419,20 +2418,22 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_pag
        return stat;
 }
 
-static
-void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
+static 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];
+
        /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
        if (!drive->id->model[0] &&
            !strncmp(drive->id->fw_rev, "241N", 4)) {
-               curspeed = le16_to_cpu(cap->curspeed);
-               maxspeed = le16_to_cpu(cap->maxspeed);
+               curspeed = le16_to_cpu(curspeed);
+               maxspeed = le16_to_cpu(maxspeed);
        } else {
-               curspeed = be16_to_cpu(cap->curspeed);
-               maxspeed = be16_to_cpu(cap->maxspeed);
+               curspeed = be16_to_cpu(curspeed);
+               maxspeed = be16_to_cpu(maxspeed);
        }
 
        cd->state_flags.current_speed = (curspeed + (176/2)) / 176;
@@ -2445,14 +2446,14 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
        ide_drive_t *drive = cdi->handle;
        struct cdrom_info *cd = drive->driver_data;
        struct request_sense sense;
-       struct atapi_capabilities_page cap;
+       u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
        int stat;
 
        if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
                return stat;
 
-       if (!ide_cdrom_get_capabilities(drive, &cap)) {
-               ide_cdrom_update_speed(drive, &cap);
+       if (!ide_cdrom_get_capabilities(drive, buf)) {
+               ide_cdrom_update_speed(drive, buf);
                cdi->speed = cd->state_flags.current_speed;
        }
         return 0;
@@ -2636,7 +2637,8 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
 {
        struct cdrom_info *cd = drive->driver_data;
        struct cdrom_device_info *cdi = &cd->devinfo;
-       struct atapi_capabilities_page cap;
+       u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
+       mechtype_t mechtype;
        int nslots = 1;
 
        cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
@@ -2666,26 +2668,28 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
        cdi->handle = drive;
        cdi->ops = &ide_cdrom_dops;
 
-       if (ide_cdrom_get_capabilities(drive, &cap))
+       if (ide_cdrom_get_capabilities(drive, buf))
                return 0;
 
-       if (cap.lock == 0)
+       if ((buf[8 + 6] & 0x01) == 0)
                cd->config_flags.no_doorlock = 1;
-       if (cap.eject)
+       if (buf[8 + 6] & 0x08)
                cd->config_flags.no_eject = 0;
-       if (cap.cd_r_write)
+       if (buf[8 + 3] & 0x01)
                cdi->mask &= ~CDC_CD_R;
-       if (cap.cd_rw_write)
+       if (buf[8 + 3] & 0x02)
                cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
-       if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom)
+       if (buf[8 + 2] & 0x38)
                cdi->mask &= ~CDC_DVD;
-       if (cap.dvd_ram_write)
+       if (buf[8 + 3] & 0x20)
                cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
-       if (cap.dvd_r_write)
+       if (buf[8 + 3] & 0x10)
                cdi->mask &= ~CDC_DVD_R;
-       if (cap.audio_play)
+       if (buf[8 + 4] & 0x01)
                cdi->mask &= ~CDC_PLAY_AUDIO;
-       if (cap.mechtype == mechtype_caddy || cap.mechtype == mechtype_popup)
+
+       mechtype = buf[8 + 6] >> 5;
+       if (mechtype == mechtype_caddy || mechtype == mechtype_popup)
                cdi->mask |= CDC_CLOSE_TRAY;
 
        /* Some drives used by Apple don't advertise audio play
@@ -2705,14 +2709,14 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
 
        else
 #endif /* not STANDARD_ATAPI */
-       if (cap.mechtype == mechtype_individual_changer ||
-           cap.mechtype == mechtype_cartridge_changer) {
+       if (mechtype == mechtype_individual_changer ||
+           mechtype == mechtype_cartridge_changer) {
                nslots = cdrom_number_of_slots(cdi);
                if (nslots > 1)
                        cdi->mask &= ~CDC_SELECT_DISC;
        }
 
-       ide_cdrom_update_speed(drive, &cap);
+       ide_cdrom_update_speed(drive, buf);
 
        printk(KERN_INFO "%s: ATAPI", drive->name);
 
@@ -2737,7 +2741,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
        else
                printk(KERN_CONT " drive");
 
-       printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(cap.buffer_size));
+       printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(*(u16 *)&buf[8 + 12]));
 
        return nslots;
 }
index 8dbe346b4b444af0a70d2b83a89f99f01bd111dc..9d88b1a7ffe590b7cc90508f30f41cadc81666fd 100644 (file)
 #define SECTORS_PER_FRAME      (CD_FRAMESIZE >> SECTOR_BITS)
 #define SECTOR_BUFFER_SIZE     (CD_FRAMESIZE * 32)
 
+/* Capabilities Page size including 8 bytes of Mode Page Header */
+#define ATAPI_CAPABILITIES_PAGE_SIZE           (8 + 20)
+#define ATAPI_CAPABILITIES_PAGE_PAD_SIZE       4
+
 /* Configuration flags.  These describe the capabilities of the drive.
    They generally do not change after initialization, unless we learn
    more about the drive from stuff failing. */
@@ -124,225 +128,6 @@ struct atapi_toc {
          /* One extra for the leadout. */
 };
 
-/* This should probably go into cdrom.h along with the other
- * generic stuff now in the Mt. Fuji spec.
- */
-struct atapi_capabilities_page {
-       struct mode_page_header header;
-#if defined(__BIG_ENDIAN_BITFIELD)
-       __u8 parameters_saveable : 1;
-       __u8 reserved1           : 1;
-       __u8 page_code           : 6;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-       __u8 page_code           : 6;
-       __u8 reserved1           : 1;
-       __u8 parameters_saveable : 1;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-       byte     page_length;
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-       __u8 reserved2           : 2;
-       /* Drive supports reading of DVD-RAM discs */
-       __u8 dvd_ram_read        : 1;
-       /* Drive supports reading of DVD-R discs */
-       __u8 dvd_r_read          : 1;
-       /* Drive supports reading of DVD-ROM discs */
-       __u8 dvd_rom             : 1;
-       /* Drive supports reading CD-R discs with addressing method 2 */
-       __u8 method2             : 1; /* reserved in 1.2 */
-       /* Drive can read from CD-R/W (CD-E) discs (orange book, part III) */
-       __u8 cd_rw_read          : 1; /* reserved in 1.2 */
-       /* Drive supports read from CD-R discs (orange book, part II) */
-       __u8 cd_r_read           : 1; /* reserved in 1.2 */
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-       /* Drive supports read from CD-R discs (orange book, part II) */
-       __u8 cd_r_read           : 1; /* reserved in 1.2 */
-       /* Drive can read from CD-R/W (CD-E) discs (orange book, part III) */
-       __u8 cd_rw_read          : 1; /* reserved in 1.2 */
-       /* Drive supports reading CD-R discs with addressing method 2 */
-       __u8 method2             : 1;
-       /* Drive supports reading of DVD-ROM discs */
-       __u8 dvd_rom             : 1;
-       /* Drive supports reading of DVD-R discs */
-       __u8 dvd_r_read          : 1;
-       /* Drive supports reading of DVD-RAM discs */
-       __u8 dvd_ram_read        : 1;
-       __u8 reserved2           : 2;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-       __u8 reserved3           : 2;
-       /* Drive can write DVD-RAM discs */
-       __u8 dvd_ram_write       : 1;
-       /* Drive can write DVD-R discs */
-       __u8 dvd_r_write         : 1;
-       __u8 reserved3a          : 1;
-       /* Drive can fake writes */
-       __u8 test_write          : 1;
-       /* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
-       __u8 cd_rw_write         : 1; /* reserved in 1.2 */
-       /* Drive supports write to CD-R discs (orange book, part II) */
-       __u8 cd_r_write          : 1; /* reserved in 1.2 */
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-       /* Drive can write to CD-R discs (orange book, part II) */
-       __u8 cd_r_write          : 1; /* reserved in 1.2 */
-       /* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
-       __u8 cd_rw_write         : 1; /* reserved in 1.2 */
-       /* Drive can fake writes */
-       __u8 test_write          : 1;
-       __u8 reserved3a          : 1;
-       /* Drive can write DVD-R discs */
-       __u8 dvd_r_write         : 1;
-       /* Drive can write DVD-RAM discs */
-       __u8 dvd_ram_write       : 1;
-       __u8 reserved3           : 2;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-       __u8 reserved4           : 1;
-       /* Drive can read multisession discs. */
-       __u8 multisession        : 1;
-       /* Drive can read mode 2, form 2 data. */
-       __u8 mode2_form2         : 1;
-       /* Drive can read mode 2, form 1 (XA) data. */
-       __u8 mode2_form1         : 1;
-       /* Drive supports digital output on port 2. */
-       __u8 digport2            : 1;
-       /* Drive supports digital output on port 1. */
-       __u8 digport1            : 1;
-       /* Drive can deliver a composite audio/video data stream. */
-       __u8 composite           : 1;
-       /* Drive supports audio play operations. */
-       __u8 audio_play          : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-       /* Drive supports audio play operations. */
-       __u8 audio_play          : 1;
-       /* Drive can deliver a composite audio/video data stream. */
-       __u8 composite           : 1;
-       /* Drive supports digital output on port 1. */
-       __u8 digport1            : 1;
-       /* Drive supports digital output on port 2. */
-       __u8 digport2            : 1;
-       /* Drive can read mode 2, form 1 (XA) data. */
-       __u8 mode2_form1         : 1;
-       /* Drive can read mode 2, form 2 data. */
-       __u8 mode2_form2         : 1;
-       /* Drive can read multisession discs. */
-       __u8 multisession        : 1;
-       __u8 reserved4           : 1;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-       __u8 reserved5           : 1;
-       /* Drive can return Media Catalog Number (UPC) info. */
-       __u8 upc                 : 1;
-       /* Drive can return International Standard Recording Code info. */
-       __u8 isrc                : 1;
-       /* Drive supports C2 error pointers. */
-       __u8 c2_pointers         : 1;
-       /* R-W data will be returned deinterleaved and error corrected. */
-       __u8 rw_corr             : 1;
-       /* Subchannel reads can return combined R-W information. */
-       __u8 rw_supported        : 1;
-       /* Drive can continue a read cdda operation from a loss of streaming.*/
-       __u8 cdda_accurate       : 1;
-       /* Drive can read Red Book audio data. */
-       __u8 cdda                : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-       /* Drive can read Red Book audio data. */
-       __u8 cdda                : 1;
-       /* Drive can continue a read cdda operation from a loss of streaming.*/
-       __u8 cdda_accurate       : 1;
-       /* Subchannel reads can return combined R-W information. */
-       __u8 rw_supported        : 1;
-       /* R-W data will be returned deinterleaved and error corrected. */
-       __u8 rw_corr             : 1;
-       /* Drive supports C2 error pointers. */
-       __u8 c2_pointers         : 1;
-       /* Drive can return International Standard Recording Code info. */
-       __u8 isrc                : 1;
-       /* Drive can return Media Catalog Number (UPC) info. */
-       __u8 upc                 : 1;
-       __u8 reserved5           : 1;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-       /* Drive mechanism types. */
-       mechtype_t mechtype      : 3;
-       __u8 reserved6           : 1;
-       /* Drive can eject a disc or changer cartridge. */
-       __u8 eject               : 1;
-       /* State of prevent/allow jumper. */
-       __u8 prevent_jumper      : 1;
-       /* Present state of door lock. */
-       __u8 lock_state          : 1;
-       /* Drive can lock the door. */
-       __u8 lock                : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-
-       /* Drive can lock the door. */
-       __u8 lock                : 1;
-       /* Present state of door lock. */
-       __u8 lock_state          : 1;
-       /* State of prevent/allow jumper. */
-       __u8 prevent_jumper      : 1;
-       /* Drive can eject a disc or changer cartridge. */
-       __u8 eject               : 1;
-       __u8 reserved6           : 1;
-       /* Drive mechanism types. */
-       mechtype_t mechtype      : 3;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-       __u8 reserved7           : 4;
-       /* Drive supports software slot selection. */
-       __u8 sss                 : 1;  /* reserved in 1.2 */
-       /* Changer can report exact contents of slots. */
-       __u8 disc_present        : 1;  /* reserved in 1.2 */
-       /* Audio for each channel can be muted independently. */
-       __u8 separate_mute       : 1;
-       /* Audio level for each channel can be controlled independently. */
-       __u8 separate_volume     : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
-
-       /* Audio level for each channel can be controlled independently. */
-       __u8 separate_volume     : 1;
-       /* Audio for each channel can be muted independently. */
-       __u8 separate_mute       : 1;
-       /* Changer can report exact contents of slots. */
-       __u8 disc_present        : 1;  /* reserved in 1.2 */
-       /* Drive supports software slot selection. */
-       __u8 sss                 : 1;  /* reserved in 1.2 */
-       __u8 reserved7           : 4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-
-       /* Note: the following four fields are returned in big-endian form. */
-       /* Maximum speed (in kB/s). */
-       unsigned short maxspeed;
-       /* Number of discrete volume levels. */
-       unsigned short n_vol_levels;
-       /* Size of cache in drive, in kB. */
-       unsigned short buffer_size;
-       /* Current speed (in kB/s). */
-       unsigned short curspeed;
-       char pad[4];
-};
-
 /* Extra per-device info for cdrom drives. */
 struct cdrom_info {
        ide_drive_t     *drive;