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