Пример #1
0
//Poll a interrupt queue,check if the queue has been processed.
//Please note it's a blocking poll,since HelloX's event mechanism is adopted.
void* EHCIPollIntQueue(struct usb_device *dev,struct int_queue *queue)
{
	DWORD dwResult = 0;
	void* pRet = NULL;

	dwResult = WaitForThisObjectEx(queue->hEvent, 5);  //Wait for 5 millionseconds.
	switch (dwResult)
	{
	case OBJECT_WAIT_RESOURCE:
		if (INT_QUEUE_STATUS_COMPLETED == queue->dwStatus)
		{
			pRet = queue->first->buffer;
		}
		break;
	case OBJECT_WAIT_TIMEOUT:
	case OBJECT_WAIT_DELETED:
	case OBJECT_WAIT_FAILED:
		//Just for debugging.
		if (_ehciQueueIntHandler(queue))
		{
			pRet = queue->first->buffer;
			debug("%s: Transimit success,int queue status = %X,overlay token = %X,qTD token = %X.\r\n", 
				__func__,
				queue->dwStatus,
				queue->first->qh_overlay.qt_token,
				queue->tds->qt_token);
			return pRet;
		}
		else
		{
			debug("%s: Transmit failed,int queue status = %X,overlay_tok = %X,qTD_tok = %X.\r\n",
				__func__,
				queue->dwStatus,
				queue->current->qh_overlay.qt_token,
				queue->tds[queue->current - queue->first].qt_token);
			return pRet;
		}
		queue->dwStatus = INT_QUEUE_STATUS_CANCELED;
		break;
	default:
		BUG();
		break;
	}
	return pRet;
}
Пример #2
0
//Start USB isochronous transfer.
BOOL usbStartISOXfer(__USB_ISO_DESCRIPTOR* pIsoDesc)
{
	__COMMON_USB_CONTROLLER* pCommCtrl = NULL;
	struct iTD* pitd = NULL;
	struct usb_device* pUsbDev = NULL;
	struct ehci_ctrl* pEhciCtrl = NULL;
	DWORD dwResult = 0;
	BOOL bResult = FALSE;
	//int transact = 0;

	if (NULL == pIsoDesc)
	{
		goto __TERMINAL;
	}
	pCommCtrl = pIsoDesc->pCtrl;
	pUsbDev = pIsoDesc->pPhyDev->lpPrivateInfo;
	if ((NULL == pCommCtrl) || (NULL == pUsbDev))
	{
		BUG();
	}
	pitd = pIsoDesc->itdArray;
	pEhciCtrl = pCommCtrl->pUsbCtrl;
	if ((NULL == pitd) || (NULL == pEhciCtrl))
	{
		BUG();
	}
	//Set descriptor's status accordingly.
	pIsoDesc->status = USB_ISODESC_STATUS_INPROCESS;
	ResetEvent(pIsoDesc->hEvent);

#if 0
	//Set the act bit of each transaction(s) iTD descriptor,so controller will process it.
	for (int transact = 0; transact < 8; transact++)
	{
		if (0 == pitd->transaction[transact])  //Reach the end.
		{
			break;
		}
		pitd->transaction[transact] |= ITD_TRANS_STATUS_SET(ITD_TRANS_STATUS_ACT);
		//Just for debugging.__Fill_iTD should be called here...
		pitd->transaction[0] &= 0xF000FFFF;
		pitd->transaction[0] |= ITD_TRANS_XLEN_SET(pIsoDesc->bufflength);
	}
#endif
	//Fill iTD's all variable fields.
	__Fill_iTD(pIsoDesc, pitd, pIsoDesc->direction, pIsoDesc->buffer, pIsoDesc->bufflength, pIsoDesc->endpoint, 
		pIsoDesc->maxPacketSize, pIsoDesc->multi);
	flush_dcache_range((unsigned long)pitd,
		ALIGN_END_ADDR(struct iTD, pitd, 1));

	//Start periodic schedule if not yet.
	WaitForThisObject(pEhciCtrl->hMutex);
	if (pEhciCtrl->periodic_schedules == 0)
	{
		ehci_enable_periodic(pEhciCtrl);
		pEhciCtrl->periodic_schedules++;
	}
	ReleaseMutex(pEhciCtrl->hMutex);

	//Pending on the descriptor to wait the arrival of data.
	dwResult = WaitForThisObjectEx(pIsoDesc->hEvent, USB_DEFAULT_XFER_TIMEOUT);
	switch (dwResult)
	{
	case OBJECT_WAIT_RESOURCE:
		if (USB_ISODESC_STATUS_COMPLETED == pIsoDesc->status)
		{
			bResult = TRUE;
			break;
		}
		if (USB_ISODESC_STATUS_ERROR == pIsoDesc->status)
		{
			//Try to restore from error.
			//IsoClearError(pIsoDesc);

			//Clear the act bit.
			pitd->transaction[0] &= ~0x80000000;
			pitd->transaction[1] &= ~0x80000000;
			pitd->transaction[2] &= ~0x80000000;
			pitd->transaction[3] &= ~0x80000000;
			pitd->transaction[4] &= ~0x80000000;
			pitd->transaction[5] &= ~0x80000000;
			pitd->transaction[6] &= ~0x80000000;
			pitd->transaction[7] &= ~0x80000000;
			flush_dcache_range((unsigned long)pitd,
				ALIGN_END_ADDR(struct iTD, pitd, 1));
			break;
		}
		BUG();
		break;
	case OBJECT_WAIT_TIMEOUT:
	case OBJECT_WAIT_FAILED:
		//Set status as canceled.
		pIsoDesc->status = USB_ISODESC_STATUS_CANCELED;
		//Clear the act bit.
		pitd->transaction[0] &= ~0x80000000;
		pitd->transaction[1] &= ~0x80000000;
		pitd->transaction[2] &= ~0x80000000;
		pitd->transaction[3] &= ~0x80000000;
		pitd->transaction[4] &= ~0x80000000;
		pitd->transaction[5] &= ~0x80000000;
		pitd->transaction[6] &= ~0x80000000;
		pitd->transaction[7] &= ~0x80000000;
		flush_dcache_range((unsigned long)pitd,
			ALIGN_END_ADDR(struct iTD, pitd, 1));
		_hx_printf("%s:iTD timed out.\r\n", __func__);
		break;
	case OBJECT_WAIT_DELETED:
		BUG();  //Should not occur.
		break;
	default:
		_hx_printf("%s:unexcepted timeout waiting's return value[%d].\r\n",
			__func__, dwResult);
		BUG();
	}