Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/usb/usb_busdma.c
Show First 20 Lines • Show All 594 Lines • ▼ Show 20 Lines | if (err == EINPROGRESS) { | ||||
err = 0; | err = 0; | ||||
} | } | ||||
USB_MTX_UNLOCK(uptag->mtx); | USB_MTX_UNLOCK(uptag->mtx); | ||||
if (err || uptag->dma_error) { | if (err || uptag->dma_error) { | ||||
bus_dmamem_free(utag->tag, ptr, map); | bus_dmamem_free(utag->tag, ptr, map); | ||||
goto error; | goto error; | ||||
} | } | ||||
pc->isloaded = 1; | |||||
memset(ptr, 0, size); | memset(ptr, 0, size); | ||||
usb_pc_cpu_flush(pc); | usb_pc_cpu_flush(pc); | ||||
return (0); | return (0); | ||||
error: | error: | ||||
/* reset most of the page cache */ | /* reset most of the page cache */ | ||||
pc->buffer = NULL; | pc->buffer = NULL; | ||||
pc->page_start = NULL; | pc->page_start = NULL; | ||||
pc->page_offset_buf = 0; | pc->page_offset_buf = 0; | ||||
pc->page_offset_end = 0; | pc->page_offset_end = 0; | ||||
pc->isloaded = 0; | |||||
pc->map = NULL; | pc->map = NULL; | ||||
pc->tag = NULL; | pc->tag = NULL; | ||||
return (1); | return (1); | ||||
} | } | ||||
/*------------------------------------------------------------------------* | /*------------------------------------------------------------------------* | ||||
* usb_pc_free_mem - free DMA memory | * usb_pc_free_mem - free DMA memory | ||||
* | * | ||||
* This function is NULL safe. | * This function is NULL safe. | ||||
*------------------------------------------------------------------------*/ | *------------------------------------------------------------------------*/ | ||||
void | void | ||||
usb_pc_free_mem(struct usb_page_cache *pc) | usb_pc_free_mem(struct usb_page_cache *pc) | ||||
{ | { | ||||
if (pc && pc->buffer) { | if (pc && pc->buffer) { | ||||
if (pc->isloaded) | |||||
bus_dmamap_unload(pc->tag, pc->map); | bus_dmamap_unload(pc->tag, pc->map); | ||||
bus_dmamem_free(pc->tag, pc->buffer, pc->map); | bus_dmamem_free(pc->tag, pc->buffer, pc->map); | ||||
pc->buffer = NULL; | pc->buffer = NULL; | ||||
pc->isloaded = 0; | |||||
} | } | ||||
} | } | ||||
/*------------------------------------------------------------------------* | /*------------------------------------------------------------------------* | ||||
* usb_pc_load_mem - load virtual memory into DMA | * usb_pc_load_mem - load virtual memory into DMA | ||||
* | * | ||||
* Return values: | * Return values: | ||||
* 0: Success | * 0: Success | ||||
Show All 15 Lines | if (sync) { | ||||
int err; | int err; | ||||
uptag = pc->tag_parent; | uptag = pc->tag_parent; | ||||
/* | /* | ||||
* We have to unload the previous loaded DMA | * We have to unload the previous loaded DMA | ||||
* pages before trying to load a new one! | * pages before trying to load a new one! | ||||
*/ | */ | ||||
if (pc->isloaded) | |||||
bus_dmamap_unload(pc->tag, pc->map); | bus_dmamap_unload(pc->tag, pc->map); | ||||
/* | /* | ||||
* Try to load memory into DMA. | * Try to load memory into DMA. | ||||
*/ | */ | ||||
err = bus_dmamap_load( | err = bus_dmamap_load( | ||||
pc->tag, pc->map, pc->buffer, size, | pc->tag, pc->map, pc->buffer, size, | ||||
&usb_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK); | &usb_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK); | ||||
if (err == EINPROGRESS) { | if (err == EINPROGRESS) { | ||||
cv_wait(uptag->cv, uptag->mtx); | cv_wait(uptag->cv, uptag->mtx); | ||||
err = 0; | err = 0; | ||||
} | } | ||||
if (err || uptag->dma_error) { | if (err || uptag->dma_error) { | ||||
pc->isloaded = 0; | |||||
return (1); | return (1); | ||||
} | } | ||||
} else { | } else { | ||||
/* | /* | ||||
* We have to unload the previous loaded DMA | * We have to unload the previous loaded DMA | ||||
* pages before trying to load a new one! | * pages before trying to load a new one! | ||||
*/ | */ | ||||
if (pc->isloaded) | |||||
bus_dmamap_unload(pc->tag, pc->map); | bus_dmamap_unload(pc->tag, pc->map); | ||||
/* | /* | ||||
* Try to load memory into DMA. The callback | * Try to load memory into DMA. The callback | ||||
* will be called in all cases: | * will be called in all cases: | ||||
*/ | */ | ||||
if (bus_dmamap_load( | if (bus_dmamap_load( | ||||
pc->tag, pc->map, pc->buffer, size, | pc->tag, pc->map, pc->buffer, size, | ||||
&usb_pc_load_mem_cb, pc, BUS_DMA_WAITOK)) { | &usb_pc_load_mem_cb, pc, BUS_DMA_WAITOK)) { | ||||
} | } | ||||
} | } | ||||
pc->isloaded = 1; | |||||
} else { | } else { | ||||
if (!sync) { | if (!sync) { | ||||
/* | /* | ||||
* Call callback so that refcount is decremented | * Call callback so that refcount is decremented | ||||
* properly: | * properly: | ||||
*/ | */ | ||||
pc->tag_parent->dma_error = 0; | pc->tag_parent->dma_error = 0; | ||||
(pc->tag_parent->func) (pc->tag_parent); | (pc->tag_parent->func) (pc->tag_parent); | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | |||||
* usb_pc_dmamap_destroy | * usb_pc_dmamap_destroy | ||||
* | * | ||||
* This function is NULL safe. | * This function is NULL safe. | ||||
*------------------------------------------------------------------------*/ | *------------------------------------------------------------------------*/ | ||||
void | void | ||||
usb_pc_dmamap_destroy(struct usb_page_cache *pc) | usb_pc_dmamap_destroy(struct usb_page_cache *pc) | ||||
{ | { | ||||
if (pc && pc->tag) { | if (pc && pc->tag) { | ||||
if (pc->isloaded) | |||||
bus_dmamap_unload(pc->tag, pc->map); | |||||
bus_dmamap_destroy(pc->tag, pc->map); | bus_dmamap_destroy(pc->tag, pc->map); | ||||
pc->tag = NULL; | pc->tag = NULL; | ||||
pc->map = NULL; | pc->map = NULL; | ||||
} | } | ||||
} | } | ||||
/*------------------------------------------------------------------------* | /*------------------------------------------------------------------------* | ||||
* usb_dma_tag_find - factored out code | * usb_dma_tag_find - factored out code | ||||
▲ Show 20 Lines • Show All 306 Lines • Show Last 20 Lines |