aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@pathscale.com>2006-09-28 12:00:13 -0400
committerRoland Dreier <rolandd@cisco.com>2006-09-28 14:16:53 -0400
commit1fd3b40fde3bfacdf742cadfe99cfd47ffd05219 (patch)
tree5f08e8046319dc31d5abdec16764b7889feb9b74
parent076fafcdee37c87564abd1ad993e17d77fc32daa (diff)
IB/ipath: Improved support for PowerPC
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c60
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c55
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c56
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h20
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c56
-rw-r--r--drivers/infiniband/hw/ipath/ipath_wc_ppc64.c20
8 files changed, 198 insertions, 73 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 467816043d10..68fc9b5a4ad8 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -755,8 +755,8 @@ static void get_rhf_errstring(u32 err, char *msg, size_t len)
755static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum, 755static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum,
756 int err) 756 int err)
757{ 757{
758 return dd->ipath_port0_skbs ? 758 return dd->ipath_port0_skbinfo ?
759 (void *)dd->ipath_port0_skbs[bufnum]->data : NULL; 759 (void *) dd->ipath_port0_skbinfo[bufnum].skb->data : NULL;
760} 760}
761 761
762/** 762/**
@@ -778,31 +778,34 @@ struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd,
778 */ 778 */
779 779
780 /* 780 /*
781 * We need 4 extra bytes for unaligned transfer copying 781 * We need 2 extra bytes for ipath_ether data sent in the
782 * key header. In order to keep everything dword aligned,
783 * we'll reserve 4 bytes.
782 */ 784 */
785 len = dd->ipath_ibmaxlen + 4;
786
783 if (dd->ipath_flags & IPATH_4BYTE_TID) { 787 if (dd->ipath_flags & IPATH_4BYTE_TID) {
784 /* we need a 4KB multiple alignment, and there is no way 788 /* We need a 2KB multiple alignment, and there is no way
785 * to do it except to allocate extra and then skb_reserve 789 * to do it except to allocate extra and then skb_reserve
786 * enough to bring it up to the right alignment. 790 * enough to bring it up to the right alignment.
787 */ 791 */
788 len = dd->ipath_ibmaxlen + 4 + (1 << 11) - 1; 792 len += 2047;
789 } 793 }
790 else 794
791 len = dd->ipath_ibmaxlen + 4;
792 skb = __dev_alloc_skb(len, gfp_mask); 795 skb = __dev_alloc_skb(len, gfp_mask);
793 if (!skb) { 796 if (!skb) {
794 ipath_dev_err(dd, "Failed to allocate skbuff, length %u\n", 797 ipath_dev_err(dd, "Failed to allocate skbuff, length %u\n",
795 len); 798 len);
796 goto bail; 799 goto bail;
797 } 800 }
801
802 skb_reserve(skb, 4);
803
798 if (dd->ipath_flags & IPATH_4BYTE_TID) { 804 if (dd->ipath_flags & IPATH_4BYTE_TID) {
799 u32 una = ((1 << 11) - 1) & (unsigned long)(skb->data + 4); 805 u32 una = (unsigned long)skb->data & 2047;
800 if (una) 806 if (una)
801 skb_reserve(skb, 4 + (1 << 11) - una); 807 skb_reserve(skb, 2048 - una);
802 else 808 }
803 skb_reserve(skb, 4);
804 } else
805 skb_reserve(skb, 4);
806 809
807bail: 810bail:
808 return skb; 811 return skb;
@@ -1345,8 +1348,9 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
1345 ipath_cdbg(VERBOSE, "reuse port %d rcvhdrq @%p %llx phys; " 1348 ipath_cdbg(VERBOSE, "reuse port %d rcvhdrq @%p %llx phys; "
1346 "hdrtailaddr@%p %llx physical\n", 1349 "hdrtailaddr@%p %llx physical\n",
1347 pd->port_port, pd->port_rcvhdrq, 1350 pd->port_port, pd->port_rcvhdrq,
1348 pd->port_rcvhdrq_phys, pd->port_rcvhdrtail_kvaddr, 1351 (unsigned long long) pd->port_rcvhdrq_phys,
1349 (unsigned long long)pd->port_rcvhdrqtailaddr_phys); 1352 pd->port_rcvhdrtail_kvaddr, (unsigned long long)
1353 pd->port_rcvhdrqtailaddr_phys);
1350 1354
1351 /* clear for security and sanity on each use */ 1355 /* clear for security and sanity on each use */
1352 memset(pd->port_rcvhdrq, 0, pd->port_rcvhdrq_size); 1356 memset(pd->port_rcvhdrq, 0, pd->port_rcvhdrq_size);
@@ -1827,17 +1831,22 @@ void ipath_free_pddata(struct ipath_devdata *dd, struct ipath_portdata *pd)
1827 kfree(pd->port_rcvegrbuf_phys); 1831 kfree(pd->port_rcvegrbuf_phys);
1828 pd->port_rcvegrbuf_phys = NULL; 1832 pd->port_rcvegrbuf_phys = NULL;
1829 pd->port_rcvegrbuf_chunks = 0; 1833 pd->port_rcvegrbuf_chunks = 0;
1830 } else if (pd->port_port == 0 && dd->ipath_port0_skbs) { 1834 } else if (pd->port_port == 0 && dd->ipath_port0_skbinfo) {
1831 unsigned e; 1835 unsigned e;
1832 struct sk_buff **skbs = dd->ipath_port0_skbs; 1836 struct ipath_skbinfo *skbinfo = dd->ipath_port0_skbinfo;
1833 1837
1834 dd->ipath_port0_skbs = NULL; 1838 dd->ipath_port0_skbinfo = NULL;
1835 ipath_cdbg(VERBOSE, "free closed port %d ipath_port0_skbs " 1839 ipath_cdbg(VERBOSE, "free closed port %d "
1836 "@ %p\n", pd->port_port, skbs); 1840 "ipath_port0_skbinfo @ %p\n", pd->port_port,
1841 skbinfo);
1837 for (e = 0; e < dd->ipath_rcvegrcnt; e++) 1842 for (e = 0; e < dd->ipath_rcvegrcnt; e++)
1838 if (skbs[e]) 1843 if (skbinfo[e].skb) {
1839 dev_kfree_skb(skbs[e]); 1844 pci_unmap_single(dd->pcidev, skbinfo[e].phys,
1840 vfree(skbs); 1845 dd->ipath_ibmaxlen,
1846 PCI_DMA_FROMDEVICE);
1847 dev_kfree_skb(skbinfo[e].skb);
1848 }
1849 vfree(skbinfo);
1841 } 1850 }
1842 kfree(pd->port_tid_pg_list); 1851 kfree(pd->port_tid_pg_list);
1843 vfree(pd->subport_uregbase); 1852 vfree(pd->subport_uregbase);
@@ -1934,7 +1943,7 @@ static void cleanup_device(struct ipath_devdata *dd)
1934 1943
1935 if (dd->ipath_pioavailregs_dma) { 1944 if (dd->ipath_pioavailregs_dma) {
1936 dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, 1945 dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
1937 dd->ipath_pioavailregs_dma, 1946 (void *) dd->ipath_pioavailregs_dma,
1938 dd->ipath_pioavailregs_phys); 1947 dd->ipath_pioavailregs_phys);
1939 dd->ipath_pioavailregs_dma = NULL; 1948 dd->ipath_pioavailregs_dma = NULL;
1940 } 1949 }
@@ -1947,6 +1956,7 @@ static void cleanup_device(struct ipath_devdata *dd)
1947 1956
1948 if (dd->ipath_pageshadow) { 1957 if (dd->ipath_pageshadow) {
1949 struct page **tmpp = dd->ipath_pageshadow; 1958 struct page **tmpp = dd->ipath_pageshadow;
1959 dma_addr_t *tmpd = dd->ipath_physshadow;
1950 int i, cnt = 0; 1960 int i, cnt = 0;
1951 1961
1952 ipath_cdbg(VERBOSE, "Unlocking any expTID pages still " 1962 ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
@@ -1957,6 +1967,8 @@ static void cleanup_device(struct ipath_devdata *dd)
1957 for (i = port_tidbase; i < maxtid; i++) { 1967 for (i = port_tidbase; i < maxtid; i++) {
1958 if (!tmpp[i]) 1968 if (!tmpp[i])
1959 continue; 1969 continue;
1970 pci_unmap_page(dd->pcidev, tmpd[i],
1971 PAGE_SIZE, PCI_DMA_FROMDEVICE);
1960 ipath_release_user_pages(&tmpp[i], 1); 1972 ipath_release_user_pages(&tmpp[i], 1);
1961 tmpp[i] = NULL; 1973 tmpp[i] = NULL;
1962 cnt++; 1974 cnt++;
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index d4fc4118ddd5..64221b937762 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -364,11 +364,14 @@ static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
364 "vaddr %lx\n", i, tid + tidoff, vaddr); 364 "vaddr %lx\n", i, tid + tidoff, vaddr);
365 /* we "know" system pages and TID pages are same size */ 365 /* we "know" system pages and TID pages are same size */
366 dd->ipath_pageshadow[porttid + tid] = pagep[i]; 366 dd->ipath_pageshadow[porttid + tid] = pagep[i];
367 dd->ipath_physshadow[porttid + tid] = ipath_map_page(
368 dd->pcidev, pagep[i], 0, PAGE_SIZE,
369 PCI_DMA_FROMDEVICE);
367 /* 370 /*
368 * don't need atomic or it's overhead 371 * don't need atomic or it's overhead
369 */ 372 */
370 __set_bit(tid, tidmap); 373 __set_bit(tid, tidmap);
371 physaddr = page_to_phys(pagep[i]); 374 physaddr = dd->ipath_physshadow[porttid + tid];
372 ipath_stats.sps_pagelocks++; 375 ipath_stats.sps_pagelocks++;
373 ipath_cdbg(VERBOSE, 376 ipath_cdbg(VERBOSE,
374 "TID %u, vaddr %lx, physaddr %llx pgp %p\n", 377 "TID %u, vaddr %lx, physaddr %llx pgp %p\n",
@@ -402,6 +405,9 @@ static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
402 tid); 405 tid);
403 dd->ipath_f_put_tid(dd, &tidbase[tid], 1, 406 dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
404 dd->ipath_tidinvalid); 407 dd->ipath_tidinvalid);
408 pci_unmap_page(dd->pcidev,
409 dd->ipath_physshadow[porttid + tid],
410 PAGE_SIZE, PCI_DMA_FROMDEVICE);
405 dd->ipath_pageshadow[porttid + tid] = NULL; 411 dd->ipath_pageshadow[porttid + tid] = NULL;
406 ipath_stats.sps_pageunlocks++; 412 ipath_stats.sps_pageunlocks++;
407 } 413 }
@@ -515,6 +521,9 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
515 pd->port_pid, tid); 521 pd->port_pid, tid);
516 dd->ipath_f_put_tid(dd, &tidbase[tid], 1, 522 dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
517 dd->ipath_tidinvalid); 523 dd->ipath_tidinvalid);
524 pci_unmap_page(dd->pcidev,
525 dd->ipath_physshadow[porttid + tid],
526 PAGE_SIZE, PCI_DMA_FROMDEVICE);
518 ipath_release_user_pages( 527 ipath_release_user_pages(
519 &dd->ipath_pageshadow[porttid + tid], 1); 528 &dd->ipath_pageshadow[porttid + tid], 1);
520 dd->ipath_pageshadow[porttid + tid] = NULL; 529 dd->ipath_pageshadow[porttid + tid] = NULL;
@@ -711,7 +720,7 @@ static int ipath_manage_rcvq(struct ipath_portdata *pd, unsigned subport,
711 * updated and correct itself, even in the face of software 720 * updated and correct itself, even in the face of software
712 * bugs. 721 * bugs.
713 */ 722 */
714 *pd->port_rcvhdrtail_kvaddr = 0; 723 *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0;
715 set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, 724 set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
716 &dd->ipath_rcvctrl); 725 &dd->ipath_rcvctrl);
717 } else 726 } else
@@ -923,11 +932,11 @@ bail:
923 932
924/* common code for the mappings on dma_alloc_coherent mem */ 933/* common code for the mappings on dma_alloc_coherent mem */
925static int ipath_mmap_mem(struct vm_area_struct *vma, 934static int ipath_mmap_mem(struct vm_area_struct *vma,
926 struct ipath_portdata *pd, unsigned len, 935 struct ipath_portdata *pd, unsigned len, int write_ok,
927 int write_ok, dma_addr_t addr, char *what) 936 void *kvaddr, char *what)
928{ 937{
929 struct ipath_devdata *dd = pd->port_dd; 938 struct ipath_devdata *dd = pd->port_dd;
930 unsigned pfn = (unsigned long)addr >> PAGE_SHIFT; 939 unsigned long pfn;
931 int ret; 940 int ret;
932 941
933 if ((vma->vm_end - vma->vm_start) > len) { 942 if ((vma->vm_end - vma->vm_start) > len) {
@@ -950,17 +959,17 @@ static int ipath_mmap_mem(struct vm_area_struct *vma,
950 vma->vm_flags &= ~VM_MAYWRITE; 959 vma->vm_flags &= ~VM_MAYWRITE;
951 } 960 }
952 961
962 pfn = virt_to_phys(kvaddr) >> PAGE_SHIFT;
953 ret = remap_pfn_range(vma, vma->vm_start, pfn, 963 ret = remap_pfn_range(vma, vma->vm_start, pfn,
954 len, vma->vm_page_prot); 964 len, vma->vm_page_prot);
955 if (ret) 965 if (ret)
956 dev_info(&dd->pcidev->dev, 966 dev_info(&dd->pcidev->dev, "%s port%u mmap of %lx, %x "
957 "%s port%u mmap of %lx, %x bytes r%c failed: %d\n", 967 "bytes r%c failed: %d\n", what, pd->port_port,
958 what, pd->port_port, (unsigned long)addr, len, 968 pfn, len, write_ok?'w':'o', ret);
959 write_ok?'w':'o', ret);
960 else 969 else
961 ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes r%c\n", 970 ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes "
962 what, pd->port_port, (unsigned long)addr, len, 971 "r%c\n", what, pd->port_port, pfn, len,
963 write_ok?'w':'o'); 972 write_ok?'w':'o');
964bail: 973bail:
965 return ret; 974 return ret;
966} 975}
@@ -1049,7 +1058,7 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
1049 struct ipath_devdata *dd = pd->port_dd; 1058 struct ipath_devdata *dd = pd->port_dd;
1050 unsigned long start, size; 1059 unsigned long start, size;
1051 size_t total_size, i; 1060 size_t total_size, i;
1052 dma_addr_t *phys; 1061 unsigned long pfn;
1053 int ret; 1062 int ret;
1054 1063
1055 size = pd->port_rcvegrbuf_size; 1064 size = pd->port_rcvegrbuf_size;
@@ -1073,11 +1082,11 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
1073 vma->vm_flags &= ~VM_MAYWRITE; 1082 vma->vm_flags &= ~VM_MAYWRITE;
1074 1083
1075 start = vma->vm_start; 1084 start = vma->vm_start;
1076 phys = pd->port_rcvegrbuf_phys;
1077 1085
1078 for (i = 0; i < pd->port_rcvegrbuf_chunks; i++, start += size) { 1086 for (i = 0; i < pd->port_rcvegrbuf_chunks; i++, start += size) {
1079 ret = remap_pfn_range(vma, start, phys[i] >> PAGE_SHIFT, 1087 pfn = virt_to_phys(pd->port_rcvegrbuf[i]) >> PAGE_SHIFT;
1080 size, vma->vm_page_prot); 1088 ret = remap_pfn_range(vma, start, pfn, size,
1089 vma->vm_page_prot);
1081 if (ret < 0) 1090 if (ret < 0)
1082 goto bail; 1091 goto bail;
1083 } 1092 }
@@ -1290,7 +1299,7 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
1290 else if (pgaddr == dd->ipath_pioavailregs_phys) 1299 else if (pgaddr == dd->ipath_pioavailregs_phys)
1291 /* in-memory copy of pioavail registers */ 1300 /* in-memory copy of pioavail registers */
1292 ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0, 1301 ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
1293 dd->ipath_pioavailregs_phys, 1302 (void *) dd->ipath_pioavailregs_dma,
1294 "pioavail registers"); 1303 "pioavail registers");
1295 else if (subport_fp(fp)) 1304 else if (subport_fp(fp))
1296 /* Subports don't mmap the physical receive buffers */ 1305 /* Subports don't mmap the physical receive buffers */
@@ -1304,12 +1313,12 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
1304 * from an i/o perspective. 1313 * from an i/o perspective.
1305 */ 1314 */
1306 ret = ipath_mmap_mem(vma, pd, pd->port_rcvhdrq_size, 1, 1315 ret = ipath_mmap_mem(vma, pd, pd->port_rcvhdrq_size, 1,
1307 pd->port_rcvhdrq_phys, 1316 pd->port_rcvhdrq,
1308 "rcvhdrq"); 1317 "rcvhdrq");
1309 else if (pgaddr == (u64) pd->port_rcvhdrqtailaddr_phys) 1318 else if (pgaddr == (u64) pd->port_rcvhdrqtailaddr_phys)
1310 /* in-memory copy of rcvhdrq tail register */ 1319 /* in-memory copy of rcvhdrq tail register */
1311 ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0, 1320 ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
1312 pd->port_rcvhdrqtailaddr_phys, 1321 pd->port_rcvhdrtail_kvaddr,
1313 "rcvhdrq tail"); 1322 "rcvhdrq tail");
1314 else 1323 else
1315 ret = -EINVAL; 1324 ret = -EINVAL;
@@ -1802,7 +1811,7 @@ static int ipath_do_user_init(struct file *fp,
1802 * We explictly set the in-memory copy to 0 beforehand, so we don't 1811 * We explictly set the in-memory copy to 0 beforehand, so we don't
1803 * have to wait to be sure the DMA update has happened. 1812 * have to wait to be sure the DMA update has happened.
1804 */ 1813 */
1805 *pd->port_rcvhdrtail_kvaddr = 0ULL; 1814 *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0ULL;
1806 set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, 1815 set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
1807 &dd->ipath_rcvctrl); 1816 &dd->ipath_rcvctrl);
1808 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 1817 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
@@ -1832,6 +1841,8 @@ static void unlock_expected_tids(struct ipath_portdata *pd)
1832 if (!dd->ipath_pageshadow[i]) 1841 if (!dd->ipath_pageshadow[i])
1833 continue; 1842 continue;
1834 1843
1844 pci_unmap_page(dd->pcidev, dd->ipath_physshadow[i],
1845 PAGE_SIZE, PCI_DMA_FROMDEVICE);
1835 ipath_release_user_pages_on_close(&dd->ipath_pageshadow[i], 1846 ipath_release_user_pages_on_close(&dd->ipath_pageshadow[i],
1836 1); 1847 1);
1837 dd->ipath_pageshadow[i] = NULL; 1848 dd->ipath_pageshadow[i] = NULL;
@@ -1936,14 +1947,14 @@ static int ipath_close(struct inode *in, struct file *fp)
1936 i = dd->ipath_pbufsport * (port - 1); 1947 i = dd->ipath_pbufsport * (port - 1);
1937 ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport); 1948 ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport);
1938 1949
1950 dd->ipath_f_clear_tids(dd, pd->port_port);
1951
1939 if (dd->ipath_pageshadow) 1952 if (dd->ipath_pageshadow)
1940 unlock_expected_tids(pd); 1953 unlock_expected_tids(pd);
1941 ipath_stats.sps_ports--; 1954 ipath_stats.sps_ports--;
1942 ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n", 1955 ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
1943 pd->port_comm, pd->port_pid, 1956 pd->port_comm, pd->port_pid,
1944 dd->ipath_unit, port); 1957 dd->ipath_unit, port);
1945
1946 dd->ipath_f_clear_tids(dd, pd->port_port);
1947 } 1958 }
1948 1959
1949 pd->port_pid = 0; 1960 pd->port_pid = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index ac5cbe27c068..08a44dd9ed6f 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -1113,7 +1113,7 @@ static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr,
1113 if (pa != dd->ipath_tidinvalid) { 1113 if (pa != dd->ipath_tidinvalid) {
1114 if (pa & ((1U << 11) - 1)) { 1114 if (pa & ((1U << 11) - 1)) {
1115 dev_info(&dd->pcidev->dev, "BUG: physaddr %lx " 1115 dev_info(&dd->pcidev->dev, "BUG: physaddr %lx "
1116 "not 4KB aligned!\n", pa); 1116 "not 2KB aligned!\n", pa);
1117 return; 1117 return;
1118 } 1118 }
1119 pa >>= 11; 1119 pa >>= 11;
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 44669dc2e22d..d819cca524cd 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -88,13 +88,13 @@ MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver");
88static int create_port0_egr(struct ipath_devdata *dd) 88static int create_port0_egr(struct ipath_devdata *dd)
89{ 89{
90 unsigned e, egrcnt; 90 unsigned e, egrcnt;
91 struct sk_buff **skbs; 91 struct ipath_skbinfo *skbinfo;
92 int ret; 92 int ret;
93 93
94 egrcnt = dd->ipath_rcvegrcnt; 94 egrcnt = dd->ipath_rcvegrcnt;
95 95
96 skbs = vmalloc(sizeof(*dd->ipath_port0_skbs) * egrcnt); 96 skbinfo = vmalloc(sizeof(*dd->ipath_port0_skbinfo) * egrcnt);
97 if (skbs == NULL) { 97 if (skbinfo == NULL) {
98 ipath_dev_err(dd, "allocation error for eager TID " 98 ipath_dev_err(dd, "allocation error for eager TID "
99 "skb array\n"); 99 "skb array\n");
100 ret = -ENOMEM; 100 ret = -ENOMEM;
@@ -109,13 +109,13 @@ static int create_port0_egr(struct ipath_devdata *dd)
109 * 4 bytes so that the data buffer stays word aligned. 109 * 4 bytes so that the data buffer stays word aligned.
110 * See ipath_kreceive() for more details. 110 * See ipath_kreceive() for more details.
111 */ 111 */
112 skbs[e] = ipath_alloc_skb(dd, GFP_KERNEL); 112 skbinfo[e].skb = ipath_alloc_skb(dd, GFP_KERNEL);
113 if (!skbs[e]) { 113 if (!skbinfo[e].skb) {
114 ipath_dev_err(dd, "SKB allocation error for " 114 ipath_dev_err(dd, "SKB allocation error for "
115 "eager TID %u\n", e); 115 "eager TID %u\n", e);
116 while (e != 0) 116 while (e != 0)
117 dev_kfree_skb(skbs[--e]); 117 dev_kfree_skb(skbinfo[--e].skb);
118 vfree(skbs); 118 vfree(skbinfo);
119 ret = -ENOMEM; 119 ret = -ENOMEM;
120 goto bail; 120 goto bail;
121 } 121 }
@@ -124,14 +124,17 @@ static int create_port0_egr(struct ipath_devdata *dd)
124 * After loop above, so we can test non-NULL to see if ready 124 * After loop above, so we can test non-NULL to see if ready
125 * to use at receive, etc. 125 * to use at receive, etc.
126 */ 126 */
127 dd->ipath_port0_skbs = skbs; 127 dd->ipath_port0_skbinfo = skbinfo;
128 128
129 for (e = 0; e < egrcnt; e++) { 129 for (e = 0; e < egrcnt; e++) {
130 unsigned long phys = 130 dd->ipath_port0_skbinfo[e].phys =
131 virt_to_phys(dd->ipath_port0_skbs[e]->data); 131 ipath_map_single(dd->pcidev,
132 dd->ipath_port0_skbinfo[e].skb->data,
133 dd->ipath_ibmaxlen, PCI_DMA_FROMDEVICE);
132 dd->ipath_f_put_tid(dd, e + (u64 __iomem *) 134 dd->ipath_f_put_tid(dd, e + (u64 __iomem *)
133 ((char __iomem *) dd->ipath_kregbase + 135 ((char __iomem *) dd->ipath_kregbase +
134 dd->ipath_rcvegrbase), 0, phys); 136 dd->ipath_rcvegrbase), 0,
137 dd->ipath_port0_skbinfo[e].phys);
135 } 138 }
136 139
137 ret = 0; 140 ret = 0;
@@ -432,16 +435,33 @@ done:
432 */ 435 */
433static void init_shadow_tids(struct ipath_devdata *dd) 436static void init_shadow_tids(struct ipath_devdata *dd)
434{ 437{
435 dd->ipath_pageshadow = (struct page **) 438 struct page **pages;
436 vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt * 439 dma_addr_t *addrs;
440
441 pages = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
437 sizeof(struct page *)); 442 sizeof(struct page *));
438 if (!dd->ipath_pageshadow) 443 if (!pages) {
439 ipath_dev_err(dd, "failed to allocate shadow page * " 444 ipath_dev_err(dd, "failed to allocate shadow page * "
440 "array, no expected sends!\n"); 445 "array, no expected sends!\n");
441 else 446 dd->ipath_pageshadow = NULL;
442 memset(dd->ipath_pageshadow, 0, 447 return;
443 dd->ipath_cfgports * dd->ipath_rcvtidcnt * 448 }
444 sizeof(struct page *)); 449
450 addrs = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
451 sizeof(dma_addr_t));
452 if (!addrs) {
453 ipath_dev_err(dd, "failed to allocate shadow dma handle "
454 "array, no expected sends!\n");
455 vfree(dd->ipath_pageshadow);
456 dd->ipath_pageshadow = NULL;
457 return;
458 }
459
460 memset(pages, 0, dd->ipath_cfgports * dd->ipath_rcvtidcnt *
461 sizeof(struct page *));
462
463 dd->ipath_pageshadow = pages;
464 dd->ipath_physshadow = addrs;
445} 465}
446 466
447static void enable_chip(struct ipath_devdata *dd, 467static void enable_chip(struct ipath_devdata *dd,
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 54b3dbc8195a..f4d8aafc6306 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -605,7 +605,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
605 * don't report same point multiple times, 605 * don't report same point multiple times,
606 * except kernel 606 * except kernel
607 */ 607 */
608 tl = (u32) * pd->port_rcvhdrtail_kvaddr; 608 tl = *(u64 *) pd->port_rcvhdrtail_kvaddr;
609 if (tl == dd->ipath_lastrcvhdrqtails[i]) 609 if (tl == dd->ipath_lastrcvhdrqtails[i])
610 continue; 610 continue;
611 hd = ipath_read_ureg32(dd, ur_rcvhdrhead, 611 hd = ipath_read_ureg32(dd, ur_rcvhdrhead,
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 96e2bd8fb5f8..2a0e9a430634 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -39,6 +39,8 @@
39 */ 39 */
40 40
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/pci.h>
43#include <linux/dma-mapping.h>
42#include <asm/io.h> 44#include <asm/io.h>
43 45
44#include "ipath_common.h" 46#include "ipath_common.h"
@@ -62,7 +64,7 @@ struct ipath_portdata {
62 /* rcvhdrq base, needs mmap before useful */ 64 /* rcvhdrq base, needs mmap before useful */
63 void *port_rcvhdrq; 65 void *port_rcvhdrq;
64 /* kernel virtual address where hdrqtail is updated */ 66 /* kernel virtual address where hdrqtail is updated */
65 volatile __le64 *port_rcvhdrtail_kvaddr; 67 void *port_rcvhdrtail_kvaddr;
66 /* 68 /*
67 * temp buffer for expected send setup, allocated at open, instead 69 * temp buffer for expected send setup, allocated at open, instead
68 * of each setup call 70 * of each setup call
@@ -146,6 +148,11 @@ struct _ipath_layer {
146 void *l_arg; 148 void *l_arg;
147}; 149};
148 150
151struct ipath_skbinfo {
152 struct sk_buff *skb;
153 dma_addr_t phys;
154};
155
149struct ipath_devdata { 156struct ipath_devdata {
150 struct list_head ipath_list; 157 struct list_head ipath_list;
151 158
@@ -168,7 +175,7 @@ struct ipath_devdata {
168 /* ipath_cfgports pointers */ 175 /* ipath_cfgports pointers */
169 struct ipath_portdata **ipath_pd; 176 struct ipath_portdata **ipath_pd;
170 /* sk_buffs used by port 0 eager receive queue */ 177 /* sk_buffs used by port 0 eager receive queue */
171 struct sk_buff **ipath_port0_skbs; 178 struct ipath_skbinfo *ipath_port0_skbinfo;
172 /* kvirt address of 1st 2k pio buffer */ 179 /* kvirt address of 1st 2k pio buffer */
173 void __iomem *ipath_pio2kbase; 180 void __iomem *ipath_pio2kbase;
174 /* kvirt address of 1st 4k pio buffer */ 181 /* kvirt address of 1st 4k pio buffer */
@@ -335,6 +342,8 @@ struct ipath_devdata {
335 u64 *ipath_tidsimshadow; 342 u64 *ipath_tidsimshadow;
336 /* shadow copy of struct page *'s for exp tid pages */ 343 /* shadow copy of struct page *'s for exp tid pages */
337 struct page **ipath_pageshadow; 344 struct page **ipath_pageshadow;
345 /* shadow copy of dma handles for exp tid pages */
346 dma_addr_t *ipath_physshadow;
338 /* lock to workaround chip bug 9437 */ 347 /* lock to workaround chip bug 9437 */
339 spinlock_t ipath_tid_lock; 348 spinlock_t ipath_tid_lock;
340 349
@@ -865,6 +874,13 @@ int ipathfs_add_device(struct ipath_devdata *);
865int ipathfs_remove_device(struct ipath_devdata *); 874int ipathfs_remove_device(struct ipath_devdata *);
866 875
867/* 876/*
877 * dma_addr wrappers - all 0's invalid for hw
878 */
879dma_addr_t ipath_map_page(struct pci_dev *, struct page *, unsigned long,
880 size_t, int);
881dma_addr_t ipath_map_single(struct pci_dev *, void *, size_t, int);
882
883/*
868 * Flush write combining store buffers (if present) and perform a write 884 * Flush write combining store buffers (if present) and perform a write
869 * barrier. 885 * barrier.
870 */ 886 */
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index e32fca9faf80..413754b1d8a2 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -90,6 +90,62 @@ bail:
90} 90}
91 91
92/** 92/**
93 * ipath_map_page - a safety wrapper around pci_map_page()
94 *
95 * A dma_addr of all 0's is interpreted by the chip as "disabled".
96 * Unfortunately, it can also be a valid dma_addr returned on some
97 * architectures.
98 *
99 * The powerpc iommu assigns dma_addrs in ascending order, so we don't
100 * have to bother with retries or mapping a dummy page to insure we
101 * don't just get the same mapping again.
102 *
103 * I'm sure we won't be so lucky with other iommu's, so FIXME.
104 */
105dma_addr_t ipath_map_page(struct pci_dev *hwdev, struct page *page,
106 unsigned long offset, size_t size, int direction)
107{
108 dma_addr_t phys;
109
110 phys = pci_map_page(hwdev, page, offset, size, direction);
111
112 if (phys == 0) {
113 pci_unmap_page(hwdev, phys, size, direction);
114 phys = pci_map_page(hwdev, page, offset, size, direction);
115 /*
116 * FIXME: If we get 0 again, we should keep this page,
117 * map another, then free the 0 page.
118 */
119 }
120
121 return phys;
122}
123
124/**
125 * ipath_map_single - a safety wrapper around pci_map_single()
126 *
127 * Same idea as ipath_map_page().
128 */
129dma_addr_t ipath_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
130 int direction)
131{
132 dma_addr_t phys;
133
134 phys = pci_map_single(hwdev, ptr, size, direction);
135
136 if (phys == 0) {
137 pci_unmap_single(hwdev, phys, size, direction);
138 phys = pci_map_single(hwdev, ptr, size, direction);
139 /*
140 * FIXME: If we get 0 again, we should keep this page,
141 * map another, then free the 0 page.
142 */
143 }
144
145 return phys;
146}
147
148/**
93 * ipath_get_user_pages - lock user pages into memory 149 * ipath_get_user_pages - lock user pages into memory
94 * @start_page: the start page 150 * @start_page: the start page
95 * @num_pages: the number of pages 151 * @num_pages: the number of pages
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c b/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
index 036fde662aa9..0095bb70f34e 100644
--- a/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
+++ b/drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
@@ -38,13 +38,23 @@
38#include "ipath_kernel.h" 38#include "ipath_kernel.h"
39 39
40/** 40/**
41 * ipath_unordered_wc - indicate whether write combining is ordered 41 * ipath_enable_wc - enable write combining for MMIO writes to the device
42 * @dd: infinipath device
42 * 43 *
43 * PowerPC systems (at least those in the 970 processor family) 44 * Nothing to do on PowerPC, so just return without error.
44 * write partially filled store buffers in address order, but will write 45 */
45 * completely filled store buffers in "random" order, and therefore must 46int ipath_enable_wc(struct ipath_devdata *dd)
46 * have serialization for correctness with current InfiniPath chips. 47{
48 return 0;
49}
50
51/**
52 * ipath_unordered_wc - indicate whether write combining is unordered
47 * 53 *
54 * Because our performance depends on our ability to do write
55 * combining mmio writes in the most efficient way, we need to
56 * know if we are on a processor that may reorder stores when
57 * write combining.
48 */ 58 */
49int ipath_unordered_wc(void) 59int ipath_unordered_wc(void)
50{ 60{