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

📄 usbhcdohcilib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
    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);    }/***************************************************************************** destroyHost - tears down an HCD_HOST** RETURNS: N/A*/LOCAL VOID destroyHost    (    pHCD_HOST pHost    )        {    pUSB_IRP pIrp;    pHCD_PIPE pPipe;    /* Mark host as being shut down */    pHost->shutdown = TRUE;    /* release any pending IRPs */    while ((pIrp = usbListFirst (&pHost->rootIrps)) != NULL)	cancelIrp (pHost, pIrp, S_usbHcdLib_IRP_CANCELED);    while ((pIrp = usbListFirst (&pHost->busIrps)) != NULL)	cancelIrp (pHost, pIrp, S_usbHcdLib_IRP_CANCELED);    /* release any pending pipes */    while ((pPipe = usbListFirst (&pHost->pipes)) != NULL)	destroyPipe (pHost, pPipe);    /* Disable the HC */    HC_DWORD_OUT (OHCI_HC_CONTROL, 0);    HC_DWORD_OUT (OHCI_HC_COMMAND_STATUS, OHCI_CS_HCR);    /* restore original interrupt handler */    if (pHost->intInstalled)	usbPciIntRestore (intHandler, pHost, pHost->pciCfgHdr.intLine);    /* terminate/destroy interrupt handler thread */    if (pHost->intThread != NULL)	{	/* Terminate the interrupt service thread */	pHost->intThreadExitRequest = TRUE;	OSS_SEM_GIVE (pHost->intPending);	OSS_SEM_TAKE (pHost->intThreadExit, INT_TIMEOUT);	OSS_THREAD_DESTROY (pHost->intThread);	}    /* release other resources */    if (pHost->hostMutex != NULL)	OSS_MUTEX_DESTROY (pHost->hostMutex);    if (pHost->intThreadExit != NULL)	OSS_SEM_DESTROY (pHost->intThreadExit);    if (pHost->intPending != NULL)	OSS_SEM_DESTROY (pHost->intPending);    if (pHost->handle != NULL)	usbHandleDestroy (pHost->handle);    /* release root hub per-port data */    if (pHost->pRhPortChange != NULL)	OSS_FREE (pHost->pRhPortChange);    /* eliminate DMA memory pool.     *     * NOTE: This automatically deletes any objects allocated within the     * DMA memory pool, e.g., the OHCI HCCA.     */    if (pHost->dmaPool != NULL)	cacheDmaFree (pHost->dmaPool);    OSS_FREE (pHost);    }/***************************************************************************** fncAttach - Initialize the HCD and attach to specified bus(es)** The convention for the OHCI HCD is that the param passed in the HRB* is a pointer to a PCI_CFG_HEADER structure for the HC to be managed.** RETURNS: S_usbHcdLib_xxxx*/LOCAL int fncAttach    (    pHRB_ATTACH pHrb    )    {    pHCD_HOST pHost;    pPCI_CFG_HEADER pCfgHdr;    UINT32 memBase;    int i;    int s;    /* validate parameters */    if ((s = validateHrb (pHrb, sizeof (*pHrb))) != OK)	return s;    /* Check to make sure structures compiled to correct size */    if (OHCI_HCCA_ACTLEN != OHCI_HCCA_LEN || 	OHCI_ED_ACTLEN != OHCI_ED_LEN ||	OHCI_TD_GEN_ACTLEN != OHCI_TD_GEN_LEN ||	OHCI_TD_ISO_ACTLEN != OHCI_TD_ISO_LEN ||	TD_WRAPPER_ACTLEN != TD_WRAPPER_LEN)	{	return S_usbHcdLib_STRUCT_SIZE_FAULT;	}    /* determine io base address */    pCfgHdr = (pPCI_CFG_HEADER) pHrb->param;    memBase = 0;    for (i = 0; i < PCI_CFG_NUM_BASE_REG; i++)	if ((pCfgHdr->baseReg [i] & PCI_CFG_BASE_IO) == 0 &&	    (memBase = pCfgHdr->baseReg [i] & PCI_CFG_MEMBASE_MASK) != 0)	    break;    if (memBase == 0)	return S_usbHcdLib_HW_NOT_READY;    /* create/initialize an HCD_HOST structure to manage the HC. */    if ((pHost = OSS_CALLOC (sizeof (*pHost))) == NULL)	return S_usbHcdLib_OUT_OF_MEMORY;    memcpy (&pHost->pciCfgHdr, pCfgHdr, sizeof (*pCfgHdr));    pHost->mngmtCallback = pHrb->mngmtCallback;    pHost->mngmtCallbackParam = pHrb->mngmtCallbackParam;    /* initialize pHost->memBase...cannot use HC_SET_BITS, etc. until      * ioBase is initialized.     */    pHost->memBase = (pUINT32) (memBase + USB_PCI_MEMIO_OFFSET());    /*      * Create a semaphore to syncronize the host controller.  This is used     * to make the HC wait a frame for traffic to settle      */    pHost->hcSyncSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY);    if (pHost->hcSyncSem == NULL)        return S_usbHcdLib_OUT_OF_RESOURCES;        /* Check the hardware revision level */    if ((HC_DWORD_IN (OHCI_HC_REVISION) & OHCI_RREV_REV_MASK) 	< REQUIRED_OHCI_LEVEL)    	return S_usbHcdLib_HW_NOT_READY;    /* reset the host controller.     *     * NOTE: At the same time, we disable anything else which may be     * enabled in the OHCI control register.     *     * NOTE: We allow the HC to revert to the nominal (default) frame     * interval in response to the reset.     */    HC_DWORD_OUT (OHCI_HC_CONTROL, 0);    HC_DWORD_OUT (OHCI_HC_COMMAND_STATUS, OHCI_CS_HCR);    if (!waitOnBits (pHost, OHCI_HC_COMMAND_STATUS, OHCI_CS_HCR, 0))	{	destroyHost (pHost);	return S_usbHcdLib_HW_NOT_READY;	}    /* Allocate structures, resources, etc. */    if ((pHost->dmaPool = cacheDmaMalloc (DMA_MEMORY_SIZE))  == NULL || 	(pHost->memPartId = memPartCreate (pHost->dmaPool, 					   DMA_MEMORY_SIZE)) == NULL || 	(pHost->pRhPortChange = OSS_CALLOC (pHost->numPorts * sizeof (UINT32))) == NULL	|| 	(pHost->pHcca = DMA_MALLOC (sizeof (*pHost->pHcca), 				    OHCI_HCCA_ALIGNMENT)) == NULL || 	(pHost->pIsochAnchorEd = DMA_MALLOC (sizeof (*pHost->pIsochAnchorEd), 					     OHCI_TD_ISO_ALIGNMENT)) == NULL || 	usbHandleCreate (HCD_HOST_SIG, 			pH

⌨️ 快捷键说明

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