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#include <common.h>
40
41#ifdef CONFIG_USB_OHCI
42
43#include <malloc.h>
44#include <usb.h>
45#include "usb_ohci.h"
46
47#include <mpc5xxx.h>
48
49#define OHCI_USE_NPS
50#undef OHCI_VERBOSE_DEBUG
51#undef DEBUG
52#undef SHOW_INFO
53#undef OHCI_FILL_TRACE
54
55
56#define OHCI_CONTROL_INIT \
57 (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
58
59#define readl(a) (*((volatile u32 *)(a)))
60#define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
61
62#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
63
64#ifdef DEBUG
65#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
66#else
67#define dbg(format, arg...) do {} while(0)
68#endif
69#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
70#ifdef SHOW_INFO
71#define info(format, arg...) printf("INFO: " format "\n", ## arg)
72#else
73#define info(format, arg...) do {} while(0)
74#endif
75
76#define m16_swap(x) swap_16(x)
77#define m32_swap(x) swap_32(x)
78
79#define ohci_cpu_to_le16(x) (x)
80#define ohci_cpu_to_le32(x) (x)
81
82
83static ohci_t gohci;
84
85struct ohci_hcca ghcca[1];
86
87struct ohci_hcca *phcca;
88
89struct ohci_device ohci_dev;
90
91urb_priv_t urb_priv;
92
93int got_rhsc;
94
95struct usb_device *devgone;
96
97int urb_finished = 0;
98
99
100
101
102
103
104
105#define OHCI_QUIRK_AMD756 0xabcd
106#define read_roothub(hc, register, mask) ({ \
107 u32 temp = readl (&hc->regs->roothub.register); \
108 if (hc->flags & OHCI_QUIRK_AMD756) \
109 while (temp & mask) \
110 temp = readl (&hc->regs->roothub.register); \
111 temp; })
112
113static u32 roothub_a (struct ohci *hc)
114 { return read_roothub (hc, a, 0xfc0fe000); }
115static inline u32 roothub_b (struct ohci *hc)
116 { return readl (&hc->regs->roothub.b); }
117static inline u32 roothub_status (struct ohci *hc)
118 { return readl (&hc->regs->roothub.status); }
119static u32 roothub_portstatus (struct ohci *hc, int i)
120 { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
121
122
123
124static int hc_interrupt (void);
125static void
126td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
127 int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
128
129
130
131
132
133
134
135static void urb_free_priv (urb_priv_t * urb)
136{
137 int i;
138 int last;
139 struct td * td;
140
141 last = urb->length - 1;
142 if (last >= 0) {
143 for (i = 0; i <= last; i++) {
144 td = urb->td[i];
145 if (td) {
146 td->usb_dev = NULL;
147 urb->td[i] = NULL;
148 }
149 }
150 }
151}
152
153
154
155#ifdef DEBUG
156static int sohci_get_current_frame_number (struct usb_device * dev);
157
158
159
160
161static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer,
162 int transfer_len, struct devrequest * setup, char * str, int small)
163{
164 urb_priv_t * purb = &urb_priv;
165
166 dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
167 str,
168 sohci_get_current_frame_number (dev),
169 usb_pipedevice (pipe),
170 usb_pipeendpoint (pipe),
171 usb_pipeout (pipe)? 'O': 'I',
172 usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
173 (usb_pipecontrol (pipe)? "CTRL": "BULK"),
174 purb->actual_length,
175 transfer_len, dev->status);
176#ifdef OHCI_VERBOSE_DEBUG
177 if (!small) {
178 int i, len;
179
180 if (usb_pipecontrol (pipe)) {
181 printf (__FILE__ ": cmd(8):");
182 for (i = 0; i < 8 ; i++)
183 printf (" %02x", ((__u8 *) setup) [i]);
184 printf ("\n");
185 }
186 if (transfer_len > 0 && buffer) {
187 printf (__FILE__ ": data(%d/%d):",
188 purb->actual_length,
189 transfer_len);
190 len = usb_pipeout (pipe)?
191 transfer_len: purb->actual_length;
192 for (i = 0; i < 16 && i < len; i++)
193 printf (" %02x", ((__u8 *) buffer) [i]);
194 printf ("%s\n", i < len? "...": "");
195 }
196 }
197#endif
198}
199
200
201void ep_print_int_eds (ohci_t *ohci, char * str) {
202 int i, j;
203 __u32 * ed_p;
204 for (i= 0; i < 32; i++) {
205 j = 5;
206 ed_p = &(ohci->hcca->int_table [i]);
207 if (*ed_p == 0)
208 continue;
209 printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
210 while (*ed_p != 0 && j--) {
211 ed_t *ed = (ed_t *)ohci_cpu_to_le32(ed_p);
212 printf (" ed: %4x;", ed->hwINFO);
213 ed_p = &ed->hwNextED;
214 }
215 printf ("\n");
216 }
217}
218
219static void ohci_dump_intr_mask (char *label, __u32 mask)
220{
221 dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
222 label,
223 mask,
224 (mask & OHCI_INTR_MIE) ? " MIE" : "",
225 (mask & OHCI_INTR_OC) ? " OC" : "",
226 (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
227 (mask & OHCI_INTR_FNO) ? " FNO" : "",
228 (mask & OHCI_INTR_UE) ? " UE" : "",
229 (mask & OHCI_INTR_RD) ? " RD" : "",
230 (mask & OHCI_INTR_SF) ? " SF" : "",
231 (mask & OHCI_INTR_WDH) ? " WDH" : "",
232 (mask & OHCI_INTR_SO) ? " SO" : ""
233 );
234}
235
236static void maybe_print_eds (char *label, __u32 value)
237{
238 ed_t *edp = (ed_t *)value;
239
240 if (value) {
241 dbg ("%s %08x", label, value);
242 dbg ("%08x", edp->hwINFO);
243 dbg ("%08x", edp->hwTailP);
244 dbg ("%08x", edp->hwHeadP);
245 dbg ("%08x", edp->hwNextED);
246 }
247}
248
249static char * hcfs2string (int state)
250{
251 switch (state) {
252 case OHCI_USB_RESET: return "reset";
253 case OHCI_USB_RESUME: return "resume";
254 case OHCI_USB_OPER: return "operational";
255 case OHCI_USB_SUSPEND: return "suspend";
256 }
257 return "?";
258}
259
260
261static void ohci_dump_status (ohci_t *controller)
262{
263 struct ohci_regs *regs = controller->regs;
264 __u32 temp;
265
266 temp = readl (®s->revision) & 0xff;
267 if (temp != 0x10)
268 dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
269
270 temp = readl (®s->control);
271 dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
272 (temp & OHCI_CTRL_RWE) ? " RWE" : "",
273 (temp & OHCI_CTRL_RWC) ? " RWC" : "",
274 (temp & OHCI_CTRL_IR) ? " IR" : "",
275 hcfs2string (temp & OHCI_CTRL_HCFS),
276 (temp & OHCI_CTRL_BLE) ? " BLE" : "",
277 (temp & OHCI_CTRL_CLE) ? " CLE" : "",
278 (temp & OHCI_CTRL_IE) ? " IE" : "",
279 (temp & OHCI_CTRL_PLE) ? " PLE" : "",
280 temp & OHCI_CTRL_CBSR
281 );
282
283 temp = readl (®s->cmdstatus);
284 dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
285 (temp & OHCI_SOC) >> 16,
286 (temp & OHCI_OCR) ? " OCR" : "",
287 (temp & OHCI_BLF) ? " BLF" : "",
288 (temp & OHCI_CLF) ? " CLF" : "",
289 (temp & OHCI_HCR) ? " HCR" : ""
290 );
291
292 ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus));
293 ohci_dump_intr_mask ("intrenable", readl (®s->intrenable));
294
295 maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent));
296
297 maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead));
298 maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent));
299
300 maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead));
301 maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent));
302
303 maybe_print_eds ("donehead", readl (®s->donehead));
304}
305
306static void ohci_dump_roothub (ohci_t *controller, int verbose)
307{
308 __u32 temp, ndp, i;
309
310 temp = roothub_a (controller);
311 ndp = (temp & RH_A_NDP);
312
313 if (verbose) {
314 dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
315 ((temp & RH_A_POTPGT) >> 24) & 0xff,
316 (temp & RH_A_NOCP) ? " NOCP" : "",
317 (temp & RH_A_OCPM) ? " OCPM" : "",
318 (temp & RH_A_DT) ? " DT" : "",
319 (temp & RH_A_NPS) ? " NPS" : "",
320 (temp & RH_A_PSM) ? " PSM" : "",
321 ndp
322 );
323 temp = roothub_b (controller);
324 dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
325 temp,
326 (temp & RH_B_PPCM) >> 16,
327 (temp & RH_B_DR)
328 );
329 temp = roothub_status (controller);
330 dbg ("roothub.status: %08x%s%s%s%s%s%s",
331 temp,
332 (temp & RH_HS_CRWE) ? " CRWE" : "",
333 (temp & RH_HS_OCIC) ? " OCIC" : "",
334 (temp & RH_HS_LPSC) ? " LPSC" : "",
335 (temp & RH_HS_DRWE) ? " DRWE" : "",
336 (temp & RH_HS_OCI) ? " OCI" : "",
337 (temp & RH_HS_LPS) ? " LPS" : ""
338 );
339 }
340
341 for (i = 0; i < ndp; i++) {
342 temp = roothub_portstatus (controller, i);
343 dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
344 i,
345 temp,
346 (temp & RH_PS_PRSC) ? " PRSC" : "",
347 (temp & RH_PS_OCIC) ? " OCIC" : "",
348 (temp & RH_PS_PSSC) ? " PSSC" : "",
349 (temp & RH_PS_PESC) ? " PESC" : "",
350 (temp & RH_PS_CSC) ? " CSC" : "",
351
352 (temp & RH_PS_LSDA) ? " LSDA" : "",
353 (temp & RH_PS_PPS) ? " PPS" : "",
354 (temp & RH_PS_PRS) ? " PRS" : "",
355 (temp & RH_PS_POCI) ? " POCI" : "",
356 (temp & RH_PS_PSS) ? " PSS" : "",
357
358 (temp & RH_PS_PES) ? " PES" : "",
359 (temp & RH_PS_CCS) ? " CCS" : ""
360 );
361 }
362}
363
364static void ohci_dump (ohci_t *controller, int verbose)
365{
366 dbg ("OHCI controller usb-%s state", controller->slot_name);
367
368
369 ohci_dump_status (controller);
370 if (verbose)
371 ep_print_int_eds (controller, "hcca");
372 dbg ("hcca frame #%04x", controller->hcca->frame_no);
373 ohci_dump_roothub (controller, 1);
374}
375
376
377#endif
378
379
380
381
382
383
384
385int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
386 int transfer_len, struct devrequest *setup, int interval)
387{
388 ohci_t *ohci;
389 ed_t * ed;
390 urb_priv_t *purb_priv;
391 int i, size = 0;
392
393 ohci = &gohci;
394
395
396
397 if (ohci->disabled) {
398 err("sohci_submit_job: EPIPE");
399 return -1;
400 }
401
402
403
404
405 if (!urb_finished) {
406 err("sohci_submit_job: URB NOT FINISHED");
407 return -1;
408 }
409
410 urb_finished = 0;
411
412
413 if (!(ed = ep_add_ed (dev, pipe))) {
414 err("sohci_submit_job: ENOMEM");
415 return -1;
416 }
417
418
419 switch (usb_pipetype (pipe)) {
420 case PIPE_BULK:
421 size = (transfer_len - 1) / 4096 + 1;
422 break;
423 case PIPE_CONTROL:
424 size = (transfer_len == 0)? 2:
425 (transfer_len - 1) / 4096 + 3;
426 break;
427 }
428
429 if (size >= (N_URB_TD - 1)) {
430 err("need %d TDs, only have %d", size, N_URB_TD);
431 return -1;
432 }
433 purb_priv = &urb_priv;
434 purb_priv->pipe = pipe;
435
436
437 purb_priv->length = size;
438 purb_priv->ed = ed;
439 purb_priv->actual_length = 0;
440
441
442
443 for (i = 0; i < size; i++) {
444 purb_priv->td[i] = td_alloc (dev);
445 if (!purb_priv->td[i]) {
446 purb_priv->length = i;
447 urb_free_priv (purb_priv);
448 err("sohci_submit_job: ENOMEM");
449 return -1;
450 }
451 }
452
453 if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
454 urb_free_priv (purb_priv);
455 err("sohci_submit_job: EINVAL");
456 return -1;
457 }
458
459
460 if (ed->state != ED_OPER)
461 ep_link (ohci, ed);
462
463
464 td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
465
466 return 0;
467}
468
469
470
471#ifdef DEBUG
472
473
474static int sohci_get_current_frame_number (struct usb_device *usb_dev)
475{
476 ohci_t *ohci = &gohci;
477
478 return ohci_cpu_to_le16 (ohci->hcca->frame_no);
479}
480#endif
481
482
483
484
485
486
487
488static int ep_link (ohci_t *ohci, ed_t *edi)
489{
490 volatile ed_t *ed = edi;
491
492 ed->state = ED_OPER;
493
494 switch (ed->type) {
495 case PIPE_CONTROL:
496 ed->hwNextED = 0;
497 if (ohci->ed_controltail == NULL) {
498 writel (ed, &ohci->regs->ed_controlhead);
499 } else {
500 ohci->ed_controltail->hwNextED = ohci_cpu_to_le32 ((unsigned long)ed);
501 }
502 ed->ed_prev = ohci->ed_controltail;
503 if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
504 !ohci->ed_rm_list[1] && !ohci->sleeping) {
505 ohci->hc_control |= OHCI_CTRL_CLE;
506 writel (ohci->hc_control, &ohci->regs->control);
507 }
508 ohci->ed_controltail = edi;
509 break;
510
511 case PIPE_BULK:
512 ed->hwNextED = 0;
513 if (ohci->ed_bulktail == NULL) {
514 writel (ed, &ohci->regs->ed_bulkhead);
515 } else {
516 ohci->ed_bulktail->hwNextED = ohci_cpu_to_le32 ((unsigned long)ed);
517 }
518 ed->ed_prev = ohci->ed_bulktail;
519 if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
520 !ohci->ed_rm_list[1] && !ohci->sleeping) {
521 ohci->hc_control |= OHCI_CTRL_BLE;
522 writel (ohci->hc_control, &ohci->regs->control);
523 }
524 ohci->ed_bulktail = edi;
525 break;
526 }
527 return 0;
528}
529
530
531
532
533
534
535
536
537static int ep_unlink (ohci_t *ohci, ed_t *edi)
538{
539 volatile ed_t *ed = edi;
540
541 ed->hwINFO |= ohci_cpu_to_le32 (OHCI_ED_SKIP);
542
543 switch (ed->type) {
544 case PIPE_CONTROL:
545 if (ed->ed_prev == NULL) {
546 if (!ed->hwNextED) {
547 ohci->hc_control &= ~OHCI_CTRL_CLE;
548 writel (ohci->hc_control, &ohci->regs->control);
549 }
550 writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
551 } else {
552 ed->ed_prev->hwNextED = ed->hwNextED;
553 }
554 if (ohci->ed_controltail == ed) {
555 ohci->ed_controltail = ed->ed_prev;
556 } else {
557 ((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
558 }
559 break;
560
561 case PIPE_BULK:
562 if (ed->ed_prev == NULL) {
563 if (!ed->hwNextED) {
564 ohci->hc_control &= ~OHCI_CTRL_BLE;
565 writel (ohci->hc_control, &ohci->regs->control);
566 }
567 writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
568 } else {
569 ed->ed_prev->hwNextED = ed->hwNextED;
570 }
571 if (ohci->ed_bulktail == ed) {
572 ohci->ed_bulktail = ed->ed_prev;
573 } else {
574 ((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
575 }
576 break;
577 }
578 ed->state = ED_UNLINK;
579 return 0;
580}
581
582
583
584
585
586
587
588
589
590
591static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
592{
593 td_t *td;
594 ed_t *ed_ret;
595 volatile ed_t *ed;
596
597 ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
598 (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
599
600 if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
601 err("ep_add_ed: pending delete");
602
603 return NULL;
604 }
605
606 if (ed->state == ED_NEW) {
607 ed->hwINFO = ohci_cpu_to_le32 (OHCI_ED_SKIP);
608
609 td = td_alloc (usb_dev);
610 ed->hwTailP = ohci_cpu_to_le32 ((unsigned long)td);
611 ed->hwHeadP = ed->hwTailP;
612 ed->state = ED_UNLINK;
613 ed->type = usb_pipetype (pipe);
614 ohci_dev.ed_cnt++;
615 }
616
617 ed->hwINFO = ohci_cpu_to_le32 (usb_pipedevice (pipe)
618 | usb_pipeendpoint (pipe) << 7
619 | (usb_pipeisoc (pipe)? 0x8000: 0)
620 | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
621 | usb_pipeslow (pipe) << 13
622 | usb_maxpacket (usb_dev, pipe) << 16);
623
624 return ed_ret;
625}
626
627
628
629
630
631
632
633static void td_fill (ohci_t *ohci, unsigned int info,
634 void *data, int len,
635 struct usb_device *dev, int index, urb_priv_t *urb_priv)
636{
637 volatile td_t *td, *td_pt;
638#ifdef OHCI_FILL_TRACE
639 int i;
640#endif
641
642 if (index > urb_priv->length) {
643 err("index > length");
644 return;
645 }
646
647 td_pt = urb_priv->td [index];
648 td_pt->hwNextTD = 0;
649
650
651 td = urb_priv->td [index] = (td_t *)(ohci_cpu_to_le32 (urb_priv->ed->hwTailP) & ~0xf);
652
653 td->ed = urb_priv->ed;
654 td->next_dl_td = NULL;
655 td->index = index;
656 td->data = (__u32)data;
657#ifdef OHCI_FILL_TRACE
658 if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) {
659 for (i = 0; i < len; i++)
660 printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]);
661 printf("\n");
662 }
663#endif
664 if (!len)
665 data = 0;
666
667 td->hwINFO = ohci_cpu_to_le32 (info);
668 td->hwCBP = ohci_cpu_to_le32 ((unsigned long)data);
669 if (data)
670 td->hwBE = ohci_cpu_to_le32 ((unsigned long)(data + len - 1));
671 else
672 td->hwBE = 0;
673 td->hwNextTD = ohci_cpu_to_le32 ((unsigned long)td_pt);
674
675
676 td->ed->hwTailP = td->hwNextTD;
677}
678
679
680
681
682static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
683 int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
684{
685 ohci_t *ohci = &gohci;
686 int data_len = transfer_len;
687 void *data;
688 int cnt = 0;
689 __u32 info = 0;
690 unsigned int toggle = 0;
691
692
693 if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
694 toggle = TD_T_TOGGLE;
695 } else {
696 toggle = TD_T_DATA0;
697 usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
698 }
699 urb->td_cnt = 0;
700 if (data_len)
701 data = buffer;
702 else
703 data = 0;
704
705 switch (usb_pipetype (pipe)) {
706 case PIPE_BULK:
707 info = usb_pipeout (pipe)?
708 TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
709 while(data_len > 4096) {
710 td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
711 data += 4096; data_len -= 4096; cnt++;
712 }
713 info = usb_pipeout (pipe)?
714 TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
715 td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
716 cnt++;
717
718 if (!ohci->sleeping)
719 writel (OHCI_BLF, &ohci->regs->cmdstatus);
720 break;
721
722 case PIPE_CONTROL:
723 info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
724 td_fill (ohci, info, setup, 8, dev, cnt++, urb);
725 if (data_len > 0) {
726 info = usb_pipeout (pipe)?
727 TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
728
729 td_fill (ohci, info, data, data_len, dev, cnt++, urb);
730 }
731 info = usb_pipeout (pipe)?
732 TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
733 td_fill (ohci, info, data, 0, dev, cnt++, urb);
734 if (!ohci->sleeping)
735 writel (OHCI_CLF, &ohci->regs->cmdstatus);
736 break;
737 }
738 if (urb->length != cnt)
739 dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
740}
741
742
743
744
745
746
747
748
749static void dl_transfer_length(td_t * td)
750{
751 __u32 tdBE, tdCBP;
752 urb_priv_t *lurb_priv = &urb_priv;
753
754 tdBE = ohci_cpu_to_le32 (td->hwBE);
755 tdCBP = ohci_cpu_to_le32 (td->hwCBP);
756
757
758 if (!(usb_pipecontrol(lurb_priv->pipe) &&
759 ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
760 if (tdBE != 0) {
761 if (td->hwCBP == 0)
762 lurb_priv->actual_length += tdBE - td->data + 1;
763 else
764 lurb_priv->actual_length += tdCBP - td->data;
765 }
766 }
767}
768
769
770
771
772
773
774static td_t * dl_reverse_done_list (ohci_t *ohci)
775{
776 __u32 td_list_hc;
777 td_t *td_rev = NULL;
778 td_t *td_list = NULL;
779 urb_priv_t *lurb_priv = NULL;
780
781 td_list_hc = ohci_cpu_to_le32 (ohci->hcca->done_head) & 0xfffffff0;
782 ohci->hcca->done_head = 0;
783
784 while (td_list_hc) {
785 td_list = (td_t *)td_list_hc;
786
787 if (TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO))) {
788 lurb_priv = &urb_priv;
789 dbg(" USB-error/status: %x : %p",
790 TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO)), td_list);
791 if (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x1)) {
792 if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
793 td_list->ed->hwHeadP =
794 (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & ohci_cpu_to_le32 (0xfffffff0)) |
795 (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x2));
796 lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
797 } else
798 td_list->ed->hwHeadP &= ohci_cpu_to_le32 (0xfffffff2);
799 }
800 td_list->hwNextTD = 0;
801 }
802
803 td_list->next_dl_td = td_rev;
804 td_rev = td_list;
805 td_list_hc = ohci_cpu_to_le32 (td_list->hwNextTD) & 0xfffffff0;
806 }
807 return td_list;
808}
809
810
811
812
813static int dl_done_list (ohci_t *ohci, td_t *td_list)
814{
815 td_t *td_list_next = NULL;
816 ed_t *ed;
817 int cc = 0;
818 int stat = 0;
819
820 urb_priv_t *lurb_priv;
821 __u32 tdINFO, edHeadP, edTailP;
822
823 while (td_list) {
824 td_list_next = td_list->next_dl_td;
825
826 lurb_priv = &urb_priv;
827 tdINFO = ohci_cpu_to_le32 (td_list->hwINFO);
828
829 ed = td_list->ed;
830
831 dl_transfer_length(td_list);
832
833
834 cc = TD_CC_GET (tdINFO);
835 if (++(lurb_priv->td_cnt) == lurb_priv->length) {
836 if ((ed->state & (ED_OPER | ED_UNLINK))
837 && (lurb_priv->state != URB_DEL)) {
838 dbg("ConditionCode %#x", cc);
839 stat = cc_to_error[cc];
840 urb_finished = 1;
841 }
842 }
843
844 if (ed->state != ED_NEW) {
845 edHeadP = ohci_cpu_to_le32 (ed->hwHeadP) & 0xfffffff0;
846 edTailP = ohci_cpu_to_le32 (ed->hwTailP);
847
848
849 if ((edHeadP == edTailP) && (ed->state == ED_OPER))
850 ep_unlink (ohci, ed);
851 }
852
853 td_list = td_list_next;
854 }
855 return stat;
856}
857
858
859
860
861
862
863static __u8 root_hub_dev_des[] =
864{
865 0x12,
866 0x01,
867 0x10,
868 0x01,
869 0x09,
870 0x00,
871 0x00,
872 0x08,
873 0x00,
874 0x00,
875 0x00,
876 0x00,
877 0x00,
878 0x00,
879 0x00,
880 0x01,
881 0x00,
882 0x01
883};
884
885
886
887static __u8 root_hub_config_des[] =
888{
889 0x09,
890 0x02,
891 0x19,
892 0x00,
893 0x01,
894 0x01,
895 0x00,
896 0x40,
897
898 0x00,
899
900
901 0x09,
902 0x04,
903 0x00,
904 0x00,
905 0x01,
906 0x09,
907 0x00,
908 0x00,
909 0x00,
910
911
912 0x07,
913 0x05,
914 0x81,
915 0x03,
916 0x02,
917 0x00,
918 0xff
919};
920
921static unsigned char root_hub_str_index0[] =
922{
923 0x04,
924 0x03,
925 0x09,
926 0x04,
927};
928
929static unsigned char root_hub_str_index1[] =
930{
931 28,
932 0x03,
933 'O',
934 0,
935 'H',
936 0,
937 'C',
938 0,
939 'I',
940 0,
941 ' ',
942 0,
943 'R',
944 0,
945 'o',
946 0,
947 'o',
948 0,
949 't',
950 0,
951 ' ',
952 0,
953 'H',
954 0,
955 'u',
956 0,
957 'b',
958 0,
959};
960
961
962
963
964
965
966#define OK(x) len = (x); break
967#ifdef DEBUG
968#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
969#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
970#else
971#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status)
972#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
973#endif
974#define RD_RH_STAT roothub_status(&gohci)
975#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1)
976
977
978
979int rh_check_port_status(ohci_t *controller)
980{
981 __u32 temp, ndp, i;
982 int res;
983
984 res = -1;
985 temp = roothub_a (controller);
986 ndp = (temp & RH_A_NDP);
987 for (i = 0; i < ndp; i++) {
988 temp = roothub_portstatus (controller, i);
989
990 if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
991 (RH_PS_PESC | RH_PS_CSC)) &&
992 ((temp & RH_PS_CCS) == 0)) {
993 res = i;
994 break;
995 }
996 }
997 return res;
998}
999
1000static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
1001 void *buffer, int transfer_len, struct devrequest *cmd)
1002{
1003 void * data = buffer;
1004 int leni = transfer_len;
1005 int len = 0;
1006 int stat = 0;
1007 __u32 datab[4];
1008 __u8 *data_buf = (__u8 *)datab;
1009 __u16 bmRType_bReq;
1010 __u16 wValue;
1011 __u16 wIndex;
1012 __u16 wLength;
1013
1014#ifdef DEBUG
1015urb_priv.actual_length = 0;
1016pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
1017#endif
1018 if (usb_pipeint(pipe)) {
1019 info("Root-Hub submit IRQ: NOT implemented");
1020 return 0;
1021 }
1022
1023 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
1024 wValue = m16_swap (cmd->value);
1025 wIndex = m16_swap (cmd->index);
1026 wLength = m16_swap (cmd->length);
1027
1028 info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
1029 dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
1030
1031 switch (bmRType_bReq) {
1032
1033
1034
1035
1036
1037
1038
1039
1040 case RH_GET_STATUS:
1041 *(__u16 *) data_buf = m16_swap (1); OK (2);
1042 case RH_GET_STATUS | RH_INTERFACE:
1043 *(__u16 *) data_buf = m16_swap (0); OK (2);
1044 case RH_GET_STATUS | RH_ENDPOINT:
1045 *(__u16 *) data_buf = m16_swap (0); OK (2);
1046 case RH_GET_STATUS | RH_CLASS:
1047 *(__u32 *) data_buf = m32_swap (
1048 RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
1049 OK (4);
1050 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
1051 *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4);
1052
1053 case RH_CLEAR_FEATURE | RH_ENDPOINT:
1054 switch (wValue) {
1055 case (RH_ENDPOINT_STALL): OK (0);
1056 }
1057 break;
1058
1059 case RH_CLEAR_FEATURE | RH_CLASS:
1060 switch (wValue) {
1061 case RH_C_HUB_LOCAL_POWER:
1062 OK(0);
1063 case (RH_C_HUB_OVER_CURRENT):
1064 WR_RH_STAT(RH_HS_OCIC); OK (0);
1065 }
1066 break;
1067
1068 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
1069 switch (wValue) {
1070 case (RH_PORT_ENABLE):
1071 WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
1072 case (RH_PORT_SUSPEND):
1073 WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
1074 case (RH_PORT_POWER):
1075 WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
1076 case (RH_C_PORT_CONNECTION):
1077 WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
1078 case (RH_C_PORT_ENABLE):
1079 WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
1080 case (RH_C_PORT_SUSPEND):
1081 WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
1082 case (RH_C_PORT_OVER_CURRENT):
1083 WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
1084 case (RH_C_PORT_RESET):
1085 WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
1086 }
1087 break;
1088
1089 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
1090 switch (wValue) {
1091 case (RH_PORT_SUSPEND):
1092 WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
1093 case (RH_PORT_RESET):
1094 if (RD_RH_PORTSTAT & RH_PS_CCS)
1095 WR_RH_PORTSTAT (RH_PS_PRS);
1096 OK (0);
1097 case (RH_PORT_POWER):
1098 WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
1099 case (RH_PORT_ENABLE):
1100 if (RD_RH_PORTSTAT & RH_PS_CCS)
1101 WR_RH_PORTSTAT (RH_PS_PES );
1102 OK (0);
1103 }
1104 break;
1105
1106 case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
1107
1108 case RH_GET_DESCRIPTOR:
1109 switch ((wValue & 0xff00) >> 8) {
1110 case (0x01):
1111 len = min_t(unsigned int,
1112 leni,
1113 min_t(unsigned int,
1114 sizeof (root_hub_dev_des),
1115 wLength));
1116 data_buf = root_hub_dev_des; OK(len);
1117 case (0x02):
1118 len = min_t(unsigned int,
1119 leni,
1120 min_t(unsigned int,
1121 sizeof (root_hub_config_des),
1122 wLength));
1123 data_buf = root_hub_config_des; OK(len);
1124 case (0x03):
1125 if(wValue==0x0300) {
1126 len = min_t(unsigned int,
1127 leni,
1128 min_t(unsigned int,
1129 sizeof (root_hub_str_index0),
1130 wLength));
1131 data_buf = root_hub_str_index0;
1132 OK(len);
1133 }
1134 if(wValue==0x0301) {
1135 len = min_t(unsigned int,
1136 leni,
1137 min_t(unsigned int,
1138 sizeof (root_hub_str_index1),
1139 wLength));
1140 data_buf = root_hub_str_index1;
1141 OK(len);
1142 }
1143 default:
1144 stat = USB_ST_STALLED;
1145 }
1146 break;
1147
1148 case RH_GET_DESCRIPTOR | RH_CLASS:
1149 {
1150 __u32 temp = roothub_a (&gohci);
1151
1152 data_buf [0] = 9;
1153 data_buf [1] = 0x29;
1154 data_buf [2] = temp & RH_A_NDP;
1155 data_buf [3] = 0;
1156 if (temp & RH_A_PSM)
1157 data_buf [3] |= 0x1;
1158 if (temp & RH_A_NOCP)
1159 data_buf [3] |= 0x10;
1160 else if (temp & RH_A_OCPM)
1161 data_buf [3] |= 0x8;
1162
1163
1164 datab [1] = 0;
1165 data_buf [5] = (temp & RH_A_POTPGT) >> 24;
1166 temp = roothub_b (&gohci);
1167 data_buf [7] = temp & RH_B_DR;
1168 if (data_buf [2] < 7) {
1169 data_buf [8] = 0xff;
1170 } else {
1171 data_buf [0] += 2;
1172 data_buf [8] = (temp & RH_B_DR) >> 8;
1173 data_buf [10] = data_buf [9] = 0xff;
1174 }
1175
1176 len = min_t(unsigned int, leni,
1177 min_t(unsigned int, data_buf [0], wLength));
1178 OK (len);
1179 }
1180
1181 case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1);
1182
1183 case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0);
1184
1185 default:
1186 dbg ("unsupported root hub command");
1187 stat = USB_ST_STALLED;
1188 }
1189
1190#ifdef DEBUG
1191 ohci_dump_roothub (&gohci, 1);
1192#endif
1193
1194 len = min_t(int, len, leni);
1195 if (data != data_buf)
1196 memcpy (data, data_buf, len);
1197 dev->act_len = len;
1198 dev->status = stat;
1199
1200#ifdef DEBUG
1201 if (transfer_len)
1202 urb_priv.actual_length = transfer_len;
1203 pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0);
1204#endif
1205
1206 return stat;
1207}
1208
1209
1210
1211
1212
1213int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1214 int transfer_len, struct devrequest *setup, int interval)
1215{
1216 int stat = 0;
1217 int maxsize = usb_maxpacket(dev, pipe);
1218 int timeout;
1219
1220
1221 if (devgone == dev) {
1222 dev->status = USB_ST_CRC_ERR;
1223 return 0;
1224 }
1225
1226#ifdef DEBUG
1227 urb_priv.actual_length = 0;
1228 pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
1229#endif
1230 if (!maxsize) {
1231 err("submit_common_message: pipesize for pipe %lx is zero",
1232 pipe);
1233 return -1;
1234 }
1235
1236 if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) {
1237 err("sohci_submit_job failed");
1238 return -1;
1239 }
1240
1241
1242#define BULK_TO 5000
1243 if (usb_pipebulk(pipe))
1244 timeout = BULK_TO;
1245 else
1246 timeout = 100;
1247
1248
1249 for (;;) {
1250
1251 stat = hc_interrupt();
1252 if (stat < 0) {
1253 stat = USB_ST_CRC_ERR;
1254 break;
1255 }
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266 if ((stat >= 0) && (stat != 0xff) && (urb_finished)) {
1267
1268 break;
1269 }
1270
1271 if (--timeout) {
1272 wait_ms(1);
1273 if (!urb_finished)
1274 dbg("\%");
1275
1276 } else {
1277 err("CTL:TIMEOUT ");
1278 dbg("submit_common_msg: TO status %x\n", stat);
1279 stat = USB_ST_CRC_ERR;
1280 urb_finished = 1;
1281 break;
1282 }
1283 }
1284#if 0
1285
1286 if (got_rhsc) {
1287#ifdef DEBUG
1288 ohci_dump_roothub (&gohci, 1);
1289#endif
1290 got_rhsc = 0;
1291
1292 timeout = rh_check_port_status(&gohci);
1293 if (timeout >= 0) {
1294#if 0
1295
1296 usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
1297#endif
1298
1299
1300
1301
1302
1303 devgone = dev;
1304 }
1305 }
1306#endif
1307
1308 dev->status = stat;
1309 dev->act_len = transfer_len;
1310
1311#ifdef DEBUG
1312 pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
1313#endif
1314
1315
1316 urb_free_priv (&urb_priv);
1317 return 0;
1318}
1319
1320
1321int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1322 int transfer_len)
1323{
1324 info("submit_bulk_msg");
1325 return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
1326}
1327
1328int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1329 int transfer_len, struct devrequest *setup)
1330{
1331 int maxsize = usb_maxpacket(dev, pipe);
1332
1333 info("submit_control_msg");
1334#ifdef DEBUG
1335 urb_priv.actual_length = 0;
1336 pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
1337#endif
1338 if (!maxsize) {
1339 err("submit_control_message: pipesize for pipe %lx is zero",
1340 pipe);
1341 return -1;
1342 }
1343 if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
1344 gohci.rh.dev = dev;
1345
1346 return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
1347 setup);
1348 }
1349
1350 return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
1351}
1352
1353int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1354 int transfer_len, int interval)
1355{
1356 info("submit_int_msg");
1357 return -1;
1358}
1359
1360
1361
1362
1363
1364
1365
1366static int hc_reset (ohci_t *ohci)
1367{
1368 int timeout = 30;
1369 int smm_timeout = 50;
1370
1371 if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
1372 writel (OHCI_OCR, &ohci->regs->cmdstatus);
1373 info("USB HC TakeOver from SMM");
1374 while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
1375 wait_ms (10);
1376 if (--smm_timeout == 0) {
1377 err("USB HC TakeOver failed!");
1378 return -1;
1379 }
1380 }
1381 }
1382
1383
1384 writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
1385
1386 dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",
1387 ohci->slot_name,
1388 readl (&ohci->regs->control));
1389
1390
1391 ohci->hc_control = 0;
1392 writel (ohci->hc_control, &ohci->regs->control);
1393
1394
1395 writel (OHCI_HCR, &ohci->regs->cmdstatus);
1396 while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
1397 if (--timeout == 0) {
1398 err("USB HC reset timed out!");
1399 return -1;
1400 }
1401 udelay (1);
1402 }
1403 return 0;
1404}
1405
1406
1407
1408
1409
1410
1411
1412static int hc_start (ohci_t * ohci)
1413{
1414 __u32 mask;
1415 unsigned int fminterval;
1416
1417 ohci->disabled = 1;
1418
1419
1420
1421
1422 writel (0, &ohci->regs->ed_controlhead);
1423 writel (0, &ohci->regs->ed_bulkhead);
1424
1425 writel ((__u32)ohci->hcca, &ohci->regs->hcca);
1426
1427 fminterval = 0x2edf;
1428 writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
1429 fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
1430 writel (fminterval, &ohci->regs->fminterval);
1431 writel (0x628, &ohci->regs->lsthresh);
1432
1433
1434 ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
1435 ohci->disabled = 0;
1436 writel (ohci->hc_control, &ohci->regs->control);
1437
1438
1439 mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
1440 OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
1441 OHCI_INTR_OC | OHCI_INTR_MIE);
1442 writel (mask, &ohci->regs->intrdisable);
1443
1444 mask &= ~OHCI_INTR_MIE;
1445 writel (mask, &ohci->regs->intrstatus);
1446
1447 mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
1448 writel (mask, &ohci->regs->intrenable);
1449
1450#ifdef OHCI_USE_NPS
1451
1452 writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
1453 &ohci->regs->roothub.a);
1454 writel (RH_HS_LPSC, &ohci->regs->roothub.status);
1455#endif
1456
1457
1458 mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
1459
1460
1461 ohci->rh.devnum = 0;
1462
1463 return 0;
1464}
1465
1466
1467
1468
1469
1470static int
1471hc_interrupt (void)
1472{
1473 ohci_t *ohci = &gohci;
1474 struct ohci_regs *regs = ohci->regs;
1475 int ints;
1476 int stat = -1;
1477
1478 if ((ohci->hcca->done_head != 0) &&
1479 !(ohci_cpu_to_le32(ohci->hcca->done_head) & 0x01)) {
1480
1481 ints = OHCI_INTR_WDH;
1482
1483 } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) {
1484 ohci->disabled++;
1485 err ("%s device removed!", ohci->slot_name);
1486 return -1;
1487
1488 } else if ((ints &= readl (®s->intrenable)) == 0) {
1489 dbg("hc_interrupt: returning..\n");
1490 return 0xff;
1491 }
1492
1493
1494
1495 if (ints & OHCI_INTR_RHSC) {
1496 got_rhsc = 1;
1497 stat = 0xff;
1498 }
1499
1500 if (ints & OHCI_INTR_UE) {
1501 ohci->disabled++;
1502 err ("OHCI Unrecoverable Error, controller usb-%s disabled",
1503 ohci->slot_name);
1504
1505
1506#ifdef DEBUG
1507 ohci_dump (ohci, 1);
1508#endif
1509
1510
1511
1512
1513 hc_reset (ohci);
1514 return -1;
1515 }
1516
1517 if (ints & OHCI_INTR_WDH) {
1518 writel (OHCI_INTR_WDH, ®s->intrdisable);
1519 stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
1520 writel (OHCI_INTR_WDH, ®s->intrenable);
1521 }
1522
1523 if (ints & OHCI_INTR_SO) {
1524 dbg("USB Schedule overrun\n");
1525 writel (OHCI_INTR_SO, ®s->intrenable);
1526 stat = -1;
1527 }
1528
1529
1530 if (ints & OHCI_INTR_SF) {
1531 unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1;
1532 wait_ms(1);
1533 writel (OHCI_INTR_SF, ®s->intrdisable);
1534 if (ohci->ed_rm_list[frame] != NULL)
1535 writel (OHCI_INTR_SF, ®s->intrenable);
1536 stat = 0xff;
1537 }
1538
1539 writel (ints, ®s->intrstatus);
1540 return stat;
1541}
1542
1543
1544
1545
1546
1547
1548
1549static void hc_release_ohci (ohci_t *ohci)
1550{
1551 dbg ("USB HC release ohci usb-%s", ohci->slot_name);
1552
1553 if (!ohci->disabled)
1554 hc_reset (ohci);
1555}
1556
1557
1558
1559
1560
1561
1562static char ohci_inited = 0;
1563
1564int usb_lowlevel_init(void)
1565{
1566
1567
1568 *(vu_long *)MPC5XXX_CDM_48_FDC = CONFIG_USB_CLOCK;
1569
1570#ifdef CONFIG_PSC3_USB
1571
1572 *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00804f00;
1573#else
1574
1575 *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00807000;
1576#endif
1577
1578 *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= CONFIG_USB_CONFIG;
1579
1580 memset (&gohci, 0, sizeof (ohci_t));
1581 memset (&urb_priv, 0, sizeof (urb_priv_t));
1582
1583
1584 if ((__u32)&ghcca[0] & 0xff) {
1585 err("HCCA not aligned!!");
1586 return -1;
1587 }
1588 phcca = &ghcca[0];
1589 info("aligned ghcca %p", phcca);
1590 memset(&ohci_dev, 0, sizeof(struct ohci_device));
1591 if ((__u32)&ohci_dev.ed[0] & 0x7) {
1592 err("EDs not aligned!!");
1593 return -1;
1594 }
1595 memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
1596 if ((__u32)gtd & 0x7) {
1597 err("TDs not aligned!!");
1598 return -1;
1599 }
1600 ptd = gtd;
1601 gohci.hcca = phcca;
1602 memset (phcca, 0, sizeof (struct ohci_hcca));
1603
1604 gohci.disabled = 1;
1605 gohci.sleeping = 0;
1606 gohci.irq = -1;
1607 gohci.regs = (struct ohci_regs *)MPC5XXX_USB;
1608
1609 gohci.flags = 0;
1610 gohci.slot_name = "mpc5200";
1611
1612 if (hc_reset (&gohci) < 0) {
1613 hc_release_ohci (&gohci);
1614 return -1;
1615 }
1616
1617 if (hc_start (&gohci) < 0) {
1618 err ("can't start usb-%s", gohci.slot_name);
1619 hc_release_ohci (&gohci);
1620 return -1;
1621 }
1622
1623#ifdef DEBUG
1624 ohci_dump (&gohci, 1);
1625#endif
1626 ohci_inited = 1;
1627 urb_finished = 1;
1628
1629 return 0;
1630}
1631
1632int usb_lowlevel_stop(void)
1633{
1634
1635
1636 if (!ohci_inited)
1637 return 0;
1638
1639
1640 hc_reset (&gohci);
1641 return 0;
1642}
1643
1644#endif
1645