From 2670b664800e3af0d1f17d6d3c2a828d75b03cae Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Wed, 9 Jul 2014 15:47:55 +0000 Subject: Adds an optional bus function to set the address of a new device and 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 | 3 ++- sys/dev/usb/ohci.c | 3 ++- sys/dev/usb/uhci.c | 3 ++- sys/dev/usb/usb_subr.c | 48 ++++++++++++++++++++++++++++++------------------ sys/dev/usb/usbdi_util.c | 15 +-------------- sys/dev/usb/usbdi_util.h | 3 +-- sys/dev/usb/usbdivar.h | 4 +++- 7 files changed, 41 insertions(+), 38 deletions(-) (limited to 'sys/dev/usb') diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index 568ccebc6d9..6c4419ea88d 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -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, diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 97b04e5945f..6b99c55826a 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -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, diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 51706c7ff2e..dcb0d9cc673 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -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, diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 6e25e3238a9..eadf5b498d7 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -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); diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c index d80c7612bd0..50629ab82c3 100644 --- a/sys/dev/usb/usbdi_util.c +++ b/sys/dev/usb/usbdi_util.c @@ -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) { diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h index f33b0dcbfe5..b79622a6a90 100644 --- a/sys/dev/usb/usbdi_util.h +++ b/sys/dev/usb/usbdi_util.h @@ -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); diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index 7cbeaafbe53..18ae5067776 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -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); -- cgit v1.2.3