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->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,
|
||||
&dma->map);
|
||||
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);
|
||||
if (err)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD_version
|
||||
if (nsegs > 1) {
|
||||
err = ENOMEM;
|
||||
goto fail;
|
||||
@ -1852,20 +1839,12 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma,
|
||||
if (err)
|
||||
goto fail;
|
||||
dma->vaddr = va;
|
||||
#endif
|
||||
|
||||
err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (err)
|
||||
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);
|
||||
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_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
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_free(dma->tag, &dma->seg, 1);
|
||||
#endif
|
||||
dma->vaddr = NULL;
|
||||
}
|
||||
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->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,
|
||||
&dma->map);
|
||||
if (err)
|
||||
@ -1261,7 +1250,6 @@ iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
|
||||
if (err)
|
||||
goto fail;
|
||||
dma->vaddr = va;
|
||||
#endif
|
||||
|
||||
err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
|
||||
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_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
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_free(dma->tag, &dma->seg, 1);
|
||||
#endif
|
||||
dma->vaddr = NULL;
|
||||
}
|
||||
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)
|
||||
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.
|
||||
(*mapp)->buffer_type = bus_dmamap::BUFFER_PROHIBITED;
|
||||
// Drivers assume dmamem will never be bounced, so ensure that.
|
||||
(*mapp)->buffer_type = bus_dmamap::BUFFER_PROHIBITED;
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -289,17 +292,24 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
|
||||
} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
|
||||
dprintf("bus_dmamem_alloc: failed to align memory: wanted %#x, got %#x\n",
|
||||
dmat->alignment, vtophys(vaddr));
|
||||
bus_dmamem_free(dmat, *vaddr, *mapp);
|
||||
bus_dmamem_free(dmat, *vaddr, (mapp != NULL) ? *mapp : NULL);
|
||||
return ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
bus_dmamem_free_tagless(void* vaddr, size_t size)
|
||||
{
|
||||
kernel_contigfree(vaddr, size, M_DEVBUF);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
@ -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.
|
||||
*/
|
||||
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,
|
||||
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.
|
||||
|
@ -28,26 +28,24 @@ typedef struct bus_dmamap_obsd* bus_dmamap_obsd_t;
|
||||
|
||||
static int
|
||||
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 flags, bus_dmamap_t* dmamp, int no_alloc_map)
|
||||
int nsegments, bus_size_t maxsegsz, bus_size_t boundary,
|
||||
int flags, bus_dmamap_t* dmamp)
|
||||
{
|
||||
*dmamp = calloc(sizeof(struct bus_dmamap_obsd) + (sizeof(bus_dma_segment_t) * nsegments), 1);
|
||||
if ((*dmamp) == NULL)
|
||||
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,
|
||||
maxsize, nsegments, maxsegsz, flags, NULL, NULL,
|
||||
&(*dmamp)->_dmat);
|
||||
if (error != 0)
|
||||
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;
|
||||
}
|
||||
#define bus_dmamap_create(tag, maxsize, nsegments, maxsegsz, boundary, flags, dmamp) \
|
||||
bus_dmamap_create_obsd(tag, maxsize, nsegments, maxsegsz, boundary, 1, flags, dmamp, 0)
|
||||
#define bus_dmamap_create bus_dmamap_create_obsd
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user