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