]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/LsiScsiDxe/LsiScsi.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / LsiScsiDxe / LsiScsi.c
index 5bca85bd75eb3f9a9d57d713c1725de7464b57d8..1f52b85ed24e27a0af16567756c579c844560fa4 100644 (file)
 \r
 #include <IndustryStandard/LsiScsi.h>\r
 #include <IndustryStandard/Pci.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Protocol/PciIo.h>\r
 #include <Protocol/PciRootBridgeIo.h>\r
+#include <Protocol/ScsiPassThruExt.h>\r
 #include <Uefi/UefiSpec.h>\r
 \r
 #include "LsiScsi.h"\r
 \r
+STATIC\r
+EFI_STATUS\r
+Out8 (\r
+  IN LSI_SCSI_DEV  *Dev,\r
+  IN UINT32        Addr,\r
+  IN UINT8         Data\r
+  )\r
+{\r
+  return Dev->PciIo->Io.Write (\r
+                          Dev->PciIo,\r
+                          EfiPciIoWidthUint8,\r
+                          PCI_BAR_IDX0,\r
+                          Addr,\r
+                          1,\r
+                          &Data\r
+                          );\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+Out32 (\r
+  IN LSI_SCSI_DEV  *Dev,\r
+  IN UINT32        Addr,\r
+  IN UINT32        Data\r
+  )\r
+{\r
+  return Dev->PciIo->Io.Write (\r
+                          Dev->PciIo,\r
+                          EfiPciIoWidthUint32,\r
+                          PCI_BAR_IDX0,\r
+                          Addr,\r
+                          1,\r
+                          &Data\r
+                          );\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+In8 (\r
+  IN  LSI_SCSI_DEV  *Dev,\r
+  IN  UINT32        Addr,\r
+  OUT UINT8         *Data\r
+  )\r
+{\r
+  return Dev->PciIo->Io.Read (\r
+                          Dev->PciIo,\r
+                          EfiPciIoWidthUint8,\r
+                          PCI_BAR_IDX0,\r
+                          Addr,\r
+                          1,\r
+                          Data\r
+                          );\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+In32 (\r
+  IN  LSI_SCSI_DEV  *Dev,\r
+  IN  UINT32        Addr,\r
+  OUT UINT32        *Data\r
+  )\r
+{\r
+  return Dev->PciIo->Io.Read (\r
+                          Dev->PciIo,\r
+                          EfiPciIoWidthUint32,\r
+                          PCI_BAR_IDX0,\r
+                          Addr,\r
+                          1,\r
+                          Data\r
+                          );\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+LsiScsiReset (\r
+  IN LSI_SCSI_DEV  *Dev\r
+  )\r
+{\r
+  return Out8 (Dev, LSI_REG_ISTAT0, LSI_ISTAT0_SRST);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReportHostAdapterOverrunError (\r
+  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet\r
+  )\r
+{\r
+  Packet->SenseDataLength   = 0;\r
+  Packet->HostAdapterStatus =\r
+    EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;\r
+  Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;\r
+  return EFI_BAD_BUFFER_SIZE;\r
+}\r
+\r
+/**\r
+\r
+  Check the request packet from the Extended SCSI Pass Thru Protocol. The\r
+  request packet is modified, to be forwarded outwards by LsiScsiPassThru(),\r
+  if invalid or unsupported parameters are detected.\r
+\r
+  @param[in] Dev          The LSI 53C895A SCSI device the packet targets.\r
+\r
+  @param[in] Target       The SCSI target controlled by the LSI 53C895A SCSI\r
+                          device.\r
+\r
+  @param[in] Lun          The Logical Unit Number under the SCSI target.\r
+\r
+  @param[in out] Packet   The Extended SCSI Pass Thru Protocol packet.\r
+\r
+\r
+  @retval EFI_SUCCESS  The Extended SCSI Pass Thru Protocol packet was valid.\r
+\r
+  @return              Otherwise, invalid or unsupported parameters were\r
+                       detected. Status codes are meant for direct forwarding\r
+                       by the EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru()\r
+                       implementation.\r
+\r
+ **/\r
+STATIC\r
+EFI_STATUS\r
+LsiScsiCheckRequest (\r
+  IN LSI_SCSI_DEV                                    *Dev,\r
+  IN UINT8                                           Target,\r
+  IN UINT64                                          Lun,\r
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet\r
+  )\r
+{\r
+  if ((Target > Dev->MaxTarget) || (Lun > Dev->MaxLun) ||\r
+      (Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||\r
+      //\r
+      // Trying to receive, but destination pointer is NULL, or contradicting\r
+      // transfer direction\r
+      //\r
+      ((Packet->InTransferLength > 0) &&\r
+       ((Packet->InDataBuffer == NULL) ||\r
+        (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE)\r
+       )\r
+      ) ||\r
+\r
+      //\r
+      // Trying to send, but source pointer is NULL, or contradicting transfer\r
+      // direction\r
+      //\r
+      ((Packet->OutTransferLength > 0) &&\r
+       ((Packet->OutDataBuffer == NULL) ||\r
+        (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ)\r
+       )\r
+      )\r
+      )\r
+  {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||\r
+      ((Packet->InTransferLength > 0) && (Packet->OutTransferLength > 0)) ||\r
+      (Packet->CdbLength > sizeof Dev->Dma->Cdb))\r
+  {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (Packet->InTransferLength > sizeof Dev->Dma->Data) {\r
+    Packet->InTransferLength = sizeof Dev->Dma->Data;\r
+    return ReportHostAdapterOverrunError (Packet);\r
+  }\r
+\r
+  if (Packet->OutTransferLength > sizeof Dev->Dma->Data) {\r
+    Packet->OutTransferLength = sizeof Dev->Dma->Data;\r
+    return ReportHostAdapterOverrunError (Packet);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Interpret the request packet from the Extended SCSI Pass Thru Protocol and\r
+  compose the script to submit the command and data to the controller.\r
+\r
+  @param[in] Dev          The LSI 53C895A SCSI device the packet targets.\r
+\r
+  @param[in] Target       The SCSI target controlled by the LSI 53C895A SCSI\r
+                          device.\r
+\r
+  @param[in] Lun          The Logical Unit Number under the SCSI target.\r
+\r
+  @param[in out] Packet   The Extended SCSI Pass Thru Protocol packet.\r
+\r
+\r
+  @retval EFI_SUCCESS  The Extended SCSI Pass Thru Protocol packet was valid.\r
+\r
+  @return              Otherwise, invalid or unsupported parameters were\r
+                       detected. Status codes are meant for direct forwarding\r
+                       by the EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru()\r
+                       implementation.\r
+\r
+ **/\r
+STATIC\r
+EFI_STATUS\r
+LsiScsiProcessRequest (\r
+  IN LSI_SCSI_DEV                                    *Dev,\r
+  IN UINT8                                           Target,\r
+  IN UINT64                                          Lun,\r
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      *Script;\r
+  UINT8       *Cdb;\r
+  UINT8       *MsgOut;\r
+  UINT8       *MsgIn;\r
+  UINT8       *ScsiStatus;\r
+  UINT8       *Data;\r
+  UINT8       DStat;\r
+  UINT8       SIst0;\r
+  UINT8       SIst1;\r
+  UINT32      Csbc;\r
+  UINT32      CsbcBase;\r
+  UINT32      Transferred;\r
+\r
+  Script     = Dev->Dma->Script;\r
+  Cdb        = Dev->Dma->Cdb;\r
+  Data       = Dev->Dma->Data;\r
+  MsgIn      = Dev->Dma->MsgIn;\r
+  MsgOut     = &Dev->Dma->MsgOut;\r
+  ScsiStatus = &Dev->Dma->Status;\r
+\r
+  *ScsiStatus = 0xFF;\r
+\r
+  DStat = 0;\r
+  SIst0 = 0;\r
+  SIst1 = 0;\r
+\r
+  SetMem (Cdb, sizeof Dev->Dma->Cdb, 0x00);\r
+  CopyMem (Cdb, Packet->Cdb, Packet->CdbLength);\r
+\r
+  //\r
+  // Fetch the first Cumulative SCSI Byte Count (CSBC).\r
+  //\r
+  // CSBC is a cumulative counter of the actual number of bytes that have been\r
+  // transferred across the SCSI bus during data phases, i.e. it will not\r
+  // count bytes sent in command, status, message in and out phases.\r
+  //\r
+  Status = In32 (Dev, LSI_REG_CSBC, &CsbcBase);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Clean up the DMA buffer for the script.\r
+  //\r
+  SetMem (Script, sizeof Dev->Dma->Script, 0x00);\r
+\r
+  //\r
+  // Compose the script to transfer data between the host and the device.\r
+  //\r
+  // References:\r
+  //   * LSI53C895A PCI to Ultra2 SCSI Controller Version 2.2\r
+  //     - Chapter 5 SCSI SCRIPT Instruction Set\r
+  //   * SEABIOS lsi-scsi driver\r
+  //\r
+  // All instructions used here consist of 2 32bit words. The first word\r
+  // contains the command to execute. The second word is loaded into the\r
+  // DMA SCRIPTS Pointer Save (DSPS) register as either the DMA address\r
+  // for data transmission or the address/offset for the jump command.\r
+  // Some commands, such as the selection of the target, don't need to\r
+  // transfer data through DMA or jump to another instruction, then DSPS\r
+  // has to be zero.\r
+  //\r
+  // There are 3 major parts in this script. The first part (1~3) contains\r
+  // the instructions to select target and LUN and send the SCSI command\r
+  // from the request packet. The second part (4~7) is to handle the\r
+  // potential disconnection and prepare for the data transmission. The\r
+  // instructions in the third part (8~10) transmit the given data and\r
+  // collect the result. Instruction 11 raises the interrupt and marks the\r
+  // end of the script.\r
+  //\r
+\r
+  //\r
+  // 1. Select target.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_IO | LSI_INS_IO_OPC_SEL | (UINT32)Target << 16;\r
+  *Script++ = 0x00000000;\r
+\r
+  //\r
+  // 2. Select LUN.\r
+  //\r
+  *MsgOut   = 0x80 | (UINT8)Lun;  // 0x80: Identify bit\r
+  *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_OUT |\r
+              (UINT32)sizeof Dev->Dma->MsgOut;\r
+  *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgOut);\r
+\r
+  //\r
+  // 3. Send the SCSI Command.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_CMD |\r
+              (UINT32)sizeof Dev->Dma->Cdb;\r
+  *Script++ = LSI_SCSI_DMA_ADDR (Dev, Cdb);\r
+\r
+  //\r
+  // 4. Check whether the current SCSI phase is "Message In" or not\r
+  //    and jump to 7 if it is.\r
+  //    Note: LSI_INS_TC_RA stands for "Relative Address Mode", so the\r
+  //          offset 0x18 in the second word means jumping forward\r
+  //          3 (0x18/8) instructions.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_TC | LSI_INS_TC_OPC_JMP |\r
+              LSI_INS_TC_SCSIP_MSG_IN | LSI_INS_TC_RA |\r
+              LSI_INS_TC_CP;\r
+  *Script++ = 0x00000018;\r
+\r
+  //\r
+  // 5. Read "Message" from the initiator to trigger reselect.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_IN |\r
+              (UINT32)sizeof Dev->Dma->MsgIn;\r
+  *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgIn);\r
+\r
+  //\r
+  // 6. Wait reselect.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_IO | LSI_INS_IO_OPC_WAIT_RESEL;\r
+  *Script++ = 0x00000000;\r
+\r
+  //\r
+  // 7. Read "Message" from the initiator again\r
+  //\r
+  *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_IN |\r
+              (UINT32)sizeof Dev->Dma->MsgIn;\r
+  *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgIn);\r
+\r
+  //\r
+  // 8. Set the DMA command for the read/write operations.\r
+  //    Note: Some requests, e.g. "TEST UNIT READY", do not come with\r
+  //          allocated InDataBuffer or OutDataBuffer. We skip the DMA\r
+  //          data command for those requests or this script would fail\r
+  //          with LSI_SIST0_SGE due to the zero data length.\r
+  //\r
+  // LsiScsiCheckRequest() prevents both integer overflows in the command\r
+  // opcodes, and buffer overflows.\r
+  //\r
+  if (Packet->InTransferLength > 0) {\r
+    ASSERT (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ);\r
+    ASSERT (Packet->InTransferLength <= sizeof Dev->Dma->Data);\r
+    *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_DAT_IN |\r
+                Packet->InTransferLength;\r
+    *Script++ = LSI_SCSI_DMA_ADDR (Dev, Data);\r
+  } else if (Packet->OutTransferLength > 0) {\r
+    ASSERT (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE);\r
+    ASSERT (Packet->OutTransferLength <= sizeof Dev->Dma->Data);\r
+    CopyMem (Data, Packet->OutDataBuffer, Packet->OutTransferLength);\r
+    *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_DAT_OUT |\r
+                Packet->OutTransferLength;\r
+    *Script++ = LSI_SCSI_DMA_ADDR (Dev, Data);\r
+  }\r
+\r
+  //\r
+  // 9. Get the SCSI status.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_STAT |\r
+              (UINT32)sizeof Dev->Dma->Status;\r
+  *Script++ = LSI_SCSI_DMA_ADDR (Dev, Status);\r
+\r
+  //\r
+  // 10. Get the SCSI message.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_IN |\r
+              (UINT32)sizeof Dev->Dma->MsgIn;\r
+  *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgIn);\r
+\r
+  //\r
+  // 11. Raise the interrupt to end the script.\r
+  //\r
+  *Script++ = LSI_INS_TYPE_TC | LSI_INS_TC_OPC_INT |\r
+              LSI_INS_TC_SCSIP_DAT_OUT | LSI_INS_TC_JMP;\r
+  *Script++ = 0x00000000;\r
+\r
+  //\r
+  // Make sure the size of the script doesn't exceed the buffer.\r
+  //\r
+  ASSERT (Script <= Dev->Dma->Script + ARRAY_SIZE (Dev->Dma->Script));\r
+\r
+  //\r
+  // The controller starts to execute the script once the DMA Script\r
+  // Pointer (DSP) register is set.\r
+  //\r
+  Status = Out32 (Dev, LSI_REG_DSP, LSI_SCSI_DMA_ADDR (Dev, Script));\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Poll the device registers (DSTAT, SIST0, and SIST1) until the SIR\r
+  // bit sets.\r
+  //\r
+  for ( ; ;) {\r
+    Status = In8 (Dev, LSI_REG_DSTAT, &DStat);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+\r
+    Status = In8 (Dev, LSI_REG_SIST0, &SIst0);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+\r
+    Status = In8 (Dev, LSI_REG_SIST1, &SIst1);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+\r
+    if ((SIst0 != 0) || (SIst1 != 0)) {\r
+      goto Error;\r
+    }\r
+\r
+    //\r
+    // Check the SIR (SCRIPTS Interrupt Instruction Received) bit.\r
+    //\r
+    if (DStat & LSI_DSTAT_SIR) {\r
+      break;\r
+    }\r
+\r
+    gBS->Stall (Dev->StallPerPollUsec);\r
+  }\r
+\r
+  //\r
+  // Check if everything is good.\r
+  //   SCSI Message Code 0x00: COMMAND COMPLETE\r
+  //   SCSI Status  Code 0x00: Good\r
+  //\r
+  if ((MsgIn[0] != 0) || (*ScsiStatus != 0)) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Fetch CSBC again to calculate the transferred bytes and update\r
+  // InTransferLength/OutTransferLength.\r
+  //\r
+  // Note: The number of transferred bytes is bounded by\r
+  //       "sizeof Dev->Dma->Data", so it's safe to subtract CsbcBase\r
+  //       from Csbc. If the CSBC register wraps around, the correct\r
+  //       difference is ensured by the standard C modular arithmetic.\r
+  //\r
+  Status = In32 (Dev, LSI_REG_CSBC, &Csbc);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  Transferred = Csbc - CsbcBase;\r
+  if (Packet->InTransferLength > 0) {\r
+    if (Transferred <= Packet->InTransferLength) {\r
+      Packet->InTransferLength = Transferred;\r
+    } else {\r
+      goto Error;\r
+    }\r
+  } else if (Packet->OutTransferLength > 0) {\r
+    if (Transferred <= Packet->OutTransferLength) {\r
+      Packet->OutTransferLength = Transferred;\r
+    } else {\r
+      goto Error;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Copy Data to InDataBuffer if necessary.\r
+  //\r
+  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {\r
+    CopyMem (Packet->InDataBuffer, Data, Packet->InTransferLength);\r
+  }\r
+\r
+  //\r
+  // Always set SenseDataLength to 0.\r
+  // The instructions of LSI53C895A don't reply sense data. Instead, it\r
+  // relies on the SCSI command, "REQUEST SENSE", to get sense data. We set\r
+  // SenseDataLength to 0 to notify ScsiDiskDxe that there is no sense data\r
+  // written even if this request is processed successfully, so that It will\r
+  // issue "REQUEST SENSE" later to retrieve sense data.\r
+  //\r
+  Packet->SenseDataLength   = 0;\r
+  Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;\r
+  Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;\r
+\r
+  return EFI_SUCCESS;\r
+\r
+Error:\r
+  DEBUG ((\r
+    DEBUG_VERBOSE,\r
+    "%a: dstat: %02X, sist0: %02X, sist1: %02X\n",\r
+    __FUNCTION__,\r
+    DStat,\r
+    SIst0,\r
+    SIst1\r
+    ));\r
+  //\r
+  // Update the request packet to reflect the status.\r
+  //\r
+  if (*ScsiStatus != 0xFF) {\r
+    Packet->TargetStatus = *ScsiStatus;\r
+  } else {\r
+    Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED;\r
+  }\r
+\r
+  if (SIst0 & LSI_SIST0_PAR) {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR;\r
+  } else if (SIst0 & LSI_SIST0_RST) {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET;\r
+  } else if (SIst0 & LSI_SIST0_UDC) {\r
+    //\r
+    // The target device is disconnected unexpectedly. According to UEFI spec,\r
+    // this is TIMEOUT_COMMAND.\r
+    //\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND;\r
+  } else if (SIst0 & LSI_SIST0_SGE) {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;\r
+  } else if (SIst1 & LSI_SIST1_HTH) {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT;\r
+  } else if (SIst1 & LSI_SIST1_GEN) {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT;\r
+  } else if (SIst1 & LSI_SIST1_STO) {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT;\r
+  } else {\r
+    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;\r
+  }\r
+\r
+  //\r
+  // SenseData may be used to inspect the error. Since we don't set sense data,\r
+  // SenseDataLength has to be 0.\r
+  //\r
+  Packet->SenseDataLength = 0;\r
+\r
+  return EFI_DEVICE_ERROR;\r
+}\r
+\r
+//\r
+// The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL\r
+// for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C,\r
+// sections\r
+// - 14.1 SCSI Driver Model Overview,\r
+// - 14.7 Extended SCSI Pass Thru Protocol.\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiPassThru (\r
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                 *This,\r
+  IN UINT8                                           *Target,\r
+  IN UINT64                                          Lun,\r
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,\r
+  IN EFI_EVENT                                       Event     OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  LSI_SCSI_DEV  *Dev;\r
+\r
+  Dev    = LSI_SCSI_FROM_PASS_THRU (This);\r
+  Status = LsiScsiCheckRequest (Dev, *Target, Lun, Packet);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LsiScsiProcessRequest (Dev, *Target, Lun, Packet);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiGetNextTargetLun (\r
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,\r
+  IN OUT UINT8                        **TargetPointer,\r
+  IN OUT UINT64                       *Lun\r
+  )\r
+{\r
+  LSI_SCSI_DEV  *Dev;\r
+  UINTN         Idx;\r
+  UINT8         *Target;\r
+  UINT16        LastTarget;\r
+\r
+  //\r
+  // the TargetPointer input parameter is unnecessarily a pointer-to-pointer\r
+  //\r
+  Target = *TargetPointer;\r
+\r
+  //\r
+  // Search for first non-0xFF byte. If not found, return first target & LUN.\r
+  //\r
+  for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx) {\r
+  }\r
+\r
+  if (Idx == TARGET_MAX_BYTES) {\r
+    SetMem (Target, TARGET_MAX_BYTES, 0x00);\r
+    *Lun = 0;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  CopyMem (&LastTarget, Target, sizeof LastTarget);\r
+\r
+  //\r
+  // increment (target, LUN) pair if valid on input\r
+  //\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if ((LastTarget > Dev->MaxTarget) || (*Lun > Dev->MaxLun)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (*Lun < Dev->MaxLun) {\r
+    ++*Lun;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (LastTarget < Dev->MaxTarget) {\r
+    *Lun = 0;\r
+    ++LastTarget;\r
+    CopyMem (Target, &LastTarget, sizeof LastTarget);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiBuildDevicePath (\r
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,\r
+  IN UINT8                            *Target,\r
+  IN UINT64                           Lun,\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **DevicePath\r
+  )\r
+{\r
+  UINT16            TargetValue;\r
+  LSI_SCSI_DEV      *Dev;\r
+  SCSI_DEVICE_PATH  *ScsiDevicePath;\r
+\r
+  if (DevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CopyMem (&TargetValue, Target, sizeof TargetValue);\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if ((TargetValue > Dev->MaxTarget) || (Lun > Dev->MaxLun) || (Lun > 0xFFFF)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  ScsiDevicePath = AllocatePool (sizeof *ScsiDevicePath);\r
+  if (ScsiDevicePath == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  ScsiDevicePath->Header.Type      = MESSAGING_DEVICE_PATH;\r
+  ScsiDevicePath->Header.SubType   = MSG_SCSI_DP;\r
+  ScsiDevicePath->Header.Length[0] = (UINT8)sizeof *ScsiDevicePath;\r
+  ScsiDevicePath->Header.Length[1] = (UINT8)(sizeof *ScsiDevicePath >> 8);\r
+  ScsiDevicePath->Pun              = TargetValue;\r
+  ScsiDevicePath->Lun              = (UINT16)Lun;\r
+\r
+  *DevicePath = &ScsiDevicePath->Header;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiGetTargetLun (\r
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL         *DevicePath,\r
+  OUT UINT8                            **TargetPointer,\r
+  OUT UINT64                           *Lun\r
+  )\r
+{\r
+  SCSI_DEVICE_PATH  *ScsiDevicePath;\r
+  LSI_SCSI_DEV      *Dev;\r
+  UINT8             *Target;\r
+\r
+  if ((DevicePath == NULL) || (TargetPointer == NULL) || (*TargetPointer == NULL) ||\r
+      (Lun == NULL))\r
+  {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((DevicePath->Type    != MESSAGING_DEVICE_PATH) ||\r
+      (DevicePath->SubType != MSG_SCSI_DP))\r
+  {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath;\r
+  Dev            = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if ((ScsiDevicePath->Pun > Dev->MaxTarget) ||\r
+      (ScsiDevicePath->Lun > Dev->MaxLun))\r
+  {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Target = *TargetPointer;\r
+  ZeroMem (Target, TARGET_MAX_BYTES);\r
+  CopyMem (Target, &ScsiDevicePath->Pun, sizeof ScsiDevicePath->Pun);\r
+  *Lun = ScsiDevicePath->Lun;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiResetChannel (\r
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiResetTargetLun (\r
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,\r
+  IN UINT8                            *Target,\r
+  IN UINT64                           Lun\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LsiScsiGetNextTarget (\r
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,\r
+  IN OUT UINT8                        **TargetPointer\r
+  )\r
+{\r
+  LSI_SCSI_DEV  *Dev;\r
+  UINTN         Idx;\r
+  UINT8         *Target;\r
+  UINT16        LastTarget;\r
+\r
+  //\r
+  // the TargetPointer input parameter is unnecessarily a pointer-to-pointer\r
+  //\r
+  Target = *TargetPointer;\r
+\r
+  //\r
+  // Search for first non-0xFF byte. If not found, return first target.\r
+  //\r
+  for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx) {\r
+  }\r
+\r
+  if (Idx == TARGET_MAX_BYTES) {\r
+    SetMem (Target, TARGET_MAX_BYTES, 0x00);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  CopyMem (&LastTarget, Target, sizeof LastTarget);\r
+\r
+  //\r
+  // increment target if valid on input\r
+  //\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if (LastTarget > Dev->MaxTarget) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (LastTarget < Dev->MaxTarget) {\r
+    ++LastTarget;\r
+    CopyMem (Target, &LastTarget, sizeof LastTarget);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+LsiScsiExitBoot (\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
+  )\r
+{\r
+  LSI_SCSI_DEV  *Dev;\r
+\r
+  Dev = Context;\r
+  DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));\r
+  LsiScsiReset (Dev);\r
+}\r
+\r
 //\r
 // Probe, start and stop functions of this driver, called by the DXE core for\r
 // specific devices.\r
 EFI_STATUS\r
 EFIAPI\r
 LsiScsiControllerSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
-  IN EFI_HANDLE                  ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath OPTIONAL\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  PCI_TYPE00          Pci;\r
+  EFI_STATUS           Status;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  PCI_TYPE00           Pci;\r
 \r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
@@ -63,8 +848,9 @@ LsiScsiControllerSupported (
     goto Done;\r
   }\r
 \r
-  if (Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID &&\r
-      Pci.Hdr.DeviceId == LSI_53C895A_PCI_DEVICE_ID) {\r
+  if ((Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID) &&\r
+      (Pci.Hdr.DeviceId == LSI_53C895A_PCI_DEVICE_ID))\r
+  {\r
     Status = EFI_SUCCESS;\r
   } else {\r
     Status = EFI_UNSUPPORTED;\r
@@ -83,24 +869,259 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 LsiScsiControllerStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
-  IN EFI_HANDLE                  ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath OPTIONAL\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
   )\r
 {\r
+  EFI_STATUS    Status;\r
+  LSI_SCSI_DEV  *Dev;\r
+  UINTN         Pages;\r
+  UINTN         BytesMapped;\r
+\r
+  Dev = AllocateZeroPool (sizeof (*Dev));\r
+  if (Dev == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Dev->Signature = LSI_SCSI_DEV_SIGNATURE;\r
+\r
+  STATIC_ASSERT (\r
+    FixedPcdGet8 (PcdLsiScsiMaxTargetLimit) < 8,\r
+    "LSI 53C895A supports targets [0..7]"\r
+    );\r
+  STATIC_ASSERT (\r
+    FixedPcdGet8 (PcdLsiScsiMaxLunLimit) < 128,\r
+    "LSI 53C895A supports LUNs [0..127]"\r
+    );\r
+  Dev->MaxTarget        = PcdGet8 (PcdLsiScsiMaxTargetLimit);\r
+  Dev->MaxLun           = PcdGet8 (PcdLsiScsiMaxLunLimit);\r
+  Dev->StallPerPollUsec = PcdGet32 (PcdLsiScsiStallPerPollUsec);\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **)&Dev->PciIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreePool;\r
+  }\r
+\r
+  Status = Dev->PciIo->Attributes (\r
+                         Dev->PciIo,\r
+                         EfiPciIoAttributeOperationGet,\r
+                         0,\r
+                         &Dev->OrigPciAttrs\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    goto CloseProtocol;\r
+  }\r
+\r
+  //\r
+  // Enable I/O Space & Bus-Mastering\r
+  //\r
+  Status = Dev->PciIo->Attributes (\r
+                         Dev->PciIo,\r
+                         EfiPciIoAttributeOperationEnable,\r
+                         (EFI_PCI_IO_ATTRIBUTE_IO |\r
+                          EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),\r
+                         NULL\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    goto CloseProtocol;\r
+  }\r
+\r
+  //\r
+  // Create buffers for data transfer\r
+  //\r
+  Pages  = EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma));\r
+  Status = Dev->PciIo->AllocateBuffer (\r
+                         Dev->PciIo,\r
+                         AllocateAnyPages,\r
+                         EfiBootServicesData,\r
+                         Pages,\r
+                         (VOID **)&Dev->Dma,\r
+                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    goto RestoreAttributes;\r
+  }\r
+\r
+  BytesMapped = EFI_PAGES_TO_SIZE (Pages);\r
+  Status      = Dev->PciIo->Map (\r
+                              Dev->PciIo,\r
+                              EfiPciIoOperationBusMasterCommonBuffer,\r
+                              Dev->Dma,\r
+                              &BytesMapped,\r
+                              &Dev->DmaPhysical,\r
+                              &Dev->DmaMapping\r
+                              );\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeBuffer;\r
+  }\r
+\r
+  if (BytesMapped != EFI_PAGES_TO_SIZE (Pages)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Unmap;\r
+  }\r
+\r
+  Status = LsiScsiReset (Dev);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Unmap;\r
+  }\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                  TPL_CALLBACK,\r
+                  &LsiScsiExitBoot,\r
+                  Dev,\r
+                  &Dev->ExitBoot\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UninitDev;\r
+  }\r
+\r
+  //\r
+  // Host adapter channel, doesn't exist\r
+  //\r
+  Dev->PassThruMode.AdapterId  = MAX_UINT32;\r
+  Dev->PassThruMode.Attributes =\r
+    EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |\r
+    EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
+\r
+  Dev->PassThru.Mode             = &Dev->PassThruMode;\r
+  Dev->PassThru.PassThru         = &LsiScsiPassThru;\r
+  Dev->PassThru.GetNextTargetLun = &LsiScsiGetNextTargetLun;\r
+  Dev->PassThru.BuildDevicePath  = &LsiScsiBuildDevicePath;\r
+  Dev->PassThru.GetTargetLun     = &LsiScsiGetTargetLun;\r
+  Dev->PassThru.ResetChannel     = &LsiScsiResetChannel;\r
+  Dev->PassThru.ResetTargetLun   = &LsiScsiResetTargetLun;\r
+  Dev->PassThru.GetNextTarget    = &LsiScsiGetNextTarget;\r
+\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &ControllerHandle,\r
+                  &gEfiExtScsiPassThruProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &Dev->PassThru\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto CloseExitBoot;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
+\r
+CloseExitBoot:\r
+  gBS->CloseEvent (Dev->ExitBoot);\r
+\r
+UninitDev:\r
+  LsiScsiReset (Dev);\r
+\r
+Unmap:\r
+  Dev->PciIo->Unmap (\r
+                Dev->PciIo,\r
+                Dev->DmaMapping\r
+                );\r
+\r
+FreeBuffer:\r
+  Dev->PciIo->FreeBuffer (\r
+                Dev->PciIo,\r
+                Pages,\r
+                Dev->Dma\r
+                );\r
+\r
+RestoreAttributes:\r
+  Dev->PciIo->Attributes (\r
+                Dev->PciIo,\r
+                EfiPciIoAttributeOperationSet,\r
+                Dev->OrigPciAttrs,\r
+                NULL\r
+                );\r
+\r
+CloseProtocol:\r
+  gBS->CloseProtocol (\r
+         ControllerHandle,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         ControllerHandle\r
+         );\r
+\r
+FreePool:\r
+  FreePool (Dev);\r
+\r
+  return Status;\r
 }\r
 \r
 EFI_STATUS\r
 EFIAPI\r
 LsiScsiControllerStop (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
-  IN EFI_HANDLE                  ControllerHandle,\r
-  IN UINTN                       NumberOfChildren,\r
-  IN EFI_HANDLE                  *ChildHandleBuffer\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN UINTN                        NumberOfChildren,\r
+  IN EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
-  return EFI_SUCCESS;\r
+  EFI_STATUS                       Status;\r
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *PassThru;\r
+  LSI_SCSI_DEV                     *Dev;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiExtScsiPassThruProtocolGuid,\r
+                  (VOID **)&PassThru,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL // Lookup only\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (PassThru);\r
+\r
+  Status = gBS->UninstallProtocolInterface (\r
+                  ControllerHandle,\r
+                  &gEfiExtScsiPassThruProtocolGuid,\r
+                  &Dev->PassThru\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  gBS->CloseEvent (Dev->ExitBoot);\r
+\r
+  LsiScsiReset (Dev);\r
+\r
+  Dev->PciIo->Unmap (\r
+                Dev->PciIo,\r
+                Dev->DmaMapping\r
+                );\r
+\r
+  Dev->PciIo->FreeBuffer (\r
+                Dev->PciIo,\r
+                EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)),\r
+                Dev->Dma\r
+                );\r
+\r
+  Dev->PciIo->Attributes (\r
+                Dev->PciIo,\r
+                EfiPciIoAttributeOperationSet,\r
+                Dev->OrigPciAttrs,\r
+                NULL\r
+                );\r
+\r
+  gBS->CloseProtocol (\r
+         ControllerHandle,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         ControllerHandle\r
+         );\r
+\r
+  FreePool (Dev);\r
+\r
+  return Status;\r
 }\r
 \r
 //\r
@@ -109,7 +1130,7 @@ LsiScsiControllerStop (
 // C, 10.1 EFI Driver Binding Protocol.\r
 //\r
 STATIC\r
-EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
+EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {\r
   &LsiScsiControllerSupported,\r
   &LsiScsiControllerStart,\r
   &LsiScsiControllerStop,\r
@@ -119,7 +1140,6 @@ EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
   NULL  // DriverBindingHandle, ditto\r
 };\r
 \r
-\r
 //\r
 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and\r
 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name\r
@@ -133,20 +1153,20 @@ EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
 //\r
 \r
 STATIC\r
-EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {\r
+EFI_UNICODE_STRING_TABLE  mDriverNameTable[] = {\r
   { "eng;en", L"LSI 53C895A SCSI Controller Driver" },\r
   { NULL,     NULL                                  }\r
 };\r
 \r
 STATIC\r
-EFI_COMPONENT_NAME_PROTOCOL gComponentName;\r
+EFI_COMPONENT_NAME_PROTOCOL  gComponentName;\r
 \r
 EFI_STATUS\r
 EFIAPI\r
 LsiScsiGetDriverName (\r
-  IN  EFI_COMPONENT_NAME_PROTOCOL *This,\r
-  IN  CHAR8                       *Language,\r
-  OUT CHAR16                      **DriverName\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
   )\r
 {\r
   return LookupUnicodeString2 (\r
@@ -161,27 +1181,27 @@ LsiScsiGetDriverName (
 EFI_STATUS\r
 EFIAPI\r
 LsiScsiGetDeviceName (\r
-  IN  EFI_COMPONENT_NAME_PROTOCOL *This,\r
-  IN  EFI_HANDLE                  DeviceHandle,\r
-  IN  EFI_HANDLE                  ChildHandle,\r
-  IN  CHAR8                       *Language,\r
-  OUT CHAR16                      **ControllerName\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   DeviceHandle,\r
+  IN  EFI_HANDLE                   ChildHandle,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **ControllerName\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
 STATIC\r
-EFI_COMPONENT_NAME_PROTOCOL gComponentName = {\r
+EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {\r
   &LsiScsiGetDriverName,\r
   &LsiScsiGetDeviceName,\r
   "eng" // SupportedLanguages, ISO 639-2 language codes\r
 };\r
 \r
 STATIC\r
-EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {\r
-  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &LsiScsiGetDriverName,\r
-  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &LsiScsiGetDeviceName,\r
+EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2 = {\r
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&LsiScsiGetDriverName,\r
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&LsiScsiGetDeviceName,\r
   "en" // SupportedLanguages, RFC 4646 language codes\r
 };\r
 \r
@@ -191,8 +1211,8 @@ EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
 EFI_STATUS\r
 EFIAPI\r
 LsiScsiEntryPoint (\r
-  IN EFI_HANDLE       ImageHandle,\r
-  IN EFI_SYSTEM_TABLE *SystemTable\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
   return EfiLibInstallDriverBindingComponentName2 (\r