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