//**************************************************************************** //**************************************************************************** //** ** //** (C)Copyright 1985-2016, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** //** ** //** Phone (770)-246-8600 ** //** ** //**************************************************************************** //**************************************************************************** //**************************************************************************** // $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/amiusb.c 121 10/16/16 10:11p Wilsonlee $ // // $Revision: 121 $ // // $Date: 10/16/16 10:11p $ // //**************************************************************************** // Revision History // ---------------- // $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/amiusb.c $ // // 121 10/16/16 10:11p Wilsonlee // [TAG] EIP288158 // [Category] Improvement // [Description] Check if gUsbData is integrity. // [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl, // AmiUsbSmmGlobalDataValidationLib.c, // AmiUsbSmmGlobalDataValidationLib.cif, // AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h, // ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, // usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c, // amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c, // AmiUsbController.h, AmiUsbLibInclude.cif, // AmiUsbSmmGlobalDataValidationLib.h // // 120 7/29/16 3:13a Wilsonlee // [TAG] EIP264662 // [Category] Improvement // [Description] Don't install usb hw smi after reconnecting usb // controllers. // [Files] uhcd.c, usb.c, ohci.c, amiusb.c, amiusbhc.c // // 119 7/29/16 3:09a Wilsonlee // [TAG] EIP277810 // [Category] Improvement // [Description] Validate the memory buffer is entirely outside of SMM. // [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c, // usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c, // uhcd.c, uhcd.h, usbmisc.c // // 117 7/07/16 1:09a Wilsonlee // [TAG] EIP277810 // [Category] Improvement // [Description] Validate the memory buffer is entirely outside of SMM. // [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c, // usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c, // uhcd.c, uhcd.h, usbmisc.c // // 116 10/16/15 3:34a Wilsonlee // [TAG] EIP241977 // [Category] Improvement // [Description] Improve UsbKbcAccessControl api function. // [Files] amiusb.c // // 115 4/10/15 3:12a Wilsonlee // [TAG] EIP207413 // [Category] Improvement // [Description] Install UsbApiTable and UsbMassApitTable in // AmiUsbSmmProtocol. // [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c, // ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c // // 114 2/10/15 12:20a Wilsonlee // Fixed build error in non-smm projects. // // 113 12/03/14 9:36p Wilsonlee // [TAG] EIP193805 // [Category] Improvement // [Description] Security Enhancement for SMIHandler in USB module. // [Files] amiusb.c, uhcd.c, usbrt.mak, usbdef.h, usbsb.c // // 112 11/23/14 10:10p Wilsonlee // [TAG] EIP189293 // [Category] Improvement // [Description] Implement XHCI key repeat function. // [Files] usb.c, xhci.c , xhci.h, amiusb.c // // 111 6/05/14 9:15p Wilsonlee // [TAG] EIP171837 // [Category] Bug Fix // [Severity] Critical // [Symptom] When use afuwin update BIOS or read ROMID under pure Win8.1 // OS, sometimes the system will blue screen. // [RootCause] UsbData->EfiKeyboardBuffer is EfiBootServicesData. This // memory isn't reserved in OS. We can't write data to this memory in OS. // [Solution] We clear the buffer at USBKBDProcessKeyboardData function // if the system is under EFI. // [Files] amiusb.c // // 110 4/30/14 5:25a Wilsonlee // [TAG] EIP164842 // [Category] Improvement // [Description] Check if the devices have put into to our queue before // we put them. // [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h, // usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c // // 109 4/07/14 1:28a Wilsonlee // [TAG] EIP157193 // [Category] Improvement // [Description] Stop the usb host controllers at AcpiModeEnable if they // art extend cards or don't support HW SMI. // [Files] amiusb.c // // 108 2/10/14 1:19a Ryanchou // [TAG] EIP149929 // [Category] Improvement // [Description] Stop all external EHCI HCs in ACPI enable call. // [Files] amiusb.c // // 107 12/15/13 10:16p Wilsonlee // [TAG] EIP136594 // [Category] New Feature // [Description] Support 64 bits LBA of usb mass storages. // [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c, // usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin // // 106 11/05/13 4:46a Ryanchou // [TAG] EIP135636 // [Category] Bug Fix // [Severity] Normal // [Symptom] NumLock LED cannot be on/off properly. // [RootCause] It is the side effect of EIP #107429 changes, the // keyboard does not generate break code when pressing NumLock. // [Solution] Remove the EIP #107429 changes. // [Files] amiusb.c, usbkbd.c, efiusbkb.c // // 105 10/19/13 7:06a Ryanchou // [TAG] EIP138257 // [Category] Improvement // [Description] Correct USB HID device type. // [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c // // 104 8/06/13 4:21a Wilsonlee // [TAG] EIP128970 // [Category] Improvement // [Description] UsbInstallHwSmiHandler returns EFI_UNSUPPORTED if // HCType is invalid. // [Files] amiusb.c // // 103 6/02/13 11:43p Wilsonlee // [TAG] EIP123235 // [Category] Improvement // [Description] Stop the usb host controller at ExitBootService if it // is an extend card or it doesn't support HW SMI. // [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c, // uhcd.c // // 102 4/10/13 9:29p Wilsonlee // [TAG] EIP120573 // [Category] Bug Fix // [Severity] Important // [Symptom] Afuwinx64/Safuwinx64 hang up issue. // [RootCause] EfiZeroMem is a boot service function, we can't use it // during runtime. // [Solution] Use MemFill function to clear the KBC buffers. // [Files] amiusb.c // // 101 3/19/13 3:58a Ryanchou // [TAG] EIP118177 // [Category] Improvement // [Description] Dynamically allocate HCStrucTable at runtime. // [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c, // syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c, // usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c, // efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak, // usbmisc.c, usbsrc.sdl // // 100 1/23/13 4:15a Ryanchou // [TAG] EIP111280 // [Category] Improvement // [Description] Add USB APIs for external driver. // [Files] amiusb.c, amiusb.h, usbdef.h // // 99 1/22/13 3:09a Wilsonlee // [TAG] EIP112938 // [Category] Improvement // [Description] Create a header file for usb mass storage driver. // [Files] UsbMass.h, usbmass.c, usbdef.h, amiusb.c, efiusbmass.c // // 98 12/21/12 5:02a Ryanchou // [TAG] EIP71730 // [Category] New Feature // [Description] Added OHCI handoff support. // [Files] usb.sdl, usbport.c, amiusb.c, usbdef.h, UsbPolicy.h, usb.sd, // usb.uni // // 97 12/09/12 12:12a Wilsonlee // [TAG] EIP107429 // [Category] Improvement // [Description] Process the make code even if there is no break code. // [Files] efiusbkb.c, amiusb.c // // 96 12/02/12 10:23p Roberthsu // [TAG] EIP102150 // [Category] Bug Fix // [Severity] Normal // [Symptom] Push key and unplug KB , character repeat can not. // stop // [RootCause] Because repeat key does not clear when usb keyboard // unplug. // [Solution] When keyboard disconnrct, clear keyboard device id with // device id buffer and scancode buffer. // [Files] amiusb.c,syskbc.c,uhcd.c,usbkbd.c // // 95 11/10/12 6:39a Ryanchou // [TAG] EIP99431 // [Category] Bug Fix // [Severity] Minor // [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for // keyboard input // [RootCause] Stopping EFI USB keyboard driver does not stop the // endpoint polling, then application calls UsbAsyncInterruptTransfer, // error will be returned. // [Solution] Stops endpoint polling and release resource when // disconnecting the device driver. And improve the // UsbSyncInterruptTransfer. // [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c, // usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c, // usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h // // 94 8/29/12 8:10a Ryanchou // [TAG] EIP77262 // [Category] New Feature // [Description] Remove SMM dependency of USB. // [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c, // elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c, // efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs, // uhcd.h, usbmisc.c, AmiUsbController.h // // 93 8/07/12 9:39p Wilsonlee // [TAG] EIP96366 // [Category] New Feature // [Description] Add the token "DEFAULT_USB_EMUL6064_OPTION" that // control the default value of the I/O port 60h/64h emulation support // option. // [Files] usb.sd, usb.sdl, amiusb.c, amiusb.h // // 92 6/13/12 7:31a Lavanyap // [TAG] EIP89825 // [Category] Bug Fix // [Severity] Normal // [Symptom] System get's hangs inside the SMI handler while flashing // the Bios. // [RootCause] Port 60/64 access SMI will not be generated immediately // if accessed inside an SMI handler when KbcEmulation is enabled. // [Solution] Emulation is disabled while accessing the Port 60/64. // [Files] amiusb.c // // 91 5/22/12 10:03a Ryanchou // [TAG] EIP90154 // [Category] Improvement // [Description] Remove the USBSB_EnableSmmPeriodicSmi and // USBSB_DisableSmmPeriodicSmi hooks. // [Files] amidef.h, amiusb.c, usb.c, usbsb.c // // 90 5/04/12 6:37a Ryanchou // [TAG] EIP82875 // [Category] Improvement // [Description] Support start/stop individual USB host to avoid // reconnect issues. // [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c, // uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h, // usbbus.c, usbmisc.c // // 89 5/04/12 5:21a Wilsonlee // [TAG] EIP89307 // [Category] Improvement // [Description] Modify incorrect #pragma pack directive. // [Files] amidef.h, amiusb.c, ehci.c, ohci.c, ohci.h, uhci.h, usb.c, // usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, // UsbIo.h // // 88 5/03/12 5:50a Roberthsu // [TAG] EIP84455 // [Category] Improvement // [Description] Implement usb hid device gencric. // [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc // d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c // ,usbsrc.sdl // // 87 1/16/12 6:01a Ryanchou // [TAG] EIP81132 // [Description] Add core version check for EIP80609 solution. // [Files] amiusb.c, usbrt.mak, usbsb.c // // 86 1/14/12 4:09a Ryanchou // [TAG] EIP80609 // [Category] Bug Fix // [Severity] Important // [Symptom] If to enable debug mode and set launch CSM is "Never" in // setup, system will hang at 0xB1 // [RootCause] The pointer AmiUsb is invalid if CSM is not launched, // that may cause CPU exception. // [Solution] Added USB smm protocol, and use SmmLocateProtocol to get // the pointer. // [Files] amiusb.c, AmiUsbController.h, usbrt.mak, usbsb.c // // 85 1/13/12 4:23a Ryanchou // [TAG] EIP47348 // [Category] New Feature // [Description] Support for USB Port Reset function. // [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c, // usbbus.h, usbmass.c // // 84 12/09/11 3:09p Ryanchou // [TAG] EIP7768 // [Category] Bug Fix // [Severity] Important // [Symptom] USB mass storage can't work after unplug and plug under DOS // [RootCause] The SW SMI handler checks USB_FLAG_RUNNING_UNDER_EFI flag // to get the URP from USB global data area or EBDA. Legacy boot event // clears the flag, and UsbPrepareForLegacyOS will not be invoked. // [Solution] Check the URP in USB global data area, if it is not empty, // get it in USB global data area, or get it in EBDA. // [Files] amiusb.c // // 83 11/08/11 8:22a Wilsonlee // [TAG] EIP74876 // [Category] New Feature // [Description] Add USB API for shutdown single USB controller. // [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h, // AmiUsbController.h // // 82 11/08/11 1:41a Ryanchou // [TAG] EIP63188 // [Category] Improvement // [Description] External USB controller support. // [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c, // usbdef.h, usbmisc.c, usbsb.c, xhci.c // // 81 11/05/11 3:26a Ryanchou // [TAG] EIP70094 // [Category] Improvement // [Description] Microsoft CSM Opt-Out feature implementation. // [Files] amiusb.c, uhcd.c // // 80 10/17/11 2:24a Ryanchou // [TAG] EIP69136 // [Category] Improvement // [Description] Remove the dependency of EBDA in USB module for CSM // disabling. // [Files] amiusb.c, uhcd.c, usbport.c, usbsb.c // // 79 9/28/11 10:45a Ryanchou // [TAG] EIP66064 // [Category] Bug Fix // [Severity] Minor // [Symptom] System hangs when waiting for finger swipe // [RootCause] USB driver save the URP pointer to EBDA in function // UsbSmiCore and UsbSmiHc, the pointer will be destroyed if someone also // invoke the two functions. // [Solution] Save the URP pointer before generate SW SMI and restore it // after return from SMI. // [Files] amiusb.c, amiusbhc.c, usbport.c // // 78 8/08/11 6:57a Ryanchou // [TAG] EIP54018 // [Category] New Feature // [Description] Added USB S5 wake up support. // [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h, // usbsb.c xhci.c // // 77 8/05/11 6:18a Ryanchou // [TAG] EIP60706 // [Category] Improvement // [Description] Move gUsbBadDeviceTable into SMRAM. // [Files] usbport.c, amiusb.c, usb.c, uhcd.c, AmiUsbController.h // // 76 7/15/11 6:11a Ryanchou // [TAG] EIP38434 // [Category] New Feature // [Description] Added USB HID report protocol support. // [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c, // efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h, // usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c, // usbsrc.sdl, xhci.c // // 75 7/12/11 8:09a Ryanchou // [TAG] EIP56918 // [Category] New Feature // [Description] Added CCID device support. // [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c, // usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c, // framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h, // AmiUsbController.h, AmiUSBProtocols.cif // // 74 5/03/11 8:44a Ryanchou // [TAG] EIP57521 // [Category] Improvement // [Description] Enumerate root hub ports after start host controllers // in USB_StartLegacy. // [Files] amiusb.c // // 73 3/30/11 9:02a Ryanchou // [TAG] EIP41483 // [Category] Improvement // [Description] Stop timer SMI after legacy shutdown. // [Files] amiusb.c, AmiUsbController.h, ohci.c // // 72 3/29/11 10:07a Ryanchou // [TAG] EIP53518 // [Category] Improvement // [Description] Added chipset xHCI chip support. // [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c, // usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c // // 71 12/24/10 5:02a Tonylo // [TAG] EIP48323 // [Category] Improvement // [Description] Reflush USB keyboard data buffer to avoid junk data // sent after enable USB keyboard data throughput. // [Files] AMIUSB.C // // 70 11/22/10 8:42a Ryanchou // [TAG] EIP48064 // [Category] Improvement // [Description] The SB template implemented elink // AcpiEnableCallbackList, the XHCI/EHCI hand off function should be // invoked via the elink AcpiEnableCallbackList. // [Files] amidef.h, amiusb.c, amiusb.dxs, amiusb.h, // AmiUsbController.h, usb.sdl, usbrt.mak, usbsb.c // // 69 10/07/10 9:32a Ryanchou // EIP42986: Remove the retry loop in UsbHwSmiHandler. // // 68 8/31/10 8:57a Tonylo // Remove user tags for coding standard. // // Description: Remove user tags for coding standard. // // 67 8/18/10 4:22p Olegi // Klockwork related fixes; EIP37978 // // 66 7/27/10 9:11a Ryanchou // EIP41216: Return correct error code when device isn't present. // // 65 7/15/10 4:33a Tonylo // EIP21649 - USB mass storage device still appear in BBS menu when USB // legacy support is disabled. // // 64 6/07/10 8:56a Ryanchou // EIP38547: Fixed system halt when installing FreeBSD. // // 63 3/31/10 6:26p Olegi // // 62 3/25/10 9:45a Olegi // // 61 3/19/10 10:05a Olegi // // 60 1/27/10 5:19p Olegi // Added chipset porting hook to initialize timers. // // 59 12/01/09 10:06a Olegi // EIP31535: RWV error code corrected. // // 58 11/25/09 8:05a Olegi // EIPEIP29733: Added KBC access control API // // 57 10/30/09 5:47p Olegi // // 56 10/02/09 10:49a Olegi // Code cleanup. // // 54 9/15/09 10:21a Olegi // Added USB_INCMPT_HID_DATA_OVERFLOW incompatibility type. // // 53 8/26/09 11:41a Olegi // Changes that prevent collision of keyboard activity and mass storage // access. EIP#22808 // // 52 5/22/09 1:46p Olegi // Added the special treatment for in-built hubs. // // 51 5/21/09 5:11p Olegi // Added checking for hotplug fake drives in Read/Write/Verify functions. // // 50 1/29/09 2:31p Olegi // USB API CheckDevicePresence is extended with USB_SRCH_DEVBASECLASS_NUM // search key. // // 49 1/23/09 4:28p Olegi // Added EXTRA_CHECK_DEVICE_READY condition for the fix to EIP#15037. // // 48 1/05/09 9:40a Olegi // Changes for EIP#15037. Extra CheckDeviceReady call added to read/write // functions. // // 46 10/06/08 3:33p Olegi // EHCI change ownership testing in DOS fix (EIP#14855). // // 44 9/24/08 4:01p Olegi // Modified USBAPI_ChangeOwner so that it allows multiple calls to // acquiring the ownership without releasing it. // // 43 7/04/08 1:07p Olegi // Device "Ultra-X, Inc.: Ultra-X QTP USB HD 1.01" is removed from // incompatible device list. // // 42 6/27/08 5:52p Olegi // Added incompatible devices. // // 41 5/16/08 12:01p Olegi // Compliance with AMI coding standard. // // 40 12/17/07 4:04p Olegi // KBC emulation support added. // // 39 12/05/07 4:36p Olegi // Modification in USBSWSMIHandler() related to the 64/32-bit pointers. // // 36 7/09/07 2:11p Olegi // Changed the maximum data size of the BulkTransfer from 1kB to 64kB. // // 34 6/11/07 2:53p Olegi // Bugfix in device read/write routine: do not issue RWV command if there // is no media present. // // 32 3/20/07 12:16p Olegi // SMITHUNK removed. // // 28 10/18/06 9:40a Andriyn // Fix: race condition on hot-plug in / plug-off // // 27 10/12/06 4:41p Olegi // Modified the method of passing arguments into USBSWSMIHandler: it is // done through memory location, not using CPU register. This change is // only valid for CSM16 versions 31 and later. // // 26 4/14/06 6:39p Olegi // Conversion to be able to use x64 compiler. // // 24 3/20/06 3:37p Olegi // Version 8.5 - x64 compatible. // // 23 3/06/06 6:22p Olegi // Lun devices support modifications: supported using the index in // DEV_INFO table, not through dedicated massLun table. // // 21 1/11/06 11:51a Olegi // LegacyUsbSupport setup question functionality added. // // 18 10/20/05 3:08p Olegi // ReadDevice correction (EST change). // // 14 8/25/05 7:19p Andriyn // USB Keyboard and mouse to use EMUL 60/64 for passing data to KBC. // Fall-back when EMUL 60/64 is not present // // 13 8/23/05 5:50p Olegi // USBMassGetDeviceParameters function added. // // 12 8/11/05 9:53a Olegi // 60/64 port emulation related fixes for EMU6064 driver. // // 11 8/04/05 5:58p Andriyn // Legacy over LegacyFree // // 10 6/20/05 8:55a Olegi // .NET compiler with highest warning level and warning-as-error // modification. // // 9 6/15/05 1:59p Andriyn // Comments were changed // // 6 6/03/05 6:06p Olegi // UsbHwSmiHandler modified to be called individually from UHCI, OHCI and // EHCI drivers. // // 5 6/03/05 9:28a Olegi // ATA Error reporting is corrected in USBWrapGetATAErrorCode. // // 4 6/01/05 5:21p Olegi // Debug message shortened. // // 3 5/17/05 7:51p Andriyn // USB BUS pre-release // // 2 5/10/05 4:11p Andriyn // USBBUS implementation // // 1 3/15/05 9:23a Olegi // Initial VSS check-in. // //**************************************************************************** // //---------------------------------------------------------------------------- // // Name: AMIUSB.C // // Description: AMI USB API implementation. The following code will be // copied to SMM; only RT functions can be used. gUsbData // is obtained from AMIUHCD in the entry point and can be // used afterwards. // //---------------------------------------------------------------------------- // #include #include "amiusb.h" #include "amidef.h" #include //(EIP71750+) #if USB_RUNTIME_DRIVER_IN_SMM #include #include #endif #if USB_DEV_KBD #include "usbkbd.h" #endif #include "UsbMass.h" //(EIP54018+)> #if USB_S5_WAKEUP_SUPPORT #include #include #endif //<(EIP54018+) //#pragma warning (disable: 4152) extern UINT8 IsKbcAccessBlocked; //(EIP29733+) EFI_EMUL6064MSINPUT_PROTOCOL* gMsInput = 0; EFI_EMUL6064KBDINPUT_PROTOCOL* gKbdInput = 0; EFI_EMUL6064TRAP_PROTOCOL* gEmulationTrap = 0; USB_GLOBAL_DATA *gUsbData; //USB_BADDEV_STRUC *gUsbBadDeviceTable; //(EIP60706-) AMI_USB_SMM_PROTOCOL gUsbSmmProtocol = {0}; BOOLEAN gLockSmiHandler = FALSE; BOOLEAN gLockHwSmiHandler = FALSE; BOOLEAN gCheckUsbApiParameter = FALSE; VOID StopControllerType(UINT8); VOID StartControllerType(UINT8); UINT8 USB_StopDevice (HC_STRUC*, UINT8, UINT8); UINT8 USB_EnumerateRootHubPorts(UINT8); //(EIP57521+) VOID StopControllerBdf(UINT16); //(EIP74876+) VOID FillHcdEntries(); //(EIP71750+)> typedef VOID USB_DEV_DELAYED_DRIVER_CHECK (DEV_DRIVER*); extern USB_DEV_DELAYED_DRIVER_CHECK USB_DEV_DELAYED_DRIVER EndOfUsbDevDelayedDriverList; USB_DEV_DELAYED_DRIVER_CHECK* UsbDevDelayedDrivers[]= {USB_DEV_DELAYED_DRIVER NULL}; typedef VOID USB_DEV_DRIVER_CHECK (DEV_DRIVER*); extern USB_DEV_DRIVER_CHECK USB_DEV_DRIVER EndOfUsbDevDriverList; USB_DEV_DRIVER_CHECK* UsbDevDrivers[]= {USB_DEV_DRIVER NULL}; //<(EIP71750+) //(EIP54018+)> #if USB_S5_WAKEUP_SUPPORT VOID UsbSuspend(VOID); #endif #if USB_S5_WAKEUP_SUPPORT // //---------------------------------------------------------------------------- // // Name: UsbS5SmiCallback // // Description: // This function enter usb s5 callback. // //---------------------------------------------------------------------------- // VOID UsbS5SmiCallback( IN EFI_HANDLE DispatchHandle, IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext ) { EFI_STATUS Status = EFI_SUCCESS; #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return; } #endif UsbSuspend(); } // //---------------------------------------------------------------------------- // // Name: UsbPowerButtonSmiCallback // // Description: // This function enter s5 callback if press power button. // //---------------------------------------------------------------------------- // VOID UsbPowerButtonSmiCallback( IN EFI_HANDLE DispatchHandle, IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext ) { EFI_STATUS Status = EFI_SUCCESS; #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return; } #endif UsbSuspend(); } #endif //<(EIP54018+) // //---------------------------------------------------------------------------- // Name: aUsbApiTable - USB API Function Dispatch Table // // Type: Function Dispatch Table // // Description: This is the table of functions used by USB API // // Notes: This functions are invoked via software SMI // //---------------------------------------------------------------------------- // API_FUNC aUsbApiTable[] = { USBAPI_CheckPresence, USBAPI_Start, USBAPI_Stop, USBAPI_DisableInterrupts, USBAPI_EnableInterrupts, USBAPI_MoveDataArea, USBAPI_GetDeviceInfo, USBAPI_CheckDevicePresence, USBAPI_MassDeviceRequest, USBAPI_PowerManageUSB, USBAPI_PrepareForOS, USBAPI_SecureInterface, USBAPI_LightenKeyboardLEDs, USBAPI_ChangeOwner, USBAPI_HC_Proc, USBAPI_Core_Proc, USBAPI_LightenKeyboardLEDs_Compatible, USBAPI_KbcAccessControl, USBAPI_LegacyControl, USBAPI_GetDeviceAddress, USBAPI_ExtDriverRequest, USBAPI_CCIDRequest, USBAPI_UsbStopController, //(EIP74876+) USBAPI_HcStartStop }; // //---------------------------------------------------------------------------- // Name: USBMassAPITable - USB Mass Storage API Function Dispatch Table // // Type: Function Dispatch Table // // Description: This is the table of functions used by USB Mass Storage API // //---------------------------------------------------------------------------- // API_FUNC aUsbMassApiTable[] = { USBMassAPIGetDeviceInformation, // USB Mass API Sub-Func 00h USBMassAPIGetDeviceGeometry, // USB Mass API Sub-Func 01h USBMassAPIResetDevice, // USB Mass API Sub-Func 02h USBMassAPIReadDevice, // USB Mass API Sub-Func 03h USBMassAPIWriteDevice, // USB Mass API Sub-Func 04h USBMassAPIVerifyDevice, // USB Mass API Sub-Func 05h USBMassAPIFormatDevice, // USB Mass API Sub-Func 06h USBMassAPICommandPassThru, // USB Mass API Sub-Func 07h USBMassAPIAssignDriveNumber, // USB BIOS API function 08h USBMassAPICheckDevStatus, // USB BIOS API function 09h USBMassAPIGetDevStatus, // USB BIOS API function 0Ah USBMassAPIGetDeviceParameters // USB BIOS API function 0Bh }; EFI_DRIVER_ENTRY_POINT(USBDriverEntryPoint) // //---------------------------------------------------------------------------- // // Procedure: USBDriverEntryPoint // // Description: USB Driver entry point // //---------------------------------------------------------------------------- // EFI_STATUS USBDriverEntryPoint( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; InitAmiLib(ImageHandle, SystemTable); #if USB_RUNTIME_DRIVER_IN_SMM Status = InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL); #else Status = InstallUsbProtocols(); InitializeUsbGlobalData(); #endif ASSERT_EFI_ERROR(Status); return Status; } // //--------------------------------------------------------------------------- // // Name: InitializeUsbGlobalData // // Description: This function initializes the USB global data. // //--------------------------------------------------------------------------- // EFI_STATUS InitializeUsbGlobalData( VOID ) { EFI_STATUS Status; UINT8 bDriverIndex; UINT8 bDelayedIndex; // // Initialize host controller drivers // FillHcdEntries(); // This routine is implemented in $(BUILD_DIR)\dummyusbrt.c // // Initialize the device driver pointers // bDriverIndex = 0; bDelayedIndex = 0; //(EIP71750)> while(UsbDevDelayedDrivers[bDelayedIndex]) { UsbDevDelayedDrivers[bDelayedIndex](&gUsbData->aDelayedDrivers[bDelayedIndex]); if (gUsbData->aDelayedDrivers[bDelayedIndex].pfnDeviceInit) { (*gUsbData->aDelayedDrivers[bDelayedIndex].pfnDeviceInit)(); } if (gUsbData->aDelayedDrivers[bDelayedIndex].bDevType) { bDelayedIndex++; } } while(UsbDevDrivers[bDriverIndex]) { UsbDevDrivers[bDriverIndex](&gUsbData->aDevDriverTable[bDriverIndex]); if (gUsbData->aDevDriverTable[bDriverIndex].pfnDeviceInit) { (*gUsbData->aDevDriverTable[bDriverIndex].pfnDeviceInit)(); } if (gUsbData->aDevDriverTable[bDriverIndex].bDevType) { bDriverIndex++; } } // // Allocate a block of memory to be used as a temporary // buffer for USB mass transfer // Status = pBS->AllocatePool (EfiRuntimeServicesData, MAX_CONSUME_BUFFER_SIZE, &gUsbData->fpUSBMassConsumeBuffer); ASSERT_EFI_ERROR(Status); pBS->SetMem(gUsbData->fpUSBMassConsumeBuffer, MAX_CONSUME_BUFFER_SIZE, 0); // // Allocate a block of memory for the temporary buffer // Status = gBS->AllocatePool (EfiRuntimeServicesData, MAX_TEMP_BUFFER_SIZE, &gUsbData->fpUSBTempBuffer); ASSERT_EFI_ERROR(Status); pBS->SetMem(gUsbData->fpUSBTempBuffer, MAX_TEMP_BUFFER_SIZE, 0); // // Allow to enumerate ports // gUsbData->bEnumFlag = FALSE; return USB_SUCCESS; } // //--------------------------------------------------------------------------- // // Name: UsbApiHandler // // Description: // //--------------------------------------------------------------------------- // VOID UsbApiHandler(VOID* Param) { URP_STRUC *fpURP = (URP_STRUC*)Param; UINT8 bFuncIndex; UINT8 bNumberOfFunctions; if (fpURP == NULL) { return; } bFuncIndex = fpURP->bFuncNumber; bNumberOfFunctions = sizeof aUsbApiTable / sizeof (API_FUNC *); // // Make sure function number is valid; if function number is not zero // check for valid extended USB API function // if (bFuncIndex && ((bFuncIndex < USB_NEW_API_START_FUNC ) || bFuncIndex > (bNumberOfFunctions + USB_NEW_API_START_FUNC))) { //fpURP->bRetValue = USBAPI_INVALID_FUNCTION; USB_DEBUG(3, "UsbApiHandler Invalid function#%x\n", bFuncIndex); return; } if (bFuncIndex) { bFuncIndex = (UINT8)(bFuncIndex - USB_NEW_API_START_FUNC + 1); } aUsbApiTable[bFuncIndex](fpURP); // Call the appropriate function } // //--------------------------------------------------------------------------- // // Name: InstallUsbProtocols // // Description: This function initializes the USB global data. // //--------------------------------------------------------------------------- // EFI_STATUS InstallUsbProtocols( VOID ) { EFI_STATUS Status; EFI_USB_PROTOCOL *UsbProtocol; Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &UsbProtocol); if (EFI_ERROR(Status)) { return Status; } gUsbData = UsbProtocol->USBDataPtr; UsbProtocol->UsbRtKbcAccessControl = UsbKbcAccessControl; //Hook USB legacy control function for shutdown/init USB legacy support UsbProtocol->UsbLegacyControl = USBRT_LegacyControl; UsbProtocol->UsbStopUnsupportedHc = USB_StopUnsupportedHc; #if !USB_RUNTIME_DRIVER_IN_SMM UsbProtocol->UsbInvokeApi = UsbApiHandler; #endif return Status; } #if USB_RUNTIME_DRIVER_IN_SMM // //---------------------------------------------------------------------------- // // Procedure: InSmmFunction // // Description: SMM entry point of AMIUSB driver // //---------------------------------------------------------------------------- // EFI_STATUS InSmmFunction( EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_SMM_SW_DISPATCH_CONTEXT SwSmiContext; EFI_HANDLE SwSmiHandle = NULL; EFI_SMM_SW_DISPATCH_PROTOCOL *SwSmiDispatch; UINT32 KbcEmulFeature = 0; VOID *ProtocolNotifyRegistration; EFI_EVENT Emul6064Event = NULL; //(EIP54018+)> #if USB_S5_WAKEUP_SUPPORT EFI_SMM_SX_DISPATCH_CONTEXT S5DispatchContext; EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatchProtocol; EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PbDispatchContext; EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PbDispatchProtocol; EFI_HANDLE S5DispatchHandle; EFI_HANDLE PbDispatchHandle; #endif //<(EIP54018+) #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) EFI_HANDLE UsbSmmProtocolHandle = NULL; Status = InitAmiSmmLib(ImageHandle, SystemTable); if (EFI_ERROR(Status)) return Status; #endif InitAmiBufferValidationLib(ImageHandle, SystemTable); InstallUsbProtocols(); InitializeUsbGlobalData(); Status = pBS->LocateProtocol (&gEmul6064TrapProtocolGuid, NULL, &gEmulationTrap); if (EFI_ERROR(Status)) { Status = RegisterProtocolCallback(&gEmul6064TrapProtocolGuid, Emul6064TrapCallback, NULL, &Emul6064Event, &ProtocolNotifyRegistration); } if(!gUsbData->kbc_support) { Status = gBS->LocateProtocol (&gEmul6064MsInputProtocolGuid, NULL, &gMsInput); pBS->LocateProtocol (&gEmul6064KbdInputProtocolGuid, NULL, &gKbdInput); if (Status == EFI_SUCCESS) { gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_ON; if(gEmulationTrap) KbcEmulFeature = gEmulationTrap->FeatureSupported(gEmulationTrap); if(KbcEmulFeature & IRQ_SUPPORTED) { gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_IRQ_SUPPORT; } } else { InitSysKbc( &gKbdInput, &gMsInput ); } } else { // //Init Fake Emulation interface // InitSysKbc( &gKbdInput, &gMsInput ); } Status = USBSB_InstallSmiEventHandlers(); USB_DEBUG(DEBUG_LEVEL_3,"AMIUSB global data at 0x%x\n", gUsbData); // // Register the USB SW SMI handler // Status = pBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid, NULL, &SwSmiDispatch); if (EFI_ERROR (Status)) { USB_DEBUG(DEBUG_LEVEL_0, "SmmSwDispatch protocol: %r\n", Status); return Status; } SwSmiContext.SwSmiInputValue = USB_SWSMI; Status = SwSmiDispatch->Register (SwSmiDispatch, USBSWSMIHandler, &SwSmiContext, &SwSmiHandle); USB_DEBUG(DEBUG_LEVEL_3, "AMIUSB SW SMI registration:: %r\n", Status); #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) gUsbSmmProtocol.UsbStopUnsupportedHc = USB_StopUnsupportedHc; gUsbSmmProtocol.UsbApiTable = aUsbApiTable; gUsbSmmProtocol.UsbMassApiTable = aUsbMassApiTable; gUsbSmmProtocol.GlobalDataValidation.ConstantDataCrc32 = 0; gUsbSmmProtocol.GlobalDataValidation.Crc32Hash = (UINT32)GetCpuTimer(); Status = pSmst->SmmInstallProtocolInterface( &UsbSmmProtocolHandle, &gAmiUsbSmmProtocolGuid, EFI_NATIVE_INTERFACE, &gUsbSmmProtocol ); USB_DEBUG(DEBUG_LEVEL_3, "AMIUSB SMM protocol: %r\n", Status); #endif #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) InitAmiUsbSmmGlobalDataValidationLib(ImageHandle, SystemTable); UpdateAmiUsbSmmGlobalDataCrc32(gUsbData); #endif //(EIP54018+)> #if USB_S5_WAKEUP_SUPPORT Status = pBS->LocateProtocol( &gEfiSmmSxDispatchProtocolGuid, NULL, &SxDispatchProtocol ); if (EFI_ERROR(Status)) { return Status; } S5DispatchContext.Type = SxS5; S5DispatchContext.Phase = SxEntry; Status = SxDispatchProtocol->Register( SxDispatchProtocol, UsbS5SmiCallback, &S5DispatchContext, &S5DispatchHandle ); if (EFI_ERROR(Status)) { return Status; } // Locate Power Button Dispatch Protocol Status = pBS->LocateProtocol( &gEfiSmmPowerButtonDispatchProtocolGuid, NULL, &PbDispatchProtocol ); if (EFI_ERROR(Status)) { return Status; } // Register the handler for power button presses PbDispatchContext.Phase = PowerButtonEntry; Status = PbDispatchProtocol->Register( PbDispatchProtocol, UsbPowerButtonSmiCallback, &PbDispatchContext, &PbDispatchHandle ); #endif //<(EIP54018+) return Status; } // //---------------------------------------------------------------------------- // Procedure: USBSWSMIHandler // // Description: Invoked on reads from SW SMI port with value USB_SWSMI. This // function dispatches the USB Request Packets (URP) to the // appropriate functions. // // Input: EBDA:USB_DATA_EBDA_OFFSET - Pointer to the URP (USB Request // Packet structure) // DispatchHandle - EFI Handle // DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT // // Output: bRetValue Zero on successfull completion // Non-zero on error // //---------------------------------------------------------------------------- // VOID USBSWSMIHandler ( EFI_HANDLE DispatchHandle, EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext ) { URP_STRUC *UsbUrp; UINT16 EbdaSeg; EFI_STATUS Status; if (gLockSmiHandler == TRUE) { return; } #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { gLockHwSmiHandler = TRUE; gLockSmiHandler = TRUE; return; } #endif if (gUsbData->fpURP) { // Call from AMIUSB C area Status = AmiValidateMemoryBuffer((VOID*)gUsbData->fpURP, sizeof(URP_STRUC)); if (EFI_ERROR(Status)) { USB_DEBUG(3, "UsbApiHandler Invalid Pointer, the address is in SMRAM.\n"); return; } UsbUrp = gUsbData->fpURP; gUsbData->fpURP = 0; // Clear the switch } else { if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_OS) { return; } // // Get the fpURP pointer from EBDA // EbdaSeg = *((UINT16*)0x40E); UsbUrp = *(URP_STRUC**)(UINTN)(((UINT32)EbdaSeg << 4) + USB_DATA_EBDA_OFFSET); UsbUrp = (URP_STRUC*)((UINTN)UsbUrp & 0xFFFFFFFF); Status = AmiValidateMemoryBuffer((VOID*)UsbUrp, sizeof(URP_STRUC)); if (EFI_ERROR(Status)) { USB_DEBUG(3, "UsbApiHandler Invalid Pointer, the address is in SMRAM.\n"); return; } } if (UsbUrp == NULL) { return; } gCheckUsbApiParameter = TRUE; UsbApiHandler(UsbUrp); gCheckUsbApiParameter = FALSE; } // //---------------------------------------------------------------------------- // Procedure: UsbHwSmiHandler // // Description: USB Hardware SMI handler. // // Input: Host controller type. // //---------------------------------------------------------------------------- // VOID UsbHwSmiHandler (UINT8 HcType) { UINT8 Index; HC_STRUC *HcStruc; EFI_STATUS Status; if (gLockHwSmiHandler == TRUE) { return; } #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { gLockHwSmiHandler = TRUE; gLockSmiHandler = TRUE; return; } #endif for (Index = 0; Index < gUsbData->HcTableCount; Index++) { HcStruc = gUsbData->HcTable[Index]; if (HcStruc == NULL) { continue; } if (!(HcStruc->dHCFlag & HC_STATE_USED)) { continue; } if (HcStruc->bHCType == HcType) { // Process appropriate interrupt (*gUsbData->aHCDriverTable [GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDProcessInterrupt)(HcStruc); } } } // //---------------------------------------------------------------------------- // Procedure: xhciHWSMIHandler // // Description: USB Hardware SMI handler. // // Input: DispatchHandle - EFI Handle // DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT // // Output: Nothing // //---------------------------------------------------------------------------- // VOID UhciHWSMIHandler ( EFI_HANDLE DispatchHandle, EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext ) { UsbHwSmiHandler(USB_HC_UHCI); } VOID OhciHWSMIHandler ( EFI_HANDLE DispatchHandle, EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext ) { UsbHwSmiHandler(USB_HC_OHCI); } VOID EhciHWSMIHandler ( EFI_HANDLE DispatchHandle, EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext ) { UsbHwSmiHandler(USB_HC_EHCI); } VOID XhciHwSmiHandler ( EFI_HANDLE DispatchHandle, VOID *DispatchContext ) { UsbHwSmiHandler(USB_HC_XHCI); } // //--------------------------------------------------------------------------- // // Name: USBInstallHwSmiHandler // // Description: // This function registers USB hardware SMI callback function. // //--------------------------------------------------------------------------- // EFI_STATUS UsbInstallHwSmiHandler( HC_STRUC *HcStruc ) { EFI_STATUS Status; EFI_SMM_USB_DISPATCH_CONTEXT UsbContext; EFI_SMM_USB_DISPATCH_PROTOCOL *UsbDispatch; EFI_SMM_USB_DISPATCH UsbCallback; EFI_HANDLE Handle = NULL; if (HcStruc->HwSmiHandle != NULL) { return EFI_SUCCESS; } Status = gBS->LocateProtocol( &gEfiSmmUsbDispatchProtocolGuid, NULL, &UsbDispatch); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return Status; } switch (HcStruc->bHCType) { case USB_HC_UHCI: UsbCallback = UhciHWSMIHandler; break; case USB_HC_OHCI: UsbCallback = OhciHWSMIHandler; break; case USB_HC_EHCI: UsbCallback = EhciHWSMIHandler; break; case USB_HC_XHCI: UsbCallback = XhciHwSmiHandler; break; default: return EFI_UNSUPPORTED; } UsbContext.Type = UsbLegacy; UsbContext.Device = HcStruc->pHCdp; Status = UsbDispatch->Register( UsbDispatch, UsbCallback, &UsbContext, &Handle); USB_DEBUG(DEBUG_LEVEL_3, "AMIUSB HC type %x HW SMI registation status:: %r\n", HcStruc->bHCType, Status); if (!EFI_ERROR(Status)) { HcStruc->HwSmiHandle = Handle; } return Status; } #endif // //--------------------------------------------------------------------------- // // Name: Emul6064TrapCallback // // Description: // Update the KbcEmul feature when the Emul6064Trap Protocol becomes available. // //--------------------------------------------------------------------------- // VOID Emul6064TrapCallback ( EFI_EVENT Event, VOID *Context ) { EFI_STATUS Status; UINT32 KbcEmulFeature = 0; Status = gBS->LocateProtocol( &gEmul6064TrapProtocolGuid, NULL, &gEmulationTrap); if(!gUsbData->kbc_support) { Status = gBS->LocateProtocol( &gEmul6064MsInputProtocolGuid, NULL, &gMsInput); gBS->LocateProtocol( &gEmul6064KbdInputProtocolGuid, NULL, &gKbdInput); if (Status == EFI_SUCCESS) { gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_ON; if(gEmulationTrap) KbcEmulFeature = gEmulationTrap->FeatureSupported(gEmulationTrap); if(KbcEmulFeature & IRQ_SUPPORTED) { gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_IRQ_SUPPORT; } } else { InitSysKbc( &gKbdInput, &gMsInput ); } } else { // //Init Fake Emulation interface // InitSysKbc( &gKbdInput, &gMsInput ); } } ////////////////////////////////////////////////////////////////////////////// // // USB API Functions // ////////////////////////////////////////////////////////////////////////////// // //---------------------------------------------------------------------------- // Procedure: USBAPI_MassDeviceRequest // // Description: This routine services the USB API function number 27h. It // handles all the mass storage related calls from the higher // layer. Different sub-functions are invoked depending on // the sub-function number // // Input: fpURPPointer Pointer to the URP structure // fpURPPointer.bSubFunc Subfunction number // 00 Get Device Information // 01 Get Device Parameter // 02 Reset Device // 03 Read Device // 04 Write Device // 05 Verify Device // 06 Format Device // 07 Request Sense // 08 Test Unit Ready // 09 Start Stop Unit // 0A Read Capacity // 0B Mode Sense // 0C Device Inquiry // 0D Send Command // 0E Assign drive number // // Output: URP structure is updated with the relevant information // // //---------------------------------------------------------------------------- // VOID USBAPI_MassDeviceRequest (URP_STRUC *fpURP) { UINT8 bMassFuncIndex = fpURP->bSubFunc; UINT8 bNumberOfMassFunctions = sizeof aUsbMassApiTable / sizeof (API_FUNC *); // // Make sure function number is valid // if (bMassFuncIndex >= bNumberOfMassFunctions) { //fpURP->bRetValue = USBAPI_INVALID_FUNCTION; USB_DEBUG(3, "UsbApi MassDeviceRequet Invalid function#%x\n", bMassFuncIndex); return; } gUsbData->bUSBKBC_MassStorage = 01; // // Function number is valid - call it // aUsbMassApiTable[bMassFuncIndex](fpURP); gUsbData->bUSBKBC_MassStorage = 00; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_CheckPresence // // Description: This routine services the USB API function number 0. It // reports the USB BIOS presence, its version number and // its current status information // // Input: fpURPPointer - Pointer to the URP structure // // Output: URP structure is updated with the following information // CkPresence.wBiosRev USB BIOS revision (0210h means r2.10) // CkPresence.bBiosActive 0 - if USB BIOS is not running // CkPresence.bNumBootDev Number of USB boot devices found // CkPresence.bNumHC Number of host controller present // CkPresence.bNumPorts Number of root hub ports // CkPresence.dUsbDataArea Current USB data area // //---------------------------------------------------------------------------- // VOID USBAPI_CheckPresence (URP_STRUC *fpURP) { fpURP->bRetValue = USB_SUCCESS; fpURP->ApiData.CkPresence.bBiosActive = 0; fpURP->ApiData.CkPresence.bNumBootDev = 0; // Number of USB boot devices found fpURP->ApiData.CkPresence.bNumKeyboards = 0; // Number of USB keyboards present fpURP->ApiData.CkPresence.bNumMice = 0; // Number of USB mice present fpURP->ApiData.CkPresence.bNumPoint = 0; // Number of USB Point present //(EIP38434+) fpURP->ApiData.CkPresence.bNumHubs = 0; // Number of USB hubs present fpURP->ApiData.CkPresence.bNumStorage = 0; // Number of USB storage devices present fpURP->ApiData.CkPresence.wBiosRev = (USB_DRIVER_MAJOR_VER << 4) + USB_DRIVER_MINOR_VER; fpURP->ApiData.CkPresence.bBiosActive = USB_ACTIVE; // Set USB BIOS as active if (!(gUsbData->dUSBStateFlag & USB_FLAG_DISABLE_LEGACY_SUPPORT)) { fpURP->ApiData.CkPresence.bBiosActive |= USB_LEGACY_ENABLE; } if (gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_ON) { fpURP->ApiData.CkPresence.bBiosActive |= USB_6064_ENABLE; } USBWrap_GetDeviceCount(fpURP); // Get active USB devices } // //---------------------------------------------------------------------------- // Procedure: USBAPI_Start // // Description: This API routine configures the USB host controllers and // enumerate the devices // // Input: fpURPPointer URP structure with input parameters // StartHc.wDataAreaFlag Indicates which data area to use // // Output: StartHc.wDataAreaFlag Returns current data area pointer // bRetValue - USB_SUCCESS on success, USB_ERROR on error. // //---------------------------------------------------------------------------- // VOID USBAPI_Start (URP_STRUC *fpURP) { USB_DEBUG(DEBUG_LEVEL_3, "USBSMI: Start\n"); USB_DEBUG(DEBUG_LEVEL_3, "\tUSBAPI_HC_Proc:%x\n", &USBAPI_HC_Proc); USB_DEBUG(DEBUG_LEVEL_3, "\tUSBAPI_Core_Proc:%x\n", &USBAPI_Core_Proc); USB_DEBUG(DEBUG_LEVEL_3, "\tUSB_ReConfigDevice:%x\n", &USB_ReConfigDevice); fpURP->bRetValue = USB_StartHostControllers (gUsbData); USB_DEBUG(DEBUG_LEVEL_3, "USB_StartHostControllers returns %d\n", fpURP->bRetValue); } // //---------------------------------------------------------------------------- // Procedure: USBAPI_Stop // // Description: This routine stops the USB host controllers // // Input: fpURPPointer Pointer to the URP structure // // Output: bRetValue USB_SUCCESS on success // USB_ERROR on error // //---------------------------------------------------------------------------- // VOID USBAPI_Stop (URP_STRUC *fpURP) { gCheckUsbApiParameter = FALSE; fpURP->bRetValue = USB_StopHostControllers (gUsbData); USB_DEBUG(DEBUG_LEVEL_3, "USB_StopHostControllers returns %d\n", fpURP->bRetValue); gUsbData->dUSBStateFlag &= ~(USB_FLAG_DRIVER_STARTED); } // //---------------------------------------------------------------------------- // Procedure: USBAPI_PowerManageUSB // // Description: This routine suspends the USB host controllers // // Input: fpURPPointer Pointer to the URP structure // // Output: None // //---------------------------------------------------------------------------- // VOID USBAPI_PowerManageUSB (URP_STRUC *fpURP) { fpURP->bRetValue = USB_NOT_SUPPORTED; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_PrepareForOS // // Description: This routine updates data structures to reflect that // POST is completed // // Input: fpURPPointer Pointer to the URP structure // // Output: None // //---------------------------------------------------------------------------- // VOID USBAPI_PrepareForOS (URP_STRUC *fpURP) { fpURP->bRetValue = USB_NOT_SUPPORTED; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_SecureInterface // // Description: This routine handles the calls related to security device // // Input: fpURPPointer Pointer to the URP structure // // Output: None // //---------------------------------------------------------------------------- // VOID USBAPI_SecureInterface (URP_STRUC *fpURP) { fpURP->bRetValue = USB_NOT_SUPPORTED; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_DisableInterrupts // // Description: This routine stops the USB host controllers interrupts // // Input: fpURPPointer Pointer to the URP structure // // Output: bRetValue USB_SUCCESS on success // USB_ERROR on error (Like data area not found) // //---------------------------------------------------------------------------- // VOID USBAPI_DisableInterrupts (URP_STRUC *fpURP) { fpURP->bRetValue = USB_NOT_SUPPORTED; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_EnableInterrupts // // Description: This routine re-enable the USB host controller interrupts // // Input: fpURPPointer Pointer to the URP structure // // Output: bRetValue USB_SUCCESS on success // USB_ERROR on error (Like data area not found) // //---------------------------------------------------------------------------- // VOID USBAPI_EnableInterrupts (URP_STRUC *fpURP) { fpURP->bRetValue = USB_NOT_SUPPORTED; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_MoveDataArea // // Description: This routine stops the USB host controllers and moves // the data area used by host controllers to a new area. // The host controller is started from the new place. // // Input: fpURPPointer URP structure with input parameters // StartHc.wDataAreaFlag Indicates which data area to use // // Output: bRetValue USB_SUCCESS // //---------------------------------------------------------------------------- // VOID USBAPI_MoveDataArea(URP_STRUC *fpURP) { fpURP->bRetValue = USB_NOT_SUPPORTED; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_GetDeviceInfo // // Description: This routine returns the information regarding // a USB device like keyboard, mouse, floppy drive etc // // Input: fpURPPointer URP structure with input parameters // GetDevInfo.bDevNumber Device number (1-based) whose // information is requested // // Output: URP structure is updated with the following information // GetDevInfo.bHCNumber - HC number in which the device is found // GetDevInfo.bDevType - Type of the device // bRetValue will be one of the following value // USB_SUCCESS on successfull completion // USB_PARAMETER_ERROR if bDevNumber is invalid // USB_ERROR on error // //---------------------------------------------------------------------------- // VOID USBAPI_GetDeviceInfo (URP_STRUC *fpURP) { DEV_INFO* fpDevInfo; // // Initialize the return values // fpURP->ApiData.GetDevInfo.bHCNumber = 0; fpURP->ApiData.GetDevInfo.bDevType = 0; fpURP->bRetValue = USB_ERROR; // // Check for parameter validity // if ( !fpURP->ApiData.GetDevInfo.bDevNumber ) return; fpURP->bRetValue = USB_PARAMETER_ERROR; // // Get the device information structure for the 'n'th device // fpDevInfo = USBWrap_GetnthDeviceInfoStructure(fpURP->ApiData.GetDevInfo.bDevNumber); // if (!wRetCode) return; // USB_PARAMETER_ERROR // // Return value // fpURP->ApiData.GetDevInfo.bDevType = fpDevInfo->bDeviceType; fpURP->ApiData.GetDevInfo.bHCNumber = fpDevInfo->bHCNumber; fpURP->bRetValue = USB_SUCCESS; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_CheckDevicePresence // // Description: This routine checks whether a particular type of USB device // is installed in the system or not. // // Input: fpURPPointer URP structure with input parameters // ChkDevPrsnc.bDevType Device type to find // ChkDevPrsnc.fpHCStruc Pointer to HC being checked for device // connection; if NULL then the total number of devices // connected to ANY controller is returned. // ChkDevPrsnc.bNumber Number of devices connected // // Output: bRetValue will be one of the following value // USB_SUCCESS if device type present, ChkDevPrsnc.bNumber <> 0 // USB_ERROR if device type absent, ChkDevPrsnc.bNumber returns 0 // //---------------------------------------------------------------------------- // VOID USBAPI_CheckDevicePresence (URP_STRUC *fpURP) { UINT8 bSearchFlag; UINTN dData; bSearchFlag = USB_SRCH_DEV_NUM; if (fpURP->bSubFunc == 1) { bSearchFlag = USB_SRCH_DEVBASECLASS_NUM; } // // The total number of devices connected to ANY controller has been requested // dData = (UINTN) USB_GetDeviceInfoStruc( bSearchFlag, 0, fpURP->ApiData.ChkDevPrsnc.bDevType, fpURP->ApiData.ChkDevPrsnc.fpHCStruc); fpURP->ApiData.ChkDevPrsnc.bNumber = (UINT8)dData; fpURP->bRetValue = (UINT8)((fpURP->ApiData.ChkDevPrsnc.bNumber)? USB_SUCCESS : USB_ERROR); } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIGetDeviceInformation // // Description: This function is part of the USB BIOS MASS API. This function // returns the device information of the mass storage device // // Input: fpURPPointer Pointer to the URP structure // bDevAddr USB device address of the device // // Output: bRetValue Return value // fpURPPointer Pointer to the URP structure // dSenseData Sense data of the last command // bDevType Device type byte (HDD, CD, Removable) // bEmuType Emulation type used // fpDevId Far pointer to the device ID // dInt13Entry INT 13h entry point // // Notes: Initially the bDevAddr should be set to 0 as input. This // function returns the information regarding the first mass // storage device (if no device found it returns bDevAddr as // 0FFh) and also updates bDevAddr to the device address of // the current mass storage device. If no other mass storage // device is found then the routine sets the bit7 to 1 // indicating current information is valid but no more mass // device found in the system. The caller can get the next // device info if bDevAddr is not 0FFh and bit7 is not set // //---------------------------------------------------------------------------- // VOID USBMassAPIGetDeviceInformation (URP_STRUC *fpURP) { fpURP->bRetValue = USBMassGetDeviceInfo (&fpURP->ApiData.MassGetDevInfo); } VOID USBMassAPIGetDeviceParameters (URP_STRUC *fpURP) { DEV_INFO *DevInfo; EFI_STATUS Status; DevInfo = fpURP->ApiData.MassGetDevParms.fpDevInfo; Status = UsbDevInfoValidation(DevInfo); if (EFI_ERROR(Status)) { return; } #if USB_RUNTIME_DRIVER_IN_SMM if (gCheckUsbApiParameter) { Status = AmiValidateMemoryBuffer((VOID*)fpURP->ApiData.MassGetDevParms.fpInqData, sizeof(MASS_INQUIRY)); if (EFI_ERROR(Status)) { return; } gCheckUsbApiParameter = FALSE; } #endif fpURP->ApiData.MassGetDevParms.fpInqData = USBMassGetDeviceParameters(DevInfo); fpURP->bRetValue = (fpURP->ApiData.MassGetDevParms.fpInqData == NULL)? USB_ERROR : USB_SUCCESS; } // //----------------------------------------------------------------------------- // Procedure: USBMassAPIGetDevStatus // // Description: This function returns the drive status and media presence // status // // Input: fpURPPointer Pointer to the URP structure // fpURP->ApiData.fpDevInfo - pointer to USB device that is // requested to be checked // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // //------------------------------------------------------------------------------; // VOID USBMassAPIGetDevStatus(URP_STRUC *fpURP) { #if USB_DEV_MASS fpURP->bRetValue = USBMassGetDeviceStatus (&fpURP->ApiData.MassGetDevSts); // USB_DEBUG(DEBUG_LEVEL_3, "USBMassAPIGetDevStatus ... check function call correct?\n"); #endif } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIGetDeviceGeometry // // Description: This function is part of the USB BIOS MASS API. // // Input: fpURPPointer Pointer to the URP structure // bDevAddr USB device address of the device // // Output: bRetValue Return value // fpURPPointer Pointer to the URP structure // dSenseData Sense data of the last command // bNumHeads Number of heads // wNumCylinders Number of cylinders // bNumSectors Number of sectors // wBytesPerSector Number of bytes per sector // bMediaType Media type // //---------------------------------------------------------------------------- // VOID USBMassAPIGetDeviceGeometry(URP_STRUC *fpURP) { fpURP->bRetValue = USBMassGetDeviceGeometry (&fpURP->ApiData.MassGetDevGeo); } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIResetDevice // // Description: This function is part of the USB BIOS MASS API. // // Input: fpURPPointer Pointer to the URP structure // // Output: bRetValue Return value // //---------------------------------------------------------------------------- // VOID USBMassAPIResetDevice (URP_STRUC *fpURP) { UINT8 bDevAddr; DEV_INFO *fpDevInfo; UINT16 wResult; bDevAddr = fpURP->ApiData.MassReset.bDevAddr; // // Get the device info structure for the matching device address // fpDevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, bDevAddr, 0); if((fpDevInfo == NULL)|| (!(fpDevInfo->Flag & DEV_INFO_DEV_PRESENT))) { fpURP->bRetValue = USB_ATA_TIME_OUT_ERR; return; } // // Send Start/Stop Unit command to UFI class device only // fpURP->bRetValue = USB_SUCCESS; if(fpDevInfo->bSubClass == SUB_CLASS_UFI) { wResult = USBMassStartUnitCommand (fpDevInfo); if (wResult) { fpURP->bRetValue = USBWrapGetATAErrorCode(fpURP->ApiData.MassReset.dSenseData); } } } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIReadDevice // // Description: This function is part of the USB BIOS MASS API. // // Input: fpURPPointer Pointer to the URP structure, it contains the following: // bDevAddr USB device address of the device // dStartLBA Starting LBA address // wNumBlks Number of blocks to read // wPreSkipSize Number of bytes to skip before // wPostSkipSize Number of bytes to skip after // fpBufferPtr Far buffer pointer // // Output: fpURPPointer Pointer to the URP structure // bRetValue Return value // dSenseData Sense data of the last command // //---------------------------------------------------------------------------- // VOID USBMassAPIReadDevice ( URP_STRUC *Urp ) { DEV_INFO *DevInfo; UINT8 DevAddr; UINT16 Result; UINT32 Data = 0; UINT8 OpCode; DevAddr = Urp->ApiData.MassRead.DevAddr; if (((DevAddr == USB_HOTPLUG_FDD_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED) == FALSE)) || ((DevAddr == USB_HOTPLUG_HDD_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED) == FALSE)) || ((DevAddr == USB_HOTPLUG_CDROM_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED) == FALSE))) { Urp->bRetValue = USB_ATA_DRIVE_NOT_READY_ERR; return; } // // Get the device info structure for the matching device address // DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0); if ((DevInfo == NULL)|| (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) { Urp->bRetValue = USB_ATA_TIME_OUT_ERR; return; } //(EIP15037+)> #if EXTRA_CHECK_DEVICE_READY // // Check device ready // Data = USBMassCheckDeviceReady(DevInfo); if (Data) { Urp->ApiData.MassRead.dSenseData = Data; Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassRead.dSenseData); //(EIP31535) return; } #endif //<(EIP15037+) // // Issue read command // if (Shr64(DevInfo->MaxLba, 32)) { OpCode = COMMON_READ_16_OPCODE; } else { OpCode = COMMON_READ_10_OPCODE; } Result = USBMassRWVCommand(DevInfo, OpCode, &Urp->ApiData.MassRead); //USB_DEBUG(DEBUG_LEVEL_3, " wr(%x):%x %x", DevAddr, Result, Urp->ApiData.MassRead.dSenseData); if (Result) { Urp->bRetValue = USB_SUCCESS; return; } Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassRead.SenseData); //USB_DEBUG(DEBUG_LEVEL_3, " er(%x):%x", DevAddr, Urp->bRetValue); } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIWriteDevice // // Description: This function is part of the USB BIOS MASS API. // // Input: fpURPPointer Pointer to the URP structure // bDevAddr USB device address of the device // dStartLBA Starting LBA address // wNumBlks Number of blocks to write // wPreSkipSize Number of bytes to skip before // wPostSkipSize Number of bytes to skip after // fpBufferPtr Far buffer pointer // // Output: fpURPPointer Pointer to the URP structure // bRetValue Return value // dSenseData Sense data of the last command // //---------------------------------------------------------------------------- // VOID USBMassAPIWriteDevice( URP_STRUC *Urp ) { DEV_INFO *DevInfo; UINT8 DevAddr; UINT16 Result; UINT32 Data = 0; UINT8 OpCode; DevAddr = Urp->ApiData.MassWrite.DevAddr; if (((DevAddr == USB_HOTPLUG_FDD_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED) == FALSE)) || ((DevAddr == USB_HOTPLUG_HDD_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED) == FALSE)) || ((DevAddr == USB_HOTPLUG_CDROM_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED) == FALSE))) { Urp->bRetValue = USB_ATA_DRIVE_NOT_READY_ERR; return; } // // Get the device info structure for the matching device address // DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0); if((DevInfo == NULL)|| (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) { Urp->bRetValue = USB_ATA_TIME_OUT_ERR; return; } /* if (!(DevInfo->bLastStatus & USB_MASS_MEDIA_PRESENT)) { Urp->bRetValue = USB_ATA_NO_MEDIA_ERR; return; } */ //(EIP15037+)> #if EXTRA_CHECK_DEVICE_READY // // Check device ready // Data = USBMassCheckDeviceReady(DevInfo); if (Data) { Urp->ApiData.MassRead.dSenseData = Data; Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassWrite.dSenseData); //(EIP31535) return; } #endif //<(EIP15037+) // // Issue write command // if (Shr64(DevInfo->MaxLba, 32)) { OpCode = COMMON_WRITE_16_OPCODE; } else { OpCode = COMMON_WRITE_10_OPCODE; } Result = USBMassRWVCommand(DevInfo, OpCode, &Urp->ApiData.MassWrite); if (Result) { Urp->bRetValue = USB_SUCCESS; return; } Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassWrite.SenseData); } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIVerifyDevice // // Description: This function is part of the USB BIOS MASS API. // // Input: fpURPPointer Pointer to the URP structure // bDevAddr USB device address of the device // dStartLBA Starting LBA address // wNumBlks Number of blocks to write // wPreSkipSize Number of bytes to skip before // wPostSkipSize Number of bytes to skip after // fpBufferPtr Far buffer pointer // // Output: fpURPPointer Pointer to the URP structure // bRetValue Return value // dSenseData Sense data of the last command // //---------------------------------------------------------------------------- // VOID USBMassAPIVerifyDevice( URP_STRUC *Urp ) { DEV_INFO *DevInfo; UINT8 DevAddr; UINT16 Result; UINT32 Data = 0; UINT8 OpCode; DevAddr = Urp->ApiData.MassVerify.DevAddr; if (((DevAddr == USB_HOTPLUG_FDD_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED) == FALSE)) || ((DevAddr == USB_HOTPLUG_HDD_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED) == FALSE)) || ((DevAddr == USB_HOTPLUG_CDROM_ADDRESS) && ((gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED) == FALSE))) { Urp->bRetValue = USB_ATA_DRIVE_NOT_READY_ERR; return; } // // Get the device info structure for the matching device address // DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0); if ((DevInfo == NULL)|| (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) { Urp->bRetValue = USB_ATA_TIME_OUT_ERR; return; } //(EIP15037+)> #if EXTRA_CHECK_DEVICE_READY // // Check device ready // Data = USBMassCheckDeviceReady(DevInfo); if (Data) { Urp->ApiData.MassRead.dSenseData = Data; Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassVerify.dSenseData); //(EIP31535) return; } #endif //<(EIP15037+) // // Issue write command // if (Shr64(DevInfo->MaxLba, 32)) { OpCode = COMMON_VERIFY_16_OPCODE; } else { OpCode = COMMON_VERIFY_10_OPCODE; } Result = USBMassRWVCommand(DevInfo, OpCode, &Urp->ApiData.MassVerify); if (Result) { Urp->bRetValue = USB_SUCCESS; return; } Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassVerify.SenseData); } // //---------------------------------------------------------------------------- // Procedure: USBMassAPIFormatDevice // // Description: This function is part of the USB BIOS MASS API. // // Input: fpURPPointer Pointer to the URP structure // // Output: bRetValue Return value // //---------------------------------------------------------------------------- // VOID USBMassAPIFormatDevice(URP_STRUC *fpURP) { fpURP->bRetValue = USB_SUCCESS; } // //---------------------------------------------------------------------------- // Procedure: USBMassAPICommandPassThru // // Description: This function is part of the USB BIOS MASS API. This // function can be used to pass raw command/data sequence to // the USB mass storage device // // Input: fpURPPointer Pointer to the URP structure // // Output: bRetValue Return value // // Modified: Nothing // //---------------------------------------------------------------------------- // VOID USBMassAPICommandPassThru (URP_STRUC *fpURP) { UINT8 Result; MASS_CMD_PASS_THRU *MassCmdPassThru; EFI_STATUS Status = EFI_SUCCESS; MassCmdPassThru = &fpURP->ApiData.MassCmdPassThru; #if USB_RUNTIME_DRIVER_IN_SMM if (gCheckUsbApiParameter) { Status = AmiValidateMemoryBuffer((VOID*)MassCmdPassThru->fpCmdBuffer, MassCmdPassThru->wCmdLength); if (EFI_ERROR(Status)) { return; } Status = AmiValidateMemoryBuffer((VOID*)MassCmdPassThru->fpDataBuffer, MassCmdPassThru->wDataLength); if (EFI_ERROR(Status)) { return; } gCheckUsbApiParameter = FALSE; } #endif Result = USBMassCmdPassThru(MassCmdPassThru); fpURP->bRetValue = Result; } // //----------------------------------------------------------------------------- // Procedure: USBMassAPIAssignDriveNumber // // Description: This function is part of the USB BIOS MASS API. This function // assigns the logical drive device according to the information of the // mass storage device // // Input: fpURPPointer Pointer to the URP structure // bDevAddr USB device address of the device // bLogDevNum Logical Drive Number to assign to the device // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // //------------------------------------------------------------------------------; // VOID USBMassAPIAssignDriveNumber (URP_STRUC *fpURP) { fpURP->bRetValue = USB_SUCCESS; // No errors expected after this point } // //----------------------------------------------------------------------------- // Procedure: USBMassAPICheckDevStatus // // Description: This function is part of the USB BIOS MASS API. This function // invokes USB Mass Storage API handler to check whether device // is ready. If called for the first time, this function retrieves // the mass storage device geometry and fills the corresponding // fpDevInfo fields. // // Input: fpURPPointer Pointer to the URP structure // fpURP->ApiData.fpDevInfo - pointer to USB device that is // requested to be checked // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // //------------------------------------------------------------------------------; // VOID USBMassAPICheckDevStatus(URP_STRUC *fpURP) { #if USB_DEV_MASS UINT32 Result; DEV_INFO *DevInfo; EFI_STATUS Status; DevInfo = fpURP->ApiData.MassChkDevReady.fpDevInfo; Status = UsbDevInfoValidation(DevInfo); if (EFI_ERROR(Status)) { return; } gCheckUsbApiParameter = FALSE; Result = USBMassCheckDeviceReady(fpURP->ApiData.MassChkDevReady.fpDevInfo); fpURP->bRetValue = (UINT8)Result; #endif } // //----------------------------------------------------------------------------- // Procedure: USBAPI_LightenKeyboardLEDs // // Description: This function is part of the USB BIOS API. This function // controls LED state on the connected USB keyboards // // Input: fpURP Pointer to the URP structure // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // //------------------------------------------------------------------------------; // VOID USBAPI_LightenKeyboardLEDs(URP_STRUC *fpURP) { #if USB_DEV_KBD gCheckUsbApiParameter = FALSE; if(fpURP->ApiData.KbLedsData.fpLedMap) { gUsbData->bUSBKBShiftKeyStatus = 0; if(((LED_MAP*)fpURP->ApiData.KbLedsData.fpLedMap)->NumLock) { gUsbData->bUSBKBShiftKeyStatus |= KB_NUM_LOCK_BIT_MASK; } if(((LED_MAP*)fpURP->ApiData.KbLedsData.fpLedMap)->CapsLock) { gUsbData->bUSBKBShiftKeyStatus |= KB_CAPS_LOCK_BIT_MASK; } if(((LED_MAP*)fpURP->ApiData.KbLedsData.fpLedMap)->ScrLock) { gUsbData->bUSBKBShiftKeyStatus |= KB_SCROLL_LOCK_BIT_MASK; } } //USB_DEBUG(DEBUG_LEVEL_3," LEDs: %d\n", gUsbData->bUSBKBShiftKeyStatus); USBKB_LEDOn(); fpURP->bRetValue = USB_SUCCESS; return; #else fpURP->bRetValue = USB_NOT_SUPPORTED; #endif } VOID USBAPI_LightenKeyboardLEDs_Compatible(URP_STRUC *fpURP) { USBAPI_LightenKeyboardLEDs(fpURP); } //(EIP29733+)> // //----------------------------------------------------------------------------- // Procedure: USBAPI_KbcAccessControl // // Description: This function is part of the USB BIOS API. This function // is used to control whether KBC access in USB module // should be blocked or not. // // Input: fpURP Pointer to the URP structure // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // // Notes: // //------------------------------------------------------------------------------; // VOID UsbKbcAccessControl( UINT8 ControlSwitch ) { UINT8 Index; HC_STRUC *HcStruc; #if USB_RUNTIME_DRIVER_IN_SMM EFI_STATUS Status = EFI_SUCCESS; Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { gLockHwSmiHandler = TRUE; gLockSmiHandler = TRUE; return; } #endif gCheckUsbApiParameter = FALSE; IsKbcAccessBlocked = (ControlSwitch != 0)? TRUE : FALSE; for (Index = 0; Index < gUsbData->HcTableCount; Index++) { HcStruc = gUsbData->HcTable[Index]; if (HcStruc == NULL) { continue; } if (HcStruc->dHCFlag & HC_STATE_RUNNING) { break; } } if (Index == gUsbData->HcTableCount) { return; } /* // // Check if the USB access in Legacy mode. If it's legacy mode enable/disable // the Kbcemulation based on the ControlSwitch // if(!(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)) { if(IsKbcAccessBlocked) { if(gEmulationTrap) { // // Keyboard access blocked. Disable the Emulation // gEmulationTrap->TrapDisable(gEmulationTrap); } } else { if(gEmulationTrap) { // // Keyboard access enabled. Enable the KbcEmulation // gEmulationTrap->TrapEnable(gEmulationTrap); } } } */ //(EIP48323+)> //Reflush USB data buffer if intend to disable usb keyboard data throughput. if (IsKbcAccessBlocked) { USBKeyRepeat(NULL, 1); // Disable Key repeat gUsbData->RepeatKey = 0; // Clear Legacy USB keyboard buffer MemFill(gUsbData->aKBCCharacterBufferStart, sizeof(gUsbData->aKBCCharacterBufferStart), 0); gUsbData->fpKBCCharacterBufferHead = gUsbData->aKBCCharacterBufferStart; gUsbData->fpKBCCharacterBufferTail = gUsbData->aKBCCharacterBufferStart; MemFill(gUsbData->aKBCScanCodeBufferStart, sizeof(gUsbData->aKBCScanCodeBufferStart), 0); gUsbData->fpKBCScanCodeBufferPtr = gUsbData->aKBCScanCodeBufferStart; MemFill(gUsbData->aKBCDeviceIDBufferStart, sizeof(gUsbData->aKBCDeviceIDBufferStart), 0); MemFill(gUsbData->aKBCShiftKeyStatusBufferStart, sizeof(gUsbData->aKBCShiftKeyStatusBufferStart), 0); MemFill(gUsbData->aKBInputBuffer, sizeof(gUsbData->aKBInputBuffer), 0); } //<(EIP48323+) } VOID USBAPI_KbcAccessControl(URP_STRUC *fpURP) { UsbKbcAccessControl(fpURP->ApiData.KbcControlCode); } //<(EIP29733+) // //----------------------------------------------------------------------------- // Procedure: USB_StopLegacy // // Description: This function is part of the USB BIOS API. This function init USB // legacy support. // // Input: fpURP Pointer to the URP structure // // Output: None // // Notes: // //------------------------------------------------------------------------------; // VOID USB_StopLegacy(URP_STRUC *fpURP) { //shutdown device first UINT8 bIndex; DEV_INFO *fpDevInfo; HC_STRUC *fpHCStruc; for (bIndex = 1; bIndex < MAX_DEVICES; bIndex ++){ fpDevInfo = gUsbData->aDevInfoTable +bIndex; if ((fpDevInfo->Flag & (DEV_INFO_VALID_STRUC |DEV_INFO_DEV_PRESENT) ) == (DEV_INFO_VALID_STRUC |DEV_INFO_DEV_PRESENT) ){ // fpHCStruc = gUsbData->HcTable[fpDevInfo->bHCNumber - 1]; // USB_StopDevice (fpHCStruc, fpDevInfo->bHubDeviceNumber, fpDevInfo->bHubPortNumber); } } StopControllerType(USB_HC_XHCI); //(EIP57521+) StopControllerType(USB_HC_EHCI); StopControllerType(USB_HC_UHCI); StopControllerType(USB_HC_OHCI); //return as success fpURP->bRetValue = USB_SUCCESS; } // //----------------------------------------------------------------------------- // Procedure: USB_StartLegacy // // Description: This function is part of the USB BIOS API. This function init USB // legacy support. // // Input: fpURP Pointer to the URP structure // // Output: None // // Notes: // //------------------------------------------------------------------------------; // VOID USB_StartLegacy(URP_STRUC *fpURP) { //(EIP57521)> gUsbData->bHandOverInProgress = FALSE; //Start XHCI StartControllerType(USB_HC_XHCI); USB_EnumerateRootHubPorts(USB_HC_XHCI); //Start EHCI StartControllerType(USB_HC_EHCI); USB_EnumerateRootHubPorts(USB_HC_EHCI); //Start UHCI StartControllerType(USB_HC_UHCI); USB_EnumerateRootHubPorts(USB_HC_UHCI); //Start OHCI StartControllerType(USB_HC_OHCI); USB_EnumerateRootHubPorts(USB_HC_OHCI); //<(EIP57521) //return as success fpURP->bRetValue = USB_SUCCESS; } // //----------------------------------------------------------------------------- // Procedure: USBAPI_LegacyControl // // Description: This function is part of the USB BIOS API. This function // is used to shutdown/init USB legacy support. // // Input: fpURP Pointer to the URP structure // // Output: None // // Notes: // //------------------------------------------------------------------------------; // VOID USBAPI_LegacyControl (URP_STRUC *fpURP) { UINT8 bSubLegacyFunc = fpURP->bSubFunc,i; //(EIP102150+) UINT8 Count = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr - (UINT8*)gUsbData->aKBCScanCodeBufferStart); //(EIP102150+) gCheckUsbApiParameter = FALSE; USB_DEBUG(DEBUG_LEVEL_3, "USBAPI_LegacyControl %d\n", fpURP->bSubFunc); if(bSubLegacyFunc==STOP_USB_CONTROLLER){ //(EIP43475+)> USB_StopLegacy (fpURP); //(EIP102150+)> for(i = Count; i > 0; i--) USBKB_DiscardCharacter(&gUsbData->aKBCShiftKeyStatusBufferStart[i-1]); //<(EIP102150+) if(gEmulationTrap) gEmulationTrap->TrapDisable(gEmulationTrap); } if(bSubLegacyFunc==START_USB_CONTROLLER){ USB_StartLegacy (fpURP); if(gEmulationTrap) gEmulationTrap->TrapEnable(gEmulationTrap); } //<(EIP43475+) USB_DEBUG(DEBUG_LEVEL_3, "Result %d\n", fpURP->bRetValue); } //(EIP74876+)> // //----------------------------------------------------------------------------- // Procedure: USBAPI_UsbStopController // // Description: This function is part of the USB BIOS API. This function stops // the USB host controller. // // Input: fpURP Pointer to the URP structure // // Output: None // // Notes: // //------------------------------------------------------------------------------; // VOID USBAPI_UsbStopController (URP_STRUC *fpURP) { gCheckUsbApiParameter = FALSE; StopControllerBdf(fpURP->ApiData.HcBusDevFuncNum); } //<(EIP74876+) //----------------------------------------------------- // //----------------------------------------------------- EFI_STATUS USBRT_LegacyControl (VOID *fpURP) { #if USB_RUNTIME_DRIVER_IN_SMM EFI_STATUS Status = EFI_SUCCESS; Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { gLockHwSmiHandler = TRUE; gLockSmiHandler = TRUE; return EFI_SUCCESS; } #endif // USBAPI_LegacyControl ((URP_STRUC *)fpURP); // return((EFI_STATUS)(((URP_STRUC *)fpURP)->bRetValue)); } // //---------------------------------------------------------------------------- // Procedure: USBAPI_GetDeviceAddress // // Description: // // Input: // // Output: // //---------------------------------------------------------------------------- // VOID USBAPI_GetDeviceAddress( URP_STRUC *Urp ) { UINT8 i; DEV_INFO *DevInfo = NULL; for (i = 1; i < MAX_DEVICES; i++) { if (!(gUsbData->aDevInfoTable[i].Flag & DEV_INFO_VALID_STRUC)) { continue; } if ((gUsbData->aDevInfoTable[i].wVendorId == Urp->ApiData.GetDevAddr.Vid) && (gUsbData->aDevInfoTable[i].wDeviceId == Urp->ApiData.GetDevAddr.Did)) { DevInfo = &gUsbData->aDevInfoTable[i]; } } if (DevInfo == NULL) { Urp->bRetValue = USB_ERROR; return; } Urp->ApiData.GetDevAddr.DevAddr = DevInfo->bDeviceAddress; Urp->bRetValue = USB_SUCCESS; } // //---------------------------------------------------------------------------- // Procedure: USBAPI_ExtDriverRequest // // Description: // // Input: // // Output: // //---------------------------------------------------------------------------- // VOID USBAPI_ExtDriverRequest ( URP_STRUC *Urp ) { DEV_INFO *DevInfo = NULL; DEV_DRIVER *DevDriver; DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR, 0, Urp->ApiData.DevAddr, 0); if (DevInfo == NULL) { Urp->bRetValue = USB_ERROR; return; } DevDriver = UsbFindDeviceDriverEntry(DevInfo->fpDeviceDriver); if (DevDriver != NULL) { DevDriver->pfnDriverRequest(DevInfo, Urp); } } // //----------------------------------------------------------------------------- // Procedure: USB_StopUnsupportedHc // // Description: This routine is called, from host controllers that supports // OS handover functionality, when OS wants the BIOS to hand-over // the host controllers to the OS. This routine will stop HC that // does not support this functionality. // // Input: None // // Output: None // // Notes: // //------------------------------------------------------------------------------; // VOID USB_StopUnsupportedHc() { #if USB_RUNTIME_DRIVER_IN_SMM UINT8 Index; HC_STRUC* HcStruc; EFI_STATUS Status; Status = AmiUsbSmmGlobalDataValidation(gUsbData); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { gLockHwSmiHandler = TRUE; gLockSmiHandler = TRUE; return; } USBSB_UninstallTimerHandlers(); USB_DEBUG(DEBUG_LEVEL_3, "Stopping all external HCs"); for (Index = 0; Index < gUsbData->HcTableCount; Index++) { HcStruc = gUsbData->HcTable[Index]; if (HcStruc == NULL) { continue; } if (HcStruc->HwSmiHandle != NULL) { continue; } if (HcStruc->dHCFlag & HC_STATE_RUNNING) { (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDStop)(HcStruc); USB_DEBUG(DEBUG_LEVEL_3, "."); } } USB_DEBUG(DEBUG_LEVEL_3, "\n"); #endif if(gUsbData->UsbXhciHandoff) { StopControllerType(USB_HC_XHCI); } if(gUsbData->UsbEhciHandoff) { gUsbData->bHandOverInProgress = TRUE; StopControllerType(USB_HC_EHCI); } if(gUsbData->UsbOhciHandoff) { StopControllerType(USB_HC_OHCI); } } // //----------------------------------------------------------------------------- // Procedure: USBAPI_ChangeOwner // // Description: This function is part of the USB BIOS API. This function // updates the global variables according to the new owner // // Input: fpURP Pointer to the URP structure // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // // Notes: It is a caller responsibility to release the keyboard only if it // was previously acquired. // //------------------------------------------------------------------------------; // VOID USBAPI_ChangeOwner(URP_STRUC *fpURP) { //USB_DEBUG(DEBUG_LEVEL_3, "USBAPI_ChangeOwner.."); if(fpURP->ApiData.Owner) { // Changing to Efi driver //USB_DEBUG(DEBUG_LEVEL_3, "fpURP->ApiData.Owner=%d\n", fpURP->ApiData.Owner); if(gEmulationTrap) { gEmulationTrap->TrapDisable(gEmulationTrap); } gUsbData->dUSBStateFlag |= USB_FLAG_RUNNING_UNDER_EFI; } else { // Acquiring - check the current condition first //USB_DEBUG(DEBUG_LEVEL_3, "fpURP->ApiData.Owner=%d...", fpURP->ApiData.Owner); if(gEmulationTrap) { gEmulationTrap->TrapEnable(gEmulationTrap); } if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) { //USB_DEBUG(DEBUG_LEVEL_3, "USB_FLAG_RUNNING_UNDER_EFI\n"); gUsbData->dUSBStateFlag &= ~USB_FLAG_RUNNING_UNDER_EFI; } else { //USB_DEBUG(DEBUG_LEVEL_3, "not USB_FLAG_RUNNING_UNDER_EFI\n"); } } fpURP->bRetValue = USB_SUCCESS; } // //----------------------------------------------------------------------------- // Procedure: USBAPI_HcStartStop // // Description: This function is part of the USB BIOS API. This function // starts/stops the USB host controller. // // Input: fpURP Pointer to the URP structure // // Output: None // // Notes: // //------------------------------------------------------------------------------; // VOID USBAPI_HcStartStop(URP_STRUC *Urp) { HC_STRUC* HcStruc; EFI_STATUS Status; HcStruc = Urp->ApiData.HcStartStop.HcStruc; Status = UsbHcStrucValidation(HcStruc); if (EFI_ERROR(Status)) { return; } if ((HcStruc->bHCType != USB_HC_UHCI) && (HcStruc->bHCType != USB_HC_OHCI) && (HcStruc->bHCType != USB_HC_EHCI) && (HcStruc->bHCType != USB_HC_XHCI)) { return; } gCheckUsbApiParameter = FALSE; if (Urp->ApiData.HcStartStop.Start) { Urp->bRetValue = UsbHcStart(HcStruc); } else { Urp->bRetValue = UsbHcStop(HcStruc); } } // //----------------------------------------------------------------------------- // Procedure: USBAPI_invoke_in_frame // // Description: Invokes procedure passing parameters supplied in the buffer // It replicates the stack frame so that target procedure can // see the parameters passed to the stub. // // Output: Returns result of invoked proc // //------------------------------------------------------------------------------ // // // The following typedef corresponds to the min width type that can be passed // into function call as a parameter without padding // typedef UINTN STACKWORD; UINTN USBAPI_invoke_in_frame( VOID* pProc, VOID* buffer, UINT32 paramSize ) { STACKWORD* params = (STACKWORD*)buffer; switch(paramSize/sizeof(STACKWORD)){ case 0: return ((STACKWORD (*)())pProc)(); case 1: return ((STACKWORD (*)(STACKWORD))pProc)(params[0]); case 2: return ((STACKWORD (*)(STACKWORD,STACKWORD))pProc)(params[0], params[1]); case 3: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD))pProc)( params[0],params[1],params[2]); case 4: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD, STACKWORD))pProc)( params[0],params[1],params[2],params[3]); case 5: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,STACKWORD, STACKWORD))pProc)( params[0],params[1],params[2],params[3],params[4]); case 6: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,STACKWORD, STACKWORD,STACKWORD))pProc)( params[0],params[1],params[2],params[3],params[4],params[5]); case 7: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,STACKWORD, STACKWORD,STACKWORD,STACKWORD))pProc)( params[0],params[1],params[2],params[3],params[4],params[5], params[6]); default: ASSERT(paramSize/sizeof(STACKWORD) < 4); return 0; } /* kept for reference __asm { push ecx push esi pushf //Copy stak frame std mov esi, buffer mov ecx, paramSize add esi, ecx sub esi, 4 shr ecx, 2 loop1: lodsd //DWORD PTR ds:edi push eax loop loop1 //Call proc mov eax, pProc cld call eax //Read return value mov retVal, eax //Restore stack and registers add esp, paramSize popf pop esi pop ecx } return retVal;*/ } // //----------------------------------------------------------------------------- // Procedure: USBAPI_HC_Proc // // Description: Bridge to a number of procedures supplied by HC driver // // // Input: fpURP Pointer to the URP structure // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success) // // Notes: // Assumes that buffer has a correct image of the stack that // corresponding function reads argument from // Size of the buffer can be biger than actually used. // // Following code copies the buffer (some stack frame) into new // stack frame such that invoked dirver proc can read parametes // supplied by buffer //------------------------------------------------------------------------------; // VOID USBAPI_HC_Proc(URP_STRUC *fpURP) { VOID* buffer = fpURP->ApiData.HcProc.paramBuffer; UINT32 paramSize = // align size on DWORD (fpURP->ApiData.HcProc.paramSize + 3) & ~0x3; UN_HCD_HEADER* pHdr; ASSERT( GET_HCD_INDEX(fpURP->ApiData.HcProc.bHCType) < sizeof(gUsbData->aHCDriverTable)/sizeof(HCD_HEADER)); ASSERT( fpURP->bSubFunc < sizeof(pHdr->asArray.proc)/sizeof(VOID*)); pHdr = (UN_HCD_HEADER*)(gUsbData->aHCDriverTable + GET_HCD_INDEX(fpURP->ApiData.HcProc.bHCType)); fpURP->ApiData.HcProc.retVal = USBAPI_invoke_in_frame( pHdr->asArray.proc[fpURP->bSubFunc],buffer,paramSize); fpURP->bRetValue = USB_SUCCESS; } // //----------------------------------------------------------------------------- // Procedure: USBAPI_Core_Proc // // Description: Bridge to a number of procedures supplied by Core proc table // // Input: fpURP Pointer to the URP structure // // Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success // // Notes: // Assumes that buffer has a correct image of the stack that // corresponding function reads argument from // Size of the buffer can be biger than actually used. // // Following code copies the buffer (some stack frame) into new // stack frame such that invoked proc can read parametes // supplied by buffer //------------------------------------------------------------------------------; // VOID* core_proc_table[] = { USB_GetDescriptor, USB_ReConfigDevice, USB_ReConfigDevice2, UsbAllocDevInfo, prepareForLegacyOS, USB_ResetAndReconfigDev, USB_DevDriverDisconnect, // USB_GetDataPtr, // MemCopy, }; VOID USBAPI_Core_Proc(URP_STRUC *fpURP) { VOID* buffer = fpURP->ApiData.CoreProc.paramBuffer; UINT32 paramSize = // align size on DWORD (fpURP->ApiData.CoreProc.paramSize + 3) & ~0x3; ASSERT( fpURP->bSubFunc < COUNTOF(core_proc_table)); fpURP->ApiData.CoreProc.retVal = USBAPI_invoke_in_frame( core_proc_table[fpURP->bSubFunc],buffer,paramSize); fpURP->bRetValue = USB_SUCCESS; } //---------------------------------------------------------------------------- // USB API Procedures Ends //---------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // Procedure: USBWrapGetATAError // // Description: This routine converts the sense data information into // ATAPI error code // // Input: dSenseData Sense data obtained from the device // // Output: BYTE - ATAPI error code // //---------------------------------------------------------------------------- // UINT8 USBWrapGetATAErrorCode (UINT32 dSenseData) { UINT8 sc = (UINT8)dSenseData; // Sense code UINT8 asc = (UINT8)(dSenseData >> 16); // Additional Sense Code (ASC) UINT8 ascq = (UINT8)(dSenseData >> 8); // Additional Sense Code Qualifier (ASCQ) if (ascq == 0x28) return USB_ATA_DRIVE_NOT_READY_ERR; if (sc == 7) return USB_ATA_WRITE_PROTECT_ERR; if ((asc == 0x80) && (ascq == 0x80)) return USB_ATA_TIME_OUT_ERR; if (ascq == 0x18) return USB_ATA_DATA_CORRECTED_ERR; if ((ascq==6) && (asc == 0)) return USB_ATA_MARK_NOT_FOUND_ERR; if ((ascq==0x3a) && (asc == 0)) return USB_ATA_NO_MEDIA_ERR; if ((ascq==0x11) && (asc == 0)) return USB_ATA_READ_ERR; if ((ascq==0x11) && (asc == 6)) return USB_ATA_UNCORRECTABLE_ERR; if (ascq==0x30) return USB_ATA_BAD_SECTOR_ERR; if ((ascq<0x20) || (ascq>0x26)) return USB_ATA_GENERAL_FAILURE; return USB_ATA_PARAMETER_FAILED; } // //---------------------------------------------------------------------------- // Procedure: USBWrap_GetnthDeviceInfoStructure // // Description: This routine finds the 'n'th device's DeviceInfo entry. // // Input: bDevNumber Device number (1-based) // // Output: DeviceInfo structure // //---------------------------------------------------------------------------- // DEV_INFO* USBWrap_GetnthDeviceInfoStructure(UINT8 bDevNumber) { return &gUsbData->aDevInfoTable[bDevNumber]; } // //---------------------------------------------------------------------------- // Procedure: USBWrap_GetDeviceCount // // Description: This routine searches through the device entry table // and returns number of active USB devices configured // by the BIOS. // // Input: fpURPPointer Pointer to the URP // // Output: Following fields in the URP are modified // CkPresence.bNumBootDev Number of USB boot devices found // CkPresence.bNumKeyboards Number of USB keyboards present // CkPresence.bNumMice Number of USB mice present // CkPresence.bNumHubs Number of USB hubs present // CkPresence.bNumStorage Number of USB storage devices present // //---------------------------------------------------------------------------- // VOID USBWrap_GetDeviceCount(URP_STRUC *fpURP) { DEV_INFO *fpDevInfo; UINT8 i; for (i=1; iaDevInfoTable[i]; if ( (fpDevInfo->Flag & DEV_INFO_VALID_STRUC) && (fpDevInfo->Flag & DEV_INFO_DEV_PRESENT)) { fpURP->ApiData.CkPresence.bNumBootDev++; switch (fpDevInfo->bDeviceType) { case BIOS_DEV_TYPE_HID: if (fpDevInfo->HidDevType & HID_DEV_TYPE_KEYBOARD) { fpURP->ApiData.CkPresence.bNumKeyboards++; } if (fpDevInfo->HidDevType & HID_DEV_TYPE_MOUSE) { fpURP->ApiData.CkPresence.bNumMice++; } if (fpDevInfo->HidDevType & HID_DEV_TYPE_POINT) { fpURP->ApiData.CkPresence.bNumPoint++; } break; //<(EIP84455+) case BIOS_DEV_TYPE_HUB: fpURP->ApiData.CkPresence.bNumHubs++; break; case BIOS_DEV_TYPE_STORAGE: fpURP->ApiData.CkPresence.bNumStorage++; break; case BIOS_DEV_TYPE_SECURITY: break; } } } } // //---------------------------------------------------------------------------- // Procedure: MemFill // // Description: This routine fills the given memory range with the given value. // // Input: // fpPtr - Pointer to the memory region to fill. // wSize - Size in bytes of the area to be filled. // Value - Byte value to fill the given range with. // // Output: None // //---------------------------------------------------------------------------- // VOID MemFill ( UINT8* fpPtr, UINT32 dSize, UINT8 Value) { UINT32 dCount; if (fpPtr) { // Check for pointer validity for(dCount = 0; dCount < dSize; dCount++) { fpPtr[dCount] = Value; } } } // //---------------------------------------------------------------------------- // Procedure: MemCopy // // Description: This routine copies data from source to destination. // // Input: // fpSrc - Pointer to the source. // fpDest - Pointer to the destination. // wSize - Number of bytes to copy. // // Output: None // //---------------------------------------------------------------------------- // VOID MemCopy ( UINT8* fpSrc, UINT8* fpDest, UINT32 dSize) { UINT32 dCount; // // Check for pointer validity // if ((fpSrc) && (fpDest)) { for(dCount = 0; dCount < dSize; dCount++) { fpDest[dCount] = fpSrc[dCount]; } } } UINTN DevicePathSize ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *Start; if (DevicePath == NULL) { return 0; } // // Search for the end of the device path structure // Start = DevicePath; while (!EfiIsDevicePathEnd (DevicePath)) { DevicePath = EfiNextDevicePathNode (DevicePath); } // // Compute the size and add back in the size of the end device path structure // return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL); } EFI_DEVICE_PATH_PROTOCOL * AppendDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *Src1, IN EFI_DEVICE_PATH_PROTOCOL *Src2 ) { EFI_STATUS Status; UINTN Size; UINTN Size1; UINTN Size2; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath; // // Allocate space for the combined device path. It only has one end node of // length EFI_DEVICE_PATH_PROTOCOL // Size1 = DevicePathSize (Src1); Size2 = DevicePathSize (Src2); Size = Size1 + Size2; if (Size1 != 0 && Size2 != 0) { Size -= sizeof(EFI_DEVICE_PATH_PROTOCOL); } Status = gBS->AllocatePool (EfiBootServicesData, Size, (VOID **)&NewDevicePath); if (EFI_ERROR(Status)) { return NULL; } gBS->CopyMem (NewDevicePath, Src1, Size1); // // Over write Src1 EndNode and do the copy // if (Size1 != 0) { SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((CHAR8 *)NewDevicePath + (Size1 - sizeof(EFI_DEVICE_PATH_PROTOCOL))); } else { SecondDevicePath = NewDevicePath; } gBS->CopyMem (SecondDevicePath, Src2, Size2); return NewDevicePath; } //**************************************************************************** //**************************************************************************** //** ** //** (C)Copyright 1985-2016, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** //** ** //** Phone (770)-246-8600 ** //** ** //**************************************************************************** //****************************************************************************