PERFORCE change 144451 for review

Hans Petter Selasky hselasky at FreeBSD.org
Tue Jul 1 23:43:00 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=144451

Change 144451 by hselasky at hselasky_laptop001 on 2008/07/01 23:42:40

	
	- Fix some synchronisation issues.
	- Remove a debug "usb2_pause_mtx()".
	- Add code to automatically decide if IOCTLs should
	  be merged or split when two USB FIFOs are opened
	  in Read+Write mode.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/controller/at91dci_atmelarm.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/ehci2_pci.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/ohci2_atmelarm.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/ohci2_pci.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/uhci2_pci.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/usb2_bus.h#2 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/usb2_controller.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/controller/uss820dci_pccard.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#7 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#5 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_hub.c#7 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#8 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/controller/at91dci_atmelarm.c#4 (text+ko) ====

@@ -210,7 +210,6 @@
 		goto error;
 	}
 	device_set_ivars(sc->sc_dci.sc_bus.bdev, &(sc->sc_dci.sc_bus));
-	device_set_softc(sc->sc_dci.sc_bus.bdev, &(sc->sc_dci.sc_bus));
 
 	err = usb2_config_td_setup(&(sc->sc_dci.sc_config_td), sc,
 	    &(sc->sc_dci.sc_bus.mtx), NULL, 0, 4);

==== //depot/projects/usb/src/sys/dev/usb2/controller/ehci2_pci.c#4 (text+ko) ====

@@ -287,7 +287,6 @@
 		goto error;
 	}
 	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-	device_set_softc(sc->sc_bus.bdev, &sc->sc_bus);
 
 	/*
 	 * ehci_pci_match will never return NULL if ehci_pci_probe

==== //depot/projects/usb/src/sys/dev/usb2/controller/ohci2_atmelarm.c#4 (text) ====

@@ -108,7 +108,6 @@
 		goto error;
 	}
 	device_set_ivars(sc->sc_ohci.sc_bus.bdev, &(sc->sc_ohci.sc_bus));
-	device_set_softc(sc->sc_ohci.sc_bus.bdev, &(sc->sc_ohci.sc_bus));
 
 	strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));
 

==== //depot/projects/usb/src/sys/dev/usb2/controller/ohci2_pci.c#4 (text+ko) ====

@@ -235,7 +235,6 @@
 		goto error;
 	}
 	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-	device_set_softc(sc->sc_bus.bdev, &sc->sc_bus);
 
 	/*
 	 * ohci_pci_match will never return NULL if ohci_pci_probe

==== //depot/projects/usb/src/sys/dev/usb2/controller/uhci2_pci.c#4 (text+ko) ====

@@ -288,7 +288,6 @@
 		goto error;
 	}
 	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-	device_set_softc(sc->sc_bus.bdev, &sc->sc_bus);
 
 	/*
 	 * uhci_pci_match must never return NULL if uhci_pci_probe

==== //depot/projects/usb/src/sys/dev/usb2/controller/usb2_bus.h#2 (text+ko) ====

@@ -75,7 +75,6 @@
 	uint8_t	usbrev;			/* USB revision. See "USB_REV_XXX". */
 
 	uint8_t	devices_max;		/* maximum number of USB devices */
-	uint8_t	ready;			/* set when USB BUS is ready */
 	uint8_t	do_probe;		/* set if USB BUS should be re-probed */
 
 	union {

==== //depot/projects/usb/src/sys/dev/usb2/controller/usb2_controller.c#4 (text+ko) ====

@@ -50,7 +50,6 @@
 
 static void usb2_attach_sub(device_t dev, struct usb2_bus *bus);
 static void usb2_post_init(void *arg);
-static void usb2_bus_init(void *arg);
 static void usb2_bus_mem_flush_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
 static void usb2_bus_mem_alloc_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
 static void usb2_bus_mem_free_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
@@ -112,19 +111,20 @@
 static int
 usb2_attach(device_t dev)
 {
-	struct usb2_bus *bus = device_get_softc(dev);
+	struct usb2_bus *bus = device_get_ivars(dev);
 
 	DPRINTF(0, "\n");
 
-	mtx_lock(&Giant);
+	if (bus == NULL) {
+		DPRINTF(-1, "USB device has no ivars\n");
+		return (ENXIO);
+	}
 	if (usb2_post_init_called) {
 		mtx_lock(&Giant);
 		usb2_attach_sub(dev, bus);
 		mtx_unlock(&Giant);
 		usb2_needs_explore(bus, 1);
 	}
-	mtx_unlock(&Giant);
-
 	return (0);			/* return success */
 }
 
@@ -138,6 +138,10 @@
 
 	DPRINTF(0, "\n");
 
+	if (bus == NULL) {
+		/* was never setup properly */
+		return (0);
+	}
 	/* Let the USB explore process detach all devices. */
 
 	mtx_lock(&(bus->mtx));
@@ -156,9 +160,6 @@
 
 	usb2_proc_unsetup(&(bus->explore_proc));
 
-	/* clear the softc */
-	device_set_softc(dev, NULL);
-
 	return (0);
 }
 
@@ -218,8 +219,10 @@
 	bus = ((struct usb2_bus_msg *)pm)->bus;
 	udev = bus->devices[USB_ROOT_HUB_ADDR];
 	dev = bus->bdev;
+	/* clear the softc */
+	device_set_softc(dev, NULL);
+	/* clear bdev variable */
 	bus->bdev = NULL;
-	bus->ready = 0;
 
 	mtx_unlock(&(bus->mtx));
 	mtx_lock(&Giant);
@@ -231,7 +234,9 @@
 	 * Free USB Root device, but not any sub-devices, hence they
 	 * are freed by the caller of this function:
 	 */
+	sx_xlock(udev->default_sx + 1);
 	usb2_detach_device(udev, USB_IFACE_INDEX_ANY, 0);
+	sx_unlock(udev->default_sx + 1);
 	usb2_free_device(udev);
 
 	mtx_unlock(&Giant);
@@ -320,8 +325,8 @@
 	    &(bus->mtx), USB_PRI_MED)) {
 		printf("WARNING: Creation of USB explore process failed.\n");
 	}
-	/* set ready flag */
-	bus->ready = 1;
+	/* set softc - we are ready */
+	device_set_softc(dev, bus);
 	return;
 }
 
@@ -342,16 +347,20 @@
 
 	mtx_lock(&Giant);
 
+	usb2_devclass_ptr = devclass_find("usbus");
+
 	dc = usb2_devclass_ptr;
 	if (dc) {
 		max = devclass_get_maxunit(dc) + 1;
 		for (n = 0; n != max; n++) {
 			dev = devclass_get_device(dc, n);
 			if (dev && device_is_attached(dev)) {
-				bus = device_get_softc(dev);
-				mtx_lock(&Giant);
-				usb2_attach_sub(dev, bus);
-				mtx_unlock(&Giant);
+				bus = device_get_ivars(dev);
+				if (bus) {
+					mtx_lock(&Giant);
+					usb2_attach_sub(dev, bus);
+					mtx_unlock(&Giant);
+				}
 			}
 		}
 	} else {
@@ -369,21 +378,6 @@
 }
 
 SYSINIT(usb2_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb2_post_init, NULL);
-
-/*------------------------------------------------------------------------*
- *	usb2_bus_init
- *
- * This function is called before the USB system is started.
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_init(void *arg)
-{
-	/* register our devclass */
-	usb2_devclass_ptr = devclass_find("usbus");
-	return;
-}
-
-SYSINIT(usb2_bus_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, usb2_bus_init, NULL);
 SYSUNINIT(usb2_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb2_bus_unload, NULL);
 
 /*------------------------------------------------------------------------*

==== //depot/projects/usb/src/sys/dev/usb2/controller/uss820dci_pccard.c#4 (text+ko) ====

@@ -189,7 +189,6 @@
 		goto error;
 	}
 	device_set_ivars(sc->sc_bus.bdev, &(sc->sc_bus));
-	device_set_softc(sc->sc_bus.bdev, &(sc->sc_bus));
 
 	err = usb2_config_td_setup(&(sc->sc_config_td), sc,
 	    &(sc->sc_bus.mtx), NULL, 0, 4);

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#7 (text+ko) ====

@@ -314,10 +314,6 @@
 		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;
@@ -941,7 +937,11 @@
 		return;
 	}
 	if (usb2_last_devloc != (uint32_t)(0 - 1)) {
-		DPRINTF(-1, "Clone race!\n");
+		/*
+		 * XXX can we assume that the clone and open operation is
+		 * atomic ?
+		 */
+		DPRINTF(1, "Clone race!\n");
 	}
 	usb2_last_devloc = usb2_path_convert(name +
 	    sizeof(USB_DEVICE_NAME) - 1);
@@ -1083,7 +1083,10 @@
 {
 	struct usb2_location loc;
 	int fflags;
+	int err_rx;
+	int err_tx;
 	int err;
+	uint8_t is_common = 0;
 
 	err = usb2_ref_device(fp, &loc, 0);;
 	if (err) {
@@ -1093,19 +1096,49 @@
 
 	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) {
-			err = (loc.rxfifo->methods->f_ioctl) (
-			    loc.rxfifo, cmd, addr, fflags & ~FWRITE, td);
+	if (fflags & FREAD) {
+		if (fflags & FWRITE) {
+			/*
+			 * Automagically figure out if we have an IOCTL that
+			 * should not be replicated to both FIFOs:
+			 */
+			if ((loc.rxfifo->priv_sc0 ==
+			    loc.txfifo->priv_sc0) &&
+			    (loc.rxfifo->priv_sc1 ==
+			    loc.txfifo->priv_sc1) &&
+			    (loc.rxfifo->methods ==
+			    loc.txfifo->methods)) {
+				is_common = 1;
+			}
+		}
+		err_rx = usb2_ioctl_f_sub(loc.rxfifo, cmd, addr, td);
+		if (err_rx == ENOTTY) {
+			err_rx = (loc.rxfifo->methods->f_ioctl) (
+			    loc.rxfifo, cmd, addr,
+			    is_common ? fflags : (fflags & ~FWRITE), td);
 		}
+	} else {
+		err_rx = 0;
 	}
-	if ((fflags & FWRITE) && (err == 0)) {
-		err = usb2_ioctl_f_sub(loc.txfifo, cmd, addr, td);
-		if (err) {
-			err = (loc.txfifo->methods->f_ioctl) (
-			    loc.txfifo, cmd, addr, fflags & ~FREAD, td);
+	if (fflags & FWRITE) {
+		err_tx = usb2_ioctl_f_sub(loc.txfifo, cmd, addr, td);
+		if (err_tx == ENOTTY) {
+			if (is_common)
+				err_tx = 0;	/* already handled this IOCTL */
+			else
+				err_tx = (loc.txfifo->methods->f_ioctl) (
+				    loc.txfifo, cmd, addr, fflags & ~FREAD, td);
 		}
+	} else {
+		err_tx = 0;
+	}
+
+	if (err_rx) {
+		err = err_rx;
+	} else if (err_tx) {
+		err = err_tx;
+	} else {
+		err = 0;		/* no error */
 	}
 	usb2_unref_device(&loc);
 	return (err);

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#5 (text+ko) ====

@@ -571,9 +571,6 @@
 				DPRINTF(0, "characteristics=0x%04x\n",
 				    UGETW(hd.wHubCharacteristics));
 			} else {
-
-				usb2_pause_mtx(&Giant, 100);
-
 				err = usb2_req_get_device_status
 				    (udev, &Giant, &ds);
 				if (err) {

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_hub.c#7 (text+ko) ====

@@ -1282,8 +1282,8 @@
 {
 	DPRINTF(0, "\n");
 
-	if (bus->ready == 0) {
-		DPRINTF(0, "BUS is not ready\n");
+	if (bus == NULL) {
+		DPRINTF(0, "No bus pointer!\n");
 		return;
 	}
 	mtx_lock(&(bus->mtx));

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#8 (text+ko) ====

@@ -1885,6 +1885,14 @@
 		if (pq->curr == xfer) {
 			/* start the next USB transfer, if any */
 			usb2_command_wrapper(pq, NULL);
+
+			if (pq->curr || TAILQ_FIRST(&(pq->head))) {
+				/* there is another USB transfer waiting */
+			} else {
+				/* this is the last USB transfer */
+				/* clear isochronous sync flag */
+				xfer->pipe->is_synced = 0;
+			}
 		}
 	}
 	/* keep some statistics */
@@ -1896,13 +1904,6 @@
 		    [xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
 	}
 
-	/*
-	 * if this is the last USB transfer on the PIPE queue we are no
-	 * longer synced:
-	 */
-	if (TAILQ_FIRST(&(xfer->pipe->pipe_q.head)) == NULL) {
-		xfer->pipe->is_synced = 0;
-	}
 	/* call the USB transfer callback */
 	usb2_command_wrapper(&(xfer->usb2_root->done_q), xfer);
 	return;


More information about the p4-projects mailing list