Author: cem
Date: Wed Nov 18 22:20:40 2015
New Revision: 291033
URL: https://svnweb.freebsd.org/changeset/base/291033

Log:
  NTB: Expose 32-bit BAR limits to consumers
  
  32-bit BARs can only address memory mapped in the low 32 bits of
  physical RAM.  Expose this as a 'plimit' out parameter from
  ntb_mw_get_range().
  
  Fix if_ntb to allocate memory within this limit.
  
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sys/dev/ntb/if_ntb/if_ntb.c
  head/sys/dev/ntb/ntb_hw/ntb_hw.c
  head/sys/dev/ntb/ntb_hw/ntb_hw.h

Modified: head/sys/dev/ntb/if_ntb/if_ntb.c
==============================================================================
--- head/sys/dev/ntb/if_ntb/if_ntb.c    Wed Nov 18 22:20:31 2015        
(r291032)
+++ head/sys/dev/ntb/if_ntb/if_ntb.c    Wed Nov 18 22:20:40 2015        
(r291033)
@@ -207,6 +207,7 @@ struct ntb_transport_mw {
        size_t          phys_size;
        size_t          xlat_align;
        size_t          xlat_align_size;
+       bus_addr_t      addr_limit;
        /* Tx buff is off vbase / phys_addr */
        caddr_t         vbase;
        size_t          xlat_size;
@@ -576,7 +577,8 @@ ntb_transport_probe(struct ntb_softc *nt
                mw = &nt->mw_vec[i];
 
                rc = ntb_mw_get_range(ntb, i, &mw->phys_addr, &mw->vbase,
-                   &mw->phys_size, &mw->xlat_align, &mw->xlat_align_size);
+                   &mw->phys_size, &mw->xlat_align, &mw->xlat_align_size,
+                   &mw->addr_limit);
                if (rc != 0)
                        goto err;
 
@@ -1306,7 +1308,7 @@ ntb_set_mw(struct ntb_transport_ctx *nt,
        mw->buff_size = buff_size;
 
        mw->virt_addr = contigmalloc(mw->buff_size, M_NTB_IF, M_ZERO, 0,
-           BUS_SPACE_MAXADDR, mw->xlat_align, 0);
+           mw->addr_limit, mw->xlat_align, 0);
        if (mw->virt_addr == NULL) {
                mw->xlat_size = 0;
                mw->buff_size = 0;

Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.c
==============================================================================
--- head/sys/dev/ntb/ntb_hw/ntb_hw.c    Wed Nov 18 22:20:31 2015        
(r291032)
+++ head/sys/dev/ntb/ntb_hw/ntb_hw.c    Wed Nov 18 22:20:40 2015        
(r291033)
@@ -2485,15 +2485,19 @@ ntb_peer_spad_read(struct ntb_softc *ntb
  */
 int
 ntb_mw_get_range(struct ntb_softc *ntb, unsigned mw_idx, vm_paddr_t *base,
-    caddr_t *vbase, size_t *size, size_t *align, size_t *align_size)
+    caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
+    bus_addr_t *plimit)
 {
        struct ntb_pci_bar_info *bar;
+       bus_addr_t limit;
        size_t bar_b2b_off;
+       enum ntb_bar bar_num;
 
        if (mw_idx >= ntb_mw_count(ntb))
                return (EINVAL);
 
-       bar = &ntb->bar_info[ntb_mw_to_bar(ntb, mw_idx)];
+       bar_num = ntb_mw_to_bar(ntb, mw_idx);
+       bar = &ntb->bar_info[bar_num];
        bar_b2b_off = 0;
        if (mw_idx == ntb->b2b_mw_idx) {
                KASSERT(ntb->b2b_off != 0,
@@ -2501,6 +2505,11 @@ ntb_mw_get_range(struct ntb_softc *ntb, 
                bar_b2b_off = ntb->b2b_off;
        }
 
+       if (bar_is_64bit(ntb, bar_num))
+               limit = BUS_SPACE_MAXADDR;
+       else
+               limit = BUS_SPACE_MAXADDR_32BIT;
+
        if (base != NULL)
                *base = bar->pbase + bar_b2b_off;
        if (vbase != NULL)
@@ -2511,6 +2520,8 @@ ntb_mw_get_range(struct ntb_softc *ntb, 
                *align = bar->size;
        if (align_size != NULL)
                *align_size = 1;
+       if (plimit != NULL)
+               *plimit = limit;
        return (0);
 }
 
@@ -2524,7 +2535,9 @@ ntb_mw_get_range(struct ntb_softc *ntb, 
  * Set the translation of a memory window.  The peer may access local memory
  * through the window starting at the address, up to the size.  The address
  * must be aligned to the alignment specified by ntb_mw_get_range().  The size
- * must be aligned to the size alignment specified by ntb_mw_get_range().
+ * must be aligned to the size alignment specified by ntb_mw_get_range().  The
+ * address must be below the plimit specified by ntb_mw_get_range() (i.e. for
+ * 32-bit BARs).
  *
  * Return: Zero on success, otherwise an error number.
  */
@@ -2586,9 +2599,9 @@ ntb_mw_set_trans(struct ntb_softc *ntb, 
                /* Configure 32-bit (split) BAR MW */
 
                if ((addr & UINT32_MAX) != addr)
-                       return (EINVAL);
+                       return (ERANGE);
                if (((addr + size) & UINT32_MAX) != (addr + size))
-                       return (EINVAL);
+                       return (ERANGE);
 
                base = ntb_reg_read(4, base_reg) & BAR_HIGH_MASK;
 

Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.h
==============================================================================
--- head/sys/dev/ntb/ntb_hw/ntb_hw.h    Wed Nov 18 22:20:31 2015        
(r291032)
+++ head/sys/dev/ntb/ntb_hw/ntb_hw.h    Wed Nov 18 22:20:40 2015        
(r291033)
@@ -77,7 +77,8 @@ void ntb_clear_ctx(struct ntb_softc *);
 
 uint8_t ntb_mw_count(struct ntb_softc *);
 int ntb_mw_get_range(struct ntb_softc *, unsigned mw_idx, vm_paddr_t *base,
-    caddr_t *vbase, size_t *size, size_t *align, size_t *align_size);
+    caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
+    bus_addr_t *plimit);
 int ntb_mw_set_trans(struct ntb_softc *, unsigned mw_idx, bus_addr_t, size_t);
 int ntb_mw_clear_trans(struct ntb_softc *, unsigned mw_idx);
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to