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