cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pipe.c (17839B)


      1// SPDX-License-Identifier: GPL-1.0+
      2/*
      3 * Renesas USB driver
      4 *
      5 * Copyright (C) 2011 Renesas Solutions Corp.
      6 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
      7 */
      8#include <linux/delay.h>
      9#include <linux/slab.h>
     10#include "common.h"
     11#include "pipe.h"
     12
     13/*
     14 *		macros
     15 */
     16#define usbhsp_addr_offset(p)	((usbhs_pipe_number(p) - 1) * 2)
     17
     18#define usbhsp_flags_set(p, f)	((p)->flags |=  USBHS_PIPE_FLAGS_##f)
     19#define usbhsp_flags_clr(p, f)	((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
     20#define usbhsp_flags_has(p, f)	((p)->flags &   USBHS_PIPE_FLAGS_##f)
     21#define usbhsp_flags_init(p)	do {(p)->flags = 0; } while (0)
     22
     23/*
     24 * for debug
     25 */
     26static char *usbhsp_pipe_name[] = {
     27	[USB_ENDPOINT_XFER_CONTROL]	= "DCP",
     28	[USB_ENDPOINT_XFER_BULK]	= "BULK",
     29	[USB_ENDPOINT_XFER_INT]		= "INT",
     30	[USB_ENDPOINT_XFER_ISOC]	= "ISO",
     31};
     32
     33char *usbhs_pipe_name(struct usbhs_pipe *pipe)
     34{
     35	return usbhsp_pipe_name[usbhs_pipe_type(pipe)];
     36}
     37
     38static struct renesas_usbhs_driver_pipe_config
     39*usbhsp_get_pipe_config(struct usbhs_priv *priv, int pipe_num)
     40{
     41	struct renesas_usbhs_driver_pipe_config *pipe_configs =
     42					usbhs_get_dparam(priv, pipe_configs);
     43
     44	return &pipe_configs[pipe_num];
     45}
     46
     47/*
     48 *		DCPCTR/PIPEnCTR functions
     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 *		DCP/PIPE functions
     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 *		DCPCFG/PIPECFG functions
    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 *		PIPEnTRN/PIPEnTRE functions
    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	 * It is impossible to calculate address,
    123	 * since PIPEnTRN addresses were mapped randomly.
    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	 * It is impossible to calculate address,
    159	 * since PIPEnTRE addresses were mapped randomly.
    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 *		PIPEBUF
    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 *		DCPMAXP/PIPEMAXP
    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 *		pipe control functions
    208 */
    209static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
    210{
    211	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
    212
    213	/*
    214	 * On pipe, this is necessary before
    215	 * accesses to below registers.
    216	 *
    217	 * PIPESEL	: usbhsp_pipe_select
    218	 * PIPECFG	: usbhsp_pipe_cfg_xxx
    219	 * PIPEBUF	: usbhsp_pipe_buf_xxx
    220	 * PIPEMAXP	: usbhsp_pipe_maxp_xxx
    221	 * PIPEPERI
    222	 */
    223
    224	/*
    225	 * if pipe is dcp, no pipe is selected.
    226	 * it is no problem, because dcp have its register
    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 mask = usbhs_mod_is_host(priv) ? (CSSTS | PID_MASK) : PID_MASK;
    236
    237	/*
    238	 * make sure....
    239	 *
    240	 * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is
    241	 * specified by the CURPIPE bits.
    242	 * When changing the setting of this bit after changing
    243	 * the PID bits for the selected pipe from BUF to NAK,
    244	 * check that CSSTS = 0 and PBUSY = 0.
    245	 */
    246
    247	/*
    248	 * CURPIPE bit = 0
    249	 *
    250	 * see also
    251	 *  "Operation"
    252	 *  - "Pipe Control"
    253	 *   - "Pipe Control Registers Switching Procedure"
    254	 */
    255	usbhs_write(priv, CFIFOSEL, 0);
    256	usbhs_pipe_disable(pipe);
    257
    258	do {
    259		if (!(usbhsp_pipectrl_get(pipe) & mask))
    260			return 0;
    261
    262		udelay(10);
    263
    264	} while (timeout--);
    265
    266	return -EBUSY;
    267}
    268
    269int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
    270{
    271	u16 val;
    272
    273	val = usbhsp_pipectrl_get(pipe);
    274	if (val & BSTS)
    275		return 0;
    276
    277	return -EBUSY;
    278}
    279
    280bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe)
    281{
    282	u16 val;
    283
    284	/* Do not support for DCP pipe */
    285	if (usbhs_pipe_is_dcp(pipe))
    286		return false;
    287
    288	val = usbhsp_pipectrl_get(pipe);
    289	if (val & INBUFM)
    290		return true;
    291
    292	return false;
    293}
    294
    295/*
    296 *		PID ctrl
    297 */
    298static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
    299{
    300	u16 pid = usbhsp_pipectrl_get(pipe);
    301
    302	pid &= PID_MASK;
    303
    304	/*
    305	 * see
    306	 * "Pipe n Control Register" - "PID"
    307	 */
    308	switch (pid) {
    309	case PID_STALL11:
    310		usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
    311		fallthrough;
    312	case PID_STALL10:
    313		usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
    314	}
    315}
    316
    317void usbhs_pipe_disable(struct usbhs_pipe *pipe)
    318{
    319	int timeout = 1024;
    320	u16 val;
    321
    322	/* see "Pipe n Control Register" - "PID" */
    323	__usbhsp_pid_try_nak_if_stall(pipe);
    324
    325	usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
    326
    327	do {
    328		val  = usbhsp_pipectrl_get(pipe);
    329		val &= PBUSY;
    330		if (!val)
    331			break;
    332
    333		udelay(10);
    334	} while (timeout--);
    335}
    336
    337void usbhs_pipe_enable(struct usbhs_pipe *pipe)
    338{
    339	/* see "Pipe n Control Register" - "PID" */
    340	__usbhsp_pid_try_nak_if_stall(pipe);
    341
    342	usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
    343}
    344
    345void usbhs_pipe_stall(struct usbhs_pipe *pipe)
    346{
    347	u16 pid = usbhsp_pipectrl_get(pipe);
    348
    349	pid &= PID_MASK;
    350
    351	/*
    352	 * see
    353	 * "Pipe n Control Register" - "PID"
    354	 */
    355	switch (pid) {
    356	case PID_NAK:
    357		usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
    358		break;
    359	case PID_BUF:
    360		usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
    361		break;
    362	}
    363}
    364
    365int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
    366{
    367	u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK;
    368
    369	return (int)(pid == PID_STALL10 || pid == PID_STALL11);
    370}
    371
    372void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
    373{
    374	if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
    375		return;
    376
    377	/*
    378	 * clear and disable transfer counter for IN/OUT pipe
    379	 */
    380	usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR);
    381
    382	/*
    383	 * Only IN direction bulk pipe can use transfer count.
    384	 * Without using this function,
    385	 * received data will break if it was large data size.
    386	 * see PIPEnTRN/PIPEnTRE for detail
    387	 */
    388	if (usbhs_pipe_is_dir_in(pipe)) {
    389		int maxp = usbhs_pipe_get_maxpacket(pipe);
    390
    391		usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp));
    392		usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */
    393	}
    394}
    395
    396
    397/*
    398 *		pipe setup
    399 */
    400static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host,
    401				int dir_in, u16 *pipecfg)
    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	static const 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
    416	if (usbhs_pipe_is_dcp(pipe))
    417		return -EINVAL;
    418
    419	/*
    420	 * PIPECFG
    421	 *
    422	 * see
    423	 *  - "Register Descriptions" - "PIPECFG" register
    424	 *  - "Features"  - "Pipe configuration"
    425	 *  - "Operation" - "Pipe Control"
    426	 */
    427
    428	/* TYPE */
    429	type = type_array[usbhs_pipe_type(pipe)];
    430
    431	/* BFRE */
    432	if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
    433	    usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
    434		bfre = 0; /* FIXME */
    435
    436	/* DBLB: see usbhs_pipe_config_update() */
    437
    438	/* CNTMD */
    439	if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
    440		cntmd = 0; /* FIXME */
    441
    442	/* DIR */
    443	if (dir_in)
    444		usbhsp_flags_set(pipe, IS_DIR_HOST);
    445
    446	if (!!is_host ^ !!dir_in)
    447		dir |= DIR_OUT;
    448
    449	if (!dir)
    450		usbhsp_flags_set(pipe, IS_DIR_IN);
    451
    452	/* SHTNAK */
    453	if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
    454	    !dir)
    455		shtnak = SHTNAK;
    456
    457	/* EPNUM */
    458	epnum = 0; /* see usbhs_pipe_config_update() */
    459	*pipecfg = type		|
    460		   bfre		|
    461		   dblb		|
    462		   cntmd	|
    463		   dir		|
    464		   shtnak	|
    465		   epnum;
    466	return 0;
    467}
    468
    469static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
    470{
    471	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
    472	struct device *dev = usbhs_priv_to_dev(priv);
    473	int pipe_num = usbhs_pipe_number(pipe);
    474	u16 buff_size;
    475	u16 bufnmb;
    476	u16 bufnmb_cnt;
    477	struct renesas_usbhs_driver_pipe_config *pipe_config =
    478					usbhsp_get_pipe_config(priv, pipe_num);
    479
    480	/*
    481	 * PIPEBUF
    482	 *
    483	 * see
    484	 *  - "Register Descriptions" - "PIPEBUF" register
    485	 *  - "Features"  - "Pipe configuration"
    486	 *  - "Operation" - "FIFO Buffer Memory"
    487	 *  - "Operation" - "Pipe Control"
    488	 */
    489	buff_size = pipe_config->bufsize;
    490	bufnmb = pipe_config->bufnum;
    491
    492	/* change buff_size to register value */
    493	bufnmb_cnt = (buff_size / 64) - 1;
    494
    495	dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
    496		pipe_num, buff_size, bufnmb);
    497
    498	return	(0x1f & bufnmb_cnt)	<< 10 |
    499		(0xff & bufnmb)		<<  0;
    500}
    501
    502void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
    503			      u16 epnum, u16 maxp)
    504{
    505	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
    506	int pipe_num = usbhs_pipe_number(pipe);
    507	struct renesas_usbhs_driver_pipe_config *pipe_config =
    508					usbhsp_get_pipe_config(priv, pipe_num);
    509	u16 dblb = pipe_config->double_buf ? DBLB : 0;
    510
    511	if (devsel > 0xA) {
    512		struct device *dev = usbhs_priv_to_dev(priv);
    513
    514		dev_err(dev, "devsel error %d\n", devsel);
    515
    516		devsel = 0;
    517	}
    518
    519	usbhsp_pipe_barrier(pipe);
    520
    521	pipe->maxp = maxp;
    522
    523	usbhsp_pipe_select(pipe);
    524	usbhsp_pipe_maxp_set(pipe, 0xFFFF,
    525			     (devsel << 12) |
    526			     maxp);
    527
    528	if (!usbhs_pipe_is_dcp(pipe))
    529		usbhsp_pipe_cfg_set(pipe,  0x000F | DBLB, epnum | dblb);
    530}
    531
    532/*
    533 *		pipe control
    534 */
    535int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
    536{
    537	/*
    538	 * see
    539	 *	usbhs_pipe_config_update()
    540	 *	usbhs_dcp_malloc()
    541	 */
    542	return pipe->maxp;
    543}
    544
    545int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
    546{
    547	return usbhsp_flags_has(pipe, IS_DIR_IN);
    548}
    549
    550int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
    551{
    552	return usbhsp_flags_has(pipe, IS_DIR_HOST);
    553}
    554
    555int usbhs_pipe_is_running(struct usbhs_pipe *pipe)
    556{
    557	return usbhsp_flags_has(pipe, IS_RUNNING);
    558}
    559
    560void usbhs_pipe_running(struct usbhs_pipe *pipe, int running)
    561{
    562	if (running)
    563		usbhsp_flags_set(pipe, IS_RUNNING);
    564	else
    565		usbhsp_flags_clr(pipe, IS_RUNNING);
    566}
    567
    568void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence)
    569{
    570	u16 mask = (SQCLR | SQSET);
    571	u16 val;
    572
    573	/*
    574	 * sequence
    575	 *  0  : data0
    576	 *  1  : data1
    577	 *  -1 : no change
    578	 */
    579	switch (sequence) {
    580	case 0:
    581		val = SQCLR;
    582		break;
    583	case 1:
    584		val = SQSET;
    585		break;
    586	default:
    587		return;
    588	}
    589
    590	usbhsp_pipectrl_set(pipe, mask, val);
    591}
    592
    593static int usbhs_pipe_get_data_sequence(struct usbhs_pipe *pipe)
    594{
    595	return !!(usbhsp_pipectrl_get(pipe) & SQMON);
    596}
    597
    598void usbhs_pipe_clear(struct usbhs_pipe *pipe)
    599{
    600	if (usbhs_pipe_is_dcp(pipe)) {
    601		usbhs_fifo_clear_dcp(pipe);
    602	} else {
    603		usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
    604		usbhsp_pipectrl_set(pipe, ACLRM, 0);
    605	}
    606}
    607
    608/* Should call usbhsp_pipe_select() before */
    609void usbhs_pipe_clear_without_sequence(struct usbhs_pipe *pipe,
    610				       int needs_bfre, int bfre_enable)
    611{
    612	int sequence;
    613
    614	usbhsp_pipe_select(pipe);
    615	sequence = usbhs_pipe_get_data_sequence(pipe);
    616	if (needs_bfre)
    617		usbhsp_pipe_cfg_set(pipe, BFRE, bfre_enable ? BFRE : 0);
    618	usbhs_pipe_clear(pipe);
    619	usbhs_pipe_data_sequence(pipe, sequence);
    620}
    621
    622void usbhs_pipe_config_change_bfre(struct usbhs_pipe *pipe, int enable)
    623{
    624	if (usbhs_pipe_is_dcp(pipe))
    625		return;
    626
    627	usbhsp_pipe_select(pipe);
    628	/* check if the driver needs to change the BFRE value */
    629	if (!(enable ^ !!(usbhsp_pipe_cfg_get(pipe) & BFRE)))
    630		return;
    631
    632	usbhs_pipe_clear_without_sequence(pipe, 1, enable);
    633}
    634
    635static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
    636{
    637	struct usbhs_pipe *pos, *pipe;
    638	int i;
    639
    640	/*
    641	 * find target pipe
    642	 */
    643	pipe = NULL;
    644	usbhs_for_each_pipe_with_dcp(pos, priv, i) {
    645		if (!usbhs_pipe_type_is(pos, type))
    646			continue;
    647		if (usbhsp_flags_has(pos, IS_USED))
    648			continue;
    649
    650		pipe = pos;
    651		break;
    652	}
    653
    654	if (!pipe)
    655		return NULL;
    656
    657	/*
    658	 * initialize pipe flags
    659	 */
    660	usbhsp_flags_init(pipe);
    661	usbhsp_flags_set(pipe, IS_USED);
    662
    663	return pipe;
    664}
    665
    666static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
    667{
    668	usbhsp_flags_init(pipe);
    669}
    670
    671void usbhs_pipe_init(struct usbhs_priv *priv,
    672		     int (*dma_map_ctrl)(struct device *dma_dev,
    673					 struct usbhs_pkt *pkt, int map))
    674{
    675	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
    676	struct usbhs_pipe *pipe;
    677	int i;
    678
    679	usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
    680		usbhsp_flags_init(pipe);
    681		pipe->fifo = NULL;
    682		pipe->mod_private = NULL;
    683		INIT_LIST_HEAD(&pipe->list);
    684
    685		/* pipe force init */
    686		usbhs_pipe_clear(pipe);
    687	}
    688
    689	info->dma_map_ctrl = dma_map_ctrl;
    690}
    691
    692struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
    693				     int endpoint_type,
    694				     int dir_in)
    695{
    696	struct device *dev = usbhs_priv_to_dev(priv);
    697	struct usbhs_pipe *pipe;
    698	int is_host = usbhs_mod_is_host(priv);
    699	int ret;
    700	u16 pipecfg, pipebuf;
    701
    702	pipe = usbhsp_get_pipe(priv, endpoint_type);
    703	if (!pipe) {
    704		dev_err(dev, "can't get pipe (%s)\n",
    705			usbhsp_pipe_name[endpoint_type]);
    706		return NULL;
    707	}
    708
    709	INIT_LIST_HEAD(&pipe->list);
    710
    711	usbhs_pipe_disable(pipe);
    712
    713	/* make sure pipe is not busy */
    714	ret = usbhsp_pipe_barrier(pipe);
    715	if (ret < 0) {
    716		dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
    717		return NULL;
    718	}
    719
    720	if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) {
    721		dev_err(dev, "can't setup pipe\n");
    722		return NULL;
    723	}
    724
    725	pipebuf  = usbhsp_setup_pipebuff(pipe);
    726
    727	usbhsp_pipe_select(pipe);
    728	usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
    729	usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
    730	usbhs_pipe_clear(pipe);
    731
    732	usbhs_pipe_sequence_data0(pipe);
    733
    734	dev_dbg(dev, "enable pipe %d : %s (%s)\n",
    735		usbhs_pipe_number(pipe),
    736		usbhs_pipe_name(pipe),
    737		usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
    738
    739	/*
    740	 * epnum / maxp are still not set to this pipe.
    741	 * call usbhs_pipe_config_update() after this function !!
    742	 */
    743
    744	return pipe;
    745}
    746
    747void usbhs_pipe_free(struct usbhs_pipe *pipe)
    748{
    749	usbhsp_pipe_select(pipe);
    750	usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0);
    751	usbhsp_put_pipe(pipe);
    752}
    753
    754void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
    755{
    756	if (pipe->fifo)
    757		pipe->fifo->pipe = NULL;
    758
    759	pipe->fifo = fifo;
    760
    761	if (fifo)
    762		fifo->pipe = pipe;
    763}
    764
    765
    766/*
    767 *		dcp control
    768 */
    769struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
    770{
    771	struct usbhs_pipe *pipe;
    772
    773	pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
    774	if (!pipe)
    775		return NULL;
    776
    777	INIT_LIST_HEAD(&pipe->list);
    778
    779	/*
    780	 * call usbhs_pipe_config_update() after this function !!
    781	 */
    782
    783	return pipe;
    784}
    785
    786void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
    787{
    788	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
    789
    790	WARN_ON(!usbhs_pipe_is_dcp(pipe));
    791
    792	usbhs_pipe_enable(pipe);
    793
    794	if (!usbhs_mod_is_host(priv)) /* funconly */
    795		usbhsp_pipectrl_set(pipe, CCPL, CCPL);
    796}
    797
    798void usbhs_dcp_dir_for_host(struct usbhs_pipe *pipe, int dir_out)
    799{
    800	usbhsp_pipe_cfg_set(pipe, DIR_OUT,
    801			    dir_out ? DIR_OUT : 0);
    802}
    803
    804/*
    805 *		pipe module function
    806 */
    807int usbhs_pipe_probe(struct usbhs_priv *priv)
    808{
    809	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
    810	struct usbhs_pipe *pipe;
    811	struct device *dev = usbhs_priv_to_dev(priv);
    812	struct renesas_usbhs_driver_pipe_config *pipe_configs =
    813					usbhs_get_dparam(priv, pipe_configs);
    814	int pipe_size = usbhs_get_dparam(priv, pipe_size);
    815	int i;
    816
    817	/* This driver expects 1st pipe is DCP */
    818	if (pipe_configs[0].type != USB_ENDPOINT_XFER_CONTROL) {
    819		dev_err(dev, "1st PIPE is not DCP\n");
    820		return -EINVAL;
    821	}
    822
    823	info->pipe = kcalloc(pipe_size, sizeof(struct usbhs_pipe),
    824			     GFP_KERNEL);
    825	if (!info->pipe)
    826		return -ENOMEM;
    827
    828	info->size = pipe_size;
    829
    830	/*
    831	 * init pipe
    832	 */
    833	usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
    834		pipe->priv = priv;
    835
    836		usbhs_pipe_type(pipe) =
    837			pipe_configs[i].type & USB_ENDPOINT_XFERTYPE_MASK;
    838
    839		dev_dbg(dev, "pipe %x\t: %s\n",
    840			i, usbhsp_pipe_name[pipe_configs[i].type]);
    841	}
    842
    843	return 0;
    844}
    845
    846void usbhs_pipe_remove(struct usbhs_priv *priv)
    847{
    848	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
    849
    850	kfree(info->pipe);
    851}