Lines Matching +full:dma +full:- +full:safe +full:- +full:map
1 /*-
33 /*------------------------------------------------------------------------*
34 * usbd_get_page - lookup DMA-able memory for the given offset
38 *------------------------------------------------------------------------*/
46 if (pc->page_start) { in usbd_get_page()
48 /* Case 1 - something has been loaded into DMA */ in usbd_get_page()
50 if (pc->buffer) { in usbd_get_page()
52 /* Case 1a - Kernel Virtual Address */ in usbd_get_page()
54 res->buffer = USB_ADD_BYTES(pc->buffer, offset); in usbd_get_page()
56 offset += pc->page_offset_buf; in usbd_get_page()
60 page = pc->page_start; in usbd_get_page()
62 if (pc->ismultiseg) { in usbd_get_page()
68 res->length = USB_PAGE_SIZE - offset; in usbd_get_page()
69 res->physaddr = page->physaddr + offset; in usbd_get_page()
71 res->length = (usb_size_t)-1; in usbd_get_page()
72 res->physaddr = page->physaddr + offset; in usbd_get_page()
74 if (!pc->buffer) { in usbd_get_page()
76 /* Case 1b - Non Kernel Virtual Address */ in usbd_get_page()
78 res->buffer = USB_ADD_BYTES(page->buffer, offset); in usbd_get_page()
83 /* Case 2 - Plain PIO */ in usbd_get_page()
85 res->buffer = USB_ADD_BYTES(pc->buffer, offset); in usbd_get_page()
86 res->length = (usb_size_t)-1; in usbd_get_page()
88 res->physaddr = 0; in usbd_get_page()
92 /*------------------------------------------------------------------------*
93 * usbd_copy_in - copy directly to DMA-able memory
94 *------------------------------------------------------------------------*/
111 len -= buf_res.length; in usbd_copy_in()
116 /*------------------------------------------------------------------------*
117 * usbd_copy_out - copy directly from DMA-able memory
118 *------------------------------------------------------------------------*/
135 len -= res.length; in usbd_copy_out()
140 /*------------------------------------------------------------------------*
141 * usbd_frame_zero - zero DMA-able memory
142 *------------------------------------------------------------------------*/
159 len -= res.length; in usbd_frame_zero()
165 /*------------------------------------------------------------------------*
166 * usb_pc_common_mem_cb - BUS-DMA callback function
167 *------------------------------------------------------------------------*/
181 nseg = ((length + USB_PAGE_SIZE - 1) / USB_PAGE_SIZE); in usb_pc_common_mem_cb()
183 pg = pc->page_start; in usb_pc_common_mem_cb()
184 pg->physaddr = phys & ~(USB_PAGE_SIZE - 1); in usb_pc_common_mem_cb()
185 rem = phys & (USB_PAGE_SIZE - 1); in usb_pc_common_mem_cb()
186 pc->page_offset_buf = rem; in usb_pc_common_mem_cb()
187 pc->page_offset_end += rem; in usb_pc_common_mem_cb()
192 pg->physaddr = (phys + off) & ~(USB_PAGE_SIZE - 1); in usb_pc_common_mem_cb()
196 /*------------------------------------------------------------------------*
197 * usb_pc_alloc_mem - allocate DMA'able memory
202 *------------------------------------------------------------------------*/
217 rem = (-((uintptr_t)ptr)) & (align - 1); in usb_pc_alloc_mem()
226 pc->buffer = ((uint8_t *)ptr) + rem; in usb_pc_alloc_mem()
227 pc->page_start = pg; in usb_pc_alloc_mem()
228 pc->page_offset_buf = 0; in usb_pc_alloc_mem()
229 pc->page_offset_end = size; in usb_pc_alloc_mem()
230 pc->map = NULL; in usb_pc_alloc_mem()
231 pc->tag = ptr; in usb_pc_alloc_mem()
232 pc->ismultiseg = (align == 1); in usb_pc_alloc_mem()
235 usb_pc_common_mem_cb(pc, pc->buffer, size); in usb_pc_alloc_mem()
242 pc->buffer = NULL; in usb_pc_alloc_mem()
243 pc->page_start = NULL; in usb_pc_alloc_mem()
244 pc->page_offset_buf = 0; in usb_pc_alloc_mem()
245 pc->page_offset_end = 0; in usb_pc_alloc_mem()
246 pc->map = NULL; in usb_pc_alloc_mem()
247 pc->tag = NULL; in usb_pc_alloc_mem()
251 /*------------------------------------------------------------------------*
252 * usb_pc_free_mem - free DMA memory
254 * This function is NULL safe.
255 *------------------------------------------------------------------------*/
259 if (pc != NULL && pc->buffer != NULL) { in usb_pc_free_mem()
260 free(pc->tag, XXX); in usb_pc_free_mem()
261 pc->buffer = NULL; in usb_pc_free_mem()
265 /*------------------------------------------------------------------------*
266 * usb_pc_load_mem - load virtual memory into DMA
271 *------------------------------------------------------------------------*/
276 pc->page_offset_buf = 0; in usb_pc_load_mem()
277 pc->page_offset_end = size; in usb_pc_load_mem()
278 pc->ismultiseg = 1; in usb_pc_load_mem()
280 mtx_assert(pc->tag_parent->mtx, MA_OWNED); in usb_pc_load_mem()
284 usb_pc_common_mem_cb(pc, pc->buffer, size); in usb_pc_load_mem()
291 pc->tag_parent->dma_error = 0; in usb_pc_load_mem()
292 (pc->tag_parent->func) (pc->tag_parent); in usb_pc_load_mem()
297 /*------------------------------------------------------------------------*
298 * usb_pc_cpu_invalidate - invalidate CPU cache
299 *------------------------------------------------------------------------*/
303 if (pc->page_offset_end == pc->page_offset_buf) { in usb_pc_cpu_invalidate()
310 /*------------------------------------------------------------------------*
311 * usb_pc_cpu_flush - flush CPU cache
312 *------------------------------------------------------------------------*/
316 if (pc->page_offset_end == pc->page_offset_buf) { in usb_pc_cpu_flush()
323 /*------------------------------------------------------------------------*
324 * usb_pc_dmamap_create - create a DMA map
329 *------------------------------------------------------------------------*/
336 /*------------------------------------------------------------------------*
339 * This function is NULL safe.
340 *------------------------------------------------------------------------*/
347 /*------------------------------------------------------------------------*
348 * usb_dma_tag_setup - initialise USB DMA tags
349 *------------------------------------------------------------------------*/
366 cv_init(udpt->cv, "USB DMA CV"); in usb_dma_tag_setup()
369 udpt->mtx = mtx; in usb_dma_tag_setup()
370 udpt->func = func; in usb_dma_tag_setup()
371 udpt->tag = dmat; in usb_dma_tag_setup()
372 udpt->utag_first = udt; in usb_dma_tag_setup()
373 udpt->utag_max = nudt; in usb_dma_tag_setup()
374 udpt->dma_bits = ndmabits; in usb_dma_tag_setup()
376 while (nudt--) { in usb_dma_tag_setup()
378 udt->tag_parent = udpt; in usb_dma_tag_setup()
383 /*------------------------------------------------------------------------*
384 * usb_bus_tag_unsetup - factored out code
385 *------------------------------------------------------------------------*/
392 udt = udpt->utag_first; in usb_dma_tag_unsetup()
393 nudt = udpt->utag_max; in usb_dma_tag_unsetup()
395 while (nudt--) { in usb_dma_tag_unsetup()
396 udt->align = 0; in usb_dma_tag_unsetup()
400 if (udpt->utag_max) { in usb_dma_tag_unsetup()
402 cv_destroy(udpt->cv); in usb_dma_tag_unsetup()
406 /*------------------------------------------------------------------------*
409 * This function handles loading of virtual buffers into DMA and is
411 *------------------------------------------------------------------------*/
419 xfer = pq->curr; in usb_bdma_work_loop()
420 info = xfer->xroot; in usb_bdma_work_loop()
422 mtx_assert(info->xfer_mtx, MA_OWNED); in usb_bdma_work_loop()
424 if (xfer->error) { in usb_bdma_work_loop()
426 USB_BUS_LOCK(info->bus); in usb_bdma_work_loop()
428 USB_BUS_UNLOCK(info->bus); in usb_bdma_work_loop()
431 if (!xfer->flags_int.bdma_setup) { in usb_bdma_work_loop()
436 xfer->flags_int.bdma_setup = 1; in usb_bdma_work_loop()
438 /* reset BUS-DMA load state */ in usb_bdma_work_loop()
440 info->dma_error = 0; in usb_bdma_work_loop()
442 if (xfer->flags_int.isochronous_xfr) { in usb_bdma_work_loop()
445 frlength_0 = xfer->sumlen; in usb_bdma_work_loop()
448 nframes = xfer->nframes; in usb_bdma_work_loop()
449 frlength_0 = xfer->frlengths[0]; in usb_bdma_work_loop()
453 * Set DMA direction first. This is needed to in usb_bdma_work_loop()
458 pg = xfer->dma_page_ptr; in usb_bdma_work_loop()
460 if (xfer->flags_int.control_xfr && in usb_bdma_work_loop()
461 xfer->flags_int.control_hdr) { in usb_bdma_work_loop()
463 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { in usb_bdma_work_loop()
465 xfer->frbuffers[0].isread = 1; in usb_bdma_work_loop()
468 xfer->frbuffers[0].isread = 0; in usb_bdma_work_loop()
472 xfer->frbuffers[0].isread = isread; in usb_bdma_work_loop()
481 xfer->frbuffers[0].page_start = pg; in usb_bdma_work_loop()
483 info->dma_nframes = nframes; in usb_bdma_work_loop()
484 info->dma_currframe = 0; in usb_bdma_work_loop()
485 info->dma_frlength_0 = frlength_0; in usb_bdma_work_loop()
490 while (--nframes > 0) { in usb_bdma_work_loop()
491 xfer->frbuffers[nframes].isread = isread; in usb_bdma_work_loop()
492 xfer->frbuffers[nframes].page_start = pg; in usb_bdma_work_loop()
494 pg += (xfer->frlengths[nframes] / USB_PAGE_SIZE); in usb_bdma_work_loop()
499 if (info->dma_error) { in usb_bdma_work_loop()
500 USB_BUS_LOCK(info->bus); in usb_bdma_work_loop()
502 USB_BUS_UNLOCK(info->bus); in usb_bdma_work_loop()
505 if (info->dma_currframe != info->dma_nframes) { in usb_bdma_work_loop()
507 if (info->dma_currframe == 0) { in usb_bdma_work_loop()
509 usb_pc_load_mem(xfer->frbuffers, in usb_bdma_work_loop()
510 info->dma_frlength_0, 0); in usb_bdma_work_loop()
513 nframes = info->dma_currframe; in usb_bdma_work_loop()
514 usb_pc_load_mem(xfer->frbuffers + nframes, in usb_bdma_work_loop()
515 xfer->frlengths[nframes], 0); in usb_bdma_work_loop()
519 info->dma_currframe++; in usb_bdma_work_loop()
533 /*------------------------------------------------------------------------*
536 * This function is called when the BUS-DMA has loaded virtual memory
537 * into DMA, if any.
538 *------------------------------------------------------------------------*/
546 mtx_assert(info->xfer_mtx, MA_OWNED); in usb_bdma_done_event()
549 info->dma_error = udpt->dma_error; in usb_bdma_done_event()
552 usb_command_wrapper(&info->dma_q, in usb_bdma_done_event()
553 info->dma_q.curr); in usb_bdma_done_event()
556 /*------------------------------------------------------------------------*
559 * This function handles DMA synchronisation that must be done before
561 *------------------------------------------------------------------------*/
568 if (xfer->flags_int.isochronous_xfr) { in usb_bdma_pre_sync()
573 nframes = xfer->nframes; in usb_bdma_pre_sync()
576 pc = xfer->frbuffers; in usb_bdma_pre_sync()
578 while (nframes--) { in usb_bdma_pre_sync()
580 if (pc->isread) { in usb_bdma_pre_sync()
589 /*------------------------------------------------------------------------*
592 * This function handles DMA synchronisation that must be done after
594 *------------------------------------------------------------------------*/
601 if (xfer->flags_int.isochronous_xfr) { in usb_bdma_post_sync()
606 nframes = xfer->nframes; in usb_bdma_post_sync()
609 pc = xfer->frbuffers; in usb_bdma_post_sync()
611 while (nframes--) { in usb_bdma_post_sync()
612 if (pc->isread) { in usb_bdma_post_sync()