diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/infiniband/hw/ipath/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 18 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_wc_x86_64.c | 43 |
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 | */ |
| 155 | void ipath_disable_wc(struct ipath_devdata *dd) | 141 | void 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 | } |
