aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/ipath/Kconfig3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c18
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_wc_x86_64.c43
4 files changed, 26 insertions, 42 deletions
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig
index 1d9bb115cbf6..8fe54ff00580 100644
--- a/drivers/infiniband/hw/ipath/Kconfig
+++ b/drivers/infiniband/hw/ipath/Kconfig
@@ -9,3 +9,6 @@ config INFINIBAND_IPATH
9 as IP-over-InfiniBand as well as with userspace applications 9 as IP-over-InfiniBand as well as with userspace applications
10 (in conjunction with InfiniBand userspace access). 10 (in conjunction with InfiniBand userspace access).
11 For QLogic PCIe QLE based cards, use the QIB driver instead. 11 For QLogic PCIe QLE based cards, use the QIB driver instead.
12
13 If you have this hardware you will need to boot with PAT disabled
14 on your x86-64 systems, use the nopat kernel parameter.
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index bd0caedafe99..2d7e503d13cb 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -42,6 +42,9 @@
42#include <linux/bitmap.h> 42#include <linux/bitmap.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/module.h> 44#include <linux/module.h>
45#ifdef CONFIG_X86_64
46#include <asm/pat.h>
47#endif
45 48
46#include "ipath_kernel.h" 49#include "ipath_kernel.h"
47#include "ipath_verbs.h" 50#include "ipath_verbs.h"
@@ -395,6 +398,14 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
395 unsigned long long addr; 398 unsigned long long addr;
396 u32 bar0 = 0, bar1 = 0; 399 u32 bar0 = 0, bar1 = 0;
397 400
401#ifdef CONFIG_X86_64
402 if (WARN(pat_enabled(),
403 "ipath needs PAT disabled, boot with nopat kernel parameter\n")) {
404 ret = -ENODEV;
405 goto bail;
406 }
407#endif
408
398 dd = ipath_alloc_devdata(pdev); 409 dd = ipath_alloc_devdata(pdev);
399 if (IS_ERR(dd)) { 410 if (IS_ERR(dd)) {
400 ret = PTR_ERR(dd); 411 ret = PTR_ERR(dd);
@@ -542,6 +553,7 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
542 dd->ipath_kregbase = __ioremap(addr, len, 553 dd->ipath_kregbase = __ioremap(addr, len,
543 (_PAGE_NO_CACHE|_PAGE_WRITETHRU)); 554 (_PAGE_NO_CACHE|_PAGE_WRITETHRU));
544#else 555#else
556 /* XXX: split this properly to enable on PAT */
545 dd->ipath_kregbase = ioremap_nocache(addr, len); 557 dd->ipath_kregbase = ioremap_nocache(addr, len);
546#endif 558#endif
547 559
@@ -587,12 +599,8 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
587 599
588 ret = ipath_enable_wc(dd); 600 ret = ipath_enable_wc(dd);
589 601
590 if (ret) { 602 if (ret)
591 ipath_dev_err(dd, "Write combining not enabled "
592 "(err %d): performance may be poor\n",
593 -ret);
594 ret = 0; 603 ret = 0;
595 }
596 604
597 ipath_verify_pioperf(dd); 605 ipath_verify_pioperf(dd);
598 606
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index e08db7020cd4..f0f947122779 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -463,9 +463,7 @@ struct ipath_devdata {
463 /* offset in HT config space of slave/primary interface block */ 463 /* offset in HT config space of slave/primary interface block */
464 u8 ipath_ht_slave_off; 464 u8 ipath_ht_slave_off;
465 /* for write combining settings */ 465 /* for write combining settings */
466 unsigned long ipath_wc_cookie; 466 int wc_cookie;
467 unsigned long ipath_wc_base;
468 unsigned long ipath_wc_len;
469 /* ref count for each pkey */ 467 /* ref count for each pkey */
470 atomic_t ipath_pkeyrefs[4]; 468 atomic_t ipath_pkeyrefs[4];
471 /* shadow copy of struct page *'s for exp tid pages */ 469 /* shadow copy of struct page *'s for exp tid pages */
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
index 4ad0b932df1f..7b6e4c843e19 100644
--- a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
+++ b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <asm/mtrr.h>
41#include <asm/processor.h> 40#include <asm/processor.h>
42 41
43#include "ipath_kernel.h" 42#include "ipath_kernel.h"
@@ -122,27 +121,14 @@ int ipath_enable_wc(struct ipath_devdata *dd)
122 } 121 }
123 122
124 if (!ret) { 123 if (!ret) {
125 int cookie; 124 dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen);
126 ipath_cdbg(VERBOSE, "Setting mtrr for chip to WC " 125 if (dd->wc_cookie < 0) {
127 "(addr %llx, len=0x%llx)\n", 126 ipath_dev_err(dd, "Seting mtrr failed on PIO buffers\n");
128 (unsigned long long) pioaddr, 127 ret = -ENODEV;
129 (unsigned long long) piolen); 128 } else if (dd->wc_cookie == 0)
130 cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); 129 ipath_cdbg(VERBOSE, "Set mtrr for chip to WC not needed\n");
131 if (cookie < 0) { 130 else
132 { 131 ipath_cdbg(VERBOSE, "Set mtrr for chip to WC\n");
133 dev_info(&dd->pcidev->dev,
134 "mtrr_add() WC for PIO bufs "
135 "failed (%d)\n",
136 cookie);
137 ret = -EINVAL;
138 }
139 } else {
140 ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, "
141 "cookie is %d\n", cookie);
142 dd->ipath_wc_cookie = cookie;
143 dd->ipath_wc_base = (unsigned long) pioaddr;
144 dd->ipath_wc_len = (unsigned long) piolen;
145 }
146 } 132 }
147 133
148 return ret; 134 return ret;
@@ -154,16 +140,5 @@ int ipath_enable_wc(struct ipath_devdata *dd)
154 */ 140 */
155void ipath_disable_wc(struct ipath_devdata *dd) 141void ipath_disable_wc(struct ipath_devdata *dd)
156{ 142{
157 if (dd->ipath_wc_cookie) { 143 arch_phys_wc_del(dd->wc_cookie);
158 int r;
159 ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n");
160 r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base,
161 dd->ipath_wc_len);
162 if (r < 0)
163 dev_info(&dd->pcidev->dev,
164 "mtrr_del(%lx, %lx, %lx) failed: %d\n",
165 dd->ipath_wc_cookie, dd->ipath_wc_base,
166 dd->ipath_wc_len, r);
167 dd->ipath_wc_cookie = 0; /* even on failure */
168 }
169} 144}