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