summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_handle_request.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2013-02-13 12:35:17 +0000
committerhselasky <hselasky@FreeBSD.org>2013-02-13 12:35:17 +0000
commita40dc60f62a62caf12c402fff2a0756a7550a72e (patch)
treebd9f44c788357d73342a4ffabe096ed49372b919 /sys/dev/usb/usb_handle_request.c
parent6133fc8dbb41bc8c02588df00d5946dad1d4d98f (diff)
downloadFreeBSD-src-a40dc60f62a62caf12c402fff2a0756a7550a72e.zip
FreeBSD-src-a40dc60f62a62caf12c402fff2a0756a7550a72e.tar.gz
Resolve a LOR after r246616. Protect control requests using the USB device
enumeration lock. Make sure all callers of usbd_enum_lock() check the return value. Remove the control transfer specific lock. Bump the FreeBSD version number, hence external USB modules may need to be recompiled due to a USB device structure change. MFC after: 1 week
Diffstat (limited to 'sys/dev/usb/usb_handle_request.c')
-rw-r--r--sys/dev/usb/usb_handle_request.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/dev/usb/usb_handle_request.c b/sys/dev/usb/usb_handle_request.c
index a775d67..7f3cdc6 100644
--- a/sys/dev/usb/usb_handle_request.c
+++ b/sys/dev/usb/usb_handle_request.c
@@ -149,6 +149,7 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
{
struct usb_device *udev = xfer->xroot->udev;
usb_error_t err = 0;
+ uint8_t do_unlock;
/*
* We need to protect against other threads doing probe and
@@ -156,7 +157,8 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
*/
USB_XFER_UNLOCK(xfer);
- usbd_enum_lock(udev);
+ /* Prevent re-enumeration */
+ do_unlock = usbd_enum_lock(udev);
if (conf_no == USB_UNCONFIG_NO) {
conf_no = USB_UNCONFIG_INDEX;
@@ -179,7 +181,8 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
goto done;
}
done:
- usbd_enum_unlock(udev);
+ if (do_unlock)
+ usbd_enum_unlock(udev);
USB_XFER_LOCK(xfer);
return (err);
}
@@ -221,6 +224,7 @@ usb_handle_iface_request(struct usb_xfer *xfer,
int error;
uint8_t iface_index;
uint8_t temp_state;
+ uint8_t do_unlock;
if ((req.bmRequestType & 0x1F) == UT_INTERFACE) {
iface_index = req.wIndex[0]; /* unicast */
@@ -234,7 +238,8 @@ usb_handle_iface_request(struct usb_xfer *xfer,
*/
USB_XFER_UNLOCK(xfer);
- usbd_enum_lock(udev);
+ /* Prevent re-enumeration */
+ do_unlock = usbd_enum_lock(udev);
error = ENXIO;
@@ -350,17 +355,20 @@ tr_repeat:
goto tr_stalled;
}
tr_valid:
- usbd_enum_unlock(udev);
+ if (do_unlock)
+ usbd_enum_unlock(udev);
USB_XFER_LOCK(xfer);
return (0);
tr_short:
- usbd_enum_unlock(udev);
+ if (do_unlock)
+ usbd_enum_unlock(udev);
USB_XFER_LOCK(xfer);
return (USB_ERR_SHORT_XFER);
tr_stalled:
- usbd_enum_unlock(udev);
+ if (do_unlock)
+ usbd_enum_unlock(udev);
USB_XFER_LOCK(xfer);
return (USB_ERR_STALLED);
}
OpenPOWER on IntegriCloud