1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74#include <common.h>
75#include <pci.h>
76
77#ifdef CONFIG_USB_UHCI
78
79#include <usb.h>
80#include "usb_uhci.h"
81
82#define USB_MAX_TEMP_TD 128
83#define USB_MAX_TEMP_INT_TD 32
84
85
86
87
88#ifdef USB_UHCI_DEBUG
89#define USB_UHCI_PRINTF(fmt,args...) printf (fmt ,##args)
90#else
91#define USB_UHCI_PRINTF(fmt,args...)
92#endif
93
94
95static int irqvec = -1;
96unsigned int usb_base_addr;
97
98static uhci_td_t td_int[8];
99static uhci_qh_t qh_cntrl;
100static uhci_qh_t qh_bulk;
101static uhci_qh_t qh_end;
102static uhci_td_t td_last;
103
104
105static uhci_td_t tmp_td[USB_MAX_TEMP_TD];
106static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD];
107
108static unsigned long framelist[1024] __attribute__ ((aligned (0x1000)));
109
110static struct virt_root_hub rh;
111
112
113
114
115int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
116 void *buffer, int transfer_len,struct devrequest *setup);
117
118
119
120
121
122void usb_fill_td(uhci_td_t* td,unsigned long link,unsigned long status,
123 unsigned long info, unsigned long buffer, unsigned long dev)
124{
125 td->link=swap_32(link);
126 td->status=swap_32(status);
127 td->info=swap_32(info);
128 td->buffer=swap_32(buffer);
129 td->dev_ptr=dev;
130}
131
132
133
134
135
136
137void usb_fill_qh(uhci_qh_t* qh,unsigned long head,unsigned long element)
138{
139 qh->head=swap_32(head);
140 qh->element=swap_32(element);
141 qh->dev_ptr=0L;
142}
143
144
145
146unsigned long usb_uhci_td_stat(unsigned long status)
147{
148 unsigned long result=0;
149 result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0;
150 result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0;
151 result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0;
152 result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0;
153 result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
154 result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
155 result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0;
156 return result;
157}
158
159
160
161
162int usb_get_td_status(uhci_td_t *td,struct usb_device *dev)
163{
164 unsigned long temp,info;
165 unsigned long stat;
166 uhci_td_t *mytd=td;
167
168 if(dev->devnum==rh.devnum)
169 return 0;
170 dev->act_len=0;
171 stat=0;
172 do {
173 temp=swap_32((unsigned long)mytd->status);
174 stat=usb_uhci_td_stat(temp);
175 info=swap_32((unsigned long)mytd->info);
176 if(((info & 0xff)!= USB_PID_SETUP) &&
177 (((info >> 21) & 0x7ff)!= 0x7ff) &&
178 (temp & 0x7FF)!=0x7ff)
179 {
180 dev->act_len+=(temp & 0x7FF) + 1;
181 }
182 if(stat) {
183 dev->status=stat;
184 return -1;
185 }
186 temp=swap_32((unsigned long)mytd->link);
187 mytd=(uhci_td_t *)(temp & 0xfffffff0);
188 }while((temp & 0x1)==0);
189 dev->status=stat;
190 return 0;
191}
192
193
194
195
196
197
198
199
200
201
202int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
203 int transfer_len,struct devrequest *setup)
204{
205 unsigned long destination, status;
206 int maxsze = usb_maxpacket(dev, pipe);
207 unsigned long dataptr;
208 int len;
209 int pktsze;
210 int i=0;
211
212 if (!maxsze) {
213 USB_UHCI_PRINTF("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", pipe);
214 return -1;
215 }
216 if(((pipe>>8)&0x7f)==rh.devnum) {
217
218 return uhci_submit_rh_msg(dev,pipe,buffer,transfer_len,setup);
219 }
220 USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",transfer_len,maxsze);
221
222 destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
223
224 status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
225
226
227 usb_fill_td(&tmp_td[i],UHCI_PTR_TERM ,status, destination | (7 << 21),(unsigned long)setup,(unsigned long)dev);
228#if 0
229 {
230 char *sp=(char *)setup;
231 printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
232 sp[0],sp[1],sp[2],sp[3],sp[4],sp[5],sp[6],sp[7]);
233 }
234#endif
235 dataptr = (unsigned long)buffer;
236 len=transfer_len;
237
238
239
240 destination = (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN)==0 ? USB_PID_OUT : USB_PID_IN);
241 while (len > 0) {
242
243 pktsze = len;
244 i++;
245 if (pktsze > maxsze)
246 pktsze = maxsze;
247 destination ^= 1 << TD_TOKEN_TOGGLE;
248 usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21),dataptr,(unsigned long)dev);
249 tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
250
251 dataptr += pktsze;
252 len -= pktsze;
253 }
254
255
256
257
258 destination &= ~UHCI_PID;
259 if (((pipe & USB_DIR_IN)==0) || (transfer_len == 0))
260 destination |= USB_PID_IN;
261 else
262 destination |= USB_PID_OUT;
263 destination |= 1 << TD_TOKEN_TOGGLE;
264 i++;
265 status &=~TD_CTRL_SPD;
266
267 usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21),0,(unsigned long)dev);
268 tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
269
270 USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n",i);
271
272 qh_cntrl.element=0xffffffffL;
273
274 qh_cntrl.dev_ptr=(unsigned long)dev;
275
276 qh_cntrl.element=swap_32((unsigned long)&tmp_td[0]);
277 return 0;
278}
279
280
281
282
283int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len)
284{
285 unsigned long destination, status,info;
286 unsigned long dataptr;
287 int maxsze = usb_maxpacket(dev, pipe);
288 int len;
289 int i=0;
290
291 if(transfer_len < 0) {
292 printf("Negative transfer length in submit_bulk\n");
293 return -1;
294 }
295 if (!maxsze)
296 return -1;
297
298 destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
299
300 status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
301
302
303 len = transfer_len;
304 dataptr = (unsigned long)buffer;
305 do {
306 int pktsze = len;
307 if (pktsze > maxsze)
308 pktsze = maxsze;
309
310 info = destination | (((pktsze - 1)&UHCI_NULL_DATA_SIZE) << 21) |
311 (usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE);
312
313 if((len-pktsze)==0)
314 status |= TD_CTRL_IOC;
315
316 usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, info,dataptr,(unsigned long)dev);
317 if(i>0)
318 tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
319 i++;
320 dataptr += pktsze;
321 len -= pktsze;
322 usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
323 } while (len > 0);
324
325 qh_bulk.element=0xffffffffL;
326
327 qh_bulk.dev_ptr=(unsigned long)dev;
328
329 qh_bulk.element=swap_32((unsigned long)&tmp_td[0]);
330 return 0;
331}
332
333
334
335
336uhci_td_t *uhci_alloc_int_td(void)
337{
338 int i;
339 for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
340 if(tmp_int_td[i].dev_ptr==0)
341 return &tmp_int_td[i];
342 }
343 return NULL;
344}
345
346#if 0
347void uhci_show_temp_int_td(void)
348{
349 int i;
350 for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
351 if((tmp_int_td[i].dev_ptr&0x01)!=0x1L)
352 printf("temp_td %d is assigned to dev %lx\n",i,tmp_int_td[i].dev_ptr);
353 }
354 printf("all others temp_tds are free\n");
355}
356#endif
357
358
359
360int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len, int interval)
361{
362 int nint, n;
363 unsigned long status, destination;
364 unsigned long info,tmp;
365 uhci_td_t *mytd;
366 if (interval < 0 || interval >= 256)
367 return -1;
368
369 if (interval == 0)
370 nint = 0;
371 else {
372 for (nint = 0, n = 1; nint <= 8; nint++, n += n)
373 {
374 if(interval < n) {
375 interval = n / 2;
376 break;
377 }
378 }
379 nint--;
380 }
381
382 USB_UHCI_PRINTF("Rounded interval to %i, chain %i\n", interval, nint);
383 mytd=uhci_alloc_int_td();
384 if(mytd==NULL) {
385 printf("No free INT TDs found\n");
386 return -1;
387 }
388 status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
389
390
391
392 destination =(pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe) | (((transfer_len - 1) & 0x7ff) << 21);
393
394 info = destination | (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
395 tmp = swap_32(td_int[nint].link);
396 usb_fill_td(mytd,tmp,status, info,(unsigned long)buffer,(unsigned long)dev);
397
398 tmp = swap_32((unsigned long)mytd);
399 td_int[nint].link=tmp;
400
401 usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
402
403 return 0;
404}
405
406
407
408
409
410
411void reset_hc(void)
412{
413
414
415 out16r( usb_base_addr + USBPORTSC1,0x0204);
416 out16r( usb_base_addr + USBPORTSC2,0x0204);
417 out16r( usb_base_addr + USBCMD,USBCMD_GRESET | USBCMD_RS);
418
419 out16r(usb_base_addr + USBINTR,0);
420 wait_ms(50);
421 out16r( usb_base_addr + USBCMD,0);
422 wait_ms(10);
423}
424
425void start_hc(void)
426{
427 int timeout = 1000;
428
429 while(in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
430 if (!--timeout) {
431 printf("USBCMD_HCRESET timed out!\n");
432 break;
433 }
434 }
435
436 out16r(usb_base_addr + USBINTR,USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
437
438 out16r(usb_base_addr + USBFRNUM,0);
439
440 out32r(usb_base_addr+USBFLBASEADD,(unsigned long)&framelist);
441
442 out16r(usb_base_addr + USBCMD,USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
443}
444
445
446
447void usb_init_skel(void)
448{
449 unsigned long temp;
450 int n;
451
452 for(n=0;n<USB_MAX_TEMP_INT_TD;n++)
453 tmp_int_td[n].dev_ptr=0L;
454
455 usb_fill_td(&td_last,UHCI_PTR_TERM,TD_CTRL_IOC ,0,0,0L);
456
457
458 usb_fill_qh(&qh_end,UHCI_PTR_TERM,(unsigned long)&td_last);
459
460 temp=(unsigned long)&qh_end;
461 usb_fill_qh(&qh_bulk,temp | UHCI_PTR_QH,UHCI_PTR_TERM);
462
463 temp=(unsigned long)&qh_bulk;
464 usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH,UHCI_PTR_TERM);
465
466 temp=(unsigned long)&qh_cntrl;
467 usb_fill_td(&td_int[0],temp | UHCI_PTR_QH,0,0,0,0L);
468 temp=(unsigned long)&td_int[0];
469 for(n=1; n<8; n++)
470 usb_fill_td(&td_int[n],temp,0,0,0,0L);
471 for (n = 0; n < 1024; n++) {
472
473 int m, o;
474 if ((n&127)==127)
475 framelist[n]= swap_32((unsigned long)&td_int[0]);
476 else
477 for (o = 1, m = 2; m <= 128; o++, m += m)
478 if ((n & (m - 1)) == ((m - 1) / 2))
479 framelist[n]= swap_32((unsigned long)&td_int[o]);
480 }
481}
482
483
484
485
486void usb_check_skel(void)
487{
488 struct usb_device *dev;
489
490 if(qh_cntrl.dev_ptr!=0)
491 {
492 dev=(struct usb_device *)qh_cntrl.dev_ptr;
493 usb_get_td_status(&tmp_td[0],dev);
494 if(!(dev->status & USB_ST_NOT_PROC)) {
495 qh_cntrl.dev_ptr=0;
496 }
497 }
498
499 if(qh_bulk.dev_ptr!=0)
500 {
501 dev=(struct usb_device *)qh_bulk.dev_ptr;
502 usb_get_td_status(&tmp_td[0],dev);
503 if(!(dev->status & USB_ST_NOT_PROC)) {
504 qh_bulk.dev_ptr=0;
505 }
506 }
507}
508
509
510
511
512
513void usb_check_int_chain(void)
514{
515 int i,res;
516 unsigned long link,status;
517 struct usb_device *dev;
518 uhci_td_t *td,*prevtd;
519
520 for(i=0;i<8;i++) {
521 prevtd = &td_int[i];
522 link=swap_32(td_int[i].link) & 0xfffffff0;
523 td=(uhci_td_t *)link;
524
525
526
527
528 while(((i>0) && (link != (unsigned long)&td_int[0])) ||
529 ((i==0) && !(swap_32(td->link) & UHCI_PTR_QH)))
530 {
531
532 status=swap_32(td->status);
533 if((td->dev_ptr!=0L) && !(status & TD_CTRL_ACTIVE)) {
534
535 dev=(struct usb_device *)td->dev_ptr;
536 dev->irq_act_len=((status & 0x7FF)==0x7FF) ? 0 : (status & 0x7FF) + 1;
537 dev->irq_status=usb_uhci_td_stat(status);
538 res=dev->irq_handle(dev);
539 if(res==1) {
540
541 status|=TD_CTRL_ACTIVE;
542 td->status=swap_32(status);
543 prevtd=td;
544 }
545 else {
546 prevtd->link=td->link;
547
548 td->dev_ptr=0L;
549 }
550 }
551 link=swap_32(td->link) & 0xfffffff0;
552 td=(uhci_td_t *)link;
553 }
554 }
555}
556
557
558
559
560void handle_usb_interrupt(void)
561{
562 unsigned short status;
563
564
565
566
567
568
569 status = in16r(usb_base_addr + USBSTS);
570
571 if (!status)
572 return;
573 if (status != 1) {
574
575 if ((status&0x20) && ((in16r(usb_base_addr+USBCMD) && USBCMD_RS)==0)) {
576 out16r(usb_base_addr + USBCMD, USBCMD_RS | in16r(usb_base_addr + USBCMD));
577 }
578 }
579 usb_check_int_chain();
580 usb_check_skel();
581 out16r(usb_base_addr+USBSTS,status);
582}
583
584
585
586
587int usb_lowlevel_init(void)
588{
589 unsigned char temp;
590 int busdevfunc;
591
592
593
594 char *s;
595
596
597 busdevfunc=pci_find_device(USB_UHCI_VEND_ID,USB_UHCI_DEV_ID,0);
598 if(busdevfunc == -1) {
599 printf("Error USB UHCI (%04X,%04X) not found\n",USB_UHCI_VEND_ID,USB_UHCI_DEV_ID);
600 return -1;
601 }
602
603#if 1
604 s = getenv("usb_irq");
605 if (s)
606 {
607 temp = atoi(s);
608 pci_write_config_byte(busdevfunc, PCI_INTERRUPT_LINE, temp);
609 }
610 else
611#endif
612 pci_read_config_byte(busdevfunc,PCI_INTERRUPT_LINE,&temp);
613
614 s = getenv("usb_base");
615 if (s)
616 {
617 unsigned long temp2;
618 temp2 = atoi(s);
619 pci_write_config_dword(busdevfunc, PCI_BASE_ADDRESS_4, temp2|0x01);
620 }
621
622 irqvec = temp;
623 irq_free_handler(irqvec);
624 USB_UHCI_PRINTF("Interrupt Line = %d\n",irqvec);
625 pci_read_config_byte(busdevfunc,PCI_INTERRUPT_PIN,&temp);
626 USB_UHCI_PRINTF("Interrupt Pin = %ld\n",temp);
627 pci_read_config_dword(busdevfunc,PCI_BASE_ADDRESS_4,&usb_base_addr);
628 USB_UHCI_PRINTF("IO Base Address = 0x%lx\n",usb_base_addr);
629 usb_base_addr&=0xFFFFFFF0;
630 usb_base_addr+=CONFIG_SYS_ISA_IO_BASE_ADDRESS;
631 rh.devnum = 0;
632 usb_init_skel();
633 reset_hc();
634 start_hc();
635 irq_install_handler(irqvec, (interrupt_handler_t *)handle_usb_interrupt, NULL);
636 irq_install_handler(0, (interrupt_handler_t *)handle_usb_interrupt, NULL);
637
638 return 0;
639}
640
641
642
643int usb_lowlevel_stop(void)
644{
645 if(irqvec == -1)
646 return 1;
647 irq_free_handler(irqvec);
648 irq_free_handler(0);
649 reset_hc();
650 irqvec = -1;
651 return 0;
652}
653
654
655
656
657
658#undef USB_RH_DEBUG
659
660#ifdef USB_RH_DEBUG
661#define USB_RH_PRINTF(fmt,args...) printf (fmt ,##args)
662static void usb_display_wValue(unsigned short wValue,unsigned short wIndex);
663static void usb_display_Req(unsigned short req);
664#else
665#define USB_RH_PRINTF(fmt,args...)
666static void usb_display_wValue(unsigned short wValue,unsigned short wIndex) {}
667static void usb_display_Req(unsigned short req) {}
668#endif
669
670static unsigned char root_hub_dev_des[] =
671{
672 0x12,
673 0x01,
674 0x00,
675 0x01,
676 0x09,
677 0x00,
678 0x00,
679 0x08,
680 0x00,
681 0x00,
682 0x00,
683 0x00,
684 0x00,
685 0x00,
686 0x01,
687 0x00,
688 0x00,
689 0x01
690};
691
692
693
694static unsigned char root_hub_config_des[] =
695{
696 0x09,
697 0x02,
698 0x19,
699 0x00,
700 0x01,
701 0x01,
702 0x00,
703 0x40,
704
705 0x00,
706
707
708 0x09,
709 0x04,
710 0x00,
711 0x00,
712 0x01,
713 0x09,
714 0x00,
715 0x00,
716 0x00,
717
718
719 0x07,
720 0x05,
721 0x81,
722 0x03,
723 0x08,
724 0x00,
725 0xff
726};
727
728
729static unsigned char root_hub_hub_des[] =
730{
731 0x09,
732 0x29,
733 0x02,
734 0x00,
735 0x00,
736 0x01,
737 0x00,
738 0x00,
739 0xff
740};
741
742static unsigned char root_hub_str_index0[] =
743{
744 0x04,
745 0x03,
746 0x09,
747 0x04,
748};
749
750static unsigned char root_hub_str_index1[] =
751{
752 28,
753 0x03,
754 'U',
755 0,
756 'H',
757 0,
758 'C',
759 0,
760 'I',
761 0,
762 ' ',
763 0,
764 'R',
765 0,
766 'o',
767 0,
768 'o',
769 0,
770 't',
771 0,
772 ' ',
773 0,
774 'H',
775 0,
776 'u',
777 0,
778 'b',
779 0,
780};
781
782
783
784
785
786
787
788int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len,struct devrequest *cmd)
789{
790 void *data = buffer;
791 int leni = transfer_len;
792 int len = 0;
793 int status = 0;
794 int stat = 0;
795 int i;
796
797 unsigned short cstatus;
798
799 unsigned short bmRType_bReq;
800 unsigned short wValue;
801 unsigned short wIndex;
802 unsigned short wLength;
803
804 if (usb_pipeint(pipe)) {
805 printf("Root-Hub submit IRQ: NOT implemented\n");
806#if 0
807 uhci->rh.urb = urb;
808 uhci->rh.send = 1;
809 uhci->rh.interval = urb->interval;
810 rh_init_int_timer (urb);
811#endif
812 return 0;
813 }
814 bmRType_bReq = cmd->requesttype | cmd->request << 8;
815 wValue = swap_16(cmd->value);
816 wIndex = swap_16(cmd->index);
817 wLength = swap_16(cmd->length);
818 usb_display_Req(bmRType_bReq);
819 for (i = 0; i < 8; i++)
820 rh.c_p_r[i] = 0;
821 USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
822 dev->devnum, 8, cmd->requesttype,cmd->request, wValue, wIndex, wLength);
823
824 switch (bmRType_bReq) {
825
826
827
828
829
830
831
832
833 case RH_GET_STATUS:
834 *(unsigned short *) data = swap_16(1);
835 len=2;
836 break;
837 case RH_GET_STATUS | RH_INTERFACE:
838 *(unsigned short *) data = swap_16(0);
839 len=2;
840 break;
841 case RH_GET_STATUS | RH_ENDPOINT:
842 *(unsigned short *) data = swap_16(0);
843 len=2;
844 break;
845 case RH_GET_STATUS | RH_CLASS:
846 *(unsigned long *) data = swap_32(0);
847 len=4;
848 break;
849 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
850
851 status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
852 cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
853 ((status & USBPORTSC_PEC) >> (3 - 1)) |
854 (rh.c_p_r[wIndex - 1] << (0 + 4));
855 status = (status & USBPORTSC_CCS) |
856 ((status & USBPORTSC_PE) >> (2 - 1)) |
857 ((status & USBPORTSC_SUSP) >> (12 - 2)) |
858 ((status & USBPORTSC_PR) >> (9 - 4)) |
859 (1 << 8) |
860 ((status & USBPORTSC_LSDA) << (-8 + 9));
861
862 *(unsigned short *) data = swap_16(status);
863 *(unsigned short *) (data + 2) = swap_16(cstatus);
864 len=4;
865 break;
866 case RH_CLEAR_FEATURE | RH_ENDPOINT:
867 switch (wValue) {
868 case (RH_ENDPOINT_STALL):
869 len=0;
870 break;
871 }
872 break;
873
874 case RH_CLEAR_FEATURE | RH_CLASS:
875 switch (wValue) {
876 case (RH_C_HUB_OVER_CURRENT):
877 len=0;
878 break;
879 }
880 break;
881
882 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
883 usb_display_wValue(wValue,wIndex);
884 switch (wValue) {
885 case (RH_PORT_ENABLE):
886 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
887 status = (status & 0xfff5) & ~USBPORTSC_PE;
888 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
889 len=0;
890 break;
891 case (RH_PORT_SUSPEND):
892 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
893 status = (status & 0xfff5) & ~USBPORTSC_SUSP;
894 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
895 len=0;
896 break;
897 case (RH_PORT_POWER):
898 len=0;
899 break;
900 case (RH_C_PORT_CONNECTION):
901 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
902 status = (status & 0xfff5) | USBPORTSC_CSC;
903 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
904 len=0;
905 break;
906 case (RH_C_PORT_ENABLE):
907 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
908 status = (status & 0xfff5) | USBPORTSC_PEC;
909 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
910 len=0;
911 break;
912 case (RH_C_PORT_SUSPEND):
913
914 len=0;
915 break;
916 case (RH_C_PORT_OVER_CURRENT):
917 len=0;
918 break;
919 case (RH_C_PORT_RESET):
920 rh.c_p_r[wIndex - 1] = 0;
921 len=0;
922 break;
923 }
924 break;
925 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
926 usb_display_wValue(wValue,wIndex);
927 switch (wValue) {
928 case (RH_PORT_SUSPEND):
929 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
930 status = (status & 0xfff5) | USBPORTSC_SUSP;
931 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
932 len=0;
933 break;
934 case (RH_PORT_RESET):
935 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
936 status = (status & 0xfff5) | USBPORTSC_PR;
937 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
938 wait_ms(10);
939 status = (status & 0xfff5) & ~USBPORTSC_PR;
940 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
941 udelay(10);
942 status = (status & 0xfff5) | USBPORTSC_PE;
943 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
944 wait_ms(10);
945 status = (status & 0xfff5) | 0xa;
946 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
947 len=0;
948 break;
949 case (RH_PORT_POWER):
950 len=0;
951 break;
952 case (RH_PORT_ENABLE):
953 status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
954 status = (status & 0xfff5) | USBPORTSC_PE;
955 out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
956 len=0;
957 break;
958 }
959 break;
960
961 case RH_SET_ADDRESS:
962 rh.devnum = wValue;
963 len=0;
964 break;
965 case RH_GET_DESCRIPTOR:
966 switch ((wValue & 0xff00) >> 8) {
967 case (0x01):
968 i=sizeof(root_hub_config_des);
969 status=i > wLength ? wLength : i;
970 len = leni > status ? status : leni;
971 memcpy (data, root_hub_dev_des, len);
972 break;
973 case (0x02):
974 i=sizeof(root_hub_config_des);
975 status=i > wLength ? wLength : i;
976 len = leni > status ? status : leni;
977 memcpy (data, root_hub_config_des, len);
978 break;
979 case (0x03):
980 if(wValue==0x0300) {
981 i=sizeof(root_hub_str_index0);
982 status = i > wLength ? wLength : i;
983 len = leni > status ? status : leni;
984 memcpy (data, root_hub_str_index0, len);
985 break;
986 }
987 if(wValue==0x0301) {
988 i=sizeof(root_hub_str_index1);
989 status = i > wLength ? wLength : i;
990 len = leni > status ? status : leni;
991 memcpy (data, root_hub_str_index1, len);
992 break;
993 }
994 stat = USB_ST_STALLED;
995 }
996 break;
997
998 case RH_GET_DESCRIPTOR | RH_CLASS:
999 root_hub_hub_des[2] = 2;
1000 i=sizeof(root_hub_hub_des);
1001 status= i > wLength ? wLength : i;
1002 len = leni > status ? status : leni;
1003 memcpy (data, root_hub_hub_des, len);
1004 break;
1005 case RH_GET_CONFIGURATION:
1006 *(unsigned char *) data = 0x01;
1007 len = 1;
1008 break;
1009 case RH_SET_CONFIGURATION:
1010 len=0;
1011 break;
1012 default:
1013 stat = USB_ST_STALLED;
1014 }
1015 USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n",stat,
1016 in16r(usb_base_addr + USBPORTSC1), in16r(usb_base_addr + USBPORTSC2));
1017 dev->act_len=len;
1018 dev->status=stat;
1019 return stat;
1020
1021}
1022
1023
1024
1025
1026
1027#ifdef USB_RH_DEBUG
1028
1029static void usb_display_Req(unsigned short req)
1030{
1031 USB_RH_PRINTF("- Root-Hub Request: ");
1032 switch (req) {
1033 case RH_GET_STATUS:
1034 USB_RH_PRINTF("Get Status ");
1035 break;
1036 case RH_GET_STATUS | RH_INTERFACE:
1037 USB_RH_PRINTF("Get Status Interface ");
1038 break;
1039 case RH_GET_STATUS | RH_ENDPOINT:
1040 USB_RH_PRINTF("Get Status Endpoint ");
1041 break;
1042 case RH_GET_STATUS | RH_CLASS:
1043 USB_RH_PRINTF("Get Status Class");
1044 break;
1045 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
1046 USB_RH_PRINTF("Get Status Class Others");
1047 break;
1048 case RH_CLEAR_FEATURE | RH_ENDPOINT:
1049 USB_RH_PRINTF("Clear Feature Endpoint ");
1050 break;
1051 case RH_CLEAR_FEATURE | RH_CLASS:
1052 USB_RH_PRINTF("Clear Feature Class ");
1053 break;
1054 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
1055 USB_RH_PRINTF("Clear Feature Other Class ");
1056 break;
1057 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
1058 USB_RH_PRINTF("Set Feature Other Class ");
1059 break;
1060 case RH_SET_ADDRESS:
1061 USB_RH_PRINTF("Set Address ");
1062 break;
1063 case RH_GET_DESCRIPTOR:
1064 USB_RH_PRINTF("Get Descriptor ");
1065 break;
1066 case RH_GET_DESCRIPTOR | RH_CLASS:
1067 USB_RH_PRINTF("Get Descriptor Class ");
1068 break;
1069 case RH_GET_CONFIGURATION:
1070 USB_RH_PRINTF("Get Configuration ");
1071 break;
1072 case RH_SET_CONFIGURATION:
1073 USB_RH_PRINTF("Get Configuration ");
1074 break;
1075 default:
1076 USB_RH_PRINTF("****UNKNOWN**** 0x%04X ",req);
1077 }
1078 USB_RH_PRINTF("\n");
1079
1080}
1081
1082static void usb_display_wValue(unsigned short wValue,unsigned short wIndex)
1083{
1084 switch (wValue) {
1085 case (RH_PORT_ENABLE):
1086 USB_RH_PRINTF("Root-Hub: Enable Port %d\n",wIndex);
1087 break;
1088 case (RH_PORT_SUSPEND):
1089 USB_RH_PRINTF("Root-Hub: Suspend Port %d\n",wIndex);
1090 break;
1091 case (RH_PORT_POWER):
1092 USB_RH_PRINTF("Root-Hub: Port Power %d\n",wIndex);
1093 break;
1094 case (RH_C_PORT_CONNECTION):
1095 USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n",wIndex);
1096 break;
1097 case (RH_C_PORT_ENABLE):
1098 USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n",wIndex);
1099 break;
1100 case (RH_C_PORT_SUSPEND):
1101 USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n",wIndex);
1102 break;
1103 case (RH_C_PORT_OVER_CURRENT):
1104 USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",wIndex);
1105 break;
1106 case (RH_C_PORT_RESET):
1107 USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n",wIndex);
1108 break;
1109 default:
1110 USB_RH_PRINTF("Root-Hub: unknown %x %x\n",wValue,wIndex);
1111 break;
1112 }
1113}
1114
1115#endif
1116
1117
1118#ifdef USB_UHCI_DEBUG
1119
1120static int usb_display_td(uhci_td_t *td)
1121{
1122 unsigned long tmp;
1123 int valid;
1124
1125 printf("TD at %p:\n",td);
1126
1127 tmp=swap_32(td->link);
1128 printf("Link points to 0x%08lX, %s first, %s, %s\n",tmp&0xfffffff0,
1129 ((tmp & 0x4)==0x4) ? "Depth" : "Breath",
1130 ((tmp & 0x2)==0x2) ? "QH" : "TD",
1131 ((tmp & 0x1)==0x1) ? "invalid" : "valid");
1132 valid=((tmp & 0x1)==0x0);
1133 tmp=swap_32(td->status);
1134 printf(" %s %ld Errors %s %s %s \n %s %s %s %s %s %s\n Len 0x%lX\n",
1135 (((tmp>>29)&0x1)==0x1) ? "SPD Enable" : "SPD Disable",
1136 ((tmp>>28)&0x3),
1137 (((tmp>>26)&0x1)==0x1) ? "Low Speed" : "Full Speed",
1138 (((tmp>>25)&0x1)==0x1) ? "ISO " : "",
1139 (((tmp>>24)&0x1)==0x1) ? "IOC " : "",
1140 (((tmp>>23)&0x1)==0x1) ? "Active " : "Inactive ",
1141 (((tmp>>22)&0x1)==0x1) ? "Stalled" : "",
1142 (((tmp>>21)&0x1)==0x1) ? "Data Buffer Error" : "",
1143 (((tmp>>20)&0x1)==0x1) ? "Babble" : "",
1144 (((tmp>>19)&0x1)==0x1) ? "NAK" : "",
1145 (((tmp>>18)&0x1)==0x1) ? "Bitstuff Error" : "",
1146 (tmp&0x7ff));
1147 tmp=swap_32(td->info);
1148 printf(" MaxLen 0x%lX\n",((tmp>>21)&0x7FF));
1149 printf(" %s Endpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",((tmp>>19)&0x1)==0x1 ? "TOGGLE" : "",
1150 ((tmp>>15)&0xF),((tmp>>8)&0x7F),tmp&0xFF);
1151 tmp=swap_32(td->buffer);
1152 printf(" Buffer 0x%08lX\n",tmp);
1153 printf(" DEV %08lX\n",td->dev_ptr);
1154 return valid;
1155}
1156
1157
1158void usb_show_td(int max)
1159{
1160 int i;
1161 if(max>0) {
1162 for(i=0;i<max;i++) {
1163 usb_display_td(&tmp_td[i]);
1164 }
1165 }
1166 else {
1167 i=0;
1168 do {
1169 printf("tmp_td[%d]\n",i);
1170 }while(usb_display_td(&tmp_td[i++]));
1171 }
1172}
1173
1174
1175#endif
1176#endif
1177
1178
1179