aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ata_piix.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@canonical.com>2011-10-06 23:50:22 -0400
committerJeff Garzik <jgarzik@redhat.com>2011-10-07 23:46:37 -0400
commit5e5a4f5d5a08c9c504fe956391ac3dae2c66556d (patch)
tree7e5aad3c063b2972d3890afbf3b847e39a4b57de /drivers/ata/ata_piix.c
parent21dba24481f70696308bd4361a7b2460c8a41965 (diff)
ata_piix: make DVD Drive recognisable on systems with Intel Sandybridge chipsets(v2)
This quirk patch fixes one kind of bug inside some Intel Sandybridge chipsets, see reports from https://bugzilla.kernel.org/show_bug.cgi?id=40592. Many guys also have reported the problem before: https://bugs.launchpad.net/bugs/737388 https://bugs.launchpad.net/bugs/794642 https://bugs.launchpad.net/bugs/782389 ...... With help from Tejun, the problem is found to be caused by 32bit PIO mode, so introduce the quirk patch to disable 32bit PIO on SATA piix for some Sandybridge CPT chipsets. Seth also tested the patch on all five affected chipsets (pci device ID: 0x1c00, 0x1c01, 0x1d00, 0x1e00, 0x1e01), and found the patch does fix the problem. Tested-by: Heasley, Seth <seth.heasley@intel.com> Cc: Alan Cox <alan@linux.intel.com> Signed-off-by: Ming Lei <ming.lei@canonical.com> Acked-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com> Cc: stable@kernel.org
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r--drivers/ata/ata_piix.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 43107e9415da..cc431d6bc97f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -113,6 +113,8 @@ enum {
113 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, 113 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS,
114 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, 114 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
115 115
116 PIIX_FLAG_PIO16 = (1 << 30), /*support 16bit PIO only*/
117
116 PIIX_80C_PRI = (1 << 5) | (1 << 4), 118 PIIX_80C_PRI = (1 << 5) | (1 << 4),
117 PIIX_80C_SEC = (1 << 7) | (1 << 6), 119 PIIX_80C_SEC = (1 << 7) | (1 << 6),
118 120
@@ -147,6 +149,7 @@ enum piix_controller_ids {
147 ich8m_apple_sata, /* locks up on second port enable */ 149 ich8m_apple_sata, /* locks up on second port enable */
148 tolapai_sata, 150 tolapai_sata,
149 piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ 151 piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */
152 ich8_sata_snb,
150}; 153};
151 154
152struct piix_map_db { 155struct piix_map_db {
@@ -177,6 +180,7 @@ static int piix_sidpr_scr_write(struct ata_link *link,
177static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, 180static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
178 unsigned hints); 181 unsigned hints);
179static bool piix_irq_check(struct ata_port *ap); 182static bool piix_irq_check(struct ata_port *ap);
183static int piix_port_start(struct ata_port *ap);
180#ifdef CONFIG_PM 184#ifdef CONFIG_PM
181static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); 185static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
182static int piix_pci_device_resume(struct pci_dev *pdev); 186static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -298,21 +302,21 @@ static const struct pci_device_id piix_pci_tbl[] = {
298 /* SATA Controller IDE (PCH) */ 302 /* SATA Controller IDE (PCH) */
299 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, 303 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
300 /* SATA Controller IDE (CPT) */ 304 /* SATA Controller IDE (CPT) */
301 { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, 305 { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
302 /* SATA Controller IDE (CPT) */ 306 /* SATA Controller IDE (CPT) */
303 { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, 307 { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
304 /* SATA Controller IDE (CPT) */ 308 /* SATA Controller IDE (CPT) */
305 { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, 309 { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
306 /* SATA Controller IDE (CPT) */ 310 /* SATA Controller IDE (CPT) */
307 { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, 311 { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
308 /* SATA Controller IDE (PBG) */ 312 /* SATA Controller IDE (PBG) */
309 { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, 313 { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
310 /* SATA Controller IDE (PBG) */ 314 /* SATA Controller IDE (PBG) */
311 { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, 315 { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
312 /* SATA Controller IDE (Panther Point) */ 316 /* SATA Controller IDE (Panther Point) */
313 { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, 317 { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
314 /* SATA Controller IDE (Panther Point) */ 318 /* SATA Controller IDE (Panther Point) */
315 { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, 319 { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
316 /* SATA Controller IDE (Panther Point) */ 320 /* SATA Controller IDE (Panther Point) */
317 { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, 321 { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
318 /* SATA Controller IDE (Panther Point) */ 322 /* SATA Controller IDE (Panther Point) */
@@ -338,6 +342,7 @@ static struct scsi_host_template piix_sht = {
338static struct ata_port_operations piix_sata_ops = { 342static struct ata_port_operations piix_sata_ops = {
339 .inherits = &ata_bmdma32_port_ops, 343 .inherits = &ata_bmdma32_port_ops,
340 .sff_irq_check = piix_irq_check, 344 .sff_irq_check = piix_irq_check,
345 .port_start = piix_port_start,
341}; 346};
342 347
343static struct ata_port_operations piix_pata_ops = { 348static struct ata_port_operations piix_pata_ops = {
@@ -478,6 +483,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
478 [ich8_2port_sata] = &ich8_2port_map_db, 483 [ich8_2port_sata] = &ich8_2port_map_db,
479 [ich8m_apple_sata] = &ich8m_apple_map_db, 484 [ich8m_apple_sata] = &ich8m_apple_map_db,
480 [tolapai_sata] = &tolapai_map_db, 485 [tolapai_sata] = &tolapai_map_db,
486 [ich8_sata_snb] = &ich8_map_db,
481}; 487};
482 488
483static struct ata_port_info piix_port_info[] = { 489static struct ata_port_info piix_port_info[] = {
@@ -606,6 +612,19 @@ static struct ata_port_info piix_port_info[] = {
606 .port_ops = &piix_vmw_ops, 612 .port_ops = &piix_vmw_ops,
607 }, 613 },
608 614
615 /*
616 * some Sandybridge chipsets have broken 32 mode up to now,
617 * see https://bugzilla.kernel.org/show_bug.cgi?id=40592
618 */
619 [ich8_sata_snb] =
620 {
621 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16,
622 .pio_mask = ATA_PIO4,
623 .mwdma_mask = ATA_MWDMA2,
624 .udma_mask = ATA_UDMA6,
625 .port_ops = &piix_sata_ops,
626 },
627
609}; 628};
610 629
611static struct pci_bits piix_enable_bits[] = { 630static struct pci_bits piix_enable_bits[] = {
@@ -649,6 +668,14 @@ static const struct ich_laptop ich_laptop[] = {
649 { 0, } 668 { 0, }
650}; 669};
651 670
671static int piix_port_start(struct ata_port *ap)
672{
673 if (!(ap->flags & PIIX_FLAG_PIO16))
674 ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
675
676 return ata_bmdma_port_start(ap);
677}
678
652/** 679/**
653 * ich_pata_cable_detect - Probe host controller cable detect info 680 * ich_pata_cable_detect - Probe host controller cable detect info
654 * @ap: Port for which cable detect info is desired 681 * @ap: Port for which cable detect info is desired