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