> Date: Thu, 22 Jan 2015 19:38:42 +0100 (CET)
> From: Mark Kettenis <[email protected]>
>
> > Date: Thu, 22 Jan 2015 18:04:44 +0100
> > From: Stefan Sperling <[email protected]>
> >
> > On Thu, Jan 22, 2015 at 11:34:47AM -0500, John Merriam wrote:
> > > So, what could be the problem then? Theoretically it did work as of the
> > > 1.35 if_bce.c revision which seems to have shipped in OpenBSD 5.0. This
> > > message:
> > >
> > > http://marc.info/?l=openbsd-tech&m=130217668909255
> > >
> > > seems to verify that it did actually work at one point.
> >
> > It looks as if some ring descriptor data is still being allocated with
> > bus_dmamem_alloc(). That function probably doesn't respect the mapping
> > constraints bce(4) hardware requires.
> >
> > This diff makes bce use the same memory allocation APIs as bwi(4) is
> > using. Some bwi devices have the same 1GB problem and I know the bwi
> > code works fine with such devices. So perhaps applying the same approach
> > to bce will fix your issue.
>
> I'd really prefer it if we'd solve this issue by promoting
> _bus_dmamem_alloc_range() to a first class citizen. I'll try to
> recover an old diff that did this tonight.
>
> No harm in testing this diff though to verify that it indeed solves
> the issue.
So here is the alternative diff. Only amd64/i386 are actually
implemented, but those are the only platforms we support bce(4) on.
Index: dev/pci/if_bce.c
===================================================================
RCS file: /home/cvs/src/sys/dev/pci/if_bce.c,v
retrieving revision 1.40
diff -u -p -r1.40 if_bce.c
--- dev/pci/if_bce.c 22 Dec 2014 02:28:51 -0000 1.40
+++ dev/pci/if_bce.c 22 Jan 2015 20:38:05 -0000
@@ -315,8 +315,9 @@ bce_attach(struct device *parent, struct
* XXX PAGE_SIZE is wasteful; we only need 1KB + 1KB, but
* due to the limition above. ??
*/
- if ((error = bus_dmamem_alloc(sc->bce_dmatag, 2 * PAGE_SIZE,
- PAGE_SIZE, 2 * PAGE_SIZE, &seg, 1, &rseg, BUS_DMA_NOWAIT))) {
+ if ((error = bus_dmamem_alloc_range(sc->bce_dmatag, 2 * PAGE_SIZE,
+ PAGE_SIZE, 2 * PAGE_SIZE, &seg, 1, &rseg, BUS_DMA_NOWAIT,
+ (bus_addr_t)0, (bus_addr_t)0x3fffffff))) {
printf(": unable to alloc space for ring descriptors, "
"error = %d\n", error);
uvm_km_free(kernel_map, (vaddr_t)sc->bce_data,
Index: arch/amd64/amd64/bus_dma.c
===================================================================
RCS file: /home/cvs/src/sys/arch/amd64/amd64/bus_dma.c,v
retrieving revision 1.46
diff -u -p -r1.46 bus_dma.c
--- arch/amd64/amd64/bus_dma.c 16 Nov 2014 12:30:56 -0000 1.46
+++ arch/amd64/amd64/bus_dma.c 22 Jan 2015 20:38:05 -0000
@@ -424,7 +424,7 @@ _bus_dmamem_alloc(bus_dma_tag_t t, bus_s
* memory under the 4gig boundary.
*/
return (_bus_dmamem_alloc_range(t, size, alignment, boundary,
- segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)0xffffffff));
+ segs, nsegs, rsegs, flags, (bus_addr_t)0, (bus_addr_t)0xffffffff));
}
/*
@@ -662,7 +662,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t,
int
_bus_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
- int flags, paddr_t low, paddr_t high)
+ int flags, bus_addr_t low, bus_addr_t high)
{
paddr_t curaddr, lastaddr;
struct vm_page *m;
Index: arch/amd64/include/bus.h
===================================================================
RCS file: /home/cvs/src/sys/arch/amd64/include/bus.h,v
retrieving revision 1.31
diff -u -p -r1.31 bus.h
--- arch/amd64/include/bus.h 29 Mar 2014 18:09:28 -0000 1.31
+++ arch/amd64/include/bus.h 22 Jan 2015 20:38:05 -0000
@@ -594,6 +594,9 @@ struct bus_dma_tag {
*/
int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
bus_size_t, bus_dma_segment_t *, int, int *, int);
+ int (*_dmamem_alloc_range)(bus_dma_tag_t, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t *, int, int *, int,
+ bus_addr_t, bus_addr_t);
void (*_dmamem_free)(bus_dma_tag_t,
bus_dma_segment_t *, int);
int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
@@ -622,6 +625,9 @@ struct bus_dma_tag {
#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
+#define bus_dmamem_alloc_range(t, s, a, b, sg, n, r, f, l, h) \
+ (*(t)->_dmamem_alloc_range)((t), (s), (a), (b), (sg), \
+ (n), (r), (f), (l), (h))
#define bus_dmamem_free(t, sg, n) \
(*(t)->_dmamem_free)((t), (sg), (n))
#define bus_dmamem_map(t, sg, n, s, k, f) \
@@ -686,6 +692,6 @@ paddr_t _bus_dmamem_mmap(bus_dma_tag_t t
int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
bus_size_t alignment, bus_size_t boundary,
bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
- paddr_t low, paddr_t high);
+ bus_addr_t low, bus_addr_t high);
#endif /* _MACHINE_BUS_H_ */
Index: arch/amd64/isa/isa_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/arch/amd64/isa/isa_machdep.c,v
retrieving revision 1.25
diff -u -p -r1.25 isa_machdep.c
--- arch/amd64/isa/isa_machdep.c 22 Dec 2014 03:13:45 -0000 1.25
+++ arch/amd64/isa/isa_machdep.c 22 Jan 2015 20:38:05 -0000
@@ -151,6 +151,7 @@ struct bus_dma_tag isa_bus_dma_tag = {
_isa_bus_dmamap_unload,
_isa_bus_dmamap_sync,
_isa_bus_dmamem_alloc,
+ _bus_dmamem_alloc_range,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
@@ -666,7 +667,7 @@ _isa_bus_dmamem_alloc(bus_dma_tag_t t, b
/* Otherwise try anywhere (we'll bounce later) */
error = _bus_dmamem_alloc_range(t, size, alignment, boundary,
- segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)-1);
+ segs, nsegs, rsegs, flags, (bus_addr_t)0, (bus_addr_t)-1);
return (error);
}
Index: arch/amd64/pci/pci_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.60
diff -u -p -r1.60 pci_machdep.c
--- arch/amd64/pci/pci_machdep.c 16 Dec 2014 23:13:20 -0000 1.60
+++ arch/amd64/pci/pci_machdep.c 22 Jan 2015 20:38:05 -0000
@@ -141,6 +141,7 @@ struct bus_dma_tag pci_bus_dma_tag = {
_bus_dmamap_unload,
_bus_dmamap_sync,
_bus_dmamem_alloc,
+ _bus_dmamem_alloc_range,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
Index: arch/i386/eisa/eisa_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/arch/i386/eisa/eisa_machdep.c,v
retrieving revision 1.14
diff -u -p -r1.14 eisa_machdep.c
--- arch/i386/eisa/eisa_machdep.c 6 Sep 2010 19:05:48 -0000 1.14
+++ arch/i386/eisa/eisa_machdep.c 22 Jan 2015 20:38:05 -0000
@@ -93,6 +93,7 @@ struct bus_dma_tag eisa_bus_dma_tag = {
_bus_dmamap_unload,
_bus_dmamap_sync,
_bus_dmamem_alloc,
+ _bus_dmamem_alloc_range,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
Index: arch/i386/i386/bus_dma.c
===================================================================
RCS file: /home/cvs/src/sys/arch/i386/i386/bus_dma.c,v
retrieving revision 1.33
diff -u -p -r1.33 bus_dma.c
--- arch/i386/i386/bus_dma.c 16 Nov 2014 12:30:57 -0000 1.33
+++ arch/i386/i386/bus_dma.c 22 Jan 2015 20:38:05 -0000
@@ -387,7 +387,7 @@ _bus_dmamem_alloc(bus_dma_tag_t t, bus_s
{
return (_bus_dmamem_alloc_range(t, size, alignment, boundary,
- segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)-1));
+ segs, nsegs, rsegs, flags, (bus_addr_t)0, (bus_addr_t)-1));
}
/*
@@ -619,7 +619,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t,
int
_bus_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
- int flags, paddr_t low, paddr_t high)
+ int flags, bus_addr_t low, bus_addr_t high)
{
paddr_t curaddr, lastaddr;
struct vm_page *m;
Index: arch/i386/include/bus.h
===================================================================
RCS file: /home/cvs/src/sys/arch/i386/include/bus.h,v
retrieving revision 1.64
diff -u -p -r1.64 bus.h
--- arch/i386/include/bus.h 17 Oct 2014 20:37:57 -0000 1.64
+++ arch/i386/include/bus.h 22 Jan 2015 20:38:05 -0000
@@ -596,6 +596,9 @@ struct bus_dma_tag {
*/
int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
bus_size_t, bus_dma_segment_t *, int, int *, int);
+ int (*_dmamem_alloc_range)(bus_dma_tag_t, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t *, int, int *, int,
+ bus_addr_t, bus_addr_t);
void (*_dmamem_free)(bus_dma_tag_t,
bus_dma_segment_t *, int);
int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
@@ -624,6 +627,9 @@ struct bus_dma_tag {
#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
+#define bus_dmamem_alloc_range(t, s, a, b, sg, n, r, f, l, h) \
+ (*(t)->_dmamem_alloc_range)((t), (s), (a), (b), (sg), \
+ (n), (r), (f), (l), (h))
#define bus_dmamem_free(t, sg, n) \
(*(t)->_dmamem_free)((t), (sg), (n))
#define bus_dmamem_map(t, sg, n, s, k, f) \
Index: arch/i386/isa/isa_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/arch/i386/isa/isa_machdep.c,v
retrieving revision 1.78
diff -u -p -r1.78 isa_machdep.c
--- arch/i386/isa/isa_machdep.c 22 Dec 2014 03:14:59 -0000 1.78
+++ arch/i386/isa/isa_machdep.c 22 Jan 2015 20:38:05 -0000
@@ -148,6 +148,7 @@ struct bus_dma_tag isa_bus_dma_tag = {
_isa_bus_dmamap_unload,
_isa_bus_dmamap_sync,
_isa_bus_dmamem_alloc,
+ _bus_dmamem_alloc_range,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
@@ -939,7 +940,7 @@ _isa_bus_dmamem_alloc(bus_dma_tag_t t, b
/* Otherwise try anywhere (we'll bounce later) */
error = _bus_dmamem_alloc_range(t, size, alignment, boundary,
- segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)-1);
+ segs, nsegs, rsegs, flags, (bus_addr_t)0, (bus_addr_t)-1);
return (error);
}
Index: arch/i386/pci/pci_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/arch/i386/pci/pci_machdep.c,v
retrieving revision 1.79
diff -u -p -r1.79 pci_machdep.c
--- arch/i386/pci/pci_machdep.c 12 Jul 2014 18:44:42 -0000 1.79
+++ arch/i386/pci/pci_machdep.c 22 Jan 2015 20:38:05 -0000
@@ -185,6 +185,7 @@ struct bus_dma_tag pci_bus_dma_tag = {
_bus_dmamap_unload,
_bus_dmamap_sync,
_bus_dmamem_alloc,
+ _bus_dmamem_alloc_range,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,