2 Header file for IDE Bus Driver, containing the helper functions'
5 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
8 @par Revision Reference:
9 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
10 Add - IDEBlkIoReadBlocksExt() func definition
11 Add - IDEBlkIoWriteBlocksExt() func definition
19 // Helper functions Prototype
22 read a one-byte data from a IDE port.
24 @param PciIo The PCI IO protocol instance
25 @param Port the IDE Port number
27 return the one-byte data read from IDE port
31 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
36 Reads multiple words of data from the IDE data port.
37 Call the IO abstraction once to do the complete read,
38 not one word at a time.
40 @param PciIo Pointer to the EFI_PCI_IO instance
41 @param Port IO port to read
42 @param Count No. of UINT16's to read
43 @param Buffer Pointer to the data buffer for read
47 IDEReadPortWMultiple (
48 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
55 write a 1-byte data to a specific IDE port.
57 @param PciIo PCI IO protocol instance
58 @param Port The IDE port to be writen
59 @param Data The data to write to the port
63 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
69 write a 1-word data to a specific IDE port.
71 @param PciIo PCI IO protocol instance
72 @param Port The IDE port to be writen
73 @param Data The data to write to the port
77 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
83 Write multiple words of data to the IDE data port.
84 Call the IO abstraction once to do the complete read,
85 not one word at a time.
87 @param PciIo Pointer to the EFI_PCI_IO instance
88 @param Port IO port to read
89 @param Count No. of UINT16's to read
90 @param Buffer Pointer to the data buffer for read
94 IDEWritePortWMultiple (
95 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
102 Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
103 use fixed addresses. In Native-PCI mode, get base addresses from BARs in
104 the PCI IDE controller's Configuration Space.
106 The steps to get IDE IO port registers' base addresses for each channel
109 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
110 controller's Configuration Space to determine the operating mode.
112 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
114 ___________________________________________
115 | | Command Block | Control Block |
116 | Channel | Registers | Registers |
117 |___________|_______________|_______________|
118 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
119 |___________|_______________|_______________|
120 | Secondary | 170h - 177h | 376h - 377h |
121 |___________|_______________|_______________|
123 Table 1. Compatibility resource mappings
126 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
127 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
129 ___________________________________________________
130 | | Command Block | Control Block |
131 | Channel | Registers | Registers |
132 |___________|___________________|___________________|
133 | Primary | BAR at offset 0x10| BAR at offset 0x14|
134 |___________|___________________|___________________|
135 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
136 |___________|___________________|___________________|
138 Table 2. BARs for Register Mapping
140 @note Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for
141 primary, 0374h for secondary. So 2 bytes extra offset should be
142 added to the base addresses read from BARs.
144 For more details, please refer to PCI IDE Controller Specification and Intel
147 @param PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
148 @param IdeRegsBaseAddr Pointer to IDE_REGISTERS_BASE_ADDR to
149 receive IDE IO port registers' base addresses
151 @retval EFI_UNSUPPORTED return this value when the BARs is not IO type
152 @retval EFI_SUCCESS Get the Base address successfully
153 @retval other read the pci configureation data error
157 GetIdeRegistersBaseAddr (
158 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
159 OUT IDE_REGISTERS_BASE_ADDR
*IdeRegsBaseAddr
163 This function is used to requery IDE resources. The IDE controller will
164 probably switch between native and legacy modes during the EFI->CSM->OS
165 transfer. We do this everytime before an BlkIo operation to ensure its
168 @param IdeDev The BLK_IO private data which specifies the IDE device
170 @retval EFI_INVALID_PARAMETER return this value when the channel is invalid
171 @retval EFI_SUCCESS reassign the IDE IO resource successfully
172 @retval other get the IDE current base address effor
176 ReassignIdeResources (
177 IN IDE_BLK_IO_DEV
*IdeDev
181 Detect if there is disk attached to this port.
183 @param IdeDev The BLK_IO private data which specifies the IDE device.
185 @retval EFI_NOT_FOUND The device or channel is not found
186 @retval EFI_SUCCESS The device is found
191 IN IDE_BLK_IO_DEV
*IdeDev
195 This interface is used to initialize all state data related to the
196 detection of one channel.
200 InitializeIDEChannelData (
205 This function is used to poll for the DRQ bit clear in the Status
206 Register. DRQ is cleared when the device is finished transferring data.
207 So this function is called after data transfer is finished.
209 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
210 to record all the information of the IDE device.
211 @param TimeoutInMilliSeconds used to designate the timeout for the DRQ clear.
213 @retval EFI_SUCCESS DRQ bit clear within the time out.
215 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
218 Read Status Register will clear interrupt status.
223 IN IDE_BLK_IO_DEV
*IdeDev
,
224 IN UINTN TimeoutInMilliSeconds
228 This function is used to poll for the DRQ bit clear in the Alternate
229 Status Register. DRQ is cleared when the device is finished
230 transferring data. So this function is called after data transfer
233 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
234 to record all the information of the IDE device.
236 @param TimeoutInMilliSeconds used to designate the timeout for the DRQ clear.
238 @retval EFI_SUCCESS DRQ bit clear within the time out.
240 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
242 Read Alternate Status Register will not clear interrupt status.
247 IN IDE_BLK_IO_DEV
*IdeDev
,
248 IN UINTN TimeoutInMilliSeconds
252 This function is used to poll for the DRQ bit set in the
254 DRQ is set when the device is ready to transfer data. So this function
255 is called after the command is sent to the device and before required
258 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to
259 record all the information of the IDE device.
260 @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.
262 @retval EFI_SUCCESS DRQ bit set within the time out.
263 @retval EFI_TIMEOUT DRQ bit not set within the time out.
264 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
266 @note Read Status Register will clear interrupt status.
271 IN IDE_BLK_IO_DEV
*IdeDev
,
272 IN UINTN TimeoutInMilliSeconds
276 This function is used to poll for the DRQ bit set in the Alternate Status Register.
277 DRQ is set when the device is ready to transfer data. So this function is called after
278 the command is sent to the device and before required data is transferred.
280 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to
281 record all the information of the IDE device.
283 @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.
285 @retval EFI_SUCCESS DRQ bit set within the time out.
286 @retval EFI_TIMEOUT DRQ bit not set within the time out.
287 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
288 @note Read Alternate Status Register will not clear interrupt status.
293 IN IDE_BLK_IO_DEV
*IdeDev
,
294 IN UINTN TimeoutInMilliSeconds
298 This function is used to poll for the BSY bit clear in the Status Register. BSY
299 is clear when the device is not busy. Every command must be sent after device is not busy.
301 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
302 to record all the information of the IDE device.
303 @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.
305 @retval EFI_SUCCESS BSY bit clear within the time out.
306 @retval EFI_TIMEOUT BSY bit not clear within the time out.
308 @note Read Status Register will clear interrupt status.
312 IN IDE_BLK_IO_DEV
*IdeDev
,
313 IN UINTN TimeoutInMilliSeconds
317 This function is used to poll for the BSY bit clear in the Alternate Status Register.
318 BSY is clear when the device is not busy. Every command must be sent after device is
321 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
322 all the information of the IDE device.
323 @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.
325 @retval EFI_SUCCESS BSY bit clear within the time out.
326 @retval EFI_TIMEOUT BSY bit not clear within the time out.
327 @note Read Alternate Status Register will not clear interrupt status.
332 IN IDE_BLK_IO_DEV
*IdeDev
,
333 IN UINTN TimeoutInMilliSeconds
337 This function is used to poll for the DRDY bit set in the Status Register. DRDY
338 bit is set when the device is ready to accept command. Most ATA commands must be
339 sent after DRDY set except the ATAPI Packet Command.
341 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
342 to record all the information of the IDE device.
343 @param DelayInMilliSeconds used to designate the timeout for the DRQ ready.
345 @retval EFI_SUCCESS DRDY bit set within the time out.
346 @retval EFI_TIMEOUT DRDY bit not set within the time out.
348 @note Read Status Register will clear interrupt status.
352 IN IDE_BLK_IO_DEV
*IdeDev
,
353 IN UINTN DelayInMilliSeconds
357 This function is used to poll for the DRDY bit set in the Alternate Status Register.
358 DRDY bit is set when the device is ready to accept command. Most ATA commands must
359 be sent after DRDY set except the ATAPI Packet Command.
361 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
362 to record all the information of the IDE device.
363 @param DelayInMilliSeconds used to designate the timeout for the DRQ ready.
365 @retval EFI_SUCCESS DRDY bit set within the time out.
366 @retval EFI_TIMEOUT DRDY bit not set within the time out.
368 @note Read Alternate Status Register will clear interrupt status.
373 IN IDE_BLK_IO_DEV
*IdeDev
,
374 IN UINTN DelayInMilliSeconds
378 // ATA device functions' prototype
381 Sends out an ATA Identify Command to the specified device.
383 This function is called by DiscoverIdeDevice() during its device
384 identification. It sends out the ATA Identify Command to the
385 specified device. Only ATA device responses to this command. If
386 the command succeeds, it returns the Identify data structure which
387 contains information about the device. This function extracts the
388 information it needs to fill the IDE_BLK_IO_DEV data structure,
389 including device type, media block size, media capacity, and etc.
391 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
392 all the information of the IDE device.
394 @retval EFI_SUCCESS Identify ATA device successfully.
395 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
396 @note parameter IdeDev will be updated in this function.
401 IN IDE_BLK_IO_DEV
*IdeDev
405 This function is called by ATAIdentify() or ATAPIIdentify() to print device's module name.
407 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
408 all the information of the IDE device.
412 IN IDE_BLK_IO_DEV
*IdeDev
415 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
417 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
418 all the information of the IDE device.
419 @param Buffer buffer contained data transferred from device to host.
420 @param ByteCount data size in byte unit of the buffer.
421 @param AtaCommand value of the Command Register
422 @param Head value of the Head/Device Register
423 @param SectorCount value of the Sector Count Register
424 @param SectorNumber value of the Sector Number Register
425 @param CylinderLsb value of the low byte of the Cylinder Register
426 @param CylinderMsb value of the high byte of the Cylinder Register
428 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
429 @retval EFI_DEVICE_ERROR command sent failed.
434 IN IDE_BLK_IO_DEV
*IdeDev
,
439 IN UINT8 SectorCount
,
440 IN UINT8 SectorNumber
,
441 IN UINT8 CylinderLsb
,
446 This function is used to send out ATA commands conforms to the
447 PIO Data Out Protocol.
449 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
450 to record all the information of the IDE device.
451 @param *Buffer buffer contained data transferred from host to device.
452 @param ByteCount data size in byte unit of the buffer.
453 @param AtaCommand value of the Command Register
454 @param Head value of the Head/Device Register
455 @param SectorCount value of the Sector Count Register
456 @param SectorNumber value of the Sector Number Register
457 @param CylinderLsb value of the low byte of the Cylinder Register
458 @param CylinderMsb value of the high byte of the Cylinder Register
460 @retval EFI_SUCCESS send out the ATA command and device received required
462 @retval EFI_DEVICE_ERROR command sent failed.
467 IN IDE_BLK_IO_DEV
*IdeDev
,
472 IN UINT8 SectorCount
,
473 IN UINT8 SectorNumber
,
474 IN UINT8 CylinderLsb
,
479 This function is used to analyze the Status Register and print out
480 some debug information and if there is ERR bit set in the Status
481 Register, the Error Register's value is also be parsed and print out.
483 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to
484 record all the information of the IDE device.
486 @retval EFI_SUCCESS No err information in the Status Register.
487 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
492 IN IDE_BLK_IO_DEV
*IdeDev
496 This function is used to implement the Soft Reset on the specified device. But,
497 the ATA Soft Reset mechanism is so strong a reset method that it will force
498 resetting on both devices connected to the same cable.
500 It is called by IdeBlkIoReset(), a interface function of Block
503 This function can also be used by the ATAPI device to perform reset when
504 ATAPI Reset command is failed.
506 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
507 all the information of the IDE device.
508 @retval EFI_SUCCESS Soft reset completes successfully.
509 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
511 @note The registers initial values after ATA soft reset are different
512 to the ATA device and ATAPI device.
516 IN IDE_BLK_IO_DEV
*IdeDev
520 This function is the ATA implementation for ReadBlocks in the
521 Block I/O Protocol interface.
523 @param IdeBlkIoDevice Indicates the calling context.
524 @param MediaId The media id that the read request is for.
525 @param Lba The starting logical block address to read from on the device.
526 @param BufferSize The size of the Buffer in bytes. This must be a multiple
527 of the intrinsic block size of the device.
529 @param Buffer A pointer to the destination buffer for the data. The caller
530 is responsible for either having implicit or explicit ownership
531 of the memory that data is read into.
533 @retval EFI_SUCCESS Read Blocks successfully.
534 @retval EFI_DEVICE_ERROR Read Blocks failed.
535 @retval EFI_NO_MEDIA There is no media in the device.
536 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
537 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
538 intrinsic block size of the device.
539 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
540 or the data buffer is not valid.
542 @note If Read Block error because of device error, this function will call
543 AtaSoftReset() function to reset device.
548 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
556 This function is the ATA implementation for WriteBlocks in the
557 Block I/O Protocol interface.
559 @param IdeBlkIoDevice Indicates the calling context.
560 @param MediaId The media id that the write request is for.
561 @param Lba The starting logical block address to write onto the device.
562 @param BufferSize The size of the Buffer in bytes. This must be a multiple
563 of the intrinsic block size of the device.
564 @param Buffer A pointer to the source buffer for the data.The caller
565 is responsible for either having implicit or explicit
566 ownership of the memory that data is written from.
568 @retval EFI_SUCCESS Write Blocks successfully.
569 @retval EFI_DEVICE_ERROR Write Blocks failed.
570 @retval EFI_NO_MEDIA There is no media in the device.
571 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
573 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
574 intrinsic block size of the device.
575 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
576 or the data buffer is not valid.
578 @note If Write Block error because of device error, this function will call
579 AtaSoftReset() function to reset device.
582 AtaBlkIoWriteBlocks (
583 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
591 This function is called by DiscoverIdeDevice() during its device
593 Its main purpose is to get enough information for the device media
594 to fill in the Media data structure of the Block I/O Protocol interface.
596 There are 5 steps to reach such objective:
597 1. Sends out the ATAPI Identify Command to the specified device.
598 Only ATAPI device responses to this command. If the command succeeds,
599 it returns the Identify data structure which filled with information
600 about the device. Since the ATAPI device contains removable media,
601 the only meaningful information is the device module name.
602 2. Sends out ATAPI Inquiry Packet Command to the specified device.
603 This command will return inquiry data of the device, which contains
604 the device type information.
605 3. Allocate sense data space for future use. We don't detect the media
606 presence here to improvement boot performance, especially when CD
607 media is present. The media detection will be performed just before
608 each BLK_IO read/write
610 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
611 to record all the information of the IDE device.
613 @retval EFI_SUCCESS Identify ATAPI device successfully.
614 @retval EFI_DEVICE_ERROR ATAPI Identify Device Command failed or device type
615 is not supported by this IDE driver.
616 @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed
618 @note Parameter "IdeDev" will be updated in this function.
622 IN IDE_BLK_IO_DEV
*IdeDev
626 This function is used to implement the Soft Reset on the specified
627 ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
628 Soft Reset Command special for ATAPI device, and it only take effects
629 on the specified ATAPI device, not on the whole IDE bus.
630 Since the ATAPI soft reset is needed when device is in exceptional
631 condition (such as BSY bit is always set ), I think the Soft Reset
632 command should be sent without waiting for the BSY clear and DRDY
634 This function is called by IdeBlkIoReset(),
635 a interface function of Block I/O protocol.
637 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
638 to record all the information of the IDE device.
640 @retval EFI_SUCCESS Soft reset completes successfully.
641 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
646 IN IDE_BLK_IO_DEV
*IdeDev
650 This function is the ATAPI implementation for ReadBlocks in the
651 Block I/O Protocol interface.
653 @param IdeBlkIoDevice Indicates the calling context.
654 @param MediaId The media id that the read request is for.
655 @param Lba The starting logical block address to read from on the device.
656 @param BufferSize The size of the Buffer in bytes. This must be a multiple
657 of the intrinsic block size of the device.
658 @param Buffer A pointer to the destination buffer for the data. The caller
659 is responsible for either having implicit or explicit
660 ownership of the memory that data is read into.
662 @retval EFI_SUCCESS Read Blocks successfully.
663 @retval EFI_DEVICE_ERROR Read Blocks failed.
664 @retval EFI_NO_MEDIA There is no media in the device.
665 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
666 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
667 intrinsic block size of the device.
668 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
669 or the data buffer is not valid.
672 AtapiBlkIoReadBlocks (
673 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
681 This function is the ATAPI implementation for WriteBlocks in the
682 Block I/O Protocol interface.
684 @param IdeBlkIoDevice Indicates the calling context.
685 @param MediaId The media id that the write request is for.
686 @param Lba The starting logical block address to write onto the device.
687 @param BufferSize The size of the Buffer in bytes. This must be a multiple
688 of the intrinsic block size of the device.
689 @param Buffer A pointer to the source buffer for the data. The caller
690 is responsible for either having implicit or explicit ownership
691 of the memory that data is written from.
693 @retval EFI_SUCCESS Write Blocks successfully.
694 @retval EFI_DEVICE_ERROR Write Blocks failed.
695 @retval EFI_NO_MEDIA There is no media in the device.
696 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
697 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
698 intrinsic block size of the device.
699 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
700 or the data buffer is not valid.
702 @retval EFI_WRITE_PROTECTED The write protected is enabled or the media does not support write
705 AtapiBlkIoWriteBlocks (
706 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
714 Release resources of an IDE device before stopping it.
716 @param IdeBlkIoDevice Standard IDE device private data structure
720 ReleaseIdeResources (
721 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
725 Set the calculated Best transfer mode to a detected device
727 @param IdeDev Standard IDE device private data structure
728 @param TransferMode The device transfer mode to be set
729 @return Set transfer mode Command execute status.
732 SetDeviceTransferMode (
733 IN IDE_BLK_IO_DEV
*IdeDev
,
734 IN ATA_TRANSFER_MODE
*TransferMode
737 Send ATA command into device with NON_DATA protocol.
739 @param IdeDev Standard IDE device private data structure
740 @param AtaCommand The ATA command to be sent
741 @param Device The value in Device register
742 @param Feature The value in Feature register
743 @param SectorCount The value in SectorCount register
744 @param LbaLow The value in LBA_LOW register
745 @param LbaMiddle The value in LBA_MIDDLE register
746 @param LbaHigh The value in LBA_HIGH register
748 @retval EFI_SUCCESS Reading succeed
749 @retval EFI_ABORTED Command failed
750 @retval EFI_DEVICE_ERROR Device status error.
754 AtaNonDataCommandIn (
755 IN IDE_BLK_IO_DEV
*IdeDev
,
759 IN UINT8 SectorCount
,
766 Enable Long Physical Sector Feature for ATA device.
768 @param IdeDev The IDE device data
770 @retval EFI_SUCCESS The ATA device supports Long Physical Sector feature
771 and corresponding fields in BlockIo structure is updated.
772 @retval EFI_UNSUPPORTED The device is not ATA device or Long Physical Sector
773 feature is not supported.
776 AtaEnableLongPhysicalSector (
777 IN IDE_BLK_IO_DEV
*IdeDev
781 Set drive parameters for devices not support PACKETS command.
783 @param IdeDev Standard IDE device private data structure
784 @param DriveParameters The device parameters to be set into the disk
785 @return SetParameters Command execute status.
790 IN IDE_BLK_IO_DEV
*IdeDev
,
791 IN ATA_DRIVE_PARMS
*DriveParameters
795 Enable Interrupt on IDE controller.
797 @param IdeDev Standard IDE device private data structure
799 @retval EFI_SUCCESS Enable Interrupt successfully
803 IN IDE_BLK_IO_DEV
*IdeDev