PERFORCE change 102068 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Jul 21 18:29:27 UTC 2006
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;
+}
+
/*---------------------------------------------------------------------------*
* 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;
More information about the p4-projects
mailing list