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

📄 usbohci.c

📁 usb2 driver for vxwokrs
💻 C
📖 第 1 页 / 共 4 页
字号:
    {       /* To hold the state of the OHCI Controller after reset */    UINT32          uOhciControllerState = 0;    /* To hold the value read from the registers */    UINT32          uRegisterValue = 0;    /* To hold the status of the operation */    BUS_OPERATION_STATUS     uStatus = BUS_OPERATION_SUCCESS;    /* To hold the status of initializing the root hub emulation module */    USBHST_STATUS   nRootHubEmulationInit = FALSE;    /* To hold the value of the HcFmInterval register */    UINT32          uHcFmInterval = 0;    /* To hold the temporary data */    UINT32          uTemp = 0;    /* To hold the default control endpoint descriptor */    USB_ENDPOINT_DESCRIPTOR controlEndpointDescriptor =    	{        7,                                      /* bLength */        USB_OHCI_ENDPOINT_DESCRIPTOR_TYPE,      /* Endpoint Descritpor Type */        0x00,                                   /* Endpoint Address */        USB_OHCI_CONTROL_TRANSFER,              /* bmAttributes */        USB_DEFAULT_DEVICE_MAXIMUM_PACKET_SIZE,	/* wMaxPacketSize */        0                                       /* bInterval */    	};    /* To hold the pointer to the host controller information */    PUSB_OHCI_INFORMATION   pOhciControllerInfo = NULL;    /* Obtain the pointer to the host controller information */    pOhciControllerInfo = &usbOhciControllerInfo[uHostControllerIndex];    pOhciControllerInfo->uIrqNumber = pOhciBusInfo[uHostControllerIndex]->irq;    pOhciControllerInfo->uBaseAddress =                       (UINT32)pOhciBusInfo[uHostControllerIndex]->pBaseAddress;        /* Initialize the OHCI Controller (BEGIN) */    /*     * The following initization steps should be followed to initialize     * the OHCI Host Controller:     *     * a) Save the contents of the HcFmInterval register.     * b) Issue a software reset to the host controller. It takes 1 micro     *    second to complete the software reset.     * c) Restore the contents of the HcFmInterval register.     * d) Initialize the device data HCCA block to match the current     *    device data state.     * e) Initialize the Operational Registers to match the current device     *    data state.     * f) Program the HcHCCA register with the physical address of the     *    HCCA block.     * g) Set HcInterruptEnable to have all interrupt enabled except SOF     *    detect.     * h) Set HcControl to have "all queues on".     * i) Set HcPeriodicStart to a value that is 90% of the value in     *    FrameInterval field of HcFmInterval register.     * j) Put the host control in Operation State.     */    OS_LOG_MESSAGE_LOW(        OHCD,        "Entering the function: usbOhciInitializeHostController().\n",         0,         0,         0,         0);    /* Create the endpoint list access event */    pOhciControllerInfo->endpointListAccessEvent =        OS_CREATE_EVENT (OS_EVENT_SIGNALED);    /* Check whether the event was created successfully */    if (pOhciControllerInfo->endpointListAccessEvent == OS_INVALID_EVENT_ID)    	{        return FALSE;    	}    /*     * Allocate memory for the Host Controller Communication Area.     *     * NOTE: This memory should be aligned to 256 bytes boundary.     */    pOhciControllerInfo->pHcca =        (PUSB_OHCI_HCCA) OS_MALLOC (sizeof(USB_OHCI_HCCA) + 256);    /* Check whether memory was allocated successfully */    if (pOhciControllerInfo->pHcca == NULL)    	{        return FALSE;    	}    /* Reset the Host Controller Communication Area */    OS_MEMSET ((PUCHAR) pOhciControllerInfo->pHcca,              0,              sizeof(USB_OHCI_HCCA) + 256);    /*     * Check whether the Host Controller Communication Area is aligned to     * 256 bytes boundary.     */    uTemp = (UINT32) pOhciControllerInfo->pHcca;    if ((uTemp % 256) != 0)    	{        /*         * Align the Host Controller Communication Area to 256 bytes         * boundary         */        pOhciControllerInfo->pHccaAligned =            (PUSB_OHCI_HCCA) ((uTemp & (~0xFF)) + 256);    	}    else    	{        /* Initialize the Host Controller Communication Area pointer */        pOhciControllerInfo->pHccaAligned = pOhciControllerInfo->pHcca;    	}    /* Create the pipe for the default control endpoint */    uStatus = usbOhciCreatePipe (				uHostControllerIndex,				USB_DEFAULT_DEVICE_ADDRESS,				USB_DEFAULT_DEVICE_SPEED,				(PUCHAR) (&controlEndpointDescriptor),				(UINT16) 0,				(PUINT32) (&pOhciControllerInfo->pDefaultEndpointDescriptor));    /*     * Check whether the pipe for default control endpoint was created     * successfully     */    if (uStatus != USBHST_SUCCESS)    	{        /* Return from the function */        return FALSE;    	}    /* Read the contents of the HcFmInterval register */    uHcFmInterval = USB_OHCI_REG_READ (uHostControllerIndex,                                        (pOhciControllerInfo->uBaseAddress +                                        USB_OHCI_FM_INTERVAL_REGISTER_OFFSET));    /* Reset the OHCI Controller */    USB_OHCI_REG_WRITE (uHostControllerIndex,                         (pOhciControllerInfo->uBaseAddress +                         USB_OHCI_COMMAND_STATUS_REGISTER_OFFSET),                        USB_OHCI_COMMAND_STATUS_HCR);    /*     * Wait for the reset operation to complete. The reset operation should     * be completed in 1 micro second. However, a delay of 1 milli second     * is provided.     *     * NOTE: This extra delay will not create any performance issues.     *       Since the host controller is being enabled, this delay is     *       acceptable.     */    OS_DELAY_MS (USB_OHCI_WAIT_FOR_HOST_CONTROLLER_RESET_COMPLETION);    /* Wait for the reset to be complete */    while ((USB_OHCI_REG_READ (uHostControllerIndex,                           (pOhciControllerInfo->uBaseAddress +                            USB_OHCI_COMMAND_STATUS_REGISTER_OFFSET)) &                            USB_OHCI_COMMAND_STATUS_HCR) !=             0)        {        OS_DELAY_MS(1);        }        /* Check the status of the OHCI Controller */    uOhciControllerState =        USB_OHCI_REG_READ (uHostControllerIndex,                           (pOhciControllerInfo->uBaseAddress +                            USB_OHCI_CONTROL_REGISTER_OFFSET));    /* Check whether the OHCI Controller is in SUSPEND state */    if ((uOhciControllerState & USB_OHCI_CONTROL_HCFS_USB_SUSPEND) !=         USB_OHCI_CONTROL_HCFS_USB_SUSPEND)        {        /* Failed to reset the OHCI Controller */        OS_LOG_MESSAGE_HIGH (            OHCD,            "Failed to reset the host controller ..... \n",            0,            0,            0,            0);        return FALSE;        }    /*     * Update the maximum packet size that can be transmitted by the host     * controller without causing a schedule overrun. (BEGIN)     */    /* Update the largets packet size that can be transmitted in a frame */    /* PENDING: Give proper explanation for this value */    uHcFmInterval = uHcFmInterval | (0x2781 << 16);    /*     * Update the maximum packet size that can be transmitted by the host     * controller without causing a schedule overrun. (END)     */         /* Restore the contents of the HcFmInterval register */    USB_OHCI_REG_WRITE (uHostControllerIndex,                        (pOhciControllerInfo->uBaseAddress +                         USB_OHCI_FM_INTERVAL_REGISTER_OFFSET),                         uHcFmInterval);    /* Flush the contents of the cache to the RAM */    DMA_FLUSH(pOhciControllerInfo->pHccaAligned, sizeof(USB_OHCI_HCCA));    /* Invalidate the cache */    DMA_INVALIDATE(pOhciControllerInfo->pHccaAligned, sizeof(USB_OHCI_HCCA));    /*     * Program the Host Controller Communication Area into the HcHCCA     * Register     */    USB_OHCI_REG_WRITE (uHostControllerIndex,                         (pOhciControllerInfo->uBaseAddress +                         USB_OHCI_HCCA_REGISTER_OFFSET),              		(USB_OHCD_CONVERT_TO_BUS_MEM (uHostControllerIndex,                        pOhciControllerInfo->pHccaAligned)));    /*     * Initialize the Host Controller Communication Area for interrupt and     * isochronous transfers.     *     * NOTE: No initialization is required. The transfers will be queued     *       based on the need.     */    /*     * Initialize the head pointer for bulk transfers.     *     * NOTE: No initailization is required. The transfers will be queued     *       based on the need.     */    /* Initialize the head pointer for control transfers (BEGIN) */    /* Program the HcControlHeadED register */    USB_OHCI_REG_WRITE (uHostControllerIndex, 		(pOhciControllerInfo->uBaseAddress +                 USB_OHCI_CONTROL_HEAD_ED_REGISTER_OFFSET),                (USB_OHCD_CONVERT_TO_BUS_MEM (uHostControllerIndex,                 pOhciControllerInfo->pDefaultEndpointDescriptor)));    /* Initialize the head pointer for control transfers (END) */    /*     * Enable the data transfers lists in the HcControl Register (BEGIN)     *     * The following lists are initialized.     *     * a) Control List Enable     * b) Bulk List Enable     * c) Periodic List Enable (Interrupt Only)     * d) Isochronous List Enable     */    /* Read the contents of the HcControl register */    uTemp = USB_OHCI_REG_READ (uHostControllerIndex,                                pOhciControllerInfo->uBaseAddress +                                USB_OHCI_CONTROL_REGISTER_OFFSET);    /* Enable the processing of the endpoint descriptor list */    uTemp |= (USB_OHCI_CONTROL_CLE |               USB_OHCI_CONTROL_BLE |               USB_OHCI_CONTROL_PLE |               USB_OHCI_CONTROL_IE);    /* Update the contents of the HcControl register */    USB_OHCI_REG_WRITE (uHostControllerIndex, 		(pOhciControllerInfo->uBaseAddress + USB_OHCI_CONTROL_REGISTER_OFFSET), 		uTemp);    /* Enable the control list in the HcControl Register (END) */    /* Update the HcPeriodicStart Register (BEGIN) */    /* Read the contents of the HcFmInterval register */    uTemp = USB_OHCI_REG_READ (uHostControllerIndex,  			       pOhciControllerInfo->uBaseAddress +                                USB_OHCI_FM_INTERVAL_REGISTER_OFFSET);    /* Obtain the contents of the HcFmInterval::FrameInterval field */    uRegisterValue = uTemp & 0x00003FFF;    /* Compute the frame interval for starting the periodic transfers */    uRegisterValue = (uRegisterValue *                      USB_OHCI_PERCENTAGE_BANDWIDTH_FOR_PERIODIC_TRANSFERS);    uRegisterValue = (uRegisterValue & 0x00003FFF);    /*     * Program the HcPeriodicStart register with the frame interval for     * starting the periodic transfers.     */    USB_OHCI_REG_WRITE (uHostControllerIndex, 		(pOhciControllerInfo->uBaseAddress +                 USB_OHCI_PERIODIC_START_REGISTER_OFFSET),		uRegisterValue);    /* Update the HcPeriodicStart Register (END) */    /*     * Update the maximum periodic bandwidth available on this OHCI host     * controller.     */    pOhciControllerInfo->uMaximumBandwidthAvailable =        (UINT32) (USB_OHCI_MAXIMUM_USB11_BANDWIDTH *                 USB_OHCI_PERCENTAGE_BANDWIDTH_FOR_PERIODIC_TRANSFERS);    /* Set the OHCI Controller to operational state (BEGIN) */    /*     * NOTE: After host controller reset, the host controller enters the     *       USB_SUSPEND state. The host controller should not remain in      *       this state for more than 2 ms. If not, the host controller      *       will enter USB_RESUME state and the host controller should     *       remain in this state for the minimum duration specified in     *       the USB specification (i.e. 5 ms).     */    /* Read the contents of the HC Control Register */    uRegisterValue = USB_OHCI_REG_READ (uHostControllerIndex, 		                        pOhciControllerInfo->uBaseAddress +                                         USB_OHCI_CONTROL_REGISTER_OFFSET);    /* Clear the previous state */    uRegisterValue &= (~USB_OHCI_CONTROL_HCFS_MASK);    /* Set the OHCI Controller in operational state */    uRegisterValue |= USB_OHCI_CONTROL_HCFS_USB_OPERATIONAL;    /* Program the HC Control Register */    USB_OHCI_REG_WRITE (uHostControllerIndex, 		        (pOhciControllerInfo->uBaseAddress +                         USB_OHCI_CONTROL_REGISTER_OFFSET),                        uRegisterValue);    /* Set the OHCI Controller to operational state (END) */    /*     * Update the frame interval register (BEGIN)      *     * NOTE: It is observed that some controllers like Opti OHCI card     *       do not allow the HcFmInterval register to be updated when the      *       controller is in USB_SUSPEND state. Hence, the HcFmInterval      *       register is updated after the host controller is in      *       USB_OPERATIONAL state.     */	OS_DELAY_MS(2);     /* Update the contents of the HcFmInterval register */     USB_OHCI_REG_WRITE (uHostControllerIndex,                         (pOhciControllerInfo->uBaseAddress +                             USB_OHCI_FM_INTERVAL_REGISTER_OFFSET),                         uHcFmInterval);    /* Update the frame interval register (END) */    /* Initialize the root hub emulation module */    nRootHubEmulationInit = usbOhciRootHubEmulationInit (uHostControllerIndex);    /*     * Check whether the root hub emulation module was initialize     * successfully     */    if (nRootHubEmulationInit != USBHST_SUCCESS)        {        /* Failed to initialize the root hub emulation module */        OS_LOG_MESSAGE_HIGH (            OHCD,            "Failed to initialize the root hub emulation module ..... \n",            0,            0,            0,            0);        return FALSE;        }    /* Read the contents of the HcRhDescriptorA Register */    uRegisterValue = USB_OHCI_REG_READ (uHostControllerIndex,                           (pOhciControllerInfo->uBaseAddress +                            USB_OHCI_RH_DESCRIPTOR_A_REGISTER_OFFSET));    uRegisterValue &= ~0x300;    /*      * Set the bit which indicates that the ports are to be powered on     * a per-port basis     */    uRegisterValue |= 0x100;            USB_OHCI_REG_WRITE (uHostControllerIndex,                         (pOhciControllerInfo->uBaseAddress +                         USB_OHCI_RH_DESCRIPTOR_A_REGISTER_OFFSET),

⌨️ 快捷键说明

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