]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/libata-ahci-enclosure-management-bios-workaround
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / libata-ahci-enclosure-management-bios-workaround
CommitLineData
00e5a55c
BS
1From 4c1e9aa41b2f9afe8f26e2efe5bb4695f6c40772 Mon Sep 17 00:00:00 2001
2From: David Milburn <dmilburn@redhat.com>
3Date: Fri, 3 Apr 2009 15:36:41 -0500
4Subject: libata: ahci enclosure management bios workaround
5References: bnc#489005
6
7During driver initialization ahci_start_port may not be able
8to turn LEDs off because the hardware may still be transmitting
9a message. And since the BIOS may not be setting the LEDs to
10off the drive LEDs may end up in a fault state. This has
11been seen on ICH9r and ICH10r when configured in AHCI mode
12instead of RAID mode, this patch doesn't key off a specific
13set of device IDs but will give the EM transmit bit a chance
14to clear if busy.
15
16Signed-off-by: David Milburn <dmilburn@redhat.com>
17Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
18Signed-off-by: Tejun Heo <teheo@suse.de>
19---
20 drivers/ata/ahci.c | 17 +++++++++++++++--
21 1 file changed, 15 insertions(+), 2 deletions(-)
22
23Index: linux-2.6.27-SLE11_BRANCH/drivers/ata/ahci.c
24===================================================================
25--- linux-2.6.27-SLE11_BRANCH.orig/drivers/ata/ahci.c
26+++ linux-2.6.27-SLE11_BRANCH/drivers/ata/ahci.c
27@@ -62,6 +62,7 @@ static ssize_t ahci_led_store(struct ata
28 static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
29 ssize_t size);
30 #define MAX_SLOTS 8
31+#define MAX_RETRY 15
32
33 enum {
34 AHCI_PCI_BAR = 5,
35@@ -1095,6 +1096,8 @@ static void ahci_start_port(struct ata_p
36 struct ahci_port_priv *pp = ap->private_data;
37 struct ata_link *link;
38 struct ahci_em_priv *emp;
39+ ssize_t rc;
40+ int i;
41
42 /* enable FIS reception */
43 ahci_start_fis_rx(ap);
44@@ -1106,7 +1109,17 @@ static void ahci_start_port(struct ata_p
45 if (ap->flags & ATA_FLAG_EM) {
46 ata_port_for_each_link(link, ap) {
47 emp = &pp->em_priv[link->pmp];
48- ahci_transmit_led_message(ap, emp->led_state, 4);
49+
50+ /* EM Transmit bit maybe busy during init */
51+ for (i = 0; i < MAX_RETRY; i++) {
52+ rc = ahci_transmit_led_message(ap,
53+ emp->led_state,
54+ 4);
55+ if (rc == -EBUSY)
56+ udelay(100);
57+ else
58+ break;
59+ }
60 }
61 }
62
63@@ -1308,7 +1321,7 @@ static ssize_t ahci_transmit_led_message
64 em_ctl = readl(mmio + HOST_EM_CTL);
65 if (em_ctl & EM_CTL_TM) {
66 spin_unlock_irqrestore(ap->lock, flags);
67- return -EINVAL;
68+ return -EBUSY;
69 }
70
71 /*