X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FUhciDxe%2FUhci.c;h=92567f93e48d565bd626fbfa84b1bfd68fa8af40;hp=d129af8715c6e41969c710d2416a447f865ae056;hb=cd5ebaa06dca3e6ef3c464081e6defe00d358c69;hpb=1c61953576f35507eb24032fe2804eaf9a0e976c diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c index d129af8715..92567f93e4 100644 --- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c +++ b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c @@ -1,7 +1,9 @@ /** @file -Copyright (c) 2004 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials + The UHCI driver model and HC protocol routines. + +Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -9,35 +11,33 @@ http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -Module Name: - - Uhci.c - -Abstract: - - The UHCI driver model and HC protocol routines. - -Revision History - - **/ #include "Uhci.h" + +EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = { + UhciDriverBindingSupported, + UhciDriverBindingStart, + UhciDriverBindingStop, + 0x20, + NULL, + NULL +}; + /** Provides software reset for the USB host controller according to UEFI 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param Attributes A bit mask of the reset operation to perform. See - below for a list of the supported bit mask values. + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param Attributes A bit mask of the reset operation to perform. See + below for a list of the supported bit mask values. - @return EFI_SUCCESS : The reset operation succeeded. - @return EFI_INVALID_PARAMETER : Attributes is not valid. - @return EFI_UNSUPPORTED : This type of reset is not currently supported - @return EFI_DEVICE_ERROR : Other errors + @return EFI_SUCCESS The reset operation succeeded. + @return EFI_INVALID_PARAMETER Attributes is not valid. + @return EFI_UNSUPPORTED This type of reset is not currently supported. + @return EFI_DEVICE_ERROR Other errors. **/ -STATIC EFI_STATUS EFIAPI Uhci2Reset ( @@ -112,15 +112,14 @@ ON_INVAILD_PARAMETER: /** Retrieves current state of the USB host controller according to UEFI 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param State Variable to receive current device state + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param State Variable to receive current device state. - @return EFI_SUCCESS : The state is returned - @return EFI_INVALID_PARAMETER : State is not valid. - @return EFI_DEVICE_ERROR : Other errors2006 + @return EFI_SUCCESS The state is returned. + @return EFI_INVALID_PARAMETER State is not valid. + @return EFI_DEVICE_ERROR Other errors. **/ -STATIC EFI_STATUS EFIAPI Uhci2GetState ( @@ -141,7 +140,7 @@ Uhci2GetState ( UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET); UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET); - if (UsbCmd & USBCMD_EGSM) { + if ((UsbCmd & USBCMD_EGSM) !=0 ) { *State = EfiUsbHcStateSuspend; } else if ((UsbSts & USBSTS_HCH) != 0) { @@ -158,16 +157,15 @@ Uhci2GetState ( /** Sets the USB host controller to a specific state according to UEFI 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param State Indicates the state of the host controller that will - be set. + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param State Indicates the state of the host controller that will + be set. - @return EFI_SUCCESS : Host controller was successfully placed in the state - @return EFI_INVALID_PARAMETER : State is invalid. - @return EFI_DEVICE_ERROR : Failed to set the state + @return EFI_SUCCESS Host controller was successfully placed in the state. + @return EFI_INVALID_PARAMETER State is invalid. + @return EFI_DEVICE_ERROR Failed to set the state. **/ -STATIC EFI_STATUS EFIAPI Uhci2SetState ( @@ -265,19 +263,18 @@ ON_EXIT: /** Retrieves capabilities of USB host controller according to UEFI 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance - @param MaxSpeed A pointer to the max speed USB host controller - supports. - @param PortNumber A pointer to the number of root hub ports. - @param Is64BitCapable A pointer to an integer to show whether USB host - controller supports 64-bit memory addressing. + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param MaxSpeed A pointer to the max speed USB host controller + supports. + @param PortNumber A pointer to the number of root hub ports. + @param Is64BitCapable A pointer to an integer to show whether USB host + controller supports 64-bit memory addressing. - @return EFI_SUCCESS : capabilities were retrieved successfully. - @return EFI_INVALID_PARAMETER : MaxSpeed or PortNumber or Is64BitCapable is NULL. - @return EFI_DEVICE_ERROR : An error was encountered + @return EFI_SUCCESS capabilities were retrieved successfully. + @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL. + @return EFI_DEVICE_ERROR An error was encountered. **/ -STATIC EFI_STATUS EFIAPI Uhci2GetCapability ( @@ -313,14 +310,15 @@ Uhci2GetCapability ( // returns 0 in this bit if port number is invalid. Also, if // PciIo IoRead returns error, 0xFFFF is returned to caller. // - if (((PortSC & 0x80) != 0) && (PortSC != 0xFFFF)) { - (*PortNumber)++; + if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) { + break; } + (*PortNumber)++; } Uhc->RootPorts = *PortNumber; - DEBUG ((EFI_D_INFO, "Uhci2GetCapability: %d ports\n", Uhc->RootPorts)); + DEBUG ((EFI_D_INFO, "Uhci2GetCapability: %d ports\n", (UINT32)Uhc->RootPorts)); return EFI_SUCCESS; } @@ -328,17 +326,16 @@ Uhci2GetCapability ( /** Retrieves the current status of a USB root hub port according to UEFI 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL. - @param PortNumber The port to get status - @param PortStatus A pointer to the current port status bits and port - status change bits. + @param This A pointer to the EFI_USB2_HC_PROTOCOL. + @param PortNumber The port to get status. + @param PortStatus A pointer to the current port status bits and port + status change bits. - @return EFI_SUCCESS : status of the USB root hub port was returned in PortStatus. - @return EFI_INVALID_PARAMETER : PortNumber is invalid. - @return EFI_DEVICE_ERROR : Can't read register + @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus. + @return EFI_INVALID_PARAMETER PortNumber is invalid. + @return EFI_DEVICE_ERROR Can't read register. **/ -STATIC EFI_STATUS EFIAPI Uhci2GetRootHubPortStatus ( @@ -367,24 +364,24 @@ Uhci2GetRootHubPortStatus ( PortSC = UhciReadReg (Uhc->PciIo, Offset); - if (PortSC & USBPORTSC_CCS) { + if ((PortSC & USBPORTSC_CCS) != 0) { PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION; } - if (PortSC & USBPORTSC_PED) { + if ((PortSC & USBPORTSC_PED) != 0) { PortStatus->PortStatus |= USB_PORT_STAT_ENABLE; } - if (PortSC & USBPORTSC_SUSP) { + if ((PortSC & USBPORTSC_SUSP) != 0) { DEBUG ((EFI_D_INFO, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber)); PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND; } - if (PortSC & USBPORTSC_PR) { + if ((PortSC & USBPORTSC_PR) != 0) { PortStatus->PortStatus |= USB_PORT_STAT_RESET; } - if (PortSC & USBPORTSC_LSDA) { + if ((PortSC & USBPORTSC_LSDA) != 0) { PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; } @@ -393,11 +390,11 @@ Uhci2GetRootHubPortStatus ( // PortStatus->PortStatus |= USB_PORT_STAT_OWNER; - if (PortSC & USBPORTSC_CSC) { + if ((PortSC & USBPORTSC_CSC) != 0) { PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION; } - if (PortSC & USBPORTSC_PEDC) { + if ((PortSC & USBPORTSC_PEDC) != 0) { PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE; } @@ -408,18 +405,17 @@ Uhci2GetRootHubPortStatus ( /** Sets a feature for the specified root hub port according to UEFI 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL. - @param PortNumber Specifies the root hub port whose feature is - requested to be set. - @param PortFeature Indicates the feature selector associated with the - feature set request. + @param This A pointer to the EFI_USB2_HC_PROTOCOL. + @param PortNumber Specifies the root hub port whose feature is + requested to be set. + @param PortFeature Indicates the feature selector associated with the + feature set request. - @return EFI_SUCCESS : PortFeature was set for the root port - @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid. - @return EFI_DEVICE_ERROR : Can't read register + @return EFI_SUCCESS PortFeature was set for the root port. + @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. + @return EFI_DEVICE_ERROR Can't read register. **/ -STATIC EFI_STATUS EFIAPI Uhci2SetRootHubPortFeature ( @@ -448,7 +444,7 @@ Uhci2SetRootHubPortFeature ( switch (PortFeature) { case EfiUsbPortSuspend: Command = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET); - if (!(Command & USBCMD_EGSM)) { + if ((Command & USBCMD_EGSM) == 0) { // // if global suspend is not active, can set port suspend // @@ -488,18 +484,17 @@ Uhci2SetRootHubPortFeature ( /** Clears a feature for the specified root hub port according to Uefi 2.0 spec. - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Specifies the root hub port whose feature is - requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param PortNumber Specifies the root hub port whose feature is + requested to be cleared. + @param PortFeature Indicates the feature selector associated with the + feature clear request. - @return EFI_SUCCESS : PortFeature was cleared for the USB root hub port - @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid. - @return EFI_DEVICE_ERROR : Can't read register + @return EFI_SUCCESS PortFeature was cleared for the USB root hub port. + @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. + @return EFI_DEVICE_ERROR Can't read register. **/ -STATIC EFI_STATUS EFIAPI Uhci2ClearRootHubPortFeature ( @@ -590,27 +585,27 @@ Uhci2ClearRootHubPortFeature ( /** - Submits control transfer to a target USB device accroding to UEFI 2.0 spec.. - - This : A pointer to the EFI_USB2_HC_PROTOCOL instance. - DeviceAddress : Target device address - DeviceSpeed : Device speed - MaximumPacketLength : Maximum packet size of the target endpoint - Request : USB device request to send - TransferDirection : Data direction of the Data stage in control transfer - Data : Data to transmit/receive in data stage - DataLength : Length of the data - TimeOut : Maximum time, in microseconds, for transfer to complete. - TransferResult : Variable to receive the transfer result - - @return EFI_SUCCESS : The control transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource. - @return EFI_INVALID_PARAMETER : Some parameters are invalid. - @return EFI_TIMEOUT : Failed due to timeout. - @return EFI_DEVICE_ERROR : Failed due to host controller or device error. + Submits control transfer to a target USB device accroding to UEFI 2.0 spec. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Target device address. + @param DeviceSpeed Device speed. + @param MaximumPacketLength Maximum packet size of the target endpoint. + @param Request USB device request to send. + @param TransferDirection Data direction of the Data stage in control transfer. + @param Data Data to transmit/receive in data stage. + @param DataLength Length of the data. + @param TimeOut Maximum time, in microseconds, for transfer to complete. + @param Translator Transaction translator to be used by this device. + @param TransferResult Variable to receive the transfer result. + + @return EFI_SUCCESS The control transfer was completed successfully. + @return EFI_OUT_OF_RESOURCES Failed due to lack of resource. + @return EFI_INVALID_PARAMETER Some parameters are invalid. + @return EFI_TIMEOUT Failed due to timeout. + @return EFI_DEVICE_ERROR Failed due to host controller or device error. **/ -STATIC EFI_STATUS EFIAPI Uhci2ControlTransfer ( @@ -638,6 +633,7 @@ Uhci2ControlTransfer ( UINT8 *DataPhy; VOID *DataMap; BOOLEAN IsSlowDevice; + UINTN TransferDataLength; Uhc = UHC_FROM_USB2_HC_PROTO (This); TDs = NULL; @@ -665,10 +661,16 @@ Uhci2ControlTransfer ( return EFI_INVALID_PARAMETER; } - if ((TransferDirection != EfiUsbNoData) && (DataLength == NULL)) { + if ((TransferDirection != EfiUsbNoData) && (Data == NULL || DataLength == NULL)) { return EFI_INVALID_PARAMETER; } + if (TransferDirection == EfiUsbNoData) { + TransferDataLength = 0; + } else { + TransferDataLength = *DataLength; + } + *TransferResult = EFI_USB_ERR_SYSTEM; Status = EFI_DEVICE_ERROR; @@ -705,9 +707,11 @@ Uhci2ControlTransfer ( Uhc, DeviceAddress, PktId, + (UINT8*)Request, RequestPhy, + (UINT8*)Data, DataPhy, - *DataLength, + TransferDataLength, (UINT8) MaximumPacketLength, IsSlowDevice ); @@ -722,7 +726,7 @@ Uhci2ControlTransfer ( // the TD to corrosponding queue head, then check // the execution result // - UhciLinkTdToQh (Uhc->CtrlQh, TDs); + UhciLinkTdToQh (Uhc, Uhc->CtrlQh, TDs); Status = UhciExecuteTransfer (Uhc, Uhc->CtrlQh, TDs, TimeOut, IsSlowDevice, &QhResult); UhciUnlinkTdFromQh (Uhc->CtrlQh, TDs); @@ -746,32 +750,30 @@ ON_EXIT: } - /** - Submits bulk transfer to a bulk endpoint of a USB device - - This : A pointer to the EFI_USB2_HC_PROTOCOL instance. - DeviceAddress : Target device address - EndPointAddress : Endpoint number and direction - DeviceSpeed : Device speed - MaximumPacketLength : Maximum packet size of the target endpoint - DataBuffersNumber : Number of data buffers prepared for the transfer. - Data : Array of pointers to the buffers of data - DataLength : On input, size of the data buffer, On output, - actually transferred data size. - DataToggle : On input, data toggle to use; On output, next data toggle - Translator : A pointr to the transaction translator data. - TimeOut : Maximum time out, in microseconds - TransferResult : Variable to receive transfer result - - @return EFI_SUCCESS : The bulk transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource. - @return EFI_INVALID_PARAMETER : Some parameters are invalid. - @return EFI_TIMEOUT : Failed due to timeout. - @return EFI_DEVICE_ERROR : Failed due to host controller or device error. + Submits bulk transfer to a bulk endpoint of a USB device. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Target device address. + @param EndPointAddress Endpoint number and direction. + @param DeviceSpeed Device speed. + @param MaximumPacketLength Maximum packet size of the target endpoint. + @param DataBuffersNumber Number of data buffers prepared for the transfer. + @param Data Array of pointers to the buffers of data. + @param DataLength On input, size of the data buffer, On output, + actually transferred data size. + @param DataToggle On input, data toggle to use; On output, next data toggle. + @param TimeOut Maximum time out, in microseconds. + @param Translator A pointr to the transaction translator data. + @param TransferResult Variable to receive transfer result. + + @return EFI_SUCCESS The bulk transfer was completed successfully. + @return EFI_OUT_OF_RESOURCES Failed due to lack of resource. + @return EFI_INVALID_PARAMETER Some parameters are invalid. + @return EFI_TIMEOUT Failed due to timeout. + @return EFI_DEVICE_ERROR Failed due to host controller or device error. **/ -STATIC EFI_STATUS EFIAPI Uhci2BulkTransfer ( @@ -808,11 +810,7 @@ Uhci2BulkTransfer ( return EFI_INVALID_PARAMETER; } - if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (*DataLength == 0) { + if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) { return EFI_INVALID_PARAMETER; } @@ -844,7 +842,7 @@ Uhci2BulkTransfer ( // Map the source data buffer for bus master access, // then create a list of TDs // - if (EndPointAddress & 0x80) { + if ((EndPointAddress & 0x80) != 0) { Direction = EfiUsbDataIn; } else { Direction = EfiUsbDataOut; @@ -862,6 +860,7 @@ Uhci2BulkTransfer ( DeviceAddress, EndPointAddress, PktId, + (UINT8 *)*Data, DataPhy, *DataLength, DataToggle, @@ -882,7 +881,7 @@ Uhci2BulkTransfer ( // BulkQh = Uhc->BulkQh; - UhciLinkTdToQh (BulkQh, TDs); + UhciLinkTdToQh (Uhc, BulkQh, TDs); Status = UhciExecuteTransfer (Uhc, BulkQh, TDs, TimeOut, FALSE, &QhResult); UhciUnlinkTdFromQh (BulkQh, TDs); @@ -905,27 +904,26 @@ ON_EXIT: Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device according to UEFI 2.0 spec. - This : A pointer to the EFI_USB2_HC_PROTOCOL instance. - DeviceAddress : Target device address - EndPointAddress : Endpoint number and direction - DeviceSpeed : Device speed - MaximumPacketLength : Maximum packet size of the target endpoint - IsNewTransfer : If TRUE, submit a new transfer, if FALSE cancel old transfer - DataToggle : On input, data toggle to use; On output, next data toggle - PollingInterval : Interrupt poll rate in milliseconds - DataLength : On input, size of the data buffer, On output, - actually transferred data size. - Translator : A pointr to the transaction translator data. - CallBackFunction : Function to call periodically - Context : User context - - @return EFI_SUCCESS : Transfer was submitted - @return EFI_INVALID_PARAMETER : Some parameters are invalid. - @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources. - @return EFI_DEVICE_ERROR : Can't read register + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Target device address. + @param EndPointAddress Endpoint number and direction. + @param DeviceSpeed Device speed. + @param MaximumPacketLength Maximum packet size of the target endpoint. + @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer. + @param DataToggle On input, data toggle to use; On output, next data toggle. + @param PollingInterval Interrupt poll rate in milliseconds. + @param DataLength On input, size of the data buffer, On output, + actually transferred data size. + @param Translator A pointr to the transaction translator data. + @param CallBackFunction Function to call periodically. + @param Context User context. + + @return EFI_SUCCESS Transfer was submitted. + @return EFI_INVALID_PARAMETER Some parameters are invalid. + @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources. + @return EFI_DEVICE_ERROR Can't read register. **/ -STATIC EFI_STATUS EFIAPI Uhci2AsyncInterruptTransfer ( @@ -951,7 +949,6 @@ Uhci2AsyncInterruptTransfer ( EFI_STATUS Status; UINT8 *DataPtr; UINT8 *DataPhy; - VOID *DataMap; UINT8 PktId; Uhc = UHC_FROM_USB2_HC_PROTO (This); @@ -959,7 +956,6 @@ Uhci2AsyncInterruptTransfer ( IntTds = NULL; DataPtr = NULL; DataPhy = NULL; - DataMap = NULL; IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE); @@ -1000,40 +996,30 @@ Uhci2AsyncInterruptTransfer ( return EFI_DEVICE_ERROR; } + if ((EndPointAddress & 0x80) == 0) { + PktId = OUTPUT_PACKET_ID; + } else { + PktId = INPUT_PACKET_ID; + } + // // Allocate and map source data buffer for bus master access. // - DataPtr = AllocatePool (DataLength); + DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength); if (DataPtr == NULL) { return EFI_OUT_OF_RESOURCES; } - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - // - // Map the user data then create a queue head and - // list of TD for it. - // - Status = UhciMapUserData ( - Uhc, - EfiUsbDataIn, - DataPtr, - &DataLength, - &PktId, - &DataPhy, - &DataMap - ); + DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength); - if (EFI_ERROR (Status)) { - goto FREE_DATA; - } + OldTpl = gBS->RaiseTPL (UHCI_TPL); Qh = UhciCreateQh (Uhc, PollingInterval); if (Qh == NULL) { Status = EFI_OUT_OF_RESOURCES; - goto UNMAP_DATA; + goto FREE_DATA; } IntTds = UhciCreateBulkOrIntTds ( @@ -1041,6 +1027,7 @@ Uhci2AsyncInterruptTransfer ( DeviceAddress, EndPointAddress, PktId, + DataPtr, DataPhy, DataLength, DataToggle, @@ -1053,7 +1040,7 @@ Uhci2AsyncInterruptTransfer ( goto DESTORY_QH; } - UhciLinkTdToQh (Qh, IntTds); + UhciLinkTdToQh (Uhc, Qh, IntTds); // // Save QH-TD structures to async Interrupt transfer list, @@ -1067,7 +1054,6 @@ Uhci2AsyncInterruptTransfer ( EndPointAddress, DataLength, PollingInterval, - DataMap, DataPtr, CallBackFunction, Context, @@ -1078,7 +1064,7 @@ Uhci2AsyncInterruptTransfer ( goto DESTORY_QH; } - UhciLinkQhToFrameList (Uhc->FrameBase, Qh); + UhciLinkQhToFrameList (Uhc, Qh); gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; @@ -1086,11 +1072,8 @@ Uhci2AsyncInterruptTransfer ( DESTORY_QH: UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW)); -UNMAP_DATA: - Uhc->PciIo->Unmap (Uhc->PciIo, DataMap); - FREE_DATA: - gBS->FreePool (DataPtr); + UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength); Uhc->PciIo->Flush (Uhc->PciIo); gBS->RestoreTPL (OldTpl); @@ -1101,28 +1084,27 @@ FREE_DATA: Submits synchronous interrupt transfer to an interrupt endpoint of a USB device according to UEFI 2.0 spec. - This : A pointer to the EFI_USB2_HC_PROTOCOL instance. - DeviceAddress : Target device address - EndPointAddress : Endpoint number and direction - DeviceSpeed : Device speed - MaximumPacketLength : Maximum packet size of the target endpoint - DataBuffersNumber : Number of data buffers prepared for the transfer. - Data : Array of pointers to the buffers of data - DataLength : On input, size of the data buffer, On output, - actually transferred data size. - DataToggle : On input, data toggle to use; On output, next data toggle - TimeOut : Maximum time out, in microseconds - Translator : A pointr to the transaction translator data. - TransferResult : Variable to receive transfer result - - @return EFI_SUCCESS : The transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource. - @return EFI_INVALID_PARAMETER : Some parameters are invalid. - @return EFI_TIMEOUT : Failed due to timeout. - @return EFI_DEVICE_ERROR : Failed due to host controller or device error. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Target device address. + @param EndPointAddress Endpoint number and direction. + @param DeviceSpeed Device speed. + @param MaximumPacketLength Maximum packet size of the target endpoint. + @param Data Array of pointers to the buffers of data. + @param DataLength On input, size of the data buffer, On output, + actually transferred data size. + @param DataToggle On input, data toggle to use; On output, next data toggle. + @param TimeOut Maximum time out, in microseconds. + @param Translator A pointr to the transaction translator data. + @param TransferResult Variable to receive transfer result. + + @return EFI_SUCCESS The transfer was completed successfully. + @return EFI_OUT_OF_RESOURCES Failed due to lack of resource. + @return EFI_INVALID_PARAMETER Some parameters are invalid. + @return EFI_TIMEOUT Failed due to timeout. + @return EFI_DEVICE_ERROR Failed due to host controller or device error. **/ -STATIC EFI_STATUS EFIAPI Uhci2SyncInterruptTransfer ( @@ -1215,6 +1197,7 @@ Uhci2SyncInterruptTransfer ( DeviceAddress, EndPointAddress, PktId, + (UINT8 *)Data, DataPhy, *DataLength, DataToggle, @@ -1230,7 +1213,7 @@ Uhci2SyncInterruptTransfer ( } - UhciLinkTdToQh (Uhc->SyncIntQh, TDs); + UhciLinkTdToQh (Uhc, Uhc->SyncIntQh, TDs); Status = UhciExecuteTransfer (Uhc, Uhc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult); @@ -1253,22 +1236,21 @@ ON_EXIT: /** Submits isochronous transfer to a target USB device according to UEFI 2.0 spec. - This : A pointer to the EFI_USB2_HC_PROTOCOL instance. - DeviceAddress : Target device address - EndPointAddress : Endpoint number and direction - DeviceSpeed : Device speed - MaximumPacketLength : Maximum packet size of the target endpoint - DataBuffersNumber : Number of data buffers prepared for the transfer. - Data : Array of pointers to the buffers of data - DataLength : On input, size of the data buffer, On output, - actually transferred data size. - Translator : A pointr to the transaction translator data. - TransferResult : Variable to receive transfer result + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Target device address. + @param EndPointAddress Endpoint number and direction. + @param DeviceSpeed Device speed. + @param MaximumPacketLength Maximum packet size of the target endpoint. + @param DataBuffersNumber Number of data buffers prepared for the transfer. + @param Data Array of pointers to the buffers of data. + @param DataLength On input, size of the data buffer, On output, + actually transferred data size. + @param Translator A pointr to the transaction translator data. + @param TransferResult Variable to receive transfer result. @return EFI_UNSUPPORTED **/ -STATIC EFI_STATUS EFIAPI Uhci2IsochronousTransfer ( @@ -1291,21 +1273,22 @@ Uhci2IsochronousTransfer ( /** Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec. - This : A pointer to the EFI_USB2_HC_PROTOCOL instance. - DeviceAddress : Target device address - EndPointAddress : Endpoint number and direction - DeviceSpeed : Device speed - MaximumPacketLength : Maximum packet size of the target endpoint - DataBuffersNumber : Number of data buffers prepared for the transfer. - Data : Array of pointers to the buffers of data - Translator : A pointr to the transaction translator data. - IsochronousCallBack : Function to call when the transfer complete - Context : Pass to the call back function as parameter + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Target device address. + @param EndPointAddress Endpoint number and direction. + @param DeviceSpeed Device speed. + @param MaximumPacketLength Maximum packet size of the target endpoint. + @param DataBuffersNumber Number of data buffers prepared for the transfer. + @param Data Array of pointers to the buffers of data. + @param DataLength On input, size of the data buffer, On output, + actually transferred data size. + @param Translator A pointr to the transaction translator data. + @param IsochronousCallBack Function to call when the transfer complete. + @param Context Pass to the call back function as parameter. @return EFI_UNSUPPORTED **/ -STATIC EFI_STATUS EFIAPI Uhci2AsyncIsochronousTransfer ( @@ -1325,29 +1308,22 @@ Uhci2AsyncIsochronousTransfer ( return EFI_UNSUPPORTED; } +/** + Entry point for EFI drivers. + + @param ImageHandle EFI_HANDLE. + @param SystemTable EFI_SYSTEM_TABLE. + + @retval EFI_SUCCESS Driver is successfully loaded. + @return Others Failed. + +**/ EFI_STATUS EFIAPI UhciDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) -/*++ - - Routine Description: - - Entry point for EFI drivers. - - Arguments: - - ImageHandle - EFI_HANDLE - SystemTable - EFI_SYSTEM_TABLE - - Returns: - - EFI_SUCCESS : Driver is successfully loaded - Others : Failed - ---*/ { return EfiLibInstallDriverBindingComponentName2 ( ImageHandle, @@ -1365,11 +1341,11 @@ UhciDriverEntryPoint ( ControllerHandle that has UsbHcProtocol installed will be supported. @param This Protocol instance pointer. - @param Controller Handle of device to test - @param RemainingDevicePath Not used + @param Controller Handle of device to test. + @param RemainingDevicePath Not used. - @return EFI_SUCCESS : This driver supports this device. - @return EFI_UNSUPPORTED : This driver does not support this device. + @return EFI_SUCCESS This driver supports this device. + @return EFI_UNSUPPORTED This driver does not support this device. **/ EFI_STATUS @@ -1404,7 +1380,7 @@ UhciDriverBindingSupported ( Status = PciIo->Pci.Read ( PciIo, EfiPciIoWidthUint8, - CLASSC_OFFSET, + PCI_CLASSCODE_OFFSET, sizeof (USB_CLASSC) / sizeof (UINT8), &UsbClassCReg ); @@ -1419,7 +1395,7 @@ UhciDriverBindingSupported ( // if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) || - (UsbClassCReg.PI != PCI_CLASSC_PI_UHCI) + (UsbClassCReg.ProgInterface != PCI_IF_UHCI) ) { Status = EFI_UNSUPPORTED; @@ -1439,14 +1415,14 @@ ON_EXIT: /** - Allocate and initialize the empty UHCI device + Allocate and initialize the empty UHCI device. - @param PciIo The PCIIO to use + @param PciIo The PCIIO to use. + @param OriginalPciAttributes The original PCI attributes. - @return Allocated UHCI device + @return Allocated UHCI device. If err, return NULL. **/ -STATIC USB_HC_DEV * UhciAllocateDev ( IN EFI_PCI_IO_PROTOCOL *PciIo, @@ -1510,20 +1486,17 @@ UhciAllocateDev ( return Uhc; ON_ERROR: - gBS->FreePool (Uhc); + FreePool (Uhc); return NULL; } /** - Free the UHCI device and release its associated resources - - @param Uhc The UHCI device to release + Free the UHCI device and release its associated resources. - @return None + @param Uhc The UHCI device to release. **/ -STATIC VOID UhciFreeDev ( IN USB_HC_DEV *Uhc @@ -1533,28 +1506,29 @@ UhciFreeDev ( gBS->CloseEvent (Uhc->AsyncIntMonitor); } + if (Uhc->ExitBootServiceEvent != NULL) { + gBS->CloseEvent (Uhc->ExitBootServiceEvent); + } + if (Uhc->MemPool != NULL) { UsbHcFreeMemPool (Uhc->MemPool); } - if (Uhc->CtrlNameTable) { + if (Uhc->CtrlNameTable != NULL) { FreeUnicodeStringTable (Uhc->CtrlNameTable); } - gBS->FreePool (Uhc); + FreePool (Uhc); } /** - Uninstall all Uhci Interface + Uninstall all Uhci Interface. - @param Controller Controller handle + @param Controller Controller handle. @param This Protocol instance pointer. - @return VOID - **/ -STATIC VOID UhciCleanDevUp ( IN EFI_HANDLE Controller, @@ -1591,19 +1565,43 @@ UhciCleanDevUp ( UhciFreeDev (Uhc); } +/** + One notified function to stop the Host Controller when gBS->ExitBootServices() called. + + @param Event Pointer to this event + @param Context Event hanlder private data + +**/ +VOID +EFIAPI +UhcExitBootService ( + EFI_EVENT Event, + VOID *Context + ) +{ + USB_HC_DEV *Uhc; + + Uhc = (USB_HC_DEV *) Context; + + // + // Stop the Host Controller + // + UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); + + return; +} /** - Starting the Usb UHCI Driver + Starting the Usb UHCI Driver. @param This Protocol instance pointer. - @param Controller Handle of device to test - @param RemainingDevicePath Not used + @param Controller Handle of device to test. + @param RemainingDevicePath Not used. @retval EFI_SUCCESS This driver supports this device. @retval EFI_UNSUPPORTED This driver does not support this device. - @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error - EFI_OUT_OF_RESOURCES- Failed due to resource - shortage + @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error. + EFI_OUT_OF_RESOURCES- Failed due to resource shortage. **/ EFI_STATUS @@ -1654,7 +1652,13 @@ UhciDriverBindingStart ( } PciAttributesSaved = TRUE; - UhciTurnOffUsbEmulation (PciIo); + // + // Robustnesss improvement such as for UoL + // Default is not required. + // + if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) { + UhciTurnOffUsbEmulation (PciIo); + } Status = PciIo->Attributes ( PciIo, @@ -1717,6 +1721,21 @@ UhciDriverBindingStart ( goto FREE_UHC; } + // + // Create event to stop the HC when exit boot service. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + UhcExitBootService, + Uhc, + &gEfiEventExitBootServicesGuid, + &Uhc->ExitBootServiceEvent + ); + if (EFI_ERROR (Status)) { + goto UNINSTALL_USBHC; + } + // // Install the component name protocol // @@ -1744,12 +1763,20 @@ UhciDriverBindingStart ( UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS | USBCMD_MAXP); return EFI_SUCCESS; + +UNINSTALL_USBHC: + gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiUsb2HcProtocolGuid, + &Uhc->Usb2Hc, + NULL + ); FREE_UHC: UhciFreeDev (Uhc); CLOSE_PCIIO: - if (PciAttributesSaved == TRUE) { + if (PciAttributesSaved) { // // Restore original PCI attributes // @@ -1777,8 +1804,8 @@ CLOSE_PCIIO: created by this driver. @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on - @param NumberOfChildren Number of Children in the ChildHandleBuffer + @param Controller Handle of device to stop driver on. + @param NumberOfChildren Number of Children in the ChildHandleBuffer. @param ChildHandleBuffer List of handles for the children we need to stop. @return EFI_SUCCESS @@ -1827,11 +1854,3 @@ UhciDriverBindingStop ( return EFI_SUCCESS; } -EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = { - UhciDriverBindingSupported, - UhciDriverBindingStart, - UhciDriverBindingStop, - 0x20, - NULL, - NULL -};