# HddSmart

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **HddSmartInternalAllocateBuffer** |  |
|  | **HddSmartInternalFreeBuffer** |  |
|  | **LShiftU64** |  |
|  | **ReadUnaligned64** |  |
|  | **CompareHobGuid** |  |
|  | **HddSmartInitHobList** |  |
|  | **HddSmartGetDebugLevel** |  |
|  | **HddSmartDebugPrint** |  |
|  | **HddSmartAssert** |  |
|  | **HddSmartAtaCommand** |  |
|  | **HddSmartBlockIoRead** |  |
|  | **HddSmartHiiCallback** |  |
|  | **HddSmartDriverEntry** |  |
|  | **HddSmartTimerPoll** |  |
|  | **HddSmartNotify** |  |
|  | **HddSmartCheckStatus** |  |
|  | **HddSmartUninstall** |  |
|  | **HddSmartGetDeviceName** |  |
|  | **HddSmartStartController** |  |
|  | **HddSmartOpenController** |  |
|  | **HddSmartReadIdentify** |  |
|  | **HddSmartReadSmartData** |  |
|  | **HddSmartBlockIoReadExt** |  |
|  | **HddSmartBlockIoWriteExt** |  |
|  | **HddSmartDeferredTimer** |  |
|  | **ModuleEntryPoint** |  |
| GUIDs | **referenced by the driver (defined in .rdata / HII package list)** |  |
| extern | **EFI_GUID  gHddSmartFormSetGuid;** |  |
| HII | **Vendor Device Path (used to publish HII forms)** |  |
| typedef | **struct {** |  |
| Internal | **function prototypes (forward declarations)** |  |
| Libc | **/ BaseLib stubs provided by this module** |  |
| Walk | **the HOB list to find the system-table HOB.** |  |
| In | **the DXE phase the HOB list is cached elsewhere.** |  |
| HOB | **/ Protocol cache (sub_2064 family)** |  |
| Scan | **the boot-services table for a HOB-format entry.** |  |
| UINTN | **Index;** |  |
| 0x80000004 | **}** |  |
| Only | **print if the current debug level matches.** |  |
| if | **(gHddSmartInstance == NULL) {** |  |
| No | **instance yet** | attempt to locate the debug protocol directly. |
| Status | **= gBS->LocateProtocol (&gEfiDebugPortProtocolGuid** |  |
| Convert | **%s to %a in the format string (in-place modification).** |  |
| ATA | **Pass-through Helpers** |  |
| ATA | **Pass-through helper (sub_B7C)** |  |
| For | **data-in commands, allocate a bounce buffer and issue the** |  |
| if | **(DataBuffer != NULL && DataSize > 0) {** |  |
| Block | **I/O wrapper (sub_5A4)** |  |
| Calculate | **byte count, aligned to 4KB boundary.** |  |
| Capacity | **= 1 << Device->SpinupTime;   // Approximate capacity** |  |
| Build | **IDENTIFY / READ command.** |  |
| if | **(BlockCount == 1 && Lba == 0) {** |  |
| IDENTIFY | **DEVICE** |  |
| Will | **be resolved from the instance** |  |
| HII | **callback (sub_D44)** |  |
| Initialise | **a local 512-byte IDENTIFY buffer.** |  |
| ZeroMem | **(SerialBuf, sizeof (SerialBuf));** |  |
| Variable | **size for "Setup" variable** |  |
| Refresh | **all drive data: copy IDENTIFY buffer into serial strings.** |  |
| for | **(Index = 0; Index < Instance->DeviceCount; Index++) {** |  |
| Copy | **the 512-byte IDENTIFY buffer into a 128-byte display area.** |  |
| CopyMem | **(SerialBuf, Device->SerialNumber, 40);** |  |
| Check | **return status from device.** |  |
| Status | **= HddSmartCheckStatus (Device, Action, &PredictedFailure);** |  |
| Read | **the "Setup" NVRAM variable to refresh the stored serial numbers.** |  |
| Refresh | **SMART data for all devices.** |  |
| If | **SMART data changed, fire the notification.** |  |
| if | **(!PredictedFailure) {** |  |
| If | **an action variable is set, post a deferred timer event.** |  |
| if | **(Instance->Initialized) {** |  |
| Driver | **entry point (sub_928)** |  |
| Cache | **global pointers.** |  |
| if | **(gST == NULL) {** |  |
| Locate | **the HII Package List protocol on our own image handle.** |  |
| Status | **= gBS->OpenProtocol (** |  |
| Locate | **the HII Database protocol.** |  |
| Status | **= gBS->LocateProtocol (** |  |
| Register | **the HII package list with the database.** |  |
| Status | **= HiiDatabase->NewPackageList (** |  |
| Allocate | **the global instance structure.** |  |
| Status | **= gBS->AllocatePool (** |  |
| Register | **function pointers.** |  |
| Publish | **the HII Config Access protocol.** |  |
| ConfigAccess | **= (EFI_HII_CONFIG_ACCESS_PROTOCOL *)gHddSmartInstance;** |  |
| Install | **the driver binding protocol.** |  |
| Status | **= gBS->InstallMultipleProtocolInterfaces (** |  |
| Register | **a notification for driver binding start.** |  |
| Status | **= gBS->RegisterProtocolNotify (** |  |
| Install | **HII formset package.** |  |
| Status | **= gBS->InstallProtocolInterface (** |  |
| Periodic | **timer callback (sub_758)** |  |
| Enumerate | **all handles that support Block IO.** |  |
| Status | **= gBS->LocateHandleBuffer (** |  |
| Open | **the Block IO protocol on this handle.** |  |
| Try | **to open ATA Pass-Through on this handle.** |  |
| if | **(gHddSmartInstance->AtaPassThru == NULL) {** |  |
| Read | **SMART data into a local buffer and check for failure.** |  |
| ZeroMem | **(SmartBuf, sizeof (SmartBuf));** |  |
| Check | **the first byte for the SMART threshold-exceeded indicator.** |  |
| if | **((SmartBuf[0] & 0x1F) != 0) {** |  |
| Predictive | **failure detected** | fire the notification. |
| HddSmartNotify | **();** |  |
| Clear | **the local buffer for the next iteration.** |  |
| Notification | **helper (sub_21C4)** |  |
| If | **a platform SMI protocol is available, use it to signal the BIOS.** |  |
| if | **(gHddSmartInstance != NULL && gHddSmartInstance->Initialized) {** |  |
| Write | **the SMI trigger value (0x2080002 = SMI port, 0 = data).** |  |
| SmiValue | **= 0x2080002;** |  |
| Protocol | **is available** | send SMI via the ACPI enable register. |
| IoWrite32 | **(0xB2, 0x2080002);** |  |
| Fall | **back: open the platform-specific protocol.** |  |
| Status | **= HddSmartGetDebugLevel ();  // Dummy call to init cache** |  |
| SMART | **data interpretation (sub_1080 / sub_18D0 / sub_1A60)** |  |
| For | **type 1 (IDENTIFY), check the IDENTIFY data words.** |  |
| if | **(CommandType == 1) {** |  |
| Initialise | **a 49-byte descriptor for SCSI pass-through.** |  |
| SMART | **RETURN STATUS** |  |
| Page | **code** |  |
| Page | **control** |  |
| Additional | **page code** |  |
| Issue | **the SCSI pass-through command if available.** |  |
| if | **(Device->SmartCapable == 1) {** |  |
| Would | **call ExtScsiPassThru** |  |
| Check | **if the device supports SMART (word 64 of IDENTIFY data).** |  |
| if | **(Device->SmartCapable) {** |  |
| For | **type 2, issue the SMART READ DATA command.** |  |
| ZeroMem | **(Buffer, sizeof (Buffer));** |  |
| Check | **word 0 (offline data structure revision) for threshold-exceeded.** |  |
| HiiConfigAccess | **protocol callback wrapper (sub_1624)** |  |
| Function | **dispatch / I/O wrapper (sub_16A0)** |  |
| ATA | **SMART feature: READ LOG** |  |
| Driver | **Binding start callback (sub_1714)** |  |
| Build | **a 49-byte SCSI pass-through descriptor for IDENTIFY.** |  |
| ZeroMem | **(Desc, sizeof (Desc));** |  |
| ATA | **feature: IDENTIFY** |  |
| Additional | **page length** |  |
| Issue | **the ATA pass-through command.** |  |
| return | **HddSmartCheckStatus (&Instance->Devices[0], 1, &SmartEnabled);** |  |
| Driver | **Binding open controller (sub_17B4)** |  |
| For | **IDE/legacy or RAID, issue a direct ATA READ SECTORS.** |  |
| return | **HddSmartBlockIoRead (&Instance->Devices[0], 0, 1, *Buffer, NULL);** |  |
| For | **native (AHCI), use the SCSI pass-through descriptor.** |  |
| Timeout | **/ flags** |  |
| Timeout | **high byte** |  |
| ATA | **feature: READ DATA** |  |
| Remaining | **bytes zeroed by ZeroMem above** |  |
| Read | **identify data (sub_18D0)** |  |
| Allocate | **a 512-byte buffer for IDENTIFY data.** |  |
| Status | **= gBS->AllocatePool (EfiBootServicesData, 512, &Buffer);** |  |
| Build | **the SCSI pass-through descriptor.** |  |
| READ | **DATA** |  |
| Extract | **the power-on hours nibble at offset 363 (word 181).** |  |
| Nibble | **= ((UINT8 *)Buffer)[363] >> 4;** |  |
| No | **useful data; compute from word 0.** |  |
| Invalid | **data** | mark as -1. |
| Error | **path.** |  |
| Read | **SMART data (sub_1A70)** |  |
| Check | **whether the flag byte indicates we should use the** |  |
| SCSI | **pass-through or the direct ATA command path.** |  |
| Build | **the 49-byte SCSI pass-through descriptor.** |  |
| SMART | **ENABLE OPERATIONS** |  |
| Issue | **the command via the protocol callback.** |  |
| Status | **= HddSmartCheckStatus (Device, 1, &Predicted);** |  |
| Block | **I/O wrapper (sub_1BFC)** |  |
| return | **HddSmartBlockIoRead (&Instance->Devices[0], 0** |  |
| Issue | **command via the Ext SCSI Pass Thru protocol.** |  |
| if | **(Instance->Devices[0].ControllerType == 1) {** |  |
| Dummy | **read to init** |  |
| Block | **I/O write wrapper (sub_1D34)** |  |
| Deferred | **timer callback (sub_1E70)** |  |
| UEFI | **module entry point** |  |
| UefiBootServicesTableLib | **and UefiRuntimeServicesTableLib** |  |
| initialisation | **(handled by constructor in the library).** |  |
| We | **also initialise our module-level copies.** |  |
| return | **HddSmartDriverEntry (ImageHandle, SystemTable);** |  |
| Utility | **functions** |  |
| Overlapping | **and source precedes destination** | copy backward. |
| Src8 | **+= n;** |  |
| If | **both buffers are large enough and well-spaced, use 64-bit copies.** |  |
| if | **(n >= 8 && ((UINTN)Src8 - (UINTN)Dst8 >= 8 ||** |  |
| Align | **source to 8 bytes if needed.** |  |
| Count | **= (UINTN)Src8 & 7;** |  |
| Align | **both pointers to 8-byte boundary.** |  |
| if | **(!Backward) {** |  |
| Copy | **8 bytes at a time.** |  |
| Count | **= n >> 3;** |  |

---
*Generated by HR650X BIOS Decompilation Project*