diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:22 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:22 -0500 |
commit | e59724c7db9afd14827f1b737605f54d47f2d226 (patch) | |
tree | ef89587dd3bc19d1271aec9b755c20ef6b186001 /drivers/ide | |
parent | 9a6dc668d9b4d639936c683879eb1e0f92c5b944 (diff) |
ide-cd: re-organize handling of quirky devices
Re-organize handling of quirky devices:
* Add struct cd_list_entry, ide_cd_quirks_list[] and ide_cd_flags() helper.
* Set flags returned by ide_cd_flags() in ide_cdrom_setup().
* Add IDE_CD_FLAG_VERTOS_{300_SDD,600_ESD} and IDE_CD_FLAG_SANYO_3CD flags.
* Move device quirks from ide_cdrom_setup() to ide_cd_quirks_list[].
* Rename IDE_CD_FLAG_NEC260 to IDE_CD_FLAG_PRE_ATAPI12 and handle
quirky Stingray 8X CD-ROM using ide_cd_quirks_list[].
* Add IDE_CD_FLAG_FULL_CAPS_PAGE flag and handle quirky ACER 50X CD-ROM
/ WPI 32X CD-ROM using ide_cd_quirk_list[].
* Add IDE_CD_FLAG_PLAY_AUDIO_OK flag and handle quirky MATSHITA DVD-ROMs
using ide_cd_quirks_list[].
* Add IDE_CD_FLAG_LE_SPEED_FIELDS flag and handle quirky ACER/AOpen 24X
CD-ROM using ide_cd_quirk_list[].
* Fix some comments about quirky devices while at it.
There should be no functionality changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cd.c | 140 | ||||
-rw-r--r-- | drivers/ide/ide-cd.h | 10 |
2 files changed, 85 insertions, 65 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4bd664dd1e44..bd552328014a 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -2377,12 +2377,7 @@ static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) | |||
2377 | struct packet_command cgc; | 2377 | struct packet_command cgc; |
2378 | int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; | 2378 | int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; |
2379 | 2379 | ||
2380 | /* | 2380 | if ((info->cd_flags & IDE_CD_FLAG_FULL_CAPS_PAGE) == 0) |
2381 | * ACER50 (and others?) require the full spec length mode sense | ||
2382 | * page capabilities size, but older drives break. | ||
2383 | */ | ||
2384 | if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || | ||
2385 | !strcmp(drive->id->model, "WPI CDS-32X"))) | ||
2386 | size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; | 2381 | size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; |
2387 | 2382 | ||
2388 | init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN); | 2383 | init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN); |
@@ -2402,9 +2397,7 @@ static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) | |||
2402 | curspeed = *(u16 *)&buf[8 + 14]; | 2397 | curspeed = *(u16 *)&buf[8 + 14]; |
2403 | maxspeed = *(u16 *)&buf[8 + 8]; | 2398 | maxspeed = *(u16 *)&buf[8 + 8]; |
2404 | 2399 | ||
2405 | /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ | 2400 | if (cd->cd_flags & IDE_CD_FLAG_LE_SPEED_FIELDS) { |
2406 | if (!drive->id->model[0] && | ||
2407 | !strncmp(drive->id->fw_rev, "241N", 4)) { | ||
2408 | curspeed = le16_to_cpu(curspeed); | 2401 | curspeed = le16_to_cpu(curspeed); |
2409 | maxspeed = le16_to_cpu(maxspeed); | 2402 | maxspeed = le16_to_cpu(maxspeed); |
2410 | } else { | 2403 | } else { |
@@ -2627,8 +2620,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) | |||
2627 | return nslots; | 2620 | return nslots; |
2628 | } | 2621 | } |
2629 | 2622 | ||
2630 | if ((cd->cd_flags & IDE_CD_FLAG_NEC260) || | 2623 | if (cd->cd_flags & IDE_CD_FLAG_PRE_ATAPI12) { |
2631 | !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) { | ||
2632 | cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT; | 2624 | cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT; |
2633 | cdi->mask &= ~CDC_PLAY_AUDIO; | 2625 | cdi->mask &= ~CDC_PLAY_AUDIO; |
2634 | return nslots; | 2626 | return nslots; |
@@ -2661,22 +2653,13 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) | |||
2661 | cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM); | 2653 | cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM); |
2662 | if (buf[8 + 3] & 0x10) | 2654 | if (buf[8 + 3] & 0x10) |
2663 | cdi->mask &= ~CDC_DVD_R; | 2655 | cdi->mask &= ~CDC_DVD_R; |
2664 | if (buf[8 + 4] & 0x01) | 2656 | if ((buf[8 + 4] & 0x01) || (cd->cd_flags & IDE_CD_FLAG_PLAY_AUDIO_OK)) |
2665 | cdi->mask &= ~CDC_PLAY_AUDIO; | 2657 | cdi->mask &= ~CDC_PLAY_AUDIO; |
2666 | 2658 | ||
2667 | mechtype = buf[8 + 6] >> 5; | 2659 | mechtype = buf[8 + 6] >> 5; |
2668 | if (mechtype == mechtype_caddy || mechtype == mechtype_popup) | 2660 | if (mechtype == mechtype_caddy || mechtype == mechtype_popup) |
2669 | cdi->mask |= CDC_CLOSE_TRAY; | 2661 | cdi->mask |= CDC_CLOSE_TRAY; |
2670 | 2662 | ||
2671 | /* Some drives used by Apple don't advertise audio play | ||
2672 | * but they do support reading TOC & audio datas | ||
2673 | */ | ||
2674 | if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 || | ||
2675 | strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 || | ||
2676 | strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 || | ||
2677 | strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0) | ||
2678 | cdi->mask &= ~CDC_PLAY_AUDIO; | ||
2679 | |||
2680 | if (cdi->sanyo_slot > 0) { | 2663 | if (cdi->sanyo_slot > 0) { |
2681 | cdi->mask &= ~CDC_SELECT_DISC; | 2664 | cdi->mask &= ~CDC_SELECT_DISC; |
2682 | nslots = 3; | 2665 | nslots = 3; |
@@ -2805,11 +2788,74 @@ static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) | |||
2805 | return 0; | 2788 | return 0; |
2806 | } | 2789 | } |
2807 | 2790 | ||
2791 | struct cd_list_entry { | ||
2792 | const char *id_model; | ||
2793 | const char *id_firmware; | ||
2794 | unsigned int cd_flags; | ||
2795 | }; | ||
2796 | |||
2797 | static const struct cd_list_entry ide_cd_quirks_list[] = { | ||
2798 | /* Limit transfer size per interrupt. */ | ||
2799 | { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_CD_FLAG_LIMIT_NFRAMES }, | ||
2800 | { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_CD_FLAG_LIMIT_NFRAMES }, | ||
2801 | /* SCR-3231 doesn't support the SET_CD_SPEED command. */ | ||
2802 | { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_CD_FLAG_NO_SPEED_SELECT }, | ||
2803 | /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ | ||
2804 | { "NEC CD-ROM DRIVE:260", "1.01", IDE_CD_FLAG_TOCADDR_AS_BCD | | ||
2805 | IDE_CD_FLAG_PRE_ATAPI12, }, | ||
2806 | /* Vertos 300, some versions of this drive like to talk BCD. */ | ||
2807 | { "V003S0DS", NULL, IDE_CD_FLAG_VERTOS_300_SSD, }, | ||
2808 | /* Vertos 600 ESD. */ | ||
2809 | { "V006E0DS", NULL, IDE_CD_FLAG_VERTOS_600_ESD, }, | ||
2810 | /* | ||
2811 | * Sanyo 3 CD changer uses a non-standard command for CD changing | ||
2812 | * (by default standard ATAPI support for CD changers is used). | ||
2813 | */ | ||
2814 | { "CD-ROM CDR-C3 G", NULL, IDE_CD_FLAG_SANYO_3CD }, | ||
2815 | { "CD-ROM CDR-C3G", NULL, IDE_CD_FLAG_SANYO_3CD }, | ||
2816 | { "CD-ROM CDR_C36", NULL, IDE_CD_FLAG_SANYO_3CD }, | ||
2817 | /* Stingray 8X CD-ROM. */ | ||
2818 | { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_CD_FLAG_PRE_ATAPI12}, | ||
2819 | /* | ||
2820 | * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length | ||
2821 | * mode sense page capabilities size, but older drives break. | ||
2822 | */ | ||
2823 | { "ATAPI CD ROM DRIVE 50X MAX", NULL, IDE_CD_FLAG_FULL_CAPS_PAGE }, | ||
2824 | { "WPI CDS-32X", NULL, IDE_CD_FLAG_FULL_CAPS_PAGE }, | ||
2825 | /* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */ | ||
2826 | { "", "241N", IDE_CD_FLAG_LE_SPEED_FIELDS }, | ||
2827 | /* | ||
2828 | * Some drives used by Apple don't advertise audio play | ||
2829 | * but they do support reading TOC & audio datas. | ||
2830 | */ | ||
2831 | { "MATSHITADVD-ROM SR-8187", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, | ||
2832 | { "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, | ||
2833 | { "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, | ||
2834 | { "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, | ||
2835 | { NULL, NULL, 0 } | ||
2836 | }; | ||
2837 | |||
2838 | static unsigned int ide_cd_flags(struct hd_driveid *id) | ||
2839 | { | ||
2840 | const struct cd_list_entry *cle = ide_cd_quirks_list; | ||
2841 | |||
2842 | while (cle->id_model) { | ||
2843 | if (strcmp(cle->id_model, id->model) == 0 && | ||
2844 | (cle->id_firmware == NULL || | ||
2845 | strstr(id->fw_rev, cle->id_firmware))) | ||
2846 | return cle->cd_flags; | ||
2847 | cle++; | ||
2848 | } | ||
2849 | |||
2850 | return 0; | ||
2851 | } | ||
2852 | |||
2808 | static | 2853 | static |
2809 | int ide_cdrom_setup (ide_drive_t *drive) | 2854 | int ide_cdrom_setup (ide_drive_t *drive) |
2810 | { | 2855 | { |
2811 | struct cdrom_info *cd = drive->driver_data; | 2856 | struct cdrom_info *cd = drive->driver_data; |
2812 | struct cdrom_device_info *cdi = &cd->devinfo; | 2857 | struct cdrom_device_info *cdi = &cd->devinfo; |
2858 | struct hd_driveid *id = drive->id; | ||
2813 | int nslots; | 2859 | int nslots; |
2814 | 2860 | ||
2815 | blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); | 2861 | blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); |
@@ -2820,53 +2866,21 @@ int ide_cdrom_setup (ide_drive_t *drive) | |||
2820 | 2866 | ||
2821 | drive->special.all = 0; | 2867 | drive->special.all = 0; |
2822 | 2868 | ||
2823 | cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED; | 2869 | cd->cd_flags = IDE_CD_FLAG_MEDIA_CHANGED | IDE_CD_FLAG_NO_EJECT | |
2870 | ide_cd_flags(id); | ||
2824 | 2871 | ||
2825 | if ((drive->id->config & 0x0060) == 0x20) | 2872 | if ((id->config & 0x0060) == 0x20) |
2826 | cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT; | 2873 | cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT; |
2827 | cd->cd_flags |= IDE_CD_FLAG_NO_EJECT; | 2874 | |
2828 | 2875 | if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_300_SSD) && | |
2829 | /* limit transfer size per interrupt. */ | 2876 | id->fw_rev[4] == '1' && id->fw_rev[6] <= '2') |
2830 | /* a testament to the nice quality of Samsung drives... */ | ||
2831 | if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430") || | ||
2832 | !strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432")) | ||
2833 | cd->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES; | ||
2834 | /* the 3231 model does not support the SET_CD_SPEED command */ | ||
2835 | else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231")) | ||
2836 | cd->cd_flags |= IDE_CD_FLAG_NO_SPEED_SELECT; | ||
2837 | |||
2838 | if (strcmp (drive->id->model, "V003S0DS") == 0 && | ||
2839 | drive->id->fw_rev[4] == '1' && | ||
2840 | drive->id->fw_rev[6] <= '2') { | ||
2841 | /* Vertos 300. | ||
2842 | Some versions of this drive like to talk BCD. */ | ||
2843 | cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD | | 2877 | cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD | |
2844 | IDE_CD_FLAG_TOCADDR_AS_BCD); | 2878 | IDE_CD_FLAG_TOCADDR_AS_BCD); |
2845 | } | 2879 | else if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_600_ESD) && |
2846 | else if (strcmp (drive->id->model, "V006E0DS") == 0 && | 2880 | id->fw_rev[4] == '1' && id->fw_rev[6] <= '2') |
2847 | drive->id->fw_rev[4] == '1' && | ||
2848 | drive->id->fw_rev[6] <= '2') { | ||
2849 | /* Vertos 600 ESD. */ | ||
2850 | cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD; | 2881 | cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD; |
2851 | } | 2882 | else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD) |
2852 | else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 && | 2883 | cdi->sanyo_slot = 3; /* 3 => use CD in slot 0 */ |
2853 | strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */ | ||
2854 | /* Old NEC260 (not R). | ||
2855 | This drive was released before the 1.2 version | ||
2856 | of the spec. */ | ||
2857 | cd->cd_flags |= (IDE_CD_FLAG_TOCADDR_AS_BCD | | ||
2858 | IDE_CD_FLAG_NEC260); | ||
2859 | } | ||
2860 | /* | ||
2861 | * Sanyo 3 CD changer uses a non-standard command for CD changing | ||
2862 | * (by default standard ATAPI support for CD changers is used). | ||
2863 | */ | ||
2864 | else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) || | ||
2865 | (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) || | ||
2866 | (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) { | ||
2867 | /* uses CD in slot 0 when value is set to 3 */ | ||
2868 | cdi->sanyo_slot = 3; | ||
2869 | } | ||
2870 | 2884 | ||
2871 | nslots = ide_cdrom_probe_capabilities (drive); | 2885 | nslots = ide_cdrom_probe_capabilities (drive); |
2872 | 2886 | ||
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 34e9291c0a8e..fc8d6d626b8d 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h | |||
@@ -44,8 +44,8 @@ enum { | |||
44 | IDE_CD_FLAG_NO_DOORLOCK = (1 << 1), | 44 | IDE_CD_FLAG_NO_DOORLOCK = (1 << 1), |
45 | /* Drive cannot eject the disc. */ | 45 | /* Drive cannot eject the disc. */ |
46 | IDE_CD_FLAG_NO_EJECT = (1 << 2), | 46 | IDE_CD_FLAG_NO_EJECT = (1 << 2), |
47 | /* Drive is a pre-1.2 NEC 260 drive. */ | 47 | /* Drive is a pre ATAPI 1.2 drive. */ |
48 | IDE_CD_FLAG_NEC260 = (1 << 3), | 48 | IDE_CD_FLAG_PRE_ATAPI12 = (1 << 3), |
49 | /* TOC addresses are in BCD. */ | 49 | /* TOC addresses are in BCD. */ |
50 | IDE_CD_FLAG_TOCADDR_AS_BCD = (1 << 4), | 50 | IDE_CD_FLAG_TOCADDR_AS_BCD = (1 << 4), |
51 | /* TOC track numbers are in BCD. */ | 51 | /* TOC track numbers are in BCD. */ |
@@ -65,6 +65,12 @@ enum { | |||
65 | IDE_CD_FLAG_DOOR_LOCKED = (1 << 10), | 65 | IDE_CD_FLAG_DOOR_LOCKED = (1 << 10), |
66 | /* SET_CD_SPEED command is unsupported. */ | 66 | /* SET_CD_SPEED command is unsupported. */ |
67 | IDE_CD_FLAG_NO_SPEED_SELECT = (1 << 11), | 67 | IDE_CD_FLAG_NO_SPEED_SELECT = (1 << 11), |
68 | IDE_CD_FLAG_VERTOS_300_SSD = (1 << 12), | ||
69 | IDE_CD_FLAG_VERTOS_600_ESD = (1 << 13), | ||
70 | IDE_CD_FLAG_SANYO_3CD = (1 << 14), | ||
71 | IDE_CD_FLAG_FULL_CAPS_PAGE = (1 << 15), | ||
72 | IDE_CD_FLAG_PLAY_AUDIO_OK = (1 << 16), | ||
73 | IDE_CD_FLAG_LE_SPEED_FIELDS = (1 << 17), | ||
68 | }; | 74 | }; |
69 | 75 | ||
70 | /* Structure of a MSF cdrom address. */ | 76 | /* Structure of a MSF cdrom address. */ |