aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/pci-dma.c8
-rw-r--r--arch/x86/pci/i386.c4
-rw-r--r--drivers/pci/intel-iommu.c6
-rw-r--r--drivers/pci/pci-acpi.c109
-rw-r--r--drivers/pci/quirks.c1
5 files changed, 89 insertions, 39 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 0c37f16b6950..c5ef1af8e79d 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
385 if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) 385 if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
386 return memory; 386 return memory;
387 387
388 if (!dev) 388 if (!dev) {
389 dev = &fallback_dev; 389 dev = &fallback_dev;
390 gfp |= GFP_DMA;
391 }
390 dma_mask = dev->coherent_dma_mask; 392 dma_mask = dev->coherent_dma_mask;
391 if (dma_mask == 0) 393 if (dma_mask == 0)
392 dma_mask = DMA_32BIT_MASK; 394 dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
393 395
394 /* Device not DMA able */ 396 /* Device not DMA able */
395 if (dev->dma_mask == NULL) 397 if (dev->dma_mask == NULL)
@@ -403,7 +405,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
403 larger than 16MB and in this case we have a chance of 405 larger than 16MB and in this case we have a chance of
404 finding fitting memory in the next higher zone first. If 406 finding fitting memory in the next higher zone first. If
405 not retry with true GFP_DMA. -AK */ 407 not retry with true GFP_DMA. -AK */
406 if (dma_mask <= DMA_32BIT_MASK) 408 if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
407 gfp |= GFP_DMA32; 409 gfp |= GFP_DMA32;
408#endif 410#endif
409 411
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 8af0f0bae2af..10fb308fded8 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -301,15 +301,13 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
301 prot = pgprot_val(vma->vm_page_prot); 301 prot = pgprot_val(vma->vm_page_prot);
302 if (pat_wc_enabled && write_combine) 302 if (pat_wc_enabled && write_combine)
303 prot |= _PAGE_CACHE_WC; 303 prot |= _PAGE_CACHE_WC;
304 else if (pat_wc_enabled) 304 else if (pat_wc_enabled || boot_cpu_data.x86 > 3)
305 /* 305 /*
306 * ioremap() and ioremap_nocache() defaults to UC MINUS for now. 306 * ioremap() and ioremap_nocache() defaults to UC MINUS for now.
307 * To avoid attribute conflicts, request UC MINUS here 307 * To avoid attribute conflicts, request UC MINUS here
308 * aswell. 308 * aswell.
309 */ 309 */
310 prot |= _PAGE_CACHE_UC_MINUS; 310 prot |= _PAGE_CACHE_UC_MINUS;
311 else if (boot_cpu_data.x86 > 3)
312 prot |= _PAGE_CACHE_UC;
313 311
314 vma->vm_page_prot = __pgprot(prot); 312 vma->vm_page_prot = __pgprot(prot);
315 313
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 1fd8bb765702..66c0fd21894b 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -49,7 +49,7 @@
49 49
50#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 50#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
51 51
52#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */ 52#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
53 53
54#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) 54#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
55 55
@@ -490,12 +490,12 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu)
490 490
491#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ 491#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
492{\ 492{\
493 unsigned long start_time = jiffies;\ 493 cycles_t start_time = get_cycles();\
494 while (1) {\ 494 while (1) {\
495 sts = op (iommu->reg + offset);\ 495 sts = op (iommu->reg + offset);\
496 if (cond)\ 496 if (cond)\
497 break;\ 497 break;\
498 if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\ 498 if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
499 panic("DMAR hardware is malfunctioning\n");\ 499 panic("DMAR hardware is malfunctioning\n");\
500 cpu_relax();\ 500 cpu_relax();\
501 }\ 501 }\
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 72f7476930c8..9d6fc8e6285d 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -19,8 +19,31 @@
19#include <linux/pci-acpi.h> 19#include <linux/pci-acpi.h>
20#include "pci.h" 20#include "pci.h"
21 21
22static u32 ctrlset_buf[3] = {0, 0, 0}; 22struct acpi_osc_data {
23static u32 global_ctrlsets = 0; 23 acpi_handle handle;
24 u32 ctrlset_buf[3];
25 u32 global_ctrlsets;
26 struct list_head sibiling;
27};
28static LIST_HEAD(acpi_osc_data_list);
29
30static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
31{
32 struct acpi_osc_data *data;
33
34 list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
35 if (data->handle == handle)
36 return data;
37 }
38 data = kzalloc(sizeof(*data), GFP_KERNEL);
39 if (!data)
40 return NULL;
41 INIT_LIST_HEAD(&data->sibiling);
42 data->handle = handle;
43 list_add_tail(&data->sibiling, &acpi_osc_data_list);
44 return data;
45}
46
24static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; 47static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
25 48
26static acpi_status 49static acpi_status
@@ -37,8 +60,27 @@ acpi_query_osc (
37 union acpi_object *out_obj; 60 union acpi_object *out_obj;
38 u32 osc_dw0; 61 u32 osc_dw0;
39 acpi_status *ret_status = (acpi_status *)retval; 62 acpi_status *ret_status = (acpi_status *)retval;
63 struct acpi_osc_data *osc_data;
64 u32 flags = (unsigned long)context, temp;
65 acpi_handle tmp;
66
67 status = acpi_get_handle(handle, "_OSC", &tmp);
68 if (ACPI_FAILURE(status))
69 return status;
70
71 osc_data = acpi_get_osc_data(handle);
72 if (!osc_data) {
73 printk(KERN_ERR "acpi osc data array is full\n");
74 return AE_ERROR;
75 }
76
77 osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
78
79 /* do _OSC query for all possible controls */
80 temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE];
81 osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
82 osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
40 83
41
42 /* Setting up input parameters */ 84 /* Setting up input parameters */
43 input.count = 4; 85 input.count = 4;
44 input.pointer = in_params; 86 input.pointer = in_params;
@@ -51,13 +93,11 @@ acpi_query_osc (
51 in_params[2].integer.value = 3; 93 in_params[2].integer.value = 3;
52 in_params[3].type = ACPI_TYPE_BUFFER; 94 in_params[3].type = ACPI_TYPE_BUFFER;
53 in_params[3].buffer.length = 12; 95 in_params[3].buffer.length = 12;
54 in_params[3].buffer.pointer = (u8 *)context; 96 in_params[3].buffer.pointer = (u8 *)osc_data->ctrlset_buf;
55 97
56 status = acpi_evaluate_object(handle, "_OSC", &input, &output); 98 status = acpi_evaluate_object(handle, "_OSC", &input, &output);
57 if (ACPI_FAILURE (status)) { 99 if (ACPI_FAILURE(status))
58 *ret_status = status; 100 goto out_nofree;
59 return status;
60 }
61 out_obj = output.pointer; 101 out_obj = output.pointer;
62 102
63 if (out_obj->type != ACPI_TYPE_BUFFER) { 103 if (out_obj->type != ACPI_TYPE_BUFFER) {
@@ -76,7 +116,8 @@ acpi_query_osc (
76 printk(KERN_DEBUG "_OSC invalid revision\n"); 116 printk(KERN_DEBUG "_OSC invalid revision\n");
77 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { 117 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
78 /* Update Global Control Set */ 118 /* Update Global Control Set */
79 global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8)); 119 osc_data->global_ctrlsets =
120 *((u32 *)(out_obj->buffer.pointer + 8));
80 status = AE_OK; 121 status = AE_OK;
81 goto query_osc_out; 122 goto query_osc_out;
82 } 123 }
@@ -85,12 +126,21 @@ acpi_query_osc (
85 } 126 }
86 127
87 /* Update Global Control Set */ 128 /* Update Global Control Set */
88 global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8)); 129 osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
89 status = AE_OK; 130 status = AE_OK;
90 131
91query_osc_out: 132query_osc_out:
92 kfree(output.pointer); 133 kfree(output.pointer);
134out_nofree:
93 *ret_status = status; 135 *ret_status = status;
136
137 osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
138 osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp;
139 if (ACPI_FAILURE(status)) {
140 /* no osc support at all */
141 osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
142 }
143
94 return status; 144 return status;
95} 145}
96 146
@@ -165,28 +215,15 @@ run_osc_out:
165 **/ 215 **/
166acpi_status __pci_osc_support_set(u32 flags, const char *hid) 216acpi_status __pci_osc_support_set(u32 flags, const char *hid)
167{ 217{
168 u32 temp; 218 acpi_status retval = AE_NOT_FOUND;
169 acpi_status retval;
170 219
171 if (!(flags & OSC_SUPPORT_MASKS)) { 220 if (!(flags & OSC_SUPPORT_MASKS)) {
172 return AE_TYPE; 221 return AE_TYPE;
173 } 222 }
174 ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
175
176 /* do _OSC query for all possible controls */
177 temp = ctrlset_buf[OSC_CONTROL_TYPE];
178 ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
179 ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
180 acpi_get_devices(hid, 223 acpi_get_devices(hid,
181 acpi_query_osc, 224 acpi_query_osc,
182 ctrlset_buf, 225 (void *)(unsigned long)flags,
183 (void **) &retval ); 226 (void **) &retval );
184 ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
185 ctrlset_buf[OSC_CONTROL_TYPE] = temp;
186 if (ACPI_FAILURE(retval)) {
187 /* no osc support at all */
188 ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
189 }
190 return AE_OK; 227 return AE_OK;
191} 228}
192 229
@@ -201,19 +238,31 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
201{ 238{
202 acpi_status status; 239 acpi_status status;
203 u32 ctrlset; 240 u32 ctrlset;
241 acpi_handle tmp;
242 struct acpi_osc_data *osc_data;
243
244 status = acpi_get_handle(handle, "_OSC", &tmp);
245 if (ACPI_FAILURE(status))
246 return status;
247
248 osc_data = acpi_get_osc_data(handle);
249 if (!osc_data) {
250 printk(KERN_ERR "acpi osc data array is full\n");
251 return AE_ERROR;
252 }
204 253
205 ctrlset = (flags & OSC_CONTROL_MASKS); 254 ctrlset = (flags & OSC_CONTROL_MASKS);
206 if (!ctrlset) { 255 if (!ctrlset) {
207 return AE_TYPE; 256 return AE_TYPE;
208 } 257 }
209 if (ctrlset_buf[OSC_SUPPORT_TYPE] && 258 if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] &&
210 ((global_ctrlsets & ctrlset) != ctrlset)) { 259 ((osc_data->global_ctrlsets & ctrlset) != ctrlset)) {
211 return AE_SUPPORT; 260 return AE_SUPPORT;
212 } 261 }
213 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; 262 osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
214 status = acpi_run_osc(handle, ctrlset_buf); 263 status = acpi_run_osc(handle, osc_data->ctrlset_buf);
215 if (ACPI_FAILURE (status)) { 264 if (ACPI_FAILURE (status)) {
216 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; 265 osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
217 } 266 }
218 267
219 return status; 268 return status;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index afd914ebe215..f2d9c770f51a 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1826,6 +1826,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
1826 } 1826 }
1827} 1827}
1828DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); 1828DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
1829DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
1829 1830
1830static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) 1831static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
1831{ 1832{