Commit 25810b20 authored by ROOL's avatar ROOL :robot:
Browse files

Add support for HC with hardware enumerate phase

Detail:
  Support controllers such as the XHCI which perform some steps of enumeration themselves in hardware, thereby needing some steps of the software enumeration to be bypassed.
  usb.c:
    Internally permit addr of 0, to represent the root hub, since the controller is responsible for allocating 1+. Merged from NetBSD 1.144.
  usb_subr.c:
    Test pointers against NULL not 0. Merged from NetBSD 1.191.
    Add 4 new bus methods, for prior to enumeration, address assignment phase, post enumeration fixup, and device removal.
  usbdivar.h:
    Prototypes of 4 new bus methods.
Admin:
  HC API version number bumped.
  Submission from Elesar.

Version 1.08. Tagged as 'NetBSD-1_08'
parent 3ced0223
/* (1.07) /* (1.08)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1. * Last processed by srccommit version: 1.1.
* *
*/ */
#define Module_MajorVersion_CMHG 1.07 #define Module_MajorVersion_CMHG 1.08
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 12 Nov 2015 #define Module_Date_CMHG 15 Nov 2015
#define Module_MajorVersion "1.07" #define Module_MajorVersion "1.08"
#define Module_Version 107 #define Module_Version 108
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "12 Nov 2015" #define Module_Date "15 Nov 2015"
#define Module_ApplicationDate "12-Nov-15" #define Module_ApplicationDate "15-Nov-15"
#define Module_ComponentName "NetBSD" #define Module_ComponentName "NetBSD"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/NetBSD" #define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/NetBSD"
#define Module_FullVersion "1.07" #define Module_FullVersion "1.08"
#define Module_HelpVersion "1.07 (12 Nov 2015)" #define Module_HelpVersion "1.08 (15 Nov 2015)"
#define Module_LibraryVersionInfo "1:7" #define Module_LibraryVersionInfo "1:8"
...@@ -29,7 +29,7 @@ SWIClass SETS USBDriverSWI_Name ...@@ -29,7 +29,7 @@ SWIClass SETS USBDriverSWI_Name
AddSWI USBDriver_Version AddSWI USBDriver_Version
; The structures in the 4 exported headers ; The structures in the 4 exported headers
; NetBSD/dev/usb/h/usb NetBSD/dev/usb/h/usbvar ; NetBSD/dev/usb/h/usb NetBSD/dev/usb/h/usbdivar
; NetBSD/dev/usb/h/usbdi NetBSD/dev/usb/h/usb_port ; NetBSD/dev/usb/h/usbdi NetBSD/dev/usb/h/usb_port
; are used by the USB host controller drivers to communicate with the main ; are used by the USB host controller drivers to communicate with the main
; USBDriver module. Thus, we need to make sure that they only register ; USBDriver module. Thus, we need to make sure that they only register
...@@ -38,7 +38,7 @@ SWIClass SETS USBDriverSWI_Name ...@@ -38,7 +38,7 @@ SWIClass SETS USBDriverSWI_Name
; structures, make sure you update this API version to the version of the ; structures, make sure you update this API version to the version of the
; USBDriver module that first implemented those changes (not the dummy value ; USBDriver module that first implemented those changes (not the dummy value
; in VersionNum file!). ; in VersionNum file!).
RISCOS_USBDRIVER_API_VERSION * 76 RISCOS_USBDRIVER_API_VERSION * 80
OPT OldOpt OPT OldOpt
END END
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
#define EHCIDriverModule_Module_Date_CMHG 04 Nov 2015 #define EHCIDriverModule_Module_Date_CMHG 04 Nov 2015
#define EHCIDriverModule_MajorVersion_CMHG 0.29 #define EHCIDriverModule_MajorVersion_CMHG 0.29
#define USBDriverModule_Module_Date_CMHG 12 Nov 2015 #define USBDriverModule_Module_Date_CMHG 15 Nov 2015
#define USBDriverModule_MajorVersion_CMHG 0.79 #define USBDriverModule_MajorVersion_CMHG 0.80
...@@ -610,15 +610,14 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p) ...@@ -610,15 +610,14 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
case USB_DEVICEINFO: case USB_DEVICEINFO:
{ {
usbd_device_handle dev;
struct usb_device_info *di = (void *)data; struct usb_device_info *di = (void *)data;
int addr = di->udi_addr; int addr = di->udi_addr;
usbd_device_handle dev;
if (addr < 1 || addr >= USB_MAX_DEVICES) if (addr < 0 || addr >= USB_MAX_DEVICES)
return (EINVAL); return (EINVAL);
dev = sc->sc_bus->devices[addr]; if ((dev = sc->sc_bus->devices[addr]) == NULL)
if (dev == NULL) return ENXIO;
return (ENXIO);
usbd_fill_deviceinfo(dev, di, 1); usbd_fill_deviceinfo(dev, di, 1);
break; break;
} }
......
...@@ -897,7 +897,7 @@ usbd_getnewaddr(usbd_bus_handle bus) ...@@ -897,7 +897,7 @@ usbd_getnewaddr(usbd_bus_handle bus)
int addr; int addr;
for (addr = 1; addr < USB_MAX_DEVICES; addr++) for (addr = 1; addr < USB_MAX_DEVICES; addr++)
if (bus->devices[addr] == 0) if (bus->devices[addr] == NULL)
return (addr); return (addr);
return (-1); return (-1);
} }
...@@ -1140,12 +1140,6 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1140,12 +1140,6 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n", DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
bus, port, depth, speed)); bus, port, depth, speed));
addr = usbd_getnewaddr(bus);
if (addr < 0) {
printf("%s: No free USB addresses, new device ignored.\n",
USBDEVNAME(bus->bdev));
return (USBD_NO_ADDR);
}
dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO); dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
if (dev == NULL) if (dev == NULL)
...@@ -1177,7 +1171,7 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1177,7 +1171,7 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
dev->def_ep_desc.bInterval = 0; dev->def_ep_desc.bInterval = 0;
/* doesn't matter, just don't let it uninitialized */ /* doesn't matter, just don't leave it uninitialized */
dev->def_ep.datatoggle = 0; dev->def_ep.datatoggle = 0;
dev->quirks = &usbd_no_quirk; dev->quirks = &usbd_no_quirk;
...@@ -1226,6 +1220,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1226,6 +1220,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (err); return (err);
} }
/* Do any bus specific preparation */
if (bus->methods->new_device_pre != NULL) {
err = bus->methods->new_device_pre(dev);
if (err) {
usbd_remove_device(dev, up);
return (err);
}
}
dd = &dev->ddesc; dd = &dev->ddesc;
/* Try a few times in case the device is slow (i.e. outside specs.) */ /* Try a few times in case the device is slow (i.e. outside specs.) */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
...@@ -1244,10 +1247,25 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1244,10 +1247,25 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (err); return (err);
} }
/* Windows resets the port here, do likewise */ /* Windows resets the port here to work around problematic LS & FS
* devices that get upset by the initial device descriptor read
* followed by another one once addressed, do likewise.
*/
if (up->parent) if (up->parent)
usbd_reset_port(up->parent, port, &ps); usbd_reset_port(up->parent, port, &ps);
/* Pick a free address on this bus segment */
if (bus->methods->new_device_addr != NULL)
addr = bus->methods->new_device_addr(dev); /* Also sets MPS for EP0 */
else
addr = usbd_getnewaddr(bus);
if (addr < 0) {
printf("%s: No free USB addresses, new device ignored.\n",
USBDEVNAME(bus->bdev));
usbd_remove_device(dev, up);
return (USBD_NO_ADDR);
}
if (speed == USB_SPEED_HIGH) { if (speed == USB_SPEED_HIGH) {
/* Max packet size must be 64 (sec 5.5.3). */ /* Max packet size must be 64 (sec 5.5.3). */
if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) { if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
...@@ -1280,6 +1298,12 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1280,6 +1298,12 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (USBD_INVAL); return (USBD_INVAL);
} }
/* 4.8.2.1 */
if (speed == USB_SPEED_SUPER)
USETW(dev->def_ep_desc.wMaxPacketSize, (1 << dd->bMaxPacketSize));
else
USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
DPRINTFN(5, ("bMaxPacketSize %u", dd->bMaxPacketSize));
USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
/* Re-establish the default pipe with the new MPS. */ /* Re-establish the default pipe with the new MPS. */
...@@ -1299,6 +1323,9 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1299,6 +1323,9 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
/* Set the address */ /* Set the address */
DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr)); DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr));
if (bus->methods->new_device_addr != NULL)
err = USBD_NORMAL_COMPLETION; /* Set earlier */
else
err = usbd_set_address(dev, addr); err = usbd_set_address(dev, addr);
if (err) { if (err) {
DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr)); DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr));
...@@ -1354,6 +1381,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, ...@@ -1354,6 +1381,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (err); return (err);
} }
/* Do any bus specific tidying now everything is known */
if (bus->methods->new_device_post != NULL) {
err = bus->methods->new_device_post(dev);
if (err) {
usbd_remove_device(dev, up);
return (err);
}
}
return (USBD_NORMAL_COMPLETION); return (USBD_NORMAL_COMPLETION);
} }
...@@ -1381,6 +1417,8 @@ usbd_remove_device(usbd_device_handle dev, struct usbd_port *up) ...@@ -1381,6 +1417,8 @@ usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
if (dev->default_pipe != NULL) if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe); usbd_kill_pipe(dev->default_pipe);
up->device = NULL; up->device = NULL;
if (dev->bus->methods->remove_device != NULL)
dev->bus->methods->remove_device(dev);
dev->bus->devices[dev->address] = NULL; dev->bus->devices[dev->address] = NULL;
free(dev, M_USB); free(dev, M_USB);
...@@ -1614,6 +1652,8 @@ usb_disconnect_port(struct usbd_port *up, device_ptr_t parent) ...@@ -1614,6 +1652,8 @@ usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
} }
usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev); usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
if (dev->bus->methods->remove_device != NULL)
dev->bus->methods->remove_device(dev);
dev->bus->devices[dev->address] = NULL; dev->bus->devices[dev->address] = NULL;
up->device = NULL; up->device = NULL;
usb_free_device(dev); usb_free_device(dev);
......
...@@ -74,6 +74,10 @@ struct usbd_bus_methods { ...@@ -74,6 +74,10 @@ struct usbd_bus_methods {
void (*freem)(struct usbd_bus *, usb_dma_t *); void (*freem)(struct usbd_bus *, usb_dma_t *);
struct usbd_xfer * (*allocx)(struct usbd_bus *); struct usbd_xfer * (*allocx)(struct usbd_bus *);
void (*freex)(struct usbd_bus *, struct usbd_xfer *); void (*freex)(struct usbd_bus *, struct usbd_xfer *);
usbd_status (*new_device_pre)(usbd_device_handle);
int (*new_device_addr)(usbd_device_handle);
usbd_status (*new_device_post)(usbd_device_handle);
void (*remove_device)(usbd_device_handle);
#ifdef USBHAL #ifdef USBHAL
int (*do_intr)(struct usbd_bus *,int irqdevno); int (*do_intr)(struct usbd_bus *,int irqdevno);
void (*shutdown)(struct usbd_bus *); void (*shutdown)(struct usbd_bus *);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment