| NUC472_NUC442_BSP V3.04.000 The Board Support Package for NUC472/NUC442

usbh_ohci.c
Go to the documentation of this file.
1/*
2 * URB OHCI HCD (Host Controller Driver) for USB.
3 *
4 * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
5 * (C) Copyright 2000 David Brownell <david-b@pacbell.net>
6 *
7 * [ Initialisation is based on Linus' ]
8 * [ uhci code and gregs ohci fragments ]
9 * [ (C) Copyright 1999 Linus Torvalds ]
10 * [ (C) Copyright 1999 Gregory P. Smith]
11 *
12 *
13 * History:
14 *
15 * 2000/09/26 fixed races in removing the private portion of the urb
16 * 2000/09/07 disable bulk and control lists when unlinking the last
17 * endpoint descriptor in order to aVOID unrecoverable errors on
18 * the Lucent chips.
19 * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
20 * urb unlink probs, indentation fixes
21 * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
22 * device unplugs.
23 * 2000/06/28 use PCI hotplug framework, for better power management
24 * and for Cardbus support (David Brownell)
25 * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling
26 * when the controller loses power; handle UE; cleanup; ...
27 *
28 * v5.2 1999/12/07 URB 3rd preview,
29 * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi)
30 * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume
31 * i386: HUB, Keyboard, Mouse, Printer
32 *
33 * v4.3 1999/10/27 multiple HCs, bulk_request
34 * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes
35 * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl.
36 * v4.0 1999/08/18
37 * v3.0 1999/06/25
38 * v2.1 1999/05/09 code clean up
39 * v2.0 1999/05/04
40 * v1.0 1999/04/27 initial release
41 */
42
43/**************************************************************************/
53#include <stdio.h>
54#include <string.h>
55
56#include "NUC472_442.h"
57#include "usbh_core.h"
58#include "usbh_ohci.h"
59
61
62#ifdef __ICCARM__
63#pragma data_alignment=256
64static uint8_t g_ohci_hcca[256];
65#pragma data_alignment=4
66#else
67static uint8_t g_ohci_hcca[256] __attribute__((aligned(256)));
68#endif
69
70
71USB_BUS_T g_ohci_bus;
72static OHCI_T ohci;
73
74char _is_in_interrupt = 0;
75
76
77/* For initializing controller (mask in an HCFS mode too) */
78#define OHCI_CONTROL_INIT \
79 ((OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE)
80
81
82/* #define OHCI_UNLINK_TIMEOUT (HZ / 10) */ /* Linux */
83#define OHCI_UNLINK_TIMEOUT 20 /* 30ms, modified by YCHuang */
84
85
86static OHCI_DEVICE_T g_ohci_dev_pool[DEV_MAX_NUM];
87static uint8_t ohci_dev_alloc_mark[DEV_MAX_NUM];
88
89static void td_submit_urb(URB_T * urb);
90static int rh_submit_urb(URB_T *urb);
91static ED_T *ep_add_ed(USB_DEV_T *usb_dev, uint32_t pipe, int interval, int load);
92static int ep_link(ED_T *edi);
93static void ep_rm_ed(USB_DEV_T *usb_dev, ED_T *ed);
94static int ep_unlink(ED_T *ed);
95static int rh_unlink_urb(URB_T *urb);
96
97
98static int cc_to_error[16] =
99{
100
101 /* mapping of the OHCI CC status to error codes */
102 /* No Error */ USB_OK,
103 /* CRC Error */ CC_ERR_CRC,
104 /* Bit Stuff */ CC_ERR_BITSTUFF,
105 /* Data Togg */ CC_ERR_DATA_TOGGLE,
106 /* Stall */ CC_ERR_STALL,
107 /* DevNotResp */ CC_ERR_NORESPONSE,
108 /* PIDCheck */ CC_ERR_PID_CHECK,
109 /* InvalidPID */ CC_ERR_INVALID_PID,
110 /* DataOver */ CC_ERR_DATAOVERRUN,
111 /* DataUnder */ CC_ERR_DATAUNDERRUN,
112 CC_ERR_NOT_DEFINED,
113 CC_ERR_NOT_DEFINED,
114 /* BufferOver */ CC_ERR_BUFFEROVERRUN,
115 /* BuffUnder */ CC_ERR_BUFFERUNDERRUN,
116 /* Not Access */ CC_ERR_NOT_ACCESS,
117 /* Not Access */ CC_ERR_NOT_ACCESS
118};
119
120
121void dump_hcca()
122{
123 int i = 0;
124 for (i = 0; i < 32; i++)
125 printf("HCCA %02d - 0x%x\n", i, ohci.hcca->int_table[i]);
126}
127
128static void TD_CompletionCode(uint8_t cc)
129{
130 switch (cc)
131 {
132 case TD_CC_NOERROR:
133 USB_debug("NO ERROR");
134 break;
135 case TD_CC_CRC:
136 USB_debug("CRC ERROR");
137 break;
138 case TD_CC_BITSTUFFING:
139 USB_debug("BIT STUFFING");
140 break;
141 case TD_CC_DATATOGGLEM:
142 USB_debug("DATA TOGGLE MISMATCH");
143 break;
144 case TD_CC_STALL:
145 USB_debug("STALL");
146 break;
147 case TD_DEVNOTRESP:
148 USB_debug("DEVICE NOT RESPONDING");
149 break;
150 case TD_PIDCHECKFAIL:
151 USB_debug("PID CHECK FAILURE");
152 break;
153 case TD_UNEXPECTEDPID:
154 USB_debug("UNEXPECTED PID");
155 break;
156 case TD_DATAOVERRUN:
157 USB_debug("DATA OVERRUN");
158 break;
159 case TD_DATAUNDERRUN:
160 USB_debug("DATA UNDERRUN");
161 break;
162 case TD_BUFFEROVERRUN:
163 USB_debug("BUFFER OVERRUN");
164 break;
165 case TD_BUFFERUNDERRUN:
166 USB_debug("BUFFER UNDERRUN");
167 break;
168 case TD_NOTACCESSED:
169 USB_debug("NOT ACCESSED");
170 break;
171 }
172 USB_debug(", [0x%02x]\n", cc);
173}
174
175
176/*-------------------------------------------------------------------------*
177 * URB support functions
178 *-------------------------------------------------------------------------*/
179
180/* free HCD-private data associated with this URB */
181static void urb_free_priv(URB_PRIV_T *urb_priv)
182{
183 int i;
184
185 for (i = 0; i < urb_priv->length; i++)
186 {
187 if (urb_priv->td[i])
188 ohci_free_td(urb_priv->td[i]);
189 }
190}
191
192
193/*-------------------------------------------------------------------------*/
194
195/* debug| print the main components of an URB
196 * small: 0) header + data packets 1) just header */
197#ifdef USB_VERBOSE_DEBUG
198static void urb_print(URB_T * urb, char * str, int small)
199{
200 int len;
201 uint32_t pipe;
202
203 pipe = urb->pipe;
204
205 if (!urb->dev || !urb->dev->bus)
206 {
207 USB_debug("%s URB: no dev\n", str);
208 return;
209 }
210
211 USB_debug("%s - ", str);
212
213 if (urb->status != 0)
214 {
215 USB_debug("URB -");
216 USB_debug("dev:%d, ", usb_pipedevice (pipe));
217 USB_debug("ep:%d<%c>, ", usb_pipeendpoint (pipe), usb_pipeout (pipe)? 'O': 'I');
218 //USB_debug("type:%s\n ", usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
219 // (usb_pipecontrol (pipe)? "CTRL": "BULK"));
220 USB_debug("flags:%04x, ", urb->transfer_flags);
221 USB_debug("len:%d/%d, ", urb->actual_length, urb->transfer_buffer_length);
222 USB_debug("stat:%d(%x)\n", urb->status, urb->status);
223 }
224
225 if (!small)
226 {
227 int i; //, len;
228
229 if (usb_pipecontrol (pipe))
230 {
231 switch (urb->setup_packet[1])
232 {
233 case 0:
234 USB_debug("GET_STATUS");
235 break;
236 case 1:
237 USB_debug("CLEAR_FEATURE");
238 break;
239 case 3:
240 USB_debug("SET_FEATURE");
241 break;
242 case 5:
243 USB_debug("SET_ADDRESS");
244 break;
245 case 6:
246 USB_debug("GET_DESCRIPTOR");
247 break;
248 case 7:
249 USB_debug("SET_DESCRIPTOR");
250 break;
251 case 8:
252 USB_debug("GET_CONFIGURATION");
253 break;
254 case 9:
255 USB_debug("SET_CONFIGURATION");
256 break;
257 case 10:
258 USB_debug("GET_INTERFACE");
259 break;
260 case 11:
261 USB_debug("SET_INTERFACE");
262 break;
263 case 12:
264 USB_debug("SYNC_FRAME");
265 break;
266 default:
267 USB_debug("Command");
268 break;
269 }
270
271 USB_debug("(8):");
272 for (i = 0; i < 8 ; i++)
273 USB_debug (" %02x", ((uint8_t *) urb->setup_packet) [i]);
274 USB_debug("\n");
275 }
276 if (urb->transfer_buffer_length > 0 && urb->transfer_buffer)
277 {
278 USB_debug(": data(%d/%d):", urb->actual_length,
279 urb->transfer_buffer_length);
280 len = usb_pipeout (pipe)?
281 urb->transfer_buffer_length: urb->actual_length;
282 for (i = 0; i < 16 && i < len; i++)
283 USB_debug (" %02x", ((uint8_t *) urb->transfer_buffer) [i]);
284 USB_debug("%s stat:%d\n", i < len? "...": "", urb->status);
285 }
286 USB_debug("\n");
287 }
288 USB_debug("\n");
289}
290#endif
291
292
293#if 0
294/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
295static void ep_print_int_eds()
296{
297 int i, j;
298 uint32_t *ed_p;
299 ED_T *ed;
300
301 for (i = 0; i < 32; i++)
302 {
303 j = 5;
304 ed_p = &(ohci.hcca->int_table[i]);
305 if (*ed_p == 0)
306 continue;
307 USB_debug("branch %d:", i);
308 while ((*ed_p != 0) && (j--))
309 {
310 ed = (ED_T *) (*ed_p);
311 USB_debug(" ed:%4x;", ed->hwINFO);
312 ed_p = &ed->hwNextED;
313 }
314 USB_debug("\n");
315 }
316}
317#endif
318
319
320/*-------------------------------------------------------------------------*
321 * Interface functions (URB)
322 *-------------------------------------------------------------------------*/
323/* return a request to the completion handler */
324
325static int sohci_return_urb(URB_T * urb)
326{
327 URB_PRIV_T *urb_priv;
328
329 urb_priv = &urb->urb_hcpriv;
330
331 /* just to be sure */
332 if (!urb->complete)
333 {
334 urb_free_priv(&urb->urb_hcpriv);
335 return -1;
336 }
337
338#ifdef USB_VERBOSE_DEBUG
339 urb_print (urb, "RET", usb_pipeout(urb->pipe));
340#endif
341
342 switch (usb_pipetype (urb->pipe))
343 {
344 case PIPE_INTERRUPT:
345 urb->complete(urb); /* call complete and requeue URB */
346 urb->actual_length = 0;
347
348#if 1 // 2013.07.31
349 if ((urb_priv->state != URB_DEL) && (urb->status == 0))
350#else
351 if (urb_priv->state != URB_DEL)
352#endif
353 {
354 urb->status = USB_ERR_URB_PENDING;
355 td_submit_urb(urb);
356 }
357 break;
358
359 case PIPE_ISOCHRONOUS:
360#if 0
361 for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next);
362 if (urbt)
363 {
364 /* send the reply and requeue URB */
365 urb->complete(urb);
366 urb->actual_length = 0;
367 urb->status = USB_ERR_URB_PENDING;
368 urb->start_frame = urb_priv->ed->last_iso + 1;
369 if (urb_priv->state != URB_DEL)
370 {
371 for (i = 0; i < urb->number_of_packets; i++)
372 {
373 urb->iso_frame_desc[i].actual_length = 0;
374 urb->iso_frame_desc[i].status = -USB_ERR_XDEV;
375 }
376 td_submit_urb (urb);
377 }
378 }
379 else
380 {
381 /* unlink URB, call complete */
382 urb_free_priv(&urb->urb_hcpriv);
383 urb->complete (urb);
384 }
385#endif
386 urb_free_priv(&urb->urb_hcpriv);
387 urb->complete(urb);
388 break;
389
390 case PIPE_BULK:
391 case PIPE_CONTROL: /* unlink URB, call complete */
392 urb_free_priv(&urb->urb_hcpriv);
393 urb->complete(urb);
394 break;
395 }
396 return 0;
397}
398
399
400/*-------------------------------------------------------------------------*/
401
402/* get a transfer request */
403
404static int sohci_submit_urb(URB_T * urb)
405{
406 URB_PRIV_T *urb_priv;
407 ED_T *ed;
408 uint32_t pipe;
409 int i, size = 0;
410
411 pipe = urb->pipe;
412
413 USB_info("[OHCI] Enter sohci_submit_urb() ...\n");
414
415 if (!urb->dev || !urb->dev->bus)
416 return USB_ERR_NODEV;
417
418 if ((usb_pipeendpoint(pipe) != 0) &&
419 (usb_endpoint_halted(urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe))))
420 return USB_ERR_PIPE;
421
422#ifdef USB_VERBOSE_DEBUG
423 urb_print (urb, "SUB", usb_pipein (pipe));
424#endif
425
426 /* handle a request to the virtual root hub */
427 if (usb_pipedevice(pipe) == ohci.rh.devnum)
428 return rh_submit_urb(urb);
429
430 /* when controller's hung, permit only roothub cleanup attempts
431 * such as powering down ports */
432 if (ohci.disabled)
433 return USB_ERR_SHUTDOWN;
434
435 /* every endpoint has an ed, locate and fill it */
436 ed = ep_add_ed(urb->dev, pipe, urb->interval, 1);
437 if (!ed)
438 return USB_ERR_NOMEM;
439
440 /* for the private part of the URB we need the number of TDs (size) */
441 switch (usb_pipetype (pipe))
442 {
443 case PIPE_BULK: /* one TD for every 4096 Byte */
444 size = (urb->transfer_buffer_length - 1) / 4096 + 1;
445 break;
446
447 case PIPE_ISOCHRONOUS: /* number of packets from URB */
448 size = urb->number_of_packets / ISO_FRAME_COUNT;
449 if (size <= 0)
450 return USB_ERR_INVAL;
451
452 for (i = 0; i < urb->number_of_packets; i++)
453 {
454 urb->iso_frame_desc[i].actual_length = 0;
455 urb->iso_frame_desc[i].status = -USB_ERR_XDEV;
456 }
457 break;
458
459 case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
460 size = (urb->transfer_buffer_length == 0)? 2:
461 (urb->transfer_buffer_length - 1) / 4096 + 3;
462 break;
463
464 case PIPE_INTERRUPT: /* one TD */
465 size = 1;
466 break;
467 }
468
469 if (size > MAX_TD_PER_OHCI_URB)
470 return USB_ERR_NOMEM;
471
472 /* allocate the private part of the URB */
473 urb_priv = &(urb->urb_hcpriv);
474 memset(urb_priv, 0, sizeof(URB_PRIV_T));
475
476 for (i = 0; i < size; i++)
477 {
478 urb_priv->td[i] = ohci_alloc_td(urb->dev);
479 if (!urb_priv->td[i])
480 {
481 urb_free_priv(urb_priv);
482 return USB_ERR_NOMEM;
483 }
484 }
485
486 /* fill the private part of the URB */
487 urb_priv->length = size;
488 urb_priv->ed = ed;
489
490 if (ed->state == ED_NEW || (ed->state & ED_DEL))
491 {
492 urb_free_priv(urb_priv);
493 return USB_ERR_INVAL;
494 }
495
496 if (usb_pipetype(pipe) == PIPE_ISOCHRONOUS)
497 {
498 if (urb->transfer_flags & USB_ISO_ASAP)
499 {
500 urb->start_frame = ((ed->state == ED_OPER) ? (ed->last_iso + 1) : (ohci.hcca->frame_no)) & 0xffff;
501 }
502 }
503
504 urb->actual_length = 0;
505 urb->status = USB_ERR_URB_PENDING;
506
507 if (pipe == PIPE_INTERRUPT)
508 USB_debug("submit: urb: %x, ed: %x\n", (int)urb, (int)ed);
509
510 /* link the ed into a chain if is not already */
511 if (ed->state != ED_OPER)
512 ep_link(ed);
513
514 /* fill the TDs and link it to the ed */
515 td_submit_urb(urb);
516 return 0;
517}
518
519
520/*-------------------------------------------------------------------------*/
521
522/* deactivate all TDs and remove the private part of the URB */
523/* interrupt callers must use async unlink mode */
524
525static int sohci_unlink_urb (URB_T * urb)
526{
527 if (!urb) /* just to be sure */
528 return USB_ERR_INVAL;
529
530 if (!urb->dev || !urb->dev->bus)
531 return USB_ERR_NODEV;
532
533#ifdef USB_VERBOSE_DEBUG
534 urb_print (urb, "UNLINK", 1);
535#endif
536
537 /* handle a request to the virtual root hub */
538 if (usb_pipedevice (urb->pipe) == ohci.rh.devnum)
539 return rh_unlink_urb(urb);
540
541 if (urb->status == USB_ERR_URB_PENDING)
542 {
543 if (!ohci.disabled)
544 {
545 URB_PRIV_T * urb_priv;
546
547 /* interrupt code may not sleep; it must use
548 * async status return to unlink pending urbs.
549 */
550 if (!(urb->transfer_flags & USB_ASYNC_UNLINK) && _is_in_interrupt)
551 {
552 USB_error("bug in call to sohci_unlink_urb!!\n");
553 return EWOULDBLOCK;
554 }
555
556 /* flag the urb and its TDs for deletion in some
557 * upcoming SF interrupt delete list processing
558 */
559 urb_priv = &urb->urb_hcpriv;
560
561 if (urb_priv->state == URB_DEL)
562 return 0;
563
564 urb_priv->state = URB_DEL;
565
566 ep_rm_ed(urb->dev, urb_priv->ed);
567 urb_priv->ed->state |= ED_URB_DEL;
568
569 if (!(urb->transfer_flags & USB_ASYNC_UNLINK))
570 {
571 /* wait until all TDs are deleted */
572 usbh_mdelay(100);
573
574 if (urb->status == USB_ERR_URB_PENDING)
575 {
576 USB_warning("unlink URB timeout\n");
577 return USB_ERR_TIMEOUT;
578 }
579
580 // 2014.07.28, force free TDs
581 urb_free_priv(&urb->urb_hcpriv);
582 }
583 else /* (urb->transfer_flags & USB_ASYNC_UNLINK) */
584 {
585 urb->status = USB_ERR_INPROGRESS;
586 }
587 }
588 else /* ohci->disabled */
589 {
590 urb_free_priv(&urb->urb_hcpriv);
591 if (urb->transfer_flags & USB_ASYNC_UNLINK)
592 {
593 urb->status = USB_ERR_CONNRESET;
594 if (urb->complete)
595 urb->complete (urb);
596 }
597 else
598 urb->status = USB_ERR_NOENT;
599 }
600 }
601 return 0;
602}
603
604/*-------------------------------------------------------------------------*/
605
606/* allocate private data space for a usb device */
607
608static int sohci_alloc_dev(USB_DEV_T *usb_dev)
609{
610 int i;
611 OHCI_DEVICE_T *ohcidev;
612
613 for (i = 0; i < DEV_MAX_NUM; i++)
614 {
615 if (ohci_dev_alloc_mark[i] == 0)
616 {
617 ohci_dev_alloc_mark[i] = 1;
618 ohcidev = &g_ohci_dev_pool[i];
619 memset((char *)ohcidev, 0, sizeof (OHCI_DEVICE_T));
620 usb_dev->hcpriv = ohcidev;
621 return 0;
622 }
623 }
624 USB_error("sohci_alloc_dev - no free memory!\n");
625 return USB_ERR_NOMEM;
626}
627
628/*-------------------------------------------------------------------------*/
629
630/* may be called from interrupt context */
631/* frees private data space of usb device */
632
633static int sohci_free_dev (USB_DEV_T * usb_dev)
634{
635 int i, cnt = 0;
636 ED_T *ed;
637 OHCI_DEVICE_T *dev;
638
639 dev = usb_to_ohci(usb_dev);
640
641 if (!dev)
642 return 0;
643
644 if (usb_dev->devnum >= 0)
645 {
646 /* driver disconnects should have unlinked all urbs
647 * (freeing all the TDs, unlinking EDs) but we need
648 * to defend against bugs that prevent that.
649 */
650 for (i = 0; i < NUM_EDS; i++)
651 {
652 ed = dev->edp[i];
653 if (ed != NULL)
654 {
655 if (ed->state != ED_NEW)
656 {
657 if (ed->state == ED_OPER)
658 {
659 /* driver on that interface didn't unlink an urb */
660 USB_warning("driver dev %d ed 0x%x unfreed URB\n", usb_dev->devnum, i);
661 ep_unlink(ed);
662 }
663 ep_rm_ed(usb_dev, ed);
664 ed->state = ED_DEL;
665 cnt++;
666 }
667 ohci_free_ed(ed);
668 dev->edp[i] = 0;
669 }
670 }
671
672 /* if the controller is running, tds for those unlinked
673 * urbs get freed by dl_del_list at the next SF interrupt
674 */
675 if (cnt > 0)
676 {
677 if (ohci.disabled)
678 {
679 /* FIXME: Something like this should kick in,
680 * though it's currently an exotic case ...
681 * the controller won't ever be touching
682 * these lists again!!
683 * dl_del_list (ohci, le16_to_cpu (ohci->hcca->frame_no) & 1);
684 */
685 USB_warning("Warning! TD leak, %d\n", cnt);
686 }
687 else if (!_is_in_interrupt)
688 {
689 /* SF interrupt handler calls dl_del_list */
690 usbh_mdelay(100);
691
692 if (dev->ed_cnt)
693 {
694 USB_error("Error! - free device %d timeout", usb_dev->devnum);
695 return USB_ERR_TIMEOUT;
696 }
697 }
698 else
699 {
700 /* likely some interface's driver has a refcount bug */
701 USB_error("Error! - devnum %d deletion in interrupt\nSystem Halt!!", usb_dev->devnum);
702 }
703 }
704 }
705
706 ohci_free_dev_td(usb_dev);
707
708 for (i = 0; i < DEV_MAX_NUM; i++)
709 {
710 if (&g_ohci_dev_pool[i] == dev)
711 ohci_dev_alloc_mark[i] = 0;
712 }
713 return 0;
714}
715
716/*-------------------------------------------------------------------------*/
717
718/* tell us the current USB frame number */
719static int sohci_get_current_frame_number(USB_DEV_T *usb_dev)
720{
721 return ohci.hcca->frame_no;
722}
723
724/*-------------------------------------------------------------------------*/
725
726USB_OP_T sohci_device_operations =
727{
728 sohci_alloc_dev,
729 sohci_free_dev,
730 sohci_get_current_frame_number,
731 sohci_submit_urb,
732 sohci_unlink_urb
733};
734
735/*-------------------------------------------------------------------------*
736 * ED handling functions
737 *-------------------------------------------------------------------------*/
738
739/* search for the right branch to insert an interrupt ed into the int tree
740 * do some load balancing;
741 * returns the branch and
742 * sets the interval to interval = 2^integer (ld (interval)) */
743static int ep_int_ballance (int interval, int load)
744{
745 int i, branch = 0;
746
747 /* search for the least loaded interrupt endpoint branch of all 32 branches */
748 for (i = 0; i < 32; i++)
749 if (ohci.ohci_int_load [branch] > ohci.ohci_int_load [i])
750 branch = i;
751
752 branch = branch % interval;
753 for (i = branch; i < 32; i += interval)
754 ohci.ohci_int_load [i] += load;
755
756 return branch;
757}
758
759/*-------------------------------------------------------------------------*/
760
761/* 2^int( ld (inter)) */
762/* depends on <inter>, return a value of 1,2,4,8,16,or 32 */
763static int ep_2_n_interval(int inter)
764{
765 int i;
766
767 for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++);
768 return 1 << i;
769}
770
771/*-------------------------------------------------------------------------*/
772
773/* the int tree is a binary tree
774 * in order to process it sequentially the indexes of the branches have to be mapped
775 * the mapping reverses the bits of a word of num_bits length */
776
777static int ep_rev(int num_bits, int word)
778{
779 int i, wout = 0;
780
781 for (i = 0; i < num_bits; i++)
782 wout |= (((word >> i) & 1) << (num_bits - i - 1));
783 return wout;
784}
785
786
787
788/*-------------------------------------------------------------------------*/
789
790/* link an ed into one of the HC chains */
791
792static int ep_link(ED_T *edi)
793{
794 int int_branch;
795 int i;
796 int inter;
797 int interval;
798 int load;
799 uint32_t *ed_p;
800 volatile ED_T *ed;
801
802 ed = edi;
803 ed->state = ED_OPER;
804 switch (ed->type)
805 {
806 case PIPE_CONTROL:
807 ed->hwNextED = 0;
808 if (ohci.ed_controltail == NULL)
809 USBH->HcControlHeadED = (uint32_t)ed;
810 else
811 ohci.ed_controltail->hwNextED = (uint32_t)ed;
812 ed->ed_prev = ohci.ed_controltail;
813 if (!ohci.ed_controltail && !ohci.ed_rm_list[0] && (!ohci.ed_rm_list[1]))
814 {
815 ohci.hc_control |= OHCI_CTRL_CLE;
816 USBH->HcControl = ohci.hc_control;
817 }
818 ohci.ed_controltail = edi;
819 break;
820
821 case PIPE_BULK:
822 ed->hwNextED = 0;
823 if (ohci.ed_bulktail == NULL)
824 USBH->HcBulkHeadED = (uint32_t)ed;
825 else
826 ohci.ed_bulktail->hwNextED = (uint32_t)ed;
827 ed->ed_prev = ohci.ed_bulktail;
828 if (!ohci.ed_bulktail && !ohci.ed_rm_list[0] && (!ohci.ed_rm_list[1]))
829 {
830 ohci.hc_control |= OHCI_CTRL_BLE;
831 USBH->HcControl = ohci.hc_control;
832 }
833 ohci.ed_bulktail = edi;
834 break;
835
836 case PIPE_INTERRUPT:
837 load = ed->int_load;
838 interval = ep_2_n_interval(ed->int_period);
839 ed->int_interval = interval;
840 int_branch = ep_int_ballance(interval, load);
841 ed->int_branch = int_branch;
842
843 for (i = 0; i < ep_rev(6, interval); i += inter)
844 {
845 inter = 1;
846
847 for (ed_p = &(ohci.hcca->int_table[ep_rev (5,i) + int_branch]);
848 (*ed_p != 0) && (((ED_T *) (*ed_p))->int_interval >= interval);
849 ed_p = &(((ED_T *) (*ed_p))->hwNextED))
850 inter = ep_rev(6, ((ED_T *) (*ed_p))->int_interval);
851 ed->hwNextED = *ed_p;
852 *ed_p = (uint32_t)ed;
853 }
854 break;
855
856 case PIPE_ISOCHRONOUS:
857 ed->hwNextED = 0;
858 ed->int_interval = 1;
859 if (ohci.ed_isotail != NULL)
860 {
861 ohci.ed_isotail->hwNextED = (uint32_t)ed;
862 ed->ed_prev = ohci.ed_isotail;
863 }
864 else
865 {
866 for ( i = 0; i < 32; i += inter)
867 {
868 inter = 1;
869 for (ed_p = &(ohci.hcca->int_table[ep_rev (5, i)]);
870 (*ed_p != 0) && ed_p; ed_p = &(((ED_T *) (*ed_p))->hwNextED))
871 inter = ep_rev (6, ((ED_T *) (*ed_p))->int_interval);
872 *ed_p = (uint32_t)ed;
873 }
874 ed->ed_prev = NULL;
875 }
876 ohci.ed_isotail = edi;
877 break;
878 }
879 return 0;
880}
881
882/*-------------------------------------------------------------------------*/
883
884/* unlink an ed from one of the HC chains.
885 * just the link to the ed is unlinked.
886 * the link from the ed still points to another operational ed or 0
887 * so the HC can eventually finish the processing of the unlinked ed */
888
889static int ep_unlink(ED_T *ed)
890{
891 int i;
892 uint32_t *ed_ptr;
893
894 ed->hwINFO |= OHCI_ED_SKIP;
895 switch (ed->type)
896 {
897 case PIPE_CONTROL:
898 if (ed->ed_prev == NULL)
899 {
900 if (!ed->hwNextED)
901 {
902 ohci.hc_control &= ~OHCI_CTRL_CLE;
903 USBH->HcControl = ohci.hc_control;
904 }
905 USBH->HcControlHeadED = ed->hwNextED;
906 }
907 else
908 ed->ed_prev->hwNextED = ed->hwNextED;
909
910 if (ohci.ed_controltail == ed)
911 ohci.ed_controltail = ed->ed_prev;
912 else
913 ((ED_T *)(ed->hwNextED))->ed_prev = ed->ed_prev;
914 break;
915
916 case PIPE_BULK:
917 if (ed->ed_prev == NULL)
918 {
919 if (!ed->hwNextED)
920 {
921 ohci.hc_control &= ~OHCI_CTRL_BLE;
922 USBH->HcControl = ohci.hc_control;
923 }
924 USBH->HcBulkHeadED = ed->hwNextED;
925 }
926 else
927 ed->ed_prev->hwNextED = ed->hwNextED;
928
929 if (ohci.ed_bulktail == ed)
930 ohci.ed_bulktail = ed->ed_prev;
931 else
932 ((ED_T *)(ed->hwNextED))->ed_prev = ed->ed_prev;
933 break;
934
935 case PIPE_ISOCHRONOUS:
936
937 if (ohci.ed_isotail == ed)
938 ohci.ed_isotail = ed->ed_prev;
939 if (ed->hwNextED != 0)
940 ((ED_T *)ed->hwNextED)->ed_prev = ed->ed_prev;
941
942 if (ed->ed_prev != NULL)
943 {
944 ed->ed_prev->hwNextED = ed->hwNextED;
945 }
946
947 // Isochronous fall through ...
948
949 case PIPE_INTERRUPT:
950 for (i = 0; i < 32; i++)
951 {
952 for (ed_ptr = (uint32_t *)&(ohci.hcca->int_table[i]);
953 (*ed_ptr != 0); ed_ptr = (uint32_t *) &(((ED_T *) (*ed_ptr))->hwNextED))
954 {
955 if (ed_ptr == (uint32_t *) &(((ED_T *) (*ed_ptr))->hwNextED))
956 break;
957
958 if ((ED_T *)*ed_ptr == ed)
959 {
960 *ed_ptr = (uint32_t) (((ED_T *) (*ed_ptr))->hwNextED);
961 break;
962 }
963 }
964 }
965 break;
966
967 }
968 ed->state = ED_UNLINK;
969 return 0;
970}
971
972
973/*-------------------------------------------------------------------------*/
974
975/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
976 * but the USB stack is a little bit stateless so we do it at every transaction
977 * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
978 * in all other cases the state is left unchanged
979 * the ed info fields are setted anyway even though most of them should not change */
980
981static ED_T *ep_add_ed(USB_DEV_T *usb_dev, uint32_t pipe, int interval, int load)
982{
983 TD_T *td;
984 ED_T *ed_ret;
985 OHCI_DEVICE_T *ohci_dev;
986 int ep_num;
987 volatile ED_T *ed;
988
989 ohci_dev = usb_to_ohci(usb_dev);
990 ep_num = (((pipe) >> 15) & 0xf);
991 if (pipe & 0x80)
992 ep_num |= 0x10;
993
994 if (ohci_dev->edp[ep_num] == NULL)
995 ohci_dev->edp[ep_num] = ohci_alloc_ed();
996
997 if (ohci_dev->edp[ep_num] == NULL)
998 {
999 return NULL;
1000 }
1001
1002 ed = ed_ret = ohci_dev->edp[ep_num];
1003
1004 if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL))
1005 return NULL;
1006
1007 if (ed->state == ED_NEW)
1008 {
1009 ed->hwINFO = OHCI_ED_SKIP; /* skip ed */
1010 /* dummy td; end of td list for ed */
1011 td = ohci_alloc_td(usb_dev);
1012 if (!td)
1013 return NULL;
1014
1015 ed->hwTailP = (uint32_t)td;
1016 ed->hwHeadP = ed->hwTailP;
1017 ed->state = ED_UNLINK;
1018 ed->type = usb_pipetype(pipe);
1019 usb_to_ohci (usb_dev)->ed_cnt++;
1020 }
1021
1022 ohci.dev[usb_pipedevice(pipe)] = usb_dev;
1023
1024 ed->hwINFO = (usb_pipedevice (pipe)
1025 | usb_pipeendpoint (pipe) << 7
1026 | (usb_pipeisoc (pipe)? 0x8000: 0)
1027 | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
1028 | usb_pipeslow (pipe) << 13
1029 | usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)) << 16);
1030
1031 if ((ed->type == PIPE_INTERRUPT) && (ed->state == ED_UNLINK))
1032 {
1033 ed->int_period = interval;
1034 ed->int_load = load;
1035 }
1036 return ed_ret;
1037}
1038
1039
1040
1041/*-------------------------------------------------------------------------*/
1042
1043/* request the removal of an endpoint
1044 * put the ep on the rm_list and request a stop of the bulk or ctrl list
1045 * real removal is done at the next start frame (SF) hardware interrupt */
1046
1047static void ep_rm_ed(USB_DEV_T *usb_dev, ED_T *ed)
1048{
1049 uint32_t frame;
1050
1051 if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL))
1052 return;
1053
1054 ed->hwINFO |= OHCI_ED_SKIP;
1055
1056 if (!ohci.disabled)
1057 {
1058 switch (ed->type)
1059 {
1060 case PIPE_CONTROL: /* stop control list */
1061 ohci.hc_control &= ~OHCI_CTRL_CLE;
1062 USBH->HcControl = ohci.hc_control;
1063 break;
1064 case PIPE_BULK: /* stop bulk list */
1065 ohci.hc_control &= ~OHCI_CTRL_BLE;
1066 USBH->HcControl = ohci.hc_control;
1067 break;
1068 }
1069 }
1070 frame = ohci.hcca->frame_no & 0x1;
1071 ed->ed_rm_list = ohci.ed_rm_list[frame];
1072 ohci.ed_rm_list[frame] = ed;
1073
1074 if (!ohci.disabled)
1075 {
1076 /* enable SOF interrupt */
1077 USBH->HcInterruptStatus = OHCI_INTR_SF;
1078 USBH->HcInterruptEnable = OHCI_INTR_SF;
1079 }
1080}
1081
1082
1083
1084/*-------------------------------------------------------------------------*
1085 * TD handling functions
1086 *-------------------------------------------------------------------------*/
1087static void iso_td_fill(uint32_t info, void *data, URB_T *urb, int index)
1088{
1089 volatile TD_T *td, *td_pt;
1090 volatile URB_PRIV_T *urb_priv;
1091 int len=0, i;
1092 uint32_t bufferStart;
1093
1094 urb_priv = &urb->urb_hcpriv;
1095
1096 if (index >= urb_priv->length)
1097 {
1098 USB_error("Error! - internal OHCI error: TD index > length\n");
1099 return;
1100 }
1101
1102 td_pt = urb_priv->td[index];
1103
1104 /*- fill the old dummy TD -*/
1105 td = urb_priv->td[index] = (TD_T *)((uint32_t)urb_priv->ed->hwTailP & 0xfffffff0); /* find the tail of the td list of this URB */
1106
1107 td->ed = urb_priv->ed;
1108 td->ed->last_iso = (info & 0xffff) + ISO_FRAME_COUNT - 1;
1109 info = (info & 0xffff0000) | ((info + OHCI_ISO_DELAY) & 0xffff);
1110 td->next_dl_td = NULL;
1111 td->index = index;
1112 td->urb = urb;
1113
1114 bufferStart = (uint32_t)data + urb->iso_frame_desc[index * ISO_FRAME_COUNT].offset;
1115
1116 /* caculate total length of frames to be filled in this TD */
1117 for (i = index * ISO_FRAME_COUNT; i < (index + 1) * ISO_FRAME_COUNT; i++)
1118 len += urb->iso_frame_desc[i].length;
1119
1120 td->hwINFO = info;
1121 td->hwCBP = (uint32_t)((!bufferStart || !len) ? 0 : bufferStart) & 0xFFFFF000;
1122 td->hwBE = (uint32_t)((!bufferStart || !len ) ? 0 : (bufferStart + len -1));
1123 td->hwNextTD = (uint32_t)td_pt;
1124 td->is_iso_packet = 1;
1125
1126#ifdef DELAY_INTERRUPT
1127 info = (info & 0xFF1FFFFF) | (3 << 21); /* delay 3 frame */
1128#endif
1129
1130 td->hwPSW[0] = (((uint32_t)data + urb->iso_frame_desc[index * ISO_FRAME_COUNT].offset) & 0x0FFF) | 0xE000;
1131 for (i = 0; i < ISO_FRAME_COUNT / 2; i++)
1132 {
1133 td->hwPSW[i] = (((uint32_t)data + urb->iso_frame_desc[index * ISO_FRAME_COUNT + i * 2].offset) & 0x0FFF) |
1134 (((uint32_t)data + urb->iso_frame_desc[index * ISO_FRAME_COUNT + i * 2 + 1].offset & 0x0FFF) << 16);
1135 td->hwPSW[i] |= 0xE000E000;
1136 }
1137
1138 USB_info("Frame:[%x], CBP:[%x], BE:[%x], PSW0:[%x], PSW1:[%x]\n",
1139 td->hwINFO & 0xffff, td->hwCBP, td->hwBE, td->hwPSW[0], td->hwPSW[1]);
1140
1141 /* chaining the new dummy TD */
1142 td_pt->hwNextTD = 0;
1143 td->ed->hwTailP = td->hwNextTD;
1144}
1145
1146
1147
1148/* prepare a TD */
1149static void td_fill(uint32_t info, void *data, int len, URB_T *urb, int index)
1150{
1151 volatile TD_T *td, *td_pt;
1152 volatile URB_PRIV_T *urb_priv;
1153
1154 urb_priv = &urb->urb_hcpriv;
1155
1156 if (index >= urb_priv->length)
1157 {
1158 USB_error("Error! - internal OHCI error: TD index > length\n");
1159 return;
1160 }
1161
1162 td_pt = urb_priv->td[index];
1163
1164 /*- fill the old dummy TD -*/
1165 td = urb_priv->td[index] = (TD_T *)((uint32_t)urb_priv->ed->hwTailP & 0xfffffff0); /* find the tail of the td list of this URB */
1166 td->ed = urb_priv->ed; /* the endpoint(pipe) of this URB */
1167 td->next_dl_td = NULL;
1168 td->index = index;
1169 td->urb = urb;
1170
1171 td->hwINFO = info;
1172 td->hwCBP = (uint32_t)((!data || !len) ? 0 : data);
1173 td->hwBE = (uint32_t)((!data || !len ) ? 0 : (uint32_t)data + len - 1);
1174 td->hwNextTD = (uint32_t)td_pt;
1175 td->is_iso_packet = 0;
1176
1177#ifdef DELAY_INTERRUPT
1178 info = (info & 0xFF1FFFFF) | (3 << 21); /* delay 3 frame */
1179#endif
1180
1181 td_pt->hwNextTD = 0;
1182 td->ed->hwTailP = td->hwNextTD;
1183
1184 //USB_info("td_fill ed:[%x] td:[%x] - hwINFO:%08x hwCBP:%08x\n hwNextTD:%08x hwBE:%08x\n",
1185 // (int)td->ed, (int)td, td->hwINFO, td->hwCBP, td->hwNextTD, td->hwBE);
1186}
1187
1188/*-------------------------------------------------------------------------*/
1189
1190/* prepare all TDs of a transfer */
1191static void td_submit_urb(URB_T * urb)
1192{
1193 URB_PRIV_T *urb_priv;
1194 void *ctrl;
1195 void *data;
1196 int data_len;
1197 int cnt = 0;
1198 uint32_t info = 0;
1199 uint32_t toggle = 0;
1200
1201 urb_priv = &urb->urb_hcpriv;
1202 ctrl = urb->setup_packet;
1203 data = urb->transfer_buffer;
1204 data_len = urb->transfer_buffer_length;
1205 /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
1206 if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
1207 {
1208 toggle = TD_T_TOGGLE;
1209 }
1210 else
1211 {
1212 toggle = TD_T_DATA0;
1213 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 1);
1214 }
1215
1216 urb_priv->td_cnt = 0;
1217
1218 switch (usb_pipetype (urb->pipe))
1219 {
1220 case PIPE_BULK:
1221 info = usb_pipeout(urb->pipe)? (TD_CC | TD_DP_OUT) : (TD_CC | TD_DP_IN);
1222 while(data_len > 4096)
1223 {
1224 td_fill(info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt);
1225 data = (void *)((uint32_t)data + 4096);
1226 data_len -= 4096;
1227 cnt++;
1228 }
1229 info = usb_pipeout(urb->pipe)? (TD_CC | TD_DP_OUT) : (TD_CC | TD_R | TD_DP_IN);
1230 td_fill(info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt);
1231 cnt++;
1232 USBH->HcCommandStatus = OHCI_BLF; /* start bulk list */
1233 break;
1234
1235 case PIPE_INTERRUPT:
1236 info = usb_pipeout (urb->pipe)? (TD_CC | TD_DP_OUT | toggle) : (TD_CC | TD_R | TD_DP_IN | toggle);
1237 td_fill(info, data, data_len, urb, cnt++);
1238 break;
1239
1240 case PIPE_CONTROL:
1241 info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
1242 td_fill(info, ctrl, 8, urb, cnt++);
1243 if (data_len > 0)
1244 {
1245 info = usb_pipeout (urb->pipe)? (TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1) : (TD_CC | TD_R | TD_DP_IN | TD_T_DATA1);
1246 td_fill(info, data, data_len, urb, cnt++);
1247 }
1248 info = usb_pipeout (urb->pipe)? (TD_CC | TD_DP_IN | TD_T_DATA1): (TD_CC | TD_DP_OUT | TD_T_DATA1);
1249 td_fill(info, NULL, 0, urb, cnt++);
1250 USBH->HcCommandStatus = OHCI_CLF; /* start Control list */
1251 break;
1252
1253 case PIPE_ISOCHRONOUS:
1254 for (cnt = 0; cnt < urb->number_of_packets / ISO_FRAME_COUNT; cnt++)
1255 {
1256 iso_td_fill(TD_CC | ((ISO_FRAME_COUNT - 1) << 24) | ((urb->start_frame + cnt * ISO_FRAME_COUNT) & 0xffff ),
1257 (uint8_t *) data, urb, cnt);
1258 }
1259 break;
1260 }
1261 if (urb_priv->length != cnt)
1262 USB_error("Error! - TD LENGTH %d != CNT %d", urb_priv->length, cnt);
1263}
1264
1265/*-------------------------------------------------------------------------*
1266 * Done List handling functions
1267 *-------------------------------------------------------------------------*/
1268
1269
1270/* calculate the transfer length and update the urb */
1271
1272static void dl_transfer_length(TD_T * td)
1273{
1274 uint32_t tdBE, tdCBP;
1275 uint16_t tdPSW;
1276 URB_T *urb;
1277 URB_PRIV_T *urb_priv;
1278 int dlen = 0;
1279 int cc = 0;
1280
1281 urb = td->urb;
1282 urb_priv = &urb->urb_hcpriv;
1283
1284 tdBE = (uint32_t)td->hwBE;
1285 tdCBP = (uint32_t)td->hwCBP;
1286
1287 if (td->is_iso_packet)
1288 {
1289 int i, index;
1290
1291
1292 for (i = 0; i < ISO_FRAME_COUNT; i++)
1293 {
1294 index = td->index * ISO_FRAME_COUNT + i;
1295 if (i % 2)
1296 tdPSW = td->hwPSW[i / 2] >> 16;
1297 else
1298 tdPSW = td->hwPSW[i / 2] & 0xffff;
1299
1300 cc = (tdPSW >> 12) & 0xF;
1301 if (cc < 0xE)
1302 {
1303 if (usb_pipeout(urb->pipe))
1304 dlen = urb->iso_frame_desc[index].length;
1305 else
1306 dlen = tdPSW & 0x3ff;
1307
1308 urb->actual_length += dlen;
1309 urb->iso_frame_desc[index].actual_length = dlen;
1310 if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN))
1311 cc = TD_CC_NOERROR;
1312 urb->iso_frame_desc[index].status = cc_to_error[cc];
1313 }
1314 }
1315 }
1316 else
1317 {
1318 /* BULK, int, CONTROL DATA */
1319 if (!(usb_pipetype (urb->pipe) == PIPE_CONTROL &&
1320 ((td->index == 0) || (td->index == urb_priv->length - 1))))
1321 {
1322 if (tdBE != 0)
1323 {
1324 if (td->hwCBP == 0)
1325 urb->actual_length = (uint32_t)tdBE - (uint32_t)urb->transfer_buffer + 1;
1326 else
1327 urb->actual_length = (uint32_t)tdCBP - (uint32_t)urb->transfer_buffer;
1328 }
1329 }
1330 USB_info("td:%x urb->actual_length:%d\n", (int)td, urb->actual_length);
1331 }
1332}
1333
1334
1335/* handle an urb that is being unlinked */
1336
1337static void dl_del_urb(URB_T * urb)
1338{
1339 if (urb->transfer_flags & USB_ASYNC_UNLINK)
1340 {
1341 urb->status = USB_ERR_CONNRESET;
1342 if (urb->complete)
1343 urb->complete(urb);
1344 }
1345 else
1346 {
1347 urb->status = USB_ERR_NOENT;
1348 }
1349}
1350
1351
1352/*-------------------------------------------------------------------------*/
1353
1354/* replies to the request have to be on a FIFO basis so
1355 * we reverse the reversed done-list */
1356
1357static TD_T *dl_reverse_done_list()
1358{
1359 uint32_t td_list_hc;
1360 TD_T *td_rev = NULL;
1361 TD_T *td_list = NULL;
1362 URB_PRIV_T *urb_priv;
1363
1364 td_list_hc = (uint32_t)(ohci.hcca->done_head) & 0xfffffff0; /* mask out WD bit also */
1365 ohci.hcca->done_head = 0;
1366
1367 while (td_list_hc)
1368 {
1369 td_list = (TD_T *)td_list_hc;
1370 USB_info("TD done - 0x%08x, DEV:[%d], ED:[%d] PSW:[%x]\n", (uint32_t)td_list, td_list->urb->dev->devnum, (td_list->ed->hwINFO>>7)&0xf, td_list->hwPSW[0] >> 12);
1371
1372#ifdef USB_VERBOSE_DEBUG
1373 if (td_list->ed->hwHeadP & 0x1)
1374 USB_error("!!Halted - DEV:[%d], ED:[%d] PSW0:[%x] PSW1:[%x]\n",
1375 td_list->urb->dev->devnum, (td_list->ed->hwINFO>>7)&0xf,
1376 (td_list->hwPSW[0] >> 12) & 0xf, (td_list->hwPSW[0] >> 28) & 0xf);
1377#endif
1378
1379 if (TD_CC_GET((uint32_t)td_list->hwINFO))
1380 {
1381 urb_priv = &(td_list->urb->urb_hcpriv);
1382
1383 if (td_list->ed->type == PIPE_ISOCHRONOUS)
1384 {
1385 if ((td_list->hwINFO & 0xE0000000) == 0x80000000)
1386 {
1387 USB_error("!"); //("I N/A: %x\n", td_list->hwINFO);
1388 td_list->ed->last_iso += OHCI_ISO_DELAY;
1389 }
1390 else
1391 USB_error("ISO! - CC:0x%x, PSW:0x%x 0x%x\n", td_list->hwINFO >> 28, td_list->hwPSW[0], td_list->hwPSW[1]);
1392 }
1393 else
1394 {
1395 USB_error("CC Error!! - DEV[%d] ED[%d] - ", td_list->urb->dev->devnum, (td_list->ed->hwINFO >> 7) & 0xf);
1396 TD_CompletionCode(TD_CC_GET((uint32_t)(td_list->hwINFO)));
1397 }
1398
1399 if (td_list->ed->hwHeadP & 0x1)
1400 {
1401 if (urb_priv && ((td_list->index + 1) < urb_priv->length))
1402 {
1403 td_list->ed->hwHeadP = (urb_priv->td[urb_priv->length - 1]->hwNextTD & 0xfffffff0) |
1404 (td_list->ed->hwHeadP & 0x2);
1405 urb_priv->td_cnt += urb_priv->length - td_list->index - 1;
1406 }
1407 else
1408 td_list->ed->hwHeadP &= 0xfffffff2;
1409 }
1410 }
1411
1412 td_list->next_dl_td = td_rev;
1413 td_rev = td_list;
1414 td_list_hc = (uint32_t)(td_list->hwNextTD) & 0xfffffff0;
1415 } /* end of while */
1416 return td_list;
1417}
1418
1419/*-------------------------------------------------------------------------*/
1420
1421/* there are some pending requests to remove
1422 * - some of the eds (if ed->state & ED_DEL (set by sohci_free_dev)
1423 * - some URBs/TDs if urb_priv->state == URB_DEL */
1424
1425static void dl_del_list(uint32_t frame)
1426{
1427 ED_T *ed;
1428 uint32_t edINFO;
1429 uint32_t tdINFO;
1430 TD_T *td=NULL, *td_next=NULL, *tdHeadP=NULL, *tdTailP;
1431 uint32_t *td_p;
1432 int ctrl=0, bulk=0;
1433
1434 for (ed = ohci.ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list)
1435 {
1436 tdTailP = (TD_T *)((uint32_t)(ed->hwTailP) & 0xfffffff0);
1437 tdHeadP = (TD_T *)((uint32_t)(ed->hwHeadP) & 0xfffffff0);
1438 edINFO = (uint32_t)ed->hwINFO;
1439 td_p = &ed->hwHeadP;
1440
1441 for (td = tdHeadP; td != tdTailP; td = td_next)
1442 {
1443 URB_T * urb = td->urb;
1444 URB_PRIV_T * urb_priv = &(td->urb->urb_hcpriv);
1445
1446 td_next = (TD_T *)((uint32_t)(td->hwNextTD) & 0xfffffff0);
1447 if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL))
1448 {
1449 tdINFO = (uint32_t)td->hwINFO;
1450 if (TD_CC_GET (tdINFO) < 0xE)
1451 dl_transfer_length(td);
1452 *td_p = td->hwNextTD | (*td_p & 0x3);
1453
1454 /* URB is done; clean up */
1455 if (++(urb_priv->td_cnt) == urb_priv->length)
1456 dl_del_urb (urb);
1457 }
1458 else
1459 {
1460 td_p = &td->hwNextTD;
1461 }
1462 }
1463
1464 if (ed->state & ED_DEL)
1465 {
1466 /* set by sohci_free_dev */
1467 OHCI_DEVICE_T * dev = usb_to_ohci (ohci.dev[edINFO & 0x7F]);
1468 ohci_free_td(tdTailP); /* free dummy td */
1469 ed->hwINFO = OHCI_ED_SKIP;
1470 ed->state = ED_NEW;
1471
1472 dev->ed_cnt--; /* This may make task blocked in sohci_free_dev() to be unblocked */
1473 }
1474 else
1475 {
1476 ed->state &= ~ED_URB_DEL;
1477 tdHeadP = (TD_T *)((uint32_t)(ed->hwHeadP) & 0xfffffff0);
1478 if (tdHeadP == tdTailP)
1479 {
1480 if (ed->state == ED_OPER)
1481 ep_unlink(ed);
1482 ohci_free_td(tdTailP);
1483 ed->hwINFO = OHCI_ED_SKIP;
1484 ed->state = ED_NEW;
1485 --(usb_to_ohci (ohci.dev[edINFO & 0x7F]))->ed_cnt;
1486 }
1487 else
1488 ed->hwINFO &= ~OHCI_ED_SKIP;
1489 }
1490
1491 switch (ed->type)
1492 {
1493 case PIPE_CONTROL:
1494 ctrl = 1;
1495 break;
1496 case PIPE_BULK:
1497 bulk = 1;
1498 break;
1499 }
1500 }
1501
1502 /* maybe reenable control and bulk lists */
1503 if (!ohci.disabled)
1504 {
1505 if (ctrl) /* reset control list */
1506 USBH->HcControlCurrentED = 0;
1507 if (bulk) /* reset bulk list */
1508 USBH->HcBulkCurrentED = 0;
1509 if (!ohci.ed_rm_list[!frame])
1510 {
1511 if (ohci.ed_controltail)
1512 ohci.hc_control |= OHCI_CTRL_CLE;
1513 if (ohci.ed_bulktail)
1514 ohci.hc_control |= OHCI_CTRL_BLE;
1515 USBH->HcControl = ohci.hc_control;
1516 }
1517 }
1518
1519 ohci.ed_rm_list[frame] = NULL;
1520}
1521
1522
1523/*-------------------------------------------------------------------------*/
1524
1525/* td done list */
1526
1527static void dl_done_list(TD_T *td_list)
1528{
1529 TD_T *td_list_next = NULL;
1530 ED_T *ed;
1531 int cc = 0;
1532 URB_T *urb;
1533 URB_PRIV_T *urb_priv;
1534 uint32_t tdINFO, edHeadP, edTailP;
1535
1536 while (td_list)
1537 {
1538 td_list_next = td_list->next_dl_td;
1539
1540 urb = td_list->urb;
1541 urb_priv = &urb->urb_hcpriv;
1542 tdINFO = (uint32_t)(td_list->hwINFO);
1543
1544 ed = td_list->ed;
1545
1546 dl_transfer_length(td_list);
1547
1548 /* error code of transfer */
1549 cc = TD_CC_GET (tdINFO);
1550 if (cc == TD_CC_STALL)
1551 usb_endpoint_halt(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
1552
1553 if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN))
1554 cc = TD_CC_NOERROR;
1555
1556 if (++(urb_priv->td_cnt) == urb_priv->length)
1557 {
1558 if ((ed->state & (ED_OPER | ED_UNLINK)) && (urb_priv->state != URB_DEL))
1559 {
1560 urb->status = cc_to_error[cc];
1561 sohci_return_urb(urb);
1562 }
1563 else
1564 {
1565 dl_del_urb(urb);
1566 }
1567 }
1568 if (ed->state != ED_NEW)
1569 {
1570 edHeadP = (uint32_t)(ed->hwHeadP) & 0xfffffff0;
1571 edTailP = (uint32_t)(ed->hwTailP);
1572
1573 /* unlink eds if they are not busy */
1574 if ((edHeadP == edTailP) && (ed->state == ED_OPER))
1575 {
1576 ep_unlink(ed);
1577 }
1578 }
1579 td_list = td_list_next;
1580 }
1581}
1582
1583
1584/*-------------------------------------------------------------------------*
1585 * Virtual Root Hub
1586 *-------------------------------------------------------------------------*/
1587
1588/* Device descriptor */
1589static uint8_t root_hub_dev_des[] =
1590{
1591 0x12, /* uint8_t bLength; */
1592 0x01, /* uint8_t bDescriptorType; Device */
1593 0x10, /* uint16_t bcdUSB; v1.1 */
1594 0x01,
1595 0x09, /* uint8_t bDeviceClass; HUB_CLASSCODE */
1596 0x00, /* uint8_t bDeviceSubClass; */
1597 0x00, /* uint8_t bDeviceProtocol; */
1598 0x08, /* uint8_t bMaxPacketSize0; 8 Bytes */
1599 0x00, /* uint16_t idVendor; */
1600 0x00,
1601 0x00, /* uint16_t idProduct; */
1602 0x00,
1603 0x00, /* uint16_t bcdDevice; */
1604 0x00,
1605 0x00, /* uint8_t iManufacturer; */
1606 0x02, /* uint8_t iProduct; */
1607 0x01, /* uint8_t iSerialNumber; */
1608 0x01 /* uint8_t bNumConfigurations; */
1609};
1610
1611
1612/* Configuration descriptor */
1613static uint8_t root_hub_config_des[] =
1614{
1615 0x09, /* uint8_t bLength; */
1616 0x02, /* uint8_t bDescriptorType; Configuration */
1617 0x19, /* uint16_t wTotalLength; */
1618 0x00,
1619 0x01, /* uint8_t bNumInterfaces; */
1620 0x01, /* uint8_t bConfigurationValue; */
1621 0x00, /* uint8_t iConfiguration; */
1622 0x40, /* uint8_t bmAttributes;
1623 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
1624 0x00, /* uint8_t MaxPower; */
1625
1626 /* interface */
1627 0x09, /* uint8_t if_bLength; */
1628 0x04, /* uint8_t if_bDescriptorType; Interface */
1629 0x00, /* uint8_t if_bInterfaceNumber; */
1630 0x00, /* uint8_t if_bAlternateSetting; */
1631 0x01, /* uint8_t if_bNumEndpoints; */
1632 0x09, /* uint8_t if_bInterfaceClass; HUB_CLASSCODE */
1633 0x00, /* uint8_t if_bInterfaceSubClass; */
1634 0x00, /* uint8_t if_bInterfaceProtocol; */
1635 0x00, /* uint8_t if_iInterface; */
1636
1637 /* endpoint */
1638 0x07, /* uint8_t ep_bLength; */
1639 0x05, /* uint8_t ep_bDescriptorType; Endpoint */
1640 0x81, /* uint8_t ep_bEndpointAddress; IN Endpoint 1 */
1641 0x03, /* uint8_t ep_bmAttributes; Interrupt */
1642 0x02, /* uint16_t ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
1643 0x00,
1644 0xff /* uint8_t ep_bInterval; 255 ms */
1645};
1646
1647/* Hub class-specific descriptor is constructed dynamically */
1648
1649
1650/*-------------------------------------------------------------------------*/
1651
1652/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */
1653
1654static int rh_send_irq(void *rh_data, int rh_len)
1655{
1656 int num_ports;
1657 int i;
1658 int ret;
1659 int len;
1660 uint8_t data[8];
1661
1662 num_ports = USBH->HcRhDescriptorA & RH_A_NDP;
1663
1664 /* YCHuang: prepare the 'Hub change detected' bit, refer to USB 1.1 Spec. p.260 */
1665 *(uint8_t *)data = (USBH->HcRhStatus & (RH_HS_LPSC | RH_HS_OCIC)) ? 1: 0;
1666 ret = *(uint8_t *)data;
1667
1668 /* YCHuang: prepare the 'Port change detected' bits, refer to USB 1.1 Spec. p.260 */
1669 for ( i = 0; i < num_ports; i++)
1670 {
1671 *(uint8_t *)(data + (i + 1) / 8) |= ((USBH->HcRhPortStatus[i] &
1672 (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC))
1673 ? 1: 0) << ((i + 1) % 8);
1674 ret += *(uint8_t *)(data + (i + 1) / 8);
1675 }
1676 len = i/8 + 1;
1677
1678 if (ret > 0)
1679 {
1680 memcpy(rh_data, data, min(len, min (rh_len, sizeof(data))));
1681 return len;
1682 }
1683 return 0;
1684}
1685
1686/*-------------------------------------------------------------------------*/
1687static URB_T *_OHCI_RH_IRQ;
1688
1689/* Virtual Root Hub INTs are polled by this timer every "interval" ms */
1690
1691void ohci_int_timer_do(int ptr)
1692{
1693 int len;
1694 URB_T *urb = _OHCI_RH_IRQ;
1695
1696 if (ohci.rh.send)
1697 {
1698 len = rh_send_irq(urb->transfer_buffer, urb->transfer_buffer_length);
1699 if (len > 0)
1700 {
1701 urb->actual_length = len;
1702#ifdef USB_VERBOSE_DEBUG
1703 urb_print(urb, "RET-t(rh)", usb_pipeout (urb->pipe));
1704#endif
1705 if (urb->complete)
1706 urb->complete(urb); /* call the hub_irq() in hub.c */
1707 }
1708 }
1709}
1710
1711
1712
1713/* for returning string descriptors in UTF-16LE */
1714static int ascii2utf(char *ascii, uint8_t *utf, int utfmax)
1715{
1716 int retval;
1717
1718 for (retval = 0; *ascii && utfmax > 1; utfmax -= 2, retval += 2)
1719 {
1720 *utf++ = *ascii++ & 0x7f;
1721 *utf++ = 0;
1722 }
1723 return retval;
1724}
1725
1726
1727
1728/*
1729 * root_hub_string is used by each host controller's root hub code,
1730 * so that they're identified consistently throughout the system.
1731 */
1732static int usbh_root_hub_string(int id, int serial, char *type, uint8_t *data, int len)
1733{
1734 char buf[30];
1735
1736 /* language ids */
1737 if (id == 0)
1738 {
1739 *data++ = 4;
1740 *data++ = 3; /* 4 bytes data */
1741 *data++ = 0;
1742 *data++ = 0; /* some language id */
1743 return 4;
1744 // serial number
1745 }
1746 else if (id == 1)
1747 {
1748 sprintf (buf, "%x", serial);
1749 /* product description */
1750 }
1751 else if (id == 2)
1752 {
1753 sprintf (buf, "USB %s Root Hub", type);
1754 /* id 3 == vendor description */
1755 /* unsupported IDs --> "stall" */
1756 }
1757 else
1758 return 0;
1759
1760 data [0] = 2 + ascii2utf(buf, data + 2, len - 2);
1761 data [1] = 3;
1762 return data [0];
1763}
1764
1765
1766/*-------------------------------------------------------------------------*/
1767
1768#define RH_OK(x) len = (x); break
1769#define WR_RH_STAT(x) (USBH->HcRhStatus = (x))
1770#define WR_RH_PORTSTAT(x) (USBH->HcRhPortStatus[wIndex-1] = (x))
1771#define RD_RH_STAT (USBH->HcRhStatus)
1772#define RD_RH_PORTSTAT (USBH->HcRhPortStatus[wIndex-1])
1773
1774/* request to virtual root hub */
1775
1776static int rh_submit_urb(URB_T *urb)
1777{
1778 uint32_t pipe;
1779 DEV_REQ_T *cmd;
1780 void *data;
1781 int leni;
1782 int len = 0;
1783 int status = TD_CC_NOERROR;
1784 uint32_t datab[4];
1785 uint8_t *data_buf;
1786 uint16_t bmRType_bReq;
1787 uint16_t wValue;
1788 uint16_t wIndex;
1789 uint16_t wLength;
1790
1791 pipe = urb->pipe;
1792 cmd = (DEV_REQ_T *) urb->setup_packet;
1793 data = urb->transfer_buffer;
1794 leni = urb->transfer_buffer_length;
1795 data_buf = (uint8_t *) datab;
1796
1797 if (usb_pipeint(pipe)) /* ¦pªG³oÓ URB ¬OÄÝ©ó interrupt pipe */
1798 {
1799 ohci.rh.urb = urb;
1800 ohci.rh.send = 1;
1801 ohci.rh.interval = urb->interval;
1802 _OHCI_RH_IRQ = urb;
1803
1804 ohci_int_timer_do(0);
1805
1806 urb->status = 0;
1807 return 0;
1808 }
1809
1810 bmRType_bReq = (cmd->requesttype << 8) | cmd->request;
1811 wValue = cmd->value;
1812 wIndex = cmd->index;
1813 wLength = cmd->length;
1814 USB_info("rh_submit_urb, req = 0x%x len=%d\n", bmRType_bReq, wLength);
1815
1816#ifdef USB_VERBOSE_DEBUG /* YCHuang: added for debug */
1817 USB_debug("Command - ");
1818 switch (bmRType_bReq & 0x80FF)
1819 {
1820 case RH_GET_STATUS:
1821 USB_debug("GET_STATUS\n");
1822 break;
1823
1824 case RH_CLEAR_FEATURE:
1825 USB_debug("CLEAR_FEATURE\n");
1826 break;
1827
1828 case RH_SET_FEATURE:
1829 USB_debug("SET_FEATURE\n");
1830 break;
1831
1832 case RH_SET_ADDRESS:
1833 USB_debug("SET_ADDRESS\n");
1834 break;
1835
1836 case RH_GET_DESCRIPTOR:
1837 USB_debug("GET_DESCRIPTOR\n");
1838 break;
1839
1840 case RH_SET_DESCRIPTOR:
1841 USB_debug("SET_DESCRIPTOR\n");
1842 break;
1843
1844 case RH_GET_CONFIGURATION:
1845 USB_debug("GET_CONFIGURATION\n");
1846 break;
1847
1848 case RH_SET_CONFIGURATION:
1849 USB_debug("RH_SET_CONFIGURATION\n");
1850 break;
1851
1852 case RH_GET_STATE:
1853 USB_debug("GET_STATE\n");
1854 break;
1855
1856 case RH_GET_INTERFACE:
1857 USB_debug("GET_INTERFACE\n");
1858 break;
1859
1860 case RH_SET_INTERFACE:
1861 USB_debug("SET_INTERFACE\n");
1862 break;
1863
1864 case RH_SYNC_FRAME:
1865 USB_debug("SYNC_FRAME\n");
1866 break;
1867
1868 case RH_SET_EP:
1869 USB_debug("SET_EP\n");
1870 break;
1871 }
1872#endif
1873
1874 switch (bmRType_bReq)
1875 {
1876 /* Request Destination:
1877 without flags: Device,
1878 RH_INTERFACE: interface,
1879 RH_ENDPOINT: endpoint,
1880 RH_CLASS means HUB here,
1881 RH_OTHER | RH_CLASS almost ever means HUB_PORT here
1882 */
1883
1884 case RH_GET_STATUS:
1885 *(uint16_t *) data_buf = USB_SWAP16(1);
1886 RH_OK(2);
1887
1888 case RH_GET_STATUS | RH_INTERFACE:
1889 *(uint16_t *) data_buf = 0;
1890 RH_OK(2);
1891
1892 case RH_GET_STATUS | RH_ENDPOINT:
1893 *(uint16_t *) data_buf = 0;
1894 RH_OK(2);
1895
1896 case RH_GET_STATUS | RH_CLASS:
1897 /* BIGBIG */
1898 data_buf[0] = RD_RH_STAT & 0xFF;
1899 data_buf[1] = (RD_RH_STAT >> 8) & 0xFF;
1900 data_buf[2] = (RD_RH_STAT >> 16) & 0xFF;
1901 data_buf[3] = (RD_RH_STAT >> 24) & 0xFF;
1902 *(uint32_t *) data_buf = RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE);
1903 RH_OK(4);
1904
1905 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
1906 *(uint32_t *) data_buf = RD_RH_PORTSTAT;
1907 RH_OK(4);
1908
1909 case RH_CLEAR_FEATURE | RH_ENDPOINT:
1910 switch (wValue)
1911 {
1912 case (RH_ENDPOINT_STALL):
1913 RH_OK(0);
1914 }
1915 break;
1916
1917 case RH_CLEAR_FEATURE | RH_CLASS:
1918 switch (wValue)
1919 {
1920 case RH_C_HUB_LOCAL_POWER:
1921 RH_OK(0);
1922 case (RH_C_HUB_OVER_CURRENT):
1923 WR_RH_STAT(RH_HS_OCIC);
1924 RH_OK(0);
1925 }
1926 break;
1927
1928 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
1929 switch (wValue)
1930 {
1931 case (RH_PORT_ENABLE):
1932 WR_RH_PORTSTAT (RH_PS_CCS );
1933 RH_OK(0);
1934 case (RH_PORT_SUSPEND):
1935 WR_RH_PORTSTAT (RH_PS_POCI);
1936 RH_OK(0);
1937 case (RH_PORT_POWER):
1938 WR_RH_PORTSTAT (RH_PS_LSDA);
1939 RH_OK(0);
1940 case (RH_C_PORT_CONNECTION):
1941 WR_RH_PORTSTAT (RH_PS_CSC );
1942 RH_OK(0);
1943 case (RH_C_PORT_ENABLE):
1944 WR_RH_PORTSTAT (RH_PS_PESC);
1945 RH_OK(0);
1946 case (RH_C_PORT_SUSPEND):
1947 WR_RH_PORTSTAT (RH_PS_PSSC);
1948 RH_OK(0);
1949 case (RH_C_PORT_OVER_CURRENT):
1950 WR_RH_PORTSTAT (RH_PS_OCIC);
1951 RH_OK(0);
1952 case (RH_C_PORT_RESET):
1953 WR_RH_PORTSTAT (RH_PS_PRSC);
1954 RH_OK(0);
1955 }
1956 break;
1957
1958 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
1959 switch (wValue)
1960 {
1961 case (RH_PORT_SUSPEND):
1962 WR_RH_PORTSTAT (RH_PS_PSS );
1963 RH_OK(0);
1964
1965 case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
1966 if (RD_RH_PORTSTAT & RH_PS_CCS)
1967 WR_RH_PORTSTAT (RH_PS_PRS);
1968 RH_OK(0);
1969
1970 case (RH_PORT_POWER):
1971 WR_RH_PORTSTAT (RH_PS_PPS );
1972 RH_OK(0);
1973
1974 case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
1975 if (RD_RH_PORTSTAT & RH_PS_CCS)
1976 WR_RH_PORTSTAT (RH_PS_PES );
1977 RH_OK(0);
1978 }
1979 break;
1980
1981 case RH_SET_ADDRESS:
1982 ohci.rh.devnum = wValue;
1983 RH_OK(0);
1984
1985 case RH_GET_DESCRIPTOR:
1986 switch ((wValue & 0xff00) >> 8)
1987 {
1988 case (0x01): /* device descriptor */
1989 len = min (leni, min (sizeof (root_hub_dev_des), wLength));
1990 data_buf = root_hub_dev_des;
1991 RH_OK(len);
1992
1993 case (0x02): /* configuration descriptor */
1994 len = min (leni, min (sizeof (root_hub_config_des), wLength));
1995 data_buf = root_hub_config_des;
1996 RH_OK(len);
1997
1998 case (0x03): /* string descriptors */
1999 len = usbh_root_hub_string(wValue & 0xff, 0x0, "OHCI", data, wLength);
2000 if (len > 0)
2001 {
2002 data_buf = data;
2003 RH_OK(min (leni, len));
2004 }
2005 // else fallthrough
2006 default:
2007 status = TD_CC_STALL;
2008 }
2009 break;
2010
2011 case RH_GET_DESCRIPTOR | RH_CLASS:
2012 {
2013 uint32_t temp = USBH->HcRhDescriptorA;
2014
2015 data_buf [0] = 9; // min length;
2016 data_buf [1] = 0x29;
2017 data_buf [2] = temp & RH_A_NDP;
2018 data_buf [3] = 0;
2019 if (temp & RH_A_PSM) /* per-port power switching? */
2020 data_buf [3] |= 0x1;
2021 if (temp & RH_A_NOCP) /* no overcurrent reporting? */
2022 data_buf [3] |= 0x10;
2023 else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
2024 data_buf [3] |= 0x8;
2025
2026 datab [1] = 0;
2027 data_buf [5] = (temp & RH_A_POTPGT) >> 24;
2028 temp = USBH->HcRhDescriptorB;
2029 data_buf [7] = temp & RH_B_DR;
2030 if (data_buf [2] < 7)
2031 {
2032 data_buf [8] = 0xff;
2033 }
2034 else
2035 {
2036 data_buf [0] += 2;
2037 data_buf [8] = (temp & RH_B_DR) >> 8;
2038 data_buf [10] = data_buf [9] = 0xff;
2039 }
2040 len = min (leni, min (data_buf [0], wLength));
2041 RH_OK(len);
2042 }
2043
2044 case RH_GET_CONFIGURATION:
2045 *(uint8_t *) data_buf = 0x01;
2046 RH_OK(1);
2047
2048 case RH_SET_CONFIGURATION:
2049 WR_RH_STAT(0x10000); /* set global port power */
2050 RH_OK(0);
2051
2052 default:
2053 //USB_error("Error! - unsupported root hub command\n");
2054 status = TD_CC_STALL;
2055 }
2056
2057 len = min(len, leni);
2058 if (data != data_buf)
2059 memcpy(data, data_buf, len);
2060 urb->actual_length = len;
2061 urb->status = cc_to_error[status];
2062
2063 urb->dev = NULL;
2064 if (urb->complete)
2065 urb->complete (urb);
2066
2067 return 0;
2068}
2069
2070/*-------------------------------------------------------------------------*/
2071
2072static int rh_unlink_urb(URB_T *urb)
2073{
2074 if (ohci.rh.urb == urb)
2075 {
2076 ohci.rh.send = 0;
2077 ohci.rh.urb = NULL;
2078
2079 urb->dev = NULL;
2080 if (urb->transfer_flags & USB_ASYNC_UNLINK)
2081 {
2082 urb->status = USB_ERR_CONNRESET;
2083 if (urb->complete)
2084 urb->complete (urb);
2085 }
2086 else
2087 urb->status = USB_ERR_NOENT;
2088 }
2089 return 0;
2090}
2091
2092/*-------------------------------------------------------------------------*
2093 * HC functions
2094 *-------------------------------------------------------------------------*/
2095
2096/* reset the HC and BUS */
2097
2098static int ohci_reset()
2099{
2100 int timeout = 30;
2101
2102 /* Disable HC interrupts */
2103 USBH->HcInterruptDisable = OHCI_INTR_MIE;
2104
2105 /* Reset USB (needed by some controllers) */
2106 USBH->HcControl = 0;
2107
2108 /* HC Reset requires max 10 ms delay */
2109 USBH->HcCommandStatus = OHCI_HCR;
2110
2111 while ((USBH->HcCommandStatus & OHCI_HCR) != 0)
2112 {
2113 if (--timeout == 0)
2114 {
2115 USB_error("Error! - USB HC reset timed out!\n");
2116 return -1;
2117 }
2118 usbh_mdelay(10);
2119 }
2120 USBH->HcControl = (USBH->HcControl & 0xffffff3f) | OHCI_USB_RESET;
2121
2122 return 0;
2123}
2124
2125
2126/*-------------------------------------------------------------------------*/
2127void USBH_IRQHandler(void)
2128{
2129 int ints;
2130
2131 _is_in_interrupt = 1;
2132
2133 ints = USBH->HcInterruptStatus;
2134
2135 //printf("[irq-0x%x] 0x%x, 0x%x\n", ints, USBH->HcRhPortStatus[0], USBH->HcRhPortStatus[1]);
2136
2137 if ((ohci.hcca->done_head != 0) && !((uint32_t)(ohci.hcca->done_head) & 0x01))
2138 {
2139 ints = OHCI_INTR_WDH;
2140 }
2141
2142 if (ints & OHCI_INTR_UE)
2143 {
2144 ohci.disabled++;
2145 USB_error("Error! - OHCI Unrecoverable Error, controller disabled\n");
2146 /* e.g. due to PCI Master/Target Abort */
2147 /*
2148 * FIXME: be optimistic, hope that bug won't repeat often.
2149 * Make some non-interrupt context restart the controller.
2150 * Count and limit the retries though; either hardware or
2151 * software errors can go forever...
2152 */
2153 ohci_reset();
2154 }
2155
2156 if (ints & OHCI_INTR_OC)
2157 {
2158 USB_debug("Ownership change!!\n");
2159 }
2160
2161 if (ints & OHCI_INTR_WDH)
2162 {
2163 dl_done_list(dl_reverse_done_list());
2164 USBH->HcInterruptStatus = OHCI_INTR_WDH;
2165 }
2166
2167 if (ints & OHCI_INTR_SO)
2168 {
2169 //*(uint32_t *)0x600000 = 0x1;
2170 //while (1);
2171 //USB_error("Error! - USB Schedule overrun, count:%d\n", (USBH->HcCommandStatus >> 16) & 0x3);
2172 USBH->HcInterruptDisable = OHCI_INTR_SO;
2173 USBH->HcInterruptStatus = OHCI_INTR_SO;
2174 }
2175
2176 if (ints & OHCI_INTR_SF)
2177 {
2178 uint32_t frame = ohci.hcca->frame_no & 1;
2179
2180 USBH->HcInterruptDisable = OHCI_INTR_SF;
2181 if (ohci.ed_rm_list[!frame] != NULL)
2182 {
2183 dl_del_list(!frame);
2184 }
2185 if (ohci.ed_rm_list[frame] != NULL)
2186 USBH->HcInterruptEnable = OHCI_INTR_SF;
2187 }
2188
2189 if (ints & OHCI_INTR_RHSC)
2190 {
2191 USBH->HcInterruptDisable = OHCI_INTR_RHSC;
2192 USBH->HcInterruptStatus = OHCI_INTR_RHSC;
2193 }
2194
2195 if (ints & OHCI_INTR_RD)
2196 {
2197 USBH->HcInterruptDisable = OHCI_INTR_RD;
2198 USBH->HcInterruptStatus = OHCI_INTR_RD;
2199 }
2200
2201 ints &= ~OHCI_INTR_WDH;
2202 USBH->HcInterruptEnable = OHCI_INTR_MIE;
2203
2204 /* FIXME: check URB timeouts */
2205 _is_in_interrupt = 0;
2206}
2207
2208
2209/*-------------------------------------------------------------------------*/
2210
2211/* Start an OHCI controller, set the BUS operational
2212 * enable interrupts
2213 * connect the virtual root hub */
2214
2215static int hc_start ()
2216{
2217 uint32_t mask;
2218 uint32_t fminterval;
2219 int i;
2220 USB_DEV_T *usb_dev;
2221
2222 ohci.disabled = 1;
2223
2224 /* empty the interrupt branches */
2225 for (i = 0; i < NUM_INTS; i++)
2226 ohci.ohci_int_load[i] = 0;
2227 for (i = 0; i < NUM_INTS; i++)
2228 ohci.hcca->int_table[i] = 0;
2229
2230 /* no EDs to remove */
2231 ohci.ed_rm_list [0] = NULL;
2232 ohci.ed_rm_list [1] = NULL;
2233
2234 /* empty control and bulk lists */
2235 ohci.ed_isotail = NULL;
2236 ohci.ed_controltail = NULL;
2237 ohci.ed_bulktail = NULL;
2238
2239 /* Tell the controller where the control and bulk lists are
2240 * The lists are empty now. */
2241 USBH->HcControlHeadED = 0; /* control ED list head */
2242 USBH->HcBulkHeadED = 0; /* bulk ED list head */
2243
2244 USBH->HcHCCA = (uint32_t)ohci.hcca; /* a reset clears this */
2245
2246 fminterval = 0x2edf; /* 11,999 */
2247
2248 /* periodic start 90% of frame interval */
2249 USBH->HcPeriodicStart = (fminterval * 9) / 10;
2250
2251 /* set FSLargestDataPacket, 10,104 for 0x2edf frame interval */
2252 fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
2253 USBH->HcFmInterval = fminterval;
2254
2255 USBH->HcLSThreshold = 0x628;
2256
2257 /* start controller operations */
2258 ohci.hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
2259 ohci.disabled = 0;
2260 USBH->HcControl = ohci.hc_control;
2261
2262 /* Choose the interrupts we care about now, others later on demand */
2263 mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
2264 USBH->HcInterruptEnable = mask;
2265 USBH->HcInterruptStatus = mask;
2266
2267 /* global port power mode */
2268 USBH->HcRhDescriptorA = (USBH->HcRhDescriptorA | RH_A_NPS) & ~RH_A_PSM;
2269 USBH->HcRhStatus = RH_HS_LPSC;
2270
2271 /* POTPGT delay is bits 24-31, in 2 ms units. */
2272 usbh_mdelay((USBH->HcRhDescriptorA >> 23) & 0x1fe);
2273
2274 /* connect the virtual root hub */
2275 ohci.rh.devnum = 0;
2276 usb_dev = usbh_alloc_device(NULL, ohci.bus);
2277 if (!usb_dev)
2278 {
2279 ohci.disabled = 1;
2280 return USB_ERR_NOMEM;
2281 }
2282
2283 ohci.bus->root_hub = usb_dev;
2284 usbh_connect_device(usb_dev);
2285 if (usbh_settle_new_device(usb_dev) != 0)
2286 {
2287 usbh_free_device(usb_dev);
2288 ohci.disabled = 1;
2289 return USB_ERR_NODEV;
2290 }
2291 return 0;
2292}
2293
2294
2295#if 0
2296static void hc_restart()
2297{
2298 int temp;
2299 int i;
2300
2301 ohci.disabled = 1;
2302 if (ohci.bus->root_hub)
2303 usbh_disconnect_device(&ohci.bus->root_hub);
2304
2305 /* empty the interrupt branches */
2306 for (i = 0; i < NUM_INTS; i++)
2307 ohci.ohci_int_load[i] = 0;
2308 for (i = 0; i < NUM_INTS; i++)
2309 ohci.hcca->int_table[i] = 0;
2310
2311 /* no EDs to remove */
2312 ohci.ed_rm_list [0] = NULL;
2313 ohci.ed_rm_list [1] = NULL;
2314
2315 /* empty control and bulk lists */
2316 ohci.ed_isotail = NULL;
2317 ohci.ed_controltail = NULL;
2318 ohci.ed_bulktail = NULL;
2319
2320 if ((temp = ohci_reset()) < 0 || (temp = hc_start ()) < 0)
2321 USB_error("Error! - can't restart usb-%s, %d\n", "ohci->ohci_dev->slot_name", temp);
2322 else
2323 USB_error("Error! - restart usb-%s completed\n", "ohci->ohci_dev->slot_name");
2324}
2325#endif
2326
2327
2328/*-------------------------------------------------------------------------*/
2329
2330int usbh_init_ohci()
2331{
2332 int i;
2333
2334 if (sizeof(ED_T) != 32)
2335 {
2336 USB_error("Wrong ED_T size!!!\n");
2337 return -1;
2338 }
2339
2340 if (sizeof(TD_T) != 64)
2341 {
2342 USB_error("Wrong TD_T size!!!\n");
2343 return -1;
2344 }
2345
2346 memset((char *)&ohci, 0, sizeof(OHCI_T));
2347 ohci.hcca = (OHCI_HCCA_T *)g_ohci_hcca;
2348 memset((char *)ohci.hcca, 0, 256);
2349
2350 for (i = 0; i < DEV_MAX_NUM; i++)
2351 ohci_dev_alloc_mark[i] = 0;
2352
2353 ohci.disabled = 1;
2354
2355 if (ohci_reset() < 0)
2356 return USB_ERR_NODEV;
2357
2358 ohci.hc_control = OHCI_USB_RESET;
2359 USBH->HcControl = ohci.hc_control;
2360
2361 /*- HCD must wait 10ms for HC reset complete -*/
2362 usbh_mdelay(100);
2363
2364 /*
2365 * OHCI bus ...
2366 */
2367 g_ohci_bus.op = &sohci_device_operations;
2368 g_ohci_bus.root_hub = NULL;
2369 g_ohci_bus.hcpriv = &ohci;
2370 ohci.bus = &g_ohci_bus;
2371
2372 if (hc_start() < 0)
2373 {
2374 USB_error("Error! - can't start OHCI!\n");
2375 return USB_ERR_BUSY;
2376 }
2377 return 0;
2378}
2379
2381
__attribute__
void *__dso_handle __attribute__((weak))
Definition: _syscalls.c:35
NUC472_442.h
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
USBH
#define USBH
Definition: NUC472_442.h:28818
CC_ERR_BITSTUFF
#define CC_ERR_BITSTUFF
Definition: usbh_err_code.h:36
CC_ERR_NORESPONSE
#define CC_ERR_NORESPONSE
Definition: usbh_err_code.h:39
DEV_MAX_NUM
#define DEV_MAX_NUM
Definition: usbh_config.h:48
USB_ERR_XDEV
#define USB_ERR_XDEV
Definition: usbh_err_code.h:22
USB_ERR_TIMEOUT
#define USB_ERR_TIMEOUT
Definition: usbh_err_code.h:30
USB_OK
#define USB_OK
Definition: usbh_err_code.h:16
CC_ERR_DATAUNDERRUN
#define CC_ERR_DATAUNDERRUN
Definition: usbh_err_code.h:43
USB_ERR_NODEV
#define USB_ERR_NODEV
Definition: usbh_err_code.h:23
CC_ERR_DATA_TOGGLE
#define CC_ERR_DATA_TOGGLE
Definition: usbh_err_code.h:37
MAX_TD_PER_OHCI_URB
#define MAX_TD_PER_OHCI_URB
Definition: usbh_config.h:55
USB_ERR_NOENT
#define USB_ERR_NOENT
Definition: usbh_err_code.h:17
EWOULDBLOCK
#define EWOULDBLOCK
Definition: usbh_err_code.h:26
CC_ERR_CRC
#define CC_ERR_CRC
Definition: usbh_err_code.h:35
CC_ERR_NOT_DEFINED
#define CC_ERR_NOT_DEFINED
Definition: usbh_err_code.h:44
CC_ERR_STALL
#define CC_ERR_STALL
Definition: usbh_err_code.h:38
USB_ERR_INPROGRESS
#define USB_ERR_INPROGRESS
Definition: usbh_err_code.h:31
ISO_FRAME_COUNT
#define ISO_FRAME_COUNT
Definition: usbh_config.h:59
USB_ERR_INVAL
#define USB_ERR_INVAL
Definition: usbh_err_code.h:24
CC_ERR_BUFFERUNDERRUN
#define CC_ERR_BUFFERUNDERRUN
Definition: usbh_err_code.h:46
CC_ERR_NOT_ACCESS
#define CC_ERR_NOT_ACCESS
Definition: usbh_err_code.h:47
OHCI_ISO_DELAY
#define OHCI_ISO_DELAY
Definition: usbh_config.h:60
USB_ERR_PIPE
#define USB_ERR_PIPE
Definition: usbh_err_code.h:25
USB_ERR_NOMEM
#define USB_ERR_NOMEM
Definition: usbh_err_code.h:20
CC_ERR_PID_CHECK
#define CC_ERR_PID_CHECK
Definition: usbh_err_code.h:40
USB_ERR_BUSY
#define USB_ERR_BUSY
Definition: usbh_err_code.h:21
USB_ERR_SHUTDOWN
#define USB_ERR_SHUTDOWN
Definition: usbh_err_code.h:29
CC_ERR_BUFFEROVERRUN
#define CC_ERR_BUFFEROVERRUN
Definition: usbh_err_code.h:45
USB_ERR_CONNRESET
#define USB_ERR_CONNRESET
Definition: usbh_err_code.h:28
CC_ERR_DATAOVERRUN
#define CC_ERR_DATAOVERRUN
Definition: usbh_err_code.h:42
CC_ERR_INVALID_PID
#define CC_ERR_INVALID_PID
Definition: usbh_err_code.h:41
USB_ERR_URB_PENDING
#define USB_ERR_URB_PENDING
Definition: usbh_err_code.h:33
urb_t::setup_packet
uint8_t * setup_packet
Definition: usbh_core.h:548
urb_t::status
int status
Definition: usbh_core.h:543
urb_t::transfer_buffer
void * transfer_buffer
Definition: usbh_core.h:545
urb_t::start_frame
int start_frame
Definition: usbh_core.h:549
urb_t::actual_length
int actual_length
Definition: usbh_core.h:547
urb_t::transfer_buffer_length
int transfer_buffer_length
Definition: usbh_core.h:546
urb_t::pipe
uint32_t pipe
Definition: usbh_core.h:542
urb_t::dev
struct usb_device * dev
Definition: usbh_core.h:541
urb_t::number_of_packets
int number_of_packets
Definition: usbh_core.h:550
urb_t::transfer_flags
uint32_t transfer_flags
Definition: usbh_core.h:544
urb_t::urb_hcpriv
URB_PRIV_T urb_hcpriv
Definition: usbh_core.h:538
urb_t::iso_frame_desc
ISO_PACKET_DESCRIPTOR_T iso_frame_desc[8]
Definition: usbh_core.h:556
urb_t::next
struct urb_t * next
Definition: usbh_core.h:540
usb_device::bus
USB_BUS_T * bus
Definition: usbh_core.h:679
urb_t::complete
void(* complete)(struct urb_t *)
Definition: usbh_core.h:555
urb_t::interval
int interval
Definition: usbh_core.h:551
DEV_REQ_T
DEV_REQ_T
Definition: usbh_core.h:190
USB_DEV_T
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
NULL
#define NULL
NULL pointer.
Definition: NUC472_442.h:29018
urb_t
Definition: usbh_core.h:537
usbh_core.h
USB Host core driver header file.
usbh_ohci.h