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

📄 usbhcdohcilib.c

📁 基于VXWORK环境的ARM9 S2410的USB驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
LOCAL UINT16 getFrameNo    (    pHCD_HOST pHost    )    {    return OHCI_FMN_FN (HC_DWORD_IN (OHCI_HC_FM_NUMBER));    }/***************************************************************************** setFrameInterval - sets OHCI frame interval ** RETURNS: N/A*/LOCAL VOID setFrameInterval    (    pHCD_HOST pHost,    UINT16 sofInterval    )    {    UINT32 fmi;    fmi = HC_DWORD_IN (OHCI_HC_FM_INTERVAL) & ~OHCI_FMI_FIT;    fmi ^= OHCI_FMI_FIT;    fmi |= OHCI_FMI_FI_FMT (sofInterval);    fmi |= OHCI_FMI_FSMPS_FMT (((sofInterval - MAX_FRAME_OVERHEAD) * 6) / 7);    HC_DWORD_OUT (OHCI_HC_FM_INTERVAL, fmi);    pHost->sofInterval = sofInterval;    }/***************************************************************************** hcSynch - give the host controller a chance to synchronize** RETURNS: N/A*/LOCAL VOID hcSynch    (    pHCD_HOST pHost    )    {    UINT16 currentFrameNo = getFrameNo (pHost);    while (getFrameNo (pHost) == currentFrameNo);	semTake (pHost->hcSyncSem, 1);	semTake (pHost->hcSyncSem, 1);    }/***************************************************************************** setIrpResult - sets result in IRP and executes IRP callback** RETURNS: value from Irp result field*/LOCAL int setIrpResult    (    pUSB_IRP pIrp,    int result    )    {    if (result != PENDING)	{	pIrp->result = result;	if (pIrp->usbdCallback != NULL)	    (*pIrp->usbdCallback) (pIrp);	else if (pIrp->userCallback != NULL)	    (*pIrp->userCallback) (pIrp);	}    return result;    }/***************************************************************************** calcIntInterval - calculates the scheduling interval for interrupt transfer** RETURNS: Actual interval to be used for interrupt transfer*/LOCAL UINT16 calcIntInterval    (    UINT16 interval /* 1 <= requested interval <= OHCI_INT_ED_COUNT */    )    {    UINT16 i;    /* Select an interval which is the largest power of two less than or     * equal to the requested interval.     */    for (i = 2; i < OHCI_INT_ED_COUNT + 1; i <<= 1)	{	if (i > interval)	    break;	}    return i >> 1;    }/***************************************************************************** freeIrpWorkspace - releases IRP_WORKSPACE** Releases the IRP_WORKSPACE associated with an IRP (if there is one).** RETURNS: N/A*/LOCAL VOID freeIrpWorkspace    (    pHCD_HOST pHost,    pUSB_IRP pIrp    )    {    pIRP_WORKSPACE pWork = (pIRP_WORKSPACE) pIrp->hcdPtr;    if (pWork != NULL)	{	OSS_FREE (pWork);	pIrp->hcdPtr = NULL;	}    }/***************************************************************************** allocIrpWorkspace - creates workspace for IRP** Creates an IRP_WORKSPACE structure to manage the IRP data transfer.** RETURNS: TRUE if successful, else FALSE*/LOCAL BOOL allocIrpWorkspace    (    pHCD_HOST pHost,    pHCD_PIPE pPipe,    pUSB_IRP pIrp    )    {    pIRP_WORKSPACE pWork;    /* Allocate IRP_WORKSPACE */    if ((pWork = OSS_CALLOC (sizeof (*pWork))) == NULL)	return FALSE;    pIrp->hcdPtr = pWork;    pWork->pPipe = pPipe;    pWork->pIrp = pIrp;    return TRUE;    }/***************************************************************************** isBandwidthTracked - determines if bandwidth is tracked for this transfer** Since the USBD has already reserved adequate bandwidth for isochronous* and interrupt transfers, we only track low speed control transfers.** RETURNS: TRUE if bandwidth tracked, else FALSE.*/LOCAL BOOL isBandwidthTracked    (    pHCD_PIPE pPipe    )    {    if (pPipe->transferType == USB_XFRTYPE_CONTROL && 			       pPipe->speed == USB_SPEED_LOW)	return TRUE;    return FALSE;    }/***************************************************************************** dirFromPid - returns USB_DIR_xxxx based on USB_PID_xxxx** RETURNS: USB_DIR_xxxx*/LOCAL UINT16 dirFromPid    (    UINT16 pid    )    {    switch (pid)	{	case USB_PID_SETUP:	case USB_PID_OUT:			return USB_DIR_OUT;	case USB_PID_IN:			return USB_DIR_IN;	default:	    		return USB_DIR_IN;	}    }/***************************************************************************** unscheduleIsochPipe - removes an isoch pipe from the schedule** RETURNS: N/A*/LOCAL VOID unscheduleIsochPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    pUINT32 pPciPtrToEd;    pED_WRAPPER pCurEd;    /* Note: Instead of halting periodic transfers before delinking, we      * immediately delink them and afterward wait for the next frame to start...     * This ensures that caller won't de-allocate the structures while the     * HC may still be referencing them.     */    /* Walk the isoch. list until we find the ED to be removed. */    pPciPtrToEd = (pUINT32) &pHost->pIsochAnchorEd->ed.nextEd;    while ((pCurEd = ED_FROM_PCIPTR (*pPciPtrToEd)) != pPipe->pEd)	{	pPciPtrToEd = (pUINT32) &pCurEd->ed.nextEd;	}    *pPciPtrToEd = pPipe->pEd->ed.nextEd;    DMA_FLUSH (pPciPtrToEd, sizeof (*pPciPtrToEd));    /*       * shutOffListProcessing() halts isoch, interrupt and bulk transfers      * when a device is disconnected, we make sure they are re-enabled.     */     HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_PLE);    HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_IE);    HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_BLE);    /* Wait for the HC to make sure the structure is really released. */    hcSynch (pHost);    }    /***************************************************************************** scheduleIsochPipe - inserts isoch pipe into the schedule** Schedules an isochronous transfer for the first time.** RETURNS: N/A*/LOCAL VOID scheduleIsochPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    pED_WRAPPER pLastEd;    pED_WRAPPER pNextEd;    /* Flush the ED out of the cache before giving it to the HC. */    DMA_FLUSH (pPipe->pEd, sizeof (*pPipe->pEd));    /* Append this ED to the end of the isoch. list. */    pLastEd = pHost->pIsochAnchorEd;    while ((pNextEd = ED_FROM_PCIPTR (pLastEd->ed.nextEd)) != NULL)	pLastEd = pNextEd;    pLastEd->ed.nextEd = TO_LITTLEL (TO_PCIPTR (pPipe->pEd));    DMA_FLUSH (&pLastEd->ed.nextEd, sizeof (pLastEd->ed.nextEd));    }/***************************************************************************** unscheduleInterruptPipe - removes interrupt pipe from the schedule** RETURNS: N/A*/LOCAL VOID unscheduleInterruptPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    pUINT32 pPciPtrToEd;    pED_WRAPPER pCurEd;    UINT16 i;    /* Note: Instead of halting periodic transfers before delinking, we      * immediately delink them and afterward wait for the next frame to start...     * This ensures that caller won't de-allocate the structures while the     * HC may still be referencing them.     */    /* Remove the pipe from the interrupt lists. */    for (i = 0; i < OHCI_INT_ED_COUNT; i += pPipe->actInterval)	{	/* Walk this list until we find the ED to be removed. */	pPciPtrToEd = &pHost->pHcca->intEdTable [i];	while ((pCurEd = ED_FROM_PCIPTR (*pPciPtrToEd)) != pHost->pIsochAnchorEd &&		pCurEd->sw.pPipe->actInterval >= pPipe->actInterval &&		pCurEd != pPipe->pEd)	    {	    pPciPtrToEd = (pUINT32) &pCurEd->ed.nextEd;	    }	if (pCurEd == pPipe->pEd)	    {	    *pPciPtrToEd = pPipe->pEd->ed.nextEd;	    DMA_FLUSH (pPciPtrToEd, sizeof (*pPciPtrToEd));	    }	}    /*       * shutOffListProcessing() halts isoch, interrupt and bulk transfers      * when a device is disconnected, we make sure they are re-enabled.     */                      HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_PLE);    HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_IE);    HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_BLE);    /* Wait for the HC to make sure the structure is really released. */    hcSynch (pHost);    }    /***************************************************************************** scheduleInterruptPipe - inserts interrupt pipe into the schedule** Schedules an interrupt transfer repeatedly in the frame list as* indicated by the service interval.** RETURNS: N/A*/LOCAL VOID scheduleInterruptPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    pUINT32 pPciPtrToEd;    pED_WRAPPER pCurEd;    UINT16 i;    /* Schedule the pipe onto the interrupt lists. */    for (i = 0; i < OHCI_INT_ED_COUNT; i += pPipe->actInterval)	{	/* Walk this list until we hit the isoch. anchor or until we	 * find an pipe with a smaller interval (higher frequency).	 */	pPciPtrToEd = &pHost->pHcca->intEdTable [i];	while ((pCurEd = ED_FROM_PCIPTR (*pPciPtrToEd)) != pHost->pIsochAnchorEd &&		pCurEd->sw.pPipe->actInterval >= pPipe->actInterval &&		pCurEd != pPipe->pEd)	    {	    pPciPtrToEd = (pUINT32) &pCurEd->ed.nextEd;	    }	if (pCurEd != pPipe->pEd)	    {	    if (i == 0)		{		pPipe->pEd->ed.nextEd = *pPciPtrToEd;		DMA_FLUSH (pPipe->pEd, sizeof (*pPipe->pEd));		}	    *pPciPtrToEd = TO_LITTLEL (TO_PCIPTR (pPipe->pEd));	    DMA_FLUSH (pPciPtrToEd, sizeof (*pPciPtrToEd));	    }	}    }/***************************************************************************** unscheduleControlPipe - removes control pipe from the schedule** RETURNS: N/A*/LOCAL VOID unscheduleControlPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    pED_WRAPPER pCurEd;    pED_WRAPPER pNextEd;    /* We need to halt processing of control transfers before de-linking. */    HC_CLR_BITS (OHCI_HC_CONTROL, OHCI_CTL_CLE);    hcSynch (pHost);    /* Find the pipe's ED and de-link it. */    if ((pCurEd = FROM_PCIPTR (HC_DWORD_IN (OHCI_HC_CONTROL_HEAD_ED)))			      == pPipe->pEd)	{	/* ED is the head of the list */	HC_DWORD_OUT (OHCI_HC_CONTROL_HEAD_ED, 		      FROM_LITTLEL (pPipe->pEd->ed.nextEd));	}    else	{	/* Walk the list looking for the ED.	 *	 * NOTE: We know the ED must be on the list, so there's no need	 * to check for the end of list as we proceed. 	 */	while ((pNextEd = ED_FROM_PCIPTR (pCurEd->ed.nextEd)) != pPipe->pEd)					  pCurEd = pNextEd;	pCurEd->ed.nextEd = pPipe->pEd->ed.nextEd;	}    /*       * shutOffListProcessing() halts isoch, interrupt and bulk transfers      * when a device is disconnected, we make sure they are re-enabled.     */                      HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_PLE);    HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_IE);    HC_SET_BITS(OHCI_HC_CONTROL,OHCI_CTL_BLE);    /* Re-enable the control list. */    HC_SET_BITS (OHCI_HC_CONTROL, OHCI_CTL_CLE);    }    /***************************************************************************** scheduleControlPipe - inserts control pipe into the schedule** Inserts the control transfer into the portion of the frame list * appropriate for control transfers.** RETURNS: N/A*/LOCAL VOID scheduleControlPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    pED_WRAPPER pLastEd = FROM_PCIPTR (HC_DWORD_IN (OHCI_HC_CONTROL_HEAD_ED));    pED_WRAPPER pNextEd;    /* Flush the ED out of the cache before giving it to the HC. */    DMA_FLUSH (pPipe->pEd, sizeof (*pPipe->pEd));    if (pLastEd == NULL)	{	/* This will be the first ED on the control list. */	HC_DWORD_OUT (OHCI_HC_CONTROL_HEAD_ED, TO_PCIPTR (pPipe->pEd));	}    else

⌨️ 快捷键说明

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