diff options
-rw-r--r-- | drivers/ide/ide-cd.c | 89 |
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 | ||
2659 | static | 2659 | static |
2660 | int 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 | |||
2684 | static | ||
2685 | void 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 | |||
2702 | static | ||
2660 | int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) | 2703 | int 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 | ||
2871 | static | 2918 | static |
2872 | int 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 | |||
2896 | static | ||
2897 | int ide_cdrom_probe_capabilities (ide_drive_t *drive) | 2919 | int 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); |