diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/pata_pcmcia.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 820332a7ec7b..171da0aeb65f 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -54,6 +54,39 @@ struct ata_pcmcia_info { | |||
54 | dev_node_t node; | 54 | dev_node_t node; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /** | ||
58 | * pcmcia_set_mode - PCMCIA specific mode setup | ||
59 | * @ap: Port | ||
60 | * @r_failed_dev: Return pointer for failed device | ||
61 | * | ||
62 | * Perform the tuning and setup of the devices and timings, which | ||
63 | * for PCMCIA is the same as any other controller. We wrap it however | ||
64 | * as we need to spot hardware with incorrect or missing master/slave | ||
65 | * decode, which alas is embarrassingly common in the PC world | ||
66 | */ | ||
67 | |||
68 | static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) | ||
69 | { | ||
70 | struct ata_device *master = &ap->device[0]; | ||
71 | struct ata_device *slave = &ap->device[1]; | ||
72 | |||
73 | if (!ata_dev_enabled(master) || !ata_dev_enabled(slave)) | ||
74 | return ata_do_set_mode(ap, r_failed_dev); | ||
75 | |||
76 | if (memcmp(master->id + ATA_ID_FW_REV, slave->id + ATA_ID_FW_REV, | ||
77 | ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0) | ||
78 | { | ||
79 | /* Suspicious match, but could be two cards from | ||
80 | the same vendor - check serial */ | ||
81 | if (memcmp(master->id + ATA_ID_SERNO, slave->id + ATA_ID_SERNO, | ||
82 | ATA_ID_SERNO_LEN) == 0 && master->id[ATA_ID_SERNO] >> 8) { | ||
83 | ata_dev_printk(slave, KERN_WARNING, "is a ghost device, ignoring.\n"); | ||
84 | ata_dev_disable(slave); | ||
85 | } | ||
86 | } | ||
87 | return ata_do_set_mode(ap, r_failed_dev); | ||
88 | } | ||
89 | |||
57 | static struct scsi_host_template pcmcia_sht = { | 90 | static struct scsi_host_template pcmcia_sht = { |
58 | .module = THIS_MODULE, | 91 | .module = THIS_MODULE, |
59 | .name = DRV_NAME, | 92 | .name = DRV_NAME, |
@@ -73,6 +106,7 @@ static struct scsi_host_template pcmcia_sht = { | |||
73 | }; | 106 | }; |
74 | 107 | ||
75 | static struct ata_port_operations pcmcia_port_ops = { | 108 | static struct ata_port_operations pcmcia_port_ops = { |
109 | .set_mode = pcmcia_set_mode, | ||
76 | .port_disable = ata_port_disable, | 110 | .port_disable = ata_port_disable, |
77 | .tf_load = ata_tf_load, | 111 | .tf_load = ata_tf_load, |
78 | .tf_read = ata_tf_read, | 112 | .tf_read = ata_tf_read, |