Adds an optional bus function to set the address of a new device and
authormpi <mpi@openbsd.org>
Wed, 9 Jul 2014 15:47:54 +0000 (15:47 +0000)
committermpi <mpi@openbsd.org>
Wed, 9 Jul 2014 15:47:54 +0000 (15:47 +0000)
explicitly set it when required.

Right now xhci(4) does not need such function because it assigns
addresses when the first pipe of a device is opened.

ok yuo@, pirofti@

sys/dev/usb/ehci.c
sys/dev/usb/ohci.c
sys/dev/usb/uhci.c
sys/dev/usb/usb_subr.c
sys/dev/usb/usbdi_util.c
sys/dev/usb/usbdi_util.h
sys/dev/usb/usbdivar.h

index 568cceb..6c4419e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ehci.c,v 1.158 2014/06/04 13:52:30 mpi Exp $ */
+/*     $OpenBSD: ehci.c,v 1.159 2014/07/09 15:47:54 mpi Exp $ */
 /*     $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $        */
 
 /*
@@ -216,6 +216,7 @@ void                ehci_dump_exfer(struct ehci_xfer *);
 
 struct usbd_bus_methods ehci_bus_methods = {
        .open_pipe = ehci_open,
+       .dev_setaddr = usbd_set_address,
        .soft_intr = ehci_softintr,
        .do_poll = ehci_poll,
        .allocx = ehci_allocx,
index 97b04e5..6b99c55 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ohci.c,v 1.133 2014/06/04 13:52:30 mpi Exp $ */
+/*     $OpenBSD: ohci.c,v 1.134 2014/07/09 15:47:54 mpi Exp $ */
 /*     $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $       */
 /*     $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $       */
 
@@ -232,6 +232,7 @@ struct ohci_pipe {
 
 struct usbd_bus_methods ohci_bus_methods = {
        .open_pipe = ohci_open,
+       .dev_setaddr = usbd_set_address,
        .soft_intr = ohci_softintr,
        .do_poll = ohci_poll,
        .allocx = ohci_allocx,
index 51706c7..dcb0d9c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uhci.c,v 1.124 2014/06/04 13:52:30 mpi Exp $  */
+/*     $OpenBSD: uhci.c,v 1.125 2014/07/09 15:47:54 mpi Exp $  */
 /*     $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $        */
 /*     $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $       */
 
@@ -250,6 +250,7 @@ UREAD4(struct uhci_softc *sc, bus_size_t r)
 
 struct usbd_bus_methods uhci_bus_methods = {
        .open_pipe = uhci_open,
+       .dev_setaddr = usbd_set_address,
        .soft_intr = uhci_softintr,
        .do_poll = uhci_poll,
        .allocx = uhci_allocx,
index 6e25e32..eadf5b4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usb_subr.c,v 1.100 2014/03/08 11:42:56 mpi Exp $ */
+/*     $OpenBSD: usb_subr.c,v 1.101 2014/07/09 15:47:54 mpi Exp $ */
 /*     $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $  */
 /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $   */
 
@@ -815,13 +815,35 @@ usbd_setup_pipe(struct usbd_device *dev, struct usbd_interface *iface,
        return (USBD_NORMAL_COMPLETION);
 }
 
+int
+usbd_set_address(struct usbd_device *dev, int addr)
+{
+       usb_device_request_t req;
+
+       req.bmRequestType = UT_WRITE_DEVICE;
+       req.bRequest = UR_SET_ADDRESS;
+       USETW(req.wValue, addr);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+       if (usbd_do_request(dev, &req, 0))
+               return (1);
+
+       dev->address = addr;
+       dev->bus->devices[addr] = dev;
+
+       /* Allow device time to set new address */
+       usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
+
+       return (0);
+}
+
 int
 usbd_getnewaddr(struct usbd_bus *bus)
 {
        int addr;
 
        for (addr = 1; addr < USB_MAX_DEVICES; addr++)
-               if (bus->devices[addr] == 0)
+               if (bus->devices[addr] == NULL)
                        return (addr);
        return (-1);
 }
@@ -1167,26 +1189,16 @@ usbd_new_device(struct device *parent, struct usbd_bus *bus, int depth,
 
        err = usbd_reload_device_desc(dev);
        if (err) {
-               DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
-                   "failed\n", addr));
                usb_free_device(dev, up);
                return (err);
        }
 
-       /* Set the address. */
-       DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
-       err = usbd_set_address(dev, addr);
-       if (err) {
-               DPRINTFN(-1,("usbd_new_device: set address %d failed\n", addr));
-               err = USBD_SET_ADDR_FAILED;
-               usb_free_device(dev, up);
-               return (err);
-       }
-
-       /* Allow device time to set new address */
-       usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
-       dev->address = addr;    /* New device address now */
-       bus->devices[addr] = dev;
+       /* Set the address if the HC didn't do it already. */
+       if (bus->methods->dev_setaddr != NULL &&
+           bus->methods->dev_setaddr(dev, addr)) {
+               usb_free_device(dev, up);
+               return (USBD_SET_ADDR_FAILED);
+       }
 
        /* Re-establish the default pipe with the new address. */
        usbd_close_pipe(dev->default_pipe);
index d80c761..50629ab 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdi_util.c,v 1.36 2014/04/24 09:40:28 mpi Exp $ */
+/*     $OpenBSD: usbdi_util.c,v 1.37 2014/07/09 15:47:54 mpi Exp $ */
 /*     $NetBSD: usbdi_util.c,v 1.40 2002/07/11 21:14:36 augustss Exp $ */
 /*     $FreeBSD: src/sys/dev/usb/usbdi_util.c,v 1.14 1999/11/17 22:33:50 n_hibma Exp $ */
 
@@ -113,19 +113,6 @@ usbd_get_hub_descriptor(struct usbd_device *dev, usb_hub_descriptor_t *hd,
        return (usbd_do_request(dev, &req, hd));
 }
 
-usbd_status
-usbd_set_address(struct usbd_device *dev, int addr)
-{
-       usb_device_request_t req;
-
-       req.bmRequestType = UT_WRITE_DEVICE;
-       req.bRequest = UR_SET_ADDRESS;
-       USETW(req.wValue, addr);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, 0);
-       return usbd_do_request(dev, &req, 0);
-}
-
 usbd_status
 usbd_get_port_status(struct usbd_device *dev, int port, usb_port_status_t *ps)
 {
index f33b0dc..b79622a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdi_util.h,v 1.25 2014/04/24 09:40:28 mpi Exp $ */
+/*     $OpenBSD: usbdi_util.h,v 1.26 2014/07/09 15:47:54 mpi Exp $ */
 /*     $NetBSD: usbdi_util.h,v 1.28 2002/07/11 21:14:36 augustss Exp $ */
 /*     $FreeBSD: src/sys/dev/usb/usbdi_util.h,v 1.9 1999/11/17 22:33:50 n_hibma Exp $  */
 
@@ -34,7 +34,6 @@
 
 usbd_status    usbd_get_desc(struct usbd_device *dev, int type,
                    int index, int len, void *desc);
-usbd_status    usbd_set_address(struct usbd_device *dev, int addr);
 usbd_status    usbd_get_port_status(struct usbd_device *,
                    int, usb_port_status_t *);
 usbd_status    usbd_set_hub_feature(struct usbd_device *dev, int);
index 7cbeaaf..18ae506 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdivar.h,v 1.59 2014/05/28 11:20:55 mpi Exp $ */
+/*     $OpenBSD: usbdivar.h,v 1.60 2014/07/09 15:47:54 mpi Exp $ */
 /*     $NetBSD: usbdivar.h,v 1.70 2002/07/11 21:14:36 augustss Exp $   */
 /*     $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $   */
 
@@ -55,6 +55,7 @@ struct usbd_endpoint {
 
 struct usbd_bus_methods {
        usbd_status           (*open_pipe)(struct usbd_pipe *);
+       int                   (*dev_setaddr)(struct usbd_device *, int);
        void                  (*soft_intr)(void *);
        void                  (*do_poll)(struct usbd_bus *);
        struct usbd_xfer *    (*allocx)(struct usbd_bus *);
@@ -237,6 +238,7 @@ usbd_status usbd_reset_port(struct usbd_device *,
 usbd_status    usbd_setup_pipe(struct usbd_device *,
                    struct usbd_interface *, struct usbd_endpoint *, int,
                    struct usbd_pipe **);
+int            usbd_set_address(struct usbd_device *, int);
 usbd_status    usbd_new_device(struct device *, struct usbd_bus *,
                    int, int, int, struct usbd_port *);
 usbd_status    usbd_fill_iface_data(struct usbd_device *, int, int);