Ejemplo n.º 1
0
/*
 * handle_epinirq()
*/
static int write_ep_fifo(struct rt_ep_struct *rt_ep, struct rt_request *req)
{
	u8	*buf, epcs;
	int	length, i, ep_no = EP_NO(rt_ep);

DBG;
	xprintk("w ep%d req=%p,r.l=%d,r.a=%d\n",EP_NO(rt_ep),&req->req,req->req.length,req->req.actual);
	epcs = read_epcs(rt_ep);
	if(epcs & EP_CS_BSY)
		FATAL_ERROR("EP%d busy. epcs=%x\n", ep_no, epcs);

	/* check INEP byte count is zero? */
	if(read_inbc(ep_no))
		FATAL_ERROR("EP%d bc=%d\n", ep_no, read_inbc(ep_no));

	buf = req->req.buf + req->req.actual;
	length = (req->req.length - req->req.actual) < rt_ep->ep.maxpacket ? (req->req.length - req->req.actual) : rt_ep->ep.maxpacket;
	req->req.actual += length;
	if (!length) {	/* zlp */
		// for debug
		xprintk("<%s> zero packet\n", __func__);
		write_ep_fifo_zlp(rt_ep);
		return 0;
	}

	// write to ep in fifo
	for (i=0; i< length; i++)
		usb_write(0x80+ep_no*4, *buf++);

	epcs = read_epcs(rt_ep);
	write_epcs(rt_ep, epcs);

	return length;
}
Ejemplo n.º 2
0
static int read_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
{
	int 	bytes = 0,
		count,
		completed = 0;

	while (__raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)))
		& FSTAT_FR) {
			count = read_packet(imx_ep, req);
			bytes += count;

			completed = (count != imx_ep->fifosize);
			if (completed || req->req.actual == req->req.length) {
				completed = 1;
				break;
			}
	}

	if (completed || !req->req.length) {
		done(imx_ep, req, 0);
		D_REQ(imx_ep->imx_usb->dev, "<%s> %s req<%p> %s\n",
			__func__, imx_ep->ep.name, req,
			completed ? "completed" : "not completed");
		if (!EP_NO(imx_ep))
			ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE);
	}

	D_TRX(imx_ep->imx_usb->dev, "<%s> bytes read: %d\n", __func__, bytes);

	return completed;
}
Ejemplo n.º 3
0
void imx_flush(struct imx_ep_struct *imx_ep)
{
	struct imx_udc_struct *imx_usb = imx_ep->imx_usb;

	int temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
	__raw_writel(temp | EPSTAT_FLUSH,
		imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
}
Ejemplo n.º 4
0
int imx_ep_empty(struct imx_ep_struct *imx_ep)
{
	struct imx_udc_struct *imx_usb = imx_ep->imx_usb;

	return __raw_readl(imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)))
			& FSTAT_EMPTY;
}
Ejemplo n.º 5
0
unsigned imx_fifo_bcount(struct imx_ep_struct *imx_ep)
{
	struct imx_udc_struct *imx_usb = imx_ep->imx_usb;

	return (__raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)))
			& EPSTAT_BCOUNT) >> 16;
}
Ejemplo n.º 6
0
/*
 *******************************************************************************
 * Data tansfer over USB functions
 *******************************************************************************
 */
static int read_ep0_fifo(struct rt_ep_struct *rt_ep, struct rt_request *req)
{
	u8	*buf;
	int	byte_count, req_bufferspace, count, i;

DBG;
	if(!in_irq())
		FATAL_ERROR("not irq context.");

	byte_count = read_outbc(EP_NO(rt_ep));
	req_bufferspace = req->req.length - req->req.actual;

	buf = req->req.buf + req->req.actual;

	if(!req_bufferspace)
		FATAL_ERROR("zlp");

	if(byte_count > req_bufferspace)
		FATAL_ERROR("buffer overflow, byte_count=%d, req->req.length=%d, req->req.actual=%d\n", byte_count, req->req.length ,req->req.actual);

	count = min(byte_count, req_bufferspace);


	for (i = 0; i < count; i++){
		*buf = usb_read(EP0OUTDAT+i);
		buf++;
	}
	req->req.actual += count;

	return count;
}
Ejemplo n.º 7
0
static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
{
	int	bytes = 0,
		count,
		completed = 0;

	while (!completed) {
		count = write_packet(imx_ep, req);
		if (count < 0)
			break; /*      */
		bytes += count;

		/*                                        */
		completed = (count != imx_ep->fifosize);

		if (unlikely(completed)) {
			done(imx_ep, req, 0);
			D_REQ(imx_ep->imx_usb->dev, "<%s> %s req<%p> %s\n",
				__func__, imx_ep->ep.name, req,
				completed ? "completed" : "not completed");
			if (!EP_NO(imx_ep))
				ep0_chg_stat(__func__,
						imx_ep->imx_usb, EP0_IDLE);
		}
	}

	D_TRX(imx_ep->imx_usb->dev, "<%s> bytes sent: %d\n", __func__, bytes);

	return completed;
}
Ejemplo n.º 8
0
void imx_ep_irq_disable(struct imx_ep_struct *imx_ep)
{

	int i = EP_NO(imx_ep);

	__raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_MASK(i));
	__raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_INTR(i));
}
Ejemplo n.º 9
0
static void write_epcs(struct rt_ep_struct *rt_ep, u8 val)
{
	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0)
		usb_write(EP0CS, val);
	else
		(dir == EP_IN ? /*IN */ usb_write(0x7 + idx*8, val) : usb_write(0x3 + idx*8, val) );
}
Ejemplo n.º 10
0
static u8 read_epcs(struct rt_ep_struct *rt_ep)
{
	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0)
		return usb_read(EP0CS);

	return (dir == EP_IN ? usb_read(0x7 + idx*8) : usb_read(0x3 + idx*8) );
}
Ejemplo n.º 11
0
static int write_ep_fifo_zlp(struct rt_ep_struct *rt_ep)
{
	u8	epcs;
	int	ep_no = EP_NO(rt_ep);

DBG;
	xprintk("w%d ZLP\n", EP_NO(rt_ep));
	epcs = read_epcs(rt_ep);
	if(epcs & EP_CS_BSY)
		FATAL_ERROR("EP%d busy. cs=%x\n", ep_no, epcs);

	/* check INEP byte count is zero? */
	if(read_inbc(ep_no))
		FATAL_ERROR("EP%d bc zero. bc=%d\n", ep_no, read_inbc(ep_no));

	epcs = read_epcs(rt_ep);
	write_epcs(rt_ep, epcs);
	return 0;
}
Ejemplo n.º 12
0
void imx_ep_irq_enable(struct imx_ep_struct *imx_ep)
{

	int i = EP_NO(imx_ep);

	__raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_MASK(i));
	__raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_INTR(i));
	__raw_writel(0x1FF & ~(EPINTR_EOT | EPINTR_EOF),
		imx_ep->imx_usb->base + USB_EP_MASK(i));
}
Ejemplo n.º 13
0
static void rt_ep_rst(struct rt_ep_struct *rt_ep)
{
	u8 reg = 0;
	u8 idx = EP_NO(rt_ep);
	u8 dir = EP_DIR(rt_ep);
	if(dir == EP_IN )
		reg |= ENDPRST_IO | idx;
	usb_write(ENDPRST, reg);

	reg |= ENDPRST_TOGRST | ENDPRST_FIFORST;
	usb_write(ENDPRST, reg);	        
}
Ejemplo n.º 14
0
void imx_ep_stall(struct imx_ep_struct *imx_ep)
{
	struct imx_udc_struct *imx_usb = imx_ep->imx_usb;
	int temp, i;

	D_ERR(imx_usb->dev,
		"<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);

	imx_flush(imx_ep);

	/*                      */
	if (!EP_NO(imx_ep)) {
		temp = __raw_readl(imx_usb->base + USB_CTRL);
		__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR,
						imx_usb->base + USB_CTRL);
		do { } while (__raw_readl(imx_usb->base + USB_CTRL)
						& CTRL_CMDOVER);
		temp = __raw_readl(imx_usb->base + USB_CTRL);
		__raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL);
	}
	else {
		temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
		__raw_writel(temp | EPSTAT_STALL,
			imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));

		for (i = 0; i < 100; i ++) {
			temp = __raw_readl(imx_usb->base
						+ USB_EP_STAT(EP_NO(imx_ep)));
			if (!(temp & EPSTAT_STALL))
	 			break;
	 		udelay(20);
	 	}
		if (i == 100)
			D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
				__func__, imx_ep->ep.name);
	}
}
Ejemplo n.º 15
0
static void rt_ep_irq_disable(struct rt_ep_struct *rt_ep)
{
	u8 reg;
	u8 idx = EP_NO(rt_ep);
	u8 dir = EP_DIR(rt_ep);

	if(idx == 0 /* ep0 */){
		usb_write(IN07IEN, (usb_read(IN07IEN) & ~(0x1)) );
		usb_write(OUT07IEN, (usb_read(OUT07IEN) & ~(0x1)) );
	}else{
		reg = usb_read(dir ? IN07IEN : OUT07IEN);
		reg = reg & ~(0x1 << idx);
		usb_write(dir == EP_IN ? IN07IEN : OUT07IEN, reg);
		reg = usb_read(dir ? IN07IEN : OUT07IEN);
	}
}
Ejemplo n.º 16
0
void rt_ep_stall(struct rt_ep_struct *rt_ep)
{
	u8 tmp;
	u32 addr;
	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0){
		tmp = usb_read(EP0CS);
		tmp |= 0x1;
		usb_write(EP0CS, tmp);
	}else{
		addr = (dir == EP_IN ? 0x006 : 0x002) + idx * 8;
		tmp = usb_read(addr);
		tmp |= 0x40;
		usb_write(addr, tmp);
	}
	return;
}
Ejemplo n.º 17
0
static u32 rt_fifo_bcount(struct rt_ep_struct *rt_ep)
{
	u8 low, high;
	u32 rc;

	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0)
		return 0;

	if(dir /* IN */){
		low = usb_read(0x004 + idx*8);
		high = usb_read( (0x004 + idx*8)+1 );
	}else{  /* OUT */
		low = usb_read(0x000 + idx*8);
		high = usb_read( (0x000 + idx*8)+1 );
	}
	rc = high | low;
	return rc;
}
Ejemplo n.º 18
0
static int write_packet(struct imx_ep_struct *imx_ep, struct imx_request *req)
{
	u8	*buf;
	int	length, count, temp;

	if (unlikely(__raw_readl(imx_ep->imx_usb->base +
				 USB_EP_STAT(EP_NO(imx_ep))) & EPSTAT_ZLPS)) {
		D_TRX(imx_ep->imx_usb->dev, "<%s> zlp still queued in EP %s\n",
			__func__, imx_ep->ep.name);
		return -1;
	}

	buf = req->req.buf + req->req.actual;
	prefetch(buf);

	length = min(req->req.length - req->req.actual, (u32)imx_ep->fifosize);

	if (imx_fifo_bcount(imx_ep) + length > imx_ep->fifosize) {
		D_TRX(imx_ep->imx_usb->dev, "<%s> packet overfill %s fifo\n",
			__func__, imx_ep->ep.name);
		return -1;
	}

	req->req.actual += length;
	count = length;

	if (!count && req->req.zero) {	/*     */
		temp = __raw_readl(imx_ep->imx_usb->base
			+ USB_EP_STAT(EP_NO(imx_ep)));
		__raw_writel(temp | EPSTAT_ZLPS, imx_ep->imx_usb->base
			+ USB_EP_STAT(EP_NO(imx_ep)));
		D_TRX(imx_ep->imx_usb->dev, "<%s> zero packet\n", __func__);
		return 0;
	}

	while (count--) {
		if (count == 0) {	/*           */
			temp = __raw_readl(imx_ep->imx_usb->base
				+ USB_EP_FCTRL(EP_NO(imx_ep)));
			__raw_writel(temp | FCTRL_WFR, imx_ep->imx_usb->base
				+ USB_EP_FCTRL(EP_NO(imx_ep)));
		}
		__raw_writeb(*buf++,
			imx_ep->imx_usb->base + USB_EP_FDAT0(EP_NO(imx_ep)));
	}

	return length;
}
Ejemplo n.º 19
0
static int read_packet(struct imx_ep_struct *imx_ep, struct imx_request *req)
{
	u8	*buf;
	int	bytes_ep, bufferspace, count, i;

	bytes_ep = imx_fifo_bcount(imx_ep);
	bufferspace = req->req.length - req->req.actual;

	buf = req->req.buf + req->req.actual;
	prefetchw(buf);

	if (unlikely(imx_ep_empty(imx_ep)))
		count = 0;	/*     */
	else
		count = min(bytes_ep, bufferspace);

	for (i = count; i > 0; i--)
		*buf++ = __raw_readb(imx_ep->imx_usb->base
						+ USB_EP_FDAT0(EP_NO(imx_ep)));
	req->req.actual += count;

	return count;
}
Ejemplo n.º 20
0
static int read_ep_fifo(struct rt_ep_struct *rt_ep, struct rt_request *req)
{
	u8	*buf, ep_no, ep_no_shift;
	int	byte_count, req_bufferspace, count, i;

DBG;
	ep_no = EP_NO(rt_ep);

	byte_count = read_outbc(ep_no);
	if(unlikely(!byte_count))
		FATAL_ERROR("ep_no:%d bc = 0", ep_no);

	req_bufferspace = req->req.length - req->req.actual;

	buf = req->req.buf + req->req.actual;

	if(unlikely(!req_bufferspace))
		FATAL_ERROR("zlp");

	xprintk("bc=%d,r.l=%d,r.a=%d\n", byte_count, req->req.length ,req->req.actual);
	if(unlikely(byte_count > req_bufferspace))
		FATAL_ERROR("buffer overflow, byte_count=%d, req->req.length=%d, req->req.actual=%d\n", byte_count, req->req.length ,req->req.actual);

	count = min(byte_count, req_bufferspace);

	ep_no_shift = 0x80+ep_no * 4;
	for (i = 0; i < count; i++){
		*buf = usb_read(ep_no_shift);
		buf++;
	}

	req->req.actual += count;

	// EP Out irq handler would arm another transaction.
	return count;
}