Skip site navigation (1)Skip section navigation (2)
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>