1 /************************************************************************************ 2 * include/nuttx/usb/usbdev.h 3 * 4 * Copyright (C) 2008-2010, 2012-2013, 2017 Gregory Nutt. All rights reserved. 5 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. 6 * Author: Gregory Nutt <gnutt@nuttx.org> 7 * 8 * NOTE: This interface was inspired by the Linux gadget interface by 9 * David Brownell. That work was very helpful in determining a usable 10 * partitioning of functionality between standard class drivers and various 11 * implementations of USB controller drivers. This work, however, does 12 * not derive directly from that work and is licensed differently. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 3. Neither the name NuttX nor the names of its contributors may be 25 * used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 35 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 36 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 * POSSIBILITY OF SUCH DAMAGE. 40 * 41 ************************************************************************************/ 42 /************************************************************************************ 43 * Notice of Export Control Law 44 * =============================================== 45 * Huawei LiteOS may be subject to applicable export control laws and regulations, 46 * which might include those applicable to Huawei LiteOS of U.S. and the country in 47 * which you are located. 48 * Import, export and usage of Huawei LiteOS in any manner by you shall be in 49 * compliance with such applicable export control laws and regulations. 50 ************************************************************************************/ 51 52 #ifndef __INCLUDE_NUTTX_USB_USBDEV_H 53 #define __INCLUDE_NUTTX_USB_USBDEV_H 54 55 /************************************************************************************ 56 * Included Files 57 ************************************************************************************/ 58 59 #include "implementation/global_implementation.h" 60 #include "linux/list.h" 61 #include "errno.h" 62 #define CONFIG_USBDEV_COMPOSITE 63 #define CONFIG_USBDEV_DMA 64 #define FAR 65 /************************************************************************************ 66 * Pre-processor Definitions 67 ************************************************************************************/ 68 69 /* Endpoint helpers *****************************************************************/ 70 71 /* Configure endpoint, making it usable. The class driver may deallocate or re-use 72 * the 'desc' structure after returning: 73 * 74 * ep - the struct usbdev_ep_s instance obtained from allocep() 75 * desc - A struct usb_epdesc_s instance describing the endpoint 76 * last - true if this this last endpoint to be configured. Some hardware needs 77 * to take special action when all of the endpoints have been configured. 78 */ 79 80 #define EP_CONFIGURE(ep, desc, last) (ep)->ops->configure(ep, desc, last) 81 82 /* The endpoint will no longer be used */ 83 84 #define EP_DISABLE(ep) (ep)->ops->disable(ep) 85 86 /* Allocate/free I/O requests. Should not be called from interrupt processing! */ 87 88 #define EP_ALLOCREQ(ep) (ep)->ops->allocreq(ep) 89 #define EP_FREEREQ(ep, req) (ep)->ops->freereq(ep, req) 90 91 /* Allocate/free an I/O buffer. Should not be called from interrupt processing! */ 92 93 #ifdef CONFIG_USBDEV_DMA 94 # define EP_ALLOCBUFFER(ep, nb) (ep)->ops->allocbuffer(ep, nb) 95 # define EP_FREEBUFFER(ep, buf) (ep)->ops->freebuffer(ep, buf) 96 #else 97 # define EP_ALLOCBUFFER(ep, nb) malloc(nb) 98 # define EP_FREEBUFFER(ep, buf) free(buf) 99 #endif 100 101 /* Submit an I/O request to the endpoint */ 102 103 #define EP_SUBMIT(ep, req) (ep)->ops->submit(ep, req) 104 105 /* Cancel an I/O request previously sent to an endpoint */ 106 107 #define EP_CANCEL(ep, req) (ep)->ops->cancel(ep, req) 108 109 /* Stall or resume an endpoint */ 110 111 #define EP_STALL(ep) (ep)->ops->stall(ep, false) 112 #define EP_RESUME(ep) (ep)->ops->stall(ep, true) 113 114 #define EP_FLUSH(ep) (ep)->ops->flush(ep) 115 116 /* USB Device Driver Helpers ********************************************************/ 117 118 /* Allocate an endpoint: 119 * 120 * ep - 7-bit logical endpoint number (direction bit ignored). Zero means 121 * that any endpoint matching the other requirements will suffice. The 122 * assigned endpoint can be found in the eplog field. 123 * in - true: IN (device-to-host) endpoint requested 124 * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, 125 * USB_EP_ATTR_XFER_INT} 126 */ 127 128 #define DEV_ALLOCEP(dev, ep, desc) (dev)->ops->allocep(dev, ep, desc) 129 130 /* Release an endpoint */ 131 132 #define DEV_FREEEP(dev, ep) (dev)->ops->freeep(dev, ep) 133 134 /* Returns the current frame number */ 135 136 #define DEV_GETFRAME(dev) (dev)->ops->getframe(dev) 137 138 /* Tries to wake up the host connected to this device */ 139 140 #define DEV_WAKEUP(dev) (dev)->ops->wakeup(dev) 141 142 /* Sets the device selfpowered feature */ 143 144 #define DEV_SETSELFPOWERED(dev) (dev)->ops->selfpowered(dev, true) 145 146 /* Clears the device selfpowered feature */ 147 148 #define DEV_CLRSELFPOWERED(dev) (dev)->ops->selfpowered(dev, false) 149 150 /* Software-controlled connect to USB host. All USB class drivers need to call 151 * DEV_CONNECT() when they are ready to be enumerated. That is, (1) initially when 152 * bound to the USB driver, and (2) after a USB reset. 153 */ 154 155 #define DEV_CONNECT(dev) (dev)->ops->pullup ? (dev)->ops->pullup(dev, true) : -EOPNOTSUPP 156 157 /* Software-controlled disconnect from USB host */ 158 159 #define DEV_DISCONNECT(dev) (dev)->ops->pullup ? (dev)->ops->pullup(dev, false) : -EOPNOTSUPP 160 161 /* USB Class Driver Helpers *********************************************************/ 162 /* All may be called from interrupt handling logic except bind() and unbind() */ 163 164 /* Invoked when the driver is bound to a USB device driver. */ 165 166 #define CLASS_BIND(drvr, dev) (drvr)->ops->bind(drvr, dev) 167 168 /* Invoked when the driver is unbound from a USB device driver */ 169 170 #define CLASS_UNBIND(drvr, dev) (drvr)->ops->unbind(drvr, dev) 171 172 /* Invoked after all transfers have been stopped, when the host is disconnected. */ 173 174 #define CLASS_DISCONNECT(drvr, dev) (drvr)->ops->disconnect(drvr, dev) 175 176 /* Invoked for ep0 control requests */ 177 178 #define CLASS_SETUP(drvr, dev, ctrl, dataout, outlen) \ 179 (drvr)->ops->setup(drvr, dev, ctrl, dataout, outlen) 180 181 /* Invoked on USB suspend. */ 182 183 #define CLASS_SUSPEND(drvr, dev) \ 184 do { if ((drvr)->ops->suspend) (drvr)->ops->suspend(drvr, dev); } while (0) 185 186 /* Invoked on USB resume */ 187 188 #define CLASS_RESUME(drvr, dev) \ 189 do { if ((drvr)->ops->resume) (drvr)->ops->resume(drvr, dev); } while (0) 190 191 /* Maximum size of a request buffer */ 192 193 #define USBDEV_MAXREQUEUST UINT16_MAX 194 195 #define USBDEV_MAX_EPNUM 5 196 197 /* Request flags */ 198 199 #define USBDEV_REQFLAGS_NULLPKT 1 /* Bit 0: Terminate w/short packet; null packet if necessary */ 200 /* Bits 1-7: Available */ 201 202 /* USB directions (in endpoint addresses) */ 203 204 #define USB_EPNO_MASK (0x7f) 205 #define USB_EPNO(addr) ((addr) & USB_EPNO_MASK) 206 #define USB_EPOUT(addr) ((addr) | USB_DIR_OUT) 207 #define USB_EPIN(addr) ((addr) | USB_DIR_IN) 208 #define USB_ISEPIN(addr) (((addr) & USB_DIR_MASK) == USB_DIR_IN) 209 #define USB_ISEPOUT(addr) (((addr) & USB_DIR_MASK) == USB_DIR_OUT) 210 211 212 /************************************************************************************ 213 * Public Types 214 ************************************************************************************/ 215 216 /* USB Controller Structures ********************************************************/ 217 218 /* usbdev_devinfo_s - describes the low level bindings of an usb device */ 219 220 struct usbdev_devinfo_s 221 { 222 int ninterfaces; /* Number of interfaces in the configuration */ 223 int ifnobase; /* Offset to Interface-IDs */ 224 225 int nstrings; /* Number of Strings */ 226 int strbase; /* Offset to String Numbers */ 227 228 int nendpoints; /* Number of Endpoints referenced in the following allay */ 229 int epno[USBDEV_MAX_EPNUM]; /* Array holding the endpoint configuration for this device */ 230 }; 231 232 struct usbdevclass_driver_s; 233 struct composite_devdesc_s 234 { 235 void (*mkdevdesc)(uint8_t *buf); 236 int16_t (*mkconfdesc)(uint8_t *buf, struct usbdev_devinfo_s *devinfo); 237 int (*mkstrdesc)(uint8_t id, uint8_t *buf); 238 int (*classobject)(int minor, struct usbdev_devinfo_s *devinfo, struct usbdevclass_driver_s **classdev); 239 void (*uninitialize)(struct usbdevclass_driver_s *classdev); 240 241 int nconfigs; /* Number of configurations supported */ 242 int configid; /* The only supported configuration ID */ 243 244 int cfgdescsize; /* The size of the config descriptor */ 245 int minor; 246 247 struct usbdev_devinfo_s devinfo; 248 }; 249 250 /* struct usbdev_req_s - describes one i/o request */ 251 252 struct usbdev_ep_s; 253 struct usbdev_req_s 254 { 255 uint8_t *buf; /* Call: Buffer used for data; Return: Unchanged */ 256 uint8_t flags; /* See USBDEV_REQFLAGS_* definitions */ 257 int16_t result; /* Call: zero; Return: Result of transfer (O or -errno) */ 258 uint32_t len; /* Call: Total length of data in buf; Return: Unchanged */ 259 uint32_t xfrd; /* Call: zero; Return: Bytes transferred so far */ 260 261 /* Callback when the transfer completes */ 262 263 void (*callback)(struct usbdev_ep_s *ep, struct usbdev_req_s *req); 264 void *priv; /* Used only by callee */ 265 int is_complete; 266 struct list_head list; 267 268 /* Added in device3.0 */ 269 270 #if defined(LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER) 271 uintptr_t dma; 272 uint32_t stream_id; 273 uint8_t zero; 274 #endif 275 }; 276 277 /* Endpoint-specific interface to USB controller hardware. */ 278 279 struct usbdev_epops_s 280 { 281 /* Configure/enable and disable endpoint */ 282 283 int (*configure)(struct usbdev_ep_s *ep, const usb_endpoint_descriptor_t *desc, 284 bool last); 285 int (*disable)(struct usbdev_ep_s *ep); 286 287 /* Allocate and free I/O requests */ 288 289 struct usbdev_req_s *(*allocreq)(FAR struct usbdev_ep_s *ep); 290 void (*freereq)(struct usbdev_ep_s *ep, struct usbdev_req_s *req); 291 292 /* Allocate and free I/O buffers */ 293 294 void *(*allocbuffer)(struct usbdev_ep_s *ep, uint16_t nbytes); 295 void (*freebuffer)(struct usbdev_ep_s *ep, void *buf); 296 297 /* Submit and cancel I/O requests */ 298 299 int (*submit)(struct usbdev_ep_s *ep, struct usbdev_req_s *req); 300 int (*cancel)(struct usbdev_ep_s *ep, struct usbdev_req_s *req); 301 302 /* Stall or resume an endpoint */ 303 304 int (*stall)(struct usbdev_ep_s *ep, bool resume); 305 void (*flush)(struct usbdev_ep_s *ep); 306 }; 307 308 /* Representation of one USB endpoint */ 309 310 struct usbdev_ep_s 311 { 312 const struct usbdev_epops_s *ops; /* Endpoint operations */ 313 uint8_t eplog; /* Logical endpoint address */ 314 uint8_t used; 315 uint16_t maxpacket; /* Maximum packet size for this endpoint */ 316 void *priv; /* For use by class driver */ 317 void *ep_link; 318 struct usbdev_req_s *handle_req; 319 320 /* Added in device3.0 */ 321 322 #if defined(LOSCFG_DRIVERS_USB3_DEVICE_CONTROLLER) 323 uint16_t maxpacket_limit:16; 324 uint16_t max_streams:16; 325 uint16_t mult:2; 326 uint16_t maxburst:5; 327 const struct usb_endpoint_ss_comp_descriptor *comp_desc; 328 #endif 329 }; 330 331 /* struct usbdev_s represents a usb device */ 332 333 struct usbdev_s; 334 struct usbdev_ops_s 335 { 336 /* Allocate and free endpoints */ 337 338 struct usbdev_ep_s *(*allocep)(struct usbdev_s *dev, uint8_t eplog, usb_endpoint_descriptor_t *desc); 339 void (*freeep)(struct usbdev_s *dev, struct usbdev_ep_s *ep); 340 341 /* Get the frame number from the last SOF */ 342 343 int (*getframe)(struct usbdev_s *dev); 344 345 /* Hardware specific features */ 346 347 int (*wakeup)(struct usbdev_s *dev); 348 int (*selfpowered)(struct usbdev_s *dev, bool selfpowered); 349 int (*pullup)(struct usbdev_s *dev, bool enable); 350 351 /* Device-specific I/O command support */ 352 353 int (*ioctl)(struct usbdev_s *dev, unsigned code, unsigned long param); 354 }; 355 356 struct usbdev_s 357 { 358 const struct usbdev_ops_s *ops; /* Access to hardware specific features */ 359 struct usbdev_ep_s *ep0; /* Endpoint zero */ 360 uint8_t speed; /* Current speed of the host connection */ 361 uint8_t dualspeed:1; /* 1:supports high and full speed operation */ 362 }; 363 364 /* USB Device Class Implementations *************************************************/ 365 366 struct usbdevclass_driverops_s 367 { 368 int (*bind)(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 369 int (*unbind)(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 370 int (*setup)(struct usbdevclass_driver_s *driver, struct usbdev_s *dev, 371 const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen); 372 void (*disconnect)(struct usbdevclass_driver_s *driver, 373 struct usbdev_s *dev); 374 void (*suspend)(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 375 void (*resume)(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 376 }; 377 378 struct usbdevclass_driver_s 379 { 380 struct usbdevclass_driverops_s *ops; 381 uint8_t speed; /* Highest speed that the driver handles */ 382 }; 383 384 /************************************************************************************ 385 * Public Data 386 ************************************************************************************/ 387 388 #undef EXTERN 389 #if defined(__cplusplus) 390 # define EXTERN extern "C" 391 extern "C" 392 { 393 #else 394 # define EXTERN extern 395 #endif 396 397 /************************************************************************************ 398 * Public Functions 399 ************************************************************************************/ 400 401 /************************************************************************************ 402 * Name: usbdevclass_register 403 * 404 * Description: 405 * Register a USB device class driver. The class driver's bind() method will be 406 * called to bind it to a USB device driver. 407 * 408 ************************************************************************************/ 409 410 int usbdev_register(struct usbdevclass_driver_s *driver); 411 412 /************************************************************************************ 413 * Name: usbdev_unregister 414 * 415 * Description: 416 * Un-register usbdev class driver.If the USB device is connected to a USB host, 417 * it will first disconnect(). The driver is also requested to unbind() and clean 418 * up any device state, before this procedure finally returns. 419 * 420 ************************************************************************************/ 421 422 int usbdev_unregister(struct usbdevclass_driver_s *driver); 423 424 /**************************************************************************** 425 * Name: usbdev_dma_alloc and usbdev_dma_free 426 * 427 * Description: 428 * The USB class driver allocates packet I/O buffers for data transfer by 429 * calling the driver allocbuffer() and freebuffer() methods. Those 430 * methods are only available if CONFIG_USBDEV_DMA is defined in the 431 * system configuration. 432 * 433 * If CONFIG_USBDEV_DMAMEMORY is also defined in the NuttX configuration, 434 * then the driver implementations of the allocbuffer() and freebuffer() 435 * methods may use board-specific usbdev_dma_alloc() and usbdev_dma_free(). 436 * If CONFIG_USBDEV_DMA and CONFIG_USBDEV_DMAMEMORY are both defined, 437 * then the board-specific logic must provide the functions 438 * usbdev_dma_alloc() and usbdev_dma_free() as prototyped below: 439 * usbdev_dma_alloc() will allocate DMA-capable memory of the specified 440 * size; usbdev_dma_free() is the corresponding function that will be 441 * called to free the DMA-capable memory. 442 * 443 * This functions may be simple wrappers around gran_alloc() and 444 * gran_free() (See nuttx/mm/gran.h). Note that the gran_free() function 445 * does require the size of the allocation to be freed; that would need 446 * to be managed in the board-specific logic. 447 * 448 ****************************************************************************/ 449 450 #if defined(CONFIG_USBDEV_DMA) && defined(CONFIG_USBDEV_DMAMEMORY) 451 void *usbdev_dma_alloc(size_t size); 452 void usbdev_dma_free(void *memory); 453 #endif 454 455 #undef EXTERN 456 #if defined(__cplusplus) 457 } 458 #endif 459 460 #endif /* __INCLUDE_NUTTX_USB_USBDEV_H */ 461