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

📄 usbhcdohcilib.c

📁 基于VXWORK环境的ARM9 S2410的USB驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	else	    pWork->isochNext = FINDEX (pIrp->startFrame);	}    /* Assign TDs to direct data transfer. */    assignTds (pHost, pPipe, pIrp, pWork);    }/***************************************************************************** cancelIrp - cancel's an outstanding IRP** If the IRP's result code is not PENDING, then we cannot cancel* the IRP as it has either already completed or it is not yet enqueued.** RETURNS: OK if IRP canceled*      S_usbHcdLib_CANNOT_CANCEL if IRP already completed*/LOCAL int cancelIrp    (    pHCD_HOST pHost,    pUSB_IRP pIrp,    int result		    /* error to assign to IRP */    )    {    pIRP_WORKSPACE pWork;    pHCD_PIPE pPipe;    int s = OK;    if (pIrp->result != PENDING)	s = S_usbHcdLib_CANNOT_CANCEL;    else	{	/* The IRP is pending.  Unlink it. */	usbListUnlink (&pIrp->hcdLink);	/* If this IRP is a "bus" IRP - as opposed to a root IRP - then	 * remove it from the HC's work list.	 */	if ((pWork = (pIRP_WORKSPACE) pIrp->hcdPtr) != NULL &&	    pWork->pPipe->busAddress != pHost->rootAddress)	    {	    /* Remove QHs/TDs from the work list and release workspace. */	    pPipe = pWork->pPipe;	    unscheduleIrp (pHost, pIrp, pWork);	    freeIrpWorkspace (pHost, pIrp);	    /* This may create an opportunity to schedule other IRPs. */	    scheduleOtherIrps (pHost, pPipe);	    }	setIrpResult (pIrp, result);    	}    return s;    }/***************************************************************************** shutOffListProcessing - shut of host controller interrupts for list proc.** Permits the host controller from processing the periodic, interrupt and bulk* TD lists.** RETURNS: N/A.*/LOCAL void shutOffListProcessing    (    pHCD_HOST pHost    )    {    UINT32 controlRegChange;    hcSynch (pHost);    /*      * Read the register and mask off the bits that denote list processing      * is enabled      */    /*  Periodic List = Isoc transfers */    controlRegChange = HC_DWORD_IN (OHCI_HC_CONTROL) & (OHCI_CTL_PLE);    pHost->pHcControlReg = controlRegChange;    HC_CLR_BITS (OHCI_HC_CONTROL, pHost->pHcControlReg);    /*  Interrupt List = Interrupt transfers */    controlRegChange = HC_DWORD_IN (OHCI_HC_CONTROL) &(OHCI_CTL_IE);    pHost->pHcControlReg = controlRegChange;    HC_CLR_BITS (OHCI_HC_CONTROL, pHost->pHcControlReg);    /*  Bulk List = Bulk transfers */    controlRegChange = HC_DWORD_IN (OHCI_HC_CONTROL) & OHCI_CTL_BLE;    pHost->pHcControlReg = controlRegChange;     HC_CLR_BITS (OHCI_HC_CONTROL, pHost->pHcControlReg);    }/***************************************************************************** isHubStatus - checks status on root hub** RETURNS: hub and port status bitmap as defined by USB*/LOCAL UINT8 isHubStatus    (    pHCD_HOST pHost    )    {    UINT8 hubStatus = 0;    UINT16 port;    UINT32 portRegOffset;    UINT32 portChange;    UINT32 hcRhPortStatusReg;    for (port = 0; port < pHost->numPorts; port++)	{	portRegOffset = OHCI_HC_RH_PORT_STATUS + port * sizeof (UINT32);	/* Read & clear pending change status */	hcRhPortStatusReg = HC_DWORD_IN (portRegOffset);	portChange = hcRhPortStatusReg & 		     (OHCI_RHPS_CSC | 		     OHCI_RHPS_PESC | 		     OHCI_RHPS_PSSC | 		     OHCI_RHPS_OCIC | 		     OHCI_RHPS_PRSC);	if (portChange != 0)	    HC_DWORD_OUT (portRegOffset, portChange);        hcSynch (pHost);	/* Combine the change bits reported by the HC with those we	 * already know about.  Then report if a change is pending.	 */	pHost->pRhPortChange [port] |= portChange;	if ((pHost->pRhPortChange [port] & 	    (OHCI_RHPS_CSC | 	    OHCI_RHPS_PESC | 	    OHCI_RHPS_PSSC | 	    OHCI_RHPS_OCIC | 	    OHCI_RHPS_PRSC)) != 0)	    {	    hubStatus |= USB_HUB_ENDPOINT_STS_PORT0 << port;	    }	/*  there was a change - a device has been plugged, or unplugged */	if ( (hcRhPortStatusReg & OHCI_RHPS_CSC) !=0)	    /*  A device has been unplugged */	    if ( (hcRhPortStatusReg & OHCI_RHPS_CCS) == 0 )		{		/* Stop the host controller from processing TD's */	        shutOffListProcessing (pHost);		}	}    return hubStatus;    }/***************************************************************************** serviceRootIrps - Services root hub transactions** RETURNS: N/A*/LOCAL VOID serviceRootIrps    (    pHCD_HOST pHost    )    {    UINT8 hubStatus;    UINT16 irpCount;    pUSB_IRP pIrp;    if ((hubStatus = isHubStatus (pHost)) != 0)	{	for (irpCount = pHost->rootIrpCount; irpCount > 0; irpCount--)	    {	    pIrp = usbListFirst (&pHost->rootIrps);	    --pHost->rootIrpCount;	    usbListUnlink (&pIrp->hcdLink);	    *(pIrp->bfrList [0].pBfr) = hubStatus;	    pIrp->bfrList [0].actLen = 1;	    setIrpResult (pIrp, OK);	    }	}    }/***************************************************************************** processInterrupt - process a hardware interrupt from the HC** Determine the cause of a hardware interrupt and service it.  If the* interrupt results in the completion of one or more IRPs, handle the* completion processing for those IRPs.** RETURNS: N/A*/LOCAL VOID processInterrupt    (    pHCD_HOST pHost    )    {    UINT32 intBits = HC_DWORD_IN (OHCI_HC_INT_STATUS) & INT_ENABLE_MASK;    /* evaluate the interrupt condition */    if ((intBits & OHCI_INT_SO) != 0)	{	/* Scheduling overrun detected.  Record it. */	pHost->errScheduleOverrun++;	HC_DWORD_OUT (OHCI_HC_INT_STATUS, OHCI_INT_SO); /* acknowledge */	}    if ((intBits & OHCI_INT_UE) != 0)	{	/* Unrecoverable error detected.  Record it. */	pHost->errUnrecoverable++;	HC_DWORD_OUT (OHCI_HC_INT_STATUS, OHCI_INT_UE); /* acknowledge */	}    if ((intBits & OHCI_INT_RD) != 0)	{	/* Resume detected. */	if (pHost->mngmtCallback != NULL)	    (*pHost->mngmtCallback) (pHost->mngmtCallbackParam, 				     pHost->handle,				     0 /* bus number */, 				     HCD_MNGMT_RESUME);	HC_DWORD_OUT (OHCI_HC_INT_STATUS, OHCI_INT_RD); /* acknowledge */	}    if ((intBits & OHCI_INT_RHSC) != 0)	{	/* Root host change detected. */	serviceRootIrps (pHost);	HC_DWORD_OUT (OHCI_HC_INT_STATUS, OHCI_INT_RHSC); /* acknowledge */	}    if ((intBits & OHCI_INT_WDH) != 0)	{	/* The HC has updated the done queue.  This implies completion 	 * of one or more USB transactions detected. 	 */	serviceBusIrps (pHost);	pHost->pHcca->doneHead = 0;	HC_DWORD_OUT (OHCI_HC_INT_STATUS, OHCI_INT_WDH); /* acknowledge */	}    /* Re-enable HC interrupts */    HC_DWORD_OUT (OHCI_HC_INT_ENABLE, INT_ENABLE_MASK);    }/***************************************************************************** checkIrpTimeout - Checks for IRPs which may have timed-out** RETURNS: N/A*/LOCAL VOID checkIrpTimeout    (    pHCD_HOST pHost	/* host to check */    )    {    pUSB_IRP pIrp;    pUSB_IRP pNextIrp;    pIRP_WORKSPACE pWork;    UINT32 now;    /* Search for one or more IRPs which have been completed     * (or partially completed).     */    now = OSS_TIME ();    pIrp = usbListFirst (&pHost->busIrps);    while (pIrp != NULL)	{	pNextIrp = usbListNext (&pIrp->hcdLink);	    	pWork = (pIRP_WORKSPACE) pIrp->hcdPtr;	if (pIrp->timeout != USB_TIMEOUT_NONE && pWork->irpRunning &&	    now - pWork->startTime > pIrp->timeout)	    {	    /* This IRP has exceeded its run time. */	    cancelIrp (pHost, pIrp, S_usbHcdLib_TIMEOUT);	    }	pIrp = pNextIrp;	}    }/***************************************************************************** intThread - Thread invoked when hardware interrupts are detected** By convention, the <param> to this thread is a pointer to an HCD_HOST.* This thread waits on the intPending semaphore in the HCD_HOST which is* signalled by the actual interrupt handler.  This thread will continue* to process interrupts until intThreadExitRequest is set to TRUE in the* HCD_HOST structure.** This thread wakes up every HC_TIMEOUT_SRVC_INTERVAL milliseconds and * checks for IRPs which may have timed-out.** RETURNS: N/A*/LOCAL VOID intThread    (    pVOID param    )    {    pHCD_HOST pHost = (pHCD_HOST) param;    UINT32 interval;    UINT32 now;    UINT32 lastTime = OSS_TIME ();    do	{	/* Wait for an interrupt to be signalled. */	now = OSS_TIME ();	interval = HC_TIMEOUT_SRVC_INTERVAL - 		   min (now - lastTime, HC_TIMEOUT_SRVC_INTERVAL);	if (OSS_SEM_TAKE (pHost->intPending, interval) == OK)	    {	    /* semaphore was signalled, int pending */	    if (!pHost->intThreadExitRequest)		{		OSS_MUTEX_TAKE (pHost->hostMutex, OSS_BLOCK);		processInterrupt (pHost);		OSS_MUTEX_RELEASE (pHost->hostMutex);		}	    }	if ((now = OSS_TIME ()) - lastTime >= HC_TIMEOUT_SRVC_INTERVAL)	    {	    /* check for timed-out IRPs */	    lastTime = now;	    /* Look for IRPs which may have timed-out. */	    OSS_MUTEX_TAKE (pHost->hostMutex, OSS_BLOCK);	    checkIrpTimeout (pHost);	    OSS_MUTEX_RELEASE (pHost->hostMutex);	    }	}    while (!pHost->intThreadExitRequest);    /* Signal that we've acknowledged the exit request */    OSS_SEM_GIVE (pHost->intThreadExit);    }/***************************************************************************** intHandler - hardware interrupt handler** This is the actual routine which receives hardware interrupts from the* HC.  This routine immediately reflects the interrupt to the intThread.* interrupt handlers have execution restrictions which are not imposed* on normal threads...So, this scheme gives the intThread complete* flexibility to call other services and libraries while processing the* interrupt condition.** RETURNS: N/A*/LOCAL VOID intHandler    (    pVOID param    )    {    pHCD_HOST pHost = (pHCD_HOST) param;    /* Is there an interrupt pending in the OHCI interrupt status reg? */    if ((HC_DWORD_IN (OHCI_HC_INT_STATUS) & INT_ENABLE_MASK) != 0)	{	pHost->intCount++;	/* Disable further interrupts until the intThread takes over */	HC_DWORD_OUT (OHCI_HC_INT_DISABLE, OHCI_INT_MIE);	/* Signal the interrupt thread to process the interrupt. */	OSS_SEM_GIVE (pHost->intPending);	}    /* Prevent the hcSync routine from busy waiting. */    if(pHost->hcSyncSem) 	semGive (pHost->hcSyncSem);    }/***************************************************************************** validateHrb - validate an HRB** Checks the HRB length set in the HRB_HEADER against the <expectedLen>* passed by the caller. ** RETURNS: S_usbHcdLib_xxxx*/LOCAL int validateHrb    (    pVOID pHrb,    UINT16 expectedLen    )    {    pHRB_HEADER pHeader = (pHRB_HEADER) pHrb;    if (pHeader->hrbLength != expectedLen)	return S_usbHcdLib_BAD_PARAM;    return OK;    }/***************************************************************************** destroyPipe - tears down an HCD_PIPE** RETURNS: N/A*/LOCAL void destroyPipe    (    pHCD_HOST pHost,    pHCD_PIPE pPipe    )    {    if (pPipe->pEd != NULL) 	{	/* Release ED allocated for pipe. */	unschedulePipe (pHost, pPipe);	DMA_FREE (pPipe->pEd);	}    /* Release bandwidth associated with pipe. */    pHost->nanoseconds -= pPipe->time;    /* Release pipe */    usbListUnlink (&pPipe->link);    usbHandleDestroy (pPipe->pipeHandle);    OSS_FREE (pPipe);    }/****************************************************************************

⌨️ 快捷键说明

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