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

📄 usbohciisr.c

📁 usb2 driver for vxwokrs
💻 C
📖 第 1 页 / 共 2 页
字号:
    UINT8 uHostControllerIndex    )    {    /* To hold the value read from the interrupt status registers */    UINT32  uInterruptStatus = 0;    /* To hold the pointer to the host controller information */    PUSB_OHCI_INFORMATION   pOhciControllerInfo = NULL;    /*      * To hold the pointer to the pipe pending for deletion or cancellation     * for transfer.     */    PUSB_OHCI_ENDPOINT_DESCRIPTOR   pEndpointDescriptor = NULL;    UINT32 uRegReadValue = 0;    /* Check whether the host controller index is valid */    if (uHostControllerIndex >= maxOhciCount)    	{        /* Debug print */        OS_LOG_MESSAGE_LOW(            OHCD,            "Entering the function: usbOhciProcessInterrupts().\n",             0,             0,             0,             0);                    /* Invalid host controller index */        return;        }    /* Obtain the pointer to the host controller information */    pOhciControllerInfo = &usbOhciControllerInfo[uHostControllerIndex];#ifndef USB_OHCI_POLLING_MODE    /* Disable the interrupts */    USB_OHCI_REG_WRITE (uHostControllerIndex,         (pOhciControllerInfo->uBaseAddress +             USB_OHCI_INTERRUPT_DISABLE_REGISTER_OFFSET),		USB_OHCI_INTERRUPT_MASK);#endif /* End of #ifndef USB_OHCI_POLLING_MODE */    /* Read the contents of the HC Interrupt Status register */    uInterruptStatus =         USB_OHCI_REG_READ (uHostControllerIndex,                            pOhciControllerInfo->uBaseAddress +                            USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET);    /* Read the contents of the control register */    uRegReadValue = USB_OHCI_REG_READ(uHostControllerIndex,                                      pOhciControllerInfo->uBaseAddress +                                       USB_OHCI_CONTROL_REGISTER_OFFSET);    /* Check if there are elements in the endpoint disabled list */    if (pOhciControllerInfo->pDisabledEndpointListHead != NULL)        {       uInterruptStatus &= (USB_OHCI_INTERRUPT_MASK | USB_OHCI_INTERRUPT_STATUS_SOF);        }    else       {        uInterruptStatus &= USB_OHCI_INTERRUPT_MASK;        USB_OHCI_REG_WRITE (uHostControllerIndex,                            (pOhciControllerInfo->uBaseAddress +                            USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET),			   (uInterruptStatus & USB_OHCI_INTERRUPT_STATUS_SOF));       }    /* Check whether an interrupt is pending */    if (uInterruptStatus != 0)    	{        /*         * Check whether the Write Back Done Head interrupt is pending.         *         * NOTE: Check for the Write Back Done Head interrupt before checking         *       the SOF interrupt. This is because the SOF interrupt is used         *       for cancelling the transfers.         *         *       However, the transfer which is marked for cancellation could         *       have been completed. Hence, Write Back Done Head interrupt         *       should be checked before attempting to cancel a transfer         *       (i.e. servicing the SOF interrupt).         */        if ((uInterruptStatus & USB_OHCI_INTERRUPT_STATUS_DONE_HEAD) ==			USB_OHCI_INTERRUPT_STATUS_DONE_HEAD)        	{            /* To hold the head pointer to the list of transfers completed */            PVOID pTransferCompletion = NULL;            /* To hold the pointer to the HCCA */            PUSB_OHCI_HCCA  pHCCA = NULL;            /*             * Obtain the contents of the transfer done head in the host             * controller communication area. This value corresponds to the             * head of the list of transfers completed.             */            /* Invalidate the cache */            DMA_INVALIDATE(pOhciControllerInfo->pHccaAligned,sizeof(USB_OHCI_HCCA));            /* Retrieve the HCCA information */            pHCCA = pOhciControllerInfo->pHccaAligned;            /* Invalidate the HCCADone head cache *//*            DMA_INVALIDATE(&pHCCA->uHccaDoneHead, sizeof(UINT32));*/             DMA_INVALIDATE(pHCCA + USB_OHCI_HCCA_DONEHEAD_OFFSET , sizeof(UINT32));            /* Retrieve the HCCA Done head */            pTransferCompletion = (PVOID)pHCCA->uHccaDoneHead;            /* Retrieve the virtual address */            pTransferCompletion = (PVOID)USB_OHCD_CONVERT_FROM_BUS_MEM(                                   uHostControllerIndex,                                   (USB_OHCD_SWAP_DATA(uHostControllerIndex,                                   (UINT32)pTransferCompletion)));            /* Debug print */            OS_LOG_MESSAGE_LOW (                OHCD,                "%d: Received Write Back Done Head interrupt, TD [0x%08X]\n",                uHostControllerIndex,                (UINT32) pTransferCompletion,                0,                0);            /* Clear the write back done head interrupt */            USB_OHCI_REG_WRITE (uHostControllerIndex, 				(pOhciControllerInfo->uBaseAddress +                  USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET),				USB_OHCI_INTERRUPT_STATUS_DONE_HEAD);            /* Call the function to process the done head interrupt */            usbOhciProcessTransferCompletion (uHostControllerIndex,											  pTransferCompletion);        	}        /*          * NOTE: The least significant bit of the HccaDoneHead is set to 1         *       to indicate whether an unmasked HcInterruptStatus was set         *       when HccaDoneHead was written.         *         *       HANDLING OF THE ABOVE INTERRUPT CONDITION IS PENDING.         */        /* Check whether the SOF interrupt is pending */        if ((uInterruptStatus & USB_OHCI_INTERRUPT_STATUS_SOF) ==			USB_OHCI_INTERRUPT_STATUS_SOF)        	{            /* Clear the SOF interrupt */            USB_OHCI_REG_WRITE (uHostControllerIndex, 				(pOhciControllerInfo->uBaseAddress +                                  USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET),				USB_OHCI_INTERRUPT_STATUS_SOF);            /* Wait for the 'endpoint list access event' before updating the             * list. This event is important to prevent simultaneous updation of             * the endpoint descriptor list.             */            OS_WAIT_FOR_EVENT(pOhciControllerInfo->endpointListAccessEvent,                          OS_WAIT_INFINITE);            /*             * Obtain the pointer to the pipe marked for deletion or              * cancellation of transfer.             */            pEndpointDescriptor = 				pOhciControllerInfo->pDisabledEndpointListHead;            /*              * For all the pipes marked for deletion or cancellation of              * transfer, signal the event for deletion of pipe or cancellation              * of transfers.             */            while (pEndpointDescriptor != NULL)            	{                /*                  * Obtain the pointer to the next pipe marked for deletion                 * or transfer cancellation.                 *                 * NOTE: This step is very important if the ISR is run as a                  *       task. Especially if the ISR task if of the same                  *       priority as the other task. It might happen that                  *       the task waiting for the pipe to be deleted is                 *       scheduled. This task will delete the pipe. Hence,                 *       the operation to obtain the next pipe marked for                  *       deletion will crash.                 */                pOhciControllerInfo->pDisabledEndpointListHead =                     pEndpointDescriptor->pNextEndpointDescriptorToBeDisabled;                /*                  * Signal the event for the deletion of the pipe or                  * cancellation of transfers.                 */                OS_RELEASE_EVENT (pEndpointDescriptor->DisableEndpointEvent);                /*                  * Update the pointer to the next pipe marked for deletion                  * or transfer cancellation.                 */                pEndpointDescriptor =                     pOhciControllerInfo->pDisabledEndpointListHead;            	} /* End of while (NULL != pEndpointDescriptor) */            /* Release the 'endpoint list access event' before updating the             * list. This event is important to prevent simultaneous updation of             * the endpoint descriptor list.             */            OS_RELEASE_EVENT(pOhciControllerInfo->endpointListAccessEvent);        	}	/* End of if ((uInterruptStatus ...)) */        /* Check whether the root hub status change interrupt is pending */        if ((uInterruptStatus & USB_OHCI_INTERRUPT_STATUS_RHSC) == 			USB_OHCI_INTERRUPT_STATUS_RHSC)        	{            /* Clear the root hub status change interrupt */            USB_OHCI_REG_WRITE (uHostControllerIndex, 				(pOhciControllerInfo->uBaseAddress +                  USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET),				USB_OHCI_INTERRUPT_STATUS_RHSC);#if (CPU == SH7750)            /*              * As long as any of the status change bits are set in the Root hub             * port registers, the Root hub status change interrupt does not              * get cleared only in the case of              * the onboard host controller. Due to this reason, the RHSC             * interrupt is generated frequently. Because of this,               * the "usbOhciIsr" thread does not allow any tasks of              * lower priority to be executed if the scheduling mode is a               * priority based scheduling.             * This is done to explicitly reschedule             * other threads in the system.             */        	OS_RESCHEDULE_THREAD();#endif    	            /*              * Check whether the status change request is pending for              * the root hub.             */            if (pOhciControllerInfo->pRootHubInterruptRequest != NULL)            	{                /* Call the function to process the root hub status change */                usbOhciProcessRootHubStatusChange (uHostControllerIndex);            	}        	}        /* Check whether the resume detect interrupt is pending */        if ((uInterruptStatus & USB_OHCI_INTERRUPT_STATUS_RESUME_DETECT) == 			USB_OHCI_INTERRUPT_STATUS_RESUME_DETECT)        	{            /* Clear the resume detect interrupt */            USB_OHCI_REG_WRITE (uHostControllerIndex, 				(pOhciControllerInfo->uBaseAddress +                  USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET),				USB_OHCI_INTERRUPT_STATUS_RESUME_DETECT);            /*              * Check whether the remote wakeup feature is enabled for             * the root hub.             */            if (pOhciControllerInfo->bRemoteWakeupEnabled)            	{                /* Service the remote wakeup interrupt */                /* PENDING */            	}        	}    	}	/* End of if (uInterruptStatus != 0) */#ifndef USB_OHCI_POLLING_MODE    /* Enable the interrupts */    USB_OHCI_REG_WRITE (uHostControllerIndex,         (pOhciControllerInfo->uBaseAddress +            USB_OHCI_INTERRUPT_ENABLE_REGISTER_OFFSET),		USB_OHCI_INTERRUPT_MASK);#endif /* End of #ifndef USB_OHCI_POLLING_MODE */        return;	} /* End of function usbOhciProcessInterrupts () *//* End of File usbOhciIsr.c */

⌨️ 快捷键说明

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