summaryrefslogtreecommitdiff
path: root/drivers/ide
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-02-01 23:09:22 +0100
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-02-01 23:09:22 +0100
commite59724c7db9afd14827f1b737605f54d47f2d226 (patch)
treeef89587dd3bc19d1271aec9b755c20ef6b186001 /drivers/ide
parent9a6dc668d9b4d639936c683879eb1e0f92c5b944 (diff)
downloadlinux-rt-e59724c7db9afd14827f1b737605f54d47f2d226.tar.gz
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.c140
-rw-r--r--drivers/ide/ide-cd.h10
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)
struct packet_command cgc;
int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
- /*
- * 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")))
+ if ((info->cd_flags & IDE_CD_FLAG_FULL_CAPS_PAGE) == 0)
size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
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)
curspeed = *(u16 *)&buf[8 + 14];
maxspeed = *(u16 *)&buf[8 + 8];
- /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
- if (!drive->id->model[0] &&
- !strncmp(drive->id->fw_rev, "241N", 4)) {
+ if (cd->cd_flags & IDE_CD_FLAG_LE_SPEED_FIELDS) {
curspeed = le16_to_cpu(curspeed);
maxspeed = le16_to_cpu(maxspeed);
} else {
@@ -2627,8 +2620,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
return nslots;
}
- if ((cd->cd_flags & IDE_CD_FLAG_NEC260) ||
- !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) {
+ if (cd->cd_flags & IDE_CD_FLAG_PRE_ATAPI12) {
cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
cdi->mask &= ~CDC_PLAY_AUDIO;
return nslots;
@@ -2661,22 +2653,13 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
if (buf[8 + 3] & 0x10)
cdi->mask &= ~CDC_DVD_R;
- if (buf[8 + 4] & 0x01)
+ if ((buf[8 + 4] & 0x01) || (cd->cd_flags & IDE_CD_FLAG_PLAY_AUDIO_OK))
cdi->mask &= ~CDC_PLAY_AUDIO;
mechtype = buf[8 + 6] >> 5;
if (mechtype == mechtype_caddy || mechtype == mechtype_popup)
cdi->mask |= CDC_CLOSE_TRAY;
- /* Some drives used by Apple don't advertise audio play
- * but they do support reading TOC & audio datas
- */
- if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 ||
- strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 ||
- strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 ||
- strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0)
- cdi->mask &= ~CDC_PLAY_AUDIO;
-
if (cdi->sanyo_slot > 0) {
cdi->mask &= ~CDC_SELECT_DISC;
nslots = 3;
@@ -2805,11 +2788,74 @@ static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
return 0;
}
+struct cd_list_entry {
+ const char *id_model;
+ const char *id_firmware;
+ unsigned int cd_flags;
+};
+
+static const struct cd_list_entry ide_cd_quirks_list[] = {
+ /* Limit transfer size per interrupt. */
+ { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_CD_FLAG_LIMIT_NFRAMES },
+ { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_CD_FLAG_LIMIT_NFRAMES },
+ /* SCR-3231 doesn't support the SET_CD_SPEED command. */
+ { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_CD_FLAG_NO_SPEED_SELECT },
+ /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
+ { "NEC CD-ROM DRIVE:260", "1.01", IDE_CD_FLAG_TOCADDR_AS_BCD |
+ IDE_CD_FLAG_PRE_ATAPI12, },
+ /* Vertos 300, some versions of this drive like to talk BCD. */
+ { "V003S0DS", NULL, IDE_CD_FLAG_VERTOS_300_SSD, },
+ /* Vertos 600 ESD. */
+ { "V006E0DS", NULL, IDE_CD_FLAG_VERTOS_600_ESD, },
+ /*
+ * Sanyo 3 CD changer uses a non-standard command for CD changing
+ * (by default standard ATAPI support for CD changers is used).
+ */
+ { "CD-ROM CDR-C3 G", NULL, IDE_CD_FLAG_SANYO_3CD },
+ { "CD-ROM CDR-C3G", NULL, IDE_CD_FLAG_SANYO_3CD },
+ { "CD-ROM CDR_C36", NULL, IDE_CD_FLAG_SANYO_3CD },
+ /* Stingray 8X CD-ROM. */
+ { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_CD_FLAG_PRE_ATAPI12},
+ /*
+ * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length
+ * mode sense page capabilities size, but older drives break.
+ */
+ { "ATAPI CD ROM DRIVE 50X MAX", NULL, IDE_CD_FLAG_FULL_CAPS_PAGE },
+ { "WPI CDS-32X", NULL, IDE_CD_FLAG_FULL_CAPS_PAGE },
+ /* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */
+ { "", "241N", IDE_CD_FLAG_LE_SPEED_FIELDS },
+ /*
+ * Some drives used by Apple don't advertise audio play
+ * but they do support reading TOC & audio datas.
+ */
+ { "MATSHITADVD-ROM SR-8187", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
+ { "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
+ { "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
+ { "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
+ { NULL, NULL, 0 }
+};
+
+static unsigned int ide_cd_flags(struct hd_driveid *id)
+{
+ const struct cd_list_entry *cle = ide_cd_quirks_list;
+
+ while (cle->id_model) {
+ if (strcmp(cle->id_model, id->model) == 0 &&
+ (cle->id_firmware == NULL ||
+ strstr(id->fw_rev, cle->id_firmware)))
+ return cle->cd_flags;
+ cle++;
+ }
+
+ return 0;
+}
+
static
int ide_cdrom_setup (ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
+ struct hd_driveid *id = drive->id;
int nslots;
blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
@@ -2820,53 +2866,21 @@ int ide_cdrom_setup (ide_drive_t *drive)
drive->special.all = 0;
- cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
+ cd->cd_flags = IDE_CD_FLAG_MEDIA_CHANGED | IDE_CD_FLAG_NO_EJECT |
+ ide_cd_flags(id);
- if ((drive->id->config & 0x0060) == 0x20)
+ if ((id->config & 0x0060) == 0x20)
cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT;
- cd->cd_flags |= IDE_CD_FLAG_NO_EJECT;
-
- /* limit transfer size per interrupt. */
- /* a testament to the nice quality of Samsung drives... */
- if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430") ||
- !strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
- cd->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES;
- /* the 3231 model does not support the SET_CD_SPEED command */
- else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
- cd->cd_flags |= IDE_CD_FLAG_NO_SPEED_SELECT;
-
- if (strcmp (drive->id->model, "V003S0DS") == 0 &&
- drive->id->fw_rev[4] == '1' &&
- drive->id->fw_rev[6] <= '2') {
- /* Vertos 300.
- Some versions of this drive like to talk BCD. */
+
+ if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_300_SSD) &&
+ id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD |
IDE_CD_FLAG_TOCADDR_AS_BCD);
- }
- else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
- drive->id->fw_rev[4] == '1' &&
- drive->id->fw_rev[6] <= '2') {
- /* Vertos 600 ESD. */
+ else if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_600_ESD) &&
+ id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD;
- }
- else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 &&
- strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
- /* Old NEC260 (not R).
- This drive was released before the 1.2 version
- of the spec. */
- cd->cd_flags |= (IDE_CD_FLAG_TOCADDR_AS_BCD |
- IDE_CD_FLAG_NEC260);
- }
- /*
- * Sanyo 3 CD changer uses a non-standard command for CD changing
- * (by default standard ATAPI support for CD changers is used).
- */
- else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
- (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
- (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
- /* uses CD in slot 0 when value is set to 3 */
- cdi->sanyo_slot = 3;
- }
+ else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD)
+ cdi->sanyo_slot = 3; /* 3 => use CD in slot 0 */
nslots = ide_cdrom_probe_capabilities (drive);
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 {
IDE_CD_FLAG_NO_DOORLOCK = (1 << 1),
/* Drive cannot eject the disc. */
IDE_CD_FLAG_NO_EJECT = (1 << 2),
- /* Drive is a pre-1.2 NEC 260 drive. */
- IDE_CD_FLAG_NEC260 = (1 << 3),
+ /* Drive is a pre ATAPI 1.2 drive. */
+ IDE_CD_FLAG_PRE_ATAPI12 = (1 << 3),
/* TOC addresses are in BCD. */
IDE_CD_FLAG_TOCADDR_AS_BCD = (1 << 4),
/* TOC track numbers are in BCD. */
@@ -65,6 +65,12 @@ enum {
IDE_CD_FLAG_DOOR_LOCKED = (1 << 10),
/* SET_CD_SPEED command is unsupported. */
IDE_CD_FLAG_NO_SPEED_SELECT = (1 << 11),
+ IDE_CD_FLAG_VERTOS_300_SSD = (1 << 12),
+ IDE_CD_FLAG_VERTOS_600_ESD = (1 << 13),
+ IDE_CD_FLAG_SANYO_3CD = (1 << 14),
+ IDE_CD_FLAG_FULL_CAPS_PAGE = (1 << 15),
+ IDE_CD_FLAG_PLAY_AUDIO_OK = (1 << 16),
+ IDE_CD_FLAG_LE_SPEED_FIELDS = (1 << 17),
};
/* Structure of a MSF cdrom address. */