PERFORCE change 166559 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Jul 25 16:04:43 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166559
Change 166559 by hselasky at hselasky_laptop001 on 2009/07/25 16:04:38
USB CORE - compat Linux:
- Patch request from Tim Borgeaud:
- add automatic locking
- add refcount for killing URB's
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#45 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.h#21 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#45 (text+ko) ====
@@ -398,15 +398,32 @@
usb_submit_urb(struct urb *urb, uint16_t mem_flags)
{
struct usb_host_endpoint *uhe;
+ uint8_t do_unlock;
+ int err;
- if (urb == NULL) {
+ if (urb == NULL)
return (-EINVAL);
+
+ do_unlock = mtx_owned(&Giant) ? 0 : 1;
+ if (do_unlock)
+ mtx_lock(&Giant);
+
+ if (urb->endpoint == NULL) {
+ err = -EINVAL;
+ goto done;
}
- mtx_assert(&Giant, MA_OWNED);
- if (urb->endpoint == NULL) {
- return (-EINVAL);
+ /*
+ * Check to see if the urb is in the process of being killed
+ * and stop a urb that is in the process of being killed from
+ * being re-submitted (e.g. from its completion callback
+ * function).
+ */
+ if (urb->kill_count != 0) {
+ err = -EPERM;
+ goto done;
}
+
uhe = urb->endpoint;
/*
@@ -424,12 +441,16 @@
usbd_transfer_start(uhe->bsd_xfer[0]);
usbd_transfer_start(uhe->bsd_xfer[1]);
+ err = 0;
} else {
/* no pipes have been setup yet! */
urb->status = -EINVAL;
- return (-EINVAL);
+ err = -EINVAL;
}
- return (0);
+done:
+ if (do_unlock)
+ mtx_unlock(&Giant);
+ return (err);
}
/*------------------------------------------------------------------------*
@@ -448,9 +469,11 @@
usb_unlink_bsd(struct usb_xfer *xfer,
struct urb *urb, uint8_t drain)
{
- if (xfer &&
- usbd_transfer_pending(xfer) &&
- (xfer->priv_fifo == (void *)urb)) {
+ if (xfer == NULL)
+ return;
+ if (!usbd_transfer_pending(xfer))
+ return;
+ if (xfer->priv_fifo == (void *)urb) {
if (drain) {
mtx_unlock(&Giant);
usbd_transfer_drain(xfer);
@@ -467,14 +490,21 @@
{
struct usb_host_endpoint *uhe;
uint16_t x;
+ uint8_t do_unlock;
+ int err;
- if (urb == NULL) {
+ if (urb == NULL)
return (-EINVAL);
- }
- mtx_assert(&Giant, MA_OWNED);
+
+ do_unlock = mtx_owned(&Giant) ? 0 : 1;
+ if (do_unlock)
+ mtx_lock(&Giant);
+ if (drain)
+ urb->kill_count++;
if (urb->endpoint == NULL) {
- return (-EINVAL);
+ err = -EINVAL;
+ goto done;
}
uhe = urb->endpoint;
@@ -504,7 +534,13 @@
usb_unlink_bsd(uhe->bsd_xfer[0], urb, drain);
usb_unlink_bsd(uhe->bsd_xfer[1], urb, drain);
}
- return (0);
+ err = 0;
+done:
+ if (drain)
+ urb->kill_count--;
+ if (do_unlock)
+ mtx_unlock(&Giant);
+ return (err);
}
/*------------------------------------------------------------------------*
@@ -555,6 +591,7 @@
usb_start_wait_urb(struct urb *urb, usb_timeout_t timeout, uint16_t *p_actlen)
{
int err;
+ uint8_t do_unlock;
/* you must have a timeout! */
if (timeout == 0) {
@@ -565,6 +602,9 @@
urb->transfer_flags |= URB_WAIT_WAKEUP;
urb->transfer_flags &= ~URB_IS_SLEEPING;
+ do_unlock = mtx_owned(&Giant) ? 0 : 1;
+ if (do_unlock)
+ mtx_lock(&Giant);
err = usb_submit_urb(urb, 0);
if (err)
goto done;
@@ -582,6 +622,8 @@
err = urb->status;
done:
+ if (do_unlock)
+ mtx_unlock(&Giant);
if (err) {
*p_actlen = 0;
} else {
@@ -638,7 +680,7 @@
* transfers on control endpoint zero:
*/
err = usbd_do_request_flags(dev,
- &Giant, &req, data, USB_SHORT_XFER_OK,
+ NULL, &req, data, USB_SHORT_XFER_OK,
&actlen, timeout);
if (err) {
err = -EPIPE;
@@ -1216,9 +1258,7 @@
void
usb_kill_urb(struct urb *urb)
{
- if (usb_unlink_urb_sub(urb, 1)) {
- /* ignore */
- }
+ usb_unlink_urb_sub(urb, 1);
}
/*------------------------------------------------------------------------*
==== //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.h#21 (text+ko) ====
@@ -262,6 +262,7 @@
uint8_t setup_dma; /* (in) not used on FreeBSD */
uint8_t transfer_dma; /* (in) not used on FreeBSD */
uint8_t bsd_isread;
+ uint8_t kill_count; /* FreeBSD specific */
struct usb_iso_packet_descriptor iso_frame_desc[]; /* (in) ISO ONLY */
};
More information about the p4-projects
mailing list