// Ext SCSI Pass Thru utilities\r
//\r
\r
+/**\r
+ Writes a 32-bit value into BAR0 using MMIO\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PvScsiMmioWrite32 (\r
+ IN CONST PVSCSI_DEV *Dev,\r
+ IN UINT64 Offset,\r
+ IN UINT32 Value\r
+ )\r
+{\r
+ return Dev->PciIo->Mem.Write (\r
+ Dev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ PCI_BAR_IDX0,\r
+ Offset,\r
+ 1, // Count\r
+ &Value\r
+ );\r
+}\r
+\r
+/**\r
+ Writes multiple words of data into BAR0 using MMIO\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PvScsiMmioWrite32Multiple (\r
+ IN CONST PVSCSI_DEV *Dev,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN UINT32 *Words\r
+ )\r
+{\r
+ return Dev->PciIo->Mem.Write (\r
+ Dev->PciIo,\r
+ EfiPciIoWidthFifoUint32,\r
+ PCI_BAR_IDX0,\r
+ Offset,\r
+ Count,\r
+ Words\r
+ );\r
+}\r
+\r
+/**\r
+ Send a PVSCSI command to device.\r
+\r
+ @param[in] Dev The pvscsi host device.\r
+ @param[in] Cmd The command to send to device.\r
+ @param[in] OPTIONAL DescWords An optional command descriptor (If command\r
+ have a descriptor). The descriptor is\r
+ provided as an array of UINT32 words and\r
+ is must be 32-bit aligned.\r
+ @param[in] DescWordsCount The number of words in command descriptor.\r
+ Caller must specify here 0 if DescWords\r
+ is not supplied (It is optional). In that\r
+ case, DescWords is ignored.\r
+\r
+ @return Status codes returned by Dev->PciIo->Mem.Write().\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PvScsiWriteCmdDesc (\r
+ IN CONST PVSCSI_DEV *Dev,\r
+ IN UINT32 Cmd,\r
+ IN UINT32 *DescWords OPTIONAL,\r
+ IN UINTN DescWordsCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (DescWordsCount > PVSCSI_MAX_CMD_DATA_WORDS) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetCommand, Cmd);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (DescWordsCount > 0) {\r
+ return PvScsiMmioWrite32Multiple (\r
+ Dev,\r
+ PvScsiRegOffsetCommandData,\r
+ DescWordsCount,\r
+ DescWords\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+PvScsiResetAdapter (\r
+ IN CONST PVSCSI_DEV *Dev\r
+ )\r
+{\r
+ return PvScsiWriteCmdDesc (Dev, PvScsiCmdAdapterReset, NULL, 0);\r
+}\r
+\r
/**\r
Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and\r
EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized\r
return Status;\r
}\r
\r
+ //\r
+ // Reset adapter\r
+ //\r
+ Status = PvScsiResetAdapter (Dev);\r
+ if (EFI_ERROR (Status)) {\r
+ goto RestorePciAttributes;\r
+ }\r
+\r
//\r
// Populate the exported interface's attributes\r
//\r
Dev->PassThruMode.IoAlign = 0;\r
\r
return EFI_SUCCESS;\r
+\r
+RestorePciAttributes:\r
+ PvScsiRestorePciAttributes (Dev);\r
+\r
+ return Status;\r
}\r
\r
STATIC\r