2 Copyright (c) 2006, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 Module Name: AtapiPassThru.h
22 #include <Protocol/ScsiPassThru.h>
23 #include <Protocol/PciIo.h>
25 #include <Library/DebugLib.h>
26 #include <Library/UefiDriverEntryPoint.h>
27 #include <Library/BaseLib.h>
28 #include <Library/UefiLib.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/MemoryAllocationLib.h>
31 #include <Library/UefiBootServicesTableLib.h>
32 #include <IndustryStandard/pci22.h>
37 #define bit(a) (1 << (a))
39 #define MAX_TARGET_ID 4
45 UINT16 Command
; /* when write */
46 UINT16 Status
; /* when read */
50 UINT16 Error
; /* when read */
51 UINT16 Feature
; /* when write */
52 } IDE_ERROR_OR_FEATURE
;
55 UINT16 AltStatus
; /* when read */
56 UINT16 DeviceControl
; /* when write */
57 } IDE_AltStatus_OR_DeviceControl
;
70 // Bit definitions in Programming Interface byte of the Class Code field
71 // in PCI IDE controller's Configuration Space
73 #define IDE_PRIMARY_OPERATING_MODE BIT0
74 #define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1
75 #define IDE_SECONDARY_OPERATING_MODE BIT2
76 #define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3
79 #define ATAPI_MAX_CHANNEL 2
86 IDE_ERROR_OR_FEATURE Reg1
;
92 IDE_CMD_OR_STATUS Reg
;
93 IDE_AltStatus_OR_DeviceControl Alt
;
97 #define ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE EFI_SIGNATURE_32 ('a', 's', 'p', 't')
102 EFI_SCSI_PASS_THRU_PROTOCOL ScsiPassThru
;
103 EFI_SCSI_PASS_THRU_MODE ScsiPassThruMode
;
104 EFI_PCI_IO_PROTOCOL
*PciIo
;
105 UINT64 OriginalPciAttributes
;
107 // Local Data goes here
109 IDE_BASE_REGISTERS
*IoPort
;
110 IDE_BASE_REGISTERS AtapiIoPortRegisters
[2];
111 CHAR16 ControllerName
[100];
112 CHAR16 ChannelName
[100];
113 UINT32 LatestTargetId
;
115 } ATAPI_SCSI_PASS_THRU_DEV
;
118 // IDE registers' base addresses
121 UINT16 CommandBlockBaseAddr
;
122 UINT16 ControlBlockBaseAddr
;
123 } IDE_REGISTERS_BASE_ADDR
;
125 #define ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
127 ATAPI_SCSI_PASS_THRU_DEV, \
129 ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
135 extern EFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding
;
136 extern EFI_COMPONENT_NAME_PROTOCOL gAtapiScsiPassThruComponentName
;
137 extern EFI_COMPONENT_NAME2_PROTOCOL gAtapiScsiPassThruComponentName2
;
140 // ATAPI Command op code
142 #define OP_INQUIRY 0x12
143 #define OP_LOAD_UNLOAD_CD 0xa6
144 #define OP_MECHANISM_STATUS 0xbd
145 #define OP_MODE_SELECT_10 0x55
146 #define OP_MODE_SENSE_10 0x5a
147 #define OP_PAUSE_RESUME 0x4b
148 #define OP_PLAY_AUDIO_10 0x45
149 #define OP_PLAY_AUDIO_MSF 0x47
150 #define OP_PLAY_CD 0xbc
151 #define OP_PLAY_CD_MSF 0xb4
152 #define OP_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
153 #define OP_READ_10 0x28
154 #define OP_READ_12 0xa8
155 #define OP_READ_CAPACITY 0x25
156 #define OP_READ_CD 0xbe
157 #define OP_READ_CD_MSF 0xb9
158 #define OP_READ_HEADER 0x44
159 #define OP_READ_SUB_CHANNEL 0x42
160 #define OP_READ_TOC 0x43
161 #define OP_REQUEST_SENSE 0x03
163 #define OP_SEEK_10 0x2b
164 #define OP_SET_CD_SPEED 0xbb
165 #define OP_STOPPLAY_SCAN 0x4e
166 #define OP_START_STOP_UNIT 0x1b
167 #define OP_TEST_UNIT_READY 0x00
169 #define OP_FORMAT_UNIT 0x04
170 #define OP_READ_FORMAT_CAPACITIES 0x23
171 #define OP_VERIFY 0x2f
172 #define OP_WRITE_10 0x2a
173 #define OP_WRITE_12 0xaa
174 #define OP_WRITE_AND_VERIFY 0x2e
179 #define ATAPI_SOFT_RESET_CMD 0x08
190 DATA_DIRECTION Direction
;
193 #define MAX_CHANNEL 2
195 #define ValidCdbLength(Len) ((Len) == 6 || (Len) == 10 || (Len) == 12) ? 1 : 0
198 // IDE registers bit definitions
200 // ATA Err Reg bitmap
202 #define BBK_ERR bit (7) ///< Bad block detected
203 #define UNC_ERR bit (6) ///< Uncorrectable Data
204 #define MC_ERR bit (5) ///< Media Change
205 #define IDNF_ERR bit (4) ///< ID Not Found
206 #define MCR_ERR bit (3) ///< Media Change Requested
207 #define ABRT_ERR bit (2) ///< Aborted Command
208 #define TK0NF_ERR bit (1) ///< Track 0 Not Found
209 #define AMNF_ERR bit (0) ///< Address Mark Not Found
212 // ATAPI Err Reg bitmap
214 #define SENSE_KEY_ERR (bit (7) | bit (6) | bit (5) | bit (4))
215 #define EOM_ERR bit (1) ///< End of Media Detected
216 #define ILI_ERR bit (0) ///< Illegal Length Indication
221 #define LBA_MODE bit (6)
236 #define BSY bit (7) ///< Controller Busy
237 #define DRDY bit (6) ///< Drive Ready
238 #define DWF bit (5) ///< Drive Write Fault
239 #define DSC bit (4) ///< Disk Seek Complete
240 #define DRQ bit (3) ///< Data Request
241 #define CORR bit (2) ///< Corrected Data
242 #define IDX bit (1) ///< Index
243 #define ERR bit (0) ///< Error
244 #define CHECK bit (0) ///< Check bit for ATAPI Status Reg
247 // Device Control Reg
249 #define SRST bit (2) ///< Software Reset
250 #define IEN_L bit (1) ///< Interrupt Enable
253 // ATAPI Feature Register
255 #define OVERLAP bit (1)
259 // ATAPI Interrupt Reason Reson Reg (ATA Sector Count Register)
261 #define RELEASE bit (2)
265 #define PACKET_CMD 0xA0
267 #define DEFAULT_CMD (0xa0)
269 // default content of device control register, disable INT
271 #define DEFAULT_CTL (0x0a)
272 #define MAX_ATAPI_BYTE_COUNT (0xfffe)
275 // function prototype
280 AtapiScsiPassThruDriverBindingSupported (
281 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
282 IN EFI_HANDLE Controller
,
283 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
288 AtapiScsiPassThruDriverBindingStart (
289 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
290 IN EFI_HANDLE Controller
,
291 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
296 AtapiScsiPassThruDriverBindingStop (
297 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
298 IN EFI_HANDLE Controller
,
299 IN UINTN NumberOfChildren
,
300 IN EFI_HANDLE
*ChildHandleBuffer
304 // EFI Component Name Functions
307 Retrieves a Unicode string that is the user readable name of the driver.
309 This function retrieves the user readable name of a driver in the form of a
310 Unicode string. If the driver specified by This has a user readable name in
311 the language specified by Language, then a pointer to the driver name is
312 returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
313 by This does not support the language specified by Language,
314 then EFI_UNSUPPORTED is returned.
316 @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
317 EFI_COMPONENT_NAME_PROTOCOL instance.
319 @param Language[in] A pointer to a Null-terminated ASCII string
320 array indicating the language. This is the
321 language of the driver name that the caller is
322 requesting, and it must match one of the
323 languages specified in SupportedLanguages. The
324 number of languages supported by a driver is up
325 to the driver writer. Language is specified
326 in RFC 3066 or ISO 639-2 language code format.
328 @param DriverName[out] A pointer to the Unicode string to return.
329 This Unicode string is the name of the
330 driver specified by This in the language
331 specified by Language.
333 @retval EFI_SUCCESS The Unicode string for the Driver specified by
334 This and the language specified by Language was
335 returned in DriverName.
337 @retval EFI_INVALID_PARAMETER Language is NULL.
339 @retval EFI_INVALID_PARAMETER DriverName is NULL.
341 @retval EFI_UNSUPPORTED The driver specified by This does not support
342 the language specified by Language.
347 AtapiScsiPassThruComponentNameGetDriverName (
348 IN EFI_COMPONENT_NAME_PROTOCOL
*This
,
350 OUT CHAR16
**DriverName
355 Retrieves a Unicode string that is the user readable name of the controller
356 that is being managed by a driver.
358 This function retrieves the user readable name of the controller specified by
359 ControllerHandle and ChildHandle in the form of a Unicode string. If the
360 driver specified by This has a user readable name in the language specified by
361 Language, then a pointer to the controller name is returned in ControllerName,
362 and EFI_SUCCESS is returned. If the driver specified by This is not currently
363 managing the controller specified by ControllerHandle and ChildHandle,
364 then EFI_UNSUPPORTED is returned. If the driver specified by This does not
365 support the language specified by Language, then EFI_UNSUPPORTED is returned.
367 @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
368 EFI_COMPONENT_NAME_PROTOCOL instance.
370 @param ControllerHandle[in] The handle of a controller that the driver
371 specified by This is managing. This handle
372 specifies the controller whose name is to be
375 @param ChildHandle[in] The handle of the child controller to retrieve
376 the name of. This is an optional parameter that
377 may be NULL. It will be NULL for device
378 drivers. It will also be NULL for a bus drivers
379 that wish to retrieve the name of the bus
380 controller. It will not be NULL for a bus
381 driver that wishes to retrieve the name of a
384 @param Language[in] A pointer to a Null-terminated ASCII string
385 array indicating the language. This is the
386 language of the driver name that the caller is
387 requesting, and it must match one of the
388 languages specified in SupportedLanguages. The
389 number of languages supported by a driver is up
390 to the driver writer. Language is specified in
391 RFC 3066 or ISO 639-2 language code format.
393 @param ControllerName[out] A pointer to the Unicode string to return.
394 This Unicode string is the name of the
395 controller specified by ControllerHandle and
396 ChildHandle in the language specified by
397 Language from the point of view of the driver
400 @retval EFI_SUCCESS The Unicode string for the user readable name in
401 the language specified by Language for the
402 driver specified by This was returned in
405 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
407 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
410 @retval EFI_INVALID_PARAMETER Language is NULL.
412 @retval EFI_INVALID_PARAMETER ControllerName is NULL.
414 @retval EFI_UNSUPPORTED The driver specified by This is not currently
415 managing the controller specified by
416 ControllerHandle and ChildHandle.
418 @retval EFI_UNSUPPORTED The driver specified by This does not support
419 the language specified by Language.
424 AtapiScsiPassThruComponentNameGetControllerName (
425 IN EFI_COMPONENT_NAME_PROTOCOL
*This
,
426 IN EFI_HANDLE ControllerHandle
,
427 IN EFI_HANDLE ChildHandle OPTIONAL
,
429 OUT CHAR16
**ControllerName
434 AtapiScsiPassThruDriverEntryPoint
439 @todo Add function description
440 @todo ImageHandle - add argument description
441 @todo SystemTable - add argument description
442 @todo add return values
446 AtapiScsiPassThruDriverEntryPoint (
447 IN EFI_HANDLE ImageHandle
,
448 IN EFI_SYSTEM_TABLE
*SystemTable
453 RegisterAtapiScsiPassThru
458 @param OriginalPciAttributes
460 @todo Add function description
461 @todo This add argument description
462 @todo Controller add argument description
463 @todo PciIo add argument description
464 @todo add return values
467 RegisterAtapiScsiPassThru (
468 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
469 IN EFI_HANDLE Controller
,
470 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
471 IN UINT64 OriginalPciAttributes
476 AtapiScsiPassThruFunction
484 @todo Add function description
485 @todo This - add argument description
486 @todo Target - add argument description
487 @todo Lun - add argument description
488 @todo Packet - add argument description
489 @todo Event - add argument description
490 @todo add return values
494 AtapiScsiPassThruFunction (
495 IN EFI_SCSI_PASS_THRU_PROTOCOL
*This
,
498 IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
,
499 IN EFI_EVENT Event OPTIONAL
504 AtapiScsiPassThruGetNextDevice
506 TODO: Add function description
508 @param This TODO: add argument description
509 @param Target TODO: add argument description
510 @param Lun TODO: add argument description
512 TODO: add return values
517 AtapiScsiPassThruGetNextDevice (
518 IN EFI_SCSI_PASS_THRU_PROTOCOL
*This
,
519 IN OUT UINT32
*Target
,
525 AtapiScsiPassThruBuildDevicePath
527 TODO: Add function description
529 @param This TODO: add argument description
530 @param Target TODO: add argument description
531 @param Lun TODO: add argument description
532 @param DevicePath TODO: add argument description
534 TODO: add return values
539 AtapiScsiPassThruBuildDevicePath (
540 IN EFI_SCSI_PASS_THRU_PROTOCOL
*This
,
543 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
548 AtapiScsiPassThruGetTargetLun
550 TODO: Add function description
552 @param This TODO: add argument description
553 @param DevicePath TODO: add argument description
554 @param Target TODO: add argument description
555 @param Lun TODO: add argument description
557 TODO: add return values
562 AtapiScsiPassThruGetTargetLun (
563 IN EFI_SCSI_PASS_THRU_PROTOCOL
*This
,
564 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
571 AtapiScsiPassThruResetChannel
573 TODO: Add function description
575 @param This TODO: add argument description
577 TODO: add return values
582 AtapiScsiPassThruResetChannel (
583 IN EFI_SCSI_PASS_THRU_PROTOCOL
*This
588 AtapiScsiPassThruResetTarget
590 TODO: Add function description
592 @param This TODO: add argument description
593 @param Target TODO: add argument description
594 @param Lun TODO: add argument description
596 TODO: add return values
601 AtapiScsiPassThruResetTarget (
602 IN EFI_SCSI_PASS_THRU_PROTOCOL
*This
,
609 CheckSCSIRequestPacket
611 TODO: Add function description
613 @param Packet TODO: add argument description
615 TODO: add return values
619 CheckSCSIRequestPacket (
620 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
625 SubmitBlockingIoCommand
627 TODO: Add function description
629 @param AtapiScsiPrivate TODO: add argument description
630 @param Target TODO: add argument description
631 @param Packet TODO: add argument description
633 TODO: add return values
637 SubmitBlockingIoCommand (
638 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
640 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
647 TODO: Add function description
649 @param Packet - TODO: add argument description
651 @return TODO: add return values
656 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
663 TODO: Add function description
665 @param AtapiScsiPrivate TODO: add argument description
666 @param Target TODO: add argument description
667 @param Timeout TODO: add argument description
668 @param SenseData TODO: add argument description
669 @param SenseDataLength TODO: add argument description
671 TODO: add return values
675 RequestSenseCommand (
676 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
680 UINT8
*SenseDataLength
687 TODO: Add function description
689 @param AtapiScsiPrivate TODO: add argument description
690 @param Target TODO: add argument description
691 @param PacketCommand TODO: add argument description
692 @param Buffer TODO: add argument description
693 @param ByteCount TODO: add argument description
694 @param Direction TODO: add argument description
695 @param TimeOutInMicroSeconds TODO: add argument description
697 TODO: add return values
702 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
704 UINT8
*PacketCommand
,
707 DATA_DIRECTION Direction
,
708 UINT64 TimeOutInMicroSeconds
716 TODO: Add function description
718 @param PciIo TODO: add argument description
719 @param Port TODO: add argument description
721 TODO: add return values
726 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
735 TODO: Add function description
737 @param PciIo TODO: add argument description
738 @param Port TODO: add argument description
740 TODO: add return values
745 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
754 TODO: Add function description
756 @param PciIo TODO: add argument description
757 @param Port TODO: add argument description
758 @param Data TODO: add argument description
760 TODO: add return values
765 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
775 TODO: Add function description
777 @param PciIo TODO: add argument description
778 @param Port TODO: add argument description
779 @param Data TODO: add argument description
781 TODO: add return values
786 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
795 TODO: Add function description
797 @param AtapiScsiPrivate TODO: add argument description
798 @param TimeOutInMicroSeconds TODO: add argument description
800 TODO: add return values
805 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
806 UINT64 TimeOutInMicroSeconds
813 TODO: Add function description
815 @param AtapiScsiPrivate TODO: add argument description
816 @param TimeOutInMicroSeconds TODO: add argument description
818 TODO: add return values
823 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
824 UINT64 TimeOutInMicroSeconds
831 TODO: Add function description
833 @param AtapiScsiPrivate TODO: add argument description
834 @param TimeOutInMicroSeconds TODO: add argument description
836 TODO: add return values
841 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
842 UINT64 TimeOutInMicroSeconds
849 TODO: Add function description
851 @param AtapiScsiPrivate TODO: add argument description
852 @param TimeOutInMicroSeconds TODO: add argument description
854 TODO: add return values
859 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
860 UINT64 TimeOutInMicroSeconds
865 TODO: Add function description
867 @param AtapiScsiPrivate TODO: add argument description
868 @param TimeoutInMicroSeconds TODO: add argument description
870 TODO: add return values
874 StatusWaitForBSYClear (
875 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
876 UINT64 TimeoutInMicroSeconds
881 TODO: Add function description
883 @param AtapiScsiPrivate TODO: add argument description
884 @param TimeoutInMicroSeconds TODO: add argument description
886 TODO: add return values
890 AltStatusWaitForBSYClear (
891 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
892 UINT64 TimeoutInMicroSeconds
897 TODO: Add function description
899 @param AtapiScsiPrivate TODO: add argument description
900 @param TimeoutInMicroSeconds TODO: add argument description
902 TODO: add return values
907 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
908 UINT64 TimeoutInMicroSeconds
913 TODO: Add function description
915 @param AtapiScsiPrivate TODO: add argument description
916 @param TimeoutInMicroSeconds TODO: add argument description
918 TODO: add return values
923 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
924 UINT64 TimeoutInMicroSeconds
929 TODO: Add function description
931 @param AtapiScsiPrivate TODO: add argument description
932 @param Buffer TODO: add argument description
933 @param ByteCount TODO: add argument description
934 @param Direction TODO: add argument description
935 @param TimeOutInMicroSeconds TODO: add argument description
937 TODO: add return values
941 AtapiPassThruPioReadWriteData (
942 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
945 DATA_DIRECTION Direction
,
946 UINT64 TimeOutInMicroSeconds
951 TODO: Add function description
953 @param AtapiScsiPrivate TODO: add argument description
955 TODO: add return values
959 AtapiPassThruCheckErrorStatus (
960 ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
964 GetIdeRegistersBaseAddr (
965 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
966 OUT IDE_REGISTERS_BASE_ADDR
*IdeRegsBaseAddr
971 Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
972 use fixed addresses. In Native-PCI mode, get base addresses from BARs in
973 the PCI IDE controller's Configuration Space.
976 PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance
977 IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
978 receive IDE IO port registers' base addresses
988 InitAtapiIoPortRegisters (
989 IN ATAPI_SCSI_PASS_THRU_DEV
*AtapiScsiPrivate
,
990 IN IDE_REGISTERS_BASE_ADDR
*IdeRegsBaseAddr
996 Initialize each Channel's Base Address of CommandBlock and ControlBlock.
1000 AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1001 IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR