1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58#include <common.h>
59#include <asm/io.h>
60#include <usb.h>
61#include <malloc.h>
62#include <linux/list.h>
63
64
65
66
67
68
69
70
71
72
73#ifdef ISP116X_HCD_USE_UDELAY
74#define UDELAY 1
75#endif
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96#ifdef ISP116X_HCD_USE_EXTRA_DELAY
97#define EXTRA_DELAY 2
98#endif
99
100
101
102
103#undef DEBUG
104#undef TRACE
105#undef VERBOSE
106
107#include "isp116x.h"
108
109#define DRIVER_VERSION "08 Jan 2007"
110static const char hcd_name[] = "isp116x-hcd";
111
112struct isp116x isp116x_dev;
113struct isp116x_platform_data isp116x_board;
114static int got_rhsc;
115struct usb_device *devgone;
116static int rh_devnum;
117
118
119
120#define ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL))
121#define min_t(type,x,y) \
122 ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; })
123
124
125
126static int isp116x_reset(struct isp116x *isp116x);
127
128
129
130#define isp116x_show_reg(d, r) { \
131 if ((r) < 0x20) { \
132 DBG("%-12s[%02x]: %08x", #r, \
133 r, isp116x_read_reg32(d, r)); \
134 } else { \
135 DBG("%-12s[%02x]: %04x", #r, \
136 r, isp116x_read_reg16(d, r)); \
137 } \
138}
139
140#define isp116x_show_regs(d) { \
141 isp116x_show_reg(d, HCREVISION); \
142 isp116x_show_reg(d, HCCONTROL); \
143 isp116x_show_reg(d, HCCMDSTAT); \
144 isp116x_show_reg(d, HCINTSTAT); \
145 isp116x_show_reg(d, HCINTENB); \
146 isp116x_show_reg(d, HCFMINTVL); \
147 isp116x_show_reg(d, HCFMREM); \
148 isp116x_show_reg(d, HCFMNUM); \
149 isp116x_show_reg(d, HCLSTHRESH); \
150 isp116x_show_reg(d, HCRHDESCA); \
151 isp116x_show_reg(d, HCRHDESCB); \
152 isp116x_show_reg(d, HCRHSTATUS); \
153 isp116x_show_reg(d, HCRHPORT1); \
154 isp116x_show_reg(d, HCRHPORT2); \
155 isp116x_show_reg(d, HCHWCFG); \
156 isp116x_show_reg(d, HCDMACFG); \
157 isp116x_show_reg(d, HCXFERCTR); \
158 isp116x_show_reg(d, HCuPINT); \
159 isp116x_show_reg(d, HCuPINTENB); \
160 isp116x_show_reg(d, HCCHIPID); \
161 isp116x_show_reg(d, HCSCRATCH); \
162 isp116x_show_reg(d, HCITLBUFLEN); \
163 isp116x_show_reg(d, HCATLBUFLEN); \
164 isp116x_show_reg(d, HCBUFSTAT); \
165 isp116x_show_reg(d, HCRDITL0LEN); \
166 isp116x_show_reg(d, HCRDITL1LEN); \
167}
168
169#if defined(TRACE)
170
171static int isp116x_get_current_frame_number(struct usb_device *usb_dev)
172{
173 struct isp116x *isp116x = &isp116x_dev;
174
175 return isp116x_read_reg32(isp116x, HCFMNUM);
176}
177
178static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
179 int len, char *str)
180{
181#if defined(VERBOSE)
182 int i;
183#endif
184
185 DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
186 str,
187 isp116x_get_current_frame_number(dev),
188 usb_pipedevice(pipe),
189 usb_pipeendpoint(pipe),
190 usb_pipeout(pipe) ? 'O' : 'I',
191 usb_pipetype(pipe) < 2 ?
192 (usb_pipeint(pipe) ?
193 "INTR" : "ISOC") :
194 (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
195#if defined(VERBOSE)
196 if (len > 0 && buffer) {
197 printf(__FILE__ ": data(%d):", len);
198 for (i = 0; i < 16 && i < len; i++)
199 printf(" %02x", ((__u8 *) buffer)[i]);
200 printf("%s\n", i < len ? "..." : "");
201 }
202#endif
203}
204
205#define PTD_DIR_STR(ptd) ({char __c; \
206 switch(PTD_GET_DIR(ptd)){ \
207 case 0: __c = 's'; break; \
208 case 1: __c = 'o'; break; \
209 default: __c = 'i'; break; \
210 }; __c;})
211
212
213
214
215
216static inline void dump_ptd(struct ptd *ptd)
217{
218#if defined(VERBOSE)
219 int k;
220#endif
221
222 DBG("PTD(ext) : cc:%x %d%c%d %d,%d,%d t:%x %x%x%x",
223 PTD_GET_CC(ptd),
224 PTD_GET_FA(ptd), PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
225 PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
226 PTD_GET_TOGGLE(ptd),
227 PTD_GET_ACTIVE(ptd), PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
228#if defined(VERBOSE)
229 printf("isp116x: %s: PTD(byte): ", __FUNCTION__);
230 for (k = 0; k < sizeof(struct ptd); ++k)
231 printf("%02x ", ((u8 *) ptd)[k]);
232 printf("\n");
233#endif
234}
235
236static inline void dump_ptd_data(struct ptd *ptd, u8 * buf, int type)
237{
238#if defined(VERBOSE)
239 int k;
240
241 if (type == 0 ) {
242 printf("isp116x: %s: out data: ", __FUNCTION__);
243 for (k = 0; k < PTD_GET_LEN(ptd); ++k)
244 printf("%02x ", ((u8 *) buf)[k]);
245 printf("\n");
246 }
247 if (type == 1 ) {
248 printf("isp116x: %s: in data: ", __FUNCTION__);
249 for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
250 printf("%02x ", ((u8 *) buf)[k]);
251 printf("\n");
252 }
253
254 if (PTD_GET_LAST(ptd))
255 DBG("--- last PTD ---");
256#endif
257}
258
259#else
260
261#define dump_msg(dev, pipe, buffer, len, str) do { } while (0)
262#define dump_pkt(dev, pipe, buffer, len, setup, str, small) do {} while (0)
263
264#define dump_ptd(ptd) do {} while (0)
265#define dump_ptd_data(ptd, buf, type) do {} while (0)
266
267#endif
268
269
270
271
272static __u8 root_hub_dev_des[] = {
273 0x12,
274 0x01,
275 0x10,
276 0x01,
277 0x09,
278 0x00,
279 0x00,
280 0x08,
281 0x00,
282 0x00,
283 0x00,
284 0x00,
285 0x00,
286 0x00,
287 0x00,
288 0x01,
289 0x00,
290 0x01
291};
292
293
294static __u8 root_hub_config_des[] = {
295 0x09,
296 0x02,
297 0x19,
298 0x00,
299 0x01,
300 0x01,
301 0x00,
302 0x40,
303
304 0x00,
305
306
307 0x09,
308 0x04,
309 0x00,
310 0x00,
311 0x01,
312 0x09,
313 0x00,
314 0x00,
315 0x00,
316
317
318 0x07,
319 0x05,
320 0x81,
321 0x03,
322 0x00,
323 0x02,
324 0xff
325};
326
327static unsigned char root_hub_str_index0[] = {
328 0x04,
329 0x03,
330 0x09,
331 0x04,
332};
333
334static unsigned char root_hub_str_index1[] = {
335 0x22,
336 0x03,
337 'I',
338 0,
339 'S',
340 0,
341 'P',
342 0,
343 '1',
344 0,
345 '1',
346 0,
347 '6',
348 0,
349 'x',
350 0,
351 ' ',
352 0,
353 'R',
354 0,
355 'o',
356 0,
357 'o',
358 0,
359 't',
360 0,
361 ' ',
362 0,
363 'H',
364 0,
365 'u',
366 0,
367 'b',
368 0,
369};
370
371
372
373
374
375
376
377static int rh_check_port_status(struct isp116x *isp116x)
378{
379 u32 temp, ndp, i;
380 int res;
381
382 res = -1;
383 temp = isp116x_read_reg32(isp116x, HCRHSTATUS);
384 ndp = (temp & RH_A_NDP);
385 for (i = 0; i < ndp; i++) {
386 temp = isp116x_read_reg32(isp116x, HCRHPORT1 + i);
387
388 if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
389 (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
390 res = i;
391 break;
392 }
393 }
394 return res;
395}
396
397
398
399
400
401static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
402{
403 u8 *dp = (u8 *) buf;
404 u16 *dp2 = (u16 *) buf;
405 u16 w;
406 int quot = len % 4;
407
408 if ((unsigned long)dp2 & 1) {
409
410 for (; len > 1; len -= 2) {
411 w = *dp++;
412 w |= *dp++ << 8;
413 isp116x_raw_write_data16(isp116x, w);
414 }
415 if (len)
416 isp116x_write_data16(isp116x, (u16) * dp);
417 } else {
418
419 for (; len > 1; len -= 2)
420 isp116x_raw_write_data16(isp116x, *dp2++);
421 if (len)
422 isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
423 }
424 if (quot == 1 || quot == 2)
425 isp116x_raw_write_data16(isp116x, 0);
426}
427
428
429
430static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
431{
432 u8 *dp = (u8 *) buf;
433 u16 *dp2 = (u16 *) buf;
434 u16 w;
435 int quot = len % 4;
436
437 if ((unsigned long)dp2 & 1) {
438
439 for (; len > 1; len -= 2) {
440 w = isp116x_raw_read_data16(isp116x);
441 *dp++ = w & 0xff;
442 *dp++ = (w >> 8) & 0xff;
443 }
444 if (len)
445 *dp = 0xff & isp116x_read_data16(isp116x);
446 } else {
447
448 for (; len > 1; len -= 2)
449 *dp2++ = isp116x_raw_read_data16(isp116x);
450 if (len)
451 *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
452 }
453 if (quot == 1 || quot == 2)
454 isp116x_raw_read_data16(isp116x);
455}
456
457
458
459static void pack_fifo(struct isp116x *isp116x, struct usb_device *dev,
460 unsigned long pipe, struct ptd *ptd, int n, void *data,
461 int len)
462{
463 int buflen = n * sizeof(struct ptd) + len;
464 int i, done;
465
466 DBG("--- pack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
467
468 isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
469 isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
470 isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
471
472 done = 0;
473 for (i = 0; i < n; i++) {
474 DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
475
476 dump_ptd(&ptd[i]);
477 isp116x_write_data16(isp116x, ptd[i].count);
478 isp116x_write_data16(isp116x, ptd[i].mps);
479 isp116x_write_data16(isp116x, ptd[i].len);
480 isp116x_write_data16(isp116x, ptd[i].faddr);
481
482 dump_ptd_data(&ptd[i], (__u8 *) data + done, 0);
483 write_ptddata_to_fifo(isp116x,
484 (__u8 *) data + done,
485 PTD_GET_LEN(&ptd[i]));
486
487 done += PTD_GET_LEN(&ptd[i]);
488 }
489}
490
491
492
493static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
494 unsigned long pipe, struct ptd *ptd, int n, void *data,
495 int len)
496{
497 int buflen = n * sizeof(struct ptd) + len;
498 int i, done, cc, ret;
499
500 isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
501 isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
502 isp116x_write_addr(isp116x, HCATLPORT);
503
504 ret = TD_CC_NOERROR;
505 done = 0;
506 for (i = 0; i < n; i++) {
507 DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
508
509 ptd[i].count = isp116x_read_data16(isp116x);
510 ptd[i].mps = isp116x_read_data16(isp116x);
511 ptd[i].len = isp116x_read_data16(isp116x);
512 ptd[i].faddr = isp116x_read_data16(isp116x);
513 dump_ptd(&ptd[i]);
514
515 read_ptddata_from_fifo(isp116x,
516 (__u8 *) data + done,
517 PTD_GET_LEN(&ptd[i]));
518 dump_ptd_data(&ptd[i], (__u8 *) data + done, 1);
519
520 done += PTD_GET_LEN(&ptd[i]);
521
522 cc = PTD_GET_CC(&ptd[i]);
523
524
525
526
527
528 if (cc == TD_NOTACCESSED ||
529 (cc != TD_CC_NOERROR && (ret == TD_CC_NOERROR || ret == TD_DATAUNDERRUN)))
530 ret = cc;
531 }
532
533 DBG("--- unpack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
534
535 return ret;
536}
537
538
539
540static int isp116x_interrupt(struct isp116x *isp116x)
541{
542 u16 irqstat;
543 u32 intstat;
544 int ret = 0;
545
546 isp116x_write_reg16(isp116x, HCuPINTENB, 0);
547 irqstat = isp116x_read_reg16(isp116x, HCuPINT);
548 isp116x_write_reg16(isp116x, HCuPINT, irqstat);
549 DBG(">>>>>> irqstat %x <<<<<<", irqstat);
550
551 if (irqstat & HCuPINT_ATL) {
552 DBG(">>>>>> HCuPINT_ATL <<<<<<");
553 udelay(500);
554 ret = 1;
555 }
556
557 if (irqstat & HCuPINT_OPR) {
558 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
559 isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
560 DBG(">>>>>> HCuPINT_OPR %x <<<<<<", intstat);
561
562 if (intstat & HCINT_UE) {
563 ERR("unrecoverable error, controller disabled");
564
565
566
567
568
569
570 isp116x_reset(isp116x);
571 ret = -1;
572 return -1;
573 }
574
575 if (intstat & HCINT_RHSC) {
576 got_rhsc = 1;
577 ret = 1;
578
579
580
581 mdelay(20);
582 }
583
584 if (intstat & HCINT_SO) {
585 ERR("schedule overrun");
586 ret = -1;
587 }
588
589 irqstat &= ~HCuPINT_OPR;
590 }
591
592 return ret;
593}
594
595
596
597
598struct ptd ptd[1];
599
600static inline int max_transfer_len(struct usb_device *dev, unsigned long pipe)
601{
602 unsigned mpck = usb_maxpacket(dev, pipe);
603
604
605
606
607 return 1023 / mpck * mpck;
608}
609
610
611
612static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
613 int dir, void *buffer, int len)
614{
615 struct isp116x *isp116x = &isp116x_dev;
616 int type = usb_pipetype(pipe);
617 int epnum = usb_pipeendpoint(pipe);
618 int max = usb_maxpacket(dev, pipe);
619 int dir_out = usb_pipeout(pipe);
620 int speed_low = usb_pipeslow(pipe);
621 int i, done = 0, stat, timeout, cc;
622
623
624 int retries = 500;
625
626 DBG("------------------------------------------------");
627 dump_msg(dev, pipe, buffer, len, "SUBMIT");
628 DBG("------------------------------------------------");
629
630 if (len >= 1024) {
631 ERR("Too big job");
632 dev->status = USB_ST_CRC_ERR;
633 return -1;
634 }
635
636 if (isp116x->disabled) {
637 ERR("EPIPE");
638 dev->status = USB_ST_CRC_ERR;
639 return -1;
640 }
641
642
643 if (devgone == dev) {
644 ERR("ENODEV");
645 dev->status = USB_ST_CRC_ERR;
646 return USB_ST_CRC_ERR;
647 }
648
649 if (!max) {
650 ERR("pipesize for pipe %lx is zero", pipe);
651 dev->status = USB_ST_CRC_ERR;
652 return -1;
653 }
654
655 if (type == PIPE_ISOCHRONOUS) {
656 ERR("isochronous transfers not supported");
657 dev->status = USB_ST_CRC_ERR;
658 return -1;
659 }
660
661
662 if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) {
663 ERR("****** FIFO not empty! ******");
664 dev->status = USB_ST_BUF_ERR;
665 return -1;
666 }
667
668 retry:
669 isp116x_write_reg32(isp116x, HCINTSTAT, 0xff);
670
671
672 ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK |
673 PTD_TOGGLE(usb_gettoggle(dev, epnum, dir_out));
674 ptd->mps = PTD_MPS(max) | PTD_SPD(speed_low) | PTD_EP(epnum) | PTD_LAST_MSK;
675 ptd->len = PTD_LEN(len) | PTD_DIR(dir);
676 ptd->faddr = PTD_FA(usb_pipedevice(pipe));
677
678retry_same:
679
680 pack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
681#ifdef EXTRA_DELAY
682 mdelay(EXTRA_DELAY);
683#endif
684
685
686
687
688 if (usb_pipebulk(pipe))
689 timeout = 5000;
690 else
691 timeout = 100;
692
693
694 for (;;) {
695
696 stat = isp116x_interrupt(isp116x);
697
698 if (stat < 0) {
699 dev->status = USB_ST_CRC_ERR;
700 break;
701 }
702 if (stat > 0)
703 break;
704
705
706 if (--timeout)
707 udelay(1);
708 else {
709 ERR("CTL:TIMEOUT ");
710 stat = USB_ST_CRC_ERR;
711 break;
712 }
713 }
714
715
716 if (got_rhsc) {
717 isp116x_show_regs(isp116x);
718
719 got_rhsc = 0;
720
721
722 timeout = rh_check_port_status(isp116x);
723 if (timeout >= 0) {
724
725
726
727
728
729 devgone = dev;
730 }
731 }
732
733
734
735
736 if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) {
737 ERR("****** FIFO not ready! ******");
738 dev->status = USB_ST_BUF_ERR;
739 return -1;
740 }
741
742
743 cc = unpack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
744
745 i = PTD_GET_COUNT(ptd);
746 done += i;
747 buffer += i;
748 len -= i;
749
750
751
752
753 if (cc && cc != TD_NOTACCESSED && cc != TD_DATAUNDERRUN) {
754 if (retries >= 100) {
755 retries -= 100;
756
757
758
759 usb_settoggle(dev, epnum, dir_out, !PTD_GET_TOGGLE(ptd));
760 goto retry;
761 }
762 }
763
764
765
766
767
768
769 else if (cc == TD_NOTACCESSED || PTD_GET_ACTIVE(ptd) || (cc != TD_DATAUNDERRUN && PTD_GET_COUNT(ptd) < PTD_GET_LEN(ptd))) {
770 if (retries) {
771 --retries;
772 if (cc == TD_NOTACCESSED && PTD_GET_ACTIVE(ptd) && !PTD_GET_COUNT(ptd)) goto retry_same;
773 usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
774 goto retry;
775 }
776 }
777
778 if (cc != TD_CC_NOERROR && cc != TD_DATAUNDERRUN) {
779 DBG("****** completition code error %x ******", cc);
780 switch (cc) {
781 case TD_CC_BITSTUFFING:
782 dev->status = USB_ST_BIT_ERR;
783 break;
784 case TD_CC_STALL:
785 dev->status = USB_ST_STALLED;
786 break;
787 case TD_BUFFEROVERRUN:
788 case TD_BUFFERUNDERRUN:
789 dev->status = USB_ST_BUF_ERR;
790 break;
791 default:
792 dev->status = USB_ST_CRC_ERR;
793 }
794 return -cc;
795 }
796 else usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
797
798 dump_msg(dev, pipe, buffer, len, "SUBMIT(ret)");
799
800 dev->status = 0;
801 return done;
802}
803
804
805
806static int isp116x_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
807 void *buffer, int transfer_len,
808 struct devrequest *cmd)
809{
810 struct isp116x *isp116x = &isp116x_dev;
811 u32 tmp = 0;
812
813 int leni = transfer_len;
814 int len = 0;
815 int stat = 0;
816 u32 datab[4];
817 u8 *data_buf = (u8 *) datab;
818 u16 bmRType_bReq;
819 u16 wValue;
820 u16 wIndex;
821 u16 wLength;
822
823 if (usb_pipeint(pipe)) {
824 INFO("Root-Hub submit IRQ: NOT implemented");
825 return 0;
826 }
827
828 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
829 wValue = swap_16(cmd->value);
830 wIndex = swap_16(cmd->index);
831 wLength = swap_16(cmd->length);
832
833 DBG("--- HUB ----------------------------------------");
834 DBG("submit rh urb, req=%x val=%#x index=%#x len=%d",
835 bmRType_bReq, wValue, wIndex, wLength);
836 dump_msg(dev, pipe, buffer, transfer_len, "RH");
837 DBG("------------------------------------------------");
838
839 switch (bmRType_bReq) {
840 case RH_GET_STATUS:
841 DBG("RH_GET_STATUS");
842
843 *(__u16 *) data_buf = swap_16(1);
844 len = 2;
845 break;
846
847 case RH_GET_STATUS | RH_INTERFACE:
848 DBG("RH_GET_STATUS | RH_INTERFACE");
849
850 *(__u16 *) data_buf = swap_16(0);
851 len = 2;
852 break;
853
854 case RH_GET_STATUS | RH_ENDPOINT:
855 DBG("RH_GET_STATUS | RH_ENDPOINT");
856
857 *(__u16 *) data_buf = swap_16(0);
858 len = 2;
859 break;
860
861 case RH_GET_STATUS | RH_CLASS:
862 DBG("RH_GET_STATUS | RH_CLASS");
863
864 tmp = isp116x_read_reg32(isp116x, HCRHSTATUS);
865
866 *(__u32 *) data_buf = swap_32(tmp & ~(RH_HS_CRWE | RH_HS_DRWE));
867 len = 4;
868 break;
869
870 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
871 DBG("RH_GET_STATUS | RH_OTHER | RH_CLASS");
872
873 tmp = isp116x_read_reg32(isp116x, HCRHPORT1 + wIndex - 1);
874 *(__u32 *) data_buf = swap_32(tmp);
875 isp116x_show_regs(isp116x);
876 len = 4;
877 break;
878
879 case RH_CLEAR_FEATURE | RH_ENDPOINT:
880 DBG("RH_CLEAR_FEATURE | RH_ENDPOINT");
881
882 switch (wValue) {
883 case RH_ENDPOINT_STALL:
884 DBG("C_HUB_ENDPOINT_STALL");
885 len = 0;
886 break;
887 }
888 break;
889
890 case RH_CLEAR_FEATURE | RH_CLASS:
891 DBG("RH_CLEAR_FEATURE | RH_CLASS");
892
893 switch (wValue) {
894 case RH_C_HUB_LOCAL_POWER:
895 DBG("C_HUB_LOCAL_POWER");
896 len = 0;
897 break;
898
899 case RH_C_HUB_OVER_CURRENT:
900 DBG("C_HUB_OVER_CURRENT");
901 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
902 len = 0;
903 break;
904 }
905 break;
906
907 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
908 DBG("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS");
909
910 switch (wValue) {
911 case RH_PORT_ENABLE:
912 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
913 RH_PS_CCS);
914 len = 0;
915 break;
916
917 case RH_PORT_SUSPEND:
918 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
919 RH_PS_POCI);
920 len = 0;
921 break;
922
923 case RH_PORT_POWER:
924 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
925 RH_PS_LSDA);
926 len = 0;
927 break;
928
929 case RH_C_PORT_CONNECTION:
930 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
931 RH_PS_CSC);
932 len = 0;
933 break;
934
935 case RH_C_PORT_ENABLE:
936 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
937 RH_PS_PESC);
938 len = 0;
939 break;
940
941 case RH_C_PORT_SUSPEND:
942 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
943 RH_PS_PSSC);
944 len = 0;
945 break;
946
947 case RH_C_PORT_OVER_CURRENT:
948 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
949 RH_PS_POCI);
950 len = 0;
951 break;
952
953 case RH_C_PORT_RESET:
954 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
955 RH_PS_PRSC);
956 len = 0;
957 break;
958
959 default:
960 ERR("invalid wValue");
961 stat = USB_ST_STALLED;
962 }
963
964 isp116x_show_regs(isp116x);
965
966 break;
967
968 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
969 DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");
970
971 switch (wValue) {
972 case RH_PORT_SUSPEND:
973 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
974 RH_PS_PSS);
975 len = 0;
976 break;
977
978 case RH_PORT_RESET:
979
980 while (1) {
981 tmp =
982 isp116x_read_reg32(isp116x,
983 HCRHPORT1 + wIndex - 1);
984 if (!(tmp & RH_PS_PRS))
985 break;
986 mdelay(1);
987 }
988 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
989 RH_PS_PRS);
990 mdelay(10);
991
992 len = 0;
993 break;
994
995 case RH_PORT_POWER:
996 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
997 RH_PS_PPS);
998 len = 0;
999 break;
1000
1001 case RH_PORT_ENABLE:
1002 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
1003 RH_PS_PES);
1004 len = 0;
1005 break;
1006
1007 default:
1008 ERR("invalid wValue");
1009 stat = USB_ST_STALLED;
1010 }
1011
1012 isp116x_show_regs(isp116x);
1013
1014 break;
1015
1016 case RH_SET_ADDRESS:
1017 DBG("RH_SET_ADDRESS");
1018
1019 rh_devnum = wValue;
1020 len = 0;
1021 break;
1022
1023 case RH_GET_DESCRIPTOR:
1024 DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);
1025
1026 switch (wValue) {
1027 case (USB_DT_DEVICE << 8):
1028 len = min_t(unsigned int,
1029 leni, min_t(unsigned int,
1030 sizeof(root_hub_dev_des),
1031 wLength));
1032 data_buf = root_hub_dev_des;
1033 break;
1034
1035 case (USB_DT_CONFIG << 8):
1036 len = min_t(unsigned int,
1037 leni, min_t(unsigned int,
1038 sizeof(root_hub_config_des),
1039 wLength));
1040 data_buf = root_hub_config_des;
1041 break;
1042
1043 case ((USB_DT_STRING << 8) | 0x00):
1044 len = min_t(unsigned int,
1045 leni, min_t(unsigned int,
1046 sizeof(root_hub_str_index0),
1047 wLength));
1048 data_buf = root_hub_str_index0;
1049 break;
1050
1051 case ((USB_DT_STRING << 8) | 0x01):
1052 len = min_t(unsigned int,
1053 leni, min_t(unsigned int,
1054 sizeof(root_hub_str_index1),
1055 wLength));
1056 data_buf = root_hub_str_index1;
1057 break;
1058
1059 default:
1060 ERR("invalid wValue");
1061 stat = USB_ST_STALLED;
1062 }
1063
1064 break;
1065
1066 case RH_GET_DESCRIPTOR | RH_CLASS:
1067 DBG("RH_GET_DESCRIPTOR | RH_CLASS");
1068
1069 tmp = isp116x_read_reg32(isp116x, HCRHDESCA);
1070
1071 data_buf[0] = 0x09;
1072 data_buf[1] = 0x29;
1073 data_buf[2] = tmp & RH_A_NDP;
1074 data_buf[3] = 0;
1075 if (tmp & RH_A_PSM)
1076 data_buf[3] |= 0x01;
1077 if (tmp & RH_A_NOCP)
1078 data_buf[3] |= 0x10;
1079 else if (tmp & RH_A_OCPM)
1080 data_buf[3] |= 0x08;
1081
1082
1083 datab[1] = 0;
1084 data_buf[5] = (tmp & RH_A_POTPGT) >> 24;
1085
1086 tmp = isp116x_read_reg32(isp116x, HCRHDESCB);
1087
1088 data_buf[7] = tmp & RH_B_DR;
1089 if (data_buf[2] < 7)
1090 data_buf[8] = 0xff;
1091 else {
1092 data_buf[0] += 2;
1093 data_buf[8] = (tmp & RH_B_DR) >> 8;
1094 data_buf[10] = data_buf[9] = 0xff;
1095 }
1096
1097 len = min_t(unsigned int, leni,
1098 min_t(unsigned int, data_buf[0], wLength));
1099 break;
1100
1101 case RH_GET_CONFIGURATION:
1102 DBG("RH_GET_CONFIGURATION");
1103
1104 *(__u8 *) data_buf = 0x01;
1105 len = 1;
1106 break;
1107
1108 case RH_SET_CONFIGURATION:
1109 DBG("RH_SET_CONFIGURATION");
1110
1111 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);
1112 len = 0;
1113 break;
1114
1115 default:
1116 ERR("*** *** *** unsupported root hub command *** *** ***");
1117 stat = USB_ST_STALLED;
1118 }
1119
1120 len = min_t(int, len, leni);
1121 if (buffer != data_buf)
1122 memcpy(buffer, data_buf, len);
1123
1124 dev->act_len = len;
1125 dev->status = stat;
1126 DBG("dev act_len %d, status %d", dev->act_len, dev->status);
1127
1128 dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");
1129
1130 return stat;
1131}
1132
1133
1134
1135int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1136 int len, int interval)
1137{
1138 DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",
1139 dev, pipe, buffer, len, interval);
1140
1141 return -1;
1142}
1143
1144int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1145 int len, struct devrequest *setup)
1146{
1147 int devnum = usb_pipedevice(pipe);
1148 int epnum = usb_pipeendpoint(pipe);
1149 int max = max_transfer_len(dev, pipe);
1150 int dir_in = usb_pipein(pipe);
1151 int done, ret;
1152
1153
1154 if (devnum == rh_devnum)
1155 return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);
1156
1157
1158
1159
1160 DBG("--- SETUP PHASE --------------------------------");
1161 usb_settoggle(dev, epnum, 1, 0);
1162 ret = isp116x_submit_job(dev, pipe,
1163 PTD_DIR_SETUP,
1164 setup, sizeof(struct devrequest));
1165 if (ret < 0) {
1166 DBG("control setup phase error (ret = %d", ret);
1167 return -1;
1168 }
1169
1170
1171 DBG("--- DATA PHASE ---------------------------------");
1172 done = 0;
1173 usb_settoggle(dev, epnum, !dir_in, 1);
1174 while (done < len) {
1175 ret = isp116x_submit_job(dev, pipe,
1176 dir_in ? PTD_DIR_IN : PTD_DIR_OUT,
1177 (__u8 *) buffer + done,
1178 max > len - done ? len - done : max);
1179 if (ret < 0) {
1180 DBG("control data phase error (ret = %d)", ret);
1181 return -1;
1182 }
1183 done += ret;
1184
1185 if (dir_in && ret < max)
1186 break;
1187 }
1188
1189
1190 DBG("--- STATUS PHASE -------------------------------");
1191 usb_settoggle(dev, epnum, !dir_in, 1);
1192 ret = isp116x_submit_job(dev, pipe,
1193 !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);
1194 if (ret < 0) {
1195 DBG("control status phase error (ret = %d", ret);
1196 return -1;
1197 }
1198
1199 dev->act_len = done;
1200
1201 dump_msg(dev, pipe, buffer, len, "DEV(ret)");
1202
1203 return done;
1204}
1205
1206int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1207 int len)
1208{
1209 int dir_out = usb_pipeout(pipe);
1210 int max = max_transfer_len(dev, pipe);
1211 int done, ret;
1212
1213 DBG("--- BULK ---------------------------------------");
1214 DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",
1215 usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
1216
1217 done = 0;
1218 while (done < len) {
1219 ret = isp116x_submit_job(dev, pipe,
1220 !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,
1221 (__u8 *) buffer + done,
1222 max > len - done ? len - done : max);
1223 if (ret < 0) {
1224 DBG("error on bulk message (ret = %d)", ret);
1225 return -1;
1226 }
1227
1228 done += ret;
1229
1230 if (!dir_out && ret < max)
1231 break;
1232 }
1233
1234 dev->act_len = done;
1235
1236 return 0;
1237}
1238
1239
1240
1241static int isp116x_sw_reset(struct isp116x *isp116x)
1242{
1243 int retries = 15;
1244 int ret = 0;
1245
1246 DBG("");
1247
1248 isp116x->disabled = 1;
1249
1250 isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
1251 isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
1252 while (--retries) {
1253
1254 mdelay(1);
1255 if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
1256 break;
1257 }
1258 if (!retries) {
1259 ERR("software reset timeout");
1260 ret = -1;
1261 }
1262 return ret;
1263}
1264
1265static int isp116x_reset(struct isp116x *isp116x)
1266{
1267 unsigned long t;
1268 u16 clkrdy = 0;
1269 int ret, timeout = 15 ;
1270
1271 DBG("");
1272
1273 ret = isp116x_sw_reset(isp116x);
1274 if (ret)
1275 return ret;
1276
1277 for (t = 0; t < timeout; t++) {
1278 clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
1279 if (clkrdy)
1280 break;
1281 mdelay(1);
1282 }
1283 if (!clkrdy) {
1284 ERR("clock not ready after %dms", timeout);
1285
1286
1287 ERR("please make sure that the H_WAKEUP pin is pulled low!");
1288 ret = -1;
1289 }
1290 return ret;
1291}
1292
1293static void isp116x_stop(struct isp116x *isp116x)
1294{
1295 u32 val;
1296
1297 DBG("");
1298
1299 isp116x_write_reg16(isp116x, HCuPINTENB, 0);
1300
1301
1302
1303 val = isp116x_read_reg32(isp116x, HCRHDESCA);
1304 val &= ~(RH_A_NPS | RH_A_PSM);
1305 isp116x_write_reg32(isp116x, HCRHDESCA, val);
1306 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
1307
1308 isp116x_sw_reset(isp116x);
1309}
1310
1311
1312
1313
1314static int isp116x_start(struct isp116x *isp116x)
1315{
1316 struct isp116x_platform_data *board = isp116x->board;
1317 u32 val;
1318
1319 DBG("");
1320
1321
1322 isp116x_write_reg16(isp116x, HCuPINT, 0xff);
1323 isp116x_write_reg16(isp116x, HCuPINTENB, 0);
1324
1325 isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
1326 isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
1327
1328
1329 val = HCHWCFG_DBWIDTH(1);
1330 if (board->sel15Kres)
1331 val |= HCHWCFG_15KRSEL;
1332
1333 if (board->remote_wakeup_enable)
1334 val |= HCHWCFG_CLKNOTSTOP;
1335 if (board->oc_enable)
1336 val |= HCHWCFG_ANALOG_OC;
1337 isp116x_write_reg16(isp116x, HCHWCFG, val);
1338
1339
1340 val = (25 << 24) & RH_A_POTPGT;
1341
1342
1343
1344 val |= RH_A_PSM;
1345
1346 val |= RH_A_OCPM;
1347 isp116x_write_reg32(isp116x, HCRHDESCA, val);
1348 isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
1349
1350 val = RH_B_PPCM;
1351 isp116x_write_reg32(isp116x, HCRHDESCB, val);
1352 isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
1353
1354 val = 0;
1355 if (board->remote_wakeup_enable)
1356 val |= RH_HS_DRWE;
1357 isp116x_write_reg32(isp116x, HCRHSTATUS, val);
1358 isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
1359
1360 isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
1361
1362
1363 val = HCCONTROL_USB_OPER;
1364 if (board->remote_wakeup_enable)
1365 val |= HCCONTROL_RWE;
1366 isp116x_write_reg32(isp116x, HCCONTROL, val);
1367
1368
1369 isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
1370 isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
1371
1372 isp116x_show_regs(isp116x);
1373
1374 isp116x->disabled = 0;
1375
1376 return 0;
1377}
1378
1379
1380
1381int isp116x_check_id(struct isp116x *isp116x)
1382{
1383 int val;
1384
1385 val = isp116x_read_reg16(isp116x, HCCHIPID);
1386 if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
1387 ERR("invalid chip ID %04x", val);
1388 return -1;
1389 }
1390
1391 return 0;
1392}
1393
1394int usb_lowlevel_init(void)
1395{
1396 struct isp116x *isp116x = &isp116x_dev;
1397
1398 DBG("");
1399
1400 got_rhsc = rh_devnum = 0;
1401
1402
1403 isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;
1404 isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;
1405
1406
1407#ifdef ISP116X_HCD_SEL15kRES
1408 isp116x_board.sel15Kres = 1;
1409#endif
1410#ifdef ISP116X_HCD_OC_ENABLE
1411 isp116x_board.oc_enable = 1;
1412#endif
1413#ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE
1414 isp116x_board.remote_wakeup_enable = 1;
1415#endif
1416 isp116x->board = &isp116x_board;
1417
1418
1419 if (isp116x_check_id(isp116x) < 0)
1420 return -1;
1421
1422 isp116x->disabled = 1;
1423 isp116x->sleeping = 0;
1424
1425 isp116x_reset(isp116x);
1426 isp116x_start(isp116x);
1427
1428 return 0;
1429}
1430
1431int usb_lowlevel_stop(void)
1432{
1433 struct isp116x *isp116x = &isp116x_dev;
1434
1435 DBG("");
1436
1437 if (!isp116x->disabled)
1438 isp116x_stop(isp116x);
1439
1440 return 0;
1441}
1442