| From 5e5a4f5d5a08c9c504fe956391ac3dae2c66556d Mon Sep 17 00:00:00 2001 |
| From: Ming Lei <ming.lei@canonical.com> |
| Date: Fri, 7 Oct 2011 11:50:22 +0800 |
| Subject: ata_piix: make DVD Drive recognisable on systems with Intel Sandybridge chipsets(v2) |
| |
| From: Ming Lei <ming.lei@canonical.com> |
| |
| commit 5e5a4f5d5a08c9c504fe956391ac3dae2c66556d upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/ata/ata_piix.c | 37 ++++++++++++++++++++++++++++++++----- |
| 1 file changed, 32 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/ata/ata_piix.c |
| +++ b/drivers/ata/ata_piix.c |
| @@ -113,6 +113,8 @@ enum { |
| PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, |
| PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, |
| |
| + PIIX_FLAG_PIO16 = (1 << 30), /*support 16bit PIO only*/ |
| + |
| PIIX_80C_PRI = (1 << 5) | (1 << 4), |
| PIIX_80C_SEC = (1 << 7) | (1 << 6), |
| |
| @@ -147,6 +149,7 @@ enum piix_controller_ids { |
| ich8m_apple_sata, /* locks up on second port enable */ |
| tolapai_sata, |
| piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ |
| + ich8_sata_snb, |
| }; |
| |
| struct piix_map_db { |
| @@ -177,6 +180,7 @@ static int piix_sidpr_scr_write(struct a |
| static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
| unsigned hints); |
| static bool piix_irq_check(struct ata_port *ap); |
| +static int piix_port_start(struct ata_port *ap); |
| #ifdef CONFIG_PM |
| static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); |
| static int piix_pci_device_resume(struct pci_dev *pdev); |
| @@ -298,21 +302,21 @@ static const struct pci_device_id piix_p |
| /* SATA Controller IDE (PCH) */ |
| { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| /* SATA Controller IDE (CPT) */ |
| - { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| + { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, |
| /* SATA Controller IDE (CPT) */ |
| - { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| + { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, |
| /* SATA Controller IDE (CPT) */ |
| { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| /* SATA Controller IDE (CPT) */ |
| { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| /* SATA Controller IDE (PBG) */ |
| - { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| + { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, |
| /* SATA Controller IDE (PBG) */ |
| { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| /* SATA Controller IDE (Panther Point) */ |
| - { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| + { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, |
| /* SATA Controller IDE (Panther Point) */ |
| - { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| + { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, |
| /* SATA Controller IDE (Panther Point) */ |
| { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| /* SATA Controller IDE (Panther Point) */ |
| @@ -338,6 +342,7 @@ static struct scsi_host_template piix_sh |
| static struct ata_port_operations piix_sata_ops = { |
| .inherits = &ata_bmdma32_port_ops, |
| .sff_irq_check = piix_irq_check, |
| + .port_start = piix_port_start, |
| }; |
| |
| static struct ata_port_operations piix_pata_ops = { |
| @@ -478,6 +483,7 @@ static const struct piix_map_db *piix_ma |
| [ich8_2port_sata] = &ich8_2port_map_db, |
| [ich8m_apple_sata] = &ich8m_apple_map_db, |
| [tolapai_sata] = &tolapai_map_db, |
| + [ich8_sata_snb] = &ich8_map_db, |
| }; |
| |
| static struct ata_port_info piix_port_info[] = { |
| @@ -606,6 +612,19 @@ static struct ata_port_info piix_port_in |
| .port_ops = &piix_vmw_ops, |
| }, |
| |
| + /* |
| + * some Sandybridge chipsets have broken 32 mode up to now, |
| + * see https://bugzilla.kernel.org/show_bug.cgi?id=40592 |
| + */ |
| + [ich8_sata_snb] = |
| + { |
| + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16, |
| + .pio_mask = ATA_PIO4, |
| + .mwdma_mask = ATA_MWDMA2, |
| + .udma_mask = ATA_UDMA6, |
| + .port_ops = &piix_sata_ops, |
| + }, |
| + |
| }; |
| |
| static struct pci_bits piix_enable_bits[] = { |
| @@ -649,6 +668,14 @@ static const struct ich_laptop ich_lapto |
| { 0, } |
| }; |
| |
| +static int piix_port_start(struct ata_port *ap) |
| +{ |
| + if (!(ap->flags & PIIX_FLAG_PIO16)) |
| + ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; |
| + |
| + return ata_bmdma_port_start(ap); |
| +} |
| + |
| /** |
| * ich_pata_cable_detect - Probe host controller cable detect info |
| * @ap: Port for which cable detect info is desired |