Date: Tue, 1 Jul 2008 21:41:51 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 144443 for review Message-ID: <200807012141.m61Lfpr6091042@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=144443 Change 144443 by hselasky@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807012141.m61Lfpr6091042>