From owner-p4-projects@FreeBSD.ORG Sat Dec 8 19:42:53 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9215C16A419; Sat, 8 Dec 2007 19:42:53 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2926016A417 for ; Sat, 8 Dec 2007 19:42:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 13E3B13C46E for ; Sat, 8 Dec 2007 19:42:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lB8JgqKp045369 for ; Sat, 8 Dec 2007 19:42:52 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lB8JgqaR045366 for perforce@freebsd.org; Sat, 8 Dec 2007 19:42:52 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 8 Dec 2007 19:42:52 GMT Message-Id: <200712081942.lB8JgqaR045366@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 130505 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 Dec 2007 19:42:54 -0000 http://perforce.freebsd.org/chv.cgi?CH=130505 Change 130505 by hselasky@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) {