blob: ffaf161fb7ecf48a5637a90a97e8c970da283dff [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
18#include <malloc.h>
Jean-Christophe PLAGNIOL-VILLARD8f6bcf42009-04-03 12:46:58 +020019#include <usbdevice.h>
wdenk29e7f5a2004-03-12 00:14:09 +000020
21#define MAX_INTERFACES 2
22
23
24int maxstrings = 20;
25
26/* Global variables ************************************************************************** */
27
28struct usb_string_descriptor **usb_strings;
29
30int usb_devices;
31
32extern struct usb_function_driver ep0_driver;
33
34int registered_functions;
35int registered_devices;
36
37char *usbd_device_events[] = {
38 "DEVICE_UNKNOWN",
39 "DEVICE_INIT",
40 "DEVICE_CREATE",
41 "DEVICE_HUB_CONFIGURED",
42 "DEVICE_RESET",
43 "DEVICE_ADDRESS_ASSIGNED",
44 "DEVICE_CONFIGURED",
45 "DEVICE_SET_INTERFACE",
46 "DEVICE_SET_FEATURE",
47 "DEVICE_CLEAR_FEATURE",
48 "DEVICE_DE_CONFIGURED",
49 "DEVICE_BUS_INACTIVE",
50 "DEVICE_BUS_ACTIVITY",
51 "DEVICE_POWER_INTERRUPTION",
52 "DEVICE_HUB_RESET",
53 "DEVICE_DESTROY",
54 "DEVICE_FUNCTION_PRIVATE",
55};
56
57char *usbd_device_states[] = {
58 "STATE_INIT",
59 "STATE_CREATED",
60 "STATE_ATTACHED",
61 "STATE_POWERED",
62 "STATE_DEFAULT",
63 "STATE_ADDRESSED",
64 "STATE_CONFIGURED",
65 "STATE_UNKNOWN",
66};
67
68char *usbd_device_requests[] = {
69 "GET STATUS", /* 0 */
70 "CLEAR FEATURE", /* 1 */
71 "RESERVED", /* 2 */
72 "SET FEATURE", /* 3 */
73 "RESERVED", /* 4 */
74 "SET ADDRESS", /* 5 */
75 "GET DESCRIPTOR", /* 6 */
76 "SET DESCRIPTOR", /* 7 */
77 "GET CONFIGURATION", /* 8 */
78 "SET CONFIGURATION", /* 9 */
79 "GET INTERFACE", /* 10 */
80 "SET INTERFACE", /* 11 */
81 "SYNC FRAME", /* 12 */
82};
83
84char *usbd_device_descriptors[] = {
85 "UNKNOWN", /* 0 */
86 "DEVICE", /* 1 */
87 "CONFIG", /* 2 */
88 "STRING", /* 3 */
89 "INTERFACE", /* 4 */
90 "ENDPOINT", /* 5 */
91 "DEVICE QUALIFIER", /* 6 */
92 "OTHER SPEED", /* 7 */
93 "INTERFACE POWER", /* 8 */
94};
95
96char *usbd_device_status[] = {
97 "USBD_OPENING",
98 "USBD_OK",
99 "USBD_SUSPENDED",
100 "USBD_CLOSING",
101};
102
103
104/* Descriptor support functions ************************************************************** */
105
106
107/**
108 * usbd_get_string - find and return a string descriptor
109 * @index: string index to return
110 *
111 * Find an indexed string and return a pointer to a it.
112 */
113struct usb_string_descriptor *usbd_get_string (__u8 index)
114{
115 if (index >= maxstrings) {
116 return NULL;
117 }
118 return usb_strings[index];
119}
120
121
122/* Access to device descriptor functions ***************************************************** */
123
124
125/* *
126 * usbd_device_configuration_instance - find a configuration instance for this device
127 * @device:
128 * @configuration: index to configuration, 0 - N-1
129 *
130 * Get specifed device configuration. Index should be bConfigurationValue-1.
131 */
132static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
133 unsigned int port, unsigned int configuration)
134{
Harald Welteed1c3f02008-07-07 00:58:05 +0800135 if (configuration >= device->configurations)
wdenk29e7f5a2004-03-12 00:14:09 +0000136 return NULL;
Harald Welteed1c3f02008-07-07 00:58:05 +0800137
wdenk29e7f5a2004-03-12 00:14:09 +0000138 return device->configuration_instance_array + configuration;
139}
140
141
142/* *
143 * usbd_device_interface_instance
144 * @device:
145 * @configuration: index to configuration, 0 - N-1
146 * @interface: index to interface
147 *
148 * Return the specified interface descriptor for the specified device.
149 */
150struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *device, int port, int configuration, int interface)
151{
152 struct usb_configuration_instance *configuration_instance;
153
154 if ((configuration_instance = usbd_device_configuration_instance (device, port, configuration)) == NULL) {
155 return NULL;
156 }
157 if (interface >= configuration_instance->interfaces) {
158 return NULL;
159 }
160 return configuration_instance->interface_instance_array + interface;
161}
162
163/* *
164 * usbd_device_alternate_descriptor_list
165 * @device:
166 * @configuration: index to configuration, 0 - N-1
167 * @interface: index to interface
168 * @alternate: alternate setting
169 *
170 * Return the specified alternate descriptor for the specified device.
171 */
172struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *device, int port, int configuration, int interface, int alternate)
173{
174 struct usb_interface_instance *interface_instance;
175
176 if ((interface_instance = usbd_device_interface_instance (device, port, configuration, interface)) == NULL) {
177 return NULL;
178 }
179
180 if (alternate >= interface_instance->alternates) {
181 return NULL;
182 }
183
184 return interface_instance->alternates_instance_array + alternate;
185}
186
187
188/* *
189 * usbd_device_device_descriptor
190 * @device: which device
191 * @configuration: index to configuration, 0 - N-1
192 * @port: which port
193 *
194 * Return the specified configuration descriptor for the specified device.
195 */
196struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port)
197{
198 return (device->device_descriptor);
199}
200
wdenk29e7f5a2004-03-12 00:14:09 +0000201/**
202 * usbd_device_configuration_descriptor
203 * @device: which device
204 * @port: which port
205 * @configuration: index to configuration, 0 - N-1
206 *
207 * Return the specified configuration descriptor for the specified device.
208 */
209struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct
210 usb_device_instance
211 *device, int port, int configuration)
212{
213 struct usb_configuration_instance *configuration_instance;
214 if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) {
215 return NULL;
216 }
217 return (configuration_instance->configuration_descriptor);
218}
219
220
221/**
222 * usbd_device_interface_descriptor
223 * @device: which device
224 * @port: which port
225 * @configuration: index to configuration, 0 - N-1
226 * @interface: index to interface
227 * @alternate: alternate setting
228 *
229 * Return the specified interface descriptor for the specified device.
230 */
231struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance
232 *device, int port, int configuration, int interface, int alternate)
233{
234 struct usb_interface_instance *interface_instance;
235 if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) {
236 return NULL;
237 }
238 if ((alternate < 0) || (alternate >= interface_instance->alternates)) {
239 return NULL;
240 }
241 return (interface_instance->alternates_instance_array[alternate].interface_descriptor);
242}
243
244/**
245 * usbd_device_endpoint_descriptor_index
246 * @device: which device
247 * @port: which port
248 * @configuration: index to configuration, 0 - N-1
249 * @interface: index to interface
250 * @alternate: index setting
251 * @index: which index
252 *
253 * Return the specified endpoint descriptor for the specified device.
254 */
255struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance
256 *device, int port, int configuration, int interface, int alternate, int index)
257{
258 struct usb_alternate_instance *alternate_instance;
259
260 if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
261 return NULL;
262 }
263 if (index >= alternate_instance->endpoints) {
264 return NULL;
265 }
266 return *(alternate_instance->endpoints_descriptor_array + index);
267}
268
269
270/**
271 * usbd_device_endpoint_transfersize
272 * @device: which device
273 * @port: which port
274 * @configuration: index to configuration, 0 - N-1
275 * @interface: index to interface
276 * @index: which index
277 *
278 * Return the specified endpoint transfer size;
279 */
280int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index)
281{
282 struct usb_alternate_instance *alternate_instance;
283
284 if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
285 return 0;
286 }
287 if (index >= alternate_instance->endpoints) {
288 return 0;
289 }
290 return *(alternate_instance->endpoint_transfersize_array + index);
291}
292
293
294/**
295 * usbd_device_endpoint_descriptor
296 * @device: which device
297 * @port: which port
298 * @configuration: index to configuration, 0 - N-1
299 * @interface: index to interface
300 * @alternate: alternate setting
301 * @endpoint: which endpoint
302 *
303 * Return the specified endpoint descriptor for the specified device.
304 */
305struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint)
306{
307 struct usb_endpoint_descriptor *endpoint_descriptor;
308 int i;
309
310 for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) {
311 if (endpoint_descriptor->bEndpointAddress == endpoint) {
312 return endpoint_descriptor;
313 }
314 }
315 return NULL;
316}
317
318/**
319 * usbd_endpoint_halted
320 * @device: point to struct usb_device_instance
321 * @endpoint: endpoint to check
322 *
323 * Return non-zero if endpoint is halted.
324 */
325int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint)
326{
327 return (device->status == USB_STATUS_HALT);
328}
329
330
331/**
332 * usbd_rcv_complete - complete a receive
333 * @endpoint:
334 * @len:
335 * @urb_bad:
336 *
337 * Called from rcv interrupt to complete.
338 */
339void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad)
340{
341 if (endpoint) {
342 struct urb *rcv_urb;
343
344 /*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */
345
346 /* if we had an urb then update actual_length, dispatch if neccessary */
347 if ((rcv_urb = endpoint->rcv_urb)) {
348
349 /*usbdbg("actual: %d buffer: %d\n", */
350 /*rcv_urb->actual_length, rcv_urb->buffer_length); */
351
352 /* check the urb is ok, are we adding data less than the packetsize */
353 if (!urb_bad && (len <= endpoint->rcv_packetSize)) {
354 /*usbdbg("updating actual_length by %d\n",len); */
355
356 /* increment the received data size */
357 rcv_urb->actual_length += len;
358
359 } else {
360 usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n",
361 rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad);
362
363 rcv_urb->actual_length = 0;
364 rcv_urb->status = RECV_ERROR;
365 }
366 } else {
367 usberr("no rcv_urb!");
368 }
369 } else {
370 usberr("no endpoint!");
371 }
372
373}
374
375/**
376 * usbd_tx_complete - complete a transmit
377 * @endpoint:
378 * @resetart:
379 *
380 * Called from tx interrupt to complete.
381 */
382void usbd_tx_complete (struct usb_endpoint_instance *endpoint)
383{
384 if (endpoint) {
385 struct urb *tx_urb;
386
387 /* if we have a tx_urb advance or reset, finish if complete */
388 if ((tx_urb = endpoint->tx_urb)) {
389 int sent = endpoint->last;
390 endpoint->sent += sent;
391 endpoint->last -= sent;
392
393 if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {
394 tx_urb->actual_length = 0;
395 endpoint->sent = 0;
396 endpoint->last = 0;
397
398 /* Remove from active, save for re-use */
399 urb_detach(tx_urb);
400 urb_append(&endpoint->done, tx_urb);
401 /*usbdbg("done->next %p, tx_urb %p, done %p", */
402 /* endpoint->done.next, tx_urb, &endpoint->done); */
403
404 endpoint->tx_urb = first_urb_detached(&endpoint->tx);
405 if( endpoint->tx_urb ) {
406 endpoint->tx_queue--;
407 usbdbg("got urb from tx list");
408 }
409 if( !endpoint->tx_urb ) {
410 /*usbdbg("taking urb from done list"); */
411 endpoint->tx_urb = first_urb_detached(&endpoint->done);
412 }
413 if( !endpoint->tx_urb ) {
414 usbdbg("allocating new urb for tx_urb");
415 endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint);
416 }
417 }
418 }
419 }
420}
421
422/* URB linked list functions ***************************************************** */
423
424/*
425 * Initialize an urb_link to be a single element list.
426 * If the urb_link is being used as a distinguished list head
427 * the list is empty when the head is the only link in the list.
428 */
429void urb_link_init (urb_link * ul)
430{
431 if (ul) {
432 ul->prev = ul->next = ul;
433 }
434}
435
436/*
437 * Detach an urb_link from a list, and set it
438 * up as a single element list, so no dangling
439 * pointers can be followed, and so it can be
440 * joined to another list if so desired.
441 */
442void urb_detach (struct urb *urb)
443{
444 if (urb) {
445 urb_link *ul = &urb->link;
446 ul->next->prev = ul->prev;
447 ul->prev->next = ul->next;
448 urb_link_init (ul);
449 }
450}
451
452/*
453 * Return the first urb_link in a list with a distinguished
454 * head "hd", or NULL if the list is empty. This will also
455 * work as a predicate, returning NULL if empty, and non-NULL
456 * otherwise.
457 */
458urb_link *first_urb_link (urb_link * hd)
459{
460 urb_link *nx;
461 if (NULL != hd && NULL != (nx = hd->next) && nx != hd) {
462 /* There is at least one element in the list */
463 /* (besides the distinguished head). */
464 return (nx);
465 }
466 /* The list is empty */
467 return (NULL);
468}
469
470/*
471 * Return the first urb in a list with a distinguished
472 * head "hd", or NULL if the list is empty.
473 */
474struct urb *first_urb (urb_link * hd)
475{
476 urb_link *nx;
477 if (NULL == (nx = first_urb_link (hd))) {
478 /* The list is empty */
479 return (NULL);
480 }
481 return (p2surround (struct urb, link, nx));
482}
483
484/*
485 * Detach and return the first urb in a list with a distinguished
486 * head "hd", or NULL if the list is empty.
487 *
488 */
489struct urb *first_urb_detached (urb_link * hd)
490{
491 struct urb *urb;
492 if ((urb = first_urb (hd))) {
493 urb_detach (urb);
494 }
495 return urb;
496}
497
498
499/*
500 * Append an urb_link (or a whole list of
501 * urb_links) to the tail of another list
502 * of urb_links.
503 */
504void urb_append (urb_link * hd, struct urb *urb)
505{
506 if (hd && urb) {
507 urb_link *new = &urb->link;
508
509 /* This allows the new urb to be a list of urbs, */
510 /* with new pointing at the first, but the link */
511 /* must be initialized. */
512 /* Order is important here... */
513 urb_link *pul = hd->prev;
514 new->prev->next = hd;
515 hd->prev = new->prev;
516 new->prev = pul;
517 pul->next = new;
518 }
519}
520
521/* URB create/destroy functions ***************************************************** */
522
523/**
524 * usbd_alloc_urb - allocate an URB appropriate for specified endpoint
525 * @device: device instance
526 * @endpoint: endpoint
527 *
528 * Allocate an urb structure. The usb device urb structure is used to
529 * contain all data associated with a transfer, including a setup packet for
530 * control transfers.
531 *
532 * NOTE: endpoint_address MUST contain a direction flag.
533 */
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200534struct urb *usbd_alloc_urb (struct usb_device_instance *device,
535 struct usb_endpoint_instance *endpoint)
wdenk29e7f5a2004-03-12 00:14:09 +0000536{
537 struct urb *urb;
538
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200539 if (!(urb = (struct urb *) malloc (sizeof (struct urb)))) {
Stefan Roese37628252008-08-06 14:05:38 +0200540 usberr (" F A T A L: malloc(%zu) FAILED!!!!",
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200541 sizeof (struct urb));
542 return NULL;
wdenk29e7f5a2004-03-12 00:14:09 +0000543 }
544
545 /* Fill in known fields */
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200546 memset (urb, 0, sizeof (struct urb));
wdenk29e7f5a2004-03-12 00:14:09 +0000547 urb->endpoint = endpoint;
548 urb->device = device;
Wolfgang Denkfe036dd2008-07-13 19:51:00 +0200549 urb->buffer = (u8 *) urb->buffer_data;
550 urb->buffer_length = sizeof (urb->buffer_data);
wdenk29e7f5a2004-03-12 00:14:09 +0000551
552 urb_link_init (&urb->link);
553
554 return urb;
555}
556
557/**
558 * usbd_dealloc_urb - deallocate an URB and associated buffer
559 * @urb: pointer to an urb structure
560 *
561 * Deallocate an urb structure and associated data.
562 */
563void usbd_dealloc_urb (struct urb *urb)
564{
565 if (urb) {
566 free (urb);
567 }
568}
569
570/* Event signaling functions ***************************************************** */
571
572/**
573 * usbd_device_event - called to respond to various usb events
574 * @device: pointer to struct device
575 * @event: event to respond to
576 *
577 * Used by a Bus driver to indicate an event.
578 */
579void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data)
580{
581 usb_device_state_t state;
582
583 if (!device || !device->bus) {
584 usberr("(%p,%d) NULL device or device->bus", device, event);
585 return;
586 }
587
588 state = device->device_state;
589
590 usbinfo("%s", usbd_device_events[event]);
591
592 switch (event) {
593 case DEVICE_UNKNOWN:
594 break;
595 case DEVICE_INIT:
596 device->device_state = STATE_INIT;
597 break;
598
599 case DEVICE_CREATE:
600 device->device_state = STATE_ATTACHED;
601 break;
602
603 case DEVICE_HUB_CONFIGURED:
604 device->device_state = STATE_POWERED;
605 break;
606
607 case DEVICE_RESET:
608 device->device_state = STATE_DEFAULT;
609 device->address = 0;
610 break;
611
612 case DEVICE_ADDRESS_ASSIGNED:
613 device->device_state = STATE_ADDRESSED;
614 break;
615
616 case DEVICE_CONFIGURED:
617 device->device_state = STATE_CONFIGURED;
618 break;
619
620 case DEVICE_DE_CONFIGURED:
621 device->device_state = STATE_ADDRESSED;
622 break;
623
624 case DEVICE_BUS_INACTIVE:
625 if (device->status != USBD_CLOSING) {
626 device->status = USBD_SUSPENDED;
627 }
628 break;
629 case DEVICE_BUS_ACTIVITY:
630 if (device->status != USBD_CLOSING) {
631 device->status = USBD_OK;
632 }
633 break;
634
635 case DEVICE_SET_INTERFACE:
636 break;
637 case DEVICE_SET_FEATURE:
638 break;
639 case DEVICE_CLEAR_FEATURE:
640 break;
641
642 case DEVICE_POWER_INTERRUPTION:
643 device->device_state = STATE_POWERED;
644 break;
645 case DEVICE_HUB_RESET:
646 device->device_state = STATE_ATTACHED;
647 break;
648 case DEVICE_DESTROY:
649 device->device_state = STATE_UNKNOWN;
650 break;
651
652 case DEVICE_FUNCTION_PRIVATE:
653 break;
654
655 default:
656 usbdbg("event %d - not handled",event);
657 break;
658 }
Anatolij Gustschinf0acb782011-12-03 06:46:11 +0000659 debug("%s event: %d oldstate: %d newstate: %d status: %d address: %d",
wdenk29e7f5a2004-03-12 00:14:09 +0000660 device->name, event, state,
Anatolij Gustschinf0acb782011-12-03 06:46:11 +0000661 device->device_state, device->status, device->address);
wdenk29e7f5a2004-03-12 00:14:09 +0000662
663 /* tell the bus interface driver */
664 if( device->event ) {
665 /* usbdbg("calling device->event"); */
666 device->event(device, event, data);
667 }
668}