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@
-/* $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 $ */
/*
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,
-/* $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 $ */
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,
-/* $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 $ */
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,
-/* $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 $ */
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);
}
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);
-/* $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 $ */
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)
{
-/* $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 $ */
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);
-/* $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 $ */
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 *);
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);