1 // Copyright 2016 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 #pragma once 6 7 #include <ddk/binding.h> 8 #include <ddk/device.h> 9 #include <ddk/protocol/usb/hci.h> 10 #include <ddk/protocol/usb/hub.h> 11 #include <usb/usb-request.h> 12 #include <lib/sync/completion.h> 13 #include <zircon/hw/usb.h> 14 15 #include <threads.h> 16 #include <stdatomic.h> 17 18 typedef struct usb_bus usb_bus_t; 19 20 // Represents a USB top-level device 21 typedef struct usb_device { 22 zx_device_t* zxdev; 23 zx_device_t* hci_zxdev; 24 usb_hci_protocol_t hci; 25 usb_bus_t* bus; 26 27 // ID assigned by host controller 28 uint32_t device_id; 29 // device_id of the hub we are attached to (or zero for root hub) 30 uint32_t hub_id; 31 usb_speed_t speed; 32 33 // Interface to talk to the hub driver 34 usb_hub_interface_t hub_intf; 35 36 usb_device_descriptor_t device_desc; 37 usb_configuration_descriptor_t** config_descs; 38 uint8_t current_config_index; 39 uint8_t num_configurations; 40 41 atomic_bool langids_fetched; 42 atomic_uintptr_t lang_ids; 43 44 bool resetting; 45 // mutex that protects the resetting state member 46 mtx_t state_lock; 47 48 // thread for calling client's usb request complete callback 49 thrd_t callback_thread; 50 bool callback_thread_stop; 51 // completion used for signalling callback_thread 52 sync_completion_t callback_thread_completion; 53 // list of requests that need to have client's completion callback called 54 list_node_t completed_reqs; 55 // mutex that protects the callback_* members above 56 mtx_t callback_lock; 57 58 // pool of requests that can be reused 59 usb_request_pool_t free_reqs; 60 size_t parent_req_size; 61 size_t req_size; 62 } usb_device_t; 63 64 void usb_device_set_hub_interface(usb_device_t* dev, const usb_hub_interface_t* hub_intf); 65 66 zx_status_t usb_device_add(usb_bus_t* bus, uint32_t device_id, uint32_t hub_id, 67 usb_speed_t speed, usb_device_t** out_device); 68 69 zx_status_t usb_device_reinitialize(usb_device_t* dev); 70 71 #define USB_REQ_TO_DEV_INTERNAL(req, size) \ 72 ((usb_device_req_internal_t *)((uintptr_t)(req) + (size))) 73 #define DEV_INTERNAL_TO_USB_REQ(ctx, size) ((usb_request_t *)((uintptr_t)(ctx) - (size))) 74