]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - 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
1 From 4c1e9aa41b2f9afe8f26e2efe5bb4695f6c40772 Mon Sep 17 00:00:00 2001
2 From: David Milburn <dmilburn@redhat.com>
3 Date: Fri, 3 Apr 2009 15:36:41 -0500
4 Subject: libata: ahci enclosure management bios workaround
5 References: bnc#489005
6
7 During driver initialization ahci_start_port may not be able
8 to turn LEDs off because the hardware may still be transmitting
9 a message. And since the BIOS may not be setting the LEDs to
10 off the drive LEDs may end up in a fault state. This has
11 been seen on ICH9r and ICH10r when configured in AHCI mode
12 instead of RAID mode, this patch doesn't key off a specific
13 set of device IDs but will give the EM transmit bit a chance
14 to clear if busy.
15
16 Signed-off-by: David Milburn <dmilburn@redhat.com>
17 Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
18 Signed-off-by: Tejun Heo <teheo@suse.de>
19 ---
20 drivers/ata/ahci.c | 17 +++++++++++++++--
21 1 file changed, 15 insertions(+), 2 deletions(-)
22
23 Index: 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 /*