PERFORCE change 130505 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Dec 8 11:42:54 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=130505
Change 130505 by hselasky at hselasky_laptop001 on 2007/12/08 19:42:45
This commit is part of USB device side support.
o New function "usbd_default_transfer_setup" which
will handle setup of the default transfer on
endpoint zero independent of USB mode.
o Make "usbd_do_request_callback" static.
o Workarounds for bugs in "indent".
o Always set "actlen" to a known value before
returning from "usbd_do_request_flags". This might
prevent some future problems.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#71 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#65 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#71 (text+ko) ====
@@ -814,8 +814,7 @@
void usbd_do_callback(struct usbd_xfer **pp_xfer, struct thread *td);
void usbd_transfer_enqueue(struct usbd_xfer *xfer);
void usbd_transfer_dequeue(struct usbd_xfer *xfer, usbd_status_t error);
-void usbd_do_request_callback(struct usbd_xfer *xfer);
-usbd_status_t usbd_do_request(struct usbd_device *udev, struct mtx *mtx, usb_device_request_t *req, void *data);
+void usbd_default_transfer_setup(struct usbd_device *udev);
usbd_status_t usbd_do_request_flags(struct usbd_device *udev, struct mtx *mtx, usb_device_request_t *req, void *data, uint32_t flags, uint16_t *actlen, uint32_t timeout);
void usbd_fill_get_report(usb_device_request_t *req, uint8_t iface_no, uint8_t type, uint8_t id, uint16_t size);
void usbd_fill_set_report(usb_device_request_t *req, uint8_t iface_no, uint8_t type, uint8_t id, uint16_t size);
==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#65 (text+ko) ====
@@ -2227,22 +2227,81 @@
return;
}
-void
+/*------------------------------------------------------------------------*
+ * usbd_do_request_callback
+ *------------------------------------------------------------------------*/
+static void
usbd_do_request_callback(struct usbd_xfer *xfer)
{
+ ; /* workaround for a bug in "indent" */
+
switch (USBD_GET_STATE(xfer)) {
- case USBD_ST_SETUP:
- /**/
+ case USBD_ST_SETUP:
usbd_start_hardware(xfer);
- return;
+ break;
+ default:
+ if (!xfer->flags.use_polling) {
+ wakeup(xfer);
+ }
+ break;
+ }
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_serve_request_callback
+ *------------------------------------------------------------------------*/
+static void
+usbd_serve_request_callback(struct usbd_xfer *xfer)
+{
+ ; /* workaround for a bug in "indent" */
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_SETUP:
case USBD_ST_TRANSFERRED:
- default: /* Error */
- if (!xfer->flags.use_polling) {
- wakeup(xfer);
+ default:
+ break;
+ }
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_default_transfer_setup
+ *------------------------------------------------------------------------*/
+void
+usbd_default_transfer_setup(struct usbd_device *udev)
+{
+ struct usbd_config uc[1];
+
+ if ((udev->default_xfer[0] == NULL) ||
+ (udev->default_xfer[0]->address != udev->address) ||
+ (udev->default_ep_desc.wMaxPacketSize[0] !=
+ udev->ddesc.bMaxPacketSize)) {
+
+ udev->default_ep_desc.wMaxPacketSize[0] =
+ udev->ddesc.bMaxPacketSize;
+
+ bzero(uc, sizeof(uc));
+
+ uc[0].type = UE_CONTROL;
+ uc[0].endpoint = 0x00; /* Control pipe */
+ uc[0].direction = UE_DIR_ANY;
+ uc[0].bufsize = 1024; /* bytes */
+ uc[0].flags.proxy_buffer = 1;
+ uc[0].flags.short_xfer_ok = 1;
+ uc[0].cb[USB_MODE_HOST] = &usbd_do_request_callback;
+ uc[0].cb[USB_MODE_DEVICE] = &usbd_serve_request_callback;
+
+ usbd_transfer_unsetup(udev->default_xfer, 1);
+
+ if (usbd_transfer_setup
+ (udev, 0, udev->default_xfer, uc, 1,
+ NULL, udev->default_mtx)) {
+ PRINTFN(0, ("Could not setup default "
+ "USB transfer!\n"));
}
- return;
}
+ return;
}
/*------------------------------------------------------------------------*
@@ -2254,7 +2313,6 @@
uint32_t flags, uint16_t *actlen, uint32_t timeout)
{
struct usbd_xfer *xfer;
- struct usbd_config uc[1];
const void *desc;
uint32_t level = 0;
uint32_t start_ticks;
@@ -2277,6 +2335,13 @@
req->wIndex[1], req->wIndex[0],
req->wLength[1], req->wLength[0]));
+ /*
+ * Set "actlen" to a known value in case the caller does not
+ * check the return value:
+ */
+ if (actlen) {
+ *actlen = 0;
+ }
if (udev->usb_mode == USB_MODE_DEVICE) {
PRINTFN(0, ("USB device mode\n"));
(udev->usb_temp_get_desc) (udev, mtx, req, &desc, &temp);
@@ -2295,9 +2360,6 @@
bcopy(desc, data, length);
return (0); /* success */
}
- if (actlen) {
- (*actlen) = 0;
- }
/*
* Drop any mutex:
*/
@@ -2321,39 +2383,16 @@
sx_xlock(udev->default_sx);
/*
- * Check if we need to setup a new USB transfer:
+ * Setup a new USB transfer or use the existing one, if any:
*/
+ usbd_default_transfer_setup(udev);
- if ((udev->default_xfer[0] == NULL) ||
- (udev->default_xfer[0]->address != udev->address) ||
- (udev->default_ep_desc.wMaxPacketSize[0] !=
- udev->ddesc.bMaxPacketSize)) {
-
- udev->default_ep_desc.wMaxPacketSize[0] =
- udev->ddesc.bMaxPacketSize;
-
- bzero(uc, sizeof(uc));
-
- uc[0].type = UE_CONTROL;
- uc[0].endpoint = 0x00; /* Control pipe */
- uc[0].direction = UE_DIR_ANY;
- uc[0].bufsize = 1024; /* bytes */
- uc[0].flags.proxy_buffer = 1;
- uc[0].flags.short_xfer_ok = 1;
- uc[0].cb[USB_MODE_HOST] = &usbd_do_request_callback;
-
- usbd_transfer_unsetup(udev->default_xfer, 1);
-
- err = usbd_transfer_setup
- (udev, 0, udev->default_xfer, uc, 1,
- NULL, udev->default_mtx);
-
- if (err) {
- goto done;
- }
+ xfer = udev->default_xfer[0];
+ if (xfer == NULL) {
+ /* most likely out of memory */
+ err = USBD_NOMEM;
+ goto done;
}
- xfer = udev->default_xfer[0];
-
mtx_lock(xfer->priv_mtx);
if ((flags & USBD_USE_POLLING) || cold) {
More information about the p4-projects
mailing list