36 return Dev->PciIo->Io.Write (
54 return Dev->PciIo->Io.Write (
72 return Dev->PciIo->Io.Read (
90 return Dev->PciIo->Io.Read (
106 return Out8 (Dev, LSI_REG_ISTAT0, LSI_ISTAT0_SRST);
111ReportHostAdapterOverrunError (
115 Packet->SenseDataLength = 0;
116 Packet->HostAdapterStatus =
117 EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
118 Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
119 return EFI_BAD_BUFFER_SIZE;
155 if ((Target > Dev->MaxTarget) || (Lun > Dev->MaxLun) ||
156 (Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
161 ((Packet->InTransferLength > 0) &&
162 ((Packet->InDataBuffer ==
NULL) ||
163 (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE)
171 ((Packet->OutTransferLength > 0) &&
172 ((Packet->OutDataBuffer ==
NULL) ||
173 (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ)
178 return EFI_INVALID_PARAMETER;
181 if ((Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
182 ((Packet->InTransferLength > 0) && (Packet->OutTransferLength > 0)) ||
183 (Packet->CdbLength >
sizeof Dev->Dma->Cdb))
185 return EFI_UNSUPPORTED;
188 if (Packet->InTransferLength >
sizeof Dev->Dma->Data) {
189 Packet->InTransferLength =
sizeof Dev->Dma->Data;
190 return ReportHostAdapterOverrunError (Packet);
193 if (Packet->OutTransferLength >
sizeof Dev->Dma->Data) {
194 Packet->OutTransferLength =
sizeof Dev->Dma->Data;
195 return ReportHostAdapterOverrunError (Packet);
247 Script = Dev->Dma->Script;
249 Data = Dev->Dma->Data;
250 MsgIn = Dev->Dma->MsgIn;
251 MsgOut = &Dev->Dma->MsgOut;
252 ScsiStatus = &Dev->Dma->Status;
260 SetMem (Cdb,
sizeof Dev->Dma->Cdb, 0x00);
261 CopyMem (Cdb, Packet->Cdb, Packet->CdbLength);
270 Status = In32 (Dev, LSI_REG_CSBC, &CsbcBase);
271 if (EFI_ERROR (Status)) {
278 SetMem (Script,
sizeof Dev->Dma->Script, 0x00);
308 *Script++ = LSI_INS_TYPE_IO | LSI_INS_IO_OPC_SEL | (UINT32)Target << 16;
309 *Script++ = 0x00000000;
314 *MsgOut = 0x80 | (UINT8)Lun;
315 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_OUT |
316 (UINT32)
sizeof Dev->Dma->MsgOut;
317 *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgOut);
322 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_CMD |
323 (UINT32)
sizeof Dev->Dma->Cdb;
324 *Script++ = LSI_SCSI_DMA_ADDR (Dev, Cdb);
333 *Script++ = LSI_INS_TYPE_TC | LSI_INS_TC_OPC_JMP |
334 LSI_INS_TC_SCSIP_MSG_IN | LSI_INS_TC_RA |
336 *Script++ = 0x00000018;
341 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_IN |
342 (UINT32)
sizeof Dev->Dma->MsgIn;
343 *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgIn);
348 *Script++ = LSI_INS_TYPE_IO | LSI_INS_IO_OPC_WAIT_RESEL;
349 *Script++ = 0x00000000;
354 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_IN |
355 (UINT32)
sizeof Dev->Dma->MsgIn;
356 *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgIn);
368 if (Packet->InTransferLength > 0) {
369 ASSERT (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ);
370 ASSERT (Packet->InTransferLength <=
sizeof Dev->Dma->Data);
371 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_DAT_IN |
372 Packet->InTransferLength;
373 *Script++ = LSI_SCSI_DMA_ADDR (Dev, Data);
374 }
else if (Packet->OutTransferLength > 0) {
375 ASSERT (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE);
376 ASSERT (Packet->OutTransferLength <=
sizeof Dev->Dma->Data);
377 CopyMem (Data, Packet->OutDataBuffer, Packet->OutTransferLength);
378 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_DAT_OUT |
379 Packet->OutTransferLength;
380 *Script++ = LSI_SCSI_DMA_ADDR (Dev, Data);
386 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_STAT |
387 (UINT32)
sizeof Dev->Dma->Status;
388 *Script++ = LSI_SCSI_DMA_ADDR (Dev, Status);
393 *Script++ = LSI_INS_TYPE_BLK | LSI_INS_BLK_SCSIP_MSG_IN |
394 (UINT32)
sizeof Dev->Dma->MsgIn;
395 *Script++ = LSI_SCSI_DMA_ADDR (Dev, MsgIn);
400 *Script++ = LSI_INS_TYPE_TC | LSI_INS_TC_OPC_INT |
401 LSI_INS_TC_SCSIP_DAT_OUT | LSI_INS_TC_JMP;
402 *Script++ = 0x00000000;
407 ASSERT (Script <= Dev->Dma->Script +
ARRAY_SIZE (Dev->Dma->Script));
413 Status = Out32 (Dev, LSI_REG_DSP, LSI_SCSI_DMA_ADDR (Dev, Script));
414 if (EFI_ERROR (Status)) {
423 Status = In8 (Dev, LSI_REG_DSTAT, &DStat);
424 if (EFI_ERROR (Status)) {
428 Status = In8 (Dev, LSI_REG_SIST0, &SIst0);
429 if (EFI_ERROR (Status)) {
433 Status = In8 (Dev, LSI_REG_SIST1, &SIst1);
434 if (EFI_ERROR (Status)) {
438 if ((SIst0 != 0) || (SIst1 != 0)) {
445 if (DStat & LSI_DSTAT_SIR) {
449 gBS->Stall (Dev->StallPerPollUsec);
457 if ((MsgIn[0] != 0) || (*ScsiStatus != 0)) {
470 Status = In32 (Dev, LSI_REG_CSBC, &Csbc);
471 if (EFI_ERROR (Status)) {
475 Transferred = Csbc - CsbcBase;
476 if (Packet->InTransferLength > 0) {
477 if (Transferred <= Packet->InTransferLength) {
478 Packet->InTransferLength = Transferred;
482 }
else if (Packet->OutTransferLength > 0) {
483 if (Transferred <= Packet->OutTransferLength) {
484 Packet->OutTransferLength = Transferred;
493 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
494 CopyMem (Packet->InDataBuffer, Data, Packet->InTransferLength);
505 Packet->SenseDataLength = 0;
506 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
507 Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
514 "%a: dstat: %02X, sist0: %02X, sist1: %02X\n",
523 if (*ScsiStatus != 0xFF) {
524 Packet->TargetStatus = *ScsiStatus;
526 Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED;
529 if (SIst0 & LSI_SIST0_PAR) {
530 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR;
531 }
else if (SIst0 & LSI_SIST0_RST) {
532 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET;
533 }
else if (SIst0 & LSI_SIST0_UDC) {
538 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND;
539 }
else if (SIst0 & LSI_SIST0_SGE) {
540 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
541 }
else if (SIst1 & LSI_SIST1_HTH) {
542 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT;
543 }
else if (SIst1 & LSI_SIST1_GEN) {
544 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT;
545 }
else if (SIst1 & LSI_SIST1_STO) {
546 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT;
548 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
555 Packet->SenseDataLength = 0;
557 return EFI_DEVICE_ERROR;
581 Dev = LSI_SCSI_FROM_PASS_THRU (This);
583 if (EFI_ERROR (Status)) {
592LsiScsiGetNextTargetLun (
594 IN OUT UINT8 **TargetPointer,
606 Target = *TargetPointer;
611 for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx) {
614 if (Idx == TARGET_MAX_BYTES) {
615 SetMem (Target, TARGET_MAX_BYTES, 0x00);
620 CopyMem (&LastTarget, Target,
sizeof LastTarget);
625 Dev = LSI_SCSI_FROM_PASS_THRU (This);
626 if ((LastTarget > Dev->MaxTarget) || (*Lun > Dev->MaxLun)) {
627 return EFI_INVALID_PARAMETER;
630 if (*Lun < Dev->MaxLun) {
635 if (LastTarget < Dev->MaxTarget) {
638 CopyMem (Target, &LastTarget,
sizeof LastTarget);
642 return EFI_NOT_FOUND;
647LsiScsiBuildDevicePath (
658 if (DevicePath ==
NULL) {
659 return EFI_INVALID_PARAMETER;
662 CopyMem (&TargetValue, Target,
sizeof TargetValue);
663 Dev = LSI_SCSI_FROM_PASS_THRU (This);
664 if ((TargetValue > Dev->MaxTarget) || (Lun > Dev->MaxLun) || (Lun > 0xFFFF)) {
665 return EFI_NOT_FOUND;
669 if (ScsiDevicePath ==
NULL) {
670 return EFI_OUT_OF_RESOURCES;
675 ScsiDevicePath->Header.
Length[0] = (UINT8)
sizeof *ScsiDevicePath;
676 ScsiDevicePath->Header.
Length[1] = (UINT8)(
sizeof *ScsiDevicePath >> 8);
677 ScsiDevicePath->
Pun = TargetValue;
678 ScsiDevicePath->
Lun = (UINT16)Lun;
680 *DevicePath = &ScsiDevicePath->Header;
689 OUT UINT8 **TargetPointer,
697 if ((DevicePath ==
NULL) || (TargetPointer ==
NULL) || (*TargetPointer ==
NULL) ||
700 return EFI_INVALID_PARAMETER;
706 return EFI_UNSUPPORTED;
710 Dev = LSI_SCSI_FROM_PASS_THRU (This);
711 if ((ScsiDevicePath->
Pun > Dev->MaxTarget) ||
712 (ScsiDevicePath->
Lun > Dev->MaxLun))
714 return EFI_NOT_FOUND;
717 Target = *TargetPointer;
718 ZeroMem (Target, TARGET_MAX_BYTES);
719 CopyMem (Target, &ScsiDevicePath->
Pun,
sizeof ScsiDevicePath->
Pun);
720 *Lun = ScsiDevicePath->
Lun;
731 return EFI_UNSUPPORTED;
736LsiScsiResetTargetLun (
742 return EFI_UNSUPPORTED;
747LsiScsiGetNextTarget (
749 IN OUT UINT8 **TargetPointer
760 Target = *TargetPointer;
765 for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx) {
768 if (Idx == TARGET_MAX_BYTES) {
769 SetMem (Target, TARGET_MAX_BYTES, 0x00);
773 CopyMem (&LastTarget, Target,
sizeof LastTarget);
778 Dev = LSI_SCSI_FROM_PASS_THRU (This);
779 if (LastTarget > Dev->MaxTarget) {
780 return EFI_INVALID_PARAMETER;
783 if (LastTarget < Dev->MaxTarget) {
785 CopyMem (Target, &LastTarget,
sizeof LastTarget);
789 return EFI_NOT_FOUND;
803 DEBUG ((DEBUG_VERBOSE,
"%a: Context=0x%p\n", __func__, Context));
818LsiScsiControllerSupported (
828 Status =
gBS->OpenProtocol (
830 &gEfiPciIoProtocolGuid,
832 This->DriverBindingHandle,
834 EFI_OPEN_PROTOCOL_BY_DRIVER
836 if (EFI_ERROR (Status)) {
840 Status = PciIo->Pci.Read (
844 sizeof (Pci) /
sizeof (UINT32),
847 if (EFI_ERROR (Status)) {
851 if ((Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID) &&
852 (Pci.Hdr.DeviceId == LSI_53C895A_PCI_DEVICE_ID))
856 Status = EFI_UNSUPPORTED;
862 &gEfiPciIoProtocolGuid,
863 This->DriverBindingHandle,
871LsiScsiControllerStart (
884 return EFI_OUT_OF_RESOURCES;
887 Dev->Signature = LSI_SCSI_DEV_SIGNATURE;
891 "LSI 53C895A supports targets [0..7]"
895 "LSI 53C895A supports LUNs [0..127]"
897 Dev->MaxTarget =
PcdGet8 (PcdLsiScsiMaxTargetLimit);
898 Dev->MaxLun =
PcdGet8 (PcdLsiScsiMaxLunLimit);
899 Dev->StallPerPollUsec =
PcdGet32 (PcdLsiScsiStallPerPollUsec);
901 Status =
gBS->OpenProtocol (
903 &gEfiPciIoProtocolGuid,
904 (VOID **)&Dev->PciIo,
905 This->DriverBindingHandle,
907 EFI_OPEN_PROTOCOL_BY_DRIVER
909 if (EFI_ERROR (Status)) {
913 Status = Dev->PciIo->Attributes (
919 if (EFI_ERROR (Status)) {
926 Status = Dev->PciIo->Attributes (
933 if (EFI_ERROR (Status)) {
941 Status = Dev->PciIo->AllocateBuffer (
947 EFI_PCI_ATTRIBUTE_MEMORY_CACHED
949 if (EFI_ERROR (Status)) {
950 goto RestoreAttributes;
954 Status = Dev->PciIo->Map (
962 if (EFI_ERROR (Status)) {
967 Status = EFI_OUT_OF_RESOURCES;
971 Status = LsiScsiReset (Dev);
972 if (EFI_ERROR (Status)) {
976 Status =
gBS->CreateEvent (
977 EVT_SIGNAL_EXIT_BOOT_SERVICES,
983 if (EFI_ERROR (Status)) {
990 Dev->PassThruMode.
AdapterId = MAX_UINT32;
992 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
993 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
995 Dev->PassThru.
Mode = &Dev->PassThruMode;
996 Dev->PassThru.PassThru = &LsiScsiPassThru;
997 Dev->PassThru.GetNextTargetLun = &LsiScsiGetNextTargetLun;
998 Dev->PassThru.BuildDevicePath = &LsiScsiBuildDevicePath;
999 Dev->PassThru.GetTargetLun = &LsiScsiGetTargetLun;
1000 Dev->PassThru.ResetChannel = &LsiScsiResetChannel;
1001 Dev->PassThru.ResetTargetLun = &LsiScsiResetTargetLun;
1002 Dev->PassThru.GetNextTarget = &LsiScsiGetNextTarget;
1004 Status =
gBS->InstallProtocolInterface (
1006 &gEfiExtScsiPassThruProtocolGuid,
1010 if (EFI_ERROR (Status)) {
1017 gBS->CloseEvent (Dev->ExitBoot);
1029 Dev->PciIo->FreeBuffer (
1036 Dev->PciIo->Attributes (
1044 gBS->CloseProtocol (
1046 &gEfiPciIoProtocolGuid,
1047 This->DriverBindingHandle,
1059LsiScsiControllerStop (
1070 Status =
gBS->OpenProtocol (
1072 &gEfiExtScsiPassThruProtocolGuid,
1074 This->DriverBindingHandle,
1076 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1078 if (EFI_ERROR (Status)) {
1082 Dev = LSI_SCSI_FROM_PASS_THRU (PassThru);
1084 Status =
gBS->UninstallProtocolInterface (
1086 &gEfiExtScsiPassThruProtocolGuid,
1089 if (EFI_ERROR (Status)) {
1093 gBS->CloseEvent (Dev->ExitBoot);
1102 Dev->PciIo->FreeBuffer (
1108 Dev->PciIo->Attributes (
1115 gBS->CloseProtocol (
1117 &gEfiPciIoProtocolGuid,
1118 This->DriverBindingHandle,
1134 &LsiScsiControllerSupported,
1135 &LsiScsiControllerStart,
1136 &LsiScsiControllerStop,
1157 {
"eng;en", L
"LSI 53C895A SCSI Controller Driver" },
1166LsiScsiGetDriverName (
1169 OUT CHAR16 **DriverName
1174 This->SupportedLanguages,
1177 (BOOLEAN)(This == &gComponentName)
1183LsiScsiGetDeviceName (
1188 OUT CHAR16 **ControllerName
1191 return EFI_UNSUPPORTED;
1196 &LsiScsiGetDriverName,
1197 &LsiScsiGetDeviceName,
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName)
#define MESSAGING_DEVICE_PATH
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
STATIC EFI_STATUS LsiScsiCheckRequest(IN LSI_SCSI_DEV *Dev, IN UINT8 Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
STATIC EFI_STATUS LsiScsiProcessRequest(IN LSI_SCSI_DEV *Dev, IN UINT8 Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
#define ARRAY_SIZE(Array)
#define DEBUG(Expression)
@ EfiPciIoAttributeOperationGet
@ EfiPciIoAttributeOperationEnable
@ EfiPciIoAttributeOperationSet
#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
Enable the DMA bit in the PCI Config Header.
@ EfiPciIoOperationBusMasterCommonBuffer
#define EFI_PCI_IO_ATTRIBUTE_IO
Enable the I/O decode bit in the PCI Config Header.
#define PcdGet8(TokenName)
#define PcdGet32(TokenName)
#define FixedPcdGet8(TokenName)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_STATUS EFIAPI LookupUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable, OUT CHAR16 **UnicodeString, IN BOOLEAN Iso639Language)
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_EXT_SCSI_PASS_THRU_MODE * Mode