# ScsiDisk

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **ScsiDiskReadSectors** |  |
|  | **ScsiDiskWriteSectors** |  |
|  | **ScsiDiskReadCapacity** |  |
|  | **ScsiDiskParseCapacityData** |  |
|  | **ModuleEntryPoint** |  |
|  | **ScsiDiskDriverEntry** |  |
|  | **ScsiDiskDriverBindingSupported** |  |
|  | **ScsiDiskDriverBindingStart** |  |
|  | **ScsiDiskDriverBindingStop** |  |
|  | **ScsiDiskReset** |  |
|  | **ScsiDiskReadBlocks** |  |
|  | **ScsiDiskWriteBlocks** |  |
|  | **ScsiDiskFlushBlocks** |  |
|  | **ScsiDiskDiskIoReset** |  |
|  | **ScsiDiskDiskIoRead** |  |
|  | **ScsiDiskDiskIoWrite** |  |
|  | **ScsiDiskDiskIoFlush** |  |
|  | **ScsiDiskDetectMedia** |  |
|  | **ScsiDiskInquiryDevice** |  |
|  | **ScsiDiskTestUnitReady** |  |
|  | **ScsiDiskParseSenseData** |  |
|  | **ScsiDiskRequestSense** |  |
|  | **ScsiDiskIsHostAdapterError** |  |
|  | **ScsiDiskIsTargetError** |  |
|  | **ScsiDiskRetryCommand** |  |
|  | **ScsiDiskUnmap** |  |
|  | **ScsiDiskEraseBlocks** |  |
|  | **ScsiDiskAsyncUnmapNotification** |  |
|  | **ScsiDiskAsyncUnmapTimer** |  |
|  | **ScsiDiskCreateDeviceNode** |  |
|  | **ScsiDiskFreeDeviceMemory** |  |
|  | **ScsiDiskRegisterExitBootServices** |  |
|  | **ScsiDiskExitBootServicesCallback** |  |
|  | **ScsiDiskIsDeviceRemovable** |  |
|  | **ScsiDiskIsNeedEraseBlock** |  |
|  | **ScsiDiskIsEraseBlockProtocolInstalled** |  |
|  | **ScsiDiskComponentNameGetDriverName** |  |
|  | **ScsiDiskComponentNameGetControllerName** |  |
|  | **ScsiDiskExecuteScsiCommand** |  |
|  | **ScsiDiskExecuteTestUnitReady** |  |
|  | **ScsiDiskExecuteRequestSense** |  |
|  | **ScsiDiskExecuteInquiry** |  |
|  | **ScsiDiskExecuteInquiry16** |  |
|  | **ScsiDiskExecuteReadCapacity10** |  |
|  | **ScsiDiskExecuteReadCapacity16** |  |
|  | **ScsiDiskIsListEmpty** |  |
|  | **ScsiDiskInitializeListHead** |  |
|  | **ScsiDiskInsertTailList** |  |
|  | **ScsiDiskRemoveEntryList** |  |
|  | **ScsiDiskSwapBytes16** |  |
|  | **ScsiDiskSwapBytes32** |  |
|  | **ScsiDiskSwapBytes64** |  |
|  | **ScsiDiskReadUnaligned64** |  |
|  | **ScsiDiskGetAlignmentFromMask** |  |
|  | **ScsiDiskIsAlignedPointer** |  |
|  | **ScsiDiskFreePool** |  |
|  | **ScsiDiskSafeFreePoolWithCheck** |  |
| Global | **data (from .data section, 0x88A0-0x8AA0)** |  |
| EFI_HANDLE | **gImageHandle     = NULL;    // 0x8A70** |  |
| 0x8A60 | **EFI_BOOT_SERVICES      *gBS              = NULL;    // 0x8A68** |  |
| 0x8A78 | **//** |  |
| Component | **Name tables (in .data at 0x8A10-0x8A58)** |  |
| STATIC | **EFI_UNICODE_STRING_TABLE  mScsiDiskDriverNameTable[] = {** |  |
| EFI_DRIVER_BINDING_PROTOCOL | **instance (at 0x88C0 in .data)** |  |
| STATIC | **EFI_DRIVER_BINDING_PROTOCOL  gScsiDiskDriverBinding = {** |  |
| EFI_COMPONENT_NAME2_PROTOCOL | **instance (at 0x88E0 in .data)** |  |
| STATIC | **EFI_COMPONENT_NAME2_PROTOCOL  gScsiDiskComponentName2 = {** |  |
| EFI_DRIVER_CONFIGURATION_PROTOCOL | **instance (at 0x8900 in .data)** |  |
| STATIC | **EFI_DRIVER_CONFIGURATION_PROTOCOL  gScsiDiskDriverConfiguration = {** |  |
| GUID | **definitions** |  |
| EFI_GUID | **gEfiScsiIoProtocolGuid              = SCSI_DISK_SCSI_IO_GUID;** |  |
| Forward | **declarations of local helper functions** |  |
| STATIC | **EFI_STATUS** |  |
| Module | **Entry Point** |  |
| EFI_STATUS | **EFIAPI** |  |
| Set | **by _ModuleEntryPoint thunk** |  |
| Driver | **Binding Protocol** |  |
| Allocate | **zero-initialized device structure (0x390 bytes)** |  |
| Device | **= (SCSI_DISK_DEVICE *)gBS->AllocateZeroPool (SCSI_DISK_DEVICE_SIZE);** |  |
| Open | **SCSI I/O protocol on the controller handle** |  |
| Status | **= gBS->OpenProtocol (** |  |
| Retry | **loop for media detection** |  |
| for | **(Retry = 0; Retry < 3; Retry++) {** |  |
| No | **media present** | still create device node, just with no media |
| Set | **up Block I/O protocol function pointers (inlined in structure)** |  |
| Set | **up Disk I/O protocol function pointers (inlined in structure)** |  |
| Fill | **in media descriptor** |  |
| Install | **Block I/O and Disk I/O protocols on the controller handle** |  |
| Status | **= gBS->InstallMultipleProtocolInterfaces (** |  |
| Block | **I/O Protocol** |  |
| Allocate | **intermediate buffer for block-aligned read** |  |
| DataSize | **= ((OffsetInBlock + BufferSize + BlockSize - 1) / BlockSize) * BlockSize;** |  |
| Internal | **SCSI Command Functions** |  |
| READ16 | **(0x88): 16-byte CDB** |  |
| READ10 | **(0x28): 10-byte CDB** |  |
| WRITE16 | **(0x8A): 16-byte CDB** |  |
| WRITE10 | **(0x2A): 10-byte CDB** |  |
| Media | **Detection and Sense Processing** |  |
| EFI_STATUS | **ScsiDiskDetectMedia (** |  |
| Step | **1: TEST UNIT READY** |  |
| Status | **= ScsiDiskTestUnitReady (Device, &RetrySupported, &SenseData, &SenseDataLength);** |  |
| TUR | **failed** | parse sense to determine cause |
| if | **(ScsiDiskParseSenseData (Device, SenseData, SenseDataLength, &Result)) {** |  |
| Step | **2: If media appears present, read capacity** |  |
| if | **(Device->MediaPresentFlag) {** |  |
| Standard | **INQUIRY (36 bytes)** |  |
| DataLength | **= 36;** |  |
| Check | **if VPD pages are supported (byte 3, bit 4)** |  |
| if | **(InquiryData[3] & 0x10) {** |  |
| Request | **VPD page list (page 0x00)** |  |
| VpdLength | **= VPD_MAX_PAGE_LENGTH;** |  |
| Search | **for page 0xB0 (Block Limits / thin provisioning)** |  |
| for | **(Index = 4; Index < VpdLength; Index++) {** |  |
| Read | **VPD page 0xB0** |  |
| VpdLength | **= VPD_BLOCK_LIMITS_LEN;** |  |
| CHECK | **CONDITION** | request sense |
| Status | **= ScsiDiskRequestSense (Device, RetrySupported, SenseData, SenseDataLength);** |  |
| Fixed | **format sense data:** |  |
| byte | **0:  Valid (bit 7) | Response code** |  |
| byte | **2:  Sense key (bits 0-3)** |  |
| byte | **12: ASC** |  |
| byte | **13: ASCQ** |  |
| SenseKey | **= Sense[2] & 0x0F;** |  |
| NOT | **READY + MEDIUM NOT PRESENT = no media** |  |
| if | **(SenseKey == SCSI_SENSE_NOT_READY && Asc == SCSI_ASC_MEDIUM_NOT_PRESENT) {** |  |
| UNIT | **ATTENTION + MEDIUM CHANGED = media change** |  |
| if | **(SenseKey == SCSI_SENSE_UNIT_ATTENTION && Asc == SCSI_ASC_MEDIUM_CHANGED) {** |  |
| UNIT | **ATTENTION + RESET = bus reset detected** |  |
| if | **(SenseKey == SCSI_SENSE_UNIT_ATTENTION && Asc == SCSI_ASC_UNIT_ATTENTION_RESET) {** |  |
| Generic | **error** |  |
| Try | **READ CAPACITY (10) first** |  |
| DataLength | **= 8;** |  |
| Fall | **back to READ CAPACITY (16)** |  |
| DataLength | **= 32;** |  |
| READ | **CAPACITY (16): bytes 0-7 = returned LBA, bytes 8-11 = block size** |  |
| LastBlock | **= ((UINT64)Data[0] << 56) |** |  |
| READ | **CAPACITY (10): bytes 0-3 = returned LBA, bytes 4-7 = block size** |  |
| LastBlock | **= ((UINT32)Data[0] << 24) |** |  |
| Error | **Handling** |  |
| BOOLEAN | **ScsiDiskIsHostAdapterError (** |  |
| EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK | **case 0x02:  // EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_FAIL** |  |
| EFI_EXT_SCSI_STATUS_TARGET_GOOD | **case 0x02:  // EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION** |  |
| UNMAP | **/ Erase Block** |  |
| EFI_STATUS | **ScsiDiskUnmap (** |  |
| Build | **UNMAP parameter list** |  |
| ParamListSize | **= 24;** |  |
| Header | **(8 bytes)** |  |
| Data | **length** |  |
| Block | **descriptor data length** |  |
| Block | **descriptor (16 bytes): LBA + block count** |  |
| Build | **UNMAP CDB (10 bytes)** |  |
| Async | **UNMAP Notification** |  |
| Signal | **completion by signaling the event** |  |
| Process | **pending notifications** |  |
| while | **(!ScsiDiskIsListEmpty (&Device->AsyncUnmapQueue)) {** |  |
| Device | **Node Lifecycle** |  |
| EFI_STATUS | **ScsiDiskCreateDeviceNode (** |  |
| Cancel | **pending async UNMAP notifications** |  |
| Entry | **= Device->AsyncUnmapQueue.ForwardLink;** |  |
| Process | **pending async queue before OS takes over** |  |
| Device | **Capability Checks** |  |
| BOOLEAN | **ScsiDiskIsDeviceRemovable (** |  |
| Check | **removable bit in INQUIRY data byte 1, bit 7** |  |
| return | **(Device->InquiryDataType & 0x80) ? TRUE : FALSE;** |  |
| Component | **Name Protocol** |  |
| SCSI | **Command Execution Helpers** |  |
| EFI_STATUS | **ScsiDiskExecuteScsiCommand (** |  |
| EVPD | **= 1** |  |
| Library | **Import Wrappers (statically linked replacements)** |  |
| UINTN | **ScsiDiskIsListEmpty (** |  |
| Placeholder | **for safe-free logic** |  |

---
*Generated by HR650X BIOS Decompilation Project*