View | Details | Raw Unified | Return to bug 10138 | Differences between
and this patch

Collapse All | Expand All

(-)a/drivers/acpi/pci_irq.c (+98 lines)
Lines 25-30 Link Here
25
 */
25
 */
26
26
27
27
28
#include <linux/dmi.h>
28
#include <linux/kernel.h>
29
#include <linux/kernel.h>
29
#include <linux/module.h>
30
#include <linux/module.h>
30
#include <linux/init.h>
31
#include <linux/init.h>
Lines 76-81 static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment, Link Here
76
	return NULL;
77
	return NULL;
77
}
78
}
78
79
80
/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
81
static struct dmi_system_id medion_md9580[] = {
82
	{
83
		.ident = "Medion MD9580-F laptop",
84
		.matches = {
85
			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
86
			DMI_MATCH(DMI_PRODUCT_NAME, "A555"),
87
		},
88
	},
89
	{ }
90
};
91
92
/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
93
static struct dmi_system_id dell_optiplex[] = {
94
	{
95
		.ident = "Dell Optiplex GX1",
96
		.matches = {
97
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
98
			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"),
99
		},
100
	},
101
	{ }
102
};
103
104
/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
105
static struct dmi_system_id hp_t5710[] = {
106
	{
107
		.ident = "HP t5710",
108
		.matches = {
109
			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
110
			DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"),
111
			DMI_MATCH(DMI_BOARD_NAME, "098Ch"),
112
		},
113
	},
114
	{ }
115
};
116
117
struct prt_quirk {
118
	struct dmi_system_id	*system;
119
	unsigned int		segment;
120
	unsigned int		bus;
121
	unsigned int		device;
122
	unsigned char		pin;
123
	char			*source;	/* according to BIOS */
124
	char			*actual_source;
125
};
126
127
/*
128
 * These systems have incorrect _PRT entries.  The BIOS claims the PCI
129
 * interrupt at the listed segment/bus/device/pin is connected to the first
130
 * link device, but it is actually connected to the second.
131
 */
132
static struct prt_quirk prt_quirks[] = {
133
	{ medion_md9580, 0, 0, 9, 'A',
134
		"\\_SB_.PCI0.ISA.LNKA",
135
		"\\_SB_.PCI0.ISA.LNKB"},
136
	{ dell_optiplex, 0, 0, 0xd, 'A',
137
		"\\_SB_.LNKB",
138
		"\\_SB_.LNKA"},
139
	{ hp_t5710, 0, 0, 1, 'A',
140
		"\\_SB_.PCI0.LNK1",
141
		"\\_SB_.PCI0.LNK3"},
142
};
143
144
static void
145
do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
146
{
147
	int i;
148
	struct prt_quirk *quirk;
149
150
	for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
151
		quirk = &prt_quirks[i];
152
153
		/* All current quirks involve link devices, not GSIs */
154
		if (!prt->source)
155
			continue;
156
157
		if (dmi_check_system(quirk->system) &&
158
		    entry->id.segment == quirk->segment &&
159
		    entry->id.bus == quirk->bus &&
160
		    entry->id.device == quirk->device &&
161
		    entry->pin + 'A' == quirk->pin &&
162
		    !strcmp(prt->source, quirk->source) &&
163
		    strlen(prt->source) >= strlen(quirk->actual_source)) {
164
			printk(KERN_WARNING PREFIX "firmware reports "
165
				"%04x:%02x:%02x[%c] connected to %s; "
166
				"changing to %s\n",
167
				entry->id.segment, entry->id.bus,
168
				entry->id.device, 'A' + entry->pin,
169
				prt->source, quirk->actual_source);
170
			strcpy(prt->source, quirk->actual_source);
171
		}
172
	}
173
}
174
79
static int
175
static int
80
acpi_pci_irq_add_entry(acpi_handle handle,
176
acpi_pci_irq_add_entry(acpi_handle handle,
81
		       int segment, int bus, struct acpi_pci_routing_table *prt)
177
		       int segment, int bus, struct acpi_pci_routing_table *prt)
Lines 96-101 acpi_pci_irq_add_entry(acpi_handle handle, Link Here
96
	entry->id.function = prt->address & 0xFFFF;
192
	entry->id.function = prt->address & 0xFFFF;
97
	entry->pin = prt->pin;
193
	entry->pin = prt->pin;
98
194
195
	do_prt_fixups(entry, prt);
196
99
	/*
197
	/*
100
	 * Type 1: Dynamic
198
	 * Type 1: Dynamic
101
	 * ---------------
199
	 * ---------------

Return to bug 10138