aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ata_piix.c31
-rw-r--r--drivers/ata/libata-core.c7
-rw-r--r--drivers/ata/pata_ali.c2
-rw-r--r--include/linux/ata.h14
4 files changed, 50 insertions, 4 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 720174d628fa..14b726b9f985 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -93,7 +93,7 @@
93#include <linux/libata.h> 93#include <linux/libata.h>
94 94
95#define DRV_NAME "ata_piix" 95#define DRV_NAME "ata_piix"
96#define DRV_VERSION "2.00ac6" 96#define DRV_VERSION "2.00ac7"
97 97
98enum { 98enum {
99 PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ 99 PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -571,6 +571,23 @@ module_param(force_pcs, int, 0444);
571MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around " 571MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
572 "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)"); 572 "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)");
573 573
574struct ich_laptop {
575 u16 device;
576 u16 subvendor;
577 u16 subdevice;
578};
579
580/*
581 * List of laptops that use short cables rather than 80 wire
582 */
583
584static const struct ich_laptop ich_laptop[] = {
585 /* devid, subvendor, subdev */
586 { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
587 /* end marker */
588 { 0, }
589};
590
574/** 591/**
575 * piix_pata_cbl_detect - Probe host controller cable detect info 592 * piix_pata_cbl_detect - Probe host controller cable detect info
576 * @ap: Port for which cable detect info is desired 593 * @ap: Port for which cable detect info is desired
@@ -585,12 +602,24 @@ MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
585static void ich_pata_cbl_detect(struct ata_port *ap) 602static void ich_pata_cbl_detect(struct ata_port *ap)
586{ 603{
587 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 604 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
605 const struct ich_laptop *lap = &ich_laptop[0];
588 u8 tmp, mask; 606 u8 tmp, mask;
589 607
590 /* no 80c support in host controller? */ 608 /* no 80c support in host controller? */
591 if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0) 609 if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
592 goto cbl40; 610 goto cbl40;
593 611
612 /* Check for specials - Acer Aspire 5602WLMi */
613 while (lap->device) {
614 if (lap->device == pdev->device &&
615 lap->subvendor == pdev->subsystem_vendor &&
616 lap->subdevice == pdev->subsystem_device) {
617 ap->cbl = ATA_CBL_PATA40_SHORT;
618 return;
619 }
620 lap++;
621 }
622
594 /* check BIOS cable detect results */ 623 /* check BIOS cable detect results */
595 mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; 624 mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
596 pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); 625 pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 915a55a6cc14..b896119cccd3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3119,6 +3119,13 @@ static void ata_dev_xfermask(struct ata_device *dev)
3119 */ 3119 */
3120 if (ap->cbl == ATA_CBL_PATA40) 3120 if (ap->cbl == ATA_CBL_PATA40)
3121 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); 3121 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
3122 /* Apply drive side cable rule. Unknown or 80 pin cables reported
3123 * host side are checked drive side as well. Cases where we know a
3124 * 40wire cable is used safely for 80 are not checked here.
3125 */
3126 if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
3127 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
3128
3122 3129
3123 xfer_mask &= ata_pack_xfermask(dev->pio_mask, 3130 xfer_mask &= ata_pack_xfermask(dev->pio_mask,
3124 dev->mwdma_mask, dev->udma_mask); 3131 dev->mwdma_mask, dev->udma_mask);
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 64eed99f6814..e6d2b840e870 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -78,7 +78,7 @@ static int ali_c2_cable_detect(struct ata_port *ap)
78 implement the detect logic */ 78 implement the detect logic */
79 79
80 if (ali_cable_override(pdev)) 80 if (ali_cable_override(pdev))
81 return ATA_CBL_PATA80; 81 return ATA_CBL_PATA40_SHORT;
82 82
83 /* Host view cable detect 0x4A bit 0 primary bit 1 secondary 83 /* Host view cable detect 0x4A bit 0 primary bit 1 secondary
84 Bit set for 40 pin */ 84 Bit set for 40 pin */
diff --git a/include/linux/ata.h b/include/linux/ata.h
index d89441907024..1df941648a57 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -200,8 +200,9 @@ enum {
200 ATA_CBL_NONE = 0, 200 ATA_CBL_NONE = 0,
201 ATA_CBL_PATA40 = 1, 201 ATA_CBL_PATA40 = 1,
202 ATA_CBL_PATA80 = 2, 202 ATA_CBL_PATA80 = 2,
203 ATA_CBL_PATA_UNK = 3, 203 ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */
204 ATA_CBL_SATA = 4, 204 ATA_CBL_PATA_UNK = 4,
205 ATA_CBL_SATA = 5,
205 206
206 /* SATA Status and Control Registers */ 207 /* SATA Status and Control Registers */
207 SCR_STATUS = 0, 208 SCR_STATUS = 0,
@@ -342,6 +343,15 @@ static inline int ata_id_is_cfa(const u16 *id)
342 return 0; 343 return 0;
343} 344}
344 345
346static inline int ata_drive_40wire(const u16 *dev_id)
347{
348 if (ata_id_major_version(dev_id) >= 5 && ata_id_is_sata(dev_id))
349 return 0; /* SATA */
350 if (dev_id[93] & 0x4000)
351 return 0; /* 80 wire */
352 return 1;
353}
354
345static inline int atapi_cdb_len(const u16 *dev_id) 355static inline int atapi_cdb_len(const u16 *dev_id)
346{ 356{
347 u16 tmp = dev_id[0] & 0x3; 357 u16 tmp = dev_id[0] & 0x3;