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