diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
commit | 95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch) | |
tree | 27a92a942821cde1edda9a1b088718d436b3efe4 /drivers/block/ide-cd.c | |
parent | 45b27b0a0652331d104c953a5b192d843fff88f8 (diff) |
Merge with Linux 2.3.40.
Diffstat (limited to 'drivers/block/ide-cd.c')
-rw-r--r-- | drivers/block/ide-cd.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c index ebfef4273..48cf87c81 100644 --- a/drivers/block/ide-cd.c +++ b/drivers/block/ide-cd.c @@ -2005,9 +2005,60 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock) return cdrom_lockdoor (drive, lock); } +#undef __ACER50__ + +#ifdef __ACER50__ +/* + * the buffer struct used by ide_cdrom_get_capabilities() + */ +struct get_capabilities_buf { + char pad[8]; + struct atapi_capabilities_page cap; /* this is 4 bytes short of ATAPI standard */ + char extra_cap[4]; /* Acer 50X needs the regulation size buffer */ +}; + +static +int ide_cdrom_get_capabilities (struct cdrom_device_info *cdi, struct get_capabilities_buf *buf) +{ + int stat, attempts = 3, buflen = sizeof(*buf); + ide_drive_t *drive = (ide_drive_t*) cdi->handle; + struct cdrom_generic_command cgc; + + /* + * Most drives don't care about the buffer size; + * they return as much info as there's room for. + * But some older drives (?) had trouble with the + * standard size, preferring 4 bytes less. + * And the modern Acer 50X rejects anything smaller + * than the standard size. + */ + if (!(drive->id && !strcmp(drive->id->model,"ATAPI CD ROM DRIVE 50X MAX"))) + buflen -= sizeof(buf->extra_cap); /* for all drives except Acer 50X */ + + do { /* we seem to get stat=0x01,err=0x00 the first time (??) */ + stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); + if (stat == 0) { + /* + * The ACER/AOpen 24X cdrom has the speed + * fields byte-swapped from the standard. + */ + if (!(drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4))) { + buf->cap.curspeed = ntohs(buf->cap.curspeed); + buf->cap.maxspeed = ntohs(buf->cap.maxspeed); + } + CDROM_STATE_FLAGS (drive)->current_speed = (((unsigned int)buf->cap.curspeed) + (176/2)) / 176; + CDROM_CONFIG_FLAGS(drive)->max_speed = (((unsigned int)buf->cap.maxspeed) + (176/2)) / 176; + return 0; + } + } while (--attempts); + return stat; +} +#endif /* __ACER50__ */ + static int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) { +#ifndef __ACER50__ int stat, attempts = 3; ide_drive_t *drive = (ide_drive_t*) cdi->handle; struct cdrom_generic_command cgc; @@ -2015,11 +2066,19 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) char pad[8]; struct atapi_capabilities_page cap; } buf; +#else + int stat; + ide_drive_t *drive = (ide_drive_t*) cdi->handle; + struct cdrom_generic_command cgc; + struct get_capabilities_buf buf; +#endif /* __ACER50__ */ if ((stat = cdrom_select_speed (drive, speed)) < 0) return stat; init_cdrom_command(&cgc, &buf, sizeof(buf)); + +#ifndef __ACER50__ /* Now with that done, update the speed fields */ do { /* we seem to get stat=0x01,err=0x00 the first time (??) */ if (attempts-- <= 0) @@ -2039,6 +2098,11 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) CDROM_CONFIG_FLAGS (drive)->max_speed = (ntohs(buf.cap.maxspeed) + (176/2)) / 176; } +#else + if (ide_cdrom_get_capabilities(cdi,&buf)) + return 0; +#endif /* __ACER50__ */ + cdi->speed = CDROM_STATE_FLAGS (drive)->current_speed; return 0; } @@ -2216,12 +2280,18 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; +#ifndef __ACER50__ int stat, nslots = 1, attempts = 3; struct cdrom_generic_command cgc; struct { char pad[8]; struct atapi_capabilities_page cap; } buf; +#else + int nslots = 1; + struct cdrom_generic_command cgc; + struct get_capabilities_buf buf; +#endif /* __ACER50__ */ if (CDROM_CONFIG_FLAGS (drive)->nec260) { CDROM_CONFIG_FLAGS (drive)->no_eject = 0; @@ -2238,12 +2308,17 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) */ cdi->handle = (ide_drive_t *) drive; cdi->ops = &ide_cdrom_dops; +#ifndef __ACER50__ /* we seem to get stat=0x01,err=0x00 the first time (??) */ do { if (attempts-- <= 0) return 0; stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); } while (stat); +#else + if (ide_cdrom_get_capabilities(cdi,&buf)) + return 0; +#endif /* __ACER50__ */ if (buf.cap.lock == 0) CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1; @@ -2282,6 +2357,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) } } +#ifndef __ACER50__ /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ if (drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) { CDROM_STATE_FLAGS (drive)->current_speed = @@ -2294,6 +2370,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) CDROM_CONFIG_FLAGS (drive)->max_speed = (ntohs(buf.cap.maxspeed) + (176/2)) / 176; } +#endif /* __ACER50__ */ /* don't print speed if the drive reported 0. */ @@ -2321,7 +2398,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) if (drive->using_dma) { if ((drive->id->field_valid & 4) && - (drive->id->word93 & 0x2000) && + (drive->id->hw_config & 0x2000) && (HWIF(drive)->udma_four) && (drive->id->dma_ultra & (drive->id->dma_ultra >> 11) & 3)) { printk(", UDMA(66)"); /* UDMA BIOS-enabled! */ @@ -2598,7 +2675,7 @@ void __exit ide_cdrom_exit(void) } #endif /* MODULE */ -int __init ide_cdrom_init (void) +int ide_cdrom_init (void) { ide_drive_t *drive; struct cdrom_info *info; |