TianoCore EDK2 master
Loading...
Searching...
No Matches
AtaAtapiPassThru.c
Go to the documentation of this file.
1
10#include "AtaAtapiPassThru.h"
11
12//
13// EFI_DRIVER_BINDING_PROTOCOL instance
14//
15EFI_DRIVER_BINDING_PROTOCOL gAtaAtapiPassThruDriverBinding = {
19 0x10,
20 NULL,
21 NULL
22};
23
24ATA_ATAPI_PASS_THRU_INSTANCE gAtaAtapiPassThruInstanceTemplate = {
25 ATA_ATAPI_PASS_THRU_SIGNATURE,
26 0, // Controller Handle
27 NULL, // PciIo Protocol
28 NULL, // IdeControllerInit Protocol
29 { // AtaPassThruMode
30 //
31 // According to UEFI2.3 spec Section 12.10, Drivers for non-RAID ATA controllers should set
32 // both EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL and EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
33 // bits.
34 // Note that the driver doesn't support AtaPassThru non blocking I/O.
35 //
37 //
38 // IoAlign
39 //
40 sizeof (UINTN)
41 },
42 { // AtaPassThru
43 NULL,
51 },
52 { // ExtScsiPassThruMode
53 //
54 // AdapterId
55 //
56 0,
57 //
58 // According to UEFI2.3 spec Section 14.7, Drivers for non-RAID SCSI controllers should set
59 // both EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL and EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
60 // bits.
61 // Note that the driver doesn't support ExtScsiPassThru non blocking I/O.
62 //
63 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
64 //
65 // IoAlign
66 //
67 sizeof (UINTN)
68 },
69 { // ExtScsiPassThru
70 NULL,
78 },
79 EfiAtaUnknownMode, // Work Mode
80 { // IdeRegisters
81 { 0 },
82 { 0 }
83 },
84 { // AhciRegisters
85 0
86 },
87 { // DeviceList
88 NULL,
89 NULL
90 },
91 0, // EnabledPciAttributes
92 0, // OriginalAttributes
93 0, // PreviousPort
94 0, // PreviousPortMultiplier
95 0, // PreviousTargetId
96 0, // PreviousLun
97 NULL, // Timer event
98 { // NonBlocking TaskList
99 NULL,
100 NULL
101 }
102};
103
104ATAPI_DEVICE_PATH mAtapiDevicePathTemplate = {
105 {
108 {
109 (UINT8)(sizeof (ATAPI_DEVICE_PATH)),
110 (UINT8)((sizeof (ATAPI_DEVICE_PATH)) >> 8)
111 }
112 },
113 0,
114 0,
115 0
116};
117
118SATA_DEVICE_PATH mSataDevicePathTemplate = {
119 {
122 {
123 (UINT8)(sizeof (SATA_DEVICE_PATH)),
124 (UINT8)((sizeof (SATA_DEVICE_PATH)) >> 8)
125 }
126 },
127 0,
128 0,
129 0
130};
131
132UINT8 mScsiId[TARGET_MAX_BYTES] = {
133 0xFF, 0xFF, 0xFF, 0xFF,
134 0xFF, 0xFF, 0xFF, 0xFF,
135 0xFF, 0xFF, 0xFF, 0xFF,
136 0xFF, 0xFF, 0xFF, 0xFF
137};
138
139EDKII_ATA_ATAPI_POLICY_PROTOCOL *mAtaAtapiPolicy;
140EDKII_ATA_ATAPI_POLICY_PROTOCOL mDefaultAtaAtapiPolicy = {
141 EDKII_ATA_ATAPI_POLICY_VERSION,
142 2, // PuisEnable
143 0, // DeviceSleepEnable
144 0, // AggressiveDeviceSleepEnable
145 0 // Reserved
146};
147
184EFIAPI
186 IN UINT16 Port,
187 IN UINT16 PortMultiplierPort,
190 IN ATA_NONBLOCK_TASK *Task OPTIONAL
191 )
192{
193 EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol;
194 EFI_ATA_HC_WORK_MODE Mode;
195 EFI_STATUS Status;
196
197 Protocol = Packet->Protocol;
198
199 Mode = Instance->Mode;
200 switch (Mode) {
201 case EfiAtaIdeMode:
202 //
203 // Reassign IDE mode io port registers' base addresses
204 //
205 Status = GetIdeRegisterIoAddr (Instance->PciIo, Instance->IdeRegisters);
206
207 if (EFI_ERROR (Status)) {
208 return Status;
209 }
210
211 switch (Protocol) {
212 case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
213 Status = AtaNonDataCommandIn (
214 Instance->PciIo,
215 &Instance->IdeRegisters[Port],
216 Packet->Acb,
217 Packet->Asb,
218 Packet->Timeout,
219 Task
220 );
221 break;
222 case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
223 Status = AtaPioDataInOut (
224 Instance->PciIo,
225 &Instance->IdeRegisters[Port],
226 Packet->InDataBuffer,
227 Packet->InTransferLength,
228 TRUE,
229 Packet->Acb,
230 Packet->Asb,
231 Packet->Timeout,
232 Task
233 );
234 break;
235 case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
236 Status = AtaPioDataInOut (
237 Instance->PciIo,
238 &Instance->IdeRegisters[Port],
239 Packet->OutDataBuffer,
240 Packet->OutTransferLength,
241 FALSE,
242 Packet->Acb,
243 Packet->Asb,
244 Packet->Timeout,
245 Task
246 );
247 break;
248 case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
249 Status = AtaUdmaInOut (
250 Instance,
251 &Instance->IdeRegisters[Port],
252 TRUE,
253 Packet->InDataBuffer,
254 Packet->InTransferLength,
255 Packet->Acb,
256 Packet->Asb,
257 Packet->Timeout,
258 Task
259 );
260 break;
261 case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
262 Status = AtaUdmaInOut (
263 Instance,
264 &Instance->IdeRegisters[Port],
265 FALSE,
266 Packet->OutDataBuffer,
267 Packet->OutTransferLength,
268 Packet->Acb,
269 Packet->Asb,
270 Packet->Timeout,
271 Task
272 );
273 break;
274 default:
275 return EFI_UNSUPPORTED;
276 }
277
278 break;
279 case EfiAtaAhciMode:
280 if (PortMultiplierPort == 0xFFFF) {
281 //
282 // If there is no port multiplier, PortMultiplierPort will be 0xFFFF
283 // according to UEFI spec. Here, we convert its value to 0 to follow
284 // AHCI spec.
285 //
286 PortMultiplierPort = 0;
287 }
288
289 switch (Protocol) {
290 case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
291 Status = AhciNonDataTransfer (
292 Instance->PciIo,
293 &Instance->AhciRegisters,
294 (UINT8)Port,
295 (UINT8)PortMultiplierPort,
296 NULL,
297 0,
298 Packet->Acb,
299 Packet->Asb,
300 Packet->Timeout,
301 Task
302 );
303 break;
304 case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
305 Status = AhciPioTransfer (
306 Instance->PciIo,
307 &Instance->AhciRegisters,
308 (UINT8)Port,
309 (UINT8)PortMultiplierPort,
310 NULL,
311 0,
312 TRUE,
313 Packet->Acb,
314 Packet->Asb,
315 Packet->InDataBuffer,
316 Packet->InTransferLength,
317 Packet->Timeout,
318 Task
319 );
320 break;
321 case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
322 Status = AhciPioTransfer (
323 Instance->PciIo,
324 &Instance->AhciRegisters,
325 (UINT8)Port,
326 (UINT8)PortMultiplierPort,
327 NULL,
328 0,
329 FALSE,
330 Packet->Acb,
331 Packet->Asb,
332 Packet->OutDataBuffer,
333 Packet->OutTransferLength,
334 Packet->Timeout,
335 Task
336 );
337 break;
338 case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
339 Status = AhciDmaTransfer (
340 Instance,
341 &Instance->AhciRegisters,
342 (UINT8)Port,
343 (UINT8)PortMultiplierPort,
344 NULL,
345 0,
346 TRUE,
347 Packet->Acb,
348 Packet->Asb,
349 Packet->InDataBuffer,
350 Packet->InTransferLength,
351 Packet->Timeout,
352 Task
353 );
354 break;
355 case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
356 Status = AhciDmaTransfer (
357 Instance,
358 &Instance->AhciRegisters,
359 (UINT8)Port,
360 (UINT8)PortMultiplierPort,
361 NULL,
362 0,
363 FALSE,
364 Packet->Acb,
365 Packet->Asb,
366 Packet->OutDataBuffer,
367 Packet->OutTransferLength,
368 Packet->Timeout,
369 Task
370 );
371 break;
372 default:
373 return EFI_UNSUPPORTED;
374 }
375
376 break;
377
378 default:
379 Status = EFI_DEVICE_ERROR;
380 break;
381 }
382
383 return Status;
384}
385
394VOID
395EFIAPI
397 EFI_EVENT Event,
398 VOID *Context
399 )
400{
401 LIST_ENTRY *Entry;
402 LIST_ENTRY *EntryHeader;
403 ATA_NONBLOCK_TASK *Task;
404 EFI_STATUS Status;
406
407 Instance = (ATA_ATAPI_PASS_THRU_INSTANCE *)Context;
408 EntryHeader = &Instance->NonBlockingTaskList;
409 //
410 // Get the Tasks from the Tasks List and execute it, until there is
411 // no task in the list or the device is busy with task (EFI_NOT_READY).
412 //
413 while (TRUE) {
414 if (!IsListEmpty (EntryHeader)) {
415 Entry = GetFirstNode (EntryHeader);
416 Task = ATA_NON_BLOCK_TASK_FROM_ENTRY (Entry);
417 } else {
418 return;
419 }
420
422 Task->Port,
423 Task->PortMultiplier,
424 Task->Packet,
425 Instance,
426 Task
427 );
428
429 //
430 // If the data transfer meet a error, remove all tasks in the list since these tasks are
431 // associated with one task from Ata Bus and signal the event with error status.
432 //
433 if ((Status != EFI_NOT_READY) && (Status != EFI_SUCCESS)) {
434 DestroyAsynTaskList (Instance, TRUE);
435 break;
436 }
437
438 //
439 // For Non blocking mode, the Status of EFI_NOT_READY means the operation
440 // is not finished yet. Otherwise the operation is successful.
441 //
442 if (Status == EFI_NOT_READY) {
443 break;
444 } else {
445 RemoveEntryList (&Task->Link);
446 gBS->SignalEvent (Task->Event);
447 FreePool (Task);
448 }
449 }
450}
451
463EFIAPI
465 IN EFI_HANDLE ImageHandle,
466 IN EFI_SYSTEM_TABLE *SystemTable
467 )
468{
469 EFI_STATUS Status;
470
471 //
472 // Install driver model protocol(s).
473 //
475 ImageHandle,
476 SystemTable,
477 &gAtaAtapiPassThruDriverBinding,
478 ImageHandle,
479 &gAtaAtapiPassThruComponentName,
480 &gAtaAtapiPassThruComponentName2
481 );
482 ASSERT_EFI_ERROR (Status);
483
484 return Status;
485}
486
530EFIAPI
533 IN EFI_HANDLE Controller,
534 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
535 )
536{
537 EFI_STATUS Status;
538 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
539 EFI_PCI_IO_PROTOCOL *PciIo;
540 PCI_TYPE00 PciData;
541 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInit;
542
543 //
544 // SATA Controller is a device driver, and should ignore the
545 // "RemainingDevicePath" according to UEFI spec
546 //
547 Status = gBS->OpenProtocol (
548 Controller,
549 &gEfiDevicePathProtocolGuid,
550 (VOID *)&ParentDevicePath,
551 This->DriverBindingHandle,
552 Controller,
553 EFI_OPEN_PROTOCOL_BY_DRIVER
554 );
555 if (EFI_ERROR (Status)) {
556 //
557 // EFI_ALREADY_STARTED is also an error
558 //
559 return Status;
560 }
561
562 //
563 // Close the protocol because we don't use it here
564 //
565 gBS->CloseProtocol (
566 Controller,
567 &gEfiDevicePathProtocolGuid,
568 This->DriverBindingHandle,
569 Controller
570 );
571
572 Status = gBS->OpenProtocol (
573 Controller,
574 &gEfiIdeControllerInitProtocolGuid,
575 (VOID **)&IdeControllerInit,
576 This->DriverBindingHandle,
577 Controller,
578 EFI_OPEN_PROTOCOL_BY_DRIVER
579 );
580
581 if (EFI_ERROR (Status)) {
582 //
583 // EFI_ALREADY_STARTED is also an error
584 //
585 return Status;
586 }
587
588 //
589 // Close the I/O Abstraction(s) used to perform the supported test
590 //
591 gBS->CloseProtocol (
592 Controller,
593 &gEfiIdeControllerInitProtocolGuid,
594 This->DriverBindingHandle,
595 Controller
596 );
597
598 //
599 // Now test the EfiPciIoProtocol
600 //
601 Status = gBS->OpenProtocol (
602 Controller,
603 &gEfiPciIoProtocolGuid,
604 (VOID **)&PciIo,
605 This->DriverBindingHandle,
606 Controller,
607 EFI_OPEN_PROTOCOL_GET_PROTOCOL
608 );
609 if (EFI_ERROR (Status)) {
610 return Status;
611 }
612
613 //
614 // Now further check the PCI header: Base class (offset 0x0B) and
615 // Sub Class (offset 0x0A). This controller should be an ATA controller
616 //
617 Status = PciIo->Pci.Read (
618 PciIo,
619 EfiPciIoWidthUint8,
620 PCI_CLASSCODE_OFFSET,
621 sizeof (PciData.Hdr.ClassCode),
622 PciData.Hdr.ClassCode
623 );
624 if (EFI_ERROR (Status)) {
625 return EFI_UNSUPPORTED;
626 }
627
628 if (IS_PCI_IDE (&PciData) || IS_PCI_SATADPA (&PciData)) {
629 return EFI_SUCCESS;
630 }
631
632 return EFI_UNSUPPORTED;
633}
634
671EFIAPI
674 IN EFI_HANDLE Controller,
675 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
676 )
677{
678 EFI_STATUS Status;
679 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInit;
681 EFI_PCI_IO_PROTOCOL *PciIo;
682 UINT64 EnabledPciAttributes;
683 UINT64 OriginalPciAttributes;
684
685 Status = EFI_SUCCESS;
686 IdeControllerInit = NULL;
687 Instance = NULL;
688 OriginalPciAttributes = 0;
689
690 DEBUG ((DEBUG_INFO, "==AtaAtapiPassThru Start== Controller = %x\n", Controller));
691
692 Status = gBS->OpenProtocol (
693 Controller,
694 &gEfiIdeControllerInitProtocolGuid,
695 (VOID **)&IdeControllerInit,
696 This->DriverBindingHandle,
697 Controller,
698 EFI_OPEN_PROTOCOL_BY_DRIVER
699 );
700
701 if (EFI_ERROR (Status)) {
702 DEBUG ((DEBUG_ERROR, "Open Ide_Controller_Init Error, Status=%r", Status));
703 goto ErrorExit;
704 }
705
706 Status = gBS->OpenProtocol (
707 Controller,
708 &gEfiPciIoProtocolGuid,
709 (VOID **)&PciIo,
710 This->DriverBindingHandle,
711 Controller,
712 EFI_OPEN_PROTOCOL_GET_PROTOCOL
713 );
714 if (EFI_ERROR (Status)) {
715 DEBUG ((DEBUG_ERROR, "Get Pci_Io Protocol Error, Status=%r", Status));
716 goto ErrorExit;
717 }
718
719 Status = PciIo->Attributes (
720 PciIo,
722 0,
723 &OriginalPciAttributes
724 );
725
726 if (EFI_ERROR (Status)) {
727 goto ErrorExit;
728 }
729
730 Status = PciIo->Attributes (
731 PciIo,
733 0,
734 &EnabledPciAttributes
735 );
736 if (!EFI_ERROR (Status)) {
737 EnabledPciAttributes &= (UINT64)EFI_PCI_DEVICE_ENABLE;
738 Status = PciIo->Attributes (
739 PciIo,
741 EnabledPciAttributes,
742 NULL
743 );
744 }
745
746 if (EFI_ERROR (Status)) {
747 goto ErrorExit;
748 }
749
750 Status = gBS->LocateProtocol (&gEdkiiAtaAtapiPolicyProtocolGuid, NULL, (VOID **)&mAtaAtapiPolicy);
751 if (EFI_ERROR (Status)) {
752 //
753 // If there is no AtaAtapiPolicy exposed, use the default policy.
754 //
755 mAtaAtapiPolicy = &mDefaultAtaAtapiPolicy;
756 }
757
758 //
759 // Allocate a buffer to store the ATA_ATAPI_PASS_THRU_INSTANCE data structure
760 //
761 Instance = AllocateCopyPool (sizeof (ATA_ATAPI_PASS_THRU_INSTANCE), &gAtaAtapiPassThruInstanceTemplate);
762 if (Instance == NULL) {
763 goto ErrorExit;
764 }
765
766 Instance->ControllerHandle = Controller;
767 Instance->IdeControllerInit = IdeControllerInit;
768 Instance->PciIo = PciIo;
769 Instance->EnabledPciAttributes = EnabledPciAttributes;
770 Instance->OriginalPciAttributes = OriginalPciAttributes;
771 Instance->AtaPassThru.Mode = &Instance->AtaPassThruMode;
772 Instance->ExtScsiPassThru.Mode = &Instance->ExtScsiPassThruMode;
773 InitializeListHead (&Instance->DeviceList);
774 InitializeListHead (&Instance->NonBlockingTaskList);
775
776 Instance->TimerEvent = NULL;
777
778 Status = gBS->CreateEvent (
779 EVT_TIMER | EVT_NOTIFY_SIGNAL,
780 TPL_NOTIFY,
782 Instance,
783 &Instance->TimerEvent
784 );
785 if (EFI_ERROR (Status)) {
786 goto ErrorExit;
787 }
788
789 //
790 // Set 1ms timer.
791 //
792 Status = gBS->SetTimer (Instance->TimerEvent, TimerPeriodic, 10000);
793 if (EFI_ERROR (Status)) {
794 goto ErrorExit;
795 }
796
797 //
798 // Enumerate all inserted ATA devices.
799 //
800 Status = EnumerateAttachedDevice (Instance);
801 if (EFI_ERROR (Status)) {
802 goto ErrorExit;
803 }
804
805 Status = gBS->InstallMultipleProtocolInterfaces (
806 &Controller,
807 &gEfiAtaPassThruProtocolGuid,
808 &(Instance->AtaPassThru),
809 &gEfiExtScsiPassThruProtocolGuid,
810 &(Instance->ExtScsiPassThru),
811 NULL
812 );
813 ASSERT_EFI_ERROR (Status);
814
815 return Status;
816
817ErrorExit:
818 if (IdeControllerInit != NULL) {
819 gBS->CloseProtocol (
820 Controller,
821 &gEfiIdeControllerInitProtocolGuid,
822 This->DriverBindingHandle,
823 Controller
824 );
825 }
826
827 if ((Instance != NULL) && (Instance->TimerEvent != NULL)) {
828 gBS->CloseEvent (Instance->TimerEvent);
829 }
830
831 if (Instance != NULL) {
832 //
833 // Remove all inserted ATA devices.
834 //
835 DestroyDeviceInfoList (Instance);
836 FreePool (Instance);
837 }
838
839 return EFI_UNSUPPORTED;
840}
841
869EFIAPI
872 IN EFI_HANDLE Controller,
873 IN UINTN NumberOfChildren,
874 IN EFI_HANDLE *ChildHandleBuffer
875 )
876{
877 EFI_STATUS Status;
879 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
880 EFI_PCI_IO_PROTOCOL *PciIo;
881 EFI_AHCI_REGISTERS *AhciRegisters;
882
883 DEBUG ((DEBUG_INFO, "==AtaAtapiPassThru Stop== Controller = %x\n", Controller));
884
885 Status = gBS->OpenProtocol (
886 Controller,
887 &gEfiAtaPassThruProtocolGuid,
888 (VOID **)&AtaPassThru,
889 This->DriverBindingHandle,
890 Controller,
891 EFI_OPEN_PROTOCOL_GET_PROTOCOL
892 );
893
894 if (EFI_ERROR (Status)) {
895 return EFI_DEVICE_ERROR;
896 }
897
898 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (AtaPassThru);
899
900 Status = gBS->UninstallMultipleProtocolInterfaces (
901 Controller,
902 &gEfiAtaPassThruProtocolGuid,
903 &(Instance->AtaPassThru),
904 &gEfiExtScsiPassThruProtocolGuid,
905 &(Instance->ExtScsiPassThru),
906 NULL
907 );
908
909 if (EFI_ERROR (Status)) {
910 return EFI_DEVICE_ERROR;
911 }
912
913 //
914 // Close protocols opened by AtaAtapiPassThru controller driver
915 //
916 gBS->CloseProtocol (
917 Controller,
918 &gEfiIdeControllerInitProtocolGuid,
919 This->DriverBindingHandle,
920 Controller
921 );
922
923 //
924 // Close Non-Blocking timer and free Task list.
925 //
926 if (Instance->TimerEvent != NULL) {
927 gBS->CloseEvent (Instance->TimerEvent);
928 Instance->TimerEvent = NULL;
929 }
930
931 DestroyAsynTaskList (Instance, FALSE);
932 //
933 // Free allocated resource
934 //
935 DestroyDeviceInfoList (Instance);
936
937 PciIo = Instance->PciIo;
938
939 //
940 // Disable this ATA host controller.
941 //
942 PciIo->Attributes (
943 PciIo,
945 Instance->EnabledPciAttributes,
946 NULL
947 );
948
949 //
950 // If the current working mode is AHCI mode, then pre-allocated resource
951 // for AHCI initialization should be released.
952 //
953 if (Instance->Mode == EfiAtaAhciMode) {
954 AhciRegisters = &Instance->AhciRegisters;
955 PciIo->Unmap (
956 PciIo,
957 AhciRegisters->MapCommandTable
958 );
959 PciIo->FreeBuffer (
960 PciIo,
961 EFI_SIZE_TO_PAGES ((UINTN)AhciRegisters->MaxCommandTableSize),
962 AhciRegisters->AhciCommandTable
963 );
964 PciIo->Unmap (
965 PciIo,
966 AhciRegisters->MapCmdList
967 );
968 PciIo->FreeBuffer (
969 PciIo,
970 EFI_SIZE_TO_PAGES ((UINTN)AhciRegisters->MaxCommandListSize),
971 AhciRegisters->AhciCmdList
972 );
973 PciIo->Unmap (
974 PciIo,
975 AhciRegisters->MapRFis
976 );
977 PciIo->FreeBuffer (
978 PciIo,
979 EFI_SIZE_TO_PAGES ((UINTN)AhciRegisters->MaxReceiveFisSize),
980 AhciRegisters->AhciRFis
981 );
982 }
983
984 //
985 // Restore original PCI attributes
986 //
987 Status = PciIo->Attributes (
988 PciIo,
990 Instance->OriginalPciAttributes,
991 NULL
992 );
993 ASSERT_EFI_ERROR (Status);
994
995 FreePool (Instance);
996
997 return Status;
998}
999
1012LIST_ENTRY *
1013EFIAPI
1016 IN UINT16 Port,
1017 IN UINT16 PortMultiplier,
1018 IN EFI_ATA_DEVICE_TYPE DeviceType
1019 )
1020{
1021 EFI_ATA_DEVICE_INFO *DeviceInfo;
1022 LIST_ENTRY *Node;
1023
1024 Node = GetFirstNode (&Instance->DeviceList);
1025 while (!IsNull (&Instance->DeviceList, Node)) {
1026 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1027
1028 //
1029 // For CD-ROM working in the AHCI mode, only 8 bits are used to record
1030 // the PortMultiplier information. If the CD-ROM is directly attached
1031 // on a SATA port, the PortMultiplier should be translated from 0xFF
1032 // to 0xFFFF according to the UEFI spec.
1033 //
1034 if ((Instance->Mode == EfiAtaAhciMode) &&
1035 (DeviceInfo->Type == EfiIdeCdrom) &&
1036 (PortMultiplier == 0xFF))
1037 {
1038 PortMultiplier = 0xFFFF;
1039 }
1040
1041 if ((DeviceInfo->Type == DeviceType) &&
1042 (Port == DeviceInfo->Port) &&
1043 (PortMultiplier == DeviceInfo->PortMultiplier))
1044 {
1045 return Node;
1046 }
1047
1048 Node = GetNextNode (&Instance->DeviceList, Node);
1049 }
1050
1051 return NULL;
1052}
1053
1070EFIAPI
1073 IN UINT16 Port,
1074 IN UINT16 PortMultiplier,
1075 IN EFI_ATA_DEVICE_TYPE DeviceType,
1076 IN EFI_IDENTIFY_DATA *IdentifyData
1077 )
1078{
1079 EFI_ATA_DEVICE_INFO *DeviceInfo;
1080
1081 DeviceInfo = AllocateZeroPool (sizeof (EFI_ATA_DEVICE_INFO));
1082
1083 if (DeviceInfo == NULL) {
1084 return EFI_OUT_OF_RESOURCES;
1085 }
1086
1087 DeviceInfo->Signature = ATA_ATAPI_DEVICE_SIGNATURE;
1088 DeviceInfo->Port = Port;
1089 DeviceInfo->PortMultiplier = PortMultiplier;
1090 DeviceInfo->Type = DeviceType;
1091
1092 if (IdentifyData != NULL) {
1093 DeviceInfo->IdentifyData = AllocateCopyPool (sizeof (EFI_IDENTIFY_DATA), IdentifyData);
1094 if (DeviceInfo->IdentifyData == NULL) {
1095 FreePool (DeviceInfo);
1096 return EFI_OUT_OF_RESOURCES;
1097 }
1098 }
1099
1100 InsertTailList (&Instance->DeviceList, &DeviceInfo->Link);
1101
1102 return EFI_SUCCESS;
1103}
1104
1111VOID
1112EFIAPI
1115 )
1116{
1117 EFI_ATA_DEVICE_INFO *DeviceInfo;
1118 LIST_ENTRY *Node;
1119
1120 Node = GetFirstNode (&Instance->DeviceList);
1121 while (!IsNull (&Instance->DeviceList, Node)) {
1122 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1123
1124 Node = GetNextNode (&Instance->DeviceList, Node);
1125
1126 RemoveEntryList (&DeviceInfo->Link);
1127 if (DeviceInfo->IdentifyData != NULL) {
1128 FreePool (DeviceInfo->IdentifyData);
1129 }
1130
1131 FreePool (DeviceInfo);
1132 }
1133}
1134
1143VOID
1144EFIAPI
1147 IN BOOLEAN IsSigEvent
1148 )
1149{
1150 LIST_ENTRY *Entry;
1151 LIST_ENTRY *DelEntry;
1152 ATA_NONBLOCK_TASK *Task;
1153 EFI_TPL OldTpl;
1154
1155 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1156 if (!IsListEmpty (&Instance->NonBlockingTaskList)) {
1157 //
1158 // Free the Subtask list.
1159 //
1160 for (Entry = (&Instance->NonBlockingTaskList)->ForwardLink;
1161 Entry != (&Instance->NonBlockingTaskList);
1162 )
1163 {
1164 DelEntry = Entry;
1165 Entry = Entry->ForwardLink;
1166 Task = ATA_NON_BLOCK_TASK_FROM_ENTRY (DelEntry);
1167
1168 RemoveEntryList (DelEntry);
1169 if (IsSigEvent) {
1170 Task->Packet->Asb->AtaStatus = 0x01;
1171 gBS->SignalEvent (Task->Event);
1172 }
1173
1174 FreePool (Task);
1175 }
1176 }
1177
1178 gBS->RestoreTPL (OldTpl);
1179}
1180
1193EFIAPI
1196 )
1197{
1198 EFI_STATUS Status;
1199 PCI_TYPE00 PciData;
1200 UINT8 ClassCode;
1201
1202 Status = EFI_SUCCESS;
1203
1204 Status = Instance->PciIo->Pci.Read (
1205 Instance->PciIo,
1206 EfiPciIoWidthUint8,
1207 PCI_CLASSCODE_OFFSET,
1208 sizeof (PciData.Hdr.ClassCode),
1209 PciData.Hdr.ClassCode
1210 );
1211 ASSERT_EFI_ERROR (Status);
1212
1213 ClassCode = PciData.Hdr.ClassCode[1];
1214
1215 switch (ClassCode) {
1216 case PCI_CLASS_MASS_STORAGE_IDE:
1217 //
1218 // The ATA controller is working at IDE mode
1219 //
1220 Instance->Mode = EfiAtaIdeMode;
1221
1222 Status = IdeModeInitialization (Instance);
1223 if (EFI_ERROR (Status)) {
1224 Status = EFI_DEVICE_ERROR;
1225 goto Done;
1226 }
1227
1228 break;
1230 //
1231 // The ATA controller is working at AHCI mode
1232 //
1233 Instance->Mode = EfiAtaAhciMode;
1234
1235 Status = AhciModeInitialization (Instance);
1236
1237 if (EFI_ERROR (Status)) {
1238 Status = EFI_DEVICE_ERROR;
1239 goto Done;
1240 }
1241
1242 break;
1243 default:
1244 Status = EFI_UNSUPPORTED;
1245 }
1246
1247Done:
1248 return Status;
1249}
1250
1281EFIAPI
1284 IN UINT16 Port,
1285 IN UINT16 PortMultiplierPort,
1287 IN EFI_EVENT Event OPTIONAL
1288 )
1289{
1291 LIST_ENTRY *Node;
1292 EFI_ATA_DEVICE_INFO *DeviceInfo;
1293 EFI_IDENTIFY_DATA *IdentifyData;
1294 UINT64 Capacity;
1295 UINT32 MaxSectorCount;
1296 ATA_NONBLOCK_TASK *Task;
1297 EFI_TPL OldTpl;
1298 UINT32 BlockSize;
1299
1300 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
1301
1302 if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
1303 return EFI_INVALID_PARAMETER;
1304 }
1305
1306 if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
1307 return EFI_INVALID_PARAMETER;
1308 }
1309
1310 if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->Asb, This->Mode->IoAlign)) {
1311 return EFI_INVALID_PARAMETER;
1312 }
1313
1314 Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);
1315
1316 if (Node == NULL) {
1317 Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeCdrom);
1318 if (Node == NULL) {
1319 return EFI_INVALID_PARAMETER;
1320 }
1321 }
1322
1323 //
1324 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device).
1325 // Per ATA-6 spec, word83: bit15 is zero and bit14 is one.
1326 // If bit10 is one, it means the ata device support 48-bit addressing.
1327 //
1328 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1329 IdentifyData = DeviceInfo->IdentifyData;
1330 MaxSectorCount = 0x100;
1331 if ((IdentifyData->AtaData.command_set_supported_83 & (BIT10 | BIT15 | BIT14)) == 0x4400) {
1332 Capacity = *((UINT64 *)IdentifyData->AtaData.maximum_lba_for_48bit_addressing);
1333 if (Capacity > 0xFFFFFFF) {
1334 //
1335 // Capacity exceeds 120GB. 48-bit addressing is really needed
1336 // In this case, the max sector count is 0x10000
1337 //
1338 MaxSectorCount = 0x10000;
1339 }
1340 }
1341
1342 BlockSize = 0x200;
1343 if ((IdentifyData->AtaData.phy_logic_sector_support & (BIT14 | BIT15)) == BIT14) {
1344 //
1345 // Check logical block size
1346 //
1347 if ((IdentifyData->AtaData.phy_logic_sector_support & BIT12) != 0) {
1348 BlockSize = (UINT32)(((UINT32)(IdentifyData->AtaData.logic_sector_size_hi << 16) | IdentifyData->AtaData.logic_sector_size_lo) * sizeof (UINT16));
1349 }
1350 }
1351
1352 //
1353 // convert the transfer length from sector count to byte.
1354 //
1355 if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
1356 (Packet->InTransferLength != 0))
1357 {
1358 Packet->InTransferLength = Packet->InTransferLength * BlockSize;
1359 }
1360
1361 //
1362 // convert the transfer length from sector count to byte.
1363 //
1364 if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
1365 (Packet->OutTransferLength != 0))
1366 {
1367 Packet->OutTransferLength = Packet->OutTransferLength * BlockSize;
1368 }
1369
1370 //
1371 // If the data buffer described by InDataBuffer/OutDataBuffer and InTransferLength/OutTransferLength
1372 // is too big to be transferred in a single command, then no data is transferred and EFI_BAD_BUFFER_SIZE
1373 // is returned.
1374 //
1375 if (((Packet->InTransferLength != 0) && (Packet->InTransferLength > MaxSectorCount * BlockSize)) ||
1376 ((Packet->OutTransferLength != 0) && (Packet->OutTransferLength > MaxSectorCount * BlockSize)))
1377 {
1378 return EFI_BAD_BUFFER_SIZE;
1379 }
1380
1381 //
1382 // For non-blocking mode, queue the Task into the list.
1383 //
1384 if (Event != NULL) {
1385 Task = AllocateZeroPool (sizeof (ATA_NONBLOCK_TASK));
1386 if (Task == NULL) {
1387 return EFI_OUT_OF_RESOURCES;
1388 }
1389
1390 Task->Signature = ATA_NONBLOCKING_TASK_SIGNATURE;
1391 Task->Port = Port;
1392 Task->PortMultiplier = PortMultiplierPort;
1393 Task->Packet = Packet;
1394 Task->Event = Event;
1395 Task->IsStart = FALSE;
1396 Task->RetryTimes = DivU64x32 (Packet->Timeout, 1000) + 1;
1397 if (Packet->Timeout == 0) {
1398 Task->InfiniteWait = TRUE;
1399 } else {
1400 Task->InfiniteWait = FALSE;
1401 }
1402
1403 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1404 InsertTailList (&Instance->NonBlockingTaskList, &Task->Link);
1405 gBS->RestoreTPL (OldTpl);
1406
1407 return EFI_SUCCESS;
1408 } else {
1410 Port,
1411 PortMultiplierPort,
1412 Packet,
1413 Instance,
1414 NULL
1415 );
1416 }
1417}
1418
1451EFIAPI
1454 IN OUT UINT16 *Port
1455 )
1456{
1458 LIST_ENTRY *Node;
1459 EFI_ATA_DEVICE_INFO *DeviceInfo;
1460
1461 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
1462
1463 if (Port == NULL) {
1464 return EFI_INVALID_PARAMETER;
1465 }
1466
1467 if (*Port == 0xFFFF) {
1468 //
1469 // If the Port is all 0xFF's, start to traverse the device list from the beginning
1470 //
1471 Node = GetFirstNode (&Instance->DeviceList);
1472
1473 while (!IsNull (&Instance->DeviceList, Node)) {
1474 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1475
1476 if (DeviceInfo->Type == EfiIdeHarddisk) {
1477 *Port = DeviceInfo->Port;
1478 goto Exit;
1479 }
1480
1481 Node = GetNextNode (&Instance->DeviceList, Node);
1482 }
1483
1484 return EFI_NOT_FOUND;
1485 } else if (*Port == Instance->PreviousPort) {
1486 Node = GetFirstNode (&Instance->DeviceList);
1487
1488 while (!IsNull (&Instance->DeviceList, Node)) {
1489 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1490
1491 if ((DeviceInfo->Type == EfiIdeHarddisk) &&
1492 (DeviceInfo->Port > *Port))
1493 {
1494 *Port = DeviceInfo->Port;
1495 goto Exit;
1496 }
1497
1498 Node = GetNextNode (&Instance->DeviceList, Node);
1499 }
1500
1501 return EFI_NOT_FOUND;
1502 } else {
1503 //
1504 // Port is not equal to 0xFFFF and also not equal to previous return value
1505 //
1506 return EFI_INVALID_PARAMETER;
1507 }
1508
1509Exit:
1510 //
1511 // Update the PreviousPort and PreviousPortMultiplier.
1512 //
1513 Instance->PreviousPort = *Port;
1514
1515 return EFI_SUCCESS;
1516}
1517
1561EFIAPI
1564 IN UINT16 Port,
1565 IN OUT UINT16 *PortMultiplierPort
1566 )
1567{
1569 LIST_ENTRY *Node;
1570 EFI_ATA_DEVICE_INFO *DeviceInfo;
1571
1572 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
1573
1574 if (PortMultiplierPort == NULL) {
1575 return EFI_INVALID_PARAMETER;
1576 }
1577
1578 if (Instance->PreviousPortMultiplier == 0xFFFF) {
1579 //
1580 // If a device is directly attached on a port, previous call to this
1581 // function will return the value 0xFFFF for PortMultiplierPort. In
1582 // this case, there should be no more device on the port multiplier.
1583 //
1584 Instance->PreviousPortMultiplier = 0;
1585 return EFI_NOT_FOUND;
1586 }
1587
1588 if (*PortMultiplierPort == Instance->PreviousPortMultiplier) {
1589 Node = GetFirstNode (&Instance->DeviceList);
1590
1591 while (!IsNull (&Instance->DeviceList, Node)) {
1592 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1593
1594 if ((DeviceInfo->Type == EfiIdeHarddisk) &&
1595 (DeviceInfo->Port == Port) &&
1596 (DeviceInfo->PortMultiplier > *PortMultiplierPort))
1597 {
1598 *PortMultiplierPort = DeviceInfo->PortMultiplier;
1599 goto Exit;
1600 }
1601
1602 Node = GetNextNode (&Instance->DeviceList, Node);
1603 }
1604
1605 return EFI_NOT_FOUND;
1606 } else if (*PortMultiplierPort == 0xFFFF) {
1607 //
1608 // If the PortMultiplierPort is all 0xFF's, start to traverse the device list from the beginning
1609 //
1610 Node = GetFirstNode (&Instance->DeviceList);
1611
1612 while (!IsNull (&Instance->DeviceList, Node)) {
1613 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
1614
1615 if ((DeviceInfo->Type == EfiIdeHarddisk) &&
1616 (DeviceInfo->Port == Port))
1617 {
1618 *PortMultiplierPort = DeviceInfo->PortMultiplier;
1619 goto Exit;
1620 }
1621
1622 Node = GetNextNode (&Instance->DeviceList, Node);
1623 }
1624
1625 return EFI_NOT_FOUND;
1626 } else {
1627 //
1628 // PortMultiplierPort is not equal to 0xFFFF and also not equal to previous return value
1629 //
1630 return EFI_INVALID_PARAMETER;
1631 }
1632
1633Exit:
1634 //
1635 // Update the PreviousPort and PreviousPortMultiplier.
1636 //
1637 Instance->PreviousPortMultiplier = *PortMultiplierPort;
1638
1639 return EFI_SUCCESS;
1640}
1641
1675EFIAPI
1678 IN UINT16 Port,
1679 IN UINT16 PortMultiplierPort,
1680 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
1681 )
1682{
1683 EFI_DEV_PATH *DevicePathNode;
1685 LIST_ENTRY *Node;
1686
1687 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
1688
1689 //
1690 // Validate parameters passed in.
1691 //
1692 if (DevicePath == NULL) {
1693 return EFI_INVALID_PARAMETER;
1694 }
1695
1696 Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);
1697 if (Node == NULL) {
1698 return EFI_NOT_FOUND;
1699 }
1700
1701 if (Instance->Mode == EfiAtaIdeMode) {
1702 DevicePathNode = AllocateCopyPool (sizeof (ATAPI_DEVICE_PATH), &mAtapiDevicePathTemplate);
1703 if (DevicePathNode == NULL) {
1704 return EFI_OUT_OF_RESOURCES;
1705 }
1706
1707 DevicePathNode->Atapi.PrimarySecondary = (UINT8)Port;
1708 DevicePathNode->Atapi.SlaveMaster = (UINT8)PortMultiplierPort;
1709 DevicePathNode->Atapi.Lun = 0;
1710 } else {
1711 DevicePathNode = AllocateCopyPool (sizeof (SATA_DEVICE_PATH), &mSataDevicePathTemplate);
1712 if (DevicePathNode == NULL) {
1713 return EFI_OUT_OF_RESOURCES;
1714 }
1715
1716 DevicePathNode->Sata.HBAPortNumber = Port;
1717 DevicePathNode->Sata.PortMultiplierPortNumber = PortMultiplierPort;
1718 DevicePathNode->Sata.Lun = 0;
1719 }
1720
1721 *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathNode;
1722
1723 return EFI_SUCCESS;
1724}
1725
1763EFIAPI
1766 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1767 OUT UINT16 *Port,
1768 OUT UINT16 *PortMultiplierPort
1769 )
1770{
1771 EFI_DEV_PATH *DevicePathNode;
1773 LIST_ENTRY *Node;
1774
1775 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
1776
1777 //
1778 // Validate parameters passed in.
1779 //
1780 if ((DevicePath == NULL) || (Port == NULL) || (PortMultiplierPort == NULL)) {
1781 return EFI_INVALID_PARAMETER;
1782 }
1783
1784 //
1785 // Check whether the DevicePath belongs to SCSI_DEVICE_PATH or ATAPI_DEVICE_PATH
1786 //
1787 if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
1788 ((DevicePath->SubType != MSG_SATA_DP) &&
1789 (DevicePath->SubType != MSG_ATAPI_DP)) ||
1790 ((DevicePathNodeLength (DevicePath) != sizeof (ATAPI_DEVICE_PATH)) &&
1791 (DevicePathNodeLength (DevicePath) != sizeof (SATA_DEVICE_PATH))))
1792 {
1793 return EFI_UNSUPPORTED;
1794 }
1795
1796 DevicePathNode = (EFI_DEV_PATH *)DevicePath;
1797
1798 if (Instance->Mode == EfiAtaIdeMode) {
1799 *Port = DevicePathNode->Atapi.PrimarySecondary;
1800 *PortMultiplierPort = DevicePathNode->Atapi.SlaveMaster;
1801 } else {
1802 *Port = DevicePathNode->Sata.HBAPortNumber;
1803 *PortMultiplierPort = DevicePathNode->Sata.PortMultiplierPortNumber;
1804 }
1805
1806 Node = SearchDeviceInfoList (Instance, *Port, *PortMultiplierPort, EfiIdeHarddisk);
1807
1808 if (Node == NULL) {
1809 return EFI_NOT_FOUND;
1810 }
1811
1812 return EFI_SUCCESS;
1813}
1814
1840EFIAPI
1843 IN UINT16 Port
1844 )
1845{
1846 //
1847 // Return success directly then upper layer driver could think reset port operation is done.
1848 //
1849 return EFI_SUCCESS;
1850}
1851
1884EFIAPI
1887 IN UINT16 Port,
1888 IN UINT16 PortMultiplierPort
1889 )
1890{
1892 LIST_ENTRY *Node;
1893
1894 Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
1895
1896 Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);
1897
1898 if (Node == NULL) {
1899 return EFI_INVALID_PARAMETER;
1900 }
1901
1902 //
1903 // Return success directly then upper layer driver could think reset device operation is done.
1904 //
1905 return EFI_SUCCESS;
1906}
1907
1927EFIAPI
1930 IN UINT8 *Target,
1931 IN UINT64 Lun,
1932 IN VOID *SenseData,
1933 IN UINT8 SenseDataLength,
1934 IN UINT64 Timeout
1935 )
1936{
1938 UINT8 Cdb[12];
1939 EFI_STATUS Status;
1940
1942 ZeroMem (Cdb, 12);
1943
1944 Cdb[0] = ATA_CMD_REQUEST_SENSE;
1945 Cdb[4] = SenseDataLength;
1946
1947 Packet.Timeout = Timeout;
1948 Packet.Cdb = Cdb;
1949 Packet.CdbLength = 12;
1950 Packet.DataDirection = EFI_EXT_SCSI_DATA_DIRECTION_READ;
1951 Packet.InDataBuffer = SenseData;
1952 Packet.InTransferLength = SenseDataLength;
1953
1954 Status = ExtScsiPassThruPassThru (This, Target, Lun, &Packet, NULL);
1955
1956 return Status;
1957}
1958
2001EFIAPI
2004 IN UINT8 *Target,
2005 IN UINT64 Lun,
2007 IN EFI_EVENT Event OPTIONAL
2008 )
2009{
2010 EFI_STATUS Status;
2012 UINT8 Port;
2013 UINT8 PortMultiplier;
2014 EFI_ATA_HC_WORK_MODE Mode;
2015 LIST_ENTRY *Node;
2016 EFI_ATA_DEVICE_INFO *DeviceInfo;
2017 BOOLEAN SenseReq;
2018 EFI_SCSI_SENSE_DATA *PtrSenseData;
2019 UINTN SenseDataLen;
2020 EFI_STATUS SenseStatus;
2021
2022 SenseDataLen = 0;
2023 Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
2024
2025 if ((Packet == NULL) || (Packet->Cdb == NULL)) {
2026 return EFI_INVALID_PARAMETER;
2027 }
2028
2029 //
2030 // Don't support variable length CDB
2031 //
2032 if ((Packet->CdbLength != 6) && (Packet->CdbLength != 10) &&
2033 (Packet->CdbLength != 12) && (Packet->CdbLength != 16))
2034 {
2035 return EFI_INVALID_PARAMETER;
2036 }
2037
2038 if ((Packet->SenseDataLength != 0) && (Packet->SenseData == NULL)) {
2039 return EFI_INVALID_PARAMETER;
2040 }
2041
2042 if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
2043 return EFI_INVALID_PARAMETER;
2044 }
2045
2046 if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
2047 return EFI_INVALID_PARAMETER;
2048 }
2049
2050 if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->SenseData, This->Mode->IoAlign)) {
2051 return EFI_INVALID_PARAMETER;
2052 }
2053
2054 //
2055 // For ATAPI device, doesn't support multiple LUN device.
2056 //
2057 if (Lun != 0) {
2058 return EFI_INVALID_PARAMETER;
2059 }
2060
2061 //
2062 // The layout of Target array:
2063 // ________________________________________________________________________
2064 // | Byte 0 | Byte 1 | ... | TARGET_MAX_BYTES - 1 |
2065 // |_____________________|_____________________|_____|______________________|
2066 // | | The port multiplier | | |
2067 // | The port number | port number | N/A | N/A |
2068 // |_____________________|_____________________|_____|______________________|
2069 //
2070 // For ATAPI device, 2 bytes is enough to represent the location of SCSI device.
2071 //
2072 Port = Target[0];
2073 PortMultiplier = Target[1];
2074
2075 Node = SearchDeviceInfoList (Instance, Port, PortMultiplier, EfiIdeCdrom);
2076 if (Node == NULL) {
2077 return EFI_INVALID_PARAMETER;
2078 }
2079
2080 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
2081
2082 //
2083 // ATA_CMD_IDENTIFY_DEVICE cmd is a ATA cmd but not a SCSI cmd.
2084 // Normally it should NOT be passed down through ExtScsiPassThru protocol interface.
2085 // But to response EFI_DISK_INFO.Identify() request from ScsiDisk, we should handle this command.
2086 //
2087 if (*((UINT8 *)Packet->Cdb) == ATA_CMD_IDENTIFY_DEVICE) {
2088 CopyMem (Packet->InDataBuffer, DeviceInfo->IdentifyData, sizeof (EFI_IDENTIFY_DATA));
2089 //
2090 // For IDENTIFY DEVICE cmd, we don't need to get sense data.
2091 //
2092 Packet->SenseDataLength = 0;
2093 return EFI_SUCCESS;
2094 }
2095
2096 Mode = Instance->Mode;
2097 switch (Mode) {
2098 case EfiAtaIdeMode:
2099 //
2100 // Reassign IDE mode io port registers' base addresses
2101 //
2102 Status = GetIdeRegisterIoAddr (Instance->PciIo, Instance->IdeRegisters);
2103
2104 if (EFI_ERROR (Status)) {
2105 return Status;
2106 }
2107
2108 Status = AtaPacketCommandExecute (Instance->PciIo, &Instance->IdeRegisters[Port], Port, PortMultiplier, Packet);
2109 break;
2110 case EfiAtaAhciMode:
2111 if (PortMultiplier == 0xFF) {
2112 //
2113 // If there is no port multiplier, the PortMultiplier will be 0xFF
2114 // Here, we convert its value to 0 to follow the AHCI spec.
2115 //
2116 PortMultiplier = 0;
2117 }
2118
2119 Status = AhciPacketCommandExecute (Instance->PciIo, &Instance->AhciRegisters, Port, PortMultiplier, Packet);
2120 break;
2121 default:
2122 Status = EFI_DEVICE_ERROR;
2123 break;
2124 }
2125
2126 //
2127 // If the cmd doesn't get executed correctly, then check sense data.
2128 //
2129 if (EFI_ERROR (Status) && (Packet->SenseDataLength != 0) && (*((UINT8 *)Packet->Cdb) != ATA_CMD_REQUEST_SENSE)) {
2130 PtrSenseData = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof (EFI_SCSI_SENSE_DATA)), This->Mode->IoAlign);
2131 if (PtrSenseData == NULL) {
2132 return EFI_DEVICE_ERROR;
2133 }
2134
2135 for (SenseReq = TRUE; SenseReq;) {
2136 SenseStatus = AtaPacketRequestSense (
2137 This,
2138 Target,
2139 Lun,
2140 PtrSenseData,
2141 sizeof (EFI_SCSI_SENSE_DATA),
2142 Packet->Timeout
2143 );
2144 if (EFI_ERROR (SenseStatus)) {
2145 break;
2146 }
2147
2148 CopyMem ((UINT8 *)Packet->SenseData + SenseDataLen, PtrSenseData, sizeof (EFI_SCSI_SENSE_DATA));
2149 SenseDataLen += sizeof (EFI_SCSI_SENSE_DATA);
2150
2151 //
2152 // no more sense key or number of sense keys exceeds predefined,
2153 // skip the loop.
2154 //
2155 if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||
2156 (SenseDataLen + sizeof (EFI_SCSI_SENSE_DATA) > Packet->SenseDataLength))
2157 {
2158 SenseReq = FALSE;
2159 }
2160 }
2161
2162 FreeAlignedPages (PtrSenseData, EFI_SIZE_TO_PAGES (sizeof (EFI_SCSI_SENSE_DATA)));
2163 }
2164
2165 //
2166 // Update the SenseDataLength field to the data length received.
2167 //
2168 Packet->SenseDataLength = (UINT8)SenseDataLen;
2169 return Status;
2170}
2171
2199EFIAPI
2202 IN OUT UINT8 **Target,
2203 IN OUT UINT64 *Lun
2204 )
2205{
2207 LIST_ENTRY *Node;
2208 EFI_ATA_DEVICE_INFO *DeviceInfo;
2209 UINT8 *Target8;
2210 UINT16 *Target16;
2211
2212 Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
2213
2214 if ((Target == NULL) || (Lun == NULL)) {
2215 return EFI_INVALID_PARAMETER;
2216 }
2217
2218 if (*Target == NULL) {
2219 return EFI_INVALID_PARAMETER;
2220 }
2221
2222 Target8 = *Target;
2223 Target16 = (UINT16 *)*Target;
2224
2225 if (CompareMem (Target8, mScsiId, TARGET_MAX_BYTES) != 0) {
2226 //
2227 // For ATAPI device, we use 2 least significant bytes to represent the location of SCSI device.
2228 // So the higher bytes in Target array should be 0xFF.
2229 //
2230 if (CompareMem (&Target8[2], &mScsiId[2], TARGET_MAX_BYTES - 2) != 0) {
2231 return EFI_INVALID_PARAMETER;
2232 }
2233
2234 //
2235 // When Target is not all 0xFF's, compare 2 least significant bytes with
2236 // previous target id to see if it is returned by previous call.
2237 //
2238 if ((*Target16 != Instance->PreviousTargetId) ||
2239 (*Lun != Instance->PreviousLun))
2240 {
2241 return EFI_INVALID_PARAMETER;
2242 }
2243
2244 //
2245 // Traverse the whole device list to find the next cdrom closed to
2246 // the device signified by Target[0] and Target[1].
2247 //
2248 // Note that we here use a tricky way to find the next cdrom :
2249 // All ata devices are detected and inserted into the device list
2250 // sequentially.
2251 //
2252 Node = GetFirstNode (&Instance->DeviceList);
2253
2254 while (!IsNull (&Instance->DeviceList, Node)) {
2255 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
2256
2257 if ((DeviceInfo->Type == EfiIdeCdrom) &&
2258 ((Target8[0] < DeviceInfo->Port) ||
2259 ((Target8[0] == DeviceInfo->Port) &&
2260 (Target8[1] < (UINT8)DeviceInfo->PortMultiplier))))
2261 {
2262 Target8[0] = (UINT8)DeviceInfo->Port;
2263 Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
2264 goto Exit;
2265 }
2266
2267 Node = GetNextNode (&Instance->DeviceList, Node);
2268 }
2269
2270 return EFI_NOT_FOUND;
2271 } else {
2272 //
2273 // If the array is all 0xFF's, start to traverse the device list from the beginning
2274 //
2275 Node = GetFirstNode (&Instance->DeviceList);
2276 while (!IsNull (&Instance->DeviceList, Node)) {
2277 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
2278
2279 if (DeviceInfo->Type == EfiIdeCdrom) {
2280 Target8[0] = (UINT8)DeviceInfo->Port;
2281 Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
2282 goto Exit;
2283 }
2284
2285 Node = GetNextNode (&Instance->DeviceList, Node);
2286 }
2287
2288 return EFI_NOT_FOUND;
2289 }
2290
2291Exit:
2292 *Lun = 0;
2293
2294 //
2295 // Update the PreviousTargetId.
2296 //
2297 Instance->PreviousTargetId = *Target16;
2298 Instance->PreviousLun = *Lun;
2299
2300 return EFI_SUCCESS;
2301}
2302
2331EFIAPI
2334 IN UINT8 *Target,
2335 IN UINT64 Lun,
2336 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
2337 )
2338{
2339 EFI_DEV_PATH *DevicePathNode;
2341 UINT8 Port;
2342 UINT8 PortMultiplier;
2343
2344 Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
2345
2346 Port = Target[0];
2347 PortMultiplier = Target[1];
2348
2349 //
2350 // Validate parameters passed in.
2351 //
2352 if (DevicePath == NULL) {
2353 return EFI_INVALID_PARAMETER;
2354 }
2355
2356 //
2357 // can not build device path for the SCSI Host Controller.
2358 //
2359 if (Lun != 0) {
2360 return EFI_NOT_FOUND;
2361 }
2362
2363 if (SearchDeviceInfoList (Instance, Port, PortMultiplier, EfiIdeCdrom) == NULL) {
2364 return EFI_NOT_FOUND;
2365 }
2366
2367 if (Instance->Mode == EfiAtaIdeMode) {
2368 DevicePathNode = AllocateCopyPool (sizeof (ATAPI_DEVICE_PATH), &mAtapiDevicePathTemplate);
2369 if (DevicePathNode == NULL) {
2370 return EFI_OUT_OF_RESOURCES;
2371 }
2372
2373 DevicePathNode->Atapi.PrimarySecondary = Port;
2374 DevicePathNode->Atapi.SlaveMaster = PortMultiplier;
2375 DevicePathNode->Atapi.Lun = (UINT16)Lun;
2376 } else {
2377 DevicePathNode = AllocateCopyPool (sizeof (SATA_DEVICE_PATH), &mSataDevicePathTemplate);
2378 if (DevicePathNode == NULL) {
2379 return EFI_OUT_OF_RESOURCES;
2380 }
2381
2382 DevicePathNode->Sata.HBAPortNumber = Port;
2383 //
2384 // For CD-ROM working in the AHCI mode, only 8 bits are used to record
2385 // the PortMultiplier information. If the CD-ROM is directly attached
2386 // on a SATA port, the PortMultiplier should be translated from 0xFF
2387 // to 0xFFFF according to the UEFI spec.
2388 //
2389 DevicePathNode->Sata.PortMultiplierPortNumber = PortMultiplier == 0xFF ? 0xFFFF : PortMultiplier;
2390 DevicePathNode->Sata.Lun = (UINT16)Lun;
2391 }
2392
2393 *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathNode;
2394
2395 return EFI_SUCCESS;
2396}
2397
2418EFIAPI
2421 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
2422 OUT UINT8 **Target,
2423 OUT UINT64 *Lun
2424 )
2425{
2426 EFI_DEV_PATH *DevicePathNode;
2428 LIST_ENTRY *Node;
2429
2430 Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
2431
2432 //
2433 // Validate parameters passed in.
2434 //
2435 if ((DevicePath == NULL) || (Target == NULL) || (Lun == NULL)) {
2436 return EFI_INVALID_PARAMETER;
2437 }
2438
2439 if (*Target == NULL) {
2440 return EFI_INVALID_PARAMETER;
2441 }
2442
2443 //
2444 // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
2445 //
2446 if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
2447 ((DevicePath->SubType != MSG_ATAPI_DP) &&
2448 (DevicePath->SubType != MSG_SATA_DP)) ||
2449 ((DevicePathNodeLength (DevicePath) != sizeof (ATAPI_DEVICE_PATH)) &&
2450 (DevicePathNodeLength (DevicePath) != sizeof (SATA_DEVICE_PATH))))
2451 {
2452 return EFI_UNSUPPORTED;
2453 }
2454
2455 SetMem (*Target, TARGET_MAX_BYTES, 0xFF);
2456
2457 DevicePathNode = (EFI_DEV_PATH *)DevicePath;
2458
2459 if (Instance->Mode == EfiAtaIdeMode) {
2460 (*Target)[0] = (UINT8)DevicePathNode->Atapi.PrimarySecondary;
2461 (*Target)[1] = (UINT8)DevicePathNode->Atapi.SlaveMaster;
2462 *Lun = (UINT8)DevicePathNode->Atapi.Lun;
2463 } else {
2464 (*Target)[0] = (UINT8)DevicePathNode->Sata.HBAPortNumber;
2465 (*Target)[1] = (UINT8)DevicePathNode->Sata.PortMultiplierPortNumber;
2466 *Lun = (UINT8)DevicePathNode->Sata.Lun;
2467 }
2468
2469 Node = SearchDeviceInfoList (Instance, (*Target)[0], (*Target)[1], EfiIdeCdrom);
2470
2471 if (Node == NULL) {
2472 return EFI_NOT_FOUND;
2473 }
2474
2475 if (*Lun != 0) {
2476 return EFI_NOT_FOUND;
2477 }
2478
2479 return EFI_SUCCESS;
2480}
2481
2494EFIAPI
2497 )
2498{
2499 //
2500 // Return success directly then upper layer driver could think reset channel operation is done.
2501 //
2502 return EFI_SUCCESS;
2503}
2504
2525EFIAPI
2528 IN UINT8 *Target,
2529 IN UINT64 Lun
2530 )
2531{
2533 LIST_ENTRY *Node;
2534 UINT8 Port;
2535 UINT8 PortMultiplier;
2536
2537 Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
2538 //
2539 // For ATAPI device, doesn't support multiple LUN device.
2540 //
2541 if (Lun != 0) {
2542 return EFI_INVALID_PARAMETER;
2543 }
2544
2545 //
2546 // The layout of Target array:
2547 // ________________________________________________________________________
2548 // | Byte 0 | Byte 1 | ... | TARGET_MAX_BYTES - 1 |
2549 // |_____________________|_____________________|_____|______________________|
2550 // | | The port multiplier | | |
2551 // | The port number | port number | N/A | N/A |
2552 // |_____________________|_____________________|_____|______________________|
2553 //
2554 // For ATAPI device, 2 bytes is enough to represent the location of SCSI device.
2555 //
2556 Port = Target[0];
2557 PortMultiplier = Target[1];
2558
2559 Node = SearchDeviceInfoList (Instance, Port, PortMultiplier, EfiIdeCdrom);
2560 if (Node == NULL) {
2561 return EFI_INVALID_PARAMETER;
2562 }
2563
2564 //
2565 // Return success directly then upper layer driver could think reset target LUN operation is done.
2566 //
2567 return EFI_SUCCESS;
2568}
2569
2593EFIAPI
2596 IN OUT UINT8 **Target
2597 )
2598{
2600 LIST_ENTRY *Node;
2601 EFI_ATA_DEVICE_INFO *DeviceInfo;
2602 UINT8 *Target8;
2603 UINT16 *Target16;
2604
2605 Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
2606
2607 if ((Target == NULL) || (*Target == NULL)) {
2608 return EFI_INVALID_PARAMETER;
2609 }
2610
2611 Target8 = *Target;
2612 Target16 = (UINT16 *)*Target;
2613
2614 if (CompareMem (Target8, mScsiId, TARGET_MAX_BYTES) != 0) {
2615 //
2616 // For ATAPI device, we use 2 least significant bytes to represent the location of SCSI device.
2617 // So the higher bytes in Target array should be 0xFF.
2618 //
2619 if (CompareMem (&Target8[2], &mScsiId[2], TARGET_MAX_BYTES - 2) != 0) {
2620 return EFI_INVALID_PARAMETER;
2621 }
2622
2623 //
2624 // When Target is not all 0xFF's, compare 2 least significant bytes with
2625 // previous target id to see if it is returned by previous call.
2626 //
2627 if (*Target16 != Instance->PreviousTargetId) {
2628 return EFI_INVALID_PARAMETER;
2629 }
2630
2631 //
2632 // Traverse the whole device list to find the next cdrom closed to
2633 // the device signified by Target[0] and Target[1].
2634 //
2635 // Note that we here use a tricky way to find the next cdrom :
2636 // All ata devices are detected and inserted into the device list
2637 // sequentially.
2638 //
2639 Node = GetFirstNode (&Instance->DeviceList);
2640 while (!IsNull (&Instance->DeviceList, Node)) {
2641 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
2642
2643 if ((DeviceInfo->Type == EfiIdeCdrom) &&
2644 ((Target8[0] < DeviceInfo->Port) ||
2645 ((Target8[0] == DeviceInfo->Port) &&
2646 (Target8[1] < (UINT8)DeviceInfo->PortMultiplier))))
2647 {
2648 Target8[0] = (UINT8)DeviceInfo->Port;
2649 Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
2650 goto Exit;
2651 }
2652
2653 Node = GetNextNode (&Instance->DeviceList, Node);
2654 }
2655
2656 return EFI_NOT_FOUND;
2657 } else {
2658 //
2659 // If the array is all 0xFF's, start to traverse the device list from the beginning
2660 //
2661 Node = GetFirstNode (&Instance->DeviceList);
2662
2663 while (!IsNull (&Instance->DeviceList, Node)) {
2664 DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
2665
2666 if (DeviceInfo->Type == EfiIdeCdrom) {
2667 Target8[0] = (UINT8)DeviceInfo->Port;
2668 Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
2669 goto Exit;
2670 }
2671
2672 Node = GetNextNode (&Instance->DeviceList, Node);
2673 }
2674
2675 return EFI_NOT_FOUND;
2676 }
2677
2678Exit:
2679 //
2680 // Update the PreviousTargetId.
2681 //
2682 Instance->PreviousTargetId = *Target16;
2683
2684 return EFI_SUCCESS;
2685}
UINT64 UINTN
EFI_STATUS AhciModeInitialization(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private)
Definition: AhciMode.c:1664
EFI_STATUS AhciNonDataTransfer(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout)
Definition: AhciMode.c:981
EFI_STATUS AhciPioTransfer(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN BOOLEAN Read, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN OUT VOID *MemoryAddr, IN UINT32 DataCount, IN UINT64 Timeout)
Definition: AhciMode.c:717
EFI_STATUS EFIAPI AhciPacketCommandExecute(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_AHCI_REGISTERS *AhciRegisters, IN UINT8 Port, IN UINT8 PortMultiplier, IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
Definition: AhciMode.c:2126
EFI_STATUS EFIAPI AhciDmaTransfer(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN EFI_AHCI_REGISTERS *AhciRegisters, IN UINT8 Port, IN UINT8 PortMultiplier, IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, IN UINT8 AtapiCommandLength, IN BOOLEAN Read, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN OUT VOID *MemoryAddr, IN UINT32 DataCount, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: AhciMode.c:1158
EFI_STATUS EFIAPI AtaPacketRequestSense(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN VOID *SenseData, IN UINT8 SenseDataLength, IN UINT64 Timeout)
VOID EFIAPI AsyncNonBlockingTransferRoutine(EFI_EVENT Event, VOID *Context)
EFI_STATUS EFIAPI ExtScsiPassThruGetTargetLun(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT8 **Target, OUT UINT64 *Lun)
EFI_STATUS EFIAPI AtaAtapiPassThruSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI ExtScsiPassThruResetTargetLun(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun)
EFI_STATUS EFIAPI ExtScsiPassThruBuildDevicePath(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath)
EFI_STATUS EFIAPI ExtScsiPassThruGetNextTargetLun(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN OUT UINT8 **Target, IN OUT UINT64 *Lun)
EFI_STATUS EFIAPI AtaPassThruPassThruExecute(IN UINT16 Port, IN UINT16 PortMultiplierPort, IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet, IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN ATA_NONBLOCK_TASK *Task OPTIONAL)
EFI_STATUS EFIAPI AtaPassThruGetNextDevice(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN OUT UINT16 *PortMultiplierPort)
EFI_STATUS EFIAPI AtaPassThruPassThru(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet, IN EFI_EVENT Event OPTIONAL)
EFI_STATUS EFIAPI AtaAtapiPassThruStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI AtaPassThruResetPort(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port)
EFI_STATUS EFIAPI ExtScsiPassThruResetChannel(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This)
VOID EFIAPI DestroyDeviceInfoList(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance)
EFI_STATUS EFIAPI EnumerateAttachedDevice(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance)
VOID EFIAPI DestroyAsynTaskList(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN BOOLEAN IsSigEvent)
EFI_STATUS EFIAPI ExtScsiPassThruGetNextTarget(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN OUT UINT8 **Target)
EFI_STATUS EFIAPI AtaPassThruBuildDevicePath(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath)
EFI_STATUS EFIAPI AtaPassThruGetNextPort(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN OUT UINT16 *Port)
EFI_STATUS EFIAPI InitializeAtaAtapiPassThru(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI CreateNewDeviceInfo(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT16 Port, IN UINT16 PortMultiplier, IN EFI_ATA_DEVICE_TYPE DeviceType, IN EFI_IDENTIFY_DATA *IdentifyData)
EFI_STATUS EFIAPI AtaAtapiPassThruStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
EFI_STATUS EFIAPI AtaPassThruGetDevice(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT16 *Port, OUT UINT16 *PortMultiplierPort)
EFI_STATUS EFIAPI AtaPassThruResetDevice(IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN UINT16 PortMultiplierPort)
LIST_ENTRY *EFIAPI SearchDeviceInfoList(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT16 Port, IN UINT16 PortMultiplier, IN EFI_ATA_DEVICE_TYPE DeviceType)
EFI_STATUS EFIAPI ExtScsiPassThruPassThru(IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL)
EFI_STATUS EFIAPI AtaPioDataInOut(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT VOID *Buffer, IN UINT64 ByteCount, IN BOOLEAN Read, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: IdeMode.c:934
EFI_STATUS EFIAPI AtaNonDataCommandIn(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: IdeMode.c:1069
EFI_STATUS EFIAPI AtaUdmaInOut(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN EFI_IDE_REGISTERS *IdeRegisters, IN BOOLEAN Read, IN VOID *DataBuffer, IN UINT64 DataLength, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
Definition: IdeMode.c:1263
EFI_STATUS EFIAPI IdeModeInitialization(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance)
Definition: IdeMode.c:2601
#define ATA_CMD_REQUEST_SENSE
defined from ATA-4
Definition: Atapi.h:491
#define ATA_CMD_IDENTIFY_DEVICE
defined from ATA-3
Definition: Atapi.h:488
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
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)
Definition: SetMemWrapper.c:38
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MSG_ATAPI_DP
Definition: DevicePath.h:326
#define MSG_SATA_DP
Definition: DevicePath.h:510
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI FreeAlignedPages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI GetIdeRegisterIoAddr(IN EFI_PCI_IO_PROTOCOL *PciIo, IN OUT EFI_IDE_REGISTERS *IdeRegisters)
Definition: IdeMode.c:728
EFI_STATUS EFIAPI AtaPacketCommandExecute(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT8 Channel, IN UINT8 Device, IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
Definition: IdeMode.c:1806
#define NULL
Definition: Base.h:319
#define ADDRESS_IS_ALIGNED(Address, Alignment)
Definition: Base.h:923
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_ATA_PASS_THRU_ATTRIBUTES_NONBLOCKIO
Definition: AtaPassThru.h:44
#define EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
Definition: AtaPassThru.h:33
#define EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
Definition: AtaPassThru.h:38
@ EfiPciIoAttributeOperationDisable
Definition: PciIo.h:115
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoAttributeOperationSet
Definition: PciIo.h:107
@ EfiPciIoAttributeOperationSupported
Definition: PciIo.h:119
#define IS_PCI_IDE(_p)
Definition: Pci22.h:404
#define IS_PCI_SATADPA(_p)
Definition: Pci30.h:40
#define PCI_CLASS_MASS_STORAGE_SATADPA
Definition: Pci30.h:18
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
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)
@ TimerPeriodic
Definition: UefiSpec.h:535
EFI_EXT_SCSI_PASS_THRU_MODE * Mode
UINT16 maximum_lba_for_48bit_addressing[4]
word 100~103
Definition: Atapi.h:136
UINT16 command_set_supported_83
word 83
Definition: Atapi.h:120
UINT16 logic_sector_size_lo
word 117
Definition: Atapi.h:144
UINT16 phy_logic_sector_support
word 106
Definition: Atapi.h:139
UINT16 logic_sector_size_hi
word 118
Definition: Atapi.h:145
UINT8 PrimarySecondary
Definition: DevicePath.h:332
EFI_ATA_STATUS_BLOCK * Asb
Definition: AtaPassThru.h:114
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232
UINT16 PortMultiplierPortNumber
Definition: DevicePath.h:523
UINT16 HBAPortNumber
Definition: DevicePath.h:517
EFI_ATA_IDENTIFY_DATA AtaData