1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/delay.h>
18#include <linux/slab.h>
19#include "common.h"
20#include "pipe.h"
21
22
23
24
25#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2)
26
27#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f)
28#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
29#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
30#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0)
31
32
33
34
35static char *usbhsp_pipe_name[] = {
36 [USB_ENDPOINT_XFER_CONTROL] = "DCP",
37 [USB_ENDPOINT_XFER_BULK] = "BULK",
38 [USB_ENDPOINT_XFER_INT] = "INT",
39 [USB_ENDPOINT_XFER_ISOC] = "ISO",
40};
41
42char *usbhs_pipe_name(struct usbhs_pipe *pipe)
43{
44 return usbhsp_pipe_name[usbhs_pipe_type(pipe)];
45}
46
47
48
49
50static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
51{
52 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
53 int offset = usbhsp_addr_offset(pipe);
54
55 if (usbhs_pipe_is_dcp(pipe))
56 usbhs_bset(priv, DCPCTR, mask, val);
57 else
58 usbhs_bset(priv, PIPEnCTR + offset, mask, val);
59}
60
61static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
62{
63 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
64 int offset = usbhsp_addr_offset(pipe);
65
66 if (usbhs_pipe_is_dcp(pipe))
67 return usbhs_read(priv, DCPCTR);
68 else
69 return usbhs_read(priv, PIPEnCTR + offset);
70}
71
72
73
74
75static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
76 u16 dcp_reg, u16 pipe_reg,
77 u16 mask, u16 val)
78{
79 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
80
81 if (usbhs_pipe_is_dcp(pipe))
82 usbhs_bset(priv, dcp_reg, mask, val);
83 else
84 usbhs_bset(priv, pipe_reg, mask, val);
85}
86
87static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
88 u16 dcp_reg, u16 pipe_reg)
89{
90 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
91
92 if (usbhs_pipe_is_dcp(pipe))
93 return usbhs_read(priv, dcp_reg);
94 else
95 return usbhs_read(priv, pipe_reg);
96}
97
98
99
100
101static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
102{
103 __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
104}
105
106static u16 usbhsp_pipe_cfg_get(struct usbhs_pipe *pipe)
107{
108 return __usbhsp_pipe_xxx_get(pipe, DCPCFG, PIPECFG);
109}
110
111
112
113
114static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
115{
116 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
117 struct device *dev = usbhs_priv_to_dev(priv);
118 int num = usbhs_pipe_number(pipe);
119 u16 reg;
120
121
122
123
124
125#define CASE_PIPExTRN(a) \
126 case 0x ## a: \
127 reg = PIPE ## a ## TRN; \
128 break;
129
130 switch (num) {
131 CASE_PIPExTRN(1);
132 CASE_PIPExTRN(2);
133 CASE_PIPExTRN(3);
134 CASE_PIPExTRN(4);
135 CASE_PIPExTRN(5);
136 CASE_PIPExTRN(B);
137 CASE_PIPExTRN(C);
138 CASE_PIPExTRN(D);
139 CASE_PIPExTRN(E);
140 CASE_PIPExTRN(F);
141 CASE_PIPExTRN(9);
142 CASE_PIPExTRN(A);
143 default:
144 dev_err(dev, "unknown pipe (%d)\n", num);
145 return;
146 }
147 __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
148}
149
150static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
151{
152 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
153 struct device *dev = usbhs_priv_to_dev(priv);
154 int num = usbhs_pipe_number(pipe);
155 u16 reg;
156
157
158
159
160
161#define CASE_PIPExTRE(a) \
162 case 0x ## a: \
163 reg = PIPE ## a ## TRE; \
164 break;
165
166 switch (num) {
167 CASE_PIPExTRE(1);
168 CASE_PIPExTRE(2);
169 CASE_PIPExTRE(3);
170 CASE_PIPExTRE(4);
171 CASE_PIPExTRE(5);
172 CASE_PIPExTRE(B);
173 CASE_PIPExTRE(C);
174 CASE_PIPExTRE(D);
175 CASE_PIPExTRE(E);
176 CASE_PIPExTRE(F);
177 CASE_PIPExTRE(9);
178 CASE_PIPExTRE(A);
179 default:
180 dev_err(dev, "unknown pipe (%d)\n", num);
181 return;
182 }
183
184 __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
185}
186
187
188
189
190static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
191{
192 if (usbhs_pipe_is_dcp(pipe))
193 return;
194
195 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
196}
197
198
199
200
201static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
202{
203 __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
204}
205
206
207
208
209static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
210{
211 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe));
229}
230
231static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
232{
233 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
234 int timeout = 1024;
235 u16 val;
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 usbhs_write(priv, CFIFOSEL, 0);
256 usbhs_pipe_disable(pipe);
257
258 do {
259 val = usbhsp_pipectrl_get(pipe);
260 val &= CSSTS | PID_MASK;
261 if (!val)
262 return 0;
263
264 udelay(10);
265
266 } while (timeout--);
267
268 return -EBUSY;
269}
270
271int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
272{
273 u16 val;
274
275 val = usbhsp_pipectrl_get(pipe);
276 if (val & BSTS)
277 return 0;
278
279 return -EBUSY;
280}
281
282
283
284
285static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
286{
287 u16 pid = usbhsp_pipectrl_get(pipe);
288
289 pid &= PID_MASK;
290
291
292
293
294
295 switch (pid) {
296 case PID_STALL11:
297 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
298
299 case PID_STALL10:
300 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
301 }
302}
303
304void usbhs_pipe_disable(struct usbhs_pipe *pipe)
305{
306 int timeout = 1024;
307 u16 val;
308
309
310 __usbhsp_pid_try_nak_if_stall(pipe);
311
312 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
313
314 do {
315 val = usbhsp_pipectrl_get(pipe);
316 val &= PBUSY;
317 if (!val)
318 break;
319
320 udelay(10);
321 } while (timeout--);
322}
323
324void usbhs_pipe_enable(struct usbhs_pipe *pipe)
325{
326
327 __usbhsp_pid_try_nak_if_stall(pipe);
328
329 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
330}
331
332void usbhs_pipe_stall(struct usbhs_pipe *pipe)
333{
334 u16 pid = usbhsp_pipectrl_get(pipe);
335
336 pid &= PID_MASK;
337
338
339
340
341
342 switch (pid) {
343 case PID_NAK:
344 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
345 break;
346 case PID_BUF:
347 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
348 break;
349 }
350}
351
352int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
353{
354 u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK;
355
356 return (int)(pid == PID_STALL10 || pid == PID_STALL11);
357}
358
359void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
360{
361 if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
362 return;
363
364
365
366
367 usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR);
368
369
370
371
372
373
374
375 if (usbhs_pipe_is_dir_in(pipe)) {
376 int maxp = usbhs_pipe_get_maxpacket(pipe);
377
378 usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp));
379 usbhsp_pipe_tre_set(pipe, TRENB, TRENB);
380 }
381}
382
383
384
385
386
387static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
388{
389
390
391
392 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) ||
393 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
394 return 1;
395
396 return 0;
397}
398
399static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
400 int is_host,
401 int dir_in)
402{
403 u16 type = 0;
404 u16 bfre = 0;
405 u16 dblb = 0;
406 u16 cntmd = 0;
407 u16 dir = 0;
408 u16 epnum = 0;
409 u16 shtnak = 0;
410 u16 type_array[] = {
411 [USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
412 [USB_ENDPOINT_XFER_INT] = TYPE_INT,
413 [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
414 };
415 int is_double = usbhsp_possible_double_buffer(pipe);
416
417 if (usbhs_pipe_is_dcp(pipe))
418 return -EINVAL;
419
420
421
422
423
424
425
426
427
428
429
430 type = type_array[usbhs_pipe_type(pipe)];
431
432
433 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
434 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
435 bfre = 0;
436
437
438 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
439 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
440 dblb = (is_double) ? DBLB : 0;
441
442
443 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
444 cntmd = 0;
445
446
447 if (dir_in)
448 usbhsp_flags_set(pipe, IS_DIR_HOST);
449
450 if (!!is_host ^ !!dir_in)
451 dir |= DIR_OUT;
452
453 if (!dir)
454 usbhsp_flags_set(pipe, IS_DIR_IN);
455
456
457 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
458 !dir)
459 shtnak = SHTNAK;
460
461
462 epnum = 0;
463
464 return type |
465 bfre |
466 dblb |
467 cntmd |
468 dir |
469 shtnak |
470 epnum;
471}
472
473static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
474{
475 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
476 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
477 struct device *dev = usbhs_priv_to_dev(priv);
478 int pipe_num = usbhs_pipe_number(pipe);
479 int is_double = usbhsp_possible_double_buffer(pipe);
480 u16 buff_size;
481 u16 bufnmb;
482 u16 bufnmb_cnt;
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_CONTROL))
518 buff_size = 256;
519 else if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
520 buff_size = 64;
521 else
522 buff_size = 512;
523
524
525 bufnmb_cnt = (buff_size / 64) - 1;
526
527
528
529 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) {
530 bufnmb = pipe_num - 2;
531 } else {
532 bufnmb = info->bufnmb_last;
533 info->bufnmb_last += bufnmb_cnt + 1;
534
535
536
537
538 if (is_double)
539 info->bufnmb_last += bufnmb_cnt + 1;
540 }
541
542 dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
543 pipe_num, buff_size, bufnmb);
544
545 return (0x1f & bufnmb_cnt) << 10 |
546 (0xff & bufnmb) << 0;
547}
548
549void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
550 u16 epnum, u16 maxp)
551{
552 if (devsel > 0xA) {
553 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
554 struct device *dev = usbhs_priv_to_dev(priv);
555
556 dev_err(dev, "devsel error %d\n", devsel);
557
558 devsel = 0;
559 }
560
561 usbhsp_pipe_barrier(pipe);
562
563 pipe->maxp = maxp;
564
565 usbhsp_pipe_select(pipe);
566 usbhsp_pipe_maxp_set(pipe, 0xFFFF,
567 (devsel << 12) |
568 maxp);
569
570 if (!usbhs_pipe_is_dcp(pipe))
571 usbhsp_pipe_cfg_set(pipe, 0x000F, epnum);
572}
573
574
575
576
577int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
578{
579
580
581
582
583
584 return pipe->maxp;
585}
586
587int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
588{
589 return usbhsp_flags_has(pipe, IS_DIR_IN);
590}
591
592int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
593{
594 return usbhsp_flags_has(pipe, IS_DIR_HOST);
595}
596
597int usbhs_pipe_is_running(struct usbhs_pipe *pipe)
598{
599 return usbhsp_flags_has(pipe, IS_RUNNING);
600}
601
602void usbhs_pipe_running(struct usbhs_pipe *pipe, int running)
603{
604 if (running)
605 usbhsp_flags_set(pipe, IS_RUNNING);
606 else
607 usbhsp_flags_clr(pipe, IS_RUNNING);
608}
609
610void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
611{
612 u16 mask = (SQCLR | SQSET);
613 u16 val;
614
615
616
617
618
619
620
621 switch (sequence) {
622 case 0:
623 val = SQCLR;
624 break;
625 case 1:
626 val = SQSET;
627 break;
628 default:
629 return;
630 }
631
632 usbhsp_pipectrl_set(pipe, mask, val);
633}
634
635static int usbhs_pipe_get_data_sequence(struct usbhs_pipe *pipe)
636{
637 return !!(usbhsp_pipectrl_get(pipe) & SQMON);
638}
639
640void usbhs_pipe_clear(struct usbhs_pipe *pipe)
641{
642 if (usbhs_pipe_is_dcp(pipe)) {
643 usbhs_fifo_clear_dcp(pipe);
644 } else {
645 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
646 usbhsp_pipectrl_set(pipe, ACLRM, 0);
647 }
648}
649
650void usbhs_pipe_config_change_bfre(struct usbhs_pipe *pipe, int enable)
651{
652 int sequence;
653
654 if (usbhs_pipe_is_dcp(pipe))
655 return;
656
657 usbhsp_pipe_select(pipe);
658
659 if (!(enable ^ !!(usbhsp_pipe_cfg_get(pipe) & BFRE)))
660 return;
661
662 sequence = usbhs_pipe_get_data_sequence(pipe);
663 usbhsp_pipe_cfg_set(pipe, BFRE, enable ? BFRE : 0);
664 usbhs_pipe_clear(pipe);
665 usbhs_pipe_data_sequence(pipe, sequence);
666}
667
668static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
669{
670 struct usbhs_pipe *pos, *pipe;
671 int i;
672
673
674
675
676 pipe = NULL;
677 usbhs_for_each_pipe_with_dcp(pos, priv, i) {
678 if (!usbhs_pipe_type_is(pos, type))
679 continue;
680 if (usbhsp_flags_has(pos, IS_USED))
681 continue;
682
683 pipe = pos;
684 break;
685 }
686
687 if (!pipe)
688 return NULL;
689
690
691
692
693 usbhsp_flags_init(pipe);
694 usbhsp_flags_set(pipe, IS_USED);
695
696 return pipe;
697}
698
699static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
700{
701 usbhsp_flags_init(pipe);
702}
703
704void usbhs_pipe_init(struct usbhs_priv *priv,
705 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
706{
707 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
708 struct usbhs_pipe *pipe;
709 int i;
710
711
712
713
714
715
716
717
718
719
720
721
722
723 info->bufnmb_last = 4;
724 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
725 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
726 info->bufnmb_last++;
727
728 usbhsp_flags_init(pipe);
729 pipe->fifo = NULL;
730 pipe->mod_private = NULL;
731 INIT_LIST_HEAD(&pipe->list);
732
733
734 usbhs_pipe_clear(pipe);
735 }
736
737 info->dma_map_ctrl = dma_map_ctrl;
738}
739
740struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
741 int endpoint_type,
742 int dir_in)
743{
744 struct device *dev = usbhs_priv_to_dev(priv);
745 struct usbhs_pipe *pipe;
746 int is_host = usbhs_mod_is_host(priv);
747 int ret;
748 u16 pipecfg, pipebuf;
749
750 pipe = usbhsp_get_pipe(priv, endpoint_type);
751 if (!pipe) {
752 dev_err(dev, "can't get pipe (%s)\n",
753 usbhsp_pipe_name[endpoint_type]);
754 return NULL;
755 }
756
757 INIT_LIST_HEAD(&pipe->list);
758
759 usbhs_pipe_disable(pipe);
760
761
762 ret = usbhsp_pipe_barrier(pipe);
763 if (ret < 0) {
764 dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
765 return NULL;
766 }
767
768 pipecfg = usbhsp_setup_pipecfg(pipe, is_host, dir_in);
769 pipebuf = usbhsp_setup_pipebuff(pipe);
770
771 usbhsp_pipe_select(pipe);
772 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
773 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
774 usbhs_pipe_clear(pipe);
775
776 usbhs_pipe_sequence_data0(pipe);
777
778 dev_dbg(dev, "enable pipe %d : %s (%s)\n",
779 usbhs_pipe_number(pipe),
780 usbhs_pipe_name(pipe),
781 usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
782
783
784
785
786
787
788 return pipe;
789}
790
791void usbhs_pipe_free(struct usbhs_pipe *pipe)
792{
793 usbhsp_put_pipe(pipe);
794}
795
796void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
797{
798 if (pipe->fifo)
799 pipe->fifo->pipe = NULL;
800
801 pipe->fifo = fifo;
802
803 if (fifo)
804 fifo->pipe = pipe;
805}
806
807
808
809
810
811struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
812{
813 struct usbhs_pipe *pipe;
814
815 pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
816 if (!pipe)
817 return NULL;
818
819 INIT_LIST_HEAD(&pipe->list);
820
821
822
823
824
825 return pipe;
826}
827
828void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
829{
830 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
831
832 WARN_ON(!usbhs_pipe_is_dcp(pipe));
833
834 usbhs_pipe_enable(pipe);
835
836 if (!usbhs_mod_is_host(priv))
837 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
838}
839
840void usbhs_dcp_dir_for_host(struct usbhs_pipe *pipe, int dir_out)
841{
842 usbhsp_pipe_cfg_set(pipe, DIR_OUT,
843 dir_out ? DIR_OUT : 0);
844}
845
846
847
848
849int usbhs_pipe_probe(struct usbhs_priv *priv)
850{
851 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
852 struct usbhs_pipe *pipe;
853 struct device *dev = usbhs_priv_to_dev(priv);
854 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type);
855 int pipe_size = usbhs_get_dparam(priv, pipe_size);
856 int i;
857
858
859 if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) {
860 dev_err(dev, "1st PIPE is not DCP\n");
861 return -EINVAL;
862 }
863
864 info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL);
865 if (!info->pipe) {
866 dev_err(dev, "Could not allocate pipe\n");
867 return -ENOMEM;
868 }
869
870 info->size = pipe_size;
871
872
873
874
875 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
876 pipe->priv = priv;
877
878 usbhs_pipe_type(pipe) =
879 pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK;
880
881 dev_dbg(dev, "pipe %x\t: %s\n",
882 i, usbhsp_pipe_name[pipe_type[i]]);
883 }
884
885 return 0;
886}
887
888void usbhs_pipe_remove(struct usbhs_priv *priv)
889{
890 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
891
892 kfree(info->pipe);
893}
894