1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <assert.h>
6#include <stdint.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <threads.h>
11
12#include <ddk/binding.h>
13#include <ddk/debug.h>
14#include <ddk/device.h>
15#include <ddk/driver.h>
16#include <ddk/metadata.h>
17#include <ddk/protocol/usb-dci.h>
18#include <ddk/protocol/usb-function.h>
19#include <ddk/protocol/usb-mode-switch.h>
20#include <ddk/usb-request/usb-request.h>
21#include <zircon/listnode.h>
22#include <zircon/device/usb-peripheral.h>
23#include <zircon/hw/usb-cdc.h>
24#include <zircon/hw/usb.h>
25
26/*
27    THEORY OF OPERATION
28
29    This driver is responsible for USB in the peripheral role, that is,
30    acting as a USB device to a USB host.
31    It serves as the central point of coordination for the peripheral role.
32    It is configured via ioctls in the ZX_PROTOCOL_USB_DEVICE protocol
33    (which is used by the usbctl command line program).
34    Based on this configuration, it creates one or more DDK devices with protocol
35    ZX_PROTOCOL_USB_FUNCTION. These devices are bind points for USB function drivers,
36    which implement USB interfaces for particular functions (like USB ethernet or mass storage).
37    This driver also binds to a device with protocol ZX_PROTOCOL_USB_DCI
38    (Device Controller Interface) which is implemented by a driver for the actual
39    USB controller hardware for the peripheral role.
40
41    There are several steps needed to initialize and start USB in the peripheral role.
42    The first step is setting up the USB configuration via ioctls.
43    ioctl_usb_peripheral_set_device_desc() sets the USB device descriptor to be presented
44    to the host during enumeration.
45    Next, ioctl_usb_peripheral_add_function() can be called one or more times to add
46    descriptors for the USB functions to be included in the USB configuration.
47    Finally after all the functions have been added, ioctl_usb_peripheral_bind_functions()
48    tells this driver that configuration is complete and it is now possible to build
49    the configuration descriptor. Once we get to this point, usb_device_t.functions_bound
50    is set to true.
51
52    Independent of this configuration process, ioctl_usb_peripheral_set_mode() can be used
53    to configure the role of the USB controller. If the role is set to USB_MODE_PERIPHERAL
54    and "functions_bound" is true, then we are ready to start USB in peripheral role.
55    At this point, we create DDK devices for our list of functions.
56    When the function drivers bind to these functions, they register an interface of type
57    usb_function_interface_t with this driver via the usb_function_register() API.
58    Once all of the function drivers have registered themselves this way,
59    usb_device_t.functions_registered is set to true.
60
61    if the usb mode is set to USB_MODE_PERIPHERAL and "functions_registered" is true,
62    we are now finally ready to operate in the peripheral role.
63    At this point we can inform the DCI driver to start running in peripheral role
64    by calling usb_mode_switch_set_mode(USB_MODE_PERIPHERAL) on its ZX_PROTOCOL_USB_MODE_SWITCH
65    interface. Now the USB controller hardware is up and running as a USB peripheral.
66
67    Teardown of the peripheral role one of two ways:
68    First, ioctl_usb_peripheral_clear_functions() will reset this device's list of USB functions.
69    Second, the USB mode can be set to something other than USB_MODE_PERIPHERAL.
70    In this second case, we will remove the DDK devices for the USB functions
71    so the function drivers will unbind, but the USB configuration remains ready to go
72    for when the USB mode is switched back to USB_MODE_PERIPHERAL.
73*/
74
75#define MAX_INTERFACES 32
76
77typedef struct {
78    zx_device_t* zxdev;
79    zx_device_t* dci_dev;
80    struct usb_device* dev;
81    list_node_t node;
82    usb_function_interface_t interface;
83    usb_function_descriptor_t desc;
84    usb_descriptor_header_t* descriptors;
85    size_t descriptors_length;
86    unsigned num_interfaces;
87} usb_function_t;
88
89typedef struct usb_device {
90    // the device we publish
91    zx_device_t* zxdev;
92    // our parent device
93    zx_device_t* dci_dev;
94    // our parent's DCI protocol
95    usb_dci_protocol_t usb_dci;
96    // our parent's USB switch protocol
97    usb_mode_switch_protocol_t usb_mode_switch;
98    // USB device descriptor set via ioctl_usb_peripheral_set_device_desc()
99    usb_device_descriptor_t device_desc;
100    // USB configuration descriptor, synthesized from our functions' descriptors
101    usb_configuration_descriptor_t* config_desc;
102    // map from interface number to function
103    usb_function_t* interface_map[MAX_INTERFACES];
104    // map from endpoint index to function
105    usb_function_t* endpoint_map[USB_MAX_EPS];
106    // BTI handle shared from DCI layer
107    zx_handle_t bti_handle;
108    // strings for USB string descriptors
109    char* strings[256];
110    // list of usb_function_t
111    list_node_t functions;
112    // mutex for protecting our state
113    mtx_t lock;
114    // current USB mode set via ioctl_usb_peripheral_set_mode()
115    usb_mode_t usb_mode;
116    // our parent's USB mode
117     usb_mode_t dci_usb_mode;
118    // set if ioctl_usb_peripheral_bind_functions() has been called
119    // and we have a complete list of our function.
120    bool functions_bound;
121    // set if all our functions have registered their usb_function_interface_t
122    bool functions_registered;
123    // true if we have added child devices for our functions
124    bool function_devs_added;
125    // true if we are connected to a host
126    bool connected;
127    // current configuration number selected via USB_REQ_SET_CONFIGURATION
128    // (will be 0 or 1 since we currently do not support multiple configurations)
129    uint8_t configuration;
130    // USB connection speed
131    usb_speed_t speed;
132} usb_device_t;
133
134// for mapping bEndpointAddress value to/from index in range 0 - 31
135// OUT endpoints are in range 1 - 15, IN endpoints are in range 17 - 31
136#define ep_address_to_index(addr) (((addr) & 0xF) | (((addr) & 0x80) >> 3))
137#define ep_index_to_address(index) (((index) & 0xF) | (((index) & 0x10) << 3))
138#define OUT_EP_START    1
139#define OUT_EP_END      15
140#define IN_EP_START     17
141#define IN_EP_END       31
142
143static zx_status_t usb_dev_state_changed_locked(usb_device_t* dev);
144
145static zx_status_t usb_device_alloc_string_desc(usb_device_t* dev, const char* string,
146                                                uint8_t* out_index) {
147
148    mtx_lock(&dev->lock);
149
150    unsigned i;
151    for (i = 1; i < countof(dev->strings); i++) {
152        if (!dev->strings[i]) {
153            break;
154        }
155    }
156    if (i == countof(dev->strings)) {
157        mtx_unlock(&dev->lock);
158        return ZX_ERR_NO_RESOURCES;
159    }
160
161    dev->strings[i] = strdup(string);
162    if (!dev->strings[i]) {
163        mtx_unlock(&dev->lock);
164        return ZX_ERR_NO_MEMORY;
165    }
166
167    mtx_unlock(&dev->lock);
168
169    *out_index = i;
170    return ZX_OK;
171}
172
173static zx_protocol_device_t function_proto = {
174    .version = DEVICE_OPS_VERSION,
175    // Note that we purposely do not have a release callback for USB functions.
176    // The functions are kept on a list when not active so they can be re-added
177    // when reentering device mode.
178};
179
180static zx_status_t usb_device_function_registered(usb_device_t* dev) {
181    mtx_lock(&dev->lock);
182
183    if (dev->config_desc) {
184        zxlogf(ERROR, "usb_device_function_registered: already have configuration descriptor!\n");
185        mtx_unlock(&dev->lock);
186        return ZX_ERR_BAD_STATE;
187    }
188
189    // check to see if we have all our functions registered
190    // if so, we can build our configuration descriptor and tell the DCI driver we are ready
191    usb_function_t* function;
192    size_t length = sizeof(usb_configuration_descriptor_t);
193    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
194        if (function->descriptors) {
195            length += function->descriptors_length;
196        } else {
197            // need to wait for more functions to register
198            mtx_unlock(&dev->lock);
199            return ZX_OK;
200        }
201    }
202
203    // build our configuration descriptor
204    usb_configuration_descriptor_t* config_desc = malloc(length);
205    if (!config_desc) {
206        mtx_unlock(&dev->lock);
207        return ZX_ERR_NO_MEMORY;
208    }
209
210    config_desc->bLength = sizeof(*config_desc);
211    config_desc->bDescriptorType = USB_DT_CONFIG;
212    config_desc->wTotalLength = htole16(length);
213    config_desc->bNumInterfaces = 0;
214    config_desc->bConfigurationValue = 1;
215    config_desc->iConfiguration = 0;
216    // TODO(voydanoff) add a way to configure bmAttributes and bMaxPower
217    config_desc->bmAttributes = USB_CONFIGURATION_SELF_POWERED | USB_CONFIGURATION_RESERVED_7;
218    config_desc->bMaxPower = 0;
219
220    void* dest = config_desc + 1;
221    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
222        memcpy(dest, function->descriptors, function->descriptors_length);
223        dest += function->descriptors_length;
224        config_desc->bNumInterfaces += function->num_interfaces;
225    }
226    dev->config_desc = config_desc;
227
228    zxlogf(TRACE, "usb_device_function_registered functions_registered = true\n");
229    dev->functions_registered = true;
230
231    zx_status_t status = usb_dev_state_changed_locked(dev);
232    mtx_unlock(&dev->lock);
233    return status;
234}
235
236static zx_status_t usb_func_req_alloc(void* ctx, usb_request_t** out, uint64_t data_size,
237                                     uint8_t ep_address) {
238    return usb_request_alloc(out, data_size, ep_address);
239}
240
241static zx_status_t usb_func_req_alloc_vmo(void* ctx, usb_request_t** out, zx_handle_t vmo_handle,
242                                          uint64_t vmo_offset, uint64_t length,
243                                          uint8_t ep_address) {
244    return usb_request_alloc_vmo(out, vmo_handle, vmo_offset, length, ep_address);
245}
246
247static zx_status_t usb_func_req_init(void* ctx, usb_request_t* req, zx_handle_t vmo_handle,
248                                     uint64_t vmo_offset, uint64_t length, uint8_t ep_address) {
249    return usb_request_init(req, vmo_handle, vmo_offset, length, ep_address);
250}
251
252
253static ssize_t usb_func_req_copy_from(void* ctx, usb_request_t* req, void* data,
254                                          size_t length, size_t offset) {
255    return usb_request_copyfrom(req, data, length, offset);
256}
257
258static ssize_t usb_func_req_copy_to(void* ctx, usb_request_t* req, const void* data,
259                                        size_t length, size_t offset) {
260    return usb_request_copyto(req, data, length, offset);
261}
262
263static zx_status_t usb_func_req_mmap(void* ctx, usb_request_t* req, void** data) {
264    return usb_request_mmap(req, data);
265}
266
267static zx_status_t usb_func_req_cacheop(void* ctx, usb_request_t* req, uint32_t op,
268                                        size_t offset, size_t length) {
269    return usb_request_cacheop(req, op, offset, length);
270}
271
272static zx_status_t usb_func_req_cache_flush(void* ctx, usb_request_t* req, size_t offset,
273                                            size_t length) {
274    return usb_request_cache_flush(req, offset, length);
275}
276
277static zx_status_t usb_func_req_cache_flush_invalidate(void* ctx, usb_request_t* req,
278                                                            zx_off_t offset, size_t length) {
279    return usb_request_cache_flush_invalidate(req, offset, length);
280}
281
282static zx_status_t usb_func_req_physmap(void* ctx, usb_request_t* req) {
283    usb_function_t* function = ctx;
284    usb_device_t* dev = function->dev;
285
286    return usb_request_physmap(req, dev->bti_handle);
287}
288
289static void usb_func_req_release(void* ctx, usb_request_t* req) {
290    usb_request_release(req);
291}
292
293static void usb_func_req_complete(void* ctx, usb_request_t* req,
294                                       zx_status_t status, zx_off_t actual) {
295    usb_request_complete(req, status, actual);
296}
297
298static void usb_func_req_phys_iter_init(void* ctx, phys_iter_t* iter, usb_request_t* req,
299                                             size_t max_length) {
300    usb_request_phys_iter_init(iter, req, max_length);
301}
302
303static zx_status_t usb_func_register(void* ctx, usb_function_interface_t* interface) {
304    usb_function_t* function = ctx;
305    usb_device_t* dev = function->dev;
306    usb_function_t** endpoint_map = dev->endpoint_map;
307
308    size_t length;
309    const usb_descriptor_header_t* descriptors = usb_function_get_descriptors(interface, &length);
310
311    // validate the descriptor list
312    if (!descriptors || length < sizeof(usb_interface_descriptor_t)) {
313        return ZX_ERR_INVALID_ARGS;
314    }
315
316    usb_interface_descriptor_t* intf_desc = (usb_interface_descriptor_t *)descriptors;
317    if (intf_desc->bDescriptorType != USB_DT_INTERFACE ||
318            intf_desc->bLength != sizeof(usb_interface_descriptor_t)) {
319        zxlogf(ERROR, "usb_func_register: first descriptor not an interface descriptor\n");
320        return ZX_ERR_INVALID_ARGS;
321    }
322
323    const usb_descriptor_header_t* end = (void *)descriptors + length;
324    const usb_descriptor_header_t* header = descriptors;
325
326    while (header < end) {
327        if (header->bDescriptorType == USB_DT_INTERFACE) {
328            usb_interface_descriptor_t* desc = (usb_interface_descriptor_t *)header;
329            if (desc->bInterfaceNumber >= countof(dev->interface_map) ||
330                dev->interface_map[desc->bInterfaceNumber] != function) {
331                zxlogf(ERROR, "usb_func_register: bInterfaceNumber %u\n",
332                       desc->bInterfaceNumber);
333                return ZX_ERR_INVALID_ARGS;
334            }
335            if (desc->bAlternateSetting == 0) {
336                function->num_interfaces++;
337            }
338        } else if (header->bDescriptorType == USB_DT_ENDPOINT) {
339            usb_endpoint_descriptor_t* desc = (usb_endpoint_descriptor_t *)header;
340            unsigned index = ep_address_to_index(desc->bEndpointAddress);
341            if (index == 0 || index >= countof(dev->endpoint_map) ||
342                endpoint_map[index] != function) {
343                zxlogf(ERROR, "usb_func_register: bad endpoint address 0x%X\n",
344                       desc->bEndpointAddress);
345                return ZX_ERR_INVALID_ARGS;
346            }
347        }
348
349        if (header->bLength == 0) {
350            zxlogf(ERROR, "usb_func_register: zero length descriptor\n");
351            return ZX_ERR_INVALID_ARGS;
352        }
353        header = (void *)header + header->bLength;
354    }
355
356    function->descriptors = malloc(length);
357    if (!function->descriptors) {
358        return ZX_ERR_NO_MEMORY;
359    }
360    memcpy(function->descriptors, descriptors, length);
361    function->descriptors_length = length;
362    memcpy(&function->interface, interface, sizeof(function->interface));
363
364    return usb_device_function_registered(function->dev);
365}
366
367static zx_status_t usb_func_alloc_interface(void* ctx, uint8_t* out_intf_num) {
368    usb_function_t* function = ctx;
369    usb_device_t* dev = function->dev;
370
371    mtx_lock(&dev->lock);
372
373    for (unsigned i = 0; i < countof(dev->interface_map); i++) {
374        if (dev->interface_map[i] == NULL) {
375            dev->interface_map[i] = function;
376            mtx_unlock(&dev->lock);
377            *out_intf_num = i;
378            return ZX_OK;
379        }
380    }
381
382    mtx_unlock(&dev->lock);
383    return ZX_ERR_NO_RESOURCES;
384}
385
386static zx_status_t usb_func_alloc_ep(void* ctx, uint8_t direction, uint8_t* out_address) {
387    unsigned start, end;
388
389    if (direction == USB_DIR_OUT) {
390        start = OUT_EP_START;
391        end = OUT_EP_END;
392    } else if (direction == USB_DIR_IN) {
393        start = IN_EP_START;
394        end = IN_EP_END;
395    } else {
396        return ZX_ERR_INVALID_ARGS;
397    }
398
399    usb_function_t* function = ctx;
400    usb_device_t* dev = function->dev;
401    usb_function_t** endpoint_map = dev->endpoint_map;
402
403    mtx_lock(&dev->lock);
404    for (unsigned index = start; index <= end; index++) {
405        if (endpoint_map[index] == NULL) {
406            endpoint_map[index] = function;
407            mtx_unlock(&dev->lock);
408            *out_address = ep_index_to_address(index);
409            return ZX_OK;
410        }
411    }
412
413    mtx_unlock(&dev->lock);
414    return ZX_ERR_NO_RESOURCES;
415}
416
417static zx_status_t usb_func_config_ep(void* ctx, usb_endpoint_descriptor_t* ep_desc,
418                                      usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
419    usb_function_t* function = ctx;
420    return usb_dci_config_ep(&function->dev->usb_dci, ep_desc, ss_comp_desc);
421}
422
423static zx_status_t usb_func_disable_ep(void* ctx, uint8_t ep_addr) {
424    zxlogf(TRACE, "usb_func_disable_ep\n");
425    usb_function_t* function = ctx;
426    return usb_dci_disable_ep(&function->dev->usb_dci, ep_addr);
427}
428
429static zx_status_t usb_func_alloc_string_desc(void* ctx, const char* string, uint8_t* out_index) {
430    usb_function_t* function = ctx;
431    return usb_device_alloc_string_desc(function->dev, string, out_index);
432}
433
434static void usb_func_queue(void* ctx, usb_request_t* req) {
435    usb_function_t* function = ctx;
436    usb_dci_request_queue(&function->dev->usb_dci, req);
437}
438
439static zx_status_t usb_func_ep_set_stall(void* ctx, uint8_t ep_address) {
440    usb_function_t* function = ctx;
441    return usb_dci_ep_set_stall(&function->dev->usb_dci, ep_address);
442}
443
444static zx_status_t usb_func_ep_clear_stall(void* ctx, uint8_t ep_address) {
445    usb_function_t* function = ctx;
446    return usb_dci_ep_clear_stall(&function->dev->usb_dci, ep_address);
447}
448
449usb_function_protocol_ops_t usb_function_proto = {
450    .req_alloc = usb_func_req_alloc,
451    .req_alloc_vmo = usb_func_req_alloc_vmo,
452    .req_init = usb_func_req_init,
453    .req_copy_from = usb_func_req_copy_from,
454    .req_copy_to = usb_func_req_copy_to,
455    .req_mmap = usb_func_req_mmap,
456    .req_cacheop = usb_func_req_cacheop,
457    .req_cache_flush = usb_func_req_cache_flush,
458    .req_cache_flush_invalidate = usb_func_req_cache_flush_invalidate,
459    .req_physmap = usb_func_req_physmap,
460    .req_release = usb_func_req_release,
461    .req_complete = usb_func_req_complete,
462    .req_phys_iter_init = usb_func_req_phys_iter_init,
463    .register_func = usb_func_register,
464    .alloc_interface = usb_func_alloc_interface,
465    .alloc_ep = usb_func_alloc_ep,
466    .config_ep = usb_func_config_ep,
467    .disable_ep = usb_func_disable_ep,
468    .alloc_string_desc = usb_func_alloc_string_desc,
469    .queue = usb_func_queue,
470    .ep_set_stall = usb_func_ep_set_stall,
471    .ep_clear_stall = usb_func_ep_clear_stall,
472};
473
474static zx_status_t usb_dev_get_descriptor(usb_device_t* dev, uint8_t request_type,
475                                          uint16_t value, uint16_t index, void* buffer,
476                                          size_t length, size_t* out_actual) {
477    uint8_t type = request_type & USB_TYPE_MASK;
478
479    if (type == USB_TYPE_STANDARD) {
480        uint8_t desc_type = value >> 8;
481        if (desc_type == USB_DT_DEVICE && index == 0) {
482            const usb_device_descriptor_t* desc = &dev->device_desc;
483            if (desc->bLength == 0) {
484                zxlogf(ERROR, "usb_dev_get_descriptor: device descriptor not set\n");
485                return ZX_ERR_INTERNAL;
486            }
487            if (length > sizeof(*desc)) length = sizeof(*desc);
488            memcpy(buffer, desc, length);
489            *out_actual = length;
490            return ZX_OK;
491        } else if (desc_type == USB_DT_CONFIG && index == 0) {
492            const usb_configuration_descriptor_t* desc = dev->config_desc;
493            if (!desc) {
494                zxlogf(ERROR, "usb_dev_get_descriptor: configuration descriptor not set\n");
495                return ZX_ERR_INTERNAL;
496            }
497            uint16_t desc_length = letoh16(desc->wTotalLength);
498            if (length > desc_length) length =desc_length;
499            memcpy(buffer, desc, length);
500            *out_actual = length;
501            return ZX_OK;
502        }
503        else if (value >> 8 == USB_DT_STRING) {
504            uint8_t desc[255];
505            usb_descriptor_header_t* header = (usb_descriptor_header_t *)desc;
506            header->bDescriptorType = USB_DT_STRING;
507
508            uint8_t string_index = value & 0xFF;
509            if (string_index == 0) {
510                // special case - return language list
511                header->bLength = 4;
512                desc[2] = 0x09;     // language ID
513                desc[3] = 0x04;
514            } else {
515                char* string = dev->strings[string_index];
516                if (!string) {
517                    return ZX_ERR_INVALID_ARGS;
518                }
519                unsigned index = 2;
520
521                // convert ASCII to Unicode
522                if (string) {
523                    while (*string && index < sizeof(desc) - 2) {
524                        desc[index++] = *string++;
525                        desc[index++] = 0;
526                    }
527                }
528                // zero terminate
529                desc[index++] = 0;
530                desc[index++] = 0;
531                header->bLength = index;
532            }
533
534            if (header->bLength < length) length = header->bLength;
535            memcpy(buffer, desc, length);
536            *out_actual = length;
537            return ZX_OK;
538        }
539    }
540
541    zxlogf(ERROR, "usb_device_get_descriptor unsupported value: %d index: %d\n", value, index);
542    return ZX_ERR_NOT_SUPPORTED;
543}
544
545static zx_status_t usb_dev_set_configuration(usb_device_t* dev, uint8_t configuration) {
546    zx_status_t status = ZX_OK;
547    bool configured = configuration > 0;
548
549    mtx_lock(&dev->lock);
550
551    usb_function_t* function;
552    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
553        if (function->interface.ops) {
554            status = usb_function_set_configured(&function->interface, configured, dev->speed);
555            if (status != ZX_OK && configured) {
556                goto fail;
557            }
558        }
559    }
560
561    dev->configuration = configuration;
562
563fail:
564    mtx_unlock(&dev->lock);
565    return status;
566}
567
568static zx_status_t usb_dev_set_interface(usb_device_t* dev, unsigned interface,
569                                         unsigned alt_setting) {
570    usb_function_t* function = dev->interface_map[interface];
571    if (function && function->interface.ops) {
572        return usb_function_set_interface(&function->interface, interface, alt_setting);
573    }
574    return ZX_ERR_NOT_SUPPORTED;
575}
576
577static zx_status_t usb_dev_control(void* ctx, const usb_setup_t* setup, void* buffer,
578                                   size_t buffer_length, size_t* out_actual) {
579    usb_device_t* dev = ctx;
580    uint8_t request_type = setup->bmRequestType;
581    uint8_t request = setup->bRequest;
582    uint16_t value = le16toh(setup->wValue);
583    uint16_t index = le16toh(setup->wIndex);
584    uint16_t length = le16toh(setup->wLength);
585    if (length > buffer_length) length = buffer_length;
586
587    zxlogf(TRACE, "usb_dev_control type: 0x%02X req: %d value: %d index: %d length: %d\n",
588            request_type, request, value, index, length);
589
590    switch (request_type & USB_RECIP_MASK) {
591    case USB_RECIP_DEVICE:
592        // handle standard device requests
593        if ((request_type & (USB_DIR_MASK | USB_TYPE_MASK)) == (USB_DIR_IN | USB_TYPE_STANDARD) &&
594            request == USB_REQ_GET_DESCRIPTOR) {
595            return usb_dev_get_descriptor(dev, request_type, value, index, buffer, length,
596                                             out_actual);
597        } else if (request_type == (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) &&
598                   request == USB_REQ_SET_CONFIGURATION && length == 0) {
599            return usb_dev_set_configuration(dev, value);
600        } else if (request_type == (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) &&
601                   request == USB_REQ_GET_CONFIGURATION && length > 0) {
602            *((uint8_t *)buffer) = dev->configuration;
603            *out_actual = sizeof(uint8_t);
604            return ZX_OK;
605        }
606        break;
607    case USB_RECIP_INTERFACE: {
608        if (request_type == (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) &&
609                   request == USB_REQ_SET_INTERFACE && length == 0) {
610            return usb_dev_set_interface(dev, index, value);
611        } else {
612            // delegate to the function driver for the interface
613            usb_function_t* function = dev->interface_map[index];
614            if (function && function->interface.ops) {
615                return usb_function_control(&function->interface, setup, buffer, buffer_length,
616                                            out_actual);
617            }
618        }
619        break;
620    }
621    case USB_RECIP_ENDPOINT: {
622        // delegate to the function driver for the endpoint
623        index = ep_address_to_index(index);
624        if (index == 0 || index >= USB_MAX_EPS) {
625            return ZX_ERR_INVALID_ARGS;
626        }
627        usb_function_t* function = dev->endpoint_map[index];
628        if (function && function->interface.ops) {
629            return usb_function_control(&function->interface, setup, buffer, buffer_length,
630                                        out_actual);
631        }
632        break;
633    }
634    case USB_RECIP_OTHER:
635        // TODO(voydanoff) - how to handle this?
636    default:
637        break;
638    }
639
640    return ZX_ERR_NOT_SUPPORTED;
641}
642
643static void usb_dev_set_connected(void* ctx, bool connected) {
644    usb_device_t* dev = ctx;
645    if (dev->connected != connected) {
646        if (!connected) {
647            usb_function_t* function;
648            list_for_every_entry(&dev->functions, function, usb_function_t, node) {
649                if (function->interface.ops) {
650                    usb_function_set_configured(&function->interface, false, USB_SPEED_UNDEFINED);
651                }
652            }
653        }
654
655        dev->connected = connected;
656    }
657}
658
659static void usb_dev_set_speed(void* ctx, usb_speed_t speed) {
660    usb_device_t* dev = ctx;
661    dev->speed = speed;
662}
663
664usb_dci_interface_ops_t dci_ops = {
665    .control = usb_dev_control,
666    .set_connected = usb_dev_set_connected,
667    .set_speed = usb_dev_set_speed,
668};
669
670static zx_status_t usb_dev_set_device_desc(usb_device_t* dev, const void* in_buf, size_t in_len) {
671    if (in_len != sizeof(dev->device_desc)) {
672        return ZX_ERR_INVALID_ARGS;
673    }
674    const usb_device_descriptor_t* desc = in_buf;
675    if (desc->bLength != sizeof(*desc) ||
676        desc->bDescriptorType != USB_DT_DEVICE) {
677        return ZX_ERR_INVALID_ARGS;
678    }
679    if (desc->bNumConfigurations != 1) {
680        zxlogf(ERROR, "usb_device_ioctl: bNumConfigurations: %u, only 1 supported\n",
681                desc->bNumConfigurations);
682        return ZX_ERR_INVALID_ARGS;
683    }
684    memcpy(&dev->device_desc, desc, sizeof(dev->device_desc));
685    return ZX_OK;
686}
687
688static zx_status_t usb_dev_alloc_string_desc(usb_device_t* dev, const void* in_buf, size_t in_len,
689                                             void* out_buf, size_t out_len, size_t* out_actual) {
690    if (in_len < 2 || out_len < sizeof(uint8_t)) {
691        return ZX_ERR_INVALID_ARGS;
692    }
693
694    // make sure string is zero terminated
695    *((char *)in_buf + in_len - 1) = 0;
696
697    uint8_t index;
698    zx_status_t status = usb_device_alloc_string_desc(dev, in_buf, &index);
699    if (status != ZX_OK) {
700        return status;
701     }
702
703    *((uint8_t *)out_buf) = index;
704    *out_actual = sizeof(index);
705    return ZX_OK;
706}
707
708static zx_status_t usb_dev_add_function(usb_device_t* dev, const void* in_buf, size_t in_len) {
709    if (in_len != sizeof(usb_function_descriptor_t)) {
710        return ZX_ERR_INVALID_ARGS;
711    }
712    if (dev->functions_bound) {
713        return ZX_ERR_BAD_STATE;
714    }
715
716    usb_function_t* function = calloc(1, sizeof(usb_function_t));
717    if (!function) {
718        return ZX_ERR_NO_MEMORY;
719    }
720    function->dci_dev = dev->dci_dev;
721    function->dev = dev;
722    memcpy(&function->desc, in_buf, sizeof(function->desc));
723    list_add_tail(&dev->functions, &function->node);
724
725    return ZX_OK;
726}
727
728static void usb_dev_remove_function_devices_locked(usb_device_t* dev) {
729    zxlogf(TRACE, "usb_dev_remove_function_devices_locked\n");
730
731    usb_function_t* function;
732    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
733        if (function->zxdev) {
734            // here we remove the function from the DDK device tree,
735            // but the storage for the function remains on our function list.
736            device_remove(function->zxdev);
737            function->zxdev = NULL;
738        }
739    }
740
741    free(dev->config_desc);
742    dev->config_desc = NULL;
743    dev->functions_registered = false;
744    dev->function_devs_added = false;
745}
746
747static zx_status_t usb_dev_add_function_devices_locked(usb_device_t* dev) {
748    zxlogf(TRACE, "usb_dev_add_function_devices_locked\n");
749    if (dev->function_devs_added) {
750        return ZX_OK;
751    }
752
753    usb_device_descriptor_t* device_desc = &dev->device_desc;
754    int index = 0;
755    usb_function_t* function;
756    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
757        char name[16];
758        snprintf(name, sizeof(name), "function-%03d", index);
759
760        usb_function_descriptor_t* desc = &function->desc;
761
762        zx_device_prop_t props[] = {
763            { BIND_PROTOCOL, 0, ZX_PROTOCOL_USB_FUNCTION },
764            { BIND_USB_CLASS, 0, desc->interface_class },
765            { BIND_USB_SUBCLASS, 0, desc->interface_subclass },
766            { BIND_USB_PROTOCOL, 0, desc->interface_protocol },
767            { BIND_USB_VID, 0, device_desc->idVendor },
768            { BIND_USB_PID, 0, device_desc->idProduct },
769        };
770
771        device_add_args_t args = {
772            .version = DEVICE_ADD_ARGS_VERSION,
773            .name = name,
774            .ctx = function,
775            .ops = &function_proto,
776            .proto_id = ZX_PROTOCOL_USB_FUNCTION,
777            .proto_ops = &usb_function_proto,
778            .props = props,
779            .prop_count = countof(props),
780        };
781
782        zx_status_t status = device_add(dev->zxdev, &args, &function->zxdev);
783        if (status != ZX_OK) {
784            zxlogf(ERROR, "usb_dev_bind_functions add_device failed %d\n", status);
785            return status;
786        }
787
788        index++;
789    }
790
791    dev->function_devs_added = true;
792    return ZX_OK;
793}
794
795static zx_status_t usb_dev_state_changed_locked(usb_device_t* dev) {
796    zxlogf(TRACE, "usb_dev_state_changed_locked usb_mode: %d dci_usb_mode: %d\n", dev->usb_mode,
797            dev->dci_usb_mode);
798
799    usb_mode_t new_dci_usb_mode = dev->dci_usb_mode;
800    bool add_function_devs = (dev->usb_mode == USB_MODE_PERIPHERAL && dev->functions_bound);
801    zx_status_t status = ZX_OK;
802
803    if (dev->usb_mode == USB_MODE_PERIPHERAL) {
804        if (dev->functions_registered) {
805            // switch DCI to device mode
806            new_dci_usb_mode = USB_MODE_PERIPHERAL;
807        } else {
808            new_dci_usb_mode = USB_MODE_NONE;
809        }
810    } else {
811        new_dci_usb_mode = dev->usb_mode;
812    }
813
814    if (add_function_devs) {
815        // publish child devices if necessary
816        if (!dev->function_devs_added) {
817            status = usb_dev_add_function_devices_locked(dev);
818            if (status != ZX_OK) {
819                return status;
820            }
821        }
822    }
823
824    if (dev->dci_usb_mode != new_dci_usb_mode) {
825        zxlogf(TRACE, "usb_dev_state_changed_locked set DCI mode %d\n", new_dci_usb_mode);
826        status = usb_mode_switch_set_mode(&dev->usb_mode_switch, new_dci_usb_mode);
827        if (status != ZX_OK) {
828            usb_mode_switch_set_mode(&dev->usb_mode_switch, USB_MODE_NONE);
829            new_dci_usb_mode = USB_MODE_NONE;
830        }
831        dev->dci_usb_mode = new_dci_usb_mode;
832    }
833
834    if (!add_function_devs && dev->function_devs_added) {
835        usb_dev_remove_function_devices_locked(dev);
836    }
837
838    return status;
839}
840
841static zx_status_t usb_dev_bind_functions(usb_device_t* dev) {
842    mtx_lock(&dev->lock);
843
844    if (dev->functions_bound) {
845        zxlogf(ERROR, "usb_dev_bind_functions: already bound!\n");
846        mtx_unlock(&dev->lock);
847        return ZX_ERR_BAD_STATE;
848    }
849
850    usb_device_descriptor_t* device_desc = &dev->device_desc;
851    if (device_desc->bLength == 0) {
852        zxlogf(ERROR, "usb_dev_bind_functions: device descriptor not set\n");
853        mtx_unlock(&dev->lock);
854        return ZX_ERR_BAD_STATE;
855    }
856    if (list_is_empty(&dev->functions)) {
857        zxlogf(ERROR, "usb_dev_bind_functions: no functions to bind\n");
858        mtx_unlock(&dev->lock);
859        return ZX_ERR_BAD_STATE;
860    }
861
862    zxlogf(TRACE, "usb_dev_bind_functions functions_bound = true\n");
863    dev->functions_bound = true;
864    zx_status_t status = usb_dev_state_changed_locked(dev);
865    mtx_unlock(&dev->lock);
866    return status;
867}
868
869static zx_status_t usb_dev_clear_functions(usb_device_t* dev) {
870    zxlogf(TRACE, "usb_dev_clear_functions\n");
871    mtx_lock(&dev->lock);
872
873    usb_function_t* function;
874    while ((function = list_remove_head_type(&dev->functions, usb_function_t, node)) != NULL) {
875        if (function->zxdev) {
876            device_remove(function->zxdev);
877            // device_remove will not actually free the function, so we free it here
878            free(function->descriptors);
879            free(function);
880        }
881    }
882    free(dev->config_desc);
883    dev->config_desc = NULL;
884    dev->functions_bound = false;
885    dev->functions_registered = false;
886
887    memset(dev->interface_map, 0, sizeof(dev->interface_map));
888    memset(dev->endpoint_map, 0, sizeof(dev->endpoint_map));
889    for (unsigned i = 0; i < countof(dev->strings); i++) {
890        free(dev->strings[i]);
891        dev->strings[i] = NULL;
892    }
893
894    zx_status_t status = usb_dev_state_changed_locked(dev);
895    mtx_unlock(&dev->lock);
896    return status;
897}
898
899static zx_status_t usb_dev_get_mode(usb_device_t* dev, void* out_buf, size_t out_len,
900                                    size_t* out_actual) {
901    if (out_len < sizeof(usb_mode_t)) {
902        return ZX_ERR_INVALID_ARGS;
903    }
904
905    *((usb_mode_t *)out_buf) = dev->usb_mode;
906    *out_actual = sizeof(usb_mode_t);
907    return ZX_OK;
908}
909
910static zx_status_t usb_dev_set_mode(usb_device_t* dev, const void* in_buf, size_t in_len) {
911    if (in_len < sizeof(usb_mode_t)) {
912        return ZX_ERR_INVALID_ARGS;
913    }
914
915    mtx_lock(&dev->lock);
916    dev->usb_mode = *((usb_mode_t *)in_buf);
917    zx_status_t status = usb_dev_state_changed_locked(dev);
918    mtx_unlock(&dev->lock);
919    return status;
920}
921
922static zx_status_t usb_dev_ioctl(void* ctx, uint32_t op, const void* in_buf, size_t in_len,
923                                 void* out_buf, size_t out_len, size_t* out_actual) {
924    zxlogf(TRACE, "usb_dev_ioctl %x\n", op);
925    usb_device_t* dev = ctx;
926
927    switch (op) {
928    case IOCTL_USB_PERIPHERAL_SET_DEVICE_DESC:
929        return usb_dev_set_device_desc(dev, in_buf, in_len);
930    case IOCTL_USB_PERIPHERAL_ALLOC_STRING_DESC:
931        return usb_dev_alloc_string_desc(dev, in_buf, in_len, out_buf, out_len, out_actual);
932    case IOCTL_USB_PERIPHERAL_ADD_FUNCTION:
933        return usb_dev_add_function(dev, in_buf, in_len);
934    case IOCTL_USB_PERIPHERAL_BIND_FUNCTIONS:
935        return usb_dev_bind_functions(dev);
936    case IOCTL_USB_PERIPHERAL_CLEAR_FUNCTIONS:
937        return usb_dev_clear_functions(dev);
938    case IOCTL_USB_PERIPHERAL_GET_MODE:
939        return usb_dev_get_mode(dev, out_buf, out_len, out_actual);
940    case IOCTL_USB_PERIPHERAL_SET_MODE:
941        return usb_dev_set_mode(dev, in_buf, in_len);
942    default:
943        return ZX_ERR_NOT_SUPPORTED;
944    }
945}
946
947static void usb_dev_unbind(void* ctx) {
948    zxlogf(TRACE, "usb_dev_unbind\n");
949    usb_device_t* dev = ctx;
950    usb_dev_clear_functions(dev);
951    device_remove(dev->zxdev);
952}
953
954static void usb_dev_release(void* ctx) {
955    zxlogf(TRACE, "usb_dev_release\n");
956    usb_device_t* dev = ctx;
957    free(dev->config_desc);
958    for (unsigned i = 0; i < countof(dev->strings); i++) {
959        free(dev->strings[i]);
960    }
961    free(dev);
962}
963
964static zx_protocol_device_t device_proto = {
965    .version = DEVICE_OPS_VERSION,
966    .ioctl = usb_dev_ioctl,
967    .unbind = usb_dev_unbind,
968    .release = usb_dev_release,
969};
970
971#if defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)
972static zx_status_t usb_dev_set_default_config(usb_device_t* dev) {
973    usb_device_descriptor_t device_desc = {
974        .bLength = sizeof(usb_device_descriptor_t),
975        .bDescriptorType = USB_DT_DEVICE,
976        .bcdUSB = htole16(0x0200),
977        .bDeviceClass = 0,
978        .bDeviceSubClass = 0,
979        .bDeviceProtocol = 0,
980        .bMaxPacketSize0 = 64,
981        .idVendor = htole16(USB_DEVICE_VID),
982        .idProduct = htole16(USB_DEVICE_PID),
983        .bcdDevice = htole16(0x0100),
984        .bNumConfigurations = 1,
985    };
986
987    zx_status_t status = ZX_OK;
988
989#ifdef USB_DEVICE_MANUFACTURER
990    status = usb_device_alloc_string_desc(dev, USB_DEVICE_MANUFACTURER, &device_desc.iManufacturer);
991    if (status != ZX_OK) return status;
992#endif
993#ifdef USB_DEVICE_PRODUCT
994    usb_device_alloc_string_desc(dev, USB_DEVICE_PRODUCT, &device_desc.iProduct);
995    if (status != ZX_OK) return status;
996#endif
997#ifdef USB_DEVICE_SERIAL
998    usb_device_alloc_string_desc(dev, USB_DEVICE_SERIAL, &device_desc.iSerialNumber);
999    if (status != ZX_OK) return status;
1000#endif
1001
1002    status = usb_dev_set_device_desc(dev, &device_desc, sizeof(device_desc));
1003    if (status != ZX_OK) return status;
1004
1005    usb_function_descriptor_t function_desc;
1006    if (strcasecmp(USB_DEVICE_FUNCTIONS, "cdc") == 0) {
1007        function_desc.interface_class = USB_CLASS_COMM;
1008        function_desc.interface_subclass = USB_CDC_SUBCLASS_ETHERNET;
1009        function_desc.interface_protocol = 0;
1010    } else if (strcasecmp(USB_DEVICE_FUNCTIONS, "ums") == 0) {
1011        function_desc.interface_class = USB_CLASS_MSC;
1012        function_desc.interface_subclass = USB_SUBCLASS_MSC_SCSI;
1013        function_desc.interface_protocol = USB_PROTOCOL_MSC_BULK_ONLY;
1014    } else {
1015        zxlogf(ERROR, "usb_dev_set_default_config: unknown function %s\n", USB_DEVICE_FUNCTIONS);
1016        return ZX_ERR_INVALID_ARGS;
1017    }
1018
1019    status = usb_dev_add_function(dev, &function_desc, sizeof(function_desc));
1020    if (status != ZX_OK) return status;
1021
1022    return usb_dev_bind_functions(dev);
1023}
1024#endif // defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)
1025
1026zx_status_t usb_dev_bind(void* ctx, zx_device_t* parent) {
1027    zxlogf(INFO, "usb_dev_bind\n");
1028
1029    usb_device_t* dev = calloc(1, sizeof(usb_device_t));
1030    if (!dev) {
1031        return ZX_ERR_NO_MEMORY;
1032    }
1033    list_initialize(&dev->functions);
1034    mtx_init(&dev->lock, mtx_plain);
1035    dev->dci_dev = parent;
1036
1037    if (device_get_protocol(parent, ZX_PROTOCOL_USB_DCI, &dev->usb_dci)) {
1038        free(dev);
1039        return ZX_ERR_NOT_SUPPORTED;
1040    }
1041
1042    zx_status_t status = usb_dci_get_bti(&dev->usb_dci, &dev->bti_handle);
1043    if (status != ZX_OK) {
1044        free(dev);
1045        return status;
1046    }
1047
1048    if (device_get_protocol(parent, ZX_PROTOCOL_USB_MODE_SWITCH, &dev->usb_mode_switch)) {
1049        free(dev);
1050        return ZX_ERR_NOT_SUPPORTED;
1051    }
1052
1053    // Starting USB mode is determined from device metadata.
1054    // We read initial value and store it in dev->usb_mode, but do not actually
1055    // enable it until after all of our functions have bound.
1056    size_t actual;
1057    status = device_get_metadata(parent, DEVICE_METADATA_USB_MODE,
1058                                 &dev->usb_mode, sizeof(dev->usb_mode), &actual);
1059    if (status != ZX_OK || actual != sizeof(dev->usb_mode)) {
1060        zxlogf(ERROR, "usb_dev_bind: DEVICE_METADATA_USB_MODE not found\n");
1061        free(dev);
1062        return status;
1063    }
1064    // Set DCI mode to USB_MODE_NONE until we are ready
1065    usb_mode_switch_set_mode(&dev->usb_mode_switch, USB_MODE_NONE);
1066    dev->dci_usb_mode = USB_MODE_NONE;
1067
1068    device_add_args_t args = {
1069        .version = DEVICE_ADD_ARGS_VERSION,
1070        .name = "usb-peripheral",
1071        .ctx = dev,
1072        .ops = &device_proto,
1073        .proto_id = ZX_PROTOCOL_USB_PERIPHERAL,
1074        .flags = DEVICE_ADD_NON_BINDABLE,
1075    };
1076
1077    status = device_add(parent, &args, &dev->zxdev);
1078    if (status != ZX_OK) {
1079        zxlogf(ERROR, "usb_device_bind add_device failed %d\n", status);
1080        free(dev);
1081        return status;
1082    }
1083
1084    usb_dci_interface_t intf = {
1085        .ops = &dci_ops,
1086        .ctx = dev,
1087    };
1088    usb_dci_set_interface(&dev->usb_dci, &intf);
1089
1090#if defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)
1091    // set compile time configuration, if we have one
1092    usb_dev_set_default_config(dev);
1093#endif
1094
1095    return ZX_OK;
1096}
1097
1098static zx_driver_ops_t usb_device_ops = {
1099    .version = DRIVER_OPS_VERSION,
1100    .bind = usb_dev_bind,
1101};
1102
1103// clang-format off
1104ZIRCON_DRIVER_BEGIN(usb_device, usb_device_ops, "zircon", "0.1", 1)
1105    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_USB_DCI),
1106ZIRCON_DRIVER_END(usb_device)
1107