Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 3 | How USB works with driver model |
| 4 | =============================== |
| 5 | |
| 6 | Introduction |
| 7 | ------------ |
| 8 | |
| 9 | Driver model USB support makes use of existing features but changes how |
| 10 | drivers are found. This document provides some information intended to help |
| 11 | understand how things work with USB in U-Boot when driver model is enabled. |
| 12 | |
| 13 | |
| 14 | Enabling driver model for USB |
| 15 | ----------------------------- |
| 16 | |
| 17 | A new CONFIG_DM_USB option is provided to enable driver model for USB. This |
| 18 | causes the USB uclass to be included, and drops the equivalent code in |
| 19 | usb.c. In particular the usb_init() function is then implemented by the |
| 20 | uclass. |
| 21 | |
| 22 | |
| 23 | Support for EHCI and XHCI |
| 24 | ------------------------- |
| 25 | |
| 26 | So far OHCI is not supported. Both EHCI and XHCI drivers should be declared |
| 27 | as drivers in the USB uclass. For example: |
| 28 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 29 | .. code-block:: c |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 30 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 31 | static const struct udevice_id ehci_usb_ids[] = { |
| 32 | { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 }, |
| 33 | { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 }, |
| 34 | { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 }, |
| 35 | { } |
| 36 | }; |
| 37 | |
| 38 | U_BOOT_DRIVER(usb_ehci) = { |
| 39 | .name = "ehci_tegra", |
| 40 | .id = UCLASS_USB, |
| 41 | .of_match = ehci_usb_ids, |
| 42 | .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, |
| 43 | .probe = tegra_ehci_usb_probe, |
| 44 | .remove = tegra_ehci_usb_remove, |
| 45 | .ops = &ehci_usb_ops, |
| 46 | .platdata_auto_alloc_size = sizeof(struct usb_platdata), |
| 47 | .priv_auto_alloc_size = sizeof(struct fdt_usb), |
| 48 | .flags = DM_FLAG_ALLOC_PRIV_DMA, |
| 49 | }; |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 50 | |
| 51 | Here ehci_usb_ids is used to list the controllers that the driver supports. |
| 52 | Each has its own data value. Controllers must be in the UCLASS_USB uclass. |
| 53 | |
| 54 | The ofdata_to_platdata() method allows the controller driver to grab any |
| 55 | necessary settings from the device tree. |
| 56 | |
| 57 | The ops here are ehci_usb_ops. All EHCI drivers will use these same ops in |
| 58 | most cases, since they are all EHCI-compatible. For EHCI there are also some |
| 59 | special operations that can be overridden when calling ehci_register(). |
| 60 | |
| 61 | The driver can use priv_auto_alloc_size to set the size of its private data. |
| 62 | This can hold run-time information needed by the driver for operation. It |
| 63 | exists when the device is probed (not when it is bound) and is removed when |
| 64 | the driver is removed. |
| 65 | |
| 66 | Note that usb_platdata is currently only used to deal with setting up a bus |
| 67 | in USB device mode (OTG operation). It can be omitted if that is not |
| 68 | supported. |
| 69 | |
| 70 | The driver's probe() method should do the basic controller init and then |
| 71 | call ehci_register() to register itself as an EHCI device. It should call |
| 72 | ehci_deregister() in the remove() method. Registering a new EHCI device |
| 73 | does not by itself cause the bus to be scanned. |
| 74 | |
| 75 | The old ehci_hcd_init() function is no-longer used. Nor is it necessary to |
| 76 | set up the USB controllers from board init code. When 'usb start' is used, |
| 77 | each controller will be probed and its bus scanned. |
| 78 | |
| 79 | XHCI works in a similar way. |
| 80 | |
| 81 | |
| 82 | Data structures |
| 83 | --------------- |
| 84 | |
| 85 | The following primary data structures are in use: |
| 86 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 87 | - struct usb_device: |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 88 | This holds information about a device on the bus. All devices have |
| 89 | this structure, even the root hub. The controller itself does not |
| 90 | have this structure. You can access it for a device 'dev' with |
Simon Glass | de44acf | 2015-09-28 23:32:01 -0600 | [diff] [blame] | 91 | dev_get_parent_priv(dev). It matches the old structure except that the |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 92 | parent and child information is not present (since driver model |
| 93 | handles that). Once the device is set up, you can find the device |
| 94 | descriptor and current configuration descriptor in this structure. |
| 95 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 96 | - struct usb_platdata: |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 97 | This holds platform data for a controller. So far this is only used |
| 98 | as a work-around for controllers which can act as USB devices in OTG |
| 99 | mode, since the gadget framework does not use driver model. |
| 100 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 101 | - struct usb_dev_platdata: |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 102 | This holds platform data for a device. You can access it for a |
| 103 | device 'dev' with dev_get_parent_platdata(dev). It holds the device |
| 104 | address and speed - anything that can be determined before the device |
| 105 | driver is actually set up. When probing the bus this structure is |
| 106 | used to provide essential information to the device driver. |
| 107 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 108 | - struct usb_bus_priv: |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 109 | This is private information for each controller, maintained by the |
| 110 | controller uclass. It is mostly used to keep track of the next |
| 111 | device address to use. |
| 112 | |
| 113 | Of these, only struct usb_device was used prior to driver model. |
| 114 | |
| 115 | |
| 116 | USB buses |
| 117 | --------- |
| 118 | |
| 119 | Given a controller, you know the bus - it is the one attached to the |
| 120 | controller. Each controller handles exactly one bus. Every controller has a |
| 121 | root hub attached to it. This hub, which is itself a USB device, can provide |
| 122 | one or more 'ports' to which additional devices can be attached. It is |
| 123 | possible to power up a hub and find out which of its ports have devices |
| 124 | attached. |
| 125 | |
| 126 | Devices are given addresses starting at 1. The root hub is always address 1, |
| 127 | and from there the devices are numbered in sequence. The USB uclass takes |
| 128 | care of this numbering automatically during enumeration. |
| 129 | |
| 130 | USB devices are enumerated by finding a device on a particular hub, and |
| 131 | setting its address to the next available address. The USB bus stretches out |
| 132 | in a tree structure, potentially with multiple hubs each with several ports |
| 133 | and perhaps other hubs. Some hubs will have their own power since otherwise |
| 134 | the 5V 500mA power supplied by the controller will not be sufficient to run |
| 135 | very many devices. |
| 136 | |
| 137 | Enumeration in U-Boot takes a long time since devices are probed one at a |
| 138 | time, and each is given sufficient time to wake up and announce itself. The |
| 139 | timeouts are set for the slowest device. |
| 140 | |
| 141 | Up to 127 devices can be on each bus. USB has four bus speeds: low |
| 142 | (1.5Mbps), full (12Mbps), high (480Mbps) which is only available with USB2 |
| 143 | and newer (EHCI), and super (5Gbps) which is only available with USB3 and |
| 144 | newer (XHCI). If you connect a super-speed device to a high-speed hub, you |
| 145 | will only get high-speed. |
| 146 | |
| 147 | |
| 148 | USB operations |
| 149 | -------------- |
| 150 | |
| 151 | As before driver model, messages can be sent using submit_bulk_msg() and the |
| 152 | like. These are now implemented by the USB uclass and route through the |
| 153 | controller drivers. Note that messages are not sent to the driver of the |
| 154 | device itself - i.e. they don't pass down the stack to the controller. |
| 155 | U-Boot simply finds the controller to which the device is attached, and sends |
| 156 | the message there with an appropriate 'pipe' value so it can be addressed |
| 157 | properly. Having said that, the USB device which should receive the message |
| 158 | is passed in to the driver methods, for use by sandbox. This design decision |
| 159 | is open for review and the code impact of changing it is small since the |
| 160 | methods are typically implemented by the EHCI and XHCI stacks. |
| 161 | |
| 162 | Controller drivers (in UCLASS_USB) themselves provide methods for sending |
| 163 | each message type. For XHCI an additional alloc_device() method is provided |
| 164 | since XHCI needs to allocate a device context before it can even read the |
| 165 | device's descriptor. |
| 166 | |
| 167 | These methods use a 'pipe' which is a collection of bit fields used to |
| 168 | describe the type of message, direction of transfer and the intended |
| 169 | recipient (device number). |
| 170 | |
| 171 | |
| 172 | USB Devices |
| 173 | ----------- |
| 174 | |
| 175 | USB devices are found using a simple algorithm which works through the |
| 176 | available hubs in a depth-first search. Devices can be in any uclass, but |
| 177 | are attached to a parent hub (or controller in the case of the root hub) and |
| 178 | so have parent data attached to them (this is struct usb_device). |
| 179 | |
| 180 | By the time the device's probe() method is called, it is enumerated and is |
| 181 | ready to talk to the host. |
| 182 | |
| 183 | The enumeration process needs to work out which driver to attach to each USB |
| 184 | device. It does this by examining the device class, interface class, vendor |
| 185 | ID, product ID, etc. See struct usb_driver_entry for how drivers are matched |
| 186 | with USB devices - you can use the USB_DEVICE() macro to declare a USB |
| 187 | driver. For example, usb_storage.c defines a USB_DEVICE() to handle storage |
| 188 | devices, and it will be used for all USB devices which match. |
| 189 | |
| 190 | |
| 191 | |
| 192 | Technical details on enumeration flow |
| 193 | ------------------------------------- |
| 194 | |
| 195 | It is useful to understand precisely how a USB bus is enumerating to avoid |
| 196 | confusion when dealing with USB devices. |
| 197 | |
| 198 | Device initialisation happens roughly like this: |
| 199 | |
| 200 | - At some point the 'usb start' command is run |
| 201 | - This calls usb_init() which works through each controller in turn |
| 202 | - The controller is probed(). This does no enumeration. |
| 203 | - Then usb_scan_bus() is called. This calls usb_scan_device() to scan the |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 204 | (only) device that is attached to the controller - a root hub |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 205 | - usb_scan_device() sets up a fake struct usb_device and calls |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 206 | usb_setup_device(), passing the port number to be scanned, in this case |
| 207 | port 0 |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 208 | - usb_setup_device() first calls usb_prepare_device() to set the device |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 209 | address, then usb_select_config() to select the first configuration |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 210 | - at this point the device is enumerated but we do not have a real struct |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 211 | udevice for it. But we do have the descriptor in struct usb_device so we can |
| 212 | use this to figure out what driver to use |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 213 | - back in usb_scan_device(), we call usb_find_child() to try to find an |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 214 | existing device which matches the one we just found on the bus. This can |
| 215 | happen if the device is mentioned in the device tree, or if we previously |
| 216 | scanned the bus and so the device was created before |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 217 | - if usb_find_child() does not find an existing device, we call |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 218 | usb_find_and_bind_driver() which tries to bind one |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 219 | - usb_find_and_bind_driver() searches all available USB drivers (declared |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 220 | with USB_DEVICE()). If it finds a match it binds that driver to create a |
| 221 | new device. |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 222 | - If it does not, it binds a generic driver. A generic driver is good enough |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 223 | to allow access to the device (sending it packets, etc.) but all |
| 224 | functionality will need to be implemented outside the driver model. |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 225 | - in any case, when usb_find_child() and/or usb_find_and_bind_driver() are |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 226 | done, we have a device with the correct uclass. At this point we want to |
| 227 | probe the device |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 228 | - first we store basic information about the new device (address, port, |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 229 | speed) in its parent platform data. We cannot store it its private data |
| 230 | since that will not exist until the device is probed. |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 231 | - then we call device_probe() which probes the device |
| 232 | - the first probe step is actually the USB controller's (or USB hubs's) |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 233 | child_pre_probe() method. This gets called before anything else and is |
| 234 | intended to set up a child device ready to be used with its parent bus. For |
| 235 | USB this calls usb_child_pre_probe() which grabs the information that was |
| 236 | stored in the parent platform data and stores it in the parent private data |
| 237 | (which is struct usb_device, a real one this time). It then calls |
| 238 | usb_select_config() again to make sure that everything about the device is |
| 239 | set up |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 240 | - note that we have called usb_select_config() twice. This is inefficient |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 241 | but the alternative is to store additional information in the platform data. |
| 242 | The time taken is minimal and this way is simpler |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 243 | - at this point the device is set up and ready for use so far as the USB |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 244 | subsystem is concerned |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 245 | - the device's probe() method is then called. It can send messages and do |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 246 | whatever else it wants to make the device work. |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 247 | |
| 248 | Note that the first device is always a root hub, and this must be scanned to |
| 249 | find any devices. The above steps will have created a hub (UCLASS_USB_HUB), |
| 250 | given it address 1 and set the configuration. |
| 251 | |
| 252 | For hubs, the hub uclass has a post_probe() method. This means that after |
| 253 | any hub is probed, the uclass gets to do some processing. In this case |
| 254 | usb_hub_post_probe() is called, and the following steps take place: |
| 255 | |
| 256 | - usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 257 | calls usb_hub_configure() |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 258 | - hub power is enabled |
| 259 | - we loop through each port on the hub, performing the same steps for each |
| 260 | - first, check if there is a device present. This happens in |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 261 | usb_hub_port_connect_change(). If so, then usb_scan_device() is called to |
| 262 | scan the device, passing the appropriate port number. |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 263 | - you will recognise usb_scan_device() from the steps above. It sets up the |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 264 | device ready for use. If it is a hub, it will scan that hub before it |
| 265 | continues here (recursively, depth-first) |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 266 | - once all hub ports are scanned in this way, the hub is ready for use and |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 267 | all of its downstream devices also |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 268 | - additional controllers are scanned in the same way |
| 269 | |
| 270 | The above method has some nice properties: |
| 271 | |
| 272 | - the bus enumeration happens by virtue of driver model's natural device flow |
| 273 | - most logic is in the USB controller and hub uclasses; the actual device |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 274 | drivers do not need to know they are on a USB bus, at least so far as |
| 275 | enumeration goes |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 276 | - hub scanning happens automatically after a hub is probed |
| 277 | |
| 278 | |
| 279 | Hubs |
| 280 | ---- |
| 281 | |
| 282 | USB hubs are scanned as in the section above. While hubs have their own |
| 283 | uclass, they share some common elements with controllers: |
| 284 | |
| 285 | - they both attach private data to their children (struct usb_device, |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 286 | accessible for a child with dev_get_parent_priv(child)) |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 287 | - they both use usb_child_pre_probe() to set up their children as proper USB |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 288 | devices |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 289 | |
| 290 | |
| 291 | Example - Mass Storage |
| 292 | ---------------------- |
| 293 | |
| 294 | As an example of a USB device driver, see usb_storage.c. It uses its own |
| 295 | uclass and declares itself as follows: |
| 296 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 297 | .. code-block:: c |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 298 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 299 | U_BOOT_DRIVER(usb_mass_storage) = { |
| 300 | .name = "usb_mass_storage", |
| 301 | .id = UCLASS_MASS_STORAGE, |
| 302 | .of_match = usb_mass_storage_ids, |
| 303 | .probe = usb_mass_storage_probe, |
| 304 | }; |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 305 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 306 | static const struct usb_device_id mass_storage_id_table[] = { |
| 307 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
| 308 | .bInterfaceClass = USB_CLASS_MASS_STORAGE}, |
| 309 | { } /* Terminating entry */ |
| 310 | }; |
| 311 | |
| 312 | USB_DEVICE(usb_mass_storage, mass_storage_id_table); |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 313 | |
| 314 | The USB_DEVICE() macro attaches the given table of matching information to |
| 315 | the given driver. Note that the driver is declared in U_BOOT_DRIVER() as |
| 316 | 'usb_mass_storage' and this must match the first parameter of USB_DEVICE. |
| 317 | |
| 318 | When usb_find_and_bind_driver() is called on a USB device with the |
| 319 | bInterfaceClass value of USB_CLASS_MASS_STORAGE, it will automatically find |
| 320 | this driver and use it. |
| 321 | |
| 322 | |
| 323 | Counter-example: USB Ethernet |
| 324 | ----------------------------- |
| 325 | |
| 326 | As an example of the old way of doing things, see usb_ether.c. When the bus |
| 327 | is scanned, all Ethernet devices will be created as generic USB devices (in |
| 328 | uclass UCLASS_USB_DEV_GENERIC). Then, when the scan is completed, |
| 329 | usb_host_eth_scan() will be called. This looks through all the devices on |
| 330 | each bus and manually figures out which are Ethernet devices in the ways of |
| 331 | yore. |
| 332 | |
| 333 | In fact, usb_ether should be moved to driver model. Each USB Ethernet driver |
| 334 | (e.g drivers/usb/eth/asix.c) should include a USB_DEVICE() declaration, so |
| 335 | that it will be found as part of normal USB enumeration. Then, instead of a |
| 336 | generic USB driver, a real (driver-model-aware) driver will be used. Since |
| 337 | Ethernet now supports driver model, this should be fairly easy to achieve, |
| 338 | and then usb_ether.c and the usb_host_eth_scan() will melt away. |
| 339 | |
| 340 | |
| 341 | Sandbox |
| 342 | ------- |
| 343 | |
| 344 | All driver model uclasses must have tests and USB is no exception. To |
| 345 | achieve this, a sandbox USB controller is provided. This can make use of |
| 346 | emulation drivers which pretend to be USB devices. Emulations are provided |
| 347 | for a hub and a flash stick. These are enough to create a pretend USB bus |
| 348 | (defined by the sandbox device tree sandbox.dts) which can be scanned and |
| 349 | used. |
| 350 | |
| 351 | Tests in test/dm/usb.c make use of this feature. It allows much of the USB |
| 352 | stack to be tested without real hardware being needed. |
| 353 | |
| 354 | Here is an example device tree fragment: |
| 355 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 356 | .. code-block:: none |
| 357 | |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 358 | usb@1 { |
| 359 | compatible = "sandbox,usb"; |
| 360 | hub { |
| 361 | compatible = "usb-hub"; |
| 362 | usb,device-class = <USB_CLASS_HUB>; |
| 363 | hub-emul { |
| 364 | compatible = "sandbox,usb-hub"; |
| 365 | #address-cells = <1>; |
| 366 | #size-cells = <0>; |
| 367 | flash-stick { |
| 368 | reg = <0>; |
| 369 | compatible = "sandbox,usb-flash"; |
| 370 | sandbox,filepath = "flash.bin"; |
| 371 | }; |
| 372 | }; |
| 373 | }; |
| 374 | }; |
| 375 | |
| 376 | This defines a single controller, containing a root hub (which is required). |
| 377 | The hub is emulated by a hub emulator, and the emulated hub has a single |
| 378 | flash stick to emulate on one of its ports. |
| 379 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 380 | When 'usb start' is used, the following 'dm tree' output will be available:: |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 381 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 382 | usb [ + ] `-- usb@1 |
| 383 | usb_hub [ + ] `-- hub |
| 384 | usb_emul [ + ] |-- hub-emul |
| 385 | usb_emul [ + ] | `-- flash-stick |
| 386 | usb_mass_st [ + ] `-- usb_mass_storage |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 387 | |
| 388 | |
| 389 | This may look confusing. Most of it mirrors the device tree, but the |
| 390 | 'usb_mass_storage' device is not in the device tree. This is created by |
| 391 | usb_find_and_bind_driver() based on the USB_DRIVER in usb_storage.c. While |
| 392 | 'flash-stick' is the emulation device, 'usb_mass_storage' is the real U-Boot |
| 393 | USB device driver that talks to it. |
| 394 | |
| 395 | |
| 396 | Future work |
| 397 | ----------- |
| 398 | |
| 399 | It is pretty uncommon to have a large USB bus with lots of hubs on an |
| 400 | embedded system. In fact anything other than a root hub is uncommon. Still |
| 401 | it would be possible to speed up enumeration in two ways: |
| 402 | |
| 403 | - breadth-first search would allow devices to be reset and probed in |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 404 | parallel to some extent |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 405 | - enumeration could be lazy, in the sense that we could enumerate just the |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 406 | root hub at first, then only progress to the next 'level' when a device is |
| 407 | used that we cannot find. This could be made easier if the devices were |
| 408 | statically declared in the device tree (which is acceptable for production |
| 409 | boards where the same, known, things are on each bus). |
Simon Glass | 0d81374 | 2015-03-25 12:23:08 -0600 | [diff] [blame] | 410 | |
| 411 | But in common cases the current algorithm is sufficient. |
| 412 | |
| 413 | Other things that need doing: |
| 414 | - Convert usb_ether to use driver model as described above |
| 415 | - Test that keyboards work (and convert to driver model) |
| 416 | - Move the USB gadget framework to driver model |
| 417 | - Implement OHCI in driver model |
| 418 | - Implement USB PHYs in driver model |
| 419 | - Work out a clever way to provide lazy init for USB devices |
| 420 | |
Bin Meng | 8db0d92 | 2019-07-18 00:34:01 -0700 | [diff] [blame] | 421 | |
| 422 | .. Simon Glass <sjg@chromium.org> |
| 423 | .. 23-Mar-15 |