aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
authorEric Piel <Eric.Piel@tremplin-utc.net>2005-06-23 03:10:29 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:45:35 -0400
commit9235e68be8bf8974b65a9bf733c9d12a52307839 (patch)
tree6d31812e14dcbfab9b6a6d7c11b3dade004fd8a5 /drivers/ide/ide-cd.c
parent451512f3aed64573e912e68c94f240fec0e44438 (diff)
[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: Eric Piel <eric.piel@tremplin-utc.net> Acked-by: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c89
1 files changed, 49 insertions, 40 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 39f3e9101ed4..0a31cfda08a0 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2657,16 +2657,63 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2657} 2657}
2658 2658
2659static 2659static
2660int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
2661{
2662 struct cdrom_info *info = drive->driver_data;
2663 struct cdrom_device_info *cdi = &info->devinfo;
2664 struct packet_command cgc;
2665 int stat, attempts = 3, size = sizeof(*cap);
2666
2667 /*
2668 * ACER50 (and others?) require the full spec length mode sense
2669 * page capabilities size, but older drives break.
2670 */
2671 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2672 !strcmp(drive->id->model, "WPI CDS-32X")))
2673 size -= sizeof(cap->pad);
2674
2675 init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
2676 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2677 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2678 if (!stat)
2679 break;
2680 } while (--attempts);
2681 return stat;
2682}
2683
2684static
2685void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
2686{
2687 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
2688 if (!drive->id->model[0] &&
2689 !strncmp(drive->id->fw_rev, "241N", 4)) {
2690 CDROM_STATE_FLAGS(drive)->current_speed =
2691 (((unsigned int)cap->curspeed) + (176/2)) / 176;
2692 CDROM_CONFIG_FLAGS(drive)->max_speed =
2693 (((unsigned int)cap->maxspeed) + (176/2)) / 176;
2694 } else {
2695 CDROM_STATE_FLAGS(drive)->current_speed =
2696 (ntohs(cap->curspeed) + (176/2)) / 176;
2697 CDROM_CONFIG_FLAGS(drive)->max_speed =
2698 (ntohs(cap->maxspeed) + (176/2)) / 176;
2699 }
2700}
2701
2702static
2660int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) 2703int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2661{ 2704{
2662 ide_drive_t *drive = (ide_drive_t*) cdi->handle; 2705 ide_drive_t *drive = (ide_drive_t*) cdi->handle;
2663 struct request_sense sense; 2706 struct request_sense sense;
2707 struct atapi_capabilities_page cap;
2664 int stat; 2708 int stat;
2665 2709
2666 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0) 2710 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2667 return stat; 2711 return stat;
2668 2712
2669 cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed; 2713 if (!ide_cdrom_get_capabilities(drive, &cap)) {
2714 ide_cdrom_update_speed(drive, &cap);
2715 cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
2716 }
2670 return 0; 2717 return 0;
2671} 2718}
2672 2719
@@ -2869,31 +2916,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2869} 2916}
2870 2917
2871static 2918static
2872int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
2873{
2874 struct cdrom_info *info = drive->driver_data;
2875 struct cdrom_device_info *cdi = &info->devinfo;
2876 struct packet_command cgc;
2877 int stat, attempts = 3, size = sizeof(*cap);
2878
2879 /*
2880 * ACER50 (and others?) require the full spec length mode sense
2881 * page capabilities size, but older drives break.
2882 */
2883 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2884 !strcmp(drive->id->model, "WPI CDS-32X")))
2885 size -= sizeof(cap->pad);
2886
2887 init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
2888 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2889 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2890 if (!stat)
2891 break;
2892 } while (--attempts);
2893 return stat;
2894}
2895
2896static
2897int ide_cdrom_probe_capabilities (ide_drive_t *drive) 2919int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2898{ 2920{
2899 struct cdrom_info *info = drive->driver_data; 2921 struct cdrom_info *info = drive->driver_data;
@@ -2978,20 +3000,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2978 } 3000 }
2979 } 3001 }
2980 3002
2981 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ 3003 ide_cdrom_update_speed(drive, &cap);
2982 if (!drive->id->model[0] &&
2983 !strncmp(drive->id->fw_rev, "241N", 4)) {
2984 CDROM_STATE_FLAGS(drive)->current_speed =
2985 (((unsigned int)cap.curspeed) + (176/2)) / 176;
2986 CDROM_CONFIG_FLAGS(drive)->max_speed =
2987 (((unsigned int)cap.maxspeed) + (176/2)) / 176;
2988 } else {
2989 CDROM_STATE_FLAGS(drive)->current_speed =
2990 (ntohs(cap.curspeed) + (176/2)) / 176;
2991 CDROM_CONFIG_FLAGS(drive)->max_speed =
2992 (ntohs(cap.maxspeed) + (176/2)) / 176;
2993 }
2994
2995 /* don't print speed if the drive reported 0. 3004 /* don't print speed if the drive reported 0.
2996 */ 3005 */
2997 printk(KERN_INFO "%s: ATAPI", drive->name); 3006 printk(KERN_INFO "%s: ATAPI", drive->name);