Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-1.0+
0002 /*
0003  * Renesas USB driver
0004  *
0005  * Copyright (C) 2011 Renesas Solutions Corp.
0006  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
0007  */
0008 #include <linux/delay.h>
0009 #include <linux/slab.h>
0010 #include "common.h"
0011 #include "pipe.h"
0012 
0013 /*
0014  *      macros
0015  */
0016 #define usbhsp_addr_offset(p)   ((usbhs_pipe_number(p) - 1) * 2)
0017 
0018 #define usbhsp_flags_set(p, f)  ((p)->flags |=  USBHS_PIPE_FLAGS_##f)
0019 #define usbhsp_flags_clr(p, f)  ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
0020 #define usbhsp_flags_has(p, f)  ((p)->flags &   USBHS_PIPE_FLAGS_##f)
0021 #define usbhsp_flags_init(p)    do {(p)->flags = 0; } while (0)
0022 
0023 /*
0024  * for debug
0025  */
0026 static char *usbhsp_pipe_name[] = {
0027     [USB_ENDPOINT_XFER_CONTROL] = "DCP",
0028     [USB_ENDPOINT_XFER_BULK]    = "BULK",
0029     [USB_ENDPOINT_XFER_INT]     = "INT",
0030     [USB_ENDPOINT_XFER_ISOC]    = "ISO",
0031 };
0032 
0033 char *usbhs_pipe_name(struct usbhs_pipe *pipe)
0034 {
0035     return usbhsp_pipe_name[usbhs_pipe_type(pipe)];
0036 }
0037 
0038 static struct renesas_usbhs_driver_pipe_config
0039 *usbhsp_get_pipe_config(struct usbhs_priv *priv, int pipe_num)
0040 {
0041     struct renesas_usbhs_driver_pipe_config *pipe_configs =
0042                     usbhs_get_dparam(priv, pipe_configs);
0043 
0044     return &pipe_configs[pipe_num];
0045 }
0046 
0047 /*
0048  *      DCPCTR/PIPEnCTR functions
0049  */
0050 static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
0051 {
0052     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0053     int offset = usbhsp_addr_offset(pipe);
0054 
0055     if (usbhs_pipe_is_dcp(pipe))
0056         usbhs_bset(priv, DCPCTR, mask, val);
0057     else
0058         usbhs_bset(priv, PIPEnCTR + offset, mask, val);
0059 }
0060 
0061 static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
0062 {
0063     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0064     int offset = usbhsp_addr_offset(pipe);
0065 
0066     if (usbhs_pipe_is_dcp(pipe))
0067         return usbhs_read(priv, DCPCTR);
0068     else
0069         return usbhs_read(priv, PIPEnCTR + offset);
0070 }
0071 
0072 /*
0073  *      DCP/PIPE functions
0074  */
0075 static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
0076                   u16 dcp_reg, u16 pipe_reg,
0077                   u16 mask, u16 val)
0078 {
0079     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0080 
0081     if (usbhs_pipe_is_dcp(pipe))
0082         usbhs_bset(priv, dcp_reg, mask, val);
0083     else
0084         usbhs_bset(priv, pipe_reg, mask, val);
0085 }
0086 
0087 static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
0088                  u16 dcp_reg, u16 pipe_reg)
0089 {
0090     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0091 
0092     if (usbhs_pipe_is_dcp(pipe))
0093         return usbhs_read(priv, dcp_reg);
0094     else
0095         return usbhs_read(priv, pipe_reg);
0096 }
0097 
0098 /*
0099  *      DCPCFG/PIPECFG functions
0100  */
0101 static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
0102 {
0103     __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
0104 }
0105 
0106 static u16 usbhsp_pipe_cfg_get(struct usbhs_pipe *pipe)
0107 {
0108     return __usbhsp_pipe_xxx_get(pipe, DCPCFG, PIPECFG);
0109 }
0110 
0111 /*
0112  *      PIPEnTRN/PIPEnTRE functions
0113  */
0114 static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
0115 {
0116     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0117     struct device *dev = usbhs_priv_to_dev(priv);
0118     int num = usbhs_pipe_number(pipe);
0119     u16 reg;
0120 
0121     /*
0122      * It is impossible to calculate address,
0123      * since PIPEnTRN addresses were mapped randomly.
0124      */
0125 #define CASE_PIPExTRN(a)        \
0126     case 0x ## a:           \
0127         reg = PIPE ## a ## TRN; \
0128         break;
0129 
0130     switch (num) {
0131     CASE_PIPExTRN(1);
0132     CASE_PIPExTRN(2);
0133     CASE_PIPExTRN(3);
0134     CASE_PIPExTRN(4);
0135     CASE_PIPExTRN(5);
0136     CASE_PIPExTRN(B);
0137     CASE_PIPExTRN(C);
0138     CASE_PIPExTRN(D);
0139     CASE_PIPExTRN(E);
0140     CASE_PIPExTRN(F);
0141     CASE_PIPExTRN(9);
0142     CASE_PIPExTRN(A);
0143     default:
0144         dev_err(dev, "unknown pipe (%d)\n", num);
0145         return;
0146     }
0147     __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
0148 }
0149 
0150 static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
0151 {
0152     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0153     struct device *dev = usbhs_priv_to_dev(priv);
0154     int num = usbhs_pipe_number(pipe);
0155     u16 reg;
0156 
0157     /*
0158      * It is impossible to calculate address,
0159      * since PIPEnTRE addresses were mapped randomly.
0160      */
0161 #define CASE_PIPExTRE(a)            \
0162     case 0x ## a:               \
0163         reg = PIPE ## a ## TRE;     \
0164         break;
0165 
0166     switch (num) {
0167     CASE_PIPExTRE(1);
0168     CASE_PIPExTRE(2);
0169     CASE_PIPExTRE(3);
0170     CASE_PIPExTRE(4);
0171     CASE_PIPExTRE(5);
0172     CASE_PIPExTRE(B);
0173     CASE_PIPExTRE(C);
0174     CASE_PIPExTRE(D);
0175     CASE_PIPExTRE(E);
0176     CASE_PIPExTRE(F);
0177     CASE_PIPExTRE(9);
0178     CASE_PIPExTRE(A);
0179     default:
0180         dev_err(dev, "unknown pipe (%d)\n", num);
0181         return;
0182     }
0183 
0184     __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
0185 }
0186 
0187 /*
0188  *      PIPEBUF
0189  */
0190 static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
0191 {
0192     if (usbhs_pipe_is_dcp(pipe))
0193         return;
0194 
0195     __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
0196 }
0197 
0198 /*
0199  *      DCPMAXP/PIPEMAXP
0200  */
0201 static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
0202 {
0203     __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
0204 }
0205 
0206 /*
0207  *      pipe control functions
0208  */
0209 static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
0210 {
0211     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0212 
0213     /*
0214      * On pipe, this is necessary before
0215      * accesses to below registers.
0216      *
0217      * PIPESEL  : usbhsp_pipe_select
0218      * PIPECFG  : usbhsp_pipe_cfg_xxx
0219      * PIPEBUF  : usbhsp_pipe_buf_xxx
0220      * PIPEMAXP : usbhsp_pipe_maxp_xxx
0221      * PIPEPERI
0222      */
0223 
0224     /*
0225      * if pipe is dcp, no pipe is selected.
0226      * it is no problem, because dcp have its register
0227      */
0228     usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe));
0229 }
0230 
0231 static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
0232 {
0233     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0234     int timeout = 1024;
0235     u16 mask = usbhs_mod_is_host(priv) ? (CSSTS | PID_MASK) : PID_MASK;
0236 
0237     /*
0238      * make sure....
0239      *
0240      * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is
0241      * specified by the CURPIPE bits.
0242      * When changing the setting of this bit after changing
0243      * the PID bits for the selected pipe from BUF to NAK,
0244      * check that CSSTS = 0 and PBUSY = 0.
0245      */
0246 
0247     /*
0248      * CURPIPE bit = 0
0249      *
0250      * see also
0251      *  "Operation"
0252      *  - "Pipe Control"
0253      *   - "Pipe Control Registers Switching Procedure"
0254      */
0255     usbhs_write(priv, CFIFOSEL, 0);
0256     usbhs_pipe_disable(pipe);
0257 
0258     do {
0259         if (!(usbhsp_pipectrl_get(pipe) & mask))
0260             return 0;
0261 
0262         udelay(10);
0263 
0264     } while (timeout--);
0265 
0266     return -EBUSY;
0267 }
0268 
0269 int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
0270 {
0271     u16 val;
0272 
0273     val = usbhsp_pipectrl_get(pipe);
0274     if (val & BSTS)
0275         return 0;
0276 
0277     return -EBUSY;
0278 }
0279 
0280 bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe)
0281 {
0282     u16 val;
0283 
0284     /* Do not support for DCP pipe */
0285     if (usbhs_pipe_is_dcp(pipe))
0286         return false;
0287 
0288     val = usbhsp_pipectrl_get(pipe);
0289     if (val & INBUFM)
0290         return true;
0291 
0292     return false;
0293 }
0294 
0295 /*
0296  *      PID ctrl
0297  */
0298 static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
0299 {
0300     u16 pid = usbhsp_pipectrl_get(pipe);
0301 
0302     pid &= PID_MASK;
0303 
0304     /*
0305      * see
0306      * "Pipe n Control Register" - "PID"
0307      */
0308     switch (pid) {
0309     case PID_STALL11:
0310         usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
0311         fallthrough;
0312     case PID_STALL10:
0313         usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
0314     }
0315 }
0316 
0317 void usbhs_pipe_disable(struct usbhs_pipe *pipe)
0318 {
0319     int timeout = 1024;
0320     u16 val;
0321 
0322     /* see "Pipe n Control Register" - "PID" */
0323     __usbhsp_pid_try_nak_if_stall(pipe);
0324 
0325     usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
0326 
0327     do {
0328         val  = usbhsp_pipectrl_get(pipe);
0329         val &= PBUSY;
0330         if (!val)
0331             break;
0332 
0333         udelay(10);
0334     } while (timeout--);
0335 }
0336 
0337 void usbhs_pipe_enable(struct usbhs_pipe *pipe)
0338 {
0339     /* see "Pipe n Control Register" - "PID" */
0340     __usbhsp_pid_try_nak_if_stall(pipe);
0341 
0342     usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
0343 }
0344 
0345 void usbhs_pipe_stall(struct usbhs_pipe *pipe)
0346 {
0347     u16 pid = usbhsp_pipectrl_get(pipe);
0348 
0349     pid &= PID_MASK;
0350 
0351     /*
0352      * see
0353      * "Pipe n Control Register" - "PID"
0354      */
0355     switch (pid) {
0356     case PID_NAK:
0357         usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
0358         break;
0359     case PID_BUF:
0360         usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
0361         break;
0362     }
0363 }
0364 
0365 int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
0366 {
0367     u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK;
0368 
0369     return (int)(pid == PID_STALL10 || pid == PID_STALL11);
0370 }
0371 
0372 void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
0373 {
0374     if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
0375         return;
0376 
0377     /*
0378      * clear and disable transfer counter for IN/OUT pipe
0379      */
0380     usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR);
0381 
0382     /*
0383      * Only IN direction bulk pipe can use transfer count.
0384      * Without using this function,
0385      * received data will break if it was large data size.
0386      * see PIPEnTRN/PIPEnTRE for detail
0387      */
0388     if (usbhs_pipe_is_dir_in(pipe)) {
0389         int maxp = usbhs_pipe_get_maxpacket(pipe);
0390 
0391         usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp));
0392         usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */
0393     }
0394 }
0395 
0396 
0397 /*
0398  *      pipe setup
0399  */
0400 static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host,
0401                 int dir_in, u16 *pipecfg)
0402 {
0403     u16 type = 0;
0404     u16 bfre = 0;
0405     u16 dblb = 0;
0406     u16 cntmd = 0;
0407     u16 dir = 0;
0408     u16 epnum = 0;
0409     u16 shtnak = 0;
0410     static const u16 type_array[] = {
0411         [USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
0412         [USB_ENDPOINT_XFER_INT]  = TYPE_INT,
0413         [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
0414     };
0415 
0416     if (usbhs_pipe_is_dcp(pipe))
0417         return -EINVAL;
0418 
0419     /*
0420      * PIPECFG
0421      *
0422      * see
0423      *  - "Register Descriptions" - "PIPECFG" register
0424      *  - "Features"  - "Pipe configuration"
0425      *  - "Operation" - "Pipe Control"
0426      */
0427 
0428     /* TYPE */
0429     type = type_array[usbhs_pipe_type(pipe)];
0430 
0431     /* BFRE */
0432     if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
0433         usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
0434         bfre = 0; /* FIXME */
0435 
0436     /* DBLB: see usbhs_pipe_config_update() */
0437 
0438     /* CNTMD */
0439     if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
0440         cntmd = 0; /* FIXME */
0441 
0442     /* DIR */
0443     if (dir_in)
0444         usbhsp_flags_set(pipe, IS_DIR_HOST);
0445 
0446     if (!!is_host ^ !!dir_in)
0447         dir |= DIR_OUT;
0448 
0449     if (!dir)
0450         usbhsp_flags_set(pipe, IS_DIR_IN);
0451 
0452     /* SHTNAK */
0453     if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
0454         !dir)
0455         shtnak = SHTNAK;
0456 
0457     /* EPNUM */
0458     epnum = 0; /* see usbhs_pipe_config_update() */
0459     *pipecfg = type     |
0460            bfre     |
0461            dblb     |
0462            cntmd    |
0463            dir      |
0464            shtnak   |
0465            epnum;
0466     return 0;
0467 }
0468 
0469 static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
0470 {
0471     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0472     struct device *dev = usbhs_priv_to_dev(priv);
0473     int pipe_num = usbhs_pipe_number(pipe);
0474     u16 buff_size;
0475     u16 bufnmb;
0476     u16 bufnmb_cnt;
0477     struct renesas_usbhs_driver_pipe_config *pipe_config =
0478                     usbhsp_get_pipe_config(priv, pipe_num);
0479 
0480     /*
0481      * PIPEBUF
0482      *
0483      * see
0484      *  - "Register Descriptions" - "PIPEBUF" register
0485      *  - "Features"  - "Pipe configuration"
0486      *  - "Operation" - "FIFO Buffer Memory"
0487      *  - "Operation" - "Pipe Control"
0488      */
0489     buff_size = pipe_config->bufsize;
0490     bufnmb = pipe_config->bufnum;
0491 
0492     /* change buff_size to register value */
0493     bufnmb_cnt = (buff_size / 64) - 1;
0494 
0495     dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
0496         pipe_num, buff_size, bufnmb);
0497 
0498     return  (0x1f & bufnmb_cnt) << 10 |
0499         (0xff & bufnmb)     <<  0;
0500 }
0501 
0502 void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
0503                   u16 epnum, u16 maxp)
0504 {
0505     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0506     int pipe_num = usbhs_pipe_number(pipe);
0507     struct renesas_usbhs_driver_pipe_config *pipe_config =
0508                     usbhsp_get_pipe_config(priv, pipe_num);
0509     u16 dblb = pipe_config->double_buf ? DBLB : 0;
0510 
0511     if (devsel > 0xA) {
0512         struct device *dev = usbhs_priv_to_dev(priv);
0513 
0514         dev_err(dev, "devsel error %d\n", devsel);
0515 
0516         devsel = 0;
0517     }
0518 
0519     usbhsp_pipe_barrier(pipe);
0520 
0521     pipe->maxp = maxp;
0522 
0523     usbhsp_pipe_select(pipe);
0524     usbhsp_pipe_maxp_set(pipe, 0xFFFF,
0525                  (devsel << 12) |
0526                  maxp);
0527 
0528     if (!usbhs_pipe_is_dcp(pipe))
0529         usbhsp_pipe_cfg_set(pipe,  0x000F | DBLB, epnum | dblb);
0530 }
0531 
0532 /*
0533  *      pipe control
0534  */
0535 int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
0536 {
0537     /*
0538      * see
0539      *  usbhs_pipe_config_update()
0540      *  usbhs_dcp_malloc()
0541      */
0542     return pipe->maxp;
0543 }
0544 
0545 int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
0546 {
0547     return usbhsp_flags_has(pipe, IS_DIR_IN);
0548 }
0549 
0550 int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
0551 {
0552     return usbhsp_flags_has(pipe, IS_DIR_HOST);
0553 }
0554 
0555 int usbhs_pipe_is_running(struct usbhs_pipe *pipe)
0556 {
0557     return usbhsp_flags_has(pipe, IS_RUNNING);
0558 }
0559 
0560 void usbhs_pipe_running(struct usbhs_pipe *pipe, int running)
0561 {
0562     if (running)
0563         usbhsp_flags_set(pipe, IS_RUNNING);
0564     else
0565         usbhsp_flags_clr(pipe, IS_RUNNING);
0566 }
0567 
0568 void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
0569 {
0570     u16 mask = (SQCLR | SQSET);
0571     u16 val;
0572 
0573     /*
0574      * sequence
0575      *  0  : data0
0576      *  1  : data1
0577      *  -1 : no change
0578      */
0579     switch (sequence) {
0580     case 0:
0581         val = SQCLR;
0582         break;
0583     case 1:
0584         val = SQSET;
0585         break;
0586     default:
0587         return;
0588     }
0589 
0590     usbhsp_pipectrl_set(pipe, mask, val);
0591 }
0592 
0593 static int usbhs_pipe_get_data_sequence(struct usbhs_pipe *pipe)
0594 {
0595     return !!(usbhsp_pipectrl_get(pipe) & SQMON);
0596 }
0597 
0598 void usbhs_pipe_clear(struct usbhs_pipe *pipe)
0599 {
0600     if (usbhs_pipe_is_dcp(pipe)) {
0601         usbhs_fifo_clear_dcp(pipe);
0602     } else {
0603         usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
0604         usbhsp_pipectrl_set(pipe, ACLRM, 0);
0605     }
0606 }
0607 
0608 /* Should call usbhsp_pipe_select() before */
0609 void usbhs_pipe_clear_without_sequence(struct usbhs_pipe *pipe,
0610                        int needs_bfre, int bfre_enable)
0611 {
0612     int sequence;
0613 
0614     usbhsp_pipe_select(pipe);
0615     sequence = usbhs_pipe_get_data_sequence(pipe);
0616     if (needs_bfre)
0617         usbhsp_pipe_cfg_set(pipe, BFRE, bfre_enable ? BFRE : 0);
0618     usbhs_pipe_clear(pipe);
0619     usbhs_pipe_data_sequence(pipe, sequence);
0620 }
0621 
0622 void usbhs_pipe_config_change_bfre(struct usbhs_pipe *pipe, int enable)
0623 {
0624     if (usbhs_pipe_is_dcp(pipe))
0625         return;
0626 
0627     usbhsp_pipe_select(pipe);
0628     /* check if the driver needs to change the BFRE value */
0629     if (!(enable ^ !!(usbhsp_pipe_cfg_get(pipe) & BFRE)))
0630         return;
0631 
0632     usbhs_pipe_clear_without_sequence(pipe, 1, enable);
0633 }
0634 
0635 static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
0636 {
0637     struct usbhs_pipe *pos, *pipe;
0638     int i;
0639 
0640     /*
0641      * find target pipe
0642      */
0643     pipe = NULL;
0644     usbhs_for_each_pipe_with_dcp(pos, priv, i) {
0645         if (!usbhs_pipe_type_is(pos, type))
0646             continue;
0647         if (usbhsp_flags_has(pos, IS_USED))
0648             continue;
0649 
0650         pipe = pos;
0651         break;
0652     }
0653 
0654     if (!pipe)
0655         return NULL;
0656 
0657     /*
0658      * initialize pipe flags
0659      */
0660     usbhsp_flags_init(pipe);
0661     usbhsp_flags_set(pipe, IS_USED);
0662 
0663     return pipe;
0664 }
0665 
0666 static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
0667 {
0668     usbhsp_flags_init(pipe);
0669 }
0670 
0671 void usbhs_pipe_init(struct usbhs_priv *priv,
0672              int (*dma_map_ctrl)(struct device *dma_dev,
0673                      struct usbhs_pkt *pkt, int map))
0674 {
0675     struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
0676     struct usbhs_pipe *pipe;
0677     int i;
0678 
0679     usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
0680         usbhsp_flags_init(pipe);
0681         pipe->fifo = NULL;
0682         pipe->mod_private = NULL;
0683         INIT_LIST_HEAD(&pipe->list);
0684 
0685         /* pipe force init */
0686         usbhs_pipe_clear(pipe);
0687     }
0688 
0689     info->dma_map_ctrl = dma_map_ctrl;
0690 }
0691 
0692 struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
0693                      int endpoint_type,
0694                      int dir_in)
0695 {
0696     struct device *dev = usbhs_priv_to_dev(priv);
0697     struct usbhs_pipe *pipe;
0698     int is_host = usbhs_mod_is_host(priv);
0699     int ret;
0700     u16 pipecfg, pipebuf;
0701 
0702     pipe = usbhsp_get_pipe(priv, endpoint_type);
0703     if (!pipe) {
0704         dev_err(dev, "can't get pipe (%s)\n",
0705             usbhsp_pipe_name[endpoint_type]);
0706         return NULL;
0707     }
0708 
0709     INIT_LIST_HEAD(&pipe->list);
0710 
0711     usbhs_pipe_disable(pipe);
0712 
0713     /* make sure pipe is not busy */
0714     ret = usbhsp_pipe_barrier(pipe);
0715     if (ret < 0) {
0716         dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
0717         return NULL;
0718     }
0719 
0720     if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) {
0721         dev_err(dev, "can't setup pipe\n");
0722         return NULL;
0723     }
0724 
0725     pipebuf  = usbhsp_setup_pipebuff(pipe);
0726 
0727     usbhsp_pipe_select(pipe);
0728     usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
0729     usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
0730     usbhs_pipe_clear(pipe);
0731 
0732     usbhs_pipe_sequence_data0(pipe);
0733 
0734     dev_dbg(dev, "enable pipe %d : %s (%s)\n",
0735         usbhs_pipe_number(pipe),
0736         usbhs_pipe_name(pipe),
0737         usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
0738 
0739     /*
0740      * epnum / maxp are still not set to this pipe.
0741      * call usbhs_pipe_config_update() after this function !!
0742      */
0743 
0744     return pipe;
0745 }
0746 
0747 void usbhs_pipe_free(struct usbhs_pipe *pipe)
0748 {
0749     usbhsp_pipe_select(pipe);
0750     usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0);
0751     usbhsp_put_pipe(pipe);
0752 }
0753 
0754 void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
0755 {
0756     if (pipe->fifo)
0757         pipe->fifo->pipe = NULL;
0758 
0759     pipe->fifo = fifo;
0760 
0761     if (fifo)
0762         fifo->pipe = pipe;
0763 }
0764 
0765 
0766 /*
0767  *      dcp control
0768  */
0769 struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
0770 {
0771     struct usbhs_pipe *pipe;
0772 
0773     pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
0774     if (!pipe)
0775         return NULL;
0776 
0777     INIT_LIST_HEAD(&pipe->list);
0778 
0779     /*
0780      * call usbhs_pipe_config_update() after this function !!
0781      */
0782 
0783     return pipe;
0784 }
0785 
0786 void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
0787 {
0788     struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
0789 
0790     WARN_ON(!usbhs_pipe_is_dcp(pipe));
0791 
0792     usbhs_pipe_enable(pipe);
0793 
0794     if (!usbhs_mod_is_host(priv)) /* funconly */
0795         usbhsp_pipectrl_set(pipe, CCPL, CCPL);
0796 }
0797 
0798 void usbhs_dcp_dir_for_host(struct usbhs_pipe *pipe, int dir_out)
0799 {
0800     usbhsp_pipe_cfg_set(pipe, DIR_OUT,
0801                 dir_out ? DIR_OUT : 0);
0802 }
0803 
0804 /*
0805  *      pipe module function
0806  */
0807 int usbhs_pipe_probe(struct usbhs_priv *priv)
0808 {
0809     struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
0810     struct usbhs_pipe *pipe;
0811     struct device *dev = usbhs_priv_to_dev(priv);
0812     struct renesas_usbhs_driver_pipe_config *pipe_configs =
0813                     usbhs_get_dparam(priv, pipe_configs);
0814     int pipe_size = usbhs_get_dparam(priv, pipe_size);
0815     int i;
0816 
0817     /* This driver expects 1st pipe is DCP */
0818     if (pipe_configs[0].type != USB_ENDPOINT_XFER_CONTROL) {
0819         dev_err(dev, "1st PIPE is not DCP\n");
0820         return -EINVAL;
0821     }
0822 
0823     info->pipe = kcalloc(pipe_size, sizeof(struct usbhs_pipe),
0824                  GFP_KERNEL);
0825     if (!info->pipe)
0826         return -ENOMEM;
0827 
0828     info->size = pipe_size;
0829 
0830     /*
0831      * init pipe
0832      */
0833     usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
0834         pipe->priv = priv;
0835 
0836         usbhs_pipe_type(pipe) =
0837             pipe_configs[i].type & USB_ENDPOINT_XFERTYPE_MASK;
0838 
0839         dev_dbg(dev, "pipe %x\t: %s\n",
0840             i, usbhsp_pipe_name[pipe_configs[i].type]);
0841     }
0842 
0843     return 0;
0844 }
0845 
0846 void usbhs_pipe_remove(struct usbhs_priv *priv)
0847 {
0848     struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
0849 
0850     kfree(info->pipe);
0851 }