diff options
Diffstat (limited to 'freebsd')
-rw-r--r-- | freebsd/sys/dev/usb/usb_busdma.c | 31 | ||||
-rw-r--r-- | freebsd/sys/dev/usb/usb_busdma.h | 5 | ||||
-rw-r--r-- | freebsd/sys/dev/usb/usb_transfer.c | 20 | ||||
-rw-r--r-- | freebsd/sys/dev/usb/usbdi.h | 4 | ||||
-rw-r--r-- | freebsd/sys/sys/bus_dma.h | 6 |
5 files changed, 66 insertions, 0 deletions
diff --git a/freebsd/sys/dev/usb/usb_busdma.c b/freebsd/sys/dev/usb/usb_busdma.c index dc52fe15..b74f0823 100644 --- a/freebsd/sys/dev/usb/usb_busdma.c +++ b/freebsd/sys/dev/usb/usb_busdma.c @@ -67,6 +67,9 @@ #include <dev/usb/usb_controller.h> #include <dev/usb/usb_bus.h> #endif /* USB_GLOBAL_INCLUDE_FILE */ +#ifdef __rtems__ +#include <machine/rtems-bsd-cache.h> +#endif /* __rtems__ */ #if USB_HAVE_BUSDMA static void usb_dma_tag_create(struct usb_dma_tag *, usb_size_t, usb_size_t); @@ -543,6 +546,15 @@ usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg, uptag = pc->tag_parent; +#if defined(__rtems__) && defined(CPU_DATA_CACHE_ALIGNMENT) + while (align % CPU_DATA_CACHE_ALIGNMENT != 0) { + align *= 2; + } + if (size % CPU_DATA_CACHE_ALIGNMENT != 0) { + size = (size + (CPU_DATA_CACHE_ALIGNMENT - 1)) & + ~(CPU_DATA_CACHE_ALIGNMENT - 1); + } +#endif /* __rtems__ */ if (align != 1) { /* * The alignment must be greater or equal to the @@ -605,7 +617,12 @@ usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg, /* load memory into DMA */ err = bus_dmamap_load( utag->tag, map, ptr, size, &usb_pc_alloc_mem_cb, +#if defined(__rtems__) && CPU_DATA_CACHE_ALIGNMENT + pc, (BUS_DMA_WAITOK | BUS_DMA_COHERENT | + BUS_DMA_DO_CACHE_LINE_BLOW_UP)); +#else /* __rtems__ */ pc, (BUS_DMA_WAITOK | BUS_DMA_COHERENT)); +#endif /* __rtems__ */ if (err == EINPROGRESS) { cv_wait(uptag->cv, uptag->mtx); @@ -662,6 +679,12 @@ usb_pc_free_mem(struct usb_page_cache *pc) uint8_t usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync) { +#ifdef __rtems__ + int flags; + + flags = pc->dma_do_cache_line_blow_up ? + BUS_DMA_DO_CACHE_LINE_BLOW_UP : 0; +#endif /* __rtems__ */ /* setup page cache */ pc->page_offset_buf = 0; pc->page_offset_end = size; @@ -687,7 +710,11 @@ usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync) */ err = bus_dmamap_load( pc->tag, pc->map, pc->buffer, size, +#ifndef __rtems__ &usb_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK); +#else /* __rtems__ */ + &usb_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK | flags); +#endif /* __rtems__ */ if (err == EINPROGRESS) { cv_wait(uptag->cv, uptag->mtx); err = 0; @@ -709,7 +736,11 @@ usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync) */ if (bus_dmamap_load( pc->tag, pc->map, pc->buffer, size, +#ifndef __rtems__ &usb_pc_load_mem_cb, pc, BUS_DMA_WAITOK)) { +#else /* __rtems__ */ + &usb_pc_load_mem_cb, pc, BUS_DMA_WAITOK | flags)) { +#endif /* __rtems__ */ } } } else { diff --git a/freebsd/sys/dev/usb/usb_busdma.h b/freebsd/sys/dev/usb/usb_busdma.h index d75e67ee..03eca30d 100644 --- a/freebsd/sys/dev/usb/usb_busdma.h +++ b/freebsd/sys/dev/usb/usb_busdma.h @@ -102,6 +102,11 @@ struct usb_page_cache { * from the memory. Else write. */ uint8_t ismultiseg:1; /* set if we can have multiple * segments */ +#ifdef __rtems__ + uint8_t dma_do_cache_line_blow_up:1; + /* set if it is OK to align the buffer + * start and end to next cache line */ +#endif /* __rtems__ */ #endif }; diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c index 3b67c20c..ee1e4c28 100644 --- a/freebsd/sys/dev/usb/usb_transfer.c +++ b/freebsd/sys/dev/usb/usb_transfer.c @@ -2195,6 +2195,9 @@ usbd_xfer_set_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, /* set virtual address to load and length */ xfer->frbuffers[frindex].buffer = ptr; usbd_xfer_set_frame_len(xfer, frindex, len); +#ifdef __rtems__ + xfer->frbuffers[frindex].dma_do_cache_line_blow_up = 0; +#endif /* __rtems__ */ } void @@ -2209,6 +2212,23 @@ usbd_xfer_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, *len = xfer->frlengths[frindex]; } +#ifdef __rtems__ +/*------------------------------------------------------------------------* + * usbd_xfer_frame_allow_cache_line_blow_up + * + * Set a flag that the buffer start and end belonging to this frame can be + * aligned to the next cache line on sync and flush. + *------------------------------------------------------------------------*/ +void +usbd_xfer_frame_allow_cache_line_blow_up(struct usb_xfer *xfer, + usb_frcount_t frindex) +{ + KASSERT(frindex < xfer->max_frame_count, ("frame index overflow")); + + xfer->frbuffers[frindex].dma_do_cache_line_blow_up = 1; +} + +#endif /* __rtems__ */ /*------------------------------------------------------------------------* * usbd_xfer_old_frame_length * diff --git a/freebsd/sys/dev/usb/usbdi.h b/freebsd/sys/dev/usb/usbdi.h index 0a393844..834810a8 100644 --- a/freebsd/sys/dev/usb/usbdi.h +++ b/freebsd/sys/dev/usb/usbdi.h @@ -640,6 +640,10 @@ void usbd_xfer_set_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, void *ptr, usb_frlength_t len); void usbd_xfer_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, void **ptr, int *len); +#ifdef __rtems__ +void usbd_xfer_frame_allow_cache_line_blow_up(struct usb_xfer *xfer, + usb_frcount_t frindex); +#endif /* __rtems__ */ void usbd_xfer_set_frame_offset(struct usb_xfer *xfer, usb_frlength_t offset, usb_frcount_t frindex); usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer); diff --git a/freebsd/sys/sys/bus_dma.h b/freebsd/sys/sys/bus_dma.h index e99d8ece..d5a08be0 100644 --- a/freebsd/sys/sys/bus_dma.h +++ b/freebsd/sys/sys/bus_dma.h @@ -107,6 +107,12 @@ #define BUS_DMA_KEEP_PG_OFFSET 0x400 #define BUS_DMA_LOAD_MBUF 0x800 +#ifdef __rtems__ +/* + * Hint that the start address and size can be aligned to the next cache line. + */ +#define BUS_DMA_DO_CACHE_LINE_BLOW_UP 0x80000000 +#endif /* __rtems__ */ /* Forwards needed by prototypes below. */ union ccb; |