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