]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/usb/renesas_usbhs/pipe.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[karo-tx-linux.git] / drivers / usb / renesas_usbhs / pipe.c
1 /*
2  * Renesas USB driver
3  *
4  * Copyright (C) 2011 Renesas Solutions Corp.
5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15  *
16  */
17 #include <linux/delay.h>
18 #include <linux/slab.h>
19 #include "./common.h"
20 #include "./pipe.h"
21
22 /*
23  *              macros
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  * for debug
34  */
35 static 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
42 char *usbhs_pipe_name(struct usbhs_pipe *pipe)
43 {
44         return usbhsp_pipe_name[usbhs_pipe_type(pipe)];
45 }
46
47 /*
48  *              DCPCTR/PIPEnCTR functions
49  */
50 static 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
61 static 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  *              DCP/PIPE functions
74  */
75 static 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
87 /*
88  *              DCPCFG/PIPECFG functions
89  */
90 static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
91 {
92         __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
93 }
94
95 /*
96  *              PIPEBUF
97  */
98 static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
99 {
100         if (usbhs_pipe_is_dcp(pipe))
101                 return;
102
103         __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
104 }
105
106 /*
107  *              DCPMAXP/PIPEMAXP
108  */
109 static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
110 {
111         __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
112 }
113
114 /*
115  *              pipe control functions
116  */
117 static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
118 {
119         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
120
121         /*
122          * On pipe, this is necessary before
123          * accesses to below registers.
124          *
125          * PIPESEL      : usbhsp_pipe_select
126          * PIPECFG      : usbhsp_pipe_cfg_xxx
127          * PIPEBUF      : usbhsp_pipe_buf_xxx
128          * PIPEMAXP     : usbhsp_pipe_maxp_xxx
129          * PIPEPERI
130          */
131
132         /*
133          * if pipe is dcp, no pipe is selected.
134          * it is no problem, because dcp have its register
135          */
136         usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe));
137 }
138
139 static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
140 {
141         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
142         int timeout = 1024;
143         u16 val;
144
145         /*
146          * make sure....
147          *
148          * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is
149          * specified by the CURPIPE bits.
150          * When changing the setting of this bit after changing
151          * the PID bits for the selected pipe from BUF to NAK,
152          * check that CSSTS = 0 and PBUSY = 0.
153          */
154
155         /*
156          * CURPIPE bit = 0
157          *
158          * see also
159          *  "Operation"
160          *  - "Pipe Control"
161          *   - "Pipe Control Registers Switching Procedure"
162          */
163         usbhs_write(priv, CFIFOSEL, 0);
164         usbhs_pipe_disable(pipe);
165
166         do {
167                 val  = usbhsp_pipectrl_get(pipe);
168                 val &= CSSTS | PID_MASK;
169                 if (!val)
170                         return 0;
171
172                 udelay(10);
173
174         } while (timeout--);
175
176         return -EBUSY;
177 }
178
179 int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
180 {
181         u16 val;
182
183         val = usbhsp_pipectrl_get(pipe);
184         if (val & BSTS)
185                 return 0;
186
187         return -EBUSY;
188 }
189
190 /*
191  *              PID ctrl
192  */
193 static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
194 {
195         u16 pid = usbhsp_pipectrl_get(pipe);
196
197         pid &= PID_MASK;
198
199         /*
200          * see
201          * "Pipe n Control Register" - "PID"
202          */
203         switch (pid) {
204         case PID_STALL11:
205                 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
206                 /* fall-through */
207         case PID_STALL10:
208                 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
209         }
210 }
211
212 void usbhs_pipe_disable(struct usbhs_pipe *pipe)
213 {
214         int timeout = 1024;
215         u16 val;
216
217         /* see "Pipe n Control Register" - "PID" */
218         __usbhsp_pid_try_nak_if_stall(pipe);
219
220         usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
221
222         do {
223                 val  = usbhsp_pipectrl_get(pipe);
224                 val &= PBUSY;
225                 if (!val)
226                         break;
227
228                 udelay(10);
229         } while (timeout--);
230 }
231
232 void usbhs_pipe_enable(struct usbhs_pipe *pipe)
233 {
234         /* see "Pipe n Control Register" - "PID" */
235         __usbhsp_pid_try_nak_if_stall(pipe);
236
237         usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
238 }
239
240 void usbhs_pipe_stall(struct usbhs_pipe *pipe)
241 {
242         u16 pid = usbhsp_pipectrl_get(pipe);
243
244         pid &= PID_MASK;
245
246         /*
247          * see
248          * "Pipe n Control Register" - "PID"
249          */
250         switch (pid) {
251         case PID_NAK:
252                 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
253                 break;
254         case PID_BUF:
255                 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
256                 break;
257         }
258 }
259
260 int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
261 {
262         u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK;
263
264         return (int)(pid == PID_STALL10 || pid == PID_STALL11);
265 }
266
267 /*
268  *              pipe setup
269  */
270 static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
271 {
272         /*
273          * only ISO / BULK pipe can use double buffer
274          */
275         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) ||
276             usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
277                 return 1;
278
279         return 0;
280 }
281
282 static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
283                                 int is_host,
284                                 int dir_in)
285 {
286         u16 type = 0;
287         u16 bfre = 0;
288         u16 dblb = 0;
289         u16 cntmd = 0;
290         u16 dir = 0;
291         u16 epnum = 0;
292         u16 shtnak = 0;
293         u16 type_array[] = {
294                 [USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
295                 [USB_ENDPOINT_XFER_INT]  = TYPE_INT,
296                 [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
297         };
298         int is_double = usbhsp_possible_double_buffer(pipe);
299
300         if (usbhs_pipe_is_dcp(pipe))
301                 return -EINVAL;
302
303         /*
304          * PIPECFG
305          *
306          * see
307          *  - "Register Descriptions" - "PIPECFG" register
308          *  - "Features"  - "Pipe configuration"
309          *  - "Operation" - "Pipe Control"
310          */
311
312         /* TYPE */
313         type = type_array[usbhs_pipe_type(pipe)];
314
315         /* BFRE */
316         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
317             usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
318                 bfre = 0; /* FIXME */
319
320         /* DBLB */
321         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
322             usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
323                 dblb = (is_double) ? DBLB : 0;
324
325         /* CNTMD */
326         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
327                 cntmd = 0; /* FIXME */
328
329         /* DIR */
330         if (dir_in)
331                 usbhsp_flags_set(pipe, IS_DIR_HOST);
332
333         if (!!is_host ^ !!dir_in)
334                 dir |= DIR_OUT;
335
336         if (!dir)
337                 usbhsp_flags_set(pipe, IS_DIR_IN);
338
339         /* SHTNAK */
340         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
341             !dir)
342                 shtnak = SHTNAK;
343
344         /* EPNUM */
345         epnum = 0; /* see usbhs_pipe_config_update() */
346
347         return  type    |
348                 bfre    |
349                 dblb    |
350                 cntmd   |
351                 dir     |
352                 shtnak  |
353                 epnum;
354 }
355
356 static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
357 {
358         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
359         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
360         struct device *dev = usbhs_priv_to_dev(priv);
361         int pipe_num = usbhs_pipe_number(pipe);
362         int is_double = usbhsp_possible_double_buffer(pipe);
363         u16 buff_size;
364         u16 bufnmb;
365         u16 bufnmb_cnt;
366
367         /*
368          * PIPEBUF
369          *
370          * see
371          *  - "Register Descriptions" - "PIPEBUF" register
372          *  - "Features"  - "Pipe configuration"
373          *  - "Operation" - "FIFO Buffer Memory"
374          *  - "Operation" - "Pipe Control"
375          *
376          * ex) if pipe6 - pipe9 are USB_ENDPOINT_XFER_INT (SH7724)
377          *
378          * BUFNMB:      PIPE
379          * 0:           pipe0 (DCP 256byte)
380          * 1:           -
381          * 2:           -
382          * 3:           -
383          * 4:           pipe6 (INT 64byte)
384          * 5:           pipe7 (INT 64byte)
385          * 6:           pipe8 (INT 64byte)
386          * 7:           pipe9 (INT 64byte)
387          * 8 - xx:      free (for BULK, ISOC)
388          */
389
390         /*
391          * FIXME
392          *
393          * it doesn't have good buffer allocator
394          *
395          * DCP : 256 byte
396          * BULK: 512 byte
397          * INT :  64 byte
398          * ISOC: 512 byte
399          */
400         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_CONTROL))
401                 buff_size = 256;
402         else if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
403                 buff_size = 64;
404         else
405                 buff_size = 512;
406
407         /* change buff_size to register value */
408         bufnmb_cnt = (buff_size / 64) - 1;
409
410         /* BUFNMB has been reserved for INT pipe
411          * see above */
412         if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) {
413                 bufnmb = pipe_num - 2;
414         } else {
415                 bufnmb = info->bufnmb_last;
416                 info->bufnmb_last += bufnmb_cnt + 1;
417
418                 /*
419                  * double buffer
420                  */
421                 if (is_double)
422                         info->bufnmb_last += bufnmb_cnt + 1;
423         }
424
425         dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
426                 pipe_num, buff_size, bufnmb);
427
428         return  (0x1f & bufnmb_cnt)     << 10 |
429                 (0xff & bufnmb)         <<  0;
430 }
431
432 void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
433                               u16 epnum, u16 maxp)
434 {
435         if (devsel > 0xA) {
436                 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
437                 struct device *dev = usbhs_priv_to_dev(priv);
438
439                 dev_err(dev, "devsel error %d\n", devsel);
440
441                 devsel = 0;
442         }
443
444         usbhsp_pipe_barrier(pipe);
445
446         pipe->maxp = maxp;
447
448         usbhsp_pipe_select(pipe);
449         usbhsp_pipe_maxp_set(pipe, 0xFFFF,
450                              (devsel << 12) |
451                              maxp);
452
453         if (!usbhs_pipe_is_dcp(pipe))
454                 usbhsp_pipe_cfg_set(pipe,  0x000F, epnum);
455 }
456
457 /*
458  *              pipe control
459  */
460 int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
461 {
462         /*
463          * see
464          *      usbhs_pipe_config_update()
465          *      usbhs_dcp_malloc()
466          */
467         return pipe->maxp;
468 }
469
470 int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
471 {
472         return usbhsp_flags_has(pipe, IS_DIR_IN);
473 }
474
475 int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
476 {
477         return usbhsp_flags_has(pipe, IS_DIR_HOST);
478 }
479
480 void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
481 {
482         u16 mask = (SQCLR | SQSET);
483         u16 val;
484
485         /*
486          * sequence
487          *  0  : data0
488          *  1  : data1
489          *  -1 : no change
490          */
491         switch (sequence) {
492         case 0:
493                 val = SQCLR;
494                 break;
495         case 1:
496                 val = SQSET;
497                 break;
498         default:
499                 return;
500         }
501
502         usbhsp_pipectrl_set(pipe, mask, val);
503 }
504
505 void usbhs_pipe_clear(struct usbhs_pipe *pipe)
506 {
507         usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
508         usbhsp_pipectrl_set(pipe, ACLRM, 0);
509 }
510
511 static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
512 {
513         struct usbhs_pipe *pos, *pipe;
514         int i;
515
516         /*
517          * find target pipe
518          */
519         pipe = NULL;
520         usbhs_for_each_pipe_with_dcp(pos, priv, i) {
521                 if (!usbhs_pipe_type_is(pos, type))
522                         continue;
523                 if (usbhsp_flags_has(pos, IS_USED))
524                         continue;
525
526                 pipe = pos;
527                 break;
528         }
529
530         if (!pipe)
531                 return NULL;
532
533         /*
534          * initialize pipe flags
535          */
536         usbhsp_flags_init(pipe);
537         usbhsp_flags_set(pipe, IS_USED);
538
539         return pipe;
540 }
541
542 void usbhs_pipe_init(struct usbhs_priv *priv,
543                      int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
544 {
545         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
546         struct usbhs_pipe *pipe;
547         int i;
548
549         /*
550          * FIXME
551          *
552          * driver needs good allocator.
553          *
554          * find first free buffer area (BULK, ISOC)
555          * (DCP, INT area is fixed)
556          *
557          * buffer number 0 - 3 have been reserved for DCP
558          * see
559          *      usbhsp_to_bufnmb
560          */
561         info->bufnmb_last = 4;
562         usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
563                 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
564                         info->bufnmb_last++;
565
566                 usbhsp_flags_init(pipe);
567                 pipe->fifo = NULL;
568                 pipe->mod_private = NULL;
569                 INIT_LIST_HEAD(&pipe->list);
570
571                 /* pipe force init */
572                 usbhs_pipe_clear(pipe);
573         }
574
575         info->dma_map_ctrl = dma_map_ctrl;
576 }
577
578 struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
579                                      int endpoint_type,
580                                      int dir_in)
581 {
582         struct device *dev = usbhs_priv_to_dev(priv);
583         struct usbhs_pipe *pipe;
584         int is_host = usbhs_mod_is_host(priv);
585         int ret;
586         u16 pipecfg, pipebuf;
587
588         pipe = usbhsp_get_pipe(priv, endpoint_type);
589         if (!pipe) {
590                 dev_err(dev, "can't get pipe (%s)\n",
591                         usbhsp_pipe_name[endpoint_type]);
592                 return NULL;
593         }
594
595         INIT_LIST_HEAD(&pipe->list);
596
597         usbhs_pipe_disable(pipe);
598
599         /* make sure pipe is not busy */
600         ret = usbhsp_pipe_barrier(pipe);
601         if (ret < 0) {
602                 dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
603                 return NULL;
604         }
605
606         pipecfg  = usbhsp_setup_pipecfg(pipe, is_host, dir_in);
607         pipebuf  = usbhsp_setup_pipebuff(pipe);
608
609         usbhsp_pipe_select(pipe);
610         usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
611         usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
612
613         usbhs_pipe_sequence_data0(pipe);
614
615         dev_dbg(dev, "enable pipe %d : %s (%s)\n",
616                 usbhs_pipe_number(pipe),
617                 usbhs_pipe_name(pipe),
618                 usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
619
620         /*
621          * epnum / maxp are still not set to this pipe.
622          * call usbhs_pipe_config_update() after this function !!
623          */
624
625         return pipe;
626 }
627
628 void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
629 {
630         if (pipe->fifo)
631                 pipe->fifo->pipe = NULL;
632
633         pipe->fifo = fifo;
634
635         if (fifo)
636                 fifo->pipe = pipe;
637 }
638
639
640 /*
641  *              dcp control
642  */
643 struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
644 {
645         struct usbhs_pipe *pipe;
646
647         pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
648         if (!pipe)
649                 return NULL;
650
651         INIT_LIST_HEAD(&pipe->list);
652
653         /*
654          * call usbhs_pipe_config_update() after this function !!
655          */
656
657         return pipe;
658 }
659
660 void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
661 {
662         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
663
664         WARN_ON(!usbhs_pipe_is_dcp(pipe));
665
666         usbhs_pipe_enable(pipe);
667
668         if (!usbhs_mod_is_host(priv)) /* funconly */
669                 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
670 }
671
672 void usbhs_dcp_dir_for_host(struct usbhs_pipe *pipe, int dir_out)
673 {
674         usbhsp_pipe_cfg_set(pipe, DIR_OUT,
675                             dir_out ? DIR_OUT : 0);
676 }
677
678 /*
679  *              pipe module function
680  */
681 int usbhs_pipe_probe(struct usbhs_priv *priv)
682 {
683         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
684         struct usbhs_pipe *pipe;
685         struct device *dev = usbhs_priv_to_dev(priv);
686         u32 *pipe_type = usbhs_get_dparam(priv, pipe_type);
687         int pipe_size = usbhs_get_dparam(priv, pipe_size);
688         int i;
689
690         /* This driver expects 1st pipe is DCP */
691         if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) {
692                 dev_err(dev, "1st PIPE is not DCP\n");
693                 return -EINVAL;
694         }
695
696         info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL);
697         if (!info->pipe) {
698                 dev_err(dev, "Could not allocate pipe\n");
699                 return -ENOMEM;
700         }
701
702         info->size = pipe_size;
703
704         /*
705          * init pipe
706          */
707         usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
708                 pipe->priv = priv;
709
710                 usbhs_pipe_type(pipe) =
711                         pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK;
712
713                 dev_dbg(dev, "pipe %x\t: %s\n",
714                         i, usbhsp_pipe_name[pipe_type[i]]);
715         }
716
717         return 0;
718 }
719
720 void usbhs_pipe_remove(struct usbhs_priv *priv)
721 {
722         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
723
724         kfree(info->pipe);
725 }