2 This file contains all helper functions on the ATAPI command
4 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This function is used to get the current status of the media residing
19 in the LS-120 drive or ZIP drive. The media status is returned in the
22 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
23 to record all the information of the IDE device.
25 @retval EFI_SUCCESS The media status is achieved successfully and the media
27 @retval EFI_DEVICE_ERROR Get Media Status Command is failed.
28 @retval EFI_NO_MEDIA There is no media in the drive.
29 @retval EFI_WRITE_PROTECTED The media is writing protected.
31 @note This function must be called after the LS120EnableMediaStatus()
32 with second parameter set to TRUE
33 (means enable media status notification) is called.
37 IN IDE_BLK_IO_DEV
*IdeDev
44 // Poll Alternate Register for BSY clear within timeout.
46 EfiStatus
= WaitForBSYClear2 (IdeDev
, ATATIMEOUT
);
47 if (EFI_ERROR (EfiStatus
)) {
48 return EFI_DEVICE_ERROR
;
52 // Select device via Device/Head Register.
54 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4 | 0xe0);
55 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
58 // Poll Alternate Register for DRDY set within timeout.
59 // After device is selected, DRDY set indicates the device is ready to
62 EfiStatus
= DRDYReady2 (IdeDev
, ATATIMEOUT
);
63 if (EFI_ERROR (EfiStatus
)) {
64 return EFI_DEVICE_ERROR
;
68 // Get Media Status Command is sent
70 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, 0xDA);
73 // BSY bit will clear after command is complete.
75 EfiStatus
= WaitForBSYClear2 (IdeDev
, ATATIMEOUT
);
76 if (EFI_ERROR (EfiStatus
)) {
77 return EFI_DEVICE_ERROR
;
81 // the media status is returned by the command in the ERROR register
83 StatusValue
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
85 if ((StatusValue
& BIT1
) != 0) {
89 if ((StatusValue
& BIT6
) != 0) {
90 return EFI_WRITE_PROTECTED
;
96 This function is used to send Enable Media Status Notification Command
97 or Disable Media Status Notification Command.
99 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
100 to record all the information of the IDE device.
102 @param Enable a flag that indicates whether enable or disable media
104 @retval EFI_SUCCESS If command completes successfully.
105 @retval EFI_DEVICE_ERROR If command failed.
108 LS120EnableMediaStatus (
109 IN IDE_BLK_IO_DEV
*IdeDev
,
117 // Poll Alternate Register for BSY clear within timeout.
119 Status
= WaitForBSYClear2 (IdeDev
, ATATIMEOUT
);
120 if (EFI_ERROR (Status
)) {
121 return EFI_DEVICE_ERROR
;
125 // Select device via Device/Head Register.
127 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4 | 0xe0);
128 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
131 // Poll Alternate Register for DRDY set within timeout.
132 // After device is selected, DRDY set indicates the device is ready to
135 Status
= DRDYReady2 (IdeDev
, ATATIMEOUT
);
136 if (EFI_ERROR (Status
)) {
137 return EFI_DEVICE_ERROR
;
142 // 0x95: Enable media status notification
144 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x95);
147 // 0x31: Disable media status notification
149 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x31);
152 // Set Feature Command is sent
154 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, 0xEF);
157 // BSY bit will clear after command is complete.
159 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
160 if (EFI_ERROR (Status
)) {
161 return EFI_DEVICE_ERROR
;
167 This function reads the pending data in the device.
169 @param IdeDev Indicates the calling context.
171 @retval EFI_SUCCESS Successfully read.
172 @retval EFI_NOT_READY The BSY is set avoiding reading.
176 AtapiReadPendingData (
177 IN IDE_BLK_IO_DEV
*IdeDev
181 UINT16 TempWordBuffer
;
183 AltRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.AltStatus
);
184 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
185 return EFI_NOT_READY
;
187 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
188 TempWordBuffer
= IDEReadPortB (IdeDev
->PciIo
,IdeDev
->IoPort
->Alt
.AltStatus
);
189 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
190 IDEReadPortWMultiple (
192 IdeDev
->IoPort
->Data
,
196 TempWordBuffer
= IDEReadPortB (IdeDev
->PciIo
,IdeDev
->IoPort
->Alt
.AltStatus
);
203 This function is called by either AtapiPacketCommandIn() or AtapiPacketCommandOut().
204 It is used to transfer data between host and device. The data direction is specified
205 by the fourth parameter.
207 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
208 all the information of the IDE device.
209 @param Buffer buffer contained data transferred between host and device.
210 @param ByteCount data size in byte unit of the buffer.
211 @param Read flag used to determine the data transfer direction.
212 Read equals 1, means data transferred from device to host;
213 Read equals 0, means data transferred from host to device.
214 @param TimeOut timeout value for wait DRQ ready before each data stream's transfer.
216 @retval EFI_SUCCESS data is transferred successfully.
217 @retval EFI_DEVICE_ERROR the device failed to transfer data.
221 IN IDE_BLK_IO_DEV
*IdeDev
,
229 // required transfer data in word unit.
231 UINT32 RequiredWordCount
;
234 // actual transfer data in word unit.
236 UINT32 ActualWordCount
;
242 // No data transfer is premitted.
244 if (ByteCount
== 0) {
248 // for performance, we assert the ByteCount is an even number
249 // which is actually a resonable assumption
250 ASSERT((ByteCount
%2) == 0);
253 RequiredWordCount
= ByteCount
/ 2;
255 // ActuralWordCount means the word count of data really transferred.
259 while (ActualWordCount
< RequiredWordCount
) {
262 // before each data transfer stream, the host should poll DRQ bit ready,
263 // to see whether indicates device is ready to transfer data.
265 Status
= DRQReady2 (IdeDev
, TimeOut
);
266 if (EFI_ERROR (Status
)) {
267 return CheckErrorStatus (IdeDev
);
271 // read Status Register will clear interrupt
273 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
276 // get current data transfer size from Cylinder Registers.
278 WordCount
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
) << 8;
279 WordCount
= WordCount
| IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
280 WordCount
= WordCount
& 0xffff;
283 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
286 IDEReadPortWMultiple (
288 IdeDev
->IoPort
->Data
,
293 IDEWritePortWMultiple (
295 IdeDev
->IoPort
->Data
,
301 PtrBuffer
+= WordCount
;
302 ActualWordCount
+= WordCount
;
307 // In the case where the drive wants to send more data than we need to read,
308 // the DRQ bit will be set and cause delays from DRQClear2().
309 // We need to read data from the drive until it clears DRQ so we can move on.
311 AtapiReadPendingData (IdeDev
);
315 // After data transfer is completed, normally, DRQ bit should clear.
317 Status
= DRQClear2 (IdeDev
, ATAPITIMEOUT
);
318 if (EFI_ERROR (Status
)) {
319 return EFI_DEVICE_ERROR
;
323 // read status register to check whether error happens.
325 return CheckErrorStatus (IdeDev
);
329 This function is used to send out ATAPI commands conforms to the Packet Command
330 with PIO Data In Protocol.
332 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
333 to record all the information of the IDE device.
334 @param Packet pointer pointing to ATAPI_PACKET_COMMAND data structure
335 which contains the contents of the command.
336 @param Buffer buffer contained data transferred from device to host.
337 @param ByteCount data size in byte unit of the buffer.
338 @param TimeOut this parameter is used to specify the timeout value for the
339 PioReadWriteData() function.
341 @retval EFI_SUCCESS send out the ATAPI packet command successfully
342 and device sends data successfully.
343 @retval EFI_DEVICE_ERROR the device failed to send data.
347 AtapiPacketCommandIn (
348 IN IDE_BLK_IO_DEV
*IdeDev
,
349 IN ATAPI_PACKET_COMMAND
*Packet
,
355 UINT16
*CommandIndex
;
360 // Set all the command parameters by fill related registers.
361 // Before write to all the following registers, BSY and DRQ must be 0.
363 Status
= DRQClear2 (IdeDev
, ATAPITIMEOUT
);
364 if (EFI_ERROR (Status
)) {
369 // Select device via Device/Head Register.
373 IdeDev
->IoPort
->Head
,
374 (UINT8
) ((IdeDev
->Device
<< 4) | ATA_DEFAULT_CMD
) // DEFAULT_CMD: 0xa0 (1010,0000)
380 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x00);
383 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
384 // determine how many data should be transferred.
388 IdeDev
->IoPort
->CylinderLsb
,
389 (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff)
393 IdeDev
->IoPort
->CylinderMsb
,
394 (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8)
398 // ATA_DEFAULT_CTL:0x0a (0000,1010)
401 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, ATA_DEFAULT_CTL
);
404 // Send Packet command to inform device
405 // that the following data bytes are command packet.
407 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, ATA_CMD_PACKET
);
409 Status
= DRQReady (IdeDev
, ATAPITIMEOUT
);
410 if (EFI_ERROR (Status
)) {
415 // Send out command packet
417 CommandIndex
= Packet
->Data16
;
418 for (Count
= 0; Count
< 6; Count
++, CommandIndex
++) {
420 IDEWritePortW (IdeDev
->PciIo
, IdeDev
->IoPort
->Data
, *CommandIndex
);
425 // call PioReadWriteData() function to get
426 // requested transfer data form device.
428 return PioReadWriteData (IdeDev
, Buffer
, ByteCount
, 1, TimeOut
);
431 This function is used to send out ATAPI commands conforms to the Packet Command
432 with PIO Data Out Protocol.
434 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
435 to record all the information of the IDE device.
436 @param Packet pointer pointing to ATAPI_PACKET_COMMAND data structure
437 which contains the contents of the command.
438 @param Buffer buffer contained data transferred from host to device.
439 @param ByteCount data size in byte unit of the buffer.
440 @param TimeOut this parameter is used to specify the timeout value
441 for the PioReadWriteData() function.
442 @retval EFI_SUCCESS send out the ATAPI packet command successfully
443 and device received data successfully.
444 @retval EFI_DEVICE_ERROR the device failed to send data.
448 AtapiPacketCommandOut (
449 IN IDE_BLK_IO_DEV
*IdeDev
,
450 IN ATAPI_PACKET_COMMAND
*Packet
,
456 UINT16
*CommandIndex
;
461 // set all the command parameters
462 // Before write to all the following registers, BSY and DRQ must be 0.
464 Status
= DRQClear2 (IdeDev
, ATAPITIMEOUT
);
465 if (EFI_ERROR (Status
)) {
470 // Select device via Device/Head Register.
474 IdeDev
->IoPort
->Head
,
475 (UINT8
) ((IdeDev
->Device
<< 4) | ATA_DEFAULT_CMD
) // ATA_DEFAULT_CMD: 0xa0 (1010,0000)
481 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x00);
484 // set the transfersize to ATAPI_MAX_BYTE_COUNT to
485 // let the device determine how many data should be transferred.
489 IdeDev
->IoPort
->CylinderLsb
,
490 (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff)
494 IdeDev
->IoPort
->CylinderMsb
,
495 (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8)
499 // DEFAULT_CTL:0x0a (0000,1010)
502 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, ATA_DEFAULT_CTL
);
505 // Send Packet command to inform device
506 // that the following data bytes are command packet.
508 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, ATA_CMD_PACKET
);
510 Status
= DRQReady2 (IdeDev
, ATAPITIMEOUT
);
511 if (EFI_ERROR (Status
)) {
516 // Send out command packet
518 CommandIndex
= Packet
->Data16
;
519 for (Count
= 0; Count
< 6; Count
++, CommandIndex
++) {
520 IDEWritePortW (IdeDev
->PciIo
, IdeDev
->IoPort
->Data
, *CommandIndex
);
525 // call PioReadWriteData() function to send requested transfer data to device.
527 return PioReadWriteData (IdeDev
, Buffer
, ByteCount
, 0, TimeOut
);
530 Sends out ATAPI Inquiry Packet Command to the specified device. This command will
531 return INQUIRY data of the device.
533 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
534 to record all the information of the IDE device.
536 @retval EFI_SUCCESS Inquiry command completes successfully.
537 @retval EFI_DEVICE_ERROR Inquiry command failed.
539 @note Parameter "IdeDev" will be updated in this function.
544 IN IDE_BLK_IO_DEV
*IdeDev
547 ATAPI_PACKET_COMMAND Packet
;
549 ATAPI_INQUIRY_DATA
*InquiryData
;
552 // prepare command packet for the ATAPI Inquiry Packet Command.
554 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
555 Packet
.Inquiry
.opcode
= ATA_CMD_INQUIRY
;
556 Packet
.Inquiry
.page_code
= 0;
557 Packet
.Inquiry
.allocation_length
= (UINT8
) sizeof (ATAPI_INQUIRY_DATA
);
559 InquiryData
= AllocatePool (sizeof (ATAPI_INQUIRY_DATA
));
560 if (InquiryData
== NULL
) {
561 return EFI_DEVICE_ERROR
;
565 // Send command packet and get requested Inquiry data.
567 Status
= AtapiPacketCommandIn (
570 (UINT16
*) InquiryData
,
571 sizeof (ATAPI_INQUIRY_DATA
),
574 if (EFI_ERROR (Status
)) {
575 gBS
->FreePool (InquiryData
);
576 return EFI_DEVICE_ERROR
;
579 IdeDev
->InquiryData
= InquiryData
;
584 This function is called by DiscoverIdeDevice() during its device
586 Its main purpose is to get enough information for the device media
587 to fill in the Media data structure of the Block I/O Protocol interface.
589 There are 5 steps to reach such objective:
590 1. Sends out the ATAPI Identify Command to the specified device.
591 Only ATAPI device responses to this command. If the command succeeds,
592 it returns the Identify data structure which filled with information
593 about the device. Since the ATAPI device contains removable media,
594 the only meaningful information is the device module name.
595 2. Sends out ATAPI Inquiry Packet Command to the specified device.
596 This command will return inquiry data of the device, which contains
597 the device type information.
598 3. Allocate sense data space for future use. We don't detect the media
599 presence here to improvement boot performance, especially when CD
600 media is present. The media detection will be performed just before
601 each BLK_IO read/write
603 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
604 to record all the information of the IDE device.
606 @retval EFI_SUCCESS Identify ATAPI device successfully.
607 @retval EFI_DEVICE_ERROR ATAPI Identify Device Command failed or device type
608 is not supported by this IDE driver.
609 @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed
611 @note Parameter "IdeDev" will be updated in this function.
615 IN IDE_BLK_IO_DEV
*IdeDev
618 EFI_IDENTIFY_DATA
*AtapiIdentifyPointer
;
625 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
627 AtapiIdentifyPointer
= AllocatePool (sizeof (EFI_IDENTIFY_DATA
));
628 if (AtapiIdentifyPointer
== NULL
) {
629 return EFI_OUT_OF_RESOURCES
;
632 // Send ATAPI Identify Command to get IDENTIFY data.
634 Status
= AtaPioDataIn (
636 (VOID
*) AtapiIdentifyPointer
,
637 sizeof (EFI_IDENTIFY_DATA
),
638 ATA_CMD_IDENTIFY_DEVICE
,
646 if (EFI_ERROR (Status
)) {
647 gBS
->FreePool (AtapiIdentifyPointer
);
648 return EFI_DEVICE_ERROR
;
651 IdeDev
->IdData
= AtapiIdentifyPointer
;
652 PrintAtaModuleName (IdeDev
);
655 // Send ATAPI Inquiry Packet Command to get INQUIRY data.
657 Status
= AtapiInquiry (IdeDev
);
658 if (EFI_ERROR (Status
)) {
659 gBS
->FreePool (IdeDev
->IdData
);
661 // Make sure the pIdData will not be freed again.
663 IdeDev
->IdData
= NULL
;
664 return EFI_DEVICE_ERROR
;
667 // Get media removable info from INQUIRY data.
669 IdeDev
->BlkIo
.Media
->RemovableMedia
= (UINT8
) ((IdeDev
->InquiryData
->RMB
& 0x80) == 0x80);
672 // Identify device type via INQUIRY data.
674 switch (IdeDev
->InquiryData
->peripheral_type
& 0x1f) {
682 // device is LS120 or ZIP drive.
684 IdeDev
->Type
= IdeMagnetic
;
686 IdeDev
->BlkIo
.Media
->MediaId
= 0;
688 // Give initial value
690 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
692 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
693 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
701 IdeDev
->Type
= IdeCdRom
;
702 IdeDev
->BlkIo
.Media
->MediaId
= 0;
704 // Give initial value
706 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
708 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
709 IdeDev
->BlkIo
.Media
->BlockSize
= 0x800;
710 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
729 IdeDev
->Type
= IdeUnknown
;
730 gBS
->FreePool (IdeDev
->IdData
);
731 gBS
->FreePool (IdeDev
->InquiryData
);
733 // Make sure the pIdData and pInquiryData will not be freed again.
735 IdeDev
->IdData
= NULL
;
736 IdeDev
->InquiryData
= NULL
;
737 return EFI_DEVICE_ERROR
;
741 // original sense data numbers
743 IdeDev
->SenseDataNumber
= 20;
745 IdeDev
->SenseData
= AllocatePool (IdeDev
->SenseDataNumber
* sizeof (ATAPI_REQUEST_SENSE_DATA
));
746 if (IdeDev
->SenseData
== NULL
) {
747 gBS
->FreePool (IdeDev
->IdData
);
748 gBS
->FreePool (IdeDev
->InquiryData
);
750 // Make sure the pIdData and pInquiryData will not be freed again.
752 IdeDev
->IdData
= NULL
;
753 IdeDev
->InquiryData
= NULL
;
754 return EFI_OUT_OF_RESOURCES
;
760 Sends out ATAPI Request Sense Packet Command to the specified device. This command
761 will return all the current Sense data in the device. This function will pack
762 all the Sense data in one single buffer.
764 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
765 to record all the information of the IDE device.
766 @param SenseCounts allocated in this function, and freed by the calling function.
767 This buffer is used to accommodate all the sense data returned
770 @retval EFI_SUCCESS Request Sense command completes successfully.
771 @retval EFI_DEVICE_ERROR Request Sense command failed.
775 IN IDE_BLK_IO_DEV
*IdeDev
,
776 OUT UINTN
*SenseCounts
780 ATAPI_REQUEST_SENSE_DATA
*Sense
;
782 BOOLEAN FetchSenseData
;
783 ATAPI_PACKET_COMMAND Packet
;
787 ZeroMem (IdeDev
->SenseData
, sizeof (ATAPI_REQUEST_SENSE_DATA
) * (IdeDev
->SenseDataNumber
));
789 // fill command packet for Request Sense Packet Command
791 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
792 Packet
.RequestSence
.opcode
= ATA_CMD_REQUEST_SENSE
;
793 Packet
.RequestSence
.allocation_length
= (UINT8
) sizeof (ATAPI_REQUEST_SENSE_DATA
);
796 // initialize pointer
798 Ptr
= (UINT16
*) IdeDev
->SenseData
;
800 // request sense data from device continuously until no sense data
801 // exists in the device.
803 for (FetchSenseData
= TRUE
; FetchSenseData
;) {
805 Sense
= (ATAPI_REQUEST_SENSE_DATA
*) Ptr
;
808 // send out Request Sense Packet Command and get one Sense data form device
810 Status
= AtapiPacketCommandIn (
814 sizeof (ATAPI_REQUEST_SENSE_DATA
),
818 // failed to get Sense data
820 if (EFI_ERROR (Status
)) {
821 if (*SenseCounts
== 0) {
822 return EFI_DEVICE_ERROR
;
830 // We limit MAX sense data count to 20 in order to avoid dead loop. Some
831 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
832 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
833 // supposed to be large enough for any ATAPI device.
835 if ((Sense
->sense_key
!= ATA_SK_NO_SENSE
) && ((*SenseCounts
) < 20)) {
837 // Ptr is word-based pointer
839 Ptr
+= (sizeof (ATAPI_REQUEST_SENSE_DATA
) + 1) >> 1;
843 // when no sense key, skip out the loop
845 FetchSenseData
= FALSE
;
852 This function is used to parse sense data. Only the first sense data is honoured
854 @param IdeDev Indicates the calling context.
855 @param SenseCount Count of sense data.
856 @param Result The parsed result.
858 @retval EFI_SUCCESS Successfully parsed.
859 @retval EFI_INVALID_PARAMETER Count of sense data is zero.
864 IN IDE_BLK_IO_DEV
*IdeDev
,
866 OUT SENSE_RESULT
*Result
869 ATAPI_REQUEST_SENSE_DATA
*SenseData
;
871 if (SenseCount
== 0) {
872 return EFI_INVALID_PARAMETER
;
876 // Only use the first sense data
878 SenseData
= IdeDev
->SenseData
;
879 *Result
= SenseOtherSense
;
881 switch (SenseData
->sense_key
) {
882 case ATA_SK_NO_SENSE
:
883 *Result
= SenseNoSenseKey
;
885 case ATA_SK_NOT_READY
:
886 switch (SenseData
->addnl_sense_code
) {
887 case ATA_ASC_NO_MEDIA
:
888 *Result
= SenseNoMedia
;
890 case ATA_ASC_MEDIA_UPSIDE_DOWN
:
891 *Result
= SenseMediaError
;
893 case ATA_ASC_NOT_READY
:
894 if (SenseData
->addnl_sense_code_qualifier
== ATA_ASCQ_IN_PROGRESS
) {
895 *Result
= SenseDeviceNotReadyNeedRetry
;
897 *Result
= SenseDeviceNotReadyNoRetry
;
902 case ATA_SK_UNIT_ATTENTION
:
903 if (SenseData
->addnl_sense_code
== ATA_ASC_MEDIA_CHANGE
) {
904 *Result
= SenseMediaChange
;
907 case ATA_SK_MEDIUM_ERROR
:
908 switch (SenseData
->addnl_sense_code
) {
909 case ATA_ASC_MEDIA_ERR1
:
910 case ATA_ASC_MEDIA_ERR2
:
911 case ATA_ASC_MEDIA_ERR3
:
912 case ATA_ASC_MEDIA_ERR4
:
913 *Result
= SenseMediaError
;
925 Sends out ATAPI Test Unit Ready Packet Command to the specified device
926 to find out whether device is accessible.
928 @param IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
929 to record all the information of the IDE device.
930 @param SResult Sense result for this packet command.
932 @retval EFI_SUCCESS Device is accessible.
933 @retval EFI_DEVICE_ERROR Device is not accessible.
938 IN IDE_BLK_IO_DEV
*IdeDev
,
939 OUT SENSE_RESULT
*SResult
942 ATAPI_PACKET_COMMAND Packet
;
947 // fill command packet
949 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
950 Packet
.TestUnitReady
.opcode
= ATA_CMD_TEST_UNIT_READY
;
953 // send command packet
955 Status
= AtapiPacketCommandIn (IdeDev
, &Packet
, NULL
, 0, ATAPITIMEOUT
);
956 if (EFI_ERROR (Status
)) {
960 Status
= AtapiRequestSense (IdeDev
, &SenseCount
);
961 if (EFI_ERROR (Status
)) {
965 ParseSenseData (IdeDev
, SenseCount
, SResult
);
971 Sends out ATAPI Read Capacity Packet Command to the specified device.
972 This command will return the information regarding the capacity of the
975 Current device status will impact device's response to the Read Capacity
976 Command. For example, if the device once reset, the Read Capacity
977 Command will fail. The Sense data record the current device status, so
978 if the Read Capacity Command failed, the Sense data must be requested
979 and be analyzed to determine if the Read Capacity Command should retry.
981 @param IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
982 to record all the information of the IDE device.
983 @param SResult Sense result for this packet command
985 @retval EFI_SUCCESS Read Capacity Command finally completes successfully.
986 @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.
987 @retval EFI_NOT_READY Operation succeeds but returned capacity is 0
989 @note Parameter "IdeDev" will be updated in this function.
995 IN IDE_BLK_IO_DEV
*IdeDev
,
996 OUT SENSE_RESULT
*SResult
1000 // status returned by Read Capacity Packet Command
1003 EFI_STATUS SenseStatus
;
1004 ATAPI_PACKET_COMMAND Packet
;
1008 // used for capacity data returned from ATAPI device
1010 ATAPI_READ_CAPACITY_DATA Data
;
1011 ATAPI_READ_FORMAT_CAPACITY_DATA FormatData
;
1013 ZeroMem (&Data
, sizeof (Data
));
1014 ZeroMem (&FormatData
, sizeof (FormatData
));
1016 if (IdeDev
->Type
== IdeCdRom
) {
1018 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1019 Packet
.Inquiry
.opcode
= ATA_CMD_READ_CAPACITY
;
1020 Status
= AtapiPacketCommandIn (
1024 sizeof (ATAPI_READ_CAPACITY_DATA
),
1030 // Type == IdeMagnetic
1032 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1033 Packet
.ReadFormatCapacity
.opcode
= ATA_CMD_READ_FORMAT_CAPACITY
;
1034 Packet
.ReadFormatCapacity
.allocation_length_lo
= 12;
1035 Status
= AtapiPacketCommandIn (
1038 (UINT16
*) &FormatData
,
1039 sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA
),
1044 if (Status
== EFI_TIMEOUT
) {
1048 SenseStatus
= AtapiRequestSense (IdeDev
, &SenseCount
);
1050 if (!EFI_ERROR (SenseStatus
)) {
1051 ParseSenseData (IdeDev
, SenseCount
, SResult
);
1053 if (!EFI_ERROR (Status
) && *SResult
== SenseNoSenseKey
) {
1054 if (IdeDev
->Type
== IdeCdRom
) {
1056 IdeDev
->BlkIo
.Media
->LastBlock
= ((UINT32
) Data
.LastLba3
<< 24) |
1057 (Data
.LastLba2
<< 16) |
1058 (Data
.LastLba1
<< 8) |
1061 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
1063 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
1066 // Because the user data portion in the sector of the Data CD supported
1069 IdeDev
->BlkIo
.Media
->BlockSize
= 0x800;
1072 if (IdeDev
->Type
== IdeMagnetic
) {
1074 if (FormatData
.DesCode
== 3) {
1075 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1076 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1079 IdeDev
->BlkIo
.Media
->LastBlock
= ((UINT32
) FormatData
.LastLba3
<< 24) |
1080 (FormatData
.LastLba2
<< 16) |
1081 (FormatData
.LastLba1
<< 8) |
1082 FormatData
.LastLba0
;
1083 if (IdeDev
->BlkIo
.Media
->LastBlock
!= 0) {
1084 IdeDev
->BlkIo
.Media
->LastBlock
--;
1086 IdeDev
->BlkIo
.Media
->BlockSize
= (FormatData
.BlockSize2
<< 16) |
1087 (FormatData
.BlockSize1
<< 8) |
1088 FormatData
.BlockSize0
;
1090 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
1092 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1094 // Return EFI_NOT_READY operation succeeds but returned capacity is 0
1096 return EFI_NOT_READY
;
1099 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
1108 return EFI_DEVICE_ERROR
;
1112 This function is used to test the current media write-protected or not residing
1113 in the LS-120 drive or ZIP drive.
1114 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1115 to record all the information of the IDE device.
1116 @param WriteProtected if True, current media is write protected.
1117 if FALSE, current media is writable
1119 @retval EFI_SUCCESS The media write-protected status is achieved successfully
1120 @retval EFI_DEVICE_ERROR Get Media Status Command is failed.
1123 IsLS120orZipWriteProtected (
1124 IN IDE_BLK_IO_DEV
*IdeDev
,
1125 OUT BOOLEAN
*WriteProtected
1130 *WriteProtected
= FALSE
;
1132 Status
= LS120EnableMediaStatus (IdeDev
, TRUE
);
1133 if (EFI_ERROR (Status
)) {
1134 return EFI_DEVICE_ERROR
;
1138 // the Get Media Status Command is only valid
1139 // if a Set Features/Enable Media Status Command has been priviously issued.
1141 if (LS120GetMediaStatus (IdeDev
) == EFI_WRITE_PROTECTED
) {
1143 *WriteProtected
= TRUE
;
1146 *WriteProtected
= FALSE
;
1150 // After Get Media Status Command completes,
1151 // Set Features/Disable Media Command should be sent.
1153 Status
= LS120EnableMediaStatus (IdeDev
, FALSE
);
1154 if (EFI_ERROR (Status
)) {
1155 return EFI_DEVICE_ERROR
;
1162 Used before read/write blocks from/to ATAPI device media. Since ATAPI device
1163 media is removable, it is necessary to detect whether media is present and
1164 get current present media's information, and if media has been changed, Block
1165 I/O Protocol need to be reinstalled.
1167 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1168 to record all the information of the IDE device.
1169 @param MediaChange return value that indicates if the media of the device has been
1172 @retval EFI_SUCCESS media found successfully.
1173 @retval EFI_DEVICE_ERROR any error encounters during media detection.
1174 @retval EFI_NO_MEDIA media not found.
1177 parameter IdeDev may be updated in this function.
1182 IN IDE_BLK_IO_DEV
*IdeDev
,
1183 OUT BOOLEAN
*MediaChange
1187 EFI_STATUS CleanStateStatus
;
1188 EFI_BLOCK_IO_MEDIA OldMediaInfo
;
1190 UINTN RetryNotReady
;
1191 SENSE_RESULT SResult
;
1192 BOOLEAN WriteProtected
;
1194 CopyMem (&OldMediaInfo
, IdeDev
->BlkIo
.Media
, sizeof (EFI_BLOCK_IO_MEDIA
));
1195 *MediaChange
= FALSE
;
1197 // Retry for SenseDeviceNotReadyNeedRetry.
1198 // Each retry takes 1s and we limit the upper boundary to
1199 // 120 times about 2 min.
1201 RetryNotReady
= 120;
1204 // Do Test Unit Ready
1211 while (RetryTimes
!= 0) {
1213 Status
= AtapiTestUnitReady (IdeDev
, &SResult
);
1215 if (EFI_ERROR (Status
)) {
1217 // Test Unit Ready error without sense data.
1218 // For some devices, this means there's extra data
1219 // that has not been read, so we read these extra
1220 // data out before going on.
1222 CleanStateStatus
= AtapiReadPendingData (IdeDev
);
1223 if (EFI_ERROR (CleanStateStatus
)) {
1225 // Busy wait failed, try again
1230 // Try again without counting down RetryTimes
1235 case SenseNoSenseKey
:
1236 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1240 // Media present but the internal structure need refreshed.
1241 // Try Read Capacity
1247 case SenseDeviceNotReadyNeedRetry
:
1248 if (--RetryNotReady
== 0) {
1249 return EFI_DEVICE_ERROR
;
1251 gBS
->Stall (1000 * STALL_1_MILLI_SECOND
);
1256 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1257 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1261 case SenseDeviceNotReadyNoRetry
:
1262 case SenseMediaError
:
1263 return EFI_DEVICE_ERROR
;
1265 case SenseMediaChange
:
1266 IdeDev
->BlkIo
.Media
->MediaId
++;
1277 return EFI_DEVICE_ERROR
;
1285 while (RetryTimes
!= 0) {
1287 Status
= AtapiReadCapacity (IdeDev
, &SResult
);
1289 if (EFI_ERROR (Status
)) {
1294 case SenseNoSenseKey
:
1298 case SenseDeviceNotReadyNeedRetry
:
1300 // We use Test Unit Ready to retry which
1307 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1308 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1312 case SenseDeviceNotReadyNoRetry
:
1313 case SenseMediaError
:
1314 return EFI_DEVICE_ERROR
;
1316 case SenseMediaChange
:
1317 IdeDev
->BlkIo
.Media
->MediaId
++;
1328 return EFI_DEVICE_ERROR
;
1332 // the following code is to check the write-protected for LS120 media
1334 if ((IdeDev
->BlkIo
.Media
->MediaPresent
) && (IdeDev
->Type
== IdeMagnetic
)) {
1336 Status
= IsLS120orZipWriteProtected (IdeDev
, &WriteProtected
);
1337 if (!EFI_ERROR (Status
)) {
1339 if (WriteProtected
) {
1341 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
1344 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
1350 if (IdeDev
->BlkIo
.Media
->MediaId
!= OldMediaInfo
.MediaId
) {
1352 // Media change information got from the device
1354 *MediaChange
= TRUE
;
1357 if (IdeDev
->BlkIo
.Media
->ReadOnly
!= OldMediaInfo
.ReadOnly
) {
1358 *MediaChange
= TRUE
;
1359 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1362 if (IdeDev
->BlkIo
.Media
->BlockSize
!= OldMediaInfo
.BlockSize
) {
1363 *MediaChange
= TRUE
;
1364 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1367 if (IdeDev
->BlkIo
.Media
->LastBlock
!= OldMediaInfo
.LastBlock
) {
1368 *MediaChange
= TRUE
;
1369 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1372 if (IdeDev
->BlkIo
.Media
->MediaPresent
!= OldMediaInfo
.MediaPresent
) {
1373 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1375 // when change from no media to media present, reset the MediaId to 1.
1377 IdeDev
->BlkIo
.Media
->MediaId
= 1;
1380 // when no media, reset the MediaId to zero.
1382 IdeDev
->BlkIo
.Media
->MediaId
= 0;
1385 *MediaChange
= TRUE
;
1389 // if any change on current existing media,
1390 // the Block I/O protocol need to be reinstalled.
1393 gBS
->ReinstallProtocolInterface (
1395 &gEfiBlockIoProtocolGuid
,
1401 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1404 return EFI_NO_MEDIA
;
1409 This function is called by the AtapiBlkIoReadBlocks() to perform
1410 read from media in block unit.
1412 The main command used to access media here is READ(10) Command.
1413 READ(10) Command requests that the ATAPI device media transfer
1414 specified data to the host. Data is transferred in block(sector)
1415 unit. The maximum number of blocks that can be transferred once is
1416 65536. This is the main difference between READ(10) and READ(12)
1417 Command. The maximum number of blocks in READ(12) is 2 power 32.
1419 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1420 to record all the information of the IDE device.
1421 @param Buffer A pointer to the destination buffer for the data.
1422 @param Lba The starting logical block address to read from on the
1424 @param NumberOfBlocks The number of transfer data blocks.
1426 @return status is fully dependent on the return status of AtapiPacketCommandIn() function.
1431 IN IDE_BLK_IO_DEV
*IdeDev
,
1434 IN UINTN NumberOfBlocks
1438 ATAPI_PACKET_COMMAND Packet
;
1439 ATAPI_READ10_CMD
*Read10Packet
;
1441 UINTN BlocksRemaining
;
1451 // fill command packet for Read(10) command
1453 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1454 Read10Packet
= &Packet
.Read10
;
1455 Lba32
= (UINT32
) Lba
;
1458 BlockSize
= IdeDev
->BlkIo
.Media
->BlockSize
;
1461 // limit the data bytes that can be transferred by one Read(10) Command
1465 BlocksRemaining
= NumberOfBlocks
;
1467 Status
= EFI_SUCCESS
;
1468 while (BlocksRemaining
> 0) {
1470 if (BlocksRemaining
<= MaxBlock
) {
1472 SectorCount
= (UINT16
) BlocksRemaining
;
1475 SectorCount
= MaxBlock
;
1479 // fill the Packet data structure
1482 Read10Packet
->opcode
= ATA_CMD_READ_10
;
1485 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1486 // Lba0 is MSB, Lba3 is LSB
1488 Read10Packet
->Lba3
= (UINT8
) (Lba32
& 0xff);
1489 Read10Packet
->Lba2
= (UINT8
) (Lba32
>> 8);
1490 Read10Packet
->Lba1
= (UINT8
) (Lba32
>> 16);
1491 Read10Packet
->Lba0
= (UINT8
) (Lba32
>> 24);
1494 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1495 // TranLen0 is MSB, TranLen is LSB
1497 Read10Packet
->TranLen1
= (UINT8
) (SectorCount
& 0xff);
1498 Read10Packet
->TranLen0
= (UINT8
) (SectorCount
>> 8);
1500 ByteCount
= SectorCount
* BlockSize
;
1502 if (IdeDev
->Type
== IdeCdRom
) {
1503 TimeOut
= CDROMLONGTIMEOUT
;
1505 TimeOut
= ATAPILONGTIMEOUT
;
1508 Status
= AtapiPacketCommandIn (
1511 (UINT16
*) PtrBuffer
,
1515 if (EFI_ERROR (Status
)) {
1519 Lba32
+= SectorCount
;
1520 PtrBuffer
= (UINT8
*) PtrBuffer
+ SectorCount
* BlockSize
;
1521 BlocksRemaining
-= SectorCount
;
1528 This function is called by the AtapiBlkIoWriteBlocks() to perform
1529 write onto media in block unit.
1530 The main command used to access media here is Write(10) Command.
1531 Write(10) Command requests that the ATAPI device media transfer
1532 specified data to the host. Data is transferred in block (sector)
1533 unit. The maximum number of blocks that can be transferred once is
1536 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1537 to record all the information of the IDE device.
1538 @param Buffer A pointer to the source buffer for the data.
1539 @param Lba The starting logical block address to write onto
1541 @param NumberOfBlocks The number of transfer data blocks.
1543 @return status is fully dependent on the return status of AtapiPacketCommandOut() function.
1548 IN IDE_BLK_IO_DEV
*IdeDev
,
1551 IN UINTN NumberOfBlocks
1555 ATAPI_PACKET_COMMAND Packet
;
1556 ATAPI_READ10_CMD
*Read10Packet
;
1559 UINTN BlocksRemaining
;
1568 // fill command packet for Write(10) command
1569 // Write(10) command packet has the same data structure as
1570 // Read(10) command packet,
1571 // so here use the Read10Packet data structure
1572 // for the Write(10) command packet.
1574 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1575 Read10Packet
= &Packet
.Read10
;
1577 Lba32
= (UINT32
) Lba
;
1580 BlockSize
= IdeDev
->BlkIo
.Media
->BlockSize
;
1583 // limit the data bytes that can be transferred by one Read(10) Command
1585 MaxBlock
= (UINT16
) (65536 / BlockSize
);
1587 BlocksRemaining
= NumberOfBlocks
;
1589 Status
= EFI_SUCCESS
;
1590 while (BlocksRemaining
> 0) {
1592 if (BlocksRemaining
>= MaxBlock
) {
1593 SectorCount
= MaxBlock
;
1595 SectorCount
= (UINT16
) BlocksRemaining
;
1599 // Command code is WRITE_10.
1601 Read10Packet
->opcode
= ATA_CMD_WRITE_10
;
1604 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1605 // Lba0 is MSB, Lba3 is LSB
1607 Read10Packet
->Lba3
= (UINT8
) (Lba32
& 0xff);
1608 Read10Packet
->Lba2
= (UINT8
) (Lba32
>> 8);
1609 Read10Packet
->Lba1
= (UINT8
) (Lba32
>> 16);
1610 Read10Packet
->Lba0
= (UINT8
) (Lba32
>> 24);
1613 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1614 // TranLen0 is MSB, TranLen is LSB
1616 Read10Packet
->TranLen1
= (UINT8
) (SectorCount
& 0xff);
1617 Read10Packet
->TranLen0
= (UINT8
) (SectorCount
>> 8);
1619 ByteCount
= SectorCount
* BlockSize
;
1621 Status
= AtapiPacketCommandOut (
1624 (UINT16
*) PtrBuffer
,
1628 if (EFI_ERROR (Status
)) {
1632 Lba32
+= SectorCount
;
1633 PtrBuffer
= ((UINT8
*) PtrBuffer
+ SectorCount
* BlockSize
);
1634 BlocksRemaining
-= SectorCount
;
1640 This function is used to implement the Soft Reset on the specified
1641 ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
1642 Soft Reset Command special for ATAPI device, and it only take effects
1643 on the specified ATAPI device, not on the whole IDE bus.
1644 Since the ATAPI soft reset is needed when device is in exceptional
1645 condition (such as BSY bit is always set ), I think the Soft Reset
1646 command should be sent without waiting for the BSY clear and DRDY
1648 This function is called by IdeBlkIoReset(),
1649 a interface function of Block I/O protocol.
1651 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1652 to record all the information of the IDE device.
1654 @retval EFI_SUCCESS Soft reset completes successfully.
1655 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
1660 IN IDE_BLK_IO_DEV
*IdeDev
1668 // for ATAPI device, no need to wait DRDY ready after device selecting.
1669 // (bit7 and bit5 are both set to 1 for backward compatibility)
1671 DeviceSelect
= (UINT8
) (((BIT7
| BIT5
) | (IdeDev
->Device
<< 4)));
1672 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
1674 Command
= ATA_CMD_SOFT_RESET
;
1675 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, Command
);
1678 // BSY cleared is the only status return to the host by the device
1679 // when reset is completed.
1680 // slave device needs at most 31s to clear BSY
1682 Status
= WaitForBSYClear (IdeDev
, 31000);
1683 if (EFI_ERROR (Status
)) {
1684 return EFI_DEVICE_ERROR
;
1688 // stall 5 seconds to make the device status stable
1690 gBS
->Stall (5000000);
1696 This function is the ATAPI implementation for ReadBlocks in the
1697 Block I/O Protocol interface.
1699 @param IdeBlkIoDevice Indicates the calling context.
1700 @param MediaId The media id that the read request is for.
1701 @param Lba The starting logical block address to read from on the device.
1702 @param BufferSize The size of the Buffer in bytes. This must be a multiple
1703 of the intrinsic block size of the device.
1704 @param Buffer A pointer to the destination buffer for the data. The caller
1705 is responsible for either having implicit or explicit
1706 ownership of the memory that data is read into.
1708 @retval EFI_SUCCESS Read Blocks successfully.
1709 @retval EFI_DEVICE_ERROR Read Blocks failed.
1710 @retval EFI_NO_MEDIA There is no media in the device.
1711 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1712 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
1713 intrinsic block size of the device.
1714 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1715 or the data buffer is not valid.
1718 AtapiBlkIoReadBlocks (
1719 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1722 IN UINTN BufferSize
,
1726 EFI_BLOCK_IO_MEDIA
*Media
;
1728 UINTN NumberOfBlocks
;
1731 BOOLEAN MediaChange
;
1733 if (Buffer
== NULL
) {
1734 return EFI_INVALID_PARAMETER
;
1737 if (BufferSize
== 0) {
1742 // ATAPI device media is removable, so it is a must
1743 // to detect media first before read operation
1745 MediaChange
= FALSE
;
1746 Status
= AtapiDetectMedia (IdeBlkIoDevice
, &MediaChange
);
1747 if (EFI_ERROR (Status
)) {
1749 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1750 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1751 IdeBlkIoDevice
->Cache
= NULL
;
1757 // Get the intrinsic block size
1759 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1760 BlockSize
= Media
->BlockSize
;
1762 NumberOfBlocks
= BufferSize
/ BlockSize
;
1764 if (!(Media
->MediaPresent
)) {
1766 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1767 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1768 IdeBlkIoDevice
->Cache
= NULL
;
1770 return EFI_NO_MEDIA
;
1774 if ((MediaId
!= Media
->MediaId
) || MediaChange
) {
1776 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1777 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1778 IdeBlkIoDevice
->Cache
= NULL
;
1780 return EFI_MEDIA_CHANGED
;
1783 if (BufferSize
% BlockSize
!= 0) {
1784 return EFI_BAD_BUFFER_SIZE
;
1787 if (Lba
> Media
->LastBlock
) {
1788 return EFI_INVALID_PARAMETER
;
1791 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1792 return EFI_INVALID_PARAMETER
;
1795 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1796 return EFI_INVALID_PARAMETER
;
1800 // if all the parameters are valid, then perform read sectors command
1801 // to transfer data from device to host.
1803 Status
= AtapiReadSectors (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
1804 if (EFI_ERROR (Status
)) {
1805 return EFI_DEVICE_ERROR
;
1809 // Read blocks succeeded
1813 // save the first block to the cache for performance
1815 if (Lba
== 0 && (IdeBlkIoDevice
->Cache
== NULL
)) {
1816 IdeBlkIoDevice
->Cache
= AllocatePool (BlockSize
);
1817 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1818 CopyMem ((UINT8
*) IdeBlkIoDevice
->Cache
, (UINT8
*) Buffer
, BlockSize
);
1826 This function is the ATAPI implementation for WriteBlocks in the
1827 Block I/O Protocol interface.
1829 @param IdeBlkIoDevice Indicates the calling context.
1830 @param MediaId The media id that the write request is for.
1831 @param Lba The starting logical block address to write onto the device.
1832 @param BufferSize The size of the Buffer in bytes. This must be a multiple
1833 of the intrinsic block size of the device.
1834 @param Buffer A pointer to the source buffer for the data. The caller
1835 is responsible for either having implicit or explicit ownership
1836 of the memory that data is written from.
1838 @retval EFI_SUCCESS Write Blocks successfully.
1839 @retval EFI_DEVICE_ERROR Write Blocks failed.
1840 @retval EFI_NO_MEDIA There is no media in the device.
1841 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1842 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
1843 intrinsic block size of the device.
1844 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1845 or the data buffer is not valid.
1847 @retval EFI_WRITE_PROTECTED The write protected is enabled or the media does not support write
1850 AtapiBlkIoWriteBlocks (
1851 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1854 IN UINTN BufferSize
,
1859 EFI_BLOCK_IO_MEDIA
*Media
;
1861 UINTN NumberOfBlocks
;
1863 BOOLEAN MediaChange
;
1865 if (Lba
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1866 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1867 IdeBlkIoDevice
->Cache
= NULL
;
1870 if (Buffer
== NULL
) {
1871 return EFI_INVALID_PARAMETER
;
1874 if (BufferSize
== 0) {
1879 // ATAPI device media is removable,
1880 // so it is a must to detect media first before write operation
1882 MediaChange
= FALSE
;
1883 Status
= AtapiDetectMedia (IdeBlkIoDevice
, &MediaChange
);
1884 if (EFI_ERROR (Status
)) {
1886 if (Lba
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1887 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1888 IdeBlkIoDevice
->Cache
= NULL
;
1894 // Get the intrinsic block size
1896 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1897 BlockSize
= Media
->BlockSize
;
1898 NumberOfBlocks
= BufferSize
/ BlockSize
;
1900 if (!(Media
->MediaPresent
)) {
1902 if (Lba
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1903 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1904 IdeBlkIoDevice
->Cache
= NULL
;
1906 return EFI_NO_MEDIA
;
1909 if ((MediaId
!= Media
->MediaId
) || MediaChange
) {
1911 if (Lba
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1912 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1913 IdeBlkIoDevice
->Cache
= NULL
;
1915 return EFI_MEDIA_CHANGED
;
1918 if (Media
->ReadOnly
) {
1919 return EFI_WRITE_PROTECTED
;
1922 if (BufferSize
% BlockSize
!= 0) {
1923 return EFI_BAD_BUFFER_SIZE
;
1926 if (Lba
> Media
->LastBlock
) {
1927 return EFI_INVALID_PARAMETER
;
1930 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1931 return EFI_INVALID_PARAMETER
;
1934 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1935 return EFI_INVALID_PARAMETER
;
1939 // if all the parameters are valid,
1940 // then perform write sectors command to transfer data from host to device.
1942 Status
= AtapiWriteSectors (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
1943 if (EFI_ERROR (Status
)) {
1944 return EFI_DEVICE_ERROR
;