ide-cd: remove struct atapi_capabilities_page (take 2)
* 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>
This commit is contained in:
parent
0ba11211f9
commit
455d80a955
2 changed files with 37 additions and 248 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
#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;
|
||||
|
|
Loading…
Reference in a new issue