Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Jul 2006 18:29:26 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 102068 for review
Message-ID:  <200607211829.k6LITQRA092758@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
+}
+
 /*---------------------------------------------------------------------------*
  *  usbd_copy_out - copy directly from DMA-able memory
  *---------------------------------------------------------------------------*/

==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#12 (text+ko) ====

@@ -642,6 +642,9 @@
 usbd_copy_in(struct usbd_page_cache *cache, u_int32_t offset, 
 	     const void *ptr, u_int32_t len);
 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);
+void
 usbd_copy_out(struct usbd_page_cache *cache, u_int32_t offset, 
 	      void *ptr, u_int32_t len);
 void
@@ -824,6 +827,14 @@
 usbd_do_request_flags(struct usbd_device *udev, usb_device_request_t *req,
 		      void *data, u_int32_t flags, int *actlen,
 		      u_int32_t timeout);
+usbd_status
+usbd_do_request_mtx(struct usbd_device *udev, struct mtx *mtx, 
+		    usb_device_request_t *req, void *data);
+usbd_status
+usbd_do_request_flags_mtx(struct usbd_device *udev, struct mtx *mtx,
+			  usb_device_request_t *req, void *data, 
+			  u_int32_t flags, int *actlen,
+			  u_int32_t timeout);
 void
 usbd_fill_get_report(usb_device_request_t *req, u_int8_t iface_no, 
 		     u_int8_t type, u_int8_t id, u_int16_t size);

==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#9 (text+ko) ====

@@ -1166,59 +1166,88 @@
 	return;
 }
 
+/*---------------------------------------------------------------------------*
+ *	usbd_do_request_flags / usbd_do_request
+ *
+ * NOTE: the caller should hold "Giant" while calling this function
+ *---------------------------------------------------------------------------*/
 usbd_status
 usbd_do_request(struct usbd_device *udev, usb_device_request_t *req, void *data)
 {
-	return (usbd_do_request_flags(udev, req, data, 0, 0, 
-				      USBD_DEFAULT_TIMEOUT));
+	return usbd_do_request_flags_mtx
+	  (udev, NULL, req, data, 0, NULL, USBD_DEFAULT_TIMEOUT);
+}
+
+usbd_status
+usbd_do_request_flags(struct usbd_device *udev, usb_device_request_t *req,
+		      void *data, u_int32_t flags, int *actlen,
+		      u_int32_t timeout)
+{
+	return usbd_do_request_flags_mtx
+	  (udev, NULL, req, data, flags, actlen, timeout);
 }
 
 /*---------------------------------------------------------------------------*
- *	usbd_do_request_flags
+ *	usbd_do_request_flags_mtx / usbd_do_request_mtx
  *
- * NOTE: the caller should hold "Giant" while calling this function
+ * NOTE: the caller should hold "mtx" while calling this function
  *---------------------------------------------------------------------------*/
 usbd_status
-usbd_do_request_flags(struct usbd_device *udev, usb_device_request_t *req,
-		      void *data, u_int32_t flags, int *actlen,
-		      u_int32_t timeout)
+usbd_do_request_mtx(struct usbd_device *udev, struct mtx *mtx, 
+		    usb_device_request_t *req, void *data)
+{
+	return usbd_do_request_flags_mtx
+	  (udev, mtx, req, data, 0, 0, USBD_DEFAULT_TIMEOUT);
+}
+
+usbd_status
+usbd_do_request_flags_mtx(struct usbd_device *udev, struct mtx *mtx,
+			  usb_device_request_t *req, void *data, 
+			  u_int32_t flags, int *actlen,
+			  u_int32_t timeout)
 {
 	struct usbd_config usbd_config[1] = { /* zero */ };
 	struct usbd_xfer *xfer = NULL;
+	u_int16_t length = UGETW(req->wLength);
 	usbd_status err;
 
 	usbd_config[0].type = UE_CONTROL;
 	usbd_config[0].endpoint = 0; /* control pipe */
 	usbd_config[0].direction = -1;
 	usbd_config[0].timeout = timeout;
-	usbd_config[0].flags = flags|USBD_SYNCHRONOUS;
-	usbd_config[0].bufsize = sizeof(req[0]) + UGETW(req->wLength);
+	usbd_config[0].flags = (flags|USBD_SYNCHRONOUS|USBD_USE_DMA);
+	usbd_config[0].bufsize = sizeof(*req) + length;
 	usbd_config[0].callback = &usbd_default_callback;
 
+	if (mtx) {
+	    mtx_unlock(mtx);
+	}
+
 	/* setup transfer */
 	err = usbd_transfer_setup(udev, 0, &xfer, &usbd_config[0], 1,
-				  NULL, NULL, NULL);
+				  NULL, mtx, NULL);
+
+	if (mtx) {
+	    mtx_lock(mtx);
+	}
+
 	if(err)
 	{
 	    goto done;
 	}
 
-	/* copy IN */
+	usbd_copy_in(&(xfer->buf_data), 0, req, sizeof(*req));
 
-	bcopy(req, xfer->buffer, sizeof(req[0]));
-
 	if(!(req->bmRequestType & UT_READ))
 	{
-	    bcopy(data, ((u_int8_t *)xfer->buffer) + sizeof(req[0]), UGETW(req->wLength));
+	    usbd_copy_in(&(xfer->buf_data), sizeof(*req), data, length);
 	}
 
 	usbd_transfer_start_safe(xfer);
 
-	/* copy OUT */
-
 	if(req->bmRequestType & UT_READ)
 	{
-	    bcopy(((u_int8_t *)xfer->buffer) + sizeof(req[0]), data, UGETW(req->wLength));
+	    usbd_copy_out(&(xfer->buf_data), sizeof(*req), data, length);
 	}
 
 	err = xfer->error;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607211829.k6LITQRA092758>