goto RestorePciAttributes;\r
}\r
\r
+ //\r
+ // Allocate DMA communication buffer\r
+ //\r
+ Status = PvScsiAllocateSharedPages (\r
+ Dev,\r
+ EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),\r
+ (VOID **)&Dev->DmaBuf,\r
+ &Dev->DmaBufDmaDesc\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeRings;\r
+ }\r
+\r
//\r
// Populate the exported interface's attributes\r
//\r
\r
return EFI_SUCCESS;\r
\r
+FreeRings:\r
+ //\r
+ // Reset device to stop device usage of the rings.\r
+ // This is required to safely free the rings.\r
+ //\r
+ PvScsiResetAdapter (Dev);\r
+\r
+ PvScsiFreeRings (Dev);\r
+\r
RestorePciAttributes:\r
PvScsiRestorePciAttributes (Dev);\r
\r
)\r
{\r
//\r
- // Reset device to stop device usage of the rings.\r
- // This is required to safely free the rings.\r
+ // Reset device to:\r
+ // - Make device stop processing all requests.\r
+ // - Stop device usage of the rings.\r
+ //\r
+ // This is required to safely free the DMA communication buffer\r
+ // and the rings.\r
//\r
PvScsiResetAdapter (Dev);\r
\r
+ //\r
+ // Free DMA communication buffer\r
+ //\r
+ PvScsiFreeSharedPages (\r
+ Dev,\r
+ EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),\r
+ Dev->DmaBuf,\r
+ &Dev->DmaBufDmaDesc\r
+ );\r
+\r
PvScsiFreeRings (Dev);\r
\r
PvScsiRestorePciAttributes (Dev);\r
PVSCSI_DMA_DESC RingCmpsDmaDesc;\r
} PVSCSI_RING_DESC;\r
\r
+typedef struct {\r
+ //\r
+ // As EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.SenseDataLength is defined\r
+ // as UINT8, defining here SenseData size to MAX_UINT8 will guarantee it\r
+ // cannot overflow when passed to device.\r
+ //\r
+ UINT8 SenseData[MAX_UINT8];\r
+ //\r
+ // This size of the data is arbitrarily chosen.\r
+ // It seems to be sufficient for all I/O requests sent through\r
+ // EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() for common boot scenarios.\r
+ //\r
+ UINT8 Data[0x2000];\r
+} PVSCSI_DMA_BUFFER;\r
+\r
#define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S')\r
\r
typedef struct {\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
UINT64 OriginalPciAttributes;\r
PVSCSI_RING_DESC RingDesc;\r
+ PVSCSI_DMA_BUFFER *DmaBuf;\r
+ PVSCSI_DMA_DESC DmaBufDmaDesc;\r
UINT8 MaxTarget;\r
UINT8 MaxLun;\r
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;\r
#define PVSCSI_FROM_PASS_THRU(PassThruPointer) \\r
CR (PassThruPointer, PVSCSI_DEV, PassThru, PVSCSI_SIG)\r
\r
+#define PVSCSI_DMA_BUF_DEV_ADDR(Dev, MemberName) \\r
+ (Dev->DmaBufDmaDesc.DeviceAddress + OFFSET_OF(PVSCSI_DMA_BUFFER, MemberName))\r
+\r
#endif // __PVSCSI_DXE_H_\r