コード例 #1
0
/*
  ret < 0  : error
  ret == 0 : no data
  ret > 0  : valid data
*/
static int dpram_ipc_recv_data(struct dpram_link_device *dpld, int dev)
{
	struct link_device *ld = &dpld->ld;
	struct dpram_rxb *rxb;
	u8 __iomem *src = get_rx_buff(dpld, dev);
	u32 qsize = get_rx_buff_size(dpld, dev);
	u32 in = get_rx_head(dpld, dev);
	u32 out = get_rx_tail(dpld, dev);
	u32 rcvd = 0;
	struct mif_irq_map map;

	if (in == out)
		return 0;

	if (dev == IPC_FMT) {
		set_dpram_map(dpld, &map);
		mif_irq_log(ld->mc->msd, map, "ipc_recv", sizeof("ipc_recv"));
	}

	/* Get data length in DPRAM*/
	rcvd = (in > out) ? (in - out) : (qsize - out + in);

	mif_debug("%s: %s qsize[%u] in[%u] out[%u] rcvd[%u]\n",
		ld->name, get_dev_name(dev), qsize, in, out, rcvd);

	/* Check each queue */
	if (!dpram_circ_valid(qsize, in, out)) {
		mif_err("%s: ERR! %s_RXQ invalid (size:%d in:%d out:%d)\n",
			ld->name, get_dev_name(dev), qsize, in, out);
#if 0
		set_rx_head(dpld, dev, 0);
		set_rx_tail(dpld, dev, 0);
#else
		dpram_trigger_force_cp_crash(dpld);
#endif
		return -EINVAL;
	}

	/* Allocate an rxb */
	rxb = rxbq_get_free_rxb(&dpld->rxbq[dev]);
	if (!rxb) {
		mif_info("%s: ERR! %s rxbq_get_free_rxb fail\n",
			ld->name, get_dev_name(dev));
		return -ENOMEM;
	}

	/* Read data from each DPRAM buffer */
	dpram_ipc_read(dpld, dev, rxb_put(rxb, rcvd), src, out, rcvd, qsize);

	/* Calculate and set new out */
	out += rcvd;
	if (out >= qsize)
		out -= qsize;
	set_rx_tail(dpld, dev, out);

	return rcvd;
}
コード例 #2
0
/* Get data size in the RXQ as well as in & out pointers */
static inline int dpram_get_rxq_rcvd(struct dpram_link_device *dpld, int dev,
		u32 qsize, u32 *in, u32 *out)
{
	struct link_device *ld = &dpld->ld;
	int cnt = 3;
	u32 head;
	u32 tail;
	u32 rcvd;

	do {
		head = get_rx_head(dpld, dev);
		tail = get_rx_tail(dpld, dev);
		if (head == tail) {
			*in = head;
			*out = tail;
			return 0;
		}

		rcvd = (head > tail) ? (head - tail) : (qsize - tail + head);
		mif_debug("%s: %s_RXQ qsize[%u] in[%u] out[%u] rcvd[%u]\n",
			ld->name, get_dev_name(dev), qsize, head, tail, rcvd);

		if (dpram_circ_valid(qsize, head, tail)) {
			*in = head;
			*out = tail;
			return rcvd;
		}

		mif_info("%s: CAUTION! <%pf> "
			"%s_RXQ invalid (size:%d in:%d out:%d)\n",
			ld->name, __builtin_return_address(0),
			get_dev_name(dev), qsize, head, tail);

		udelay(100);
	} while (cnt--);

	*in = 0;
	*out = 0;
	return -EINVAL;
}
コード例 #3
0
/* get free space in the TXQ as well as in & out pointers */
static inline int get_txq_space(struct dpram_link_device *dpld, int dev,
		u32 qsize, u32 *in, u32 *out)
{
	struct link_device *ld = &dpld->ld;
	int cnt = 3;
	int space;

	do {
		*in = get_tx_head(dpld, dev);
		*out = get_tx_tail(dpld, dev);

		if (dpram_circ_valid(qsize, *in, *out)) {
			space = (*in < *out) ? (*out - *in - 1) :
				(qsize + *out - *in - 1);
			return space;
		}

		mif_info("%s: CAUTION! <%pf> "
			"%s_TXQ invalid (size:%d in:%d out:%d)\n",
			ld->name, __builtin_return_address(0),
			get_dev_name(dev), qsize, *in, *out);

		udelay(100);
	} while (cnt--);

	if (dev == IPC_FMT) {
		dpram_trigger_force_cp_crash(dpld);
	} else {
		set_tx_head(dpld, dev, 0);
		set_tx_tail(dpld, dev, 0);
	}

	*in = 0;
	*out = 0;
	return -EINVAL;
}
コード例 #4
0
/* Get free space in the TXQ as well as in & out pointers */
static inline int dpram_get_txq_space(struct dpram_link_device *dpld, int dev,
		u32 qsize, u32 *in, u32 *out)
{
	struct link_device *ld = &dpld->ld;
	int cnt = 3;
	u32 head;
	u32 tail;
	int space;

	do {
		head = get_tx_head(dpld, dev);
		tail = get_tx_tail(dpld, dev);

		space = (head < tail) ? (tail - head - 1) :
			(qsize + tail - head - 1);
		mif_debug("%s: %s_TXQ qsize[%u] in[%u] out[%u] space[%u]\n",
			ld->name, get_dev_name(dev), qsize, head, tail, space);

		if (dpram_circ_valid(qsize, head, tail)) {
			*in = head;
			*out = tail;
			return space;
		}

		mif_info("%s: CAUTION! <%pf> "
			"%s_TXQ invalid (size:%d in:%d out:%d)\n",
			ld->name, __builtin_return_address(0),
			get_dev_name(dev), qsize, head, tail);

		udelay(100);
	} while (cnt--);

	*in = 0;
	*out = 0;
	return -EINVAL;
}