PERFORCE change 102068 for review
Sam Leffler
sam at errno.com
Fri Jul 21 18:37:56 UTC 2006
Hans Petter Selasky wrote:
> http://perforce.freebsd.org/chv.cgi?CH=102068
>
> Change 102068 by hselasky at hselasky_mini_itx on 2006/07/21 18:29:01
>
> Added new functions, usbd_m_copy_in, usbd_do_request_mtx and
> usbd_do_request_flags_mtx.
>
> Affected files ...
>
> .. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#8 edit
> .. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#12 edit
> .. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#9 edit
>
> Differences ...
>
> ==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#8 (text+ko) ====
>
> @@ -43,6 +43,7 @@
> #include <sys/queue.h> /* LIST_XXX() */
> #include <sys/lock.h>
> #include <sys/malloc.h>
> +#include <sys/mbuf.h>
>
> #include <dev/usb/usb_port.h>
> #include <dev/usb/usb.h>
> @@ -1680,6 +1681,42 @@
> return;
> }
>
> +
> +/*---------------------------------------------------------------------------*
> + * usbd_m_copy_in - copy a mbuf chain directly to DMA-able memory
> + *---------------------------------------------------------------------------*/
> +void
> +usbd_m_copy_in(struct usbd_page_cache *cache, u_int32_t dst_offset,
> + struct mbuf *m, u_int32_t src_offset, u_int32_t src_len)
> +{
> + u_int32_t count;
> +
> + while (src_offset > 0) {
> + __KASSERT(m != NULL, ("usbd_m_copy_in, offset > "
> + "size of mbuf chain"));
> + if (src_offset < m->m_len) {
> + break;
> + }
> + src_offset -= m->m_len;
> + m = m->m_next;
> + }
> +
> + while (src_len > 0) {
> + __KASSERT(m != NULL, ("usbd_m_copy_in, length > "
> + "size of mbuf chain"));
> + count = min(m->m_len - src_offset, src_len);
> +
> + usbd_copy_in(cache, dst_offset, ((caddr_t)(m->m_data)) +
> + src_offset, count);
> +
> + src_len -= count;
> + dst_offset += count;
> + src_offset = 0;
> + m = m->m_next;
> + }
> + return;
> +}
FWIW you can also do this with m_apply:
struct usbd_arg {
struct usbd_page_cache *cache;
u_int32_t dst_offset;
};
static int
usbd_cb(void *arg, void *src, u_int count)
{
struct usbd_arg *ua = arg;
usbd_copy_in(ua->cache, ua->dst_offset, src, count);
ua->dst_offset += count;
return 0;
}
struct usbd_arg arg = { cache, dst_offset };
m_apply(m, m, src_offset, src_len, usbd_cb, &arg);
You might also look at the various assertion checks and such in m_apply
if you decide not to go this route.
Sam
More information about the p4-projects
mailing list