⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbhcduhcilib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
		   sizeof (pHost->pFrameList->linkPtr [frame]));	/* Advance to the next isoch TD for this IRP. */	pWork->pNextIsochTd = pTd->sw.pNext;	if (++pWork->isochNext == UHCI_FRAME_LIST_ENTRIES)	    pWork->isochNext = 0;	pWork->isochCount++;	}    }/***************************************************************************** scheduleIsochTransfer - inserts isoch IRP in frame list** Schedules an isochronous transfer for the first time.** RETURNS: N/A*/LOCAL VOID scheduleIsochTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    /* Isochronous transfers are scheduled immediately if the     * USB_IRP.flag USB_FLAG_ISO_ASAP is set else beginning in the     * frame specified by USB_IRP.startFrame.  The number of frames     * to be scheduled is equal to the number of TDs in the      * IRP_WORKSPACE.     */    if ((pIrp->flags & USB_FLAG_ISO_ASAP) != 0)	    pWork->isochNext = FINDEX (getFrameNo (pHost) + UHC_FRAME_SKIP);    else	    pWork->isochNext = FINDEX (pIrp->startFrame);    pWork->isochCount = 0;    scheduleIsochFrames (pHost, pIrp, pWork);    }/***************************************************************************** unscheduleInterruptTransfer - removes interrupt transfer from work list** RETURNS: N/A*/LOCAL VOID unscheduleInterruptTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    pQH_WRAPPER pCurrentQh;    pQH_WRAPPER pNextQh;    UINT16 i;    /* We need to search the list of interrupt QHs to find any references     * to the indicated QH and purge each one.     */    for (i = 0; i < UHCI_FRAME_LIST_ENTRIES; i += pWork->interval)	{	pCurrentQh = &pHost->pIntAnchorQhs [i];	while ((pNextQh = QH_FROM_PCIPTR (pCurrentQh->qh.qhLink))		!= pHost->pCtlAnchorQh &&		pNextQh->sw.pWork->interval >= pWork->interval &&		pNextQh != pWork->pQh)	    {	    pCurrentQh = pNextQh;	    }	if (pNextQh == pWork->pQh)	    {	    /* We found a reference to this QH. Modify the QH list to	     * skip over it.  NOTE: pNextQh == pWork->pQh. */	    pCurrentQh->qh.qhLink = pNextQh->qh.qhLink;	    DMA_FLUSH (&pCurrentQh->qh.qhLink, sizeof (pCurrentQh->qh.qhLink));	    }	}    }    /***************************************************************************** scheduleInterruptTransfer - inserts interrupt IRP in frame list** Schedules an interrupt transfer repeatedly in the frame list as* indicated by the service interval.** RETURNS: N/A*/LOCAL VOID scheduleInterruptTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    pQH_WRAPPER pExistingQh;    pQH_WRAPPER pNextQh;    UINT16 i;    /* Calculate the service interval we'll actually use. */    pWork->interval = calcIntInterval (pWork->pPipe->interval);    /* Schedule interrupt transfer periodically throughout frame list */    for (i = 0; i < UHCI_FRAME_LIST_ENTRIES; i += pWork->interval)	{	/* Find the appropriate point in the list of interrupt QHs for this	 * frame into which to schedule this QH.  This QH needs to be	 * scheduled ahead of all interrupt QHs which are serviced more	 * frequently (ie., least frequently serviced QHs come first).	 */	pExistingQh = &pHost->pIntAnchorQhs [i];	while ((pNextQh = QH_FROM_PCIPTR (pExistingQh->qh.qhLink)) 		!= pHost->pCtlAnchorQh &&		pNextQh->sw.pWork->interval >= pWork->interval &&		pNextQh != pWork->pQh)	    {	    pExistingQh = pNextQh;	    }	if (pNextQh != pWork->pQh)	    {	    if (i == 0)		{		pWork->pQh->qh.qhLink = pExistingQh->qh.qhLink;		DMA_FLUSH (&pWork->pQh->qh, sizeof (pWork->pQh->qh));		}	    pExistingQh->qh.qhLink = QH_TO_PCIPTR (pWork->pQh);	    DMA_FLUSH (&pExistingQh->qh.qhLink, sizeof (pExistingQh->qh.qhLink));	    }	}    }/***************************************************************************** unscheduleControlTransfer - removes control transfer from work list** RETURNS: N/A*/LOCAL VOID unscheduleControlTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    pQH_WRAPPER pCurrentQh;    pQH_WRAPPER pNextQh;    /* Find the control transfer in the work list and unlink it. */    pCurrentQh = pHost->pCtlAnchorQh;    while ((pNextQh = QH_FROM_PCIPTR (pCurrentQh->qh.qhLink)) != pWork->pQh)	{	pCurrentQh = pNextQh;	}    if (pNextQh == pWork->pQh)	{	/* Bipass pWork->pQh. */	pCurrentQh->qh.qhLink = pWork->pQh->qh.qhLink;	DMA_FLUSH (&pCurrentQh->qh.qhLink, sizeof (pCurrentQh->qh.qhLink));	if (pHost->pLastCtlQh == pWork->pQh)	    pHost->pLastCtlQh = pCurrentQh;	}    }    /***************************************************************************** scheduleControlTransfer - inserts control IRP in frame list** Inserts the control transfer into the portion of the frame list * appropriate for control transfers.** RETURNS: N/A*/LOCAL VOID scheduleControlTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    pQH_WRAPPER pExistingQh;    pQH_WRAPPER pNextQh;    /* Low speed control transfers must always be scheduled before full     * speed control transfers in order to ensure that they execute     * completely within a specified frame.     */    if (pWork->pPipe->speed == USB_SPEED_LOW)	{	/* Insert this low speed transfer after currently scheduled low	 * speed transfers and ahead of any high speed transfers.	 */	pExistingQh = pHost->pCtlAnchorQh;	while ((pNextQh = QH_FROM_PCIPTR (pExistingQh->qh.qhLink)) 		!= pHost->pBulkAnchorQh && 		pNextQh->sw.pWork->pPipe->speed == USB_SPEED_LOW)	    {	    pExistingQh = pNextQh;	    }	}    else	{	/* This is a full speed transfer.  Add the QH to the end of the list 	 * of control QHs. 	 */	pExistingQh = pHost->pLastCtlQh;	}    /* Set this QH's forward link to pExistingQh's forward link */    if ((pWork->pQh->qh.qhLink = pExistingQh->qh.qhLink) == 	pHost->pciPtrToBulkAnchorQh)	{	pHost->pLastCtlQh = pWork->pQh;	}    DMA_FLUSH (&pWork->pQh->qh, sizeof (pWork->pQh->qh));    /* Set the forward link of the previous QH to this QH. */    pExistingQh->qh.qhLink = QH_TO_PCIPTR (pWork->pQh);    DMA_FLUSH (&pExistingQh->qh.qhLink, sizeof (pExistingQh->qh.qhLink));    }/***************************************************************************** unscheduleBulkTransfer - removes bulk transfer from work list** RETURNS: N/A*/LOCAL VOID unscheduleBulkTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    pQH_WRAPPER pCurrentQh;    pQH_WRAPPER pNextQh;    /* Find the bulk transfer in the work list and unlink it. */    pCurrentQh = pHost->pBulkAnchorQh;    while ((pNextQh = QH_FROM_PCIPTR (pCurrentQh->qh.qhLink)) != pWork->pQh)	{	pCurrentQh = pNextQh;	}    if (pNextQh == pWork->pQh)	{	/* Bipass pWork->pQh. */	if (ENABLE_BANDWIDTH_RECLAMATION (pHost))	    {	    if (pCurrentQh == pHost->pBulkAnchorQh &&		pNextQh->qh.qhLink == pHost->pciPtrToBulkAnchorQh)		{		pCurrentQh->qh.qhLink = UHC_END_OF_LIST;		}	    else		{		pCurrentQh->qh.qhLink = pNextQh->qh.qhLink;		}	    }	else	    {	    pCurrentQh->qh.qhLink = pNextQh->qh.qhLink;	    }	DMA_FLUSH (&pCurrentQh->qh.qhLink, sizeof (pCurrentQh->qh.qhLink));	if (pHost->pLastBulkQh == pNextQh)	    pHost->pLastBulkQh = pCurrentQh;	}    }    /***************************************************************************** scheduleBulkTransfer - inserts bulk IRP in frame list** Inserts the bulk transfer into the portion of the frame list appropriate * for bulk transfers.** RETURNS: N/A*/LOCAL VOID scheduleBulkTransfer    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    /* Set the forward link of this QH to the forward link of the     * QH which is currently last on the bulk list.     */    if (ENABLE_BANDWIDTH_RECLAMATION (pHost))	{	if (pHost->pLastBulkQh->qh.qhLink == UHC_END_OF_LIST)	    pWork->pQh->qh.qhLink = pHost->pciPtrToBulkAnchorQh;	else	    pWork->pQh->qh.qhLink = pHost->pLastBulkQh->qh.qhLink;	}    else	{	pWork->pQh->qh.qhLink = pHost->pLastBulkQh->qh.qhLink;	}    DMA_FLUSH (&pWork->pQh->qh, sizeof (pWork->pQh->qh));    /* Set the forward link of the previous QH to this QH. */    pHost->pLastBulkQh->qh.qhLink = QH_TO_PCIPTR (pWork->pQh);    DMA_FLUSH (&pHost->pLastBulkQh->qh.qhLink, 		sizeof (pHost->pLastBulkQh->qh.qhLink));    pHost->pLastBulkQh = pWork->pQh;    }/***************************************************************************** unscheduleIrp - Removes QH/TDs for IRP from work UHC work lists** RETURNS: N/A*/LOCAL VOID unscheduleIrp    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )    {    /* un-Scheduling proceeds differently for each transaction type. */    switch (pWork->pPipe->transferType)	{	case USB_XFRTYPE_ISOCH:	    unscheduleIsochTransfer (pHost, pIrp, pWork);	    break;	case USB_XFRTYPE_INTERRUPT: 	    unscheduleInterruptTransfer (pHost, pIrp, pWork);	    break;	case USB_XFRTYPE_CONTROL:	    unscheduleControlTransfer (pHost, pIrp, pWork);	    break;	case USB_XFRTYPE_BULK:	    unscheduleBulkTransfer (pHost, pIrp, pWork);	    break;	}    }/***************************************************************************** scheduleIrp - try to schedule an IRP in the frame list** RETURNS: N/A*/LOCAL VOID scheduleIrp    (    pHCD_HOST pHost,    pUSB_IRP pIrp    )    {    pIRP_WORKSPACE pWork = (pIRP_WORKSPACE) pIrp->hcdPtr;    pHCD_PIPE pPipe = pWork->pPipe;    /* prepare TDs */    assignTds (pHost, pIrp, pWork);    /* Mark the time the IRP was first scheduled. */    if (!pWork->irpRunning)	{	pWork->irpRunning = TRUE;	pWork->startTime = OSS_TIME ();	}    /* Scheduling proceeds differently for each transaction type. */    switch (pPipe->transferType)	{	case USB_XFRTYPE_ISOCH:	    scheduleIsochTransfer (pHost, pIrp, pWork);	    break;	case USB_XFRTYPE_INTERRUPT: 	    scheduleInterruptTransfer (pHost, pIrp, pWork);	    break;	case USB_XFRTYPE_CONTROL:	    scheduleControlTransfer (pHost, pIrp, pWork);	    break;	case USB_XFRTYPE_BULK:	    scheduleBulkTransfer (pHost, pIrp, pWork);	    break;	}    }/***************************************************************************** rescheduleTds - Examine the given IRP and see if it needs servicing** <pIrp> is an IRP which may/may not have been assigned QHs and TDs and* currently be schedule for execution.	Examine the <pIrp> and its* associated USB_WORKSPACE in <pWork> (which might be NULL).  If no work* has been scheduled or if no TDs have been completed by the UHC, then* we do nothing.  If there are TDs which have been completed, then we* release them to the "free" pool.  If work remains to be done, then we* reschedule the TDs.  If no work remains to be done or if there is an* error, then we report that the IRP is complete.** RETURNS: OK = IRP completed ok*      PENDING = IRP still being executed*      S_usbHcdLib_xxx = IRP failed with error*/LOCAL int rescheduleTds    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    pIRP_WORKSPACE pWork    )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -