1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12/* 13 * These functions need to be implemented by platform 14 * specific code. 15 */ 16 17#ifndef __USB_USB_HOST_H_ 18#define __USB_USB_HOST_H_ 19 20#include <platsupport/io.h> 21#include <platsupport/sync/sync.h> 22#include <usb/plat/usb.h> 23 24enum usb_speed { 25/// 1.5Mbps connection 26 USBSPEED_LOW = 0, 27/// 12Mbps connection 28 USBSPEED_FULL = 1, 29/// 480Mbps connection 30 USBSPEED_HIGH = 2 31}; 32 33/* 34 * Endpoint types 35 * NOTE: do not change the defined order, see USB 2.0 spec(9.6.6) 36 */ 37enum usb_endpoint_type { 38 EP_CONTROL = 0, 39 EP_ISOCHRONOUS, 40 EP_BULK, 41 EP_INTERRUPT 42}; 43 44/* NOTE: do not change the defined order, see USB 2.0 spec(9.6.6) */ 45enum usb_endpoint_dir { 46 EP_DIR_OUT = 0, 47 EP_DIR_IN 48}; 49 50struct endpoint { 51 enum usb_endpoint_type type; 52 uint8_t num; // Endpoint number 53 enum usb_endpoint_dir dir; // Endpoint direction 54 uint16_t max_pkt; // Maximum packet size 55 uint8_t interval; // Interval for polling or NAK rate for Bulk/Control 56 57 /* For host controller driver only, actually holds queue head. */ 58 void *hcpriv; 59}; 60 61enum usb_xact_type { 62/// Input PID 63 PID_IN, 64/// Output PID 65 PID_OUT, 66/// Setup PID 67 PID_SETUP 68}; 69 70enum usb_xact_status { 71/// The transaction completed successfully 72 XACTSTAT_SUCCESS, 73/// The transaction has not been processed 74 XACTSTAT_PENDING, 75/// The transaction was cancelled due to disconnect, etc 76 XACTSTAT_CANCELLED, 77/// There was an error in processing the transaction 78 XACTSTAT_ERROR, 79/// The host exhibited a failure during the transaction. 80 XACTSTAT_HOSTERROR 81}; 82 83/* 84 * XXX: The xact size has to meet the QTD limitation. We only allocate one QTD 85 * for each xact. 86 */ 87#define MAX_XACT_SIZE (5 * PAGE_SIZE_4K) 88struct xact { 89/// Transfer type 90 enum usb_xact_type type; 91/// DMA buffer to exchange 92 void* vaddr; 93 uintptr_t paddr; 94/// The length of @ref{buf} 95 int len; 96}; 97 98static inline void* xact_get_vaddr(struct xact* xact) 99{ 100 return xact->vaddr; 101} 102 103static inline uintptr_t xact_get_paddr(struct xact* xact) 104{ 105 return xact->paddr; 106} 107 108/** Callback type for asynchronous USB transactions 109 * @param[in] token An unmodified opaque token as passed to 110 * the associated transaction request. 111 * @param[in] stat The status of the transaction. 112 * @param[in] rbytes The number of bytes remaining in the transaction. 113 * This value is generally 0 on successful transmission 114 * unless a short read or write occurs. 115 * @return 1 if the transaction should be rescheduled, 116 * otherwise, 0. 117 */ 118typedef int (*usb_cb_t)(void* token, enum usb_xact_status stat, int rbytes); 119 120struct usb_host; 121typedef struct usb_host usb_host_t; 122 123struct usb_host { 124 /// Device ID 125 enum usb_host_id id; 126 /// Number of ports provided by this host controller 127 int nports; 128 129 /// DMA allocator 130 ps_dma_man_t* dman; 131 132 /// Synchronization operations 133 ps_mutex_ops_t* sync; 134 135 /// Submit a transaction for transfer. 136 int (*schedule_xact)(usb_host_t* hdev, uint8_t addr, int8_t hub_addr, uint8_t hub_port, 137 enum usb_speed speed, struct endpoint *ep, 138 struct xact* xact, int nxact, usb_cb_t cb, void* t); 139 /// Cancel all transactions for a given device endpoint 140 int (*cancel_xact)(usb_host_t* hdev, struct endpoint *ep); 141 /// Handle an IRQ 142 void (*handle_irq)(usb_host_t* hdev); 143 144 /// IRQ numbers tied to this device 145 const int* irqs; 146 /// Host private data 147 struct usb_hc_data* pdata; 148}; 149 150 151/** 152 * Schedules a USB transaction 153 * @param[in] hdev The host controller that should be used for the transfer 154 * @param[in] addr The destination USB device address 155 * @param[in] hub_addr The USB device address of the hub at which the destination 156 * device is connected. -1 must be used if the device is not 157 * connected to a hub (i.e. when it is the root hub). 158 * 0 may be used if the device is a SPEED_FULL device. 159 * @param[in] hub_port The port at which the destination device is connected to 160 * its parent hub. 161 * 0 may be used if the device is a SPEED_FULL device. 162 * @param[in] speed The USB speed of the device. 163 * @param[in] ep The destination endpoint of the destination device. 164 * @param[in] xact An array of packet descriptors. 165 * @param[in] nxact The number of packet descriptors in the array. 166 * @param[in] cb A callback function to call on completion. 167 * NULL will result in blocking operation. 168 * @param[in] t A token to pass, unmodified, to the provided callback 169 * function on completion. 170 * @return Negative values represent failure, otherwise, the 171 * number of bytes remaining to be transferred is returned. 172 */ 173static inline int 174usb_hcd_schedule(usb_host_t* hdev, uint8_t addr, uint8_t hub_addr, uint8_t hub_port, 175 enum usb_speed speed, struct endpoint *ep, 176 struct xact* xact, int nxact, usb_cb_t cb, void* t) 177{ 178 return hdev->schedule_xact(hdev, addr, hub_addr, hub_port, speed, ep, 179 xact, nxact, cb, t); 180} 181 182static inline void 183usb_hcd_handle_irq(usb_host_t* hdev) 184{ 185 hdev->handle_irq(hdev); 186} 187 188static inline int 189usb_hcd_count_ports(usb_host_t* hdev) 190{ 191 return hdev->nports; 192} 193 194/** 195 * Initialise USB host controller. 196 * This function should only be called if you wish to use a raw API for the usb host controller, otherwise, 197 * this function will be called by usb_init and the appropriate book keeping for device management 198 * will be created and maintained. 199 * @param[in] id The id of the host controller to initialise 200 * @param[in] ioops a list of io operation functions. 201 * of the initialised host controller 202 * @param[in] sync a list of mutex operation functions. 203 * @param[out] hdev A host structure to populate. This must 204 * already be filled with a DMA allocator. 205 * and the device ID. 206 * @return 0 on success 207 */ 208int usb_host_init(enum usb_host_id id, ps_io_ops_t* ioops, ps_mutex_ops_t *sync, usb_host_t* hdev); 209 210/** Return a list of IRQ numbers handled by the provided host 211 * @param[in] host A handle to the USB host device in question 212 * @param[out] nirqs The number of IRQs handled by this host. 213 * @return A NULL terminated list of IRQs 214 */ 215const int* usb_host_irqs(usb_host_t* host, int* nirqs); 216 217 218#endif /* __USB_USB_HOST_H_ */ 219 220