]>
Commit | Line | Data |
---|---|---|
232c150a WD |
1 | /* |
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> | |
33 | #include "usbdcore.h" | |
34 | ||
35 | #define MAX_INTERFACES 2 | |
36 | ||
37 | ||
38 | int maxstrings = 20; | |
39 | ||
40 | /* Global variables ************************************************************************** */ | |
41 | ||
42 | struct usb_string_descriptor **usb_strings; | |
43 | ||
44 | int usb_devices; | |
45 | ||
46 | extern struct usb_function_driver ep0_driver; | |
47 | ||
48 | int registered_functions; | |
49 | int registered_devices; | |
50 | ||
51 | char *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 | ||
71 | char *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 | ||
82 | char *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 | ||
98 | char *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 | ||
110 | char *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 | */ | |
127 | struct 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 | */ | |
146 | static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device, | |
147 | unsigned int port, unsigned int configuration) | |
148 | { | |
149 | /* XXX */ | |
150 | configuration = configuration ? configuration - 1 : 0; | |
151 | ||
152 | if (configuration >= device->configurations) { | |
153 | return NULL; | |
154 | } | |
155 | return device->configuration_instance_array + configuration; | |
156 | } | |
157 | ||
158 | ||
159 | /* * | |
160 | * usbd_device_interface_instance | |
161 | * @device: | |
162 | * @configuration: index to configuration, 0 - N-1 | |
163 | * @interface: index to interface | |
164 | * | |
165 | * Return the specified interface descriptor for the specified device. | |
166 | */ | |
167 | struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *device, int port, int configuration, int interface) | |
168 | { | |
169 | struct usb_configuration_instance *configuration_instance; | |
170 | ||
171 | if ((configuration_instance = usbd_device_configuration_instance (device, port, configuration)) == NULL) { | |
172 | return NULL; | |
173 | } | |
174 | if (interface >= configuration_instance->interfaces) { | |
175 | return NULL; | |
176 | } | |
177 | return configuration_instance->interface_instance_array + interface; | |
178 | } | |
179 | ||
180 | /* * | |
181 | * usbd_device_alternate_descriptor_list | |
182 | * @device: | |
183 | * @configuration: index to configuration, 0 - N-1 | |
184 | * @interface: index to interface | |
185 | * @alternate: alternate setting | |
186 | * | |
187 | * Return the specified alternate descriptor for the specified device. | |
188 | */ | |
189 | struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *device, int port, int configuration, int interface, int alternate) | |
190 | { | |
191 | struct usb_interface_instance *interface_instance; | |
192 | ||
193 | if ((interface_instance = usbd_device_interface_instance (device, port, configuration, interface)) == NULL) { | |
194 | return NULL; | |
195 | } | |
196 | ||
197 | if (alternate >= interface_instance->alternates) { | |
198 | return NULL; | |
199 | } | |
200 | ||
201 | return interface_instance->alternates_instance_array + alternate; | |
202 | } | |
203 | ||
204 | ||
205 | /* * | |
206 | * usbd_device_device_descriptor | |
207 | * @device: which device | |
208 | * @configuration: index to configuration, 0 - N-1 | |
209 | * @port: which port | |
210 | * | |
211 | * Return the specified configuration descriptor for the specified device. | |
212 | */ | |
213 | struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port) | |
214 | { | |
215 | return (device->device_descriptor); | |
216 | } | |
217 | ||
218 | ||
219 | /** | |
220 | * usbd_device_configuration_descriptor | |
221 | * @device: which device | |
222 | * @port: which port | |
223 | * @configuration: index to configuration, 0 - N-1 | |
224 | * | |
225 | * Return the specified configuration descriptor for the specified device. | |
226 | */ | |
227 | struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct | |
228 | usb_device_instance | |
229 | *device, int port, int configuration) | |
230 | { | |
231 | struct usb_configuration_instance *configuration_instance; | |
232 | if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) { | |
233 | return NULL; | |
234 | } | |
235 | return (configuration_instance->configuration_descriptor); | |
236 | } | |
237 | ||
238 | ||
239 | /** | |
240 | * usbd_device_interface_descriptor | |
241 | * @device: which device | |
242 | * @port: which port | |
243 | * @configuration: index to configuration, 0 - N-1 | |
244 | * @interface: index to interface | |
245 | * @alternate: alternate setting | |
246 | * | |
247 | * Return the specified interface descriptor for the specified device. | |
248 | */ | |
249 | struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance | |
250 | *device, int port, int configuration, int interface, int alternate) | |
251 | { | |
252 | struct usb_interface_instance *interface_instance; | |
253 | if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) { | |
254 | return NULL; | |
255 | } | |
256 | if ((alternate < 0) || (alternate >= interface_instance->alternates)) { | |
257 | return NULL; | |
258 | } | |
259 | return (interface_instance->alternates_instance_array[alternate].interface_descriptor); | |
260 | } | |
261 | ||
262 | /** | |
263 | * usbd_device_endpoint_descriptor_index | |
264 | * @device: which device | |
265 | * @port: which port | |
266 | * @configuration: index to configuration, 0 - N-1 | |
267 | * @interface: index to interface | |
268 | * @alternate: index setting | |
269 | * @index: which index | |
270 | * | |
271 | * Return the specified endpoint descriptor for the specified device. | |
272 | */ | |
273 | struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance | |
274 | *device, int port, int configuration, int interface, int alternate, int index) | |
275 | { | |
276 | struct usb_alternate_instance *alternate_instance; | |
277 | ||
278 | if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) { | |
279 | return NULL; | |
280 | } | |
281 | if (index >= alternate_instance->endpoints) { | |
282 | return NULL; | |
283 | } | |
284 | return *(alternate_instance->endpoints_descriptor_array + index); | |
285 | } | |
286 | ||
287 | ||
288 | /** | |
289 | * usbd_device_endpoint_transfersize | |
290 | * @device: which device | |
291 | * @port: which port | |
292 | * @configuration: index to configuration, 0 - N-1 | |
293 | * @interface: index to interface | |
294 | * @index: which index | |
295 | * | |
296 | * Return the specified endpoint transfer size; | |
297 | */ | |
298 | int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index) | |
299 | { | |
300 | struct usb_alternate_instance *alternate_instance; | |
301 | ||
302 | if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) { | |
303 | return 0; | |
304 | } | |
305 | if (index >= alternate_instance->endpoints) { | |
306 | return 0; | |
307 | } | |
308 | return *(alternate_instance->endpoint_transfersize_array + index); | |
309 | } | |
310 | ||
311 | ||
312 | /** | |
313 | * usbd_device_endpoint_descriptor | |
314 | * @device: which device | |
315 | * @port: which port | |
316 | * @configuration: index to configuration, 0 - N-1 | |
317 | * @interface: index to interface | |
318 | * @alternate: alternate setting | |
319 | * @endpoint: which endpoint | |
320 | * | |
321 | * Return the specified endpoint descriptor for the specified device. | |
322 | */ | |
323 | struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint) | |
324 | { | |
325 | struct usb_endpoint_descriptor *endpoint_descriptor; | |
326 | int i; | |
327 | ||
328 | for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) { | |
329 | if (endpoint_descriptor->bEndpointAddress == endpoint) { | |
330 | return endpoint_descriptor; | |
331 | } | |
332 | } | |
333 | return NULL; | |
334 | } | |
335 | ||
336 | /** | |
337 | * usbd_endpoint_halted | |
338 | * @device: point to struct usb_device_instance | |
339 | * @endpoint: endpoint to check | |
340 | * | |
341 | * Return non-zero if endpoint is halted. | |
342 | */ | |
343 | int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint) | |
344 | { | |
345 | return (device->status == USB_STATUS_HALT); | |
346 | } | |
347 | ||
348 | ||
349 | /** | |
350 | * usbd_rcv_complete - complete a receive | |
351 | * @endpoint: | |
352 | * @len: | |
353 | * @urb_bad: | |
354 | * | |
355 | * Called from rcv interrupt to complete. | |
356 | */ | |
357 | void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad) | |
358 | { | |
359 | if (endpoint) { | |
360 | struct urb *rcv_urb; | |
361 | ||
362 | /*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */ | |
363 | ||
364 | /* if we had an urb then update actual_length, dispatch if neccessary */ | |
365 | if ((rcv_urb = endpoint->rcv_urb)) { | |
366 | ||
367 | /*usbdbg("actual: %d buffer: %d\n", */ | |
368 | /*rcv_urb->actual_length, rcv_urb->buffer_length); */ | |
369 | ||
370 | /* check the urb is ok, are we adding data less than the packetsize */ | |
371 | if (!urb_bad && (len <= endpoint->rcv_packetSize)) { | |
372 | /*usbdbg("updating actual_length by %d\n",len); */ | |
373 | ||
374 | /* increment the received data size */ | |
375 | rcv_urb->actual_length += len; | |
376 | ||
377 | } else { | |
378 | usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n", | |
379 | rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad); | |
380 | ||
381 | rcv_urb->actual_length = 0; | |
382 | rcv_urb->status = RECV_ERROR; | |
383 | } | |
384 | } else { | |
385 | usberr("no rcv_urb!"); | |
386 | } | |
387 | } else { | |
388 | usberr("no endpoint!"); | |
389 | } | |
390 | ||
391 | } | |
392 | ||
393 | /** | |
394 | * usbd_tx_complete - complete a transmit | |
395 | * @endpoint: | |
396 | * @resetart: | |
397 | * | |
398 | * Called from tx interrupt to complete. | |
399 | */ | |
400 | void usbd_tx_complete (struct usb_endpoint_instance *endpoint) | |
401 | { | |
402 | if (endpoint) { | |
403 | struct urb *tx_urb; | |
404 | ||
405 | /* if we have a tx_urb advance or reset, finish if complete */ | |
406 | if ((tx_urb = endpoint->tx_urb)) { | |
407 | int sent = endpoint->last; | |
408 | endpoint->sent += sent; | |
409 | endpoint->last -= sent; | |
410 | ||
411 | if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) { | |
412 | tx_urb->actual_length = 0; | |
413 | endpoint->sent = 0; | |
414 | endpoint->last = 0; | |
415 | ||
416 | /* Remove from active, save for re-use */ | |
417 | urb_detach(tx_urb); | |
418 | urb_append(&endpoint->done, tx_urb); | |
419 | /*usbdbg("done->next %p, tx_urb %p, done %p", */ | |
420 | /* endpoint->done.next, tx_urb, &endpoint->done); */ | |
421 | ||
422 | endpoint->tx_urb = first_urb_detached(&endpoint->tx); | |
423 | if( endpoint->tx_urb ) { | |
424 | endpoint->tx_queue--; | |
425 | usbdbg("got urb from tx list"); | |
426 | } | |
427 | if( !endpoint->tx_urb ) { | |
428 | /*usbdbg("taking urb from done list"); */ | |
429 | endpoint->tx_urb = first_urb_detached(&endpoint->done); | |
430 | } | |
431 | if( !endpoint->tx_urb ) { | |
432 | usbdbg("allocating new urb for tx_urb"); | |
433 | endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint); | |
434 | } | |
435 | } | |
436 | } | |
437 | } | |
438 | } | |
439 | ||
440 | /* URB linked list functions ***************************************************** */ | |
441 | ||
442 | /* | |
443 | * Initialize an urb_link to be a single element list. | |
444 | * If the urb_link is being used as a distinguished list head | |
445 | * the list is empty when the head is the only link in the list. | |
446 | */ | |
447 | void urb_link_init (urb_link * ul) | |
448 | { | |
449 | if (ul) { | |
450 | ul->prev = ul->next = ul; | |
451 | } | |
452 | } | |
453 | ||
454 | /* | |
455 | * Detach an urb_link from a list, and set it | |
456 | * up as a single element list, so no dangling | |
457 | * pointers can be followed, and so it can be | |
458 | * joined to another list if so desired. | |
459 | */ | |
460 | void urb_detach (struct urb *urb) | |
461 | { | |
462 | if (urb) { | |
463 | urb_link *ul = &urb->link; | |
464 | ul->next->prev = ul->prev; | |
465 | ul->prev->next = ul->next; | |
466 | urb_link_init (ul); | |
467 | } | |
468 | } | |
469 | ||
470 | /* | |
471 | * Return the first urb_link in a list with a distinguished | |
472 | * head "hd", or NULL if the list is empty. This will also | |
473 | * work as a predicate, returning NULL if empty, and non-NULL | |
474 | * otherwise. | |
475 | */ | |
476 | urb_link *first_urb_link (urb_link * hd) | |
477 | { | |
478 | urb_link *nx; | |
479 | if (NULL != hd && NULL != (nx = hd->next) && nx != hd) { | |
480 | /* There is at least one element in the list */ | |
481 | /* (besides the distinguished head). */ | |
482 | return (nx); | |
483 | } | |
484 | /* The list is empty */ | |
485 | return (NULL); | |
486 | } | |
487 | ||
488 | /* | |
489 | * Return the first urb in a list with a distinguished | |
490 | * head "hd", or NULL if the list is empty. | |
491 | */ | |
492 | struct urb *first_urb (urb_link * hd) | |
493 | { | |
494 | urb_link *nx; | |
495 | if (NULL == (nx = first_urb_link (hd))) { | |
496 | /* The list is empty */ | |
497 | return (NULL); | |
498 | } | |
499 | return (p2surround (struct urb, link, nx)); | |
500 | } | |
501 | ||
502 | /* | |
503 | * Detach and return the first urb in a list with a distinguished | |
504 | * head "hd", or NULL if the list is empty. | |
505 | * | |
506 | */ | |
507 | struct urb *first_urb_detached (urb_link * hd) | |
508 | { | |
509 | struct urb *urb; | |
510 | if ((urb = first_urb (hd))) { | |
511 | urb_detach (urb); | |
512 | } | |
513 | return urb; | |
514 | } | |
515 | ||
516 | ||
517 | /* | |
518 | * Append an urb_link (or a whole list of | |
519 | * urb_links) to the tail of another list | |
520 | * of urb_links. | |
521 | */ | |
522 | void urb_append (urb_link * hd, struct urb *urb) | |
523 | { | |
524 | if (hd && urb) { | |
525 | urb_link *new = &urb->link; | |
526 | ||
527 | /* This allows the new urb to be a list of urbs, */ | |
528 | /* with new pointing at the first, but the link */ | |
529 | /* must be initialized. */ | |
530 | /* Order is important here... */ | |
531 | urb_link *pul = hd->prev; | |
532 | new->prev->next = hd; | |
533 | hd->prev = new->prev; | |
534 | new->prev = pul; | |
535 | pul->next = new; | |
536 | } | |
537 | } | |
538 | ||
539 | /* URB create/destroy functions ***************************************************** */ | |
540 | ||
541 | /** | |
542 | * usbd_alloc_urb - allocate an URB appropriate for specified endpoint | |
543 | * @device: device instance | |
544 | * @endpoint: endpoint | |
545 | * | |
546 | * Allocate an urb structure. The usb device urb structure is used to | |
547 | * contain all data associated with a transfer, including a setup packet for | |
548 | * control transfers. | |
549 | * | |
550 | * NOTE: endpoint_address MUST contain a direction flag. | |
551 | */ | |
552 | struct urb *usbd_alloc_urb (struct usb_device_instance *device, struct usb_endpoint_instance *endpoint) | |
553 | { | |
554 | struct urb *urb; | |
555 | ||
556 | if( !(urb = (struct urb*)malloc(sizeof(struct urb))) ) { | |
557 | usberr(" F A T A L: malloc(%u) FAILED!!!!", sizeof(struct urb)); | |
558 | return NULL; | |
559 | } | |
560 | ||
561 | /* Fill in known fields */ | |
562 | memset(urb, 0, sizeof(struct urb)); | |
563 | urb->endpoint = endpoint; | |
564 | urb->device = device; | |
565 | urb->buffer = (u8*)urb->buffer_data; | |
566 | urb->buffer_length = sizeof(urb->buffer_data); | |
567 | ||
568 | urb_link_init (&urb->link); | |
569 | ||
570 | return urb; | |
571 | } | |
572 | ||
573 | /** | |
574 | * usbd_dealloc_urb - deallocate an URB and associated buffer | |
575 | * @urb: pointer to an urb structure | |
576 | * | |
577 | * Deallocate an urb structure and associated data. | |
578 | */ | |
579 | void usbd_dealloc_urb (struct urb *urb) | |
580 | { | |
581 | if (urb) { | |
582 | free (urb); | |
583 | } | |
584 | } | |
585 | ||
586 | /* Event signaling functions ***************************************************** */ | |
587 | ||
588 | /** | |
589 | * usbd_device_event - called to respond to various usb events | |
590 | * @device: pointer to struct device | |
591 | * @event: event to respond to | |
592 | * | |
593 | * Used by a Bus driver to indicate an event. | |
594 | */ | |
595 | void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data) | |
596 | { | |
597 | usb_device_state_t state; | |
598 | ||
599 | if (!device || !device->bus) { | |
600 | usberr("(%p,%d) NULL device or device->bus", device, event); | |
601 | return; | |
602 | } | |
603 | ||
604 | state = device->device_state; | |
605 | ||
606 | usbinfo("%s", usbd_device_events[event]); | |
607 | ||
608 | switch (event) { | |
609 | case DEVICE_UNKNOWN: | |
610 | break; | |
611 | case DEVICE_INIT: | |
612 | device->device_state = STATE_INIT; | |
613 | break; | |
614 | ||
615 | case DEVICE_CREATE: | |
616 | device->device_state = STATE_ATTACHED; | |
617 | break; | |
618 | ||
619 | case DEVICE_HUB_CONFIGURED: | |
620 | device->device_state = STATE_POWERED; | |
621 | break; | |
622 | ||
623 | case DEVICE_RESET: | |
624 | device->device_state = STATE_DEFAULT; | |
625 | device->address = 0; | |
626 | break; | |
627 | ||
628 | case DEVICE_ADDRESS_ASSIGNED: | |
629 | device->device_state = STATE_ADDRESSED; | |
630 | break; | |
631 | ||
632 | case DEVICE_CONFIGURED: | |
633 | device->device_state = STATE_CONFIGURED; | |
634 | break; | |
635 | ||
636 | case DEVICE_DE_CONFIGURED: | |
637 | device->device_state = STATE_ADDRESSED; | |
638 | break; | |
639 | ||
640 | case DEVICE_BUS_INACTIVE: | |
641 | if (device->status != USBD_CLOSING) { | |
642 | device->status = USBD_SUSPENDED; | |
643 | } | |
644 | break; | |
645 | case DEVICE_BUS_ACTIVITY: | |
646 | if (device->status != USBD_CLOSING) { | |
647 | device->status = USBD_OK; | |
648 | } | |
649 | break; | |
650 | ||
651 | case DEVICE_SET_INTERFACE: | |
652 | break; | |
653 | case DEVICE_SET_FEATURE: | |
654 | break; | |
655 | case DEVICE_CLEAR_FEATURE: | |
656 | break; | |
657 | ||
658 | case DEVICE_POWER_INTERRUPTION: | |
659 | device->device_state = STATE_POWERED; | |
660 | break; | |
661 | case DEVICE_HUB_RESET: | |
662 | device->device_state = STATE_ATTACHED; | |
663 | break; | |
664 | case DEVICE_DESTROY: | |
665 | device->device_state = STATE_UNKNOWN; | |
666 | break; | |
667 | ||
668 | case DEVICE_FUNCTION_PRIVATE: | |
669 | break; | |
670 | ||
671 | default: | |
672 | usbdbg("event %d - not handled",event); | |
673 | break; | |
674 | } | |
675 | /*usbdbg("%s event: %d oldstate: %d newstate: %d status: %d address: %d", | |
676 | device->name, event, state, | |
677 | device->device_state, device->status, device->address); */ | |
678 | ||
679 | /* tell the bus interface driver */ | |
680 | if( device->event ) { | |
681 | /* usbdbg("calling device->event"); */ | |
682 | device->event(device, event, data); | |
683 | } | |
684 | } |