Check for signals when locking the USB enumeration thread from

userspace, so that USB applications can be killed if an enumeration
thread should be stuck for various reasons.

MFC after:	1 week
This commit is contained in:
Hans Petter Selasky 2016-05-25 07:48:36 +00:00
parent 65380b5f2f
commit 10aab8b611
3 changed files with 32 additions and 2 deletions

View File

@ -228,7 +228,7 @@ usb_ref_device(struct usb_cdev_privdata *cpd,
* We need to grab the enumeration SX-lock before * We need to grab the enumeration SX-lock before
* grabbing the FIFO refs to avoid deadlock at detach! * grabbing the FIFO refs to avoid deadlock at detach!
*/ */
crd->do_unlock = usbd_enum_lock(cpd->udev); crd->do_unlock = usbd_enum_lock_sig(cpd->udev);
mtx_lock(&usb_ref_lock); mtx_lock(&usb_ref_lock);
@ -236,6 +236,12 @@ usb_ref_device(struct usb_cdev_privdata *cpd,
* Set "is_uref" after grabbing the default SX lock * Set "is_uref" after grabbing the default SX lock
*/ */
crd->is_uref = 1; crd->is_uref = 1;
/* check for signal */
if (crd->do_unlock > 1) {
crd->do_unlock = 0;
goto error;
}
} }
/* check if we are doing an open */ /* check if we are doing an open */

View File

@ -2740,7 +2740,7 @@ usbd_device_attached(struct usb_device *udev)
/* /*
* The following function locks enumerating the given USB device. If * The following function locks enumerating the given USB device. If
* the lock is already grabbed this function returns zero. Else a * the lock is already grabbed this function returns zero. Else a
* non-zero value is returned. * a value of one is returned.
*/ */
uint8_t uint8_t
usbd_enum_lock(struct usb_device *udev) usbd_enum_lock(struct usb_device *udev)
@ -2759,6 +2759,27 @@ usbd_enum_lock(struct usb_device *udev)
return (1); return (1);
} }
#if USB_HAVE_UGEN
/*
* This function is the same like usbd_enum_lock() except a value of
* 255 is returned when a signal is pending:
*/
uint8_t
usbd_enum_lock_sig(struct usb_device *udev)
{
if (sx_xlocked(&udev->enum_sx))
return (0);
if (sx_xlock_sig(&udev->enum_sx))
return (255);
if (sx_xlock_sig(&udev->sr_sx)) {
sx_xunlock(&udev->enum_sx);
return (255);
}
mtx_lock(&Giant);
return (1);
}
#endif
/* The following function unlocks enumerating the given USB device. */ /* The following function unlocks enumerating the given USB device. */
void void

View File

@ -314,6 +314,9 @@ void usb_set_device_state(struct usb_device *, enum usb_dev_state);
enum usb_dev_state usb_get_device_state(struct usb_device *); enum usb_dev_state usb_get_device_state(struct usb_device *);
uint8_t usbd_enum_lock(struct usb_device *); uint8_t usbd_enum_lock(struct usb_device *);
#if USB_HAVE_UGEN
uint8_t usbd_enum_lock_sig(struct usb_device *);
#endif
void usbd_enum_unlock(struct usb_device *); void usbd_enum_unlock(struct usb_device *);
void usbd_sr_lock(struct usb_device *); void usbd_sr_lock(struct usb_device *);
void usbd_sr_unlock(struct usb_device *); void usbd_sr_unlock(struct usb_device *);