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'
/* (1.07)
/* (1.08)
*
* This file is automatically maintained by srccommit, do not edit manually.
* 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_Date_CMHG 12 Nov 2015
#define Module_Date_CMHG 15 Nov 2015
#define Module_MajorVersion "1.07"
#define Module_Version 107
#define Module_MajorVersion "1.08"
#define Module_Version 108
#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_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/NetBSD"
#define Module_FullVersion "1.07"
#define Module_HelpVersion "1.07 (12 Nov 2015)"
#define Module_LibraryVersionInfo "1:7"
#define Module_FullVersion "1.08"
#define Module_HelpVersion "1.08 (15 Nov 2015)"
#define Module_LibraryVersionInfo "1:8"
......@@ -29,7 +29,7 @@ SWIClass SETS USBDriverSWI_Name
AddSWI USBDriver_Version
; 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
; 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
......@@ -38,7 +38,7 @@ SWIClass SETS USBDriverSWI_Name
; structures, make sure you update this API version to the version of the
; USBDriver module that first implemented those changes (not the dummy value
; in VersionNum file!).
RISCOS_USBDRIVER_API_VERSION * 76
RISCOS_USBDRIVER_API_VERSION * 80
OPT OldOpt
END
......@@ -8,5 +8,5 @@
#define EHCIDriverModule_Module_Date_CMHG 04 Nov 2015
#define EHCIDriverModule_MajorVersion_CMHG 0.29
#define USBDriverModule_Module_Date_CMHG 12 Nov 2015
#define USBDriverModule_MajorVersion_CMHG 0.79
#define USBDriverModule_Module_Date_CMHG 15 Nov 2015
#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)
case USB_DEVICEINFO:
{
usbd_device_handle dev;
struct usb_device_info *di = (void *)data;
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);
dev = sc->sc_bus->devices[addr];
if (dev == NULL)
return (ENXIO);
if ((dev = sc->sc_bus->devices[addr]) == NULL)
return ENXIO;
usbd_fill_deviceinfo(dev, di, 1);
break;
}
......
......@@ -897,7 +897,7 @@ usbd_getnewaddr(usbd_bus_handle 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);
}
......@@ -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",
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);
if (dev == NULL)
......@@ -1177,7 +1171,7 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
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->quirks = &usbd_no_quirk;
......@@ -1226,6 +1220,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
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;
/* Try a few times in case the device is slow (i.e. outside specs.) */
for (i = 0; i < 10; i++) {
......@@ -1244,10 +1247,25 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
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)
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) {
/* Max packet size must be 64 (sec 5.5.3). */
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,
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);
/* Re-establish the default pipe with the new MPS. */
......@@ -1299,7 +1323,10 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
/* Set the address */
DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr));
err = usbd_set_address(dev, addr);
if (bus->methods->new_device_addr != NULL)
err = USBD_NORMAL_COMPLETION; /* Set earlier */
else
err = usbd_set_address(dev, addr);
if (err) {
DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr));
err = USBD_SET_ADDR_FAILED;
......@@ -1354,6 +1381,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
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);
}
......@@ -1381,6 +1417,8 @@ usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe);
up->device = NULL;
if (dev->bus->methods->remove_device != NULL)
dev->bus->methods->remove_device(dev);
dev->bus->devices[dev->address] = NULL;
free(dev, M_USB);
......@@ -1614,6 +1652,8 @@ usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
}
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;
up->device = NULL;
usb_free_device(dev);
......
......@@ -74,6 +74,10 @@ struct usbd_bus_methods {
void (*freem)(struct usbd_bus *, usb_dma_t *);
struct usbd_xfer * (*allocx)(struct usbd_bus *);
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
int (*do_intr)(struct usbd_bus *,int irqdevno);
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