2 Copyright (c) 2006 - 2008, 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.
16 This function is used to get the current status of the media residing
17 in the LS-120 drive or ZIP drive. The media status is returned in the
21 pointer pointing to IDE_BLK_IO_DEV data structure, used
22 to record all the information of the IDE device.
25 The media status is achieved successfully and the media
28 @retval EFI_DEVICE_ERROR
29 Get Media Status Command is failed.
32 There is no media in the drive.
34 @retval EFI_WRITE_PROTECTED
35 The media is writing protected.
38 This function must be called after the LS120EnableMediaStatus()
39 with second parameter set to TRUE
40 (means enable media status notification) is called.
45 IN IDE_BLK_IO_DEV
*IdeDev
52 // Poll Alternate Register for BSY clear within timeout.
54 EfiStatus
= WaitForBSYClear2 (IdeDev
, ATATIMEOUT
);
55 if (EFI_ERROR (EfiStatus
)) {
56 return EFI_DEVICE_ERROR
;
60 // Select device via Device/Head Register.
62 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4 | 0xe0);
63 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
66 // Poll Alternate Register for DRDY set within timeout.
67 // After device is selected, DRDY set indicates the device is ready to
70 EfiStatus
= DRDYReady2 (IdeDev
, ATATIMEOUT
);
71 if (EFI_ERROR (EfiStatus
)) {
72 return EFI_DEVICE_ERROR
;
76 // Get Media Status Command is sent
78 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, 0xDA);
81 // BSY bit will clear after command is complete.
83 EfiStatus
= WaitForBSYClear2 (IdeDev
, ATATIMEOUT
);
84 if (EFI_ERROR (EfiStatus
)) {
85 return EFI_DEVICE_ERROR
;
89 // the media status is returned by the command in the ERROR register
91 StatusValue
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
93 if ((StatusValue
& BIT1
) != 0) {
97 if ((StatusValue
& BIT6
) != 0) {
98 return EFI_WRITE_PROTECTED
;
105 This function is used to send Enable Media Status Notification Command
106 or Disable Media Status Notification Command.
109 pointer pointing to IDE_BLK_IO_DEV data structure, used
110 to record all the information of the IDE device.
113 a flag that indicates whether enable or disable media
117 If command completes successfully.
119 @retval EFI_DEVICE_ERROR
124 LS120EnableMediaStatus (
125 IN IDE_BLK_IO_DEV
*IdeDev
,
133 // Poll Alternate Register for BSY clear within timeout.
135 Status
= WaitForBSYClear2 (IdeDev
, ATATIMEOUT
);
136 if (EFI_ERROR (Status
)) {
137 return EFI_DEVICE_ERROR
;
141 // Select device via Device/Head Register.
143 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4 | 0xe0);
144 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
147 // Poll Alternate Register for DRDY set within timeout.
148 // After device is selected, DRDY set indicates the device is ready to
151 Status
= DRDYReady2 (IdeDev
, ATATIMEOUT
);
152 if (EFI_ERROR (Status
)) {
153 return EFI_DEVICE_ERROR
;
158 // 0x95: Enable media status notification
160 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x95);
163 // 0x31: Disable media status notification
165 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x31);
168 // Set Feature Command is sent
170 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, 0xEF);
173 // BSY bit will clear after command is complete.
175 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
176 if (EFI_ERROR (Status
)) {
177 return EFI_DEVICE_ERROR
;
184 This function is called by DiscoverIdeDevice() during its device
187 Its main purpose is to get enough information for the device media
188 to fill in the Media data structure of the Block I/O Protocol interface.
190 There are 5 steps to reach such objective:
192 1. Sends out the ATAPI Identify Command to the specified device.
193 Only ATAPI device responses to this command. If the command succeeds,
194 it returns the Identify data structure which filled with information
195 about the device. Since the ATAPI device contains removable media,
196 the only meaningful information is the device module name.
198 2. Sends out ATAPI Inquiry Packet Command to the specified device.
199 This command will return inquiry data of the device, which contains
200 the device type information.
202 3. Allocate sense data space for future use. We don't detect the media
203 presence here to improvement boot performance, especially when CD
204 media is present. The media detection will be performed just before
205 each BLK_IO read/write
208 pointer pointing to IDE_BLK_IO_DEV data structure, used
209 to record all the information of the IDE device.
212 Identify ATAPI device successfully.
214 @retval EFI_DEVICE_ERROR
215 ATAPI Identify Device Command failed or device type
216 is not supported by this IDE driver.
219 Parameter "IdeDev" will be updated in this function.
221 TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
222 TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
226 IN IDE_BLK_IO_DEV
*IdeDev
229 EFI_IDENTIFY_DATA
*AtapiIdentifyPointer
;
236 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
238 AtapiIdentifyPointer
= AllocatePool (sizeof (EFI_IDENTIFY_DATA
));
239 if (AtapiIdentifyPointer
== NULL
) {
240 return EFI_OUT_OF_RESOURCES
;
243 // Send ATAPI Identify Command to get IDENTIFY data.
245 Status
= AtaPioDataIn (
247 (VOID
*) AtapiIdentifyPointer
,
248 sizeof (EFI_IDENTIFY_DATA
),
249 ATA_CMD_IDENTIFY_DEVICE
,
257 if (EFI_ERROR (Status
)) {
258 gBS
->FreePool (AtapiIdentifyPointer
);
259 return EFI_DEVICE_ERROR
;
262 IdeDev
->pIdData
= AtapiIdentifyPointer
;
263 PrintAtaModuleName (IdeDev
);
266 // Send ATAPI Inquiry Packet Command to get INQUIRY data.
268 Status
= AtapiInquiry (IdeDev
);
269 if (EFI_ERROR (Status
)) {
270 gBS
->FreePool (IdeDev
->pIdData
);
272 // Make sure the pIdData will not be freed again.
274 IdeDev
->pIdData
= NULL
;
275 return EFI_DEVICE_ERROR
;
278 // Get media removable info from INQUIRY data.
280 IdeDev
->BlkIo
.Media
->RemovableMedia
= (UINT8
) ((IdeDev
->pInquiryData
->RMB
& 0x80) == 0x80);
283 // Identify device type via INQUIRY data.
285 switch (IdeDev
->pInquiryData
->peripheral_type
& 0x1f) {
293 // device is LS120 or ZIP drive.
295 IdeDev
->Type
= IdeMagnetic
;
297 IdeDev
->BlkIo
.Media
->MediaId
= 0;
299 // Give initial value
301 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
303 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
304 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
312 IdeDev
->Type
= IdeCdRom
;
313 IdeDev
->BlkIo
.Media
->MediaId
= 0;
315 // Give initial value
317 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
319 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
320 IdeDev
->BlkIo
.Media
->BlockSize
= 0x800;
321 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
340 IdeDev
->Type
= IdeUnknown
;
341 gBS
->FreePool (IdeDev
->pIdData
);
342 gBS
->FreePool (IdeDev
->pInquiryData
);
344 // Make sure the pIdData and pInquiryData will not be freed again.
346 IdeDev
->pIdData
= NULL
;
347 IdeDev
->pInquiryData
= NULL
;
348 return EFI_DEVICE_ERROR
;
352 // original sense data numbers
354 IdeDev
->SenseDataNumber
= 20;
356 IdeDev
->SenseData
= AllocatePool (IdeDev
->SenseDataNumber
* sizeof (ATAPI_REQUEST_SENSE_DATA
));
357 if (IdeDev
->SenseData
== NULL
) {
358 gBS
->FreePool (IdeDev
->pIdData
);
359 gBS
->FreePool (IdeDev
->pInquiryData
);
361 // Make sure the pIdData and pInquiryData will not be freed again.
363 IdeDev
->pIdData
= NULL
;
364 IdeDev
->pInquiryData
= NULL
;
365 return EFI_OUT_OF_RESOURCES
;
372 Sends out ATAPI Inquiry Packet Command to the specified device.
373 This command will return INQUIRY data of the device.
376 pointer pointing to IDE_BLK_IO_DEV data structure, used
377 to record all the information of the IDE device.
380 Inquiry command completes successfully.
382 @retval EFI_DEVICE_ERROR
383 Inquiry command failed.
386 Parameter "IdeDev" will be updated in this function.
391 IN IDE_BLK_IO_DEV
*IdeDev
394 ATAPI_PACKET_COMMAND Packet
;
396 ATAPI_INQUIRY_DATA
*InquiryData
;
399 // prepare command packet for the ATAPI Inquiry Packet Command.
401 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
402 Packet
.Inquiry
.opcode
= ATA_CMD_INQUIRY
;
403 Packet
.Inquiry
.page_code
= 0;
404 Packet
.Inquiry
.allocation_length
= sizeof (ATAPI_INQUIRY_DATA
);
406 InquiryData
= AllocatePool (sizeof (ATAPI_INQUIRY_DATA
));
407 if (InquiryData
== NULL
) {
408 return EFI_DEVICE_ERROR
;
412 // Send command packet and get requested Inquiry data.
414 Status
= AtapiPacketCommandIn (
417 (UINT16
*) InquiryData
,
418 sizeof (ATAPI_INQUIRY_DATA
),
421 if (EFI_ERROR (Status
)) {
422 gBS
->FreePool (InquiryData
);
423 return EFI_DEVICE_ERROR
;
426 IdeDev
->pInquiryData
= InquiryData
;
432 This function is used to send out ATAPI commands conforms to the
433 Packet Command with PIO Data In Protocol.
436 pointer pointing to IDE_BLK_IO_DEV data structure, used
437 to record all the information of the IDE device.
440 pointer pointing to ATAPI_PACKET_COMMAND data structure
441 which contains the contents of the command.
444 buffer contained data transferred from device to host.
447 data size in byte unit of the buffer.
450 this parameter is used to specify the timeout
451 value for the PioReadWriteData() function.
454 send out the ATAPI packet command successfully
455 and device sends data successfully.
457 @retval EFI_DEVICE_ERROR
458 the device failed to send data.
462 AtapiPacketCommandIn (
463 IN IDE_BLK_IO_DEV
*IdeDev
,
464 IN ATAPI_PACKET_COMMAND
*Packet
,
470 UINT16
*CommandIndex
;
475 // Set all the command parameters by fill related registers.
476 // Before write to all the following registers, BSY and DRQ must be 0.
478 Status
= DRQClear2 (IdeDev
, ATAPITIMEOUT
);
479 if (EFI_ERROR (Status
)) {
484 // Select device via Device/Head Register.
488 IdeDev
->IoPort
->Head
,
489 (UINT8
) ((IdeDev
->Device
<< 4) | ATA_DEFAULT_CMD
) // DEFAULT_CMD: 0xa0 (1010,0000)
495 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x00);
498 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
499 // determine how many data should be transferred.
503 IdeDev
->IoPort
->CylinderLsb
,
504 (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff)
508 IdeDev
->IoPort
->CylinderMsb
,
509 (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8)
513 // ATA_DEFAULT_CTL:0x0a (0000,1010)
516 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, ATA_DEFAULT_CTL
);
519 // Send Packet command to inform device
520 // that the following data bytes are command packet.
522 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, ATA_CMD_PACKET
);
524 Status
= DRQReady (IdeDev
, ATAPITIMEOUT
);
525 if (EFI_ERROR (Status
)) {
530 // Send out command packet
532 CommandIndex
= Packet
->Data16
;
533 for (Count
= 0; Count
< 6; Count
++, CommandIndex
++) {
535 IDEWritePortW (IdeDev
->PciIo
, IdeDev
->IoPort
->Data
, *CommandIndex
);
540 // call PioReadWriteData() function to get
541 // requested transfer data form device.
543 return PioReadWriteData (IdeDev
, Buffer
, ByteCount
, 1, TimeOut
);
547 This function is used to send out ATAPI commands conforms to the
548 Packet Command with PIO Data Out Protocol.
551 pointer pointing to IDE_BLK_IO_DEV data structure, used
552 to record all the information of the IDE device.
555 pointer pointing to ATAPI_PACKET_COMMAND data structure
556 which contains the contents of the command.
559 buffer contained data transferred from host to device.
562 data size in byte unit of the buffer.
565 this parameter is used to specify the timeout
566 value for the PioReadWriteData() function.
569 send out the ATAPI packet command successfully
570 and device received data successfully.
572 @retval EFI_DEVICE_ERROR
573 the device failed to send data.
577 AtapiPacketCommandOut (
578 IN IDE_BLK_IO_DEV
*IdeDev
,
579 IN ATAPI_PACKET_COMMAND
*Packet
,
585 UINT16
*CommandIndex
;
590 // set all the command parameters
591 // Before write to all the following registers, BSY and DRQ must be 0.
593 Status
= DRQClear2 (IdeDev
, ATAPITIMEOUT
);
594 if (EFI_ERROR (Status
)) {
599 // Select device via Device/Head Register.
603 IdeDev
->IoPort
->Head
,
604 (UINT8
) ((IdeDev
->Device
<< 4) | ATA_DEFAULT_CMD
) // ATA_DEFAULT_CMD: 0xa0 (1010,0000)
610 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x00);
613 // set the transfersize to ATAPI_MAX_BYTE_COUNT to
614 // let the device determine how many data should be transferred.
618 IdeDev
->IoPort
->CylinderLsb
,
619 (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff)
623 IdeDev
->IoPort
->CylinderMsb
,
624 (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8)
628 // DEFAULT_CTL:0x0a (0000,1010)
631 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, ATA_DEFAULT_CTL
);
634 // Send Packet command to inform device
635 // that the following data bytes are command packet.
637 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, ATA_CMD_PACKET
);
639 Status
= DRQReady2 (IdeDev
, ATAPITIMEOUT
);
640 if (EFI_ERROR (Status
)) {
645 // Send out command packet
647 CommandIndex
= Packet
->Data16
;
648 for (Count
= 0; Count
< 6; Count
++, CommandIndex
++) {
649 IDEWritePortW (IdeDev
->PciIo
, IdeDev
->IoPort
->Data
, *CommandIndex
);
654 // call PioReadWriteData() function to send requested transfer data to device.
656 return PioReadWriteData (IdeDev
, Buffer
, ByteCount
, 0, TimeOut
);
660 This function is called by either AtapiPacketCommandIn() or
661 AtapiPacketCommandOut(). It is used to transfer data between
662 host and device. The data direction is specified by the fourth
666 pointer pointing to IDE_BLK_IO_DEV data structure, used
667 to record all the information of the IDE device.
670 buffer contained data transferred between host and device.
673 data size in byte unit of the buffer.
676 flag used to determine the data transfer direction.
677 Read equals 1, means data transferred from device to host;
678 Read equals 0, means data transferred from host to device.
681 timeout value for wait DRQ ready before each data
685 data is transferred successfully.
687 @retval EFI_DEVICE_ERROR
688 the device failed to transfer data.
693 IN IDE_BLK_IO_DEV
*IdeDev
,
701 // required transfer data in word unit.
703 UINT32 RequiredWordCount
;
706 // actual transfer data in word unit.
708 UINT32 ActualWordCount
;
714 // No data transfer is premitted.
716 if (ByteCount
== 0) {
720 // for performance, we assert the ByteCount is an even number
721 // which is actually a resonable assumption
722 ASSERT((ByteCount
%2) == 0);
725 RequiredWordCount
= ByteCount
/ 2;
727 // ActuralWordCount means the word count of data really transferred.
731 while (ActualWordCount
< RequiredWordCount
) {
734 // before each data transfer stream, the host should poll DRQ bit ready,
735 // to see whether indicates device is ready to transfer data.
737 Status
= DRQReady2 (IdeDev
, TimeOut
);
738 if (EFI_ERROR (Status
)) {
739 return CheckErrorStatus (IdeDev
);
743 // read Status Register will clear interrupt
745 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
748 // get current data transfer size from Cylinder Registers.
750 WordCount
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
) << 8;
751 WordCount
= WordCount
| IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
752 WordCount
= WordCount
& 0xffff;
755 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
758 IDEReadPortWMultiple (
760 IdeDev
->IoPort
->Data
,
765 IDEWritePortWMultiple (
767 IdeDev
->IoPort
->Data
,
773 PtrBuffer
+= WordCount
;
774 ActualWordCount
+= WordCount
;
779 // In the case where the drive wants to send more data than we need to read,
780 // the DRQ bit will be set and cause delays from DRQClear2().
781 // We need to read data from the drive until it clears DRQ so we can move on.
783 AtapiReadPendingData (IdeDev
);
787 // After data transfer is completed, normally, DRQ bit should clear.
789 Status
= DRQClear2 (IdeDev
, ATAPITIMEOUT
);
790 if (EFI_ERROR (Status
)) {
791 return EFI_DEVICE_ERROR
;
795 // read status register to check whether error happens.
797 return CheckErrorStatus (IdeDev
);
801 Sends out ATAPI Test Unit Ready Packet Command to the specified device
802 to find out whether device is accessible.
804 @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
805 to record all the information of the IDE device.
806 @param[out] *SResult Sense result for this packet command.
808 @retval EFI_SUCCESS Device is accessible.
809 @retval EFI_DEVICE_ERROR Device is not accessible.
814 IN IDE_BLK_IO_DEV
*IdeDev
,
815 OUT SENSE_RESULT
*SResult
818 ATAPI_PACKET_COMMAND Packet
;
823 // fill command packet
825 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
826 Packet
.TestUnitReady
.opcode
= ATA_CMD_TEST_UNIT_READY
;
829 // send command packet
831 Status
= AtapiPacketCommandIn (IdeDev
, &Packet
, NULL
, 0, ATAPITIMEOUT
);
832 if (EFI_ERROR (Status
)) {
836 Status
= AtapiRequestSense (IdeDev
, &SenseCount
);
837 if (EFI_ERROR (Status
)) {
841 ParseSenseData (IdeDev
, SenseCount
, SResult
);
846 Sends out ATAPI Request Sense Packet Command to the specified device.
847 This command will return all the current Sense data in the device.
848 This function will pack all the Sense data in one single buffer.
851 pointer pointing to IDE_BLK_IO_DEV data structure, used
852 to record all the information of the IDE device.
854 @param[out] **SenseCounts
855 allocated in this function, and freed by the calling function.
856 This buffer is used to accommodate all the sense data returned
860 Request Sense command completes successfully.
862 @retval EFI_DEVICE_ERROR
863 Request Sense command failed.
868 IN IDE_BLK_IO_DEV
*IdeDev
,
869 OUT UINTN
*SenseCounts
873 ATAPI_REQUEST_SENSE_DATA
*Sense
;
875 BOOLEAN FetchSenseData
;
876 ATAPI_PACKET_COMMAND Packet
;
880 ZeroMem (IdeDev
->SenseData
, sizeof (ATAPI_REQUEST_SENSE_DATA
) * (IdeDev
->SenseDataNumber
));
882 // fill command packet for Request Sense Packet Command
884 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
885 Packet
.RequestSence
.opcode
= ATA_CMD_REQUEST_SENSE
;
886 Packet
.RequestSence
.allocation_length
= sizeof (ATAPI_REQUEST_SENSE_DATA
);
889 // initialize pointer
891 Ptr
= (UINT16
*) IdeDev
->SenseData
;
893 // request sense data from device continuously until no sense data
894 // exists in the device.
896 for (FetchSenseData
= TRUE
; FetchSenseData
;) {
898 Sense
= (ATAPI_REQUEST_SENSE_DATA
*) Ptr
;
901 // send out Request Sense Packet Command and get one Sense data form device
903 Status
= AtapiPacketCommandIn (
907 sizeof (ATAPI_REQUEST_SENSE_DATA
),
911 // failed to get Sense data
913 if (EFI_ERROR (Status
)) {
914 if (*SenseCounts
== 0) {
915 return EFI_DEVICE_ERROR
;
923 // We limit MAX sense data count to 20 in order to avoid dead loop. Some
924 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
925 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
926 // supposed to be large enough for any ATAPI device.
928 if ((Sense
->sense_key
!= ATA_SK_NO_SENSE
) && ((*SenseCounts
) < 20)) {
930 // Ptr is word-based pointer
932 Ptr
+= (sizeof (ATAPI_REQUEST_SENSE_DATA
) + 1) >> 1;
936 // when no sense key, skip out the loop
938 FetchSenseData
= FALSE
;
946 Sends out ATAPI Read Capacity Packet Command to the specified device.
947 This command will return the information regarding the capacity of the
950 Current device status will impact device's response to the Read Capacity
951 Command. For example, if the device once reset, the Read Capacity
952 Command will fail. The Sense data record the current device status, so
953 if the Read Capacity Command failed, the Sense data must be requested
954 and be analyzed to determine if the Read Capacity Command should retry.
956 @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
957 to record all the information of the IDE device.
958 @param[out] SResult Sense result for this packet command
960 @retval EFI_SUCCESS Read Capacity Command finally completes successfully.
961 @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.
963 @note Parameter "IdeDev" will be updated in this function.
965 TODO: EFI_NOT_READY - add return value to function comment
969 IN IDE_BLK_IO_DEV
*IdeDev
,
970 OUT SENSE_RESULT
*SResult
974 // status returned by Read Capacity Packet Command
977 EFI_STATUS SenseStatus
;
978 ATAPI_PACKET_COMMAND Packet
;
982 // used for capacity data returned from ATAPI device
984 ATAPI_READ_CAPACITY_DATA Data
;
985 ATAPI_READ_FORMAT_CAPACITY_DATA FormatData
;
987 ZeroMem (&Data
, sizeof (Data
));
988 ZeroMem (&FormatData
, sizeof (FormatData
));
990 if (IdeDev
->Type
== IdeCdRom
) {
992 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
993 Packet
.Inquiry
.opcode
= ATA_CMD_READ_CAPACITY
;
994 Status
= AtapiPacketCommandIn (
998 sizeof (ATAPI_READ_CAPACITY_DATA
),
1004 // Type == IdeMagnetic
1006 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1007 Packet
.ReadFormatCapacity
.opcode
= ATA_CMD_READ_FORMAT_CAPACITY
;
1008 Packet
.ReadFormatCapacity
.allocation_length_lo
= 12;
1009 Status
= AtapiPacketCommandIn (
1012 (UINT16
*) &FormatData
,
1013 sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA
),
1018 if (Status
== EFI_TIMEOUT
) {
1022 SenseStatus
= AtapiRequestSense (IdeDev
, &SenseCount
);
1024 if (!EFI_ERROR (SenseStatus
)) {
1025 ParseSenseData (IdeDev
, SenseCount
, SResult
);
1027 if (!EFI_ERROR (Status
) && *SResult
== SenseNoSenseKey
) {
1028 if (IdeDev
->Type
== IdeCdRom
) {
1030 IdeDev
->BlkIo
.Media
->LastBlock
= (Data
.LastLba3
<< 24) |
1031 (Data
.LastLba2
<< 16) |
1032 (Data
.LastLba1
<< 8) |
1035 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
1037 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
1040 // Because the user data portion in the sector of the Data CD supported
1043 IdeDev
->BlkIo
.Media
->BlockSize
= 0x800;
1046 if (IdeDev
->Type
== IdeMagnetic
) {
1048 if (FormatData
.DesCode
== 3) {
1049 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1050 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1053 IdeDev
->BlkIo
.Media
->LastBlock
= (FormatData
.LastLba3
<< 24) |
1054 (FormatData
.LastLba2
<< 16) |
1055 (FormatData
.LastLba1
<< 8) |
1056 FormatData
.LastLba0
;
1057 if (IdeDev
->BlkIo
.Media
->LastBlock
!= 0) {
1058 IdeDev
->BlkIo
.Media
->LastBlock
--;
1060 IdeDev
->BlkIo
.Media
->BlockSize
= (FormatData
.BlockSize2
<< 16) |
1061 (FormatData
.BlockSize1
<< 8) |
1062 FormatData
.BlockSize0
;
1064 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
1066 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1068 // Return EFI_NOT_READY operation succeeds but returned capacity is 0
1070 return EFI_NOT_READY
;
1073 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
1082 return EFI_DEVICE_ERROR
;
1087 Used before read/write blocks from/to ATAPI device media.
1088 Since ATAPI device media is removable, it is necessary to detect
1089 whether media is present and get current present media's
1090 information, and if media has been changed, Block I/O Protocol
1091 need to be reinstalled.
1094 pointer pointing to IDE_BLK_IO_DEV data structure, used
1095 to record all the information of the IDE device.
1097 @param[out] *MediaChange
1098 return value that indicates if the media of the device has been
1102 media found successfully.
1104 @retval EFI_DEVICE_ERROR
1105 any error encounters during media detection.
1107 @retval EFI_NO_MEDIA
1111 parameter IdeDev may be updated in this function.
1116 IN IDE_BLK_IO_DEV
*IdeDev
,
1117 OUT BOOLEAN
*MediaChange
1121 EFI_STATUS CleanStateStatus
;
1122 EFI_BLOCK_IO_MEDIA OldMediaInfo
;
1124 UINTN RetryNotReady
;
1125 SENSE_RESULT SResult
;
1126 BOOLEAN WriteProtected
;
1128 CopyMem (&OldMediaInfo
, IdeDev
->BlkIo
.Media
, sizeof (EFI_BLOCK_IO_MEDIA
));
1129 *MediaChange
= FALSE
;
1131 // Retry for SenseDeviceNotReadyNeedRetry.
1132 // Each retry takes 1s and we limit the upper boundary to
1133 // 120 times about 2 min.
1135 RetryNotReady
= 120;
1138 // Do Test Unit Ready
1145 while (RetryTimes
!= 0) {
1147 Status
= AtapiTestUnitReady (IdeDev
, &SResult
);
1149 if (EFI_ERROR (Status
)) {
1151 // Test Unit Ready error without sense data.
1152 // For some devices, this means there's extra data
1153 // that has not been read, so we read these extra
1154 // data out before going on.
1156 CleanStateStatus
= AtapiReadPendingData (IdeDev
);
1157 if (EFI_ERROR (CleanStateStatus
)) {
1159 // Busy wait failed, try again
1164 // Try again without counting down RetryTimes
1169 case SenseNoSenseKey
:
1170 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1174 // Media present but the internal structure need refreshed.
1175 // Try Read Capacity
1181 case SenseDeviceNotReadyNeedRetry
:
1182 if (--RetryNotReady
== 0) {
1183 return EFI_DEVICE_ERROR
;
1185 gBS
->Stall (1000 * STALL_1_MILLI_SECOND
);
1190 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1191 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1195 case SenseDeviceNotReadyNoRetry
:
1196 case SenseMediaError
:
1197 return EFI_DEVICE_ERROR
;
1199 case SenseMediaChange
:
1200 IdeDev
->BlkIo
.Media
->MediaId
++;
1211 return EFI_DEVICE_ERROR
;
1219 while (RetryTimes
!= 0) {
1221 Status
= AtapiReadCapacity (IdeDev
, &SResult
);
1223 if (EFI_ERROR (Status
)) {
1228 case SenseNoSenseKey
:
1232 case SenseDeviceNotReadyNeedRetry
:
1234 // We use Test Unit Ready to retry which
1241 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1242 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1246 case SenseDeviceNotReadyNoRetry
:
1247 case SenseMediaError
:
1248 return EFI_DEVICE_ERROR
;
1250 case SenseMediaChange
:
1251 IdeDev
->BlkIo
.Media
->MediaId
++;
1262 return EFI_DEVICE_ERROR
;
1266 // the following code is to check the write-protected for LS120 media
1268 if ((IdeDev
->BlkIo
.Media
->MediaPresent
) && (IdeDev
->Type
== IdeMagnetic
)) {
1270 Status
= IsLS120orZipWriteProtected (IdeDev
, &WriteProtected
);
1271 if (!EFI_ERROR (Status
)) {
1273 if (WriteProtected
) {
1275 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
1278 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
1284 if (IdeDev
->BlkIo
.Media
->MediaId
!= OldMediaInfo
.MediaId
) {
1286 // Media change information got from the device
1288 *MediaChange
= TRUE
;
1291 if (IdeDev
->BlkIo
.Media
->ReadOnly
!= OldMediaInfo
.ReadOnly
) {
1292 *MediaChange
= TRUE
;
1293 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1296 if (IdeDev
->BlkIo
.Media
->BlockSize
!= OldMediaInfo
.BlockSize
) {
1297 *MediaChange
= TRUE
;
1298 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1301 if (IdeDev
->BlkIo
.Media
->LastBlock
!= OldMediaInfo
.LastBlock
) {
1302 *MediaChange
= TRUE
;
1303 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1306 if (IdeDev
->BlkIo
.Media
->MediaPresent
!= OldMediaInfo
.MediaPresent
) {
1307 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1309 // when change from no media to media present, reset the MediaId to 1.
1311 IdeDev
->BlkIo
.Media
->MediaId
= 1;
1314 // when no media, reset the MediaId to zero.
1316 IdeDev
->BlkIo
.Media
->MediaId
= 0;
1319 *MediaChange
= TRUE
;
1323 // if any change on current existing media,
1324 // the Block I/O protocol need to be reinstalled.
1327 gBS
->ReinstallProtocolInterface (
1329 &gEfiBlockIoProtocolGuid
,
1335 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1338 return EFI_NO_MEDIA
;
1343 This function is called by the AtapiBlkIoReadBlocks() to perform
1344 read from media in block unit.
1346 The main command used to access media here is READ(10) Command.
1347 READ(10) Command requests that the ATAPI device media transfer
1348 specified data to the host. Data is transferred in block(sector)
1349 unit. The maximum number of blocks that can be transferred once is
1350 65536. This is the main difference between READ(10) and READ(12)
1351 Command. The maximum number of blocks in READ(12) is 2 power 32.
1354 pointer pointing to IDE_BLK_IO_DEV data structure, used
1355 to record all the information of the IDE device.
1358 A pointer to the destination buffer for the data.
1361 The starting logical block address to read from
1362 on the device media.
1364 @param[in] NumberOfBlocks
1365 The number of transfer data blocks.
1367 @return status is fully dependent on the return status
1368 of AtapiPacketCommandIn() function.
1373 IN IDE_BLK_IO_DEV
*IdeDev
,
1376 IN UINTN NumberOfBlocks
1380 ATAPI_PACKET_COMMAND Packet
;
1381 ATAPI_READ10_CMD
*Read10Packet
;
1383 UINTN BlocksRemaining
;
1393 // fill command packet for Read(10) command
1395 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1396 Read10Packet
= &Packet
.Read10
;
1397 Lba32
= (UINT32
) Lba
;
1400 BlockSize
= IdeDev
->BlkIo
.Media
->BlockSize
;
1403 // limit the data bytes that can be transferred by one Read(10) Command
1407 BlocksRemaining
= NumberOfBlocks
;
1409 Status
= EFI_SUCCESS
;
1410 while (BlocksRemaining
> 0) {
1412 if (BlocksRemaining
<= MaxBlock
) {
1414 SectorCount
= (UINT16
) BlocksRemaining
;
1417 SectorCount
= MaxBlock
;
1421 // fill the Packet data structure
1424 Read10Packet
->opcode
= ATA_CMD_READ_10
;
1427 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1428 // Lba0 is MSB, Lba3 is LSB
1430 Read10Packet
->Lba3
= (UINT8
) (Lba32
& 0xff);
1431 Read10Packet
->Lba2
= (UINT8
) (Lba32
>> 8);
1432 Read10Packet
->Lba1
= (UINT8
) (Lba32
>> 16);
1433 Read10Packet
->Lba0
= (UINT8
) (Lba32
>> 24);
1436 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1437 // TranLen0 is MSB, TranLen is LSB
1439 Read10Packet
->TranLen1
= (UINT8
) (SectorCount
& 0xff);
1440 Read10Packet
->TranLen0
= (UINT8
) (SectorCount
>> 8);
1442 ByteCount
= SectorCount
* BlockSize
;
1444 if (IdeDev
->Type
== IdeCdRom
) {
1445 TimeOut
= CDROMLONGTIMEOUT
;
1447 TimeOut
= ATAPILONGTIMEOUT
;
1450 Status
= AtapiPacketCommandIn (
1453 (UINT16
*) PtrBuffer
,
1457 if (EFI_ERROR (Status
)) {
1461 Lba32
+= SectorCount
;
1462 PtrBuffer
= (UINT8
*) PtrBuffer
+ SectorCount
* BlockSize
;
1463 BlocksRemaining
-= SectorCount
;
1470 This function is called by the AtapiBlkIoWriteBlocks() to perform
1471 write onto media in block unit.
1472 The main command used to access media here is Write(10) Command.
1473 Write(10) Command requests that the ATAPI device media transfer
1474 specified data to the host. Data is transferred in block (sector)
1475 unit. The maximum number of blocks that can be transferred once is
1479 pointer pointing to IDE_BLK_IO_DEV data structure, used
1480 to record all the information of the IDE device.
1483 A pointer to the source buffer for the data.
1486 The starting logical block address to write onto
1489 @param[in] NumberOfBlocks
1490 The number of transfer data blocks.
1492 @return status is fully dependent on the return status
1493 of AtapiPacketCommandOut() function.
1498 IN IDE_BLK_IO_DEV
*IdeDev
,
1501 IN UINTN NumberOfBlocks
1505 ATAPI_PACKET_COMMAND Packet
;
1506 ATAPI_READ10_CMD
*Read10Packet
;
1509 UINTN BlocksRemaining
;
1518 // fill command packet for Write(10) command
1519 // Write(10) command packet has the same data structure as
1520 // Read(10) command packet,
1521 // so here use the Read10Packet data structure
1522 // for the Write(10) command packet.
1524 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1525 Read10Packet
= &Packet
.Read10
;
1527 Lba32
= (UINT32
) Lba
;
1530 BlockSize
= IdeDev
->BlkIo
.Media
->BlockSize
;
1533 // limit the data bytes that can be transferred by one Read(10) Command
1535 MaxBlock
= (UINT16
) (65536 / BlockSize
);
1537 BlocksRemaining
= NumberOfBlocks
;
1539 Status
= EFI_SUCCESS
;
1540 while (BlocksRemaining
> 0) {
1542 if (BlocksRemaining
>= MaxBlock
) {
1543 SectorCount
= MaxBlock
;
1545 SectorCount
= (UINT16
) BlocksRemaining
;
1549 // Command code is WRITE_10.
1551 Read10Packet
->opcode
= ATA_CMD_WRITE_10
;
1554 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1555 // Lba0 is MSB, Lba3 is LSB
1557 Read10Packet
->Lba3
= (UINT8
) (Lba32
& 0xff);
1558 Read10Packet
->Lba2
= (UINT8
) (Lba32
>> 8);
1559 Read10Packet
->Lba1
= (UINT8
) (Lba32
>> 16);
1560 Read10Packet
->Lba0
= (UINT8
) (Lba32
>> 24);
1563 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1564 // TranLen0 is MSB, TranLen is LSB
1566 Read10Packet
->TranLen1
= (UINT8
) (SectorCount
& 0xff);
1567 Read10Packet
->TranLen0
= (UINT8
) (SectorCount
>> 8);
1569 ByteCount
= SectorCount
* BlockSize
;
1571 Status
= AtapiPacketCommandOut (
1574 (UINT16
*) PtrBuffer
,
1578 if (EFI_ERROR (Status
)) {
1582 Lba32
+= SectorCount
;
1583 PtrBuffer
= ((UINT8
*) PtrBuffer
+ SectorCount
* BlockSize
);
1584 BlocksRemaining
-= SectorCount
;
1591 This function is used to implement the Soft Reset on the specified
1592 ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
1593 Soft Reset Command special for ATAPI device, and it only take effects
1594 on the specified ATAPI device, not on the whole IDE bus.
1595 Since the ATAPI soft reset is needed when device is in exceptional
1596 condition (such as BSY bit is always set ), I think the Soft Reset
1597 command should be sent without waiting for the BSY clear and DRDY
1599 This function is called by IdeBlkIoReset(),
1600 a interface function of Block I/O protocol.
1603 pointer pointing to IDE_BLK_IO_DEV data structure, used
1604 to record all the information of the IDE device.
1607 Soft reset completes successfully.
1609 @retval EFI_DEVICE_ERROR
1610 Any step during the reset process is failed.
1615 IN IDE_BLK_IO_DEV
*IdeDev
1623 // for ATAPI device, no need to wait DRDY ready after device selecting.
1624 // (bit7 and bit5 are both set to 1 for backward compatibility)
1626 DeviceSelect
= (UINT8
) (((BIT7
| BIT5
) | (IdeDev
->Device
<< 4)));
1627 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
1629 Command
= ATA_CMD_SOFT_RESET
;
1630 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, Command
);
1633 // BSY cleared is the only status return to the host by the device
1634 // when reset is completed.
1635 // slave device needs at most 31s to clear BSY
1637 Status
= WaitForBSYClear (IdeDev
, 31000);
1638 if (EFI_ERROR (Status
)) {
1639 return EFI_DEVICE_ERROR
;
1643 // stall 5 seconds to make the device status stable
1645 gBS
->Stall (5000000);
1651 This function is the ATAPI implementation for ReadBlocks in the
1652 Block I/O Protocol interface.
1654 @param[in] *IdeBlkIoDevice
1655 Indicates the calling context.
1658 The media id that the read request is for.
1661 The starting logical block address to read from
1664 @param[in] BufferSize
1665 The size of the Buffer in bytes. This must be a
1666 multiple of the intrinsic block size of the device.
1669 A pointer to the destination buffer for the data.
1670 The caller is responsible for either having implicit
1671 or explicit ownership of the memory that data is read into.
1674 Read Blocks successfully.
1676 @retval EFI_DEVICE_ERROR
1679 @retval EFI_NO_MEDIA
1680 There is no media in the device.
1682 @retval EFI_MEDIA_CHANGED
1683 The MediaId is not for the current media.
1685 @retval EFI_BAD_BUFFER_SIZE
1686 The BufferSize parameter is not a multiple of the
1687 intrinsic block size of the device.
1689 @retval EFI_INVALID_PARAMETER
1690 The read request contains LBAs that are not valid,
1691 or the data buffer is not valid.
1695 AtapiBlkIoReadBlocks (
1696 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1699 IN UINTN BufferSize
,
1703 EFI_BLOCK_IO_MEDIA
*Media
;
1705 UINTN NumberOfBlocks
;
1708 BOOLEAN MediaChange
;
1710 if (Buffer
== NULL
) {
1711 return EFI_INVALID_PARAMETER
;
1714 if (BufferSize
== 0) {
1719 // ATAPI device media is removable, so it is a must
1720 // to detect media first before read operation
1722 MediaChange
= FALSE
;
1723 Status
= AtapiDetectMedia (IdeBlkIoDevice
, &MediaChange
);
1724 if (EFI_ERROR (Status
)) {
1726 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1727 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1728 IdeBlkIoDevice
->Cache
= NULL
;
1734 // Get the intrinsic block size
1736 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1737 BlockSize
= Media
->BlockSize
;
1739 NumberOfBlocks
= BufferSize
/ BlockSize
;
1741 if (!(Media
->MediaPresent
)) {
1743 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1744 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1745 IdeBlkIoDevice
->Cache
= NULL
;
1747 return EFI_NO_MEDIA
;
1751 if ((MediaId
!= Media
->MediaId
) || MediaChange
) {
1753 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1754 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1755 IdeBlkIoDevice
->Cache
= NULL
;
1757 return EFI_MEDIA_CHANGED
;
1760 if (BufferSize
% BlockSize
!= 0) {
1761 return EFI_BAD_BUFFER_SIZE
;
1764 if (LBA
> Media
->LastBlock
) {
1765 return EFI_INVALID_PARAMETER
;
1768 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1769 return EFI_INVALID_PARAMETER
;
1772 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1773 return EFI_INVALID_PARAMETER
;
1777 // if all the parameters are valid, then perform read sectors command
1778 // to transfer data from device to host.
1780 Status
= AtapiReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1781 if (EFI_ERROR (Status
)) {
1782 return EFI_DEVICE_ERROR
;
1786 // Read blocks succeeded
1790 // save the first block to the cache for performance
1792 if (LBA
== 0 && (IdeBlkIoDevice
->Cache
== NULL
)) {
1793 IdeBlkIoDevice
->Cache
= AllocatePool (BlockSize
);
1794 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1795 CopyMem ((UINT8
*) IdeBlkIoDevice
->Cache
, (UINT8
*) Buffer
, BlockSize
);
1804 This function is the ATAPI implementation for WriteBlocks in the
1805 Block I/O Protocol interface.
1807 @param[in] *IdeBlkIoDevice
1808 Indicates the calling context.
1811 The media id that the write request is for.
1814 The starting logical block address to write onto
1817 @param[in] BufferSize
1818 The size of the Buffer in bytes. This must be a
1819 multiple of the intrinsic block size of the device.
1822 A pointer to the source buffer for the data.
1823 The caller is responsible for either having implicit
1824 or explicit ownership of the memory that data is
1828 Write Blocks successfully.
1830 @retval EFI_DEVICE_ERROR
1831 Write Blocks failed.
1833 @retval EFI_NO_MEDIA
1834 There is no media in the device.
1836 @retval EFI_MEDIA_CHANGE
1837 The MediaId is not for the current media.
1839 @retval EFI_BAD_BUFFER_SIZE
1840 The BufferSize parameter is not a multiple of the
1841 intrinsic block size of the device.
1843 @retval EFI_INVALID_PARAMETER
1844 The write request contains LBAs that are not valid,
1845 or the data buffer is not valid.
1847 TODO: EFI_MEDIA_CHANGED - add return value to function comment
1848 TODO: EFI_WRITE_PROTECTED - add return value to function comment
1851 AtapiBlkIoWriteBlocks (
1852 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1855 IN UINTN BufferSize
,
1860 EFI_BLOCK_IO_MEDIA
*Media
;
1862 UINTN NumberOfBlocks
;
1864 BOOLEAN MediaChange
;
1866 if (LBA
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1867 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1868 IdeBlkIoDevice
->Cache
= NULL
;
1871 if (Buffer
== NULL
) {
1872 return EFI_INVALID_PARAMETER
;
1875 if (BufferSize
== 0) {
1880 // ATAPI device media is removable,
1881 // so it is a must to detect media first before write operation
1883 MediaChange
= FALSE
;
1884 Status
= AtapiDetectMedia (IdeBlkIoDevice
, &MediaChange
);
1885 if (EFI_ERROR (Status
)) {
1887 if (LBA
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1888 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1889 IdeBlkIoDevice
->Cache
= NULL
;
1895 // Get the intrinsic block size
1897 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1898 BlockSize
= Media
->BlockSize
;
1899 NumberOfBlocks
= BufferSize
/ BlockSize
;
1901 if (!(Media
->MediaPresent
)) {
1903 if (LBA
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1904 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1905 IdeBlkIoDevice
->Cache
= NULL
;
1907 return EFI_NO_MEDIA
;
1910 if ((MediaId
!= Media
->MediaId
) || MediaChange
) {
1912 if (LBA
== 0 && IdeBlkIoDevice
->Cache
!= NULL
) {
1913 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1914 IdeBlkIoDevice
->Cache
= NULL
;
1916 return EFI_MEDIA_CHANGED
;
1919 if (Media
->ReadOnly
) {
1920 return EFI_WRITE_PROTECTED
;
1923 if (BufferSize
% BlockSize
!= 0) {
1924 return EFI_BAD_BUFFER_SIZE
;
1927 if (LBA
> Media
->LastBlock
) {
1928 return EFI_INVALID_PARAMETER
;
1931 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1932 return EFI_INVALID_PARAMETER
;
1935 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1936 return EFI_INVALID_PARAMETER
;
1940 // if all the parameters are valid,
1941 // then perform write sectors command to transfer data from host to device.
1943 Status
= AtapiWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1944 if (EFI_ERROR (Status
)) {
1945 return EFI_DEVICE_ERROR
;
1953 This function is used to parse sense data. Only the first
1954 sense data is honoured.
1956 @param[in] IdeDev Indicates the calling context.
1957 @param[in] SenseCount Count of sense data.
1958 @param[out] Result The parsed result.
1960 @retval EFI_SUCCESS Successfully parsed.
1961 @retval EFI_INVALID_PARAMETER Count of sense data is zero.
1966 IN IDE_BLK_IO_DEV
*IdeDev
,
1967 IN UINTN SenseCount
,
1968 OUT SENSE_RESULT
*Result
1971 ATAPI_REQUEST_SENSE_DATA
*SenseData
;
1973 if (SenseCount
== 0) {
1974 return EFI_INVALID_PARAMETER
;
1978 // Only use the first sense data
1980 SenseData
= IdeDev
->SenseData
;
1981 *Result
= SenseOtherSense
;
1983 switch (SenseData
->sense_key
) {
1984 case ATA_SK_NO_SENSE
:
1985 *Result
= SenseNoSenseKey
;
1987 case ATA_SK_NOT_READY
:
1988 switch (SenseData
->addnl_sense_code
) {
1989 case ATA_ASC_NO_MEDIA
:
1990 *Result
= SenseNoMedia
;
1992 case ATA_ASC_MEDIA_UPSIDE_DOWN
:
1993 *Result
= SenseMediaError
;
1995 case ATA_ASC_NOT_READY
:
1996 if (SenseData
->addnl_sense_code_qualifier
== ATA_ASCQ_IN_PROGRESS
) {
1997 *Result
= SenseDeviceNotReadyNeedRetry
;
1999 *Result
= SenseDeviceNotReadyNoRetry
;
2004 case ATA_SK_UNIT_ATTENTION
:
2005 if (SenseData
->addnl_sense_code
== ATA_ASC_MEDIA_CHANGE
) {
2006 *Result
= SenseMediaChange
;
2009 case ATA_SK_MEDIUM_ERROR
:
2010 switch (SenseData
->addnl_sense_code
) {
2011 case ATA_ASC_MEDIA_ERR1
:
2012 case ATA_ASC_MEDIA_ERR2
:
2013 case ATA_ASC_MEDIA_ERR3
:
2014 case ATA_ASC_MEDIA_ERR4
:
2015 *Result
= SenseMediaError
;
2027 This function reads the pending data in the device.
2029 @param[in] IdeDev Indicates the calling context.
2031 @retval EFI_SUCCESS Successfully read.
2032 @retval EFI_NOT_READY The BSY is set avoiding reading.
2036 AtapiReadPendingData (
2037 IN IDE_BLK_IO_DEV
*IdeDev
2041 UINT16 TempWordBuffer
;
2043 AltRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.AltStatus
);
2044 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
2045 return EFI_NOT_READY
;
2047 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
2048 TempWordBuffer
= IDEReadPortB (IdeDev
->PciIo
,IdeDev
->IoPort
->Alt
.AltStatus
);
2049 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
2050 IDEReadPortWMultiple (
2052 IdeDev
->IoPort
->Data
,
2056 TempWordBuffer
= IDEReadPortB (IdeDev
->PciIo
,IdeDev
->IoPort
->Alt
.AltStatus
);
2063 TODO: Add function description
2065 @param IdeDev TODO: add argument description
2066 @param WriteProtected TODO: add argument description
2068 @retval EFI_DEVICE_ERROR TODO: Add description for return value
2069 @retval EFI_DEVICE_ERROR TODO: Add description for return value
2070 @retval EFI_SUCCESS TODO: Add description for return value.
2074 IsLS120orZipWriteProtected (
2075 IN IDE_BLK_IO_DEV
*IdeDev
,
2076 OUT BOOLEAN
*WriteProtected
2081 *WriteProtected
= FALSE
;
2083 Status
= LS120EnableMediaStatus (IdeDev
, TRUE
);
2084 if (EFI_ERROR (Status
)) {
2085 return EFI_DEVICE_ERROR
;
2089 // the Get Media Status Command is only valid
2090 // if a Set Features/Enable Media Status Command has been priviously issued.
2092 if (LS120GetMediaStatus (IdeDev
) == EFI_WRITE_PROTECTED
) {
2094 *WriteProtected
= TRUE
;
2097 *WriteProtected
= FALSE
;
2101 // After Get Media Status Command completes,
2102 // Set Features/Disable Media Command should be sent.
2104 Status
= LS120EnableMediaStatus (IdeDev
, FALSE
);
2105 if (EFI_ERROR (Status
)) {
2106 return EFI_DEVICE_ERROR
;