\r
#include <Protocol/AtaPassThru.h>\r
#include <Protocol/BlockIo.h>\r
+#include <Protocol/BlockIo2.h>\r
#include <Protocol/DiskInfo.h>\r
#include <Protocol/DevicePath.h>\r
\r
//\r
// The maximum ATA transaction sector count in 48 bit addressing mode. \r
//\r
-#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x10000\r
+//#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x10000\r
+\r
+//\r
+// BugBug: if the TransferLength is equal with 0x10000 (the 48bit max length),\r
+// there is a bug that even the register interrupt bit has been sit, the buffer\r
+// seems not ready. Change the Maximum Sector Numbers to 0xFFFF to work round\r
+// this issue.\r
+//\r
+#define MAX_48BIT_TRANSFER_BLOCK_NUM 0xFFFF\r
\r
//\r
// The maximum model name in ATA identify data \r
//\r
#define MAX_MODEL_NAME_LEN 40\r
\r
+#define ATA_TASK_SIGNATURE SIGNATURE_32 ('A', 'T', 'S', 'K')\r
+#define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D')\r
+\r
+#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)\r
+\r
+//\r
+// Task for the non blocking I/O\r
+//\r
+typedef struct {\r
+ UINT32 Signature;\r
+ EFI_BLOCK_IO2_TOKEN *Token;\r
+ UINTN *UnsignalledEventCount;\r
+ EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;\r
+ BOOLEAN *IsError;// Indicate whether meeting error during source allocation for new task.\r
+ LIST_ENTRY TaskEntry;\r
+} ATA_BUS_ASYN_TASK;\r
\r
//\r
// ATA bus data structure for ATA controller\r
EFI_HANDLE DriverBindingHandle;\r
} ATA_BUS_DRIVER_DATA;\r
\r
-#define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D')\r
-\r
//\r
// ATA device data structure for each child device\r
//\r
typedef struct {\r
- UINT32 Signature;\r
+ UINT32 Signature;\r
\r
- EFI_HANDLE Handle;\r
- EFI_BLOCK_IO_PROTOCOL BlockIo;\r
- EFI_BLOCK_IO_MEDIA BlockMedia;\r
- EFI_DISK_INFO_PROTOCOL DiskInfo;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_HANDLE Handle;\r
+ EFI_BLOCK_IO_PROTOCOL BlockIo;\r
+ EFI_BLOCK_IO2_PROTOCOL BlockIo2;\r
+ EFI_BLOCK_IO_MEDIA BlockMedia;\r
+ EFI_DISK_INFO_PROTOCOL DiskInfo;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
\r
- ATA_BUS_DRIVER_DATA *AtaBusDriverData;\r
- UINT16 Port;\r
- UINT16 PortMultiplierPort;\r
+ ATA_BUS_DRIVER_DATA *AtaBusDriverData;\r
+ UINT16 Port;\r
+ UINT16 PortMultiplierPort;\r
\r
//\r
// Buffer for the execution of ATA pass through protocol\r
//\r
- EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;\r
- EFI_ATA_COMMAND_BLOCK Acb;\r
- EFI_ATA_STATUS_BLOCK *Asb;\r
+ EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;\r
+ EFI_ATA_COMMAND_BLOCK Acb;\r
+ EFI_ATA_STATUS_BLOCK *Asb;\r
\r
- BOOLEAN UdmaValid;\r
- BOOLEAN Lba48Bit;\r
+ BOOLEAN UdmaValid;\r
+ BOOLEAN Lba48Bit;\r
\r
//\r
// Cached data for ATA identify data\r
//\r
- ATA_IDENTIFY_DATA *IdentifyData;\r
+ ATA_IDENTIFY_DATA *IdentifyData;\r
\r
- EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
- CHAR16 ModelName[MAX_MODEL_NAME_LEN + 1];\r
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
+ CHAR16 ModelName[MAX_MODEL_NAME_LEN + 1];\r
\r
+ LIST_ENTRY AtaTaskList;\r
} ATA_DEVICE;\r
\r
-#define ATA_DEVICE_FROM_BLOCK_IO(a) CR (a, ATA_DEVICE, BlockIo, ATA_DEVICE_SIGNATURE)\r
-#define ATA_DEVICE_FROM_DISK_INFO(a) CR (a, ATA_DEVICE, DiskInfo, ATA_DEVICE_SIGNATURE)\r
+#define ATA_DEVICE_FROM_BLOCK_IO(a) CR (a, ATA_DEVICE, BlockIo, ATA_DEVICE_SIGNATURE)\r
+#define ATA_DEVICE_FROM_BLOCK_IO2(a) CR (a, ATA_DEVICE, BlockIo2, ATA_DEVICE_SIGNATURE)\r
+#define ATA_DEVICE_FROM_DISK_INFO(a) CR (a, ATA_DEVICE, DiskInfo, ATA_DEVICE_SIGNATURE)\r
+#define ATA_AYNS_TASK_FROM_ENTRY(a) CR (a, ATA_BUS_ASYN_TASK, TaskEntry, ATA_TASK_SIGNATURE)\r
\r
//\r
// Global Variables\r
extern EFI_COMPONENT_NAME_PROTOCOL gAtaBusComponentName;\r
extern EFI_COMPONENT_NAME2_PROTOCOL gAtaBusComponentName2;\r
\r
+/**\r
+ Allocates an aligned buffer for ATA device.\r
+\r
+ This function allocates an aligned buffer for the ATA device to perform\r
+ ATA pass through operations. The alignment requirement is from ATA pass\r
+ through interface.\r
+\r
+ @param AtaDevice The ATA child device involved for the operation.\r
+ @param BufferSize The request buffer size.\r
+\r
+ @return A pointer to the aligned buffer or NULL if the allocation fails.\r
+\r
+**/\r
+VOID *\r
+AllocateAlignedBuffer (\r
+ IN ATA_DEVICE *AtaDevice,\r
+ IN UINTN BufferSize\r
+ );\r
+\r
+/**\r
+ Frees an aligned buffer for ATA device.\r
+\r
+ This function frees an aligned buffer for the ATA device to perform\r
+ ATA pass through operations.\r
+\r
+ @param Buffer The aligned buffer to be freed.\r
+ @param BufferSize The request buffer size.\r
+\r
+**/\r
+VOID\r
+FreeAlignedBuffer (\r
+ IN VOID *Buffer,\r
+ IN UINTN BufferSize\r
+ );\r
+\r
+/**\r
+ Free SubTask. \r
+\r
+ @param[in, out] Task Pointer to task to be freed.\r
+ \r
+**/\r
+VOID\r
+EFIAPI \r
+FreeAtaSubTask (\r
+ IN ATA_BUS_ASYN_TASK *Task\r
+ );\r
\r
/**\r
Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().\r
IN OUT ATA_DEVICE *AtaDevice\r
);\r
\r
-\r
/**\r
Read or write a number of blocks from ATA device.\r
\r
ATA device. It may separate the read/write request into several ATA pass through\r
transactions.\r
\r
- @param AtaDevice The ATA child device involved for the operation.\r
- @param Buffer The pointer to the current transaction buffer.\r
- @param StartLba The starting logical block address to be accessed.\r
- @param NumberOfBlocks The block number or sector count of the transfer.\r
- @param IsWrite Indicates whether it is a write operation.\r
+ @param[in, out] AtaDevice The ATA child device involved for the operation.\r
+ @param[in, out] Buffer The pointer to the current transaction buffer.\r
+ @param[in] StartLba The starting logical block address to be accessed.\r
+ @param[in] NumberOfBlocks The block number or sector count of the transfer.\r
+ @param[in] IsWrite Indicates whether it is a write operation.\r
+ @param[in, out] Token A pointer to the token associated with the transaction.\r
\r
@retval EFI_SUCCESS The data transfer is complete successfully.\r
@return others Some error occurs when transferring data. \r
IN OUT UINT8 *Buffer,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks,\r
- IN BOOLEAN IsWrite\r
+ IN BOOLEAN IsWrite,\r
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token\r
);\r
\r
//\r
IN EFI_BLOCK_IO_PROTOCOL *This\r
);\r
\r
+/**\r
+ Reset the Block Device throught Block I/O2 protocol.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtaBlockIoResetEx (\r
+ IN EFI_BLOCK_IO2_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ );\r
+\r
+/**\r
+ Read BufferSize bytes from Lba into Buffer.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] MediaId Id of the media, changes every time the media is replaced.\r
+ @param[in] Lba The starting Logical Block Address to read from.\r
+ @param[in, out] Token A pointer to the token associated with the transaction.\r
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block size.\r
+ @param[out] Buffer A pointer to the destination buffer for the data. The caller is\r
+ responsible for either having implicit or explicit ownership of the buffer.\r
+\r
+ @retval EFI_SUCCESS The read request was queued if Event is not NULL.\r
+ The data was read correctly from the device if\r
+ the Event is NULL.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing\r
+ the read.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
+ @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, \r
+ or the buffer is not on proper alignment.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
+ of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtaBlockIoReadBlocksEx (\r
+ IN EFI_BLOCK_IO2_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA Lba,\r
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Write BufferSize bytes from Lba into Buffer.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] MediaId The media ID that the write request is for.\r
+ @param[in] Lba The starting logical block address to be written. The\r
+ caller is responsible for writing to only legitimate\r
+ locations.\r
+ @param[in, out] Token A pointer to the token associated with the transaction.\r
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block size.\r
+ @param[in] Buffer A pointer to the source buffer for the data.\r
+\r
+ @retval EFI_SUCCESS The data was written correctly to the device.\r
+ @retval EFI_WRITE_PROTECTED The device can not be written to.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, \r
+ or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtaBlockIoWriteBlocksEx (\r
+ IN EFI_BLOCK_IO2_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA Lba,\r
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Flush the Block Device.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in, out] Token A pointer to the token associated with the transaction.\r
+\r
+ @retval EFI_SUCCESS All outstanding data was written to the device\r
+ @retval EFI_DEVICE_ERROR The device reported an error while writing back the data\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtaBlockIoFlushBlocksEx (\r
+ IN EFI_BLOCK_IO2_PROTOCOL *This,\r
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token\r
+ );\r
\r
/**\r
Provides inquiry information for the controller type.\r