PERFORCE change 144443 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Tue Jul 1 21:41:52 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=144443
Change 144443 by hselasky at hselasky_laptop001 on 2008/07/01 21:41:25
Several fixes and improvements to the USB device layer /dev/usbXXX .
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#6 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#6 (text+ko) ====
@@ -75,6 +75,7 @@
static int usb2_fifo_open(struct usb2_fifo *f, struct file *fp, struct thread *td, int fflags);
static void usb2_fifo_close(struct usb2_fifo *f, struct thread *td, int fflags);
static void usb2_dev_init(void *arg);
+static void usb2_dev_init_post(void *arg);
static void usb2_dev_uninit(void *arg);
static int usb2_fifo_uiomove(struct usb2_fifo *f, void *cp, int n, struct uio *uio);
static void usb2_fifo_wakeup(struct usb2_fifo *f);
@@ -310,28 +311,35 @@
mtx_lock(&usb2_ref_lock);
ploc->bus = devclass_get_softc(usb2_devclass_ptr, ploc->bus_index);
if (ploc->bus == NULL) {
+ DPRINTF(1, "no bus\n");
goto error;
}
if (ploc->bus->ready == 0) {
+ DPRINTF(1, "not ready\n");
goto error;
}
if (ploc->dev_index >= ploc->bus->devices_max) {
+ DPRINTF(1, "invalid dev index\n");
goto error;
}
ploc->udev = ploc->bus->devices[ploc->dev_index];
if (ploc->udev == NULL) {
+ DPRINTF(1, "no device\n");
goto error;
}
if (ploc->udev->refcount == USB_DEV_REF_MAX) {
+ DPRINTF(1, "no dev ref\n");
goto error;
}
ploc->iface = usb2_get_iface(ploc->udev, ploc->iface_index);
if (ploc->ep_index != 0) {
/* non control endpoint - we need an interface */
if (ploc->iface == NULL) {
+ DPRINTF(1, "no iface\n");
goto error;
}
if (ploc->iface->idesc == NULL) {
+ DPRINTF(1, "no idesc\n");
goto error;
}
}
@@ -368,12 +376,15 @@
/* when everything is OK we increment the refcounts */
if (ploc->is_uref) {
+ DPRINTF(1, "ref udev\n");
ploc->udev->refcount++;
}
if (ploc->is_write) {
+ DPRINTF(1, "ref write\n");
ploc->txfifo->refcount++;
}
if (ploc->is_read) {
+ DPRINTF(1, "ref read\n");
ploc->rxfifo->refcount++;
}
mtx_unlock(&usb2_ref_lock);
@@ -390,6 +401,7 @@
error:
mtx_unlock(&usb2_ref_lock);
+ DPRINTF(1, "fail\n");
return (USB_ERR_INVAL);
}
@@ -513,10 +525,12 @@
if (f) {
/* nothing do to - we already have a FIFO */
+ DPRINTF(1, "has FIFO\n");
return;
}
if (ep_index >= 16) {
/* nothing to do - these are virtual endpoints */
+ DPRINTF(1, "VEP\n");
return;
}
/* automatically create a generic endpoint */
@@ -601,6 +615,7 @@
if (f == NULL) {
/* no FIFO there */
+ DPRINTF(1, "no FIFO\n");
return (ENXIO);
}
/* remove FWRITE and FREAD flags */
@@ -743,7 +758,7 @@
/* check if we are sleeping */
if (f->flag_sleeping) {
- DPRINTF(-1, "Sleeping at close!\n");
+ DPRINTF(1, "Sleeping at close!\n");
}
mtx_unlock(f->priv_mtx);
@@ -774,6 +789,7 @@
usb2_last_devloc = (0 - 1); /* reset "usb2_devloc" */
if (fp == NULL) {
+ DPRINTF(1, "fp == NULL\n");
return (ENXIO);
}
if (usb2_old_f_data != fp->f_data) {
@@ -799,10 +815,12 @@
}
if (devloc == (uint32_t)(0 - 1)) {
/* tried to open /dev/usb */
+ DPRINTF(1, "no devloc\n");
return (ENXIO);
}
err = usb2_ref_device(NULL, &loc, devloc);
if (err) {
+ DPRINTF(1, "cannot ref device\n");
return (ENXIO);
}
/* create a permissions mask */
@@ -854,7 +872,6 @@
}
usb2_fifo_check(&loc, fflags & FREAD);
usb2_fifo_check(&loc, fflags & FWRITE);
-
usb2_unref_device(&loc);
/* try to refer the device and associated FIFOs again */
@@ -866,6 +883,7 @@
err = usb2_fifo_open(loc.rxfifo, fp, td,
fflags);
if (err) {
+ DPRINTF(1, "read open failed\n");
usb2_unref_device(&loc);
return (err);
}
@@ -874,6 +892,7 @@
err = usb2_fifo_open(loc.txfifo, fp, td,
fflags);
if (err) {
+ DPRINTF(1, "write open failed\n");
if (fflags & FREAD) {
usb2_fifo_close(loc.rxfifo, td,
fflags);
@@ -923,7 +942,6 @@
}
if (usb2_last_devloc != (uint32_t)(0 - 1)) {
DPRINTF(-1, "Clone race!\n");
- return;
}
usb2_last_devloc = usb2_path_convert(name +
sizeof(USB_DEVICE_NAME) - 1);
@@ -941,7 +959,14 @@
usb2_dev_init(void *arg)
{
mtx_init(&usb2_ref_lock, "USB ref mutex", NULL, MTX_DEF);
+ return;
+}
+SYSINIT(usb2_dev_init, SI_SUB_KLD, SI_ORDER_FIRST, usb2_dev_init, NULL);
+
+static void
+usb2_dev_init_post(void *arg)
+{
/* create a dummy device so that we are visible */
usb2_dev = make_dev(&usb2_devsw, 0, UID_ROOT, GID_OPERATOR,
0000, USB_DEVICE_NAME " ");
@@ -955,7 +980,7 @@
return;
}
-SYSINIT(usb2_dev_init, SI_SUB_KLD, SI_ORDER_FIRST, usb2_dev_init, NULL);
+SYSINIT(usb2_dev_init_post, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, usb2_dev_init_post, NULL);
static void
usb2_dev_uninit(void *arg)
@@ -981,7 +1006,9 @@
int fflags;
int err;
- DPRINTF(1, "\n");
+ fflags = fp->f_flag;
+
+ DPRINTF(1, "fflags=%u\n", fflags);
err = usb2_ref_device(fp, &loc, 0);;
@@ -991,6 +1018,7 @@
/* check for error */
if (err) {
+ DPRINTF(1, "could not ref\n");
goto done;
}
if (fflags & FREAD) {
@@ -1062,6 +1090,9 @@
return (ENXIO);
}
fflags = fp->f_flag;
+
+ DPRINTF(1, "fflags=%u, cmd=0x%lx\n", fflags, cmd);
+
if ((fflags & FREAD) && (err == 0)) {
err = usb2_ioctl_f_sub(loc.rxfifo, cmd, addr, td);
if (err) {
@@ -1297,6 +1328,7 @@
f = loc.txfifo;
if (f == NULL) {
/* should not happen */
+ usb2_unref_device(&loc);
return (EPERM);
}
resid = uio->uio_resid;
@@ -1358,6 +1390,8 @@
done:
mtx_unlock(f->priv_mtx);
+ usb2_unref_device(&loc);
+
if ((flags & FOF_OFFSET) == 0)
fp->f_offset = uio->uio_offset;
fp->f_nextoff = uio->uio_offset;
@@ -1387,6 +1421,8 @@
int
usb2_fifo_wait(struct usb2_fifo *f)
{
+ int err;
+
mtx_assert(f->priv_mtx, MA_OWNED);
if (f->flag_iserror) {
@@ -1394,13 +1430,14 @@
return (EIO);
}
f->flag_sleeping = 1;
- cv_wait(&(f->cv_io), f->priv_mtx);
+
+ err = cv_wait_sig(&(f->cv_io), f->priv_mtx);
if (f->flag_iserror) {
/* we are gone */
- return (EIO);
+ err = EIO;
}
- return (0);
+ return (err);
}
void
More information about the p4-projects
mailing list