Date: Fri, 21 Jul 2006 11:37:54 -0700 From: Sam Leffler <sam@errno.com> To: Hans Petter Selasky <hselasky@freebsd.org> Cc: Perforce Change Reviews <perforce@freebsd.org> Subject: Re: PERFORCE change 102068 for review Message-ID: <44C11F02.10404@errno.com> In-Reply-To: <200607211829.k6LITQRA092758@repoman.freebsd.org> References: <200607211829.k6LITQRA092758@repoman.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Hans Petter Selasky wrote: > http://perforce.freebsd.org/chv.cgi?CH=102068 > > Change 102068 by hselasky@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?44C11F02.10404>