Unifdef __NetBSD__ here, the usb stack as a whole doesnt support NetBSD and it
obsfucates the code.
This commit is contained in:
parent
cfe04e82b1
commit
3e8739762f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=192857
@ -44,9 +44,6 @@
|
||||
#if USB_HAVE_BUSDMA
|
||||
static void usb2_dma_tag_create(struct usb2_dma_tag *, usb2_size_t, usb2_size_t);
|
||||
static void usb2_dma_tag_destroy(struct usb2_dma_tag *);
|
||||
#endif
|
||||
|
||||
#if USB_HAVE_BUSDMA && defined(__FreeBSD__)
|
||||
static void usb2_dma_lock_cb(void *, bus_dma_lock_op_t);
|
||||
static void usb2_pc_alloc_mem_cb(void *, bus_dma_segment_t *, int, int);
|
||||
static void usb2_pc_load_mem_cb(void *, bus_dma_segment_t *, int, int);
|
||||
@ -54,11 +51,6 @@ static void usb2_pc_common_mem_cb(void *, bus_dma_segment_t *, int, int,
|
||||
uint8_t);
|
||||
#endif
|
||||
|
||||
#if USB_HAVE_BUSDMA && defined(__NetBSD__)
|
||||
static void usb2_pc_common_mem_cb(struct usb2_page_cache *,
|
||||
bus_dma_segment_t *, int, int, uint8_t);
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_get_page - lookup DMA-able memory for the given offset
|
||||
*
|
||||
@ -186,11 +178,7 @@ struct usb2_m_copy_in_arg {
|
||||
};
|
||||
|
||||
static int
|
||||
#ifdef __FreeBSD__
|
||||
usb2_m_copy_in_cb(void *arg, void *src, uint32_t count)
|
||||
#else
|
||||
usb2_m_copy_in_cb(void *arg, caddr_t src, uint32_t count)
|
||||
#endif
|
||||
{
|
||||
register struct usb2_m_copy_in_arg *ua = arg;
|
||||
|
||||
@ -325,7 +313,7 @@ usb2_bzero(struct usb2_page_cache *cache, usb2_frlength_t offset,
|
||||
}
|
||||
}
|
||||
|
||||
#if USB_HAVE_BUSDMA && defined(__FreeBSD__)
|
||||
#if USB_HAVE_BUSDMA
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_dma_lock_cb - dummy callback
|
||||
@ -740,385 +728,6 @@ usb2_pc_dmamap_destroy(struct usb2_page_cache *pc)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USB_HAVE_BUSDMA && defined(__NetBSD__)
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_dma_tag_create - allocate a DMA tag
|
||||
*
|
||||
* NOTE: If the "align" parameter has a value of 1 the DMA-tag will
|
||||
* allow multi-segment mappings. Else all mappings are single-segment.
|
||||
*------------------------------------------------------------------------*/
|
||||
static void
|
||||
usb2_dma_tag_create(struct usb2_dma_tag *udt,
|
||||
usb2_size_t size, usb2_size_t align)
|
||||
{
|
||||
usb2_size_t nseg;
|
||||
|
||||
if (align == 1) {
|
||||
nseg = (2 + (size / USB_PAGE_SIZE));
|
||||
} else {
|
||||
nseg = 1;
|
||||
}
|
||||
|
||||
udt->p_seg = malloc(nseg * sizeof(*(udt->p_seg)),
|
||||
M_USB, M_WAITOK | M_ZERO);
|
||||
|
||||
if (udt->p_seg == NULL) {
|
||||
return;
|
||||
}
|
||||
udt->tag = udt->tag_parent->tag;
|
||||
udt->n_seg = nseg;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_dma_tag_free - free a DMA tag
|
||||
*------------------------------------------------------------------------*/
|
||||
static void
|
||||
usb2_dma_tag_destroy(struct usb2_dma_tag *udt)
|
||||
{
|
||||
free(udt->p_seg, M_USB);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_common_mem_cb - BUS-DMA callback function
|
||||
*------------------------------------------------------------------------*/
|
||||
static void
|
||||
usb2_pc_common_mem_cb(struct usb2_page_cache *pc, bus_dma_segment_t *segs,
|
||||
int nseg, int error, uint8_t isload, uint8_t dolock)
|
||||
{
|
||||
struct usb2_dma_parent_tag *uptag;
|
||||
struct usb2_page *pg;
|
||||
usb2_size_t rem;
|
||||
uint8_t ext_seg; /* extend last segment */
|
||||
|
||||
uptag = pc->tag_parent;
|
||||
|
||||
if (error) {
|
||||
goto done;
|
||||
}
|
||||
pg = pc->page_start;
|
||||
pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
|
||||
rem = segs->ds_addr & (USB_PAGE_SIZE - 1);
|
||||
pc->page_offset_buf = rem;
|
||||
pc->page_offset_end += rem;
|
||||
if (nseg < ((pc->page_offset_end +
|
||||
(USB_PAGE_SIZE - 1)) / USB_PAGE_SIZE)) {
|
||||
ext_seg = 1;
|
||||
} else {
|
||||
ext_seg = 0;
|
||||
}
|
||||
nseg--;
|
||||
#if (USB_DEBUG != 0)
|
||||
if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
|
||||
/*
|
||||
* This check verifies that the physical address is correct:
|
||||
*/
|
||||
DPRINTFN(0, "Page offset was not preserved!\n");
|
||||
error = 1;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
while (nseg > 0) {
|
||||
nseg--;
|
||||
segs++;
|
||||
pg++;
|
||||
pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX The segments we get from BUS-DMA are not aligned,
|
||||
* XXX so we need to extend the last segment if we are
|
||||
* XXX unaligned and cross the segment boundary!
|
||||
*/
|
||||
if (ext_seg && pc->ismultiseg) {
|
||||
(pg + 1)->physaddr = pg->physaddr + USB_PAGE_SIZE;
|
||||
}
|
||||
done:
|
||||
if (dolock)
|
||||
mtx_lock(uptag->mtx);
|
||||
|
||||
uptag->dma_error = (error ? 1 : 0);
|
||||
if (isload) {
|
||||
(uptag->func) (uptag);
|
||||
}
|
||||
if (dolock)
|
||||
mtx_unlock(uptag->mtx);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_alloc_mem - allocate DMA'able memory
|
||||
*
|
||||
* Returns:
|
||||
* 0: Success
|
||||
* Else: Failure
|
||||
*------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
usb2_pc_alloc_mem(struct usb2_page_cache *pc, struct usb2_page *pg,
|
||||
usb2_size_t size, usb2_size_t align)
|
||||
{
|
||||
struct usb2_dma_parent_tag *uptag;
|
||||
struct usb2_dma_tag *utag;
|
||||
caddr_t ptr = NULL;
|
||||
bus_dmamap_t map;
|
||||
int seg_count;
|
||||
|
||||
uptag = pc->tag_parent;
|
||||
|
||||
if (align != 1) {
|
||||
/*
|
||||
* The alignment must be greater or equal to the
|
||||
* "size" else the object can be split between two
|
||||
* memory pages and we get a problem!
|
||||
*/
|
||||
while (align < size) {
|
||||
align *= 2;
|
||||
if (align == 0) {
|
||||
goto done_5;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* get the correct DMA tag */
|
||||
utag = usb2_dma_tag_find(pc->tag_parent, size, align);
|
||||
if (utag == NULL) {
|
||||
goto done_5;
|
||||
}
|
||||
if (bus_dmamem_alloc(utag->tag, size, align, 0, utag->p_seg,
|
||||
utag->n_seg, &seg_count, BUS_DMA_WAITOK)) {
|
||||
goto done_4;
|
||||
}
|
||||
if (bus_dmamem_map(utag->tag, utag->p_seg, seg_count, size,
|
||||
&ptr, BUS_DMA_WAITOK | BUS_DMA_COHERENT)) {
|
||||
goto done_3;
|
||||
}
|
||||
if (bus_dmamap_create(utag->tag, size, utag->n_seg, (align == 1) ?
|
||||
USB_PAGE_SIZE : size, 0, BUS_DMA_WAITOK, &map)) {
|
||||
goto done_2;
|
||||
}
|
||||
if (bus_dmamap_load(utag->tag, map, ptr, size, NULL,
|
||||
BUS_DMA_WAITOK)) {
|
||||
goto done_1;
|
||||
}
|
||||
pc->p_seg = malloc(seg_count * sizeof(*(pc->p_seg)),
|
||||
M_USB, M_WAITOK | M_ZERO);
|
||||
if (pc->p_seg == NULL) {
|
||||
goto done_0;
|
||||
}
|
||||
/* store number if actual segments used */
|
||||
pc->n_seg = seg_count;
|
||||
|
||||
/* make a copy of the segments */
|
||||
bcopy(utag->p_seg, pc->p_seg,
|
||||
seg_count * sizeof(*(pc->p_seg)));
|
||||
|
||||
/* setup page cache */
|
||||
pc->buffer = ptr;
|
||||
pc->page_start = pg;
|
||||
pc->page_offset_buf = 0;
|
||||
pc->page_offset_end = size;
|
||||
pc->map = map;
|
||||
pc->tag = utag->tag;
|
||||
pc->ismultiseg = (align == 1);
|
||||
|
||||
usb2_pc_common_mem_cb(pc, utag->p_seg, seg_count, 0, 0, 1);
|
||||
|
||||
bzero(ptr, size);
|
||||
|
||||
usb2_pc_cpu_flush(pc);
|
||||
|
||||
return (0);
|
||||
|
||||
done_0:
|
||||
bus_dmamap_unload(utag->tag, map);
|
||||
done_1:
|
||||
bus_dmamap_destroy(utag->tag, map);
|
||||
done_2:
|
||||
bus_dmamem_unmap(utag->tag, ptr, size);
|
||||
done_3:
|
||||
bus_dmamem_free(utag->tag, utag->p_seg, seg_count);
|
||||
done_4:
|
||||
/* utag is destroyed later */
|
||||
done_5:
|
||||
/* reset most of the page cache */
|
||||
pc->buffer = NULL;
|
||||
pc->page_start = NULL;
|
||||
pc->page_offset_buf = 0;
|
||||
pc->page_offset_end = 0;
|
||||
pc->map = NULL;
|
||||
pc->tag = NULL;
|
||||
pc->n_seg = 0;
|
||||
pc->p_seg = NULL;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_free_mem - free DMA memory
|
||||
*
|
||||
* This function is NULL safe.
|
||||
*------------------------------------------------------------------------*/
|
||||
void
|
||||
usb2_pc_free_mem(struct usb2_page_cache *pc)
|
||||
{
|
||||
if (pc && pc->buffer) {
|
||||
bus_dmamap_unload(pc->tag, pc->map);
|
||||
bus_dmamap_destroy(pc->tag, pc->map);
|
||||
bus_dmamem_unmap(pc->tag, pc->buffer,
|
||||
pc->page_offset_end - pc->page_offset_buf);
|
||||
bus_dmamem_free(pc->tag, pc->p_seg, pc->n_seg);
|
||||
free(pc->p_seg, M_USB);
|
||||
pc->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_load_mem - load virtual memory into DMA
|
||||
*
|
||||
* Return values:
|
||||
* 0: Success
|
||||
* Else: Error
|
||||
*------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
usb2_pc_load_mem(struct usb2_page_cache *pc, usb2_size_t size, uint8_t sync)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* setup page cache */
|
||||
pc->page_offset_buf = 0;
|
||||
pc->page_offset_end = size;
|
||||
pc->ismultiseg = 1;
|
||||
|
||||
if (size > 0) {
|
||||
|
||||
/*
|
||||
* We have to unload the previous loaded DMA
|
||||
* pages before trying to load a new one!
|
||||
*/
|
||||
bus_dmamap_unload(pc->tag, pc->map);
|
||||
|
||||
/* try to load memory into DMA using using no wait option */
|
||||
if (bus_dmamap_load(pc->tag, pc->map, pc->buffer,
|
||||
size, NULL, BUS_DMA_NOWAIT)) {
|
||||
error = ENOMEM;
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
|
||||
usb2_pc_common_mem_cb(pc, pc->map->dm_segs,
|
||||
pc->map->dm_nsegs, error, !sync);
|
||||
|
||||
if (error) {
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
if (!sync) {
|
||||
/*
|
||||
* Call callback so that refcount is decremented
|
||||
* properly:
|
||||
*/
|
||||
pc->tag_parent->dma_error = 0;
|
||||
(pc->tag_parent->func) (pc->tag_parent);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_cpu_invalidate - invalidate CPU cache
|
||||
*------------------------------------------------------------------------*/
|
||||
void
|
||||
usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
|
||||
{
|
||||
usb2_size_t len;
|
||||
|
||||
len = pc->page_offset_end - pc->page_offset_buf;
|
||||
|
||||
if (len == 0) {
|
||||
/* nothing has been loaded into this page cache */
|
||||
return;
|
||||
}
|
||||
bus_dmamap_sync(pc->tag, pc->map, 0, len,
|
||||
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_cpu_flush - flush CPU cache
|
||||
*------------------------------------------------------------------------*/
|
||||
void
|
||||
usb2_pc_cpu_flush(struct usb2_page_cache *pc)
|
||||
{
|
||||
usb2_size_t len;
|
||||
|
||||
len = pc->page_offset_end - pc->page_offset_buf;
|
||||
|
||||
if (len == 0) {
|
||||
/* nothing has been loaded into this page cache */
|
||||
return;
|
||||
}
|
||||
bus_dmamap_sync(pc->tag, pc->map, 0, len,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_dmamap_create - create a DMA map
|
||||
*
|
||||
* Returns:
|
||||
* 0: Success
|
||||
* Else: Failure
|
||||
*------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
usb2_pc_dmamap_create(struct usb2_page_cache *pc, usb2_size_t size)
|
||||
{
|
||||
struct usb2_xfer_root *info;
|
||||
struct usb2_dma_tag *utag;
|
||||
|
||||
/* get info */
|
||||
info = USB_DMATAG_TO_XROOT(pc->tag_parent);
|
||||
|
||||
/* sanity check */
|
||||
if (info == NULL) {
|
||||
goto error;
|
||||
}
|
||||
utag = usb2_dma_tag_find(pc->tag_parent, size, 1);
|
||||
if (utag == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (bus_dmamap_create(utag->tag, size, utag->n_seg,
|
||||
USB_PAGE_SIZE, 0, BUS_DMA_WAITOK, &pc->map)) {
|
||||
goto error;
|
||||
}
|
||||
pc->tag = utag->tag;
|
||||
pc->p_seg = utag->p_seg;
|
||||
pc->n_seg = utag->n_seg;
|
||||
return 0; /* success */
|
||||
|
||||
error:
|
||||
pc->map = NULL;
|
||||
pc->tag = NULL;
|
||||
pc->p_seg = NULL;
|
||||
pc->n_seg = 0;
|
||||
return 1; /* failure */
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_pc_dmamap_destroy
|
||||
*
|
||||
* This function is NULL safe.
|
||||
*------------------------------------------------------------------------*/
|
||||
void
|
||||
usb2_pc_dmamap_destroy(struct usb2_page_cache *pc)
|
||||
{
|
||||
if (pc && pc->tag) {
|
||||
bus_dmamap_destroy(pc->tag, pc->map);
|
||||
pc->tag = NULL;
|
||||
pc->map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USB_HAVE_BUSDMA
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_dma_tag_find - factored out code
|
||||
*------------------------------------------------------------------------*/
|
||||
@ -1172,10 +781,8 @@ usb2_dma_tag_setup(struct usb2_dma_parent_tag *udpt,
|
||||
/* something is corrupt */
|
||||
return;
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
/* initialise condition variable */
|
||||
usb2_cv_init(udpt->cv, "USB DMA CV");
|
||||
#endif
|
||||
|
||||
/* store some information */
|
||||
udpt->mtx = mtx;
|
||||
@ -1215,10 +822,8 @@ usb2_dma_tag_unsetup(struct usb2_dma_parent_tag *udpt)
|
||||
}
|
||||
|
||||
if (udpt->utag_max) {
|
||||
#ifdef __FreeBSD__
|
||||
/* destroy the condition variable */
|
||||
usb2_cv_destroy(udpt->cv);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,13 +36,11 @@
|
||||
|
||||
#define USB_PAGE_SIZE PAGE_SIZE /* use system PAGE_SIZE */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#if (__FreeBSD_version >= 700020)
|
||||
#define USB_GET_DMA_TAG(dev) bus_get_dma_tag(dev)
|
||||
#else
|
||||
#define USB_GET_DMA_TAG(dev) NULL /* XXX */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* structure prototypes */
|
||||
|
||||
@ -86,23 +84,13 @@ struct usb2_page_search {
|
||||
*/
|
||||
struct usb2_page_cache {
|
||||
|
||||
#if USB_HAVE_BUSDMA && defined(__FreeBSD__)
|
||||
bus_dma_tag_t tag;
|
||||
bus_dmamap_t map;
|
||||
#endif
|
||||
#if USB_HAVE_BUSDMA && defined(__NetBSD__)
|
||||
bus_dma_tag_t tag;
|
||||
bus_dmamap_t map;
|
||||
bus_dma_segment_t *p_seg;
|
||||
#endif
|
||||
#if USB_HAVE_BUSDMA
|
||||
bus_dma_tag_t tag;
|
||||
bus_dmamap_t map;
|
||||
struct usb2_page *page_start;
|
||||
#endif
|
||||
struct usb2_dma_parent_tag *tag_parent; /* always set */
|
||||
void *buffer; /* virtual buffer pointer */
|
||||
#if USB_HAVE_BUSDMA && defined(_NetBSD__)
|
||||
int n_seg;
|
||||
#endif
|
||||
#if USB_HAVE_BUSDMA
|
||||
usb2_size_t page_offset_buf;
|
||||
usb2_size_t page_offset_end;
|
||||
@ -118,9 +106,7 @@ struct usb2_page_cache {
|
||||
*/
|
||||
#if USB_HAVE_BUSDMA
|
||||
struct usb2_dma_parent_tag {
|
||||
#if defined(__FreeBSD__)
|
||||
struct cv cv[1]; /* internal condition variable */
|
||||
#endif
|
||||
bus_dma_tag_t tag; /* always set */
|
||||
|
||||
struct mtx *mtx; /* private mutex, always set */
|
||||
@ -139,17 +125,10 @@ struct usb2_dma_parent_tag {}; /* empty struct */
|
||||
*/
|
||||
#if USB_HAVE_BUSDMA
|
||||
struct usb2_dma_tag {
|
||||
#if defined(__NetBSD__)
|
||||
bus_dma_segment_t *p_seg;
|
||||
#endif
|
||||
struct usb2_dma_parent_tag *tag_parent;
|
||||
bus_dma_tag_t tag;
|
||||
|
||||
usb2_size_t align;
|
||||
usb2_size_t size;
|
||||
#if defined(__NetBSD__)
|
||||
usb2_size_t n_seg;
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
struct usb2_dma_tag {}; /* empty struct */
|
||||
|
Loading…
Reference in New Issue
Block a user