Commit 9235e68b authored by Eric Piel's avatar Eric Piel Committed by Linus Torvalds

[PATCH] IDE CD reports current speed

The current ide-cd driver reports the CDROM speed (as found in
/proc/sys/dev/cdrom/info) as the current speed when loading the driver.
Changing the speed of the cdrom drive (by "eject -x" for instance) doesn't
update the speed reported by the kernel.  Updating the info could be
valuable for the user as it's the only way to know if the drive accepted
the request or discarded it.  It could even be used to list all the
available speeds of the drive.

The attached patch modifies the ide-cd driver so that after every speed
change request the new speed is updated.  Please note that the actual
modification is very little but I had to touch quite a few lines in order
to avoid to pre-declare the sub-functions.
Signed-off-by: default avatarEric Piel <eric.piel@tremplin-utc.net>
Acked-by: default avatarJens Axboe <axboe@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 451512f3
...@@ -2656,17 +2656,64 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock) ...@@ -2656,17 +2656,64 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
return cdrom_lockdoor(drive, lock, NULL); return cdrom_lockdoor(drive, lock, NULL);
} }
static
int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
{
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);
/*
* ACER50 (and others?) require the full spec length mode sense
* page capabilities size, but older drives break.
*/
if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
!strcmp(drive->id->model, "WPI CDS-32X")))
size -= sizeof(cap->pad);
init_cdrom_command(&cgc, cap, 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)
break;
} while (--attempts);
return stat;
}
static
void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
{
/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
if (!drive->id->model[0] &&
!strncmp(drive->id->fw_rev, "241N", 4)) {
CDROM_STATE_FLAGS(drive)->current_speed =
(((unsigned int)cap->curspeed) + (176/2)) / 176;
CDROM_CONFIG_FLAGS(drive)->max_speed =
(((unsigned int)cap->maxspeed) + (176/2)) / 176;
} else {
CDROM_STATE_FLAGS(drive)->current_speed =
(ntohs(cap->curspeed) + (176/2)) / 176;
CDROM_CONFIG_FLAGS(drive)->max_speed =
(ntohs(cap->maxspeed) + (176/2)) / 176;
}
}
static static
int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
{ {
ide_drive_t *drive = (ide_drive_t*) cdi->handle; ide_drive_t *drive = (ide_drive_t*) cdi->handle;
struct request_sense sense; struct request_sense sense;
struct atapi_capabilities_page cap;
int stat; int stat;
if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0) if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
return stat; return stat;
if (!ide_cdrom_get_capabilities(drive, &cap)) {
ide_cdrom_update_speed(drive, &cap);
cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed; cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
}
return 0; return 0;
} }
...@@ -2868,31 +2915,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) ...@@ -2868,31 +2915,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
return register_cdrom(devinfo); return register_cdrom(devinfo);
} }
static
int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
{
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);
/*
* ACER50 (and others?) require the full spec length mode sense
* page capabilities size, but older drives break.
*/
if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
!strcmp(drive->id->model, "WPI CDS-32X")))
size -= sizeof(cap->pad);
init_cdrom_command(&cgc, cap, 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)
break;
} while (--attempts);
return stat;
}
static static
int ide_cdrom_probe_capabilities (ide_drive_t *drive) int ide_cdrom_probe_capabilities (ide_drive_t *drive)
{ {
...@@ -2978,20 +3000,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) ...@@ -2978,20 +3000,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
} }
} }
/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ ide_cdrom_update_speed(drive, &cap);
if (!drive->id->model[0] &&
!strncmp(drive->id->fw_rev, "241N", 4)) {
CDROM_STATE_FLAGS(drive)->current_speed =
(((unsigned int)cap.curspeed) + (176/2)) / 176;
CDROM_CONFIG_FLAGS(drive)->max_speed =
(((unsigned int)cap.maxspeed) + (176/2)) / 176;
} else {
CDROM_STATE_FLAGS(drive)->current_speed =
(ntohs(cap.curspeed) + (176/2)) / 176;
CDROM_CONFIG_FLAGS(drive)->max_speed =
(ntohs(cap.maxspeed) + (176/2)) / 176;
}
/* don't print speed if the drive reported 0. /* don't print speed if the drive reported 0.
*/ */
printk(KERN_INFO "%s: ATAPI", drive->name); printk(KERN_INFO "%s: ATAPI", drive->name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment