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
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=300667
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
* 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);
@ -236,6 +236,12 @@ usb_ref_device(struct usb_cdev_privdata *cpd,
* Set "is_uref" after grabbing the default SX lock
*/
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 */

View File

@ -2740,7 +2740,7 @@ usbd_device_attached(struct usb_device *udev)
/*
* The following function locks enumerating the given USB device. If
* the lock is already grabbed this function returns zero. Else a
* non-zero value is returned.
* a value of one is returned.
*/
uint8_t
usbd_enum_lock(struct usb_device *udev)
@ -2759,6 +2759,27 @@ usbd_enum_lock(struct usb_device *udev)
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. */
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 *);
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_sr_lock(struct usb_device *);
void usbd_sr_unlock(struct usb_device *);