Skip site navigation (1)Skip section navigation (2)
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>