blob: bcb1ad3082c0e3e3536133a3df4cf70a1efd10b1 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenk29e7f5a2004-03-12 00:14:09 +00002/*
3 * (C) Copyright 2003
4 * Gerry Hamel, geh@ti.com, Texas Instruments
5 *
6 * Based on
7 * linux/drivers/usbd/usbd.c.c - USB Device Core Layer
8 *
9 * Copyright (c) 2000, 2001, 2002 Lineo
10 * Copyright (c) 2001 Hewlett Packard
11 *
12 * By:
13 * Stuart Lynne <sl@lineo.com>,
14 * Tom Rushworth <tbr@lineo.com>,
15 * Bruce Balden <balden@lineo.com>
wdenk29e7f5a2004-03-12 00:14:09 +000016 */
17
Simon Glass0f2af882020-05-10 11:40:05 -060018#include <log.h>
wdenk29e7f5a2004-03-12 00:14:09 +000019#include <malloc.h>
Simon Glassbd7a59a2019-11-14 12:57:23 -070020#include <serial.h>
Jean-Christophe PLAGNIOL-VILLARD8f6bcf42009-04-03 12:46:58 +020021#include <usbdevice.h>
wdenk29e7f5a2004-03-12 00:14:09 +000022
23#define MAX_INTERFACES 2
24
wdenk29e7f5a2004-03-12 00:14:09 +000025int maxstrings = 20;
26
27/* Global variables ************************************************************************** */
28
29struct usb_string_descriptor **usb_strings;
30
31int usb_devices;
32
33extern struct usb_function_driver ep0_driver;
34
35int registered_functions;
36int registered_devices;
37
Pali Rohár2cecb462020-12-26 19:12:11 +010038__maybe_unused static char *usbd_device_events[] = {
wdenk29e7f5a2004-03-12 00:14:09 +000039 "DEVICE_UNKNOWN",
40 "DEVICE_INIT",
41 "DEVICE_CREATE",
42 "DEVICE_HUB_CONFIGURED",
43 "DEVICE_RESET",
44 "DEVICE_ADDRESS_ASSIGNED",
45 "DEVICE_CONFIGURED",
46 "DEVICE_SET_INTERFACE",
47 "DEVICE_SET_FEATURE",
48 "DEVICE_CLEAR_FEATURE",
49 "DEVICE_DE_CONFIGURED",
50 "DEVICE_BUS_INACTIVE",
51 "DEVICE_BUS_ACTIVITY",
52 "DEVICE_POWER_INTERRUPTION",
53 "DEVICE_HUB_RESET",
54 "DEVICE_DESTROY",
55 "DEVICE_FUNCTION_PRIVATE",
56};
57
Pali Rohár2cecb462020-12-26 19:12:11 +010058__maybe_unused static char *usbd_device_status[] = {
wdenk29e7f5a2004-03-12 00:14:09 +000059 "USBD_OPENING",
60 "USBD_OK",
61 "USBD_SUSPENDED",
62 "USBD_CLOSING",
63};
64
Pali Rohár2cecb462020-12-26 19:12:11 +010065#define USBD_DEVICE_STATUS(x) (((unsigned int)x <= USBD_CLOSING) ? usbd_device_status[x] : "UNKNOWN")
66
wdenk29e7f5a2004-03-12 00:14:09 +000067/* Descriptor support functions ************************************************************** */
68
wdenk29e7f5a2004-03-12 00:14:09 +000069/**
70 * usbd_get_string - find and return a string descriptor
71 * @index: string index to return
72 *
73 * Find an indexed string and return a pointer to a it.
74 */
75struct usb_string_descriptor *usbd_get_string (__u8 index)
76{
77 if (index >= maxstrings) {
78 return NULL;
79 }
80 return usb_strings[index];
81}
82
wdenk29e7f5a2004-03-12 00:14:09 +000083/* Access to device descriptor functions ***************************************************** */
84
wdenk29e7f5a2004-03-12 00:14:09 +000085/* *
86 * usbd_device_configuration_instance - find a configuration instance for this device
87 * @device:
88 * @configuration: index to configuration, 0 - N-1
89 *
90 * Get specifed device configuration. Index should be bConfigurationValue-1.
91 */
92static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
93 unsigned int port, unsigned int configuration)
94{
Harald Welteed1c3f02008-07-07 00:58:05 +080095 if (configuration >= device->configurations)
wdenk29e7f5a2004-03-12 00:14:09 +000096 return NULL;
Harald Welteed1c3f02008-07-07 00:58:05 +080097
wdenk29e7f5a2004-03-12 00:14:09 +000098 return device->configuration_instance_array + configuration;
99}
100
wdenk29e7f5a2004-03-12 00:14:09 +0000101/* *
102 * usbd_device_interface_instance
103 * @device:
104 * @configuration: index to configuration, 0 - N-1
105 * @interface: index to interface
106 *
107 * Return the specified interface descriptor for the specified device.
108 */
109struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *device, int port, int configuration, int interface)
110{
111 struct usb_configuration_instance *configuration_instance;
112
113 if ((configuration_instance = usbd_device_configuration_instance (device, port, configuration)) == NULL) {
114 return NULL;
115 }
116 if (interface >= configuration_instance->interfaces) {
117 return NULL;
118 }
119 return configuration_instance->interface_instance_array + interface;
120}
121
122/* *
123 * usbd_device_alternate_descriptor_list
124 * @device:
125 * @configuration: index to configuration, 0 - N-1
126 * @interface: index to interface
127 * @alternate: alternate setting
128 *
129 * Return the specified alternate descriptor for the specified device.
130 */
131struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *device, int port, int configuration, int interface, int alternate)
132{
133 struct usb_interface_instance *interface_instance;
134
135 if ((interface_instance = usbd_device_interface_instance (device, port, configuration, interface)) == NULL) {
136 return NULL;
137 }
138
139 if (alternate >= interface_instance->alternates) {
140 return NULL;
141 }
142
143 return interface_instance->alternates_instance_array + alternate;
144}
145
wdenk29e7f5a2004-03-12 00:14:09 +0000146/* *
147 * usbd_device_device_descriptor
148 * @device: which device
149 * @configuration: index to configuration, 0 - N-1
150 * @port: which port
151 *
152 * Return the specified configuration descriptor for the specified device.
153 */
154struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port)
155{
156 return (device->device_descriptor);
157}
158
wdenk29e7f5a2004-03-12 00:14:09 +0000159/**
160 * usbd_device_configuration_descriptor
161 * @device: which device
162 * @port: which port
163 * @configuration: index to configuration, 0 - N-1
164 *
165 * Return the specified configuration descriptor for the specified device.
166 */
167struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct
168 usb_device_instance
169 *device, int port, int configuration)
170{
171 struct usb_configuration_instance *configuration_instance;
172 if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) {
173 return NULL;
174 }
175 return (configuration_instance->configuration_descriptor);
176}
177
wdenk29e7f5a2004-03-12 00:14:09 +0000178/**
179 * usbd_device_interface_descriptor
180 * @device: which device
181 * @port: which port
182 * @configuration: index to configuration, 0 - N-1
183 * @interface: index to interface
184 * @alternate: alternate setting
185 *
186 * Return the specified interface descriptor for the specified device.
187 */
188struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance
189 *device, int port, int configuration, int interface, int alternate)
190{
191 struct usb_interface_instance *interface_instance;
192 if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) {
193 return NULL;
194 }
195 if ((alternate < 0) || (alternate >= interface_instance->alternates)) {
196 return NULL;
197 }
198 return (interface_instance->alternates_instance_array[alternate].interface_descriptor);
199}
200
201/**
202 * usbd_device_endpoint_descriptor_index
203 * @device: which device
204 * @port: which port
205 * @configuration: index to configuration, 0 - N-1
206 * @interface: index to interface
207 * @alternate: index setting
208 * @index: which index
209 *
210 * Return the specified endpoint descriptor for the specified device.
211 */
212struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance
213 *device, int port, int configuration, int interface, int alternate, int index)
214{
215 struct usb_alternate_instance *alternate_instance;
216
217 if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
218 return NULL;
219 }
220 if (index >= alternate_instance->endpoints) {
221 return NULL;
222 }
223 return *(alternate_instance->endpoints_descriptor_array + index);
224}
225
wdenk29e7f5a2004-03-12 00:14:09 +0000226/**
227 * usbd_device_endpoint_transfersize
228 * @device: which device
229 * @port: which port
230 * @configuration: index to configuration, 0 - N-1
231 * @interface: index to interface
232 * @index: which index
233 *
234 * Return the specified endpoint transfer size;
235 */
236int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index)
237{
238 struct usb_alternate_instance *alternate_instance;
239
240 if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
241 return 0;
242 }
243 if (index >= alternate_instance->endpoints) {
244 return 0;
245 }
246 return *(alternate_instance->endpoint_transfersize_array + index);
247}
248
wdenk29e7f5a2004-03-12 00:14:09 +0000249/**
250 * usbd_device_endpoint_descriptor
251 * @device: which device
252 * @port: which port
253 * @configuration: index to configuration, 0 - N-1
254 * @interface: index to interface
255 * @alternate: alternate setting
256 * @endpoint: which endpoint
257 *
258 * Return the specified endpoint descriptor for the specified device.
259 */
260struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint)
261{
262 struct usb_endpoint_descriptor *endpoint_descriptor;
263 int i;
264
265 for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) {
266 if (endpoint_descriptor->bEndpointAddress == endpoint) {
267 return endpoint_descriptor;
268 }
269 }
270 return NULL;
271}
272
273/**
274 * usbd_endpoint_halted
275 * @device: point to struct usb_device_instance
276 * @endpoint: endpoint to check
277 *
278 * Return non-zero if endpoint is halted.
279 */
280int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint)
281{
282 return (device->status == USB_STATUS_HALT);
283}
284
wdenk29e7f5a2004-03-12 00:14:09 +0000285/**
286 * usbd_rcv_complete - complete a receive
287 * @endpoint:
288 * @len:
289 * @urb_bad:
290 *
291 * Called from rcv interrupt to complete.
292 */
293void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad)
294{
295 if (endpoint) {
296 struct urb *rcv_urb;
297
298 /*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */
299
300 /* if we had an urb then update actual_length, dispatch if neccessary */
301 if ((rcv_urb = endpoint->rcv_urb)) {
302
303 /*usbdbg("actual: %d buffer: %d\n", */
304 /*rcv_urb->actual_length, rcv_urb->buffer_length); */
305
306 /* check the urb is ok, are we adding data less than the packetsize */
307 if (!urb_bad && (len <= endpoint->rcv_packetSize)) {
308 /*usbdbg("updating actual_length by %d\n",len); */
309
310 /* increment the received data size */
311 rcv_urb->actual_length += len;
312
313 } else {
314 usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n",
315 rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad);
316
317 rcv_urb->actual_length = 0;
318 rcv_urb->status = RECV_ERROR;
319 }
320 } else {
321 usberr("no rcv_urb!");
322 }
323 } else {
324 usberr("no endpoint!");
325 }
326
327}
328
329/**
330 * usbd_tx_complete - complete a transmit
331 * @endpoint:
332 * @resetart:
333 *
334 * Called from tx interrupt to complete.
335 */
336void usbd_tx_complete (struct usb_endpoint_instance *endpoint)
337{
338 if (endpoint) {
339 struct urb *tx_urb;
340
341 /* if we have a tx_urb advance or reset, finish if complete */
342 if ((tx_urb = endpoint->tx_urb)) {
343 int sent = endpoint->last;
344 endpoint->sent += sent;
345 endpoint->last -= sent;
346
347 if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {
348 tx_urb->actual_length = 0;
349 endpoint->sent = 0;
350 endpoint->last = 0;
351
352 /* Remove from active, save for re-use */
353 urb_detach(tx_urb);
354 urb_append(&endpoint->done, tx_urb);
355 /*usbdbg("done->next %p, tx_urb %p, done %p", */
356 /* endpoint->done.next, tx_urb, &endpoint->done); */
357
358 endpoint->tx_urb = first_urb_detached(&endpoint->tx);
359 if( endpoint->tx_urb ) {
360 endpoint->tx_queue--;
361 usbdbg("got urb from tx list");
362 }
363 if( !endpoint->tx_urb ) {
364 /*usbdbg("taking urb from done list"); */
365 endpoint->tx_urb = first_urb_detached(&endpoint->done);
366 }
367 if( !endpoint->tx_urb ) {
368 usbdbg("allocating new urb for tx_urb");
369 endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint);
370 }
371 }
372 }
373 }
374}
375
376/* URB linked list functions ***************************************************** */
377
378/*
379 * Initialize an urb_link to be a single element list.
380 * If the urb_link is being used as a distinguished list head
381 * the list is empty when the head is the only link in the list.
382 */
383void urb_link_init (urb_link * ul)
384{
385 if (ul) {
386 ul->prev = ul->next = ul;
387 }
388}
389
390/*
391 * Detach an urb_link from a list, and set it
392 * up as a single element list, so no dangling
393 * pointers can be followed, and so it can be
394 * joined to another list if so desired.
395 */
396void urb_detach (struct urb *urb)
397{
398 if (urb) {
399 urb_link *ul = &urb->link;
400 ul->next->prev = ul->prev;
401 ul->prev->next = ul->next;
402 urb_link_init (ul);
403 }
404}
405
406/*
407 * Return the first urb_link in a list with a distinguished
408 * head "hd", or NULL if the list is empty. This will also
409 * work as a predicate, returning NULL if empty, and non-NULL
410 * otherwise.
411 */
412urb_link *first_urb_link (urb_link * hd)
413{
414 urb_link *nx;
415 if (NULL != hd && NULL != (nx = hd->next) && nx != hd) {
416 /* There is at least one element in the list */
417 /* (besides the distinguished head). */
418 return (nx);
419 }
420 /* The list is empty */
421 return (NULL);
422}
423
424/*
425 * Return the first urb in a list with a distinguished
426 * head "hd", or NULL if the list is empty.
427 */
428struct urb *first_urb (urb_link * hd)
429{
430 urb_link *nx;
431 if (NULL == (nx = first_urb_link (hd))) {
432 /* The list is empty */
433 return (NULL);
434 }
435 return (p2surround (struct urb, link, nx));
436}
437
438/*
439 * Detach and return the first urb in a list with a distinguished
440 * head "hd", or NULL if the list is empty.
441 *
442 */
443struct urb *first_urb_detached (urb_link * hd)
444{
445 struct urb *urb;
446 if ((urb = first_urb (hd))) {
447 urb_detach (urb);
448 }
449 return urb;
450}
451
wdenk29e7f5a2004-03-12 00:14:09 +0000452/*
453 * Append an urb_link (or a whole list of
454 * urb_links) to the tail of another list
455 * of urb_links.
456 */
457void urb_append (urb_link * hd, struct urb *urb)
458{
459 if (hd && urb) {
460 urb_link *new = &urb->link;
461
462 /* This allows the new urb to be a list of urbs, */
463 /* with new pointing at the first, but the link */
464 /* must be initialized. */
465 /* Order is important here... */
466 urb_link *pul = hd->prev;
467 new->prev->next = hd;
468 hd->prev = new->prev;
469 new->prev = pul;
470 pul->next = new;
471 }
472}
473
474/* URB create/destroy functions ***************************************************** */
475
476/**
477 * usbd_alloc_urb - allocate an URB appropriate for specified endpoint
478 * @device: device instance
479 * @endpoint: endpoint
480 *
481 * Allocate an urb structure. The usb device urb structure is used to
482 * contain all data associated with a transfer, including a setup packet for
483 * control transfers.
484 *
485 * NOTE: endpoint_address MUST contain a direction flag.
486 */
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200487struct urb *usbd_alloc_urb (struct usb_device_instance *device,
488 struct usb_endpoint_instance *endpoint)
wdenk29e7f5a2004-03-12 00:14:09 +0000489{
490 struct urb *urb;
491
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200492 if (!(urb = (struct urb *) malloc (sizeof (struct urb)))) {
Stefan Roese37628252008-08-06 14:05:38 +0200493 usberr (" F A T A L: malloc(%zu) FAILED!!!!",
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200494 sizeof (struct urb));
495 return NULL;
wdenk29e7f5a2004-03-12 00:14:09 +0000496 }
497
498 /* Fill in known fields */
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200499 memset (urb, 0, sizeof (struct urb));
wdenk29e7f5a2004-03-12 00:14:09 +0000500 urb->endpoint = endpoint;
501 urb->device = device;
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200502 urb->buffer = (u8 *) urb->buffer_data;
503 urb->buffer_length = sizeof (urb->buffer_data);
wdenk29e7f5a2004-03-12 00:14:09 +0000504
505 urb_link_init (&urb->link);
506
507 return urb;
508}
509
510/**
511 * usbd_dealloc_urb - deallocate an URB and associated buffer
512 * @urb: pointer to an urb structure
513 *
514 * Deallocate an urb structure and associated data.
515 */
516void usbd_dealloc_urb (struct urb *urb)
517{
518 if (urb) {
519 free (urb);
520 }
521}
522
523/* Event signaling functions ***************************************************** */
524
525/**
526 * usbd_device_event - called to respond to various usb events
527 * @device: pointer to struct device
528 * @event: event to respond to
529 *
530 * Used by a Bus driver to indicate an event.
531 */
532void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data)
533{
534 usb_device_state_t state;
535
536 if (!device || !device->bus) {
537 usberr("(%p,%d) NULL device or device->bus", device, event);
538 return;
539 }
540
541 state = device->device_state;
542
543 usbinfo("%s", usbd_device_events[event]);
544
545 switch (event) {
546 case DEVICE_UNKNOWN:
547 break;
548 case DEVICE_INIT:
549 device->device_state = STATE_INIT;
550 break;
551
552 case DEVICE_CREATE:
553 device->device_state = STATE_ATTACHED;
554 break;
555
556 case DEVICE_HUB_CONFIGURED:
557 device->device_state = STATE_POWERED;
558 break;
559
560 case DEVICE_RESET:
561 device->device_state = STATE_DEFAULT;
562 device->address = 0;
563 break;
564
565 case DEVICE_ADDRESS_ASSIGNED:
566 device->device_state = STATE_ADDRESSED;
567 break;
568
569 case DEVICE_CONFIGURED:
570 device->device_state = STATE_CONFIGURED;
571 break;
572
573 case DEVICE_DE_CONFIGURED:
574 device->device_state = STATE_ADDRESSED;
575 break;
576
577 case DEVICE_BUS_INACTIVE:
578 if (device->status != USBD_CLOSING) {
579 device->status = USBD_SUSPENDED;
580 }
581 break;
582 case DEVICE_BUS_ACTIVITY:
583 if (device->status != USBD_CLOSING) {
584 device->status = USBD_OK;
585 }
586 break;
587
588 case DEVICE_SET_INTERFACE:
589 break;
590 case DEVICE_SET_FEATURE:
591 break;
592 case DEVICE_CLEAR_FEATURE:
593 break;
594
595 case DEVICE_POWER_INTERRUPTION:
596 device->device_state = STATE_POWERED;
597 break;
598 case DEVICE_HUB_RESET:
599 device->device_state = STATE_ATTACHED;
600 break;
601 case DEVICE_DESTROY:
602 device->device_state = STATE_UNKNOWN;
603 break;
604
605 case DEVICE_FUNCTION_PRIVATE:
606 break;
607
608 default:
609 usbdbg("event %d - not handled",event);
610 break;
611 }
Anatolij Gustschinf0acb782011-12-03 06:46:11 +0000612 debug("%s event: %d oldstate: %d newstate: %d status: %d address: %d",
wdenk29e7f5a2004-03-12 00:14:09 +0000613 device->name, event, state,
Anatolij Gustschinf0acb782011-12-03 06:46:11 +0000614 device->device_state, device->status, device->address);
wdenk29e7f5a2004-03-12 00:14:09 +0000615
616 /* tell the bus interface driver */
617 if( device->event ) {
618 /* usbdbg("calling device->event"); */
619 device->event(device, event, data);
620 }
621}