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