Beispiel #1
0
static void mxc_udc_queue_update(u8 epnum, u8 *data, u32 len, u32 tx)
{
	mxc_ep_t *ep;
	struct ep_queue_item *tqi, *head, *last;
	int send = 0;
	int in;

	head = last = NULL;
	in = ep_is_in(epnum, tx);
	ep = mxc_udc.mxc_ep + (epnum * 2 + in);
	DBG("epnum = %d,  in = %d\n", epnum, in);
	do {
		tqi = ep->ep_dtd[ep->index];
		DBG("%s, index = %d, tqi = %p\n", __func__, ep->index, tqi);
		while (mxc_tqi_is_busy(tqi))
			;
		mxc_tqi_init_page(tqi);
		DBG("%s, line = %d, len = %d\n", __func__, __LINE__, len);
		inc_index(ep->index);
		send = MIN(len, 0x1000);
		if (data) {
			memcpy((void *)tqi->page_vir, (void *)data, send);
			_dump_buf(tqi->page_vir, send);
		}
		if (!head)
			last = head = tqi;
		else {
			last->next_item_ptr = tqi->item_dma;
			last->next_item_vir = tqi;
			last = tqi;
		}
		if (!tx)
			tqi->reserved[0] = send;
		/* we set IOS for every dtd */
		tqi->info = ((send << 16) | (1 << 15) | (1 << 7));
		data += send;
		len -= send;
	} while (len);

	last->next_item_ptr = 0x1; /* end */
	if (ep->tail) {
		ep->tail->next_item_ptr = head->item_dma;
		ep->tail->next_item_vir = head;
		if (mxc_ep_xfer_is_working(ep, in)) {
			DBG("ep is working\n");
			goto out;
		}
	}
	mxc_update_qh(ep, head, in);
out:
	ep->tail = last;
}
Beispiel #2
0
static void mxc_udc_queue_update(u8 epnum,
	u8 *data, u32 len, u32 tx)
{
	struct mxc_ep_t *ep;
	struct ep_queue_item *tqi, *head, *last;
	int send = 0;
	int in;

	head = last = NULL;
	in = ep_is_in(epnum, tx);
	ep = mxc_udc.mxc_ep + (epnum * 2 + in);
	DBG("epnum = %d,  in = %d\n", epnum, in);
	do {
		tqi = ep->ep_dtd[ep->index];
		DBG("%s, index = %d, tqi = %p\n", __func__, ep->index, tqi);
		while (mxc_tqi_is_busy(tqi))
			;
		mxc_tqi_init_page(tqi);
		DBG("%s, line = %d, len = %d\n", __func__, __LINE__, len);
		inc_index(ep->index);
		send = MIN(len, ep->max_pkt_size);
		if (data) {
			memcpy((void *)tqi->page_vir, (void *)data, send);
			_dump_buf((u8 *)(tqi->page_vir), send);

			flush_dcache_range((unsigned long)(tqi->page_vir),
				CACHE_ALIGNED_END(tqi->page_vir, send));
		}
		if (!head)
			last = head = tqi;
		else {
			last->next_item_ptr = virt_to_phys(tqi);
			last->next_item_vir = tqi;
			last = tqi;
		}
		if (!tx)
			tqi->reserved[0] = send;
		/* we set IOC for every dtd */
		tqi->info = ((send << 16) | (1 << 15) | (1 << 7));
		data += send;
		len -= send;

		flush_dcache_range((unsigned long)tqi,
			CACHE_ALIGNED_END(tqi, sizeof(struct ep_queue_item)));
	} while (len);

	last->next_item_ptr = 0x1; /* end */
	flush_dcache_range((unsigned long)last,
			CACHE_ALIGNED_END(last, sizeof(struct ep_queue_item)));

	if (ep->tail) {
		ep->tail->next_item_ptr = virt_to_phys(head);
		ep->tail->next_item_vir = head;
		flush_dcache_range((unsigned long)(ep->tail),
			CACHE_ALIGNED_END(ep->tail, sizeof(struct ep_queue_item)));

		if (mxc_ep_xfer_is_working(ep, in)) {
			DBG("ep is working\n");
			goto out;
		}
	}
	mxc_update_qh(ep, head, in);
out:
	ep->tail = last;
}