openbsd_network & drivers: Implement the real bus_dmamem functions.
This required the addition of some slight modifications to the main (FreeBSD compat) bus_dma implementation. Allows some #ifdefs from iaxwifi/idualwifi to be dropped, and will ease the porting of some future drivers. Tested with idualwifi7260, seems to work as before.
This commit is contained in:
parent
88864ff1f9
commit
231f740ccc
@ -1819,17 +1819,6 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma,
|
|||||||
dma->tag = tag;
|
dma->tag = tag;
|
||||||
dma->size = size;
|
dma->size = size;
|
||||||
|
|
||||||
#ifdef __FreeBSD_version
|
|
||||||
err = bus_dmamap_create_obsd(tag, size, 1, size, 0, alignment, BUS_DMA_NOWAIT,
|
|
||||||
&dma->map, 1);
|
|
||||||
if (err)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
err = bus_dmamem_alloc(dma->map->_dmat, (void **)&dma->vaddr,
|
|
||||||
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map->_dmamp);
|
|
||||||
if (err)
|
|
||||||
goto fail;
|
|
||||||
#else
|
|
||||||
err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
|
err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
|
||||||
&dma->map);
|
&dma->map);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1839,9 +1828,7 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma,
|
|||||||
BUS_DMA_NOWAIT | BUS_DMA_ZERO);
|
BUS_DMA_NOWAIT | BUS_DMA_ZERO);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __FreeBSD_version
|
|
||||||
if (nsegs > 1) {
|
if (nsegs > 1) {
|
||||||
err = ENOMEM;
|
err = ENOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1852,20 +1839,12 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma,
|
|||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
dma->vaddr = va;
|
dma->vaddr = va;
|
||||||
#endif
|
|
||||||
|
|
||||||
err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
|
err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
|
||||||
BUS_DMA_NOWAIT);
|
BUS_DMA_NOWAIT);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
#ifdef __FreeBSD_version
|
|
||||||
if (dma->map->dm_nsegs > 1) {
|
|
||||||
err = ENOMEM;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
|
bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
|
||||||
dma->paddr = dma->map->dm_segs[0].ds_addr;
|
dma->paddr = dma->map->dm_segs[0].ds_addr;
|
||||||
|
|
||||||
@ -1883,13 +1862,8 @@ iwx_dma_contig_free(struct iwx_dma_info *dma)
|
|||||||
bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
|
bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
|
||||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||||
bus_dmamap_unload(dma->tag, dma->map);
|
bus_dmamap_unload(dma->tag, dma->map);
|
||||||
#ifdef __FreeBSD_version
|
|
||||||
bus_dmamem_free(dma->tag, dma->vaddr, dma->map->_dmamp);
|
|
||||||
dma->map->_dmamp = NULL;
|
|
||||||
#else
|
|
||||||
bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
|
bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
|
||||||
bus_dmamem_free(dma->tag, &dma->seg, 1);
|
bus_dmamem_free(dma->tag, &dma->seg, 1);
|
||||||
#endif
|
|
||||||
dma->vaddr = NULL;
|
dma->vaddr = NULL;
|
||||||
}
|
}
|
||||||
bus_dmamap_destroy(dma->tag, dma->map);
|
bus_dmamap_destroy(dma->tag, dma->map);
|
||||||
|
@ -1235,17 +1235,6 @@ iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
|
|||||||
dma->tag = tag;
|
dma->tag = tag;
|
||||||
dma->size = size;
|
dma->size = size;
|
||||||
|
|
||||||
#ifdef __FreeBSD_version
|
|
||||||
err = bus_dmamap_create_obsd(tag, size, 1, size, 0, alignment, BUS_DMA_NOWAIT,
|
|
||||||
&dma->map, 1);
|
|
||||||
if (err)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
err = bus_dmamem_alloc(dma->map->_dmat, (void **)&dma->vaddr,
|
|
||||||
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map->_dmamp);
|
|
||||||
if (err)
|
|
||||||
goto fail;
|
|
||||||
#else
|
|
||||||
err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
|
err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
|
||||||
&dma->map);
|
&dma->map);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1261,7 +1250,6 @@ iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
|
|||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
dma->vaddr = va;
|
dma->vaddr = va;
|
||||||
#endif
|
|
||||||
|
|
||||||
err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
|
err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
|
||||||
BUS_DMA_NOWAIT);
|
BUS_DMA_NOWAIT);
|
||||||
@ -1286,13 +1274,8 @@ iwm_dma_contig_free(struct iwm_dma_info *dma)
|
|||||||
bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
|
bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
|
||||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||||
bus_dmamap_unload(dma->tag, dma->map);
|
bus_dmamap_unload(dma->tag, dma->map);
|
||||||
#ifdef __FreeBSD_version
|
|
||||||
bus_dmamem_free(dma->tag, dma->vaddr, dma->map->_dmamp);
|
|
||||||
dma->map->_dmamp = NULL;
|
|
||||||
#else
|
|
||||||
bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
|
bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
|
||||||
bus_dmamem_free(dma->tag, &dma->seg, 1);
|
bus_dmamem_free(dma->tag, &dma->seg, 1);
|
||||||
#endif
|
|
||||||
dma->vaddr = NULL;
|
dma->vaddr = NULL;
|
||||||
}
|
}
|
||||||
bus_dmamap_destroy(dma->tag, dma->map);
|
bus_dmamap_destroy(dma->tag, dma->map);
|
||||||
|
@ -253,10 +253,13 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
|
|||||||
if (flags & BUS_DMA_ZERO)
|
if (flags & BUS_DMA_ZERO)
|
||||||
mflags |= M_ZERO;
|
mflags |= M_ZERO;
|
||||||
|
|
||||||
bus_dmamap_create(dmat, flags, mapp);
|
// FreeBSD does not permit the "mapp" argument to be NULL, but we do.
|
||||||
|
if (mapp != NULL) {
|
||||||
|
bus_dmamap_create(dmat, flags, mapp);
|
||||||
|
|
||||||
// Drivers assume dmamem will never be bounced, so ensure that.
|
// Drivers assume dmamem will never be bounced, so ensure that.
|
||||||
(*mapp)->buffer_type = bus_dmamap::BUFFER_PROHIBITED;
|
(*mapp)->buffer_type = bus_dmamap::BUFFER_PROHIBITED;
|
||||||
|
}
|
||||||
|
|
||||||
// FreeBSD uses standard malloc() for the case where maxsize <= PAGE_SIZE,
|
// FreeBSD uses standard malloc() for the case where maxsize <= PAGE_SIZE,
|
||||||
// but we want to keep DMA'd memory a bit more separate, so we always use
|
// but we want to keep DMA'd memory a bit more separate, so we always use
|
||||||
@ -289,17 +292,24 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
|
|||||||
} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
|
} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
|
||||||
dprintf("bus_dmamem_alloc: failed to align memory: wanted %#x, got %#x\n",
|
dprintf("bus_dmamem_alloc: failed to align memory: wanted %#x, got %#x\n",
|
||||||
dmat->alignment, vtophys(vaddr));
|
dmat->alignment, vtophys(vaddr));
|
||||||
bus_dmamem_free(dmat, *vaddr, *mapp);
|
bus_dmamem_free(dmat, *vaddr, (mapp != NULL) ? *mapp : NULL);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
bus_dmamem_free_tagless(void* vaddr, size_t size)
|
||||||
|
{
|
||||||
|
kernel_contigfree(vaddr, size, M_DEVBUF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
bus_dmamem_free(bus_dma_tag_t dmat, void* vaddr, bus_dmamap_t map)
|
bus_dmamem_free(bus_dma_tag_t dmat, void* vaddr, bus_dmamap_t map)
|
||||||
{
|
{
|
||||||
kernel_contigfree(vaddr, dmat->maxsize, M_DEVBUF);
|
bus_dmamem_free_tagless(vaddr, dmat->maxsize);
|
||||||
bus_dmamap_destroy(dmat, map);
|
bus_dmamap_destroy(dmat, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,9 @@ int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
|
|||||||
*/
|
*/
|
||||||
void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
|
void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
|
||||||
|
|
||||||
|
/* Haiku extension, OpenBSD compatibility */
|
||||||
|
void bus_dmamem_free_tagless(void *vaddr, size_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map the buffer buf into bus space using the dmamap map.
|
* Map the buffer buf into bus space using the dmamap map.
|
||||||
*/
|
*/
|
||||||
@ -245,8 +248,10 @@ int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
|
|||||||
* is NULL we have a fully IO-coherent system.
|
* is NULL we have a fully IO-coherent system.
|
||||||
*/
|
*/
|
||||||
void bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t dmamap, bus_dmasync_op_t op);
|
void bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t dmamap, bus_dmasync_op_t op);
|
||||||
|
|
||||||
|
/* Haiku extension, OpenBSD compatibility */
|
||||||
void bus_dmamap_sync_etc(bus_dma_tag_t dmat, bus_dmamap_t dmamap,
|
void bus_dmamap_sync_etc(bus_dma_tag_t dmat, bus_dmamap_t dmamap,
|
||||||
bus_addr_t offset, bus_size_t length, bus_dmasync_op_t op); /* Haiku extension */
|
bus_addr_t offset, bus_size_t length, bus_dmasync_op_t op);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release the mapping held by map.
|
* Release the mapping held by map.
|
||||||
|
@ -28,26 +28,24 @@ typedef struct bus_dmamap_obsd* bus_dmamap_obsd_t;
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
bus_dmamap_create_obsd(bus_dma_tag_t tag, bus_size_t maxsize,
|
bus_dmamap_create_obsd(bus_dma_tag_t tag, bus_size_t maxsize,
|
||||||
int nsegments, bus_size_t maxsegsz, bus_size_t boundary, bus_size_t alignment,
|
int nsegments, bus_size_t maxsegsz, bus_size_t boundary,
|
||||||
int flags, bus_dmamap_t* dmamp, int no_alloc_map)
|
int flags, bus_dmamap_t* dmamp)
|
||||||
{
|
{
|
||||||
*dmamp = calloc(sizeof(struct bus_dmamap_obsd) + (sizeof(bus_dma_segment_t) * nsegments), 1);
|
*dmamp = calloc(sizeof(struct bus_dmamap_obsd) + (sizeof(bus_dma_segment_t) * nsegments), 1);
|
||||||
if ((*dmamp) == NULL)
|
if ((*dmamp) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
int error = bus_dma_tag_create(tag, alignment, boundary,
|
int error = bus_dma_tag_create(tag, 1, boundary,
|
||||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
|
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
|
||||||
maxsize, nsegments, maxsegsz, flags, NULL, NULL,
|
maxsize, nsegments, maxsegsz, flags, NULL, NULL,
|
||||||
&(*dmamp)->_dmat);
|
&(*dmamp)->_dmat);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (!no_alloc_map)
|
error = bus_dmamap_create((*dmamp)->_dmat, flags, &(*dmamp)->_dmamp);
|
||||||
error = bus_dmamap_create((*dmamp)->_dmat, flags, &(*dmamp)->_dmamp);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
#define bus_dmamap_create(tag, maxsize, nsegments, maxsegsz, boundary, flags, dmamp) \
|
#define bus_dmamap_create bus_dmamap_create_obsd
|
||||||
bus_dmamap_create_obsd(tag, maxsize, nsegments, maxsegsz, boundary, 1, flags, dmamp, 0)
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -111,4 +109,65 @@ bus_dmamap_sync_obsd(bus_dma_tag_t tag, bus_dmamap_t dmam,
|
|||||||
#define bus_dmamap_sync bus_dmamap_sync_obsd
|
#define bus_dmamap_sync bus_dmamap_sync_obsd
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
bus_dmamem_alloc_obsd(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)
|
||||||
|
{
|
||||||
|
// OpenBSD distinguishes between three different types of addresses:
|
||||||
|
// 1. virtual addresses (caddr_t)
|
||||||
|
// 2. opaque "bus" addresses
|
||||||
|
// 3. physical addresses
|
||||||
|
// This function returns the second type. We simply return the virtual address for it.
|
||||||
|
|
||||||
|
bus_dma_tag_t local;
|
||||||
|
int error = bus_dma_tag_create(tag, alignment, boundary,
|
||||||
|
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
|
||||||
|
size, nsegs, size, flags, NULL, NULL, &local);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
error = bus_dmamem_alloc(local, (void**)&segs[0].ds_addr, flags, NULL);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
segs[0].ds_len = size;
|
||||||
|
|
||||||
|
error = bus_dma_tag_destroy(local);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
*rsegs = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define bus_dmamem_alloc bus_dmamem_alloc_obsd
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
bus_dmamem_free_obsd(bus_dma_tag_t tag, bus_dma_segment_t* segs, int nsegs)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nsegs; i++)
|
||||||
|
bus_dmamem_free_tagless(segs[i].ds_addr, segs[i].ds_len);
|
||||||
|
}
|
||||||
|
#define bus_dmamem_free bus_dmamem_free_obsd
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
bus_dmamem_map_obsd(bus_dma_tag_t tag, bus_dma_segment_t* segs, int nsegs, size_t size, caddr_t* kvap, int flags)
|
||||||
|
{
|
||||||
|
if (nsegs != 1)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*kvap = (caddr_t)segs[0].ds_addr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define bus_dmamem_map bus_dmamem_map_obsd
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
bus_dmamem_unmap_obsd(bus_dma_tag_t tag, caddr_t kva, size_t size)
|
||||||
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
#define bus_dmamem_unmap bus_dmamem_unmap_obsd
|
||||||
|
|
||||||
|
|
||||||
#endif /* _OBSD_COMPAT_MACHINE_BUS_H_ */
|
#endif /* _OBSD_COMPAT_MACHINE_BUS_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user