| From e9c1670c2a14ef9cc20d86b24b829f3947aad34e Mon Sep 17 00:00:00 2001 |
| From: Tejun Heo <tj@kernel.org> |
| Date: Tue, 3 Mar 2009 13:52:16 +0900 |
| Subject: ata_piix: add workaround for Samsung DB-P70 |
| |
| From: Tejun Heo <tj@kernel.org> |
| |
| commit e9c1670c2a14ef9cc20d86b24b829f3947aad34e upstream. |
| |
| Samsung DB-P70 somehow botched the first ICH9 SATA port. The board |
| doesn't expose the first port but somehow SStatus reports link online |
| while failing SRST protocol leading to repeated probe failures and |
| thus long boot delay. |
| |
| Because the BIOS doesn't carry any identifying DMI information, the |
| port can't be blacklisted safely. Fortunately, the controller does |
| have subsystem vendor and ID set. It's unclear whether the subsystem |
| IDs are used only for the board but it can be safely worked around by |
| disabling SIDPR access and just using SRST works around the problem. |
| Even when the workaround is triggered on an unaffected board the only |
| side effect will be missing SCR access. |
| |
| Signed-off-by: Tejun Heo <tj@kernel.org> |
| Reported-by: Joseph Jang <josephjang@gmail.com> |
| Reported-by: Jonghyon Sohn <mrsohn@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, 37 insertions(+) |
| |
| --- a/drivers/ata/ata_piix.c |
| +++ b/drivers/ata/ata_piix.c |
| @@ -1294,6 +1294,39 @@ static const int *__devinit piix_init_sa |
| return map; |
| } |
| |
| +static bool piix_no_sidpr(struct ata_host *host) |
| +{ |
| + struct pci_dev *pdev = to_pci_dev(host->dev); |
| + |
| + /* |
| + * Samsung DB-P70 only has three ATA ports exposed and |
| + * curiously the unconnected first port reports link online |
| + * while not responding to SRST protocol causing excessive |
| + * detection delay. |
| + * |
| + * Unfortunately, the system doesn't carry enough DMI |
| + * information to identify the machine but does have subsystem |
| + * vendor and device set. As it's unclear whether the |
| + * subsystem vendor/device is used only for this specific |
| + * board, the port can't be disabled solely with the |
| + * information; however, turning off SIDPR access works around |
| + * the problem. Turn it off. |
| + * |
| + * This problem is reported in bnc#441240. |
| + * |
| + * https://bugzilla.novell.com/show_bug.cgi?id=441420 |
| + */ |
| + if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2920 && |
| + pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && |
| + pdev->subsystem_device == 0xb049) { |
| + dev_printk(KERN_WARNING, host->dev, |
| + "Samsung DB-P70 detected, disabling SIDPR\n"); |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| static int __devinit piix_init_sidpr(struct ata_host *host) |
| { |
| struct pci_dev *pdev = to_pci_dev(host->dev); |
| @@ -1307,6 +1340,10 @@ static int __devinit piix_init_sidpr(str |
| if (hpriv->map[i] == IDE) |
| return 0; |
| |
| + /* is it blacklisted? */ |
| + if (piix_no_sidpr(host)) |
| + return 0; |
| + |
| if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) |
| return 0; |
| |