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
) {
97 if (StatusValue
& BIT6
) {
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[in] *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] **SenseBuffers
855 allocated in this function, and freed by the calling function.
856 This buffer is used to accommodate all the sense data returned
860 record the unit size of the sense data block in the SenseBuffers,
862 @param[out] *BufNumbers
863 record the number of units in the SenseBuffers.
866 Request Sense command completes successfully.
868 @retval EFI_DEVICE_ERROR
869 Request Sense command failed.
874 IN IDE_BLK_IO_DEV
*IdeDev
,
875 OUT UINTN
*SenseCounts
879 ATAPI_REQUEST_SENSE_DATA
*Sense
;
881 BOOLEAN FetchSenseData
;
882 ATAPI_PACKET_COMMAND Packet
;
886 ZeroMem (IdeDev
->SenseData
, sizeof (ATAPI_REQUEST_SENSE_DATA
) * (IdeDev
->SenseDataNumber
));
888 // fill command packet for Request Sense Packet Command
890 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
891 Packet
.RequestSence
.opcode
= ATA_CMD_REQUEST_SENSE
;
892 Packet
.RequestSence
.allocation_length
= sizeof (ATAPI_REQUEST_SENSE_DATA
);
895 // initialize pointer
897 Ptr
= (UINT16
*) IdeDev
->SenseData
;
899 // request sense data from device continuously until no sense data
900 // exists in the device.
902 for (FetchSenseData
= TRUE
; FetchSenseData
;) {
904 Sense
= (ATAPI_REQUEST_SENSE_DATA
*) Ptr
;
907 // send out Request Sense Packet Command and get one Sense data form device
909 Status
= AtapiPacketCommandIn (
913 sizeof (ATAPI_REQUEST_SENSE_DATA
),
917 // failed to get Sense data
919 if (EFI_ERROR (Status
)) {
920 if (*SenseCounts
== 0) {
921 return EFI_DEVICE_ERROR
;
929 // We limit MAX sense data count to 20 in order to avoid dead loop. Some
930 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
931 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
932 // supposed to be large enough for any ATAPI device.
934 if ((Sense
->sense_key
!= ATA_SK_NO_SENSE
) && ((*SenseCounts
) < 20)) {
936 // Ptr is word-based pointer
938 Ptr
+= (sizeof (ATAPI_REQUEST_SENSE_DATA
) + 1) >> 1;
942 // when no sense key, skip out the loop
944 FetchSenseData
= FALSE
;
952 Sends out ATAPI Read Capacity Packet Command to the specified device.
953 This command will return the information regarding the capacity of the
956 Current device status will impact device's response to the Read Capacity
957 Command. For example, if the device once reset, the Read Capacity
958 Command will fail. The Sense data record the current device status, so
959 if the Read Capacity Command failed, the Sense data must be requested
960 and be analyzed to determine if the Read Capacity Command should retry.
962 @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
963 to record all the information of the IDE device.
964 @param[in] SResult Sense result for this packet command
966 @retval EFI_SUCCESS Read Capacity Command finally completes successfully.
967 @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.
969 @note Parameter "IdeDev" will be updated in this function.
971 TODO: EFI_NOT_READY - add return value to function comment
975 IN IDE_BLK_IO_DEV
*IdeDev
,
976 OUT SENSE_RESULT
*SResult
980 // status returned by Read Capacity Packet Command
983 EFI_STATUS SenseStatus
;
984 ATAPI_PACKET_COMMAND Packet
;
988 // used for capacity data returned from ATAPI device
990 ATAPI_READ_CAPACITY_DATA Data
;
991 ATAPI_READ_FORMAT_CAPACITY_DATA FormatData
;
993 ZeroMem (&Data
, sizeof (Data
));
994 ZeroMem (&FormatData
, sizeof (FormatData
));
996 if (IdeDev
->Type
== IdeCdRom
) {
998 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
999 Packet
.Inquiry
.opcode
= ATA_CMD_READ_CAPACITY
;
1000 Status
= AtapiPacketCommandIn (
1004 sizeof (ATAPI_READ_CAPACITY_DATA
),
1010 // Type == IdeMagnetic
1012 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1013 Packet
.ReadFormatCapacity
.opcode
= ATA_CMD_READ_FORMAT_CAPACITY
;
1014 Packet
.ReadFormatCapacity
.allocation_length_lo
= 12;
1015 Status
= AtapiPacketCommandIn (
1018 (UINT16
*) &FormatData
,
1019 sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA
),
1024 if (Status
== EFI_TIMEOUT
) {
1028 SenseStatus
= AtapiRequestSense (IdeDev
, &SenseCount
);
1030 if (!EFI_ERROR (SenseStatus
)) {
1031 ParseSenseData (IdeDev
, SenseCount
, SResult
);
1033 if (!EFI_ERROR (Status
) && *SResult
== SenseNoSenseKey
) {
1034 if (IdeDev
->Type
== IdeCdRom
) {
1036 IdeDev
->BlkIo
.Media
->LastBlock
= (Data
.LastLba3
<< 24) |
1037 (Data
.LastLba2
<< 16) |
1038 (Data
.LastLba1
<< 8) |
1041 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
1043 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
1046 // Because the user data portion in the sector of the Data CD supported
1049 IdeDev
->BlkIo
.Media
->BlockSize
= 0x800;
1052 if (IdeDev
->Type
== IdeMagnetic
) {
1054 if (FormatData
.DesCode
== 3) {
1055 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1056 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1059 IdeDev
->BlkIo
.Media
->LastBlock
= (FormatData
.LastLba3
<< 24) |
1060 (FormatData
.LastLba2
<< 16) |
1061 (FormatData
.LastLba1
<< 8) |
1062 FormatData
.LastLba0
;
1063 if (IdeDev
->BlkIo
.Media
->LastBlock
!= 0) {
1064 IdeDev
->BlkIo
.Media
->LastBlock
--;
1066 IdeDev
->BlkIo
.Media
->BlockSize
= (FormatData
.BlockSize2
<< 16) |
1067 (FormatData
.BlockSize1
<< 8) |
1068 FormatData
.BlockSize0
;
1070 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
1072 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1074 // Return EFI_NOT_READY operation succeeds but returned capacity is 0
1076 return EFI_NOT_READY
;
1079 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
1088 return EFI_DEVICE_ERROR
;
1093 Used before read/write blocks from/to ATAPI device media.
1094 Since ATAPI device media is removable, it is necessary to detect
1095 whether media is present and get current present media's
1096 information, and if media has been changed, Block I/O Protocol
1097 need to be reinstalled.
1100 pointer pointing to IDE_BLK_IO_DEV data structure, used
1101 to record all the information of the IDE device.
1103 @param[out] *MediaChange
1104 return value that indicates if the media of the device has been
1108 media found successfully.
1110 @retval EFI_DEVICE_ERROR
1111 any error encounters during media detection.
1113 @retval EFI_NO_MEDIA
1117 parameter IdeDev may be updated in this function.
1122 IN IDE_BLK_IO_DEV
*IdeDev
,
1123 OUT BOOLEAN
*MediaChange
1127 EFI_STATUS CleanStateStatus
;
1128 EFI_BLOCK_IO_MEDIA OldMediaInfo
;
1130 UINTN RetryNotReady
;
1131 SENSE_RESULT SResult
;
1132 BOOLEAN WriteProtected
;
1134 CopyMem (&OldMediaInfo
, IdeDev
->BlkIo
.Media
, sizeof (EFI_BLOCK_IO_MEDIA
));
1135 *MediaChange
= FALSE
;
1137 // Retry for SenseDeviceNotReadyNeedRetry.
1138 // Each retry takes 1s and we limit the upper boundary to
1139 // 120 times about 2 min.
1141 RetryNotReady
= 120;
1144 // Do Test Unit Ready
1151 while (RetryTimes
!= 0) {
1153 Status
= AtapiTestUnitReady (IdeDev
, &SResult
);
1155 if (EFI_ERROR (Status
)) {
1157 // Test Unit Ready error without sense data.
1158 // For some devices, this means there's extra data
1159 // that has not been read, so we read these extra
1160 // data out before going on.
1162 CleanStateStatus
= AtapiReadPendingData (IdeDev
);
1163 if (EFI_ERROR (CleanStateStatus
)) {
1165 // Busy wait failed, try again
1170 // Try again without counting down RetryTimes
1175 case SenseNoSenseKey
:
1176 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1180 // Media present but the internal structure need refreshed.
1181 // Try Read Capacity
1187 case SenseDeviceNotReadyNeedRetry
:
1188 if (--RetryNotReady
== 0) {
1189 return EFI_DEVICE_ERROR
;
1191 gBS
->Stall (1000 * STALL_1_MILLI_SECOND
);
1196 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1197 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1201 case SenseDeviceNotReadyNoRetry
:
1202 case SenseMediaError
:
1203 return EFI_DEVICE_ERROR
;
1205 case SenseMediaChange
:
1206 IdeDev
->BlkIo
.Media
->MediaId
++;
1217 return EFI_DEVICE_ERROR
;
1225 while (RetryTimes
!= 0) {
1227 Status
= AtapiReadCapacity (IdeDev
, &SResult
);
1229 if (EFI_ERROR (Status
)) {
1234 case SenseNoSenseKey
:
1238 case SenseDeviceNotReadyNeedRetry
:
1240 // We use Test Unit Ready to retry which
1247 IdeDev
->BlkIo
.Media
->MediaPresent
= FALSE
;
1248 IdeDev
->BlkIo
.Media
->LastBlock
= 0;
1252 case SenseDeviceNotReadyNoRetry
:
1253 case SenseMediaError
:
1254 return EFI_DEVICE_ERROR
;
1256 case SenseMediaChange
:
1257 IdeDev
->BlkIo
.Media
->MediaId
++;
1268 return EFI_DEVICE_ERROR
;
1272 // the following code is to check the write-protected for LS120 media
1274 if ((IdeDev
->BlkIo
.Media
->MediaPresent
) && (IdeDev
->Type
== IdeMagnetic
)) {
1276 Status
= IsLS120orZipWriteProtected (IdeDev
, &WriteProtected
);
1277 if (!EFI_ERROR (Status
)) {
1279 if (WriteProtected
) {
1281 IdeDev
->BlkIo
.Media
->ReadOnly
= TRUE
;
1284 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
1290 if (IdeDev
->BlkIo
.Media
->MediaId
!= OldMediaInfo
.MediaId
) {
1292 // Media change information got from the device
1294 *MediaChange
= TRUE
;
1297 if (IdeDev
->BlkIo
.Media
->ReadOnly
!= OldMediaInfo
.ReadOnly
) {
1298 *MediaChange
= TRUE
;
1299 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1302 if (IdeDev
->BlkIo
.Media
->BlockSize
!= OldMediaInfo
.BlockSize
) {
1303 *MediaChange
= TRUE
;
1304 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1307 if (IdeDev
->BlkIo
.Media
->LastBlock
!= OldMediaInfo
.LastBlock
) {
1308 *MediaChange
= TRUE
;
1309 IdeDev
->BlkIo
.Media
->MediaId
+= 1;
1312 if (IdeDev
->BlkIo
.Media
->MediaPresent
!= OldMediaInfo
.MediaPresent
) {
1313 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1315 // when change from no media to media present, reset the MediaId to 1.
1317 IdeDev
->BlkIo
.Media
->MediaId
= 1;
1320 // when no media, reset the MediaId to zero.
1322 IdeDev
->BlkIo
.Media
->MediaId
= 0;
1325 *MediaChange
= TRUE
;
1329 // if any change on current existing media,
1330 // the Block I/O protocol need to be reinstalled.
1333 gBS
->ReinstallProtocolInterface (
1335 &gEfiBlockIoProtocolGuid
,
1341 if (IdeDev
->BlkIo
.Media
->MediaPresent
) {
1344 return EFI_NO_MEDIA
;
1349 This function is called by the AtapiBlkIoReadBlocks() to perform
1350 read from media in block unit.
1352 The main command used to access media here is READ(10) Command.
1353 READ(10) Command requests that the ATAPI device media transfer
1354 specified data to the host. Data is transferred in block(sector)
1355 unit. The maximum number of blocks that can be transferred once is
1356 65536. This is the main difference between READ(10) and READ(12)
1357 Command. The maximum number of blocks in READ(12) is 2 power 32.
1360 pointer pointing to IDE_BLK_IO_DEV data structure, used
1361 to record all the information of the IDE device.
1364 A pointer to the destination buffer for the data.
1367 The starting logical block address to read from
1368 on the device media.
1370 @param[in] NumberOfBlocks
1371 The number of transfer data blocks.
1373 @return status is fully dependent on the return status
1374 of AtapiPacketCommandIn() function.
1379 IN IDE_BLK_IO_DEV
*IdeDev
,
1382 IN UINTN NumberOfBlocks
1386 ATAPI_PACKET_COMMAND Packet
;
1387 ATAPI_READ10_CMD
*Read10Packet
;
1389 UINTN BlocksRemaining
;
1399 // fill command packet for Read(10) command
1401 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1402 Read10Packet
= &Packet
.Read10
;
1403 Lba32
= (UINT32
) Lba
;
1406 BlockSize
= IdeDev
->BlkIo
.Media
->BlockSize
;
1409 // limit the data bytes that can be transferred by one Read(10) Command
1413 BlocksRemaining
= NumberOfBlocks
;
1415 Status
= EFI_SUCCESS
;
1416 while (BlocksRemaining
> 0) {
1418 if (BlocksRemaining
<= MaxBlock
) {
1420 SectorCount
= (UINT16
) BlocksRemaining
;
1423 SectorCount
= MaxBlock
;
1427 // fill the Packet data structure
1430 Read10Packet
->opcode
= ATA_CMD_READ_10
;
1433 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1434 // Lba0 is MSB, Lba3 is LSB
1436 Read10Packet
->Lba3
= (UINT8
) (Lba32
& 0xff);
1437 Read10Packet
->Lba2
= (UINT8
) (Lba32
>> 8);
1438 Read10Packet
->Lba1
= (UINT8
) (Lba32
>> 16);
1439 Read10Packet
->Lba0
= (UINT8
) (Lba32
>> 24);
1442 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1443 // TranLen0 is MSB, TranLen is LSB
1445 Read10Packet
->TranLen1
= (UINT8
) (SectorCount
& 0xff);
1446 Read10Packet
->TranLen0
= (UINT8
) (SectorCount
>> 8);
1448 ByteCount
= SectorCount
* BlockSize
;
1450 if (IdeDev
->Type
== IdeCdRom
) {
1451 TimeOut
= CDROMLONGTIMEOUT
;
1453 TimeOut
= ATAPILONGTIMEOUT
;
1456 Status
= AtapiPacketCommandIn (
1459 (UINT16
*) PtrBuffer
,
1463 if (EFI_ERROR (Status
)) {
1467 Lba32
+= SectorCount
;
1468 PtrBuffer
= (UINT8
*) PtrBuffer
+ SectorCount
* BlockSize
;
1469 BlocksRemaining
-= SectorCount
;
1476 This function is called by the AtapiBlkIoWriteBlocks() to perform
1477 write onto media in block unit.
1478 The main command used to access media here is Write(10) Command.
1479 Write(10) Command requests that the ATAPI device media transfer
1480 specified data to the host. Data is transferred in block (sector)
1481 unit. The maximum number of blocks that can be transferred once is
1485 pointer pointing to IDE_BLK_IO_DEV data structure, used
1486 to record all the information of the IDE device.
1489 A pointer to the source buffer for the data.
1492 The starting logical block address to write onto
1495 @param[in] NumberOfBlocks
1496 The number of transfer data blocks.
1498 @return status is fully dependent on the return status
1499 of AtapiPacketCommandOut() function.
1504 IN IDE_BLK_IO_DEV
*IdeDev
,
1507 IN UINTN NumberOfBlocks
1511 ATAPI_PACKET_COMMAND Packet
;
1512 ATAPI_READ10_CMD
*Read10Packet
;
1515 UINTN BlocksRemaining
;
1524 // fill command packet for Write(10) command
1525 // Write(10) command packet has the same data structure as
1526 // Read(10) command packet,
1527 // so here use the Read10Packet data structure
1528 // for the Write(10) command packet.
1530 ZeroMem (&Packet
, sizeof (ATAPI_PACKET_COMMAND
));
1531 Read10Packet
= &Packet
.Read10
;
1533 Lba32
= (UINT32
) Lba
;
1536 BlockSize
= IdeDev
->BlkIo
.Media
->BlockSize
;
1539 // limit the data bytes that can be transferred by one Read(10) Command
1541 MaxBlock
= (UINT16
) (65536 / BlockSize
);
1543 BlocksRemaining
= NumberOfBlocks
;
1545 Status
= EFI_SUCCESS
;
1546 while (BlocksRemaining
> 0) {
1548 if (BlocksRemaining
>= MaxBlock
) {
1549 SectorCount
= MaxBlock
;
1551 SectorCount
= (UINT16
) BlocksRemaining
;
1555 // Command code is WRITE_10.
1557 Read10Packet
->opcode
= ATA_CMD_WRITE_10
;
1560 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1561 // Lba0 is MSB, Lba3 is LSB
1563 Read10Packet
->Lba3
= (UINT8
) (Lba32
& 0xff);
1564 Read10Packet
->Lba2
= (UINT8
) (Lba32
>> 8);
1565 Read10Packet
->Lba1
= (UINT8
) (Lba32
>> 16);
1566 Read10Packet
->Lba0
= (UINT8
) (Lba32
>> 24);
1569 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1570 // TranLen0 is MSB, TranLen is LSB
1572 Read10Packet
->TranLen1
= (UINT8
) (SectorCount
& 0xff);
1573 Read10Packet
->TranLen0
= (UINT8
) (SectorCount
>> 8);
1575 ByteCount
= SectorCount
* BlockSize
;
1577 Status
= AtapiPacketCommandOut (
1580 (UINT16
*) PtrBuffer
,
1584 if (EFI_ERROR (Status
)) {
1588 Lba32
+= SectorCount
;
1589 PtrBuffer
= ((UINT8
*) PtrBuffer
+ SectorCount
* BlockSize
);
1590 BlocksRemaining
-= SectorCount
;
1597 This function is used to implement the Soft Reset on the specified
1598 ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
1599 Soft Reset Command special for ATAPI device, and it only take effects
1600 on the specified ATAPI device, not on the whole IDE bus.
1601 Since the ATAPI soft reset is needed when device is in exceptional
1602 condition (such as BSY bit is always set ), I think the Soft Reset
1603 command should be sent without waiting for the BSY clear and DRDY
1605 This function is called by IdeBlkIoReset(),
1606 a interface function of Block I/O protocol.
1609 pointer pointing to IDE_BLK_IO_DEV data structure, used
1610 to record all the information of the IDE device.
1613 Soft reset completes successfully.
1615 @retval EFI_DEVICE_ERROR
1616 Any step during the reset process is failed.
1621 IN IDE_BLK_IO_DEV
*IdeDev
1629 // for ATAPI device, no need to wait DRDY ready after device selecting.
1630 // (bit7 and bit5 are both set to 1 for backward compatibility)
1632 DeviceSelect
= (UINT8
) (((BIT7
| BIT5
) | (IdeDev
->Device
<< 4)));
1633 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, DeviceSelect
);
1635 Command
= ATA_CMD_SOFT_RESET
;
1636 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, Command
);
1639 // BSY cleared is the only status return to the host by the device
1640 // when reset is completed.
1641 // slave device needs at most 31s to clear BSY
1643 Status
= WaitForBSYClear (IdeDev
, 31000);
1644 if (EFI_ERROR (Status
)) {
1645 return EFI_DEVICE_ERROR
;
1649 // stall 5 seconds to make the device status stable
1651 gBS
->Stall (5000000);
1657 This function is the ATAPI implementation for ReadBlocks in the
1658 Block I/O Protocol interface.
1660 @param[in] *IdeBlkIoDev
1661 Indicates the calling context.
1664 The media id that the read request is for.
1667 The starting logical block address to read from
1670 @param[in] BufferSize
1671 The size of the Buffer in bytes. This must be a
1672 multiple of the intrinsic block size of the device.
1675 A pointer to the destination buffer for the data.
1676 The caller is responsible for either having implicit
1677 or explicit ownership of the memory that data is read into.
1680 Read Blocks successfully.
1682 @retval EFI_DEVICE_ERROR
1685 @retval EFI_NO_MEDIA
1686 There is no media in the device.
1688 @retval EFI_MEDIA_CHANGED
1689 The MediaId is not for the current media.
1691 @retval EFI_BAD_BUFFER_SIZE
1692 The BufferSize parameter is not a multiple of the
1693 intrinsic block size of the device.
1695 @retval EFI_INVALID_PARAMETER
1696 The read request contains LBAs that are not valid,
1697 or the data buffer is not valid.
1701 AtapiBlkIoReadBlocks (
1702 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1705 IN UINTN BufferSize
,
1709 EFI_BLOCK_IO_MEDIA
*Media
;
1711 UINTN NumberOfBlocks
;
1714 BOOLEAN MediaChange
;
1716 if (Buffer
== NULL
) {
1717 return EFI_INVALID_PARAMETER
;
1720 if (BufferSize
== 0) {
1725 // ATAPI device media is removable, so it is a must
1726 // to detect media first before read operation
1728 MediaChange
= FALSE
;
1729 Status
= AtapiDetectMedia (IdeBlkIoDevice
, &MediaChange
);
1730 if (EFI_ERROR (Status
)) {
1732 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1733 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1734 IdeBlkIoDevice
->Cache
= NULL
;
1740 // Get the intrinsic block size
1742 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1743 BlockSize
= Media
->BlockSize
;
1745 NumberOfBlocks
= BufferSize
/ BlockSize
;
1747 if (!(Media
->MediaPresent
)) {
1749 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1750 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1751 IdeBlkIoDevice
->Cache
= NULL
;
1753 return EFI_NO_MEDIA
;
1757 if ((MediaId
!= Media
->MediaId
) || MediaChange
) {
1759 if (IdeBlkIoDevice
->Cache
!= NULL
) {
1760 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1761 IdeBlkIoDevice
->Cache
= NULL
;
1763 return EFI_MEDIA_CHANGED
;
1766 if (BufferSize
% BlockSize
!= 0) {
1767 return EFI_BAD_BUFFER_SIZE
;
1770 if (LBA
> Media
->LastBlock
) {
1771 return EFI_INVALID_PARAMETER
;
1774 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1775 return EFI_INVALID_PARAMETER
;
1778 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1779 return EFI_INVALID_PARAMETER
;
1783 // if all the parameters are valid, then perform read sectors command
1784 // to transfer data from device to host.
1786 Status
= AtapiReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1787 if (EFI_ERROR (Status
)) {
1788 return EFI_DEVICE_ERROR
;
1792 // Read blocks succeeded
1796 // save the first block to the cache for performance
1798 if (LBA
== 0 && !IdeBlkIoDevice
->Cache
) {
1799 IdeBlkIoDevice
->Cache
= AllocatePool (BlockSize
);
1800 if (IdeBlkIoDevice
!= NULL
) {
1801 CopyMem ((UINT8
*) IdeBlkIoDevice
->Cache
, (UINT8
*) Buffer
, BlockSize
);
1810 This function is the ATAPI implementation for WriteBlocks in the
1811 Block I/O Protocol interface.
1814 Indicates the calling context.
1817 The media id that the write request is for.
1820 The starting logical block address to write onto
1823 @param[in] BufferSize
1824 The size of the Buffer in bytes. This must be a
1825 multiple of the intrinsic block size of the device.
1828 A pointer to the source buffer for the data.
1829 The caller is responsible for either having implicit
1830 or explicit ownership of the memory that data is
1834 Write Blocks successfully.
1836 @retval EFI_DEVICE_ERROR
1837 Write Blocks failed.
1839 @retval EFI_NO_MEDIA
1840 There is no media in the device.
1842 @retval EFI_MEDIA_CHANGE
1843 The MediaId is not for the current media.
1845 @retval EFI_BAD_BUFFER_SIZE
1846 The BufferSize parameter is not a multiple of the
1847 intrinsic block size of the device.
1849 @retval EFI_INVALID_PARAMETER
1850 The write request contains LBAs that are not valid,
1851 or the data buffer is not valid.
1853 TODO: EFI_MEDIA_CHANGED - add return value to function comment
1854 TODO: EFI_WRITE_PROTECTED - add return value to function comment
1857 AtapiBlkIoWriteBlocks (
1858 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1861 IN UINTN BufferSize
,
1866 EFI_BLOCK_IO_MEDIA
*Media
;
1868 UINTN NumberOfBlocks
;
1870 BOOLEAN MediaChange
;
1872 if (LBA
== 0 && IdeBlkIoDevice
->Cache
) {
1873 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1874 IdeBlkIoDevice
->Cache
= NULL
;
1877 if (Buffer
== NULL
) {
1878 return EFI_INVALID_PARAMETER
;
1881 if (BufferSize
== 0) {
1886 // ATAPI device media is removable,
1887 // so it is a must to detect media first before write operation
1889 MediaChange
= FALSE
;
1890 Status
= AtapiDetectMedia (IdeBlkIoDevice
, &MediaChange
);
1891 if (EFI_ERROR (Status
)) {
1893 if (LBA
== 0 && IdeBlkIoDevice
->Cache
) {
1894 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1895 IdeBlkIoDevice
->Cache
= NULL
;
1901 // Get the intrinsic block size
1903 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1904 BlockSize
= Media
->BlockSize
;
1905 NumberOfBlocks
= BufferSize
/ BlockSize
;
1907 if (!(Media
->MediaPresent
)) {
1909 if (LBA
== 0 && IdeBlkIoDevice
->Cache
) {
1910 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1911 IdeBlkIoDevice
->Cache
= NULL
;
1913 return EFI_NO_MEDIA
;
1916 if ((MediaId
!= Media
->MediaId
) || MediaChange
) {
1918 if (LBA
== 0 && IdeBlkIoDevice
->Cache
) {
1919 gBS
->FreePool (IdeBlkIoDevice
->Cache
);
1920 IdeBlkIoDevice
->Cache
= NULL
;
1922 return EFI_MEDIA_CHANGED
;
1925 if (Media
->ReadOnly
) {
1926 return EFI_WRITE_PROTECTED
;
1929 if (BufferSize
% BlockSize
!= 0) {
1930 return EFI_BAD_BUFFER_SIZE
;
1933 if (LBA
> Media
->LastBlock
) {
1934 return EFI_INVALID_PARAMETER
;
1937 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1938 return EFI_INVALID_PARAMETER
;
1941 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1942 return EFI_INVALID_PARAMETER
;
1946 // if all the parameters are valid,
1947 // then perform write sectors command to transfer data from host to device.
1949 Status
= AtapiWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1950 if (EFI_ERROR (Status
)) {
1951 return EFI_DEVICE_ERROR
;
1959 This function is used to parse sense data. Only the first
1960 sense data is honoured.
1962 @param[in] IdeDev Indicates the calling context.
1963 @param[in] SenseCount Count of sense data.
1964 @param[out] Result The parsed result.
1966 @retval EFI_SUCCESS Successfully parsed.
1967 @retval EFI_INVALID_PARAMETER Count of sense data is zero.
1972 IN IDE_BLK_IO_DEV
*IdeDev
,
1973 IN UINTN SenseCount
,
1974 OUT SENSE_RESULT
*Result
1977 ATAPI_REQUEST_SENSE_DATA
*SenseData
;
1979 if (SenseCount
== 0) {
1980 return EFI_INVALID_PARAMETER
;
1984 // Only use the first sense data
1986 SenseData
= IdeDev
->SenseData
;
1987 *Result
= SenseOtherSense
;
1989 switch (SenseData
->sense_key
) {
1990 case ATA_SK_NO_SENSE
:
1991 *Result
= SenseNoSenseKey
;
1993 case ATA_SK_NOT_READY
:
1994 switch (SenseData
->addnl_sense_code
) {
1995 case ATA_ASC_NO_MEDIA
:
1996 *Result
= SenseNoMedia
;
1998 case ATA_ASC_MEDIA_UPSIDE_DOWN
:
1999 *Result
= SenseMediaError
;
2001 case ATA_ASC_NOT_READY
:
2002 if (SenseData
->addnl_sense_code_qualifier
== ATA_ASCQ_IN_PROGRESS
) {
2003 *Result
= SenseDeviceNotReadyNeedRetry
;
2005 *Result
= SenseDeviceNotReadyNoRetry
;
2010 case ATA_SK_UNIT_ATTENTION
:
2011 if (SenseData
->addnl_sense_code
== ATA_ASC_MEDIA_CHANGE
) {
2012 *Result
= SenseMediaChange
;
2015 case ATA_SK_MEDIUM_ERROR
:
2016 switch (SenseData
->addnl_sense_code
) {
2017 case ATA_ASC_MEDIA_ERR1
:
2018 case ATA_ASC_MEDIA_ERR2
:
2019 case ATA_ASC_MEDIA_ERR3
:
2020 case ATA_ASC_MEDIA_ERR4
:
2021 *Result
= SenseMediaError
;
2033 This function reads the pending data in the device.
2035 @param[in] IdeDev Indicates the calling context.
2037 @retval EFI_SUCCESS Successfully read.
2038 @retval EFI_NOT_READY The BSY is set avoiding reading.
2042 AtapiReadPendingData (
2043 IN IDE_BLK_IO_DEV
*IdeDev
2047 UINT16 TempWordBuffer
;
2049 AltRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.AltStatus
);
2050 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
2051 return EFI_NOT_READY
;
2053 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
2054 TempWordBuffer
= IDEReadPortB (IdeDev
->PciIo
,IdeDev
->IoPort
->Alt
.AltStatus
);
2055 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
2056 IDEReadPortWMultiple (
2058 IdeDev
->IoPort
->Data
,
2062 TempWordBuffer
= IDEReadPortB (IdeDev
->PciIo
,IdeDev
->IoPort
->Alt
.AltStatus
);
2069 TODO: Add function description
2071 @param IdeDev TODO: add argument description
2072 @param WriteProtected TODO: add argument description
2074 @retval EFI_DEVICE_ERROR TODO: Add description for return value
2075 @retval EFI_DEVICE_ERROR TODO: Add description for return value
2076 @retval EFI_SUCCESS TODO: Add description for return value
2080 IsLS120orZipWriteProtected (
2081 IN IDE_BLK_IO_DEV
*IdeDev
,
2082 OUT BOOLEAN
*WriteProtected
2087 *WriteProtected
= FALSE
;
2089 Status
= LS120EnableMediaStatus (IdeDev
, TRUE
);
2090 if (EFI_ERROR (Status
)) {
2091 return EFI_DEVICE_ERROR
;
2095 // the Get Media Status Command is only valid
2096 // if a Set Features/Enable Media Status Command has been priviously issued.
2098 if (LS120GetMediaStatus (IdeDev
) == EFI_WRITE_PROTECTED
) {
2100 *WriteProtected
= TRUE
;
2103 *WriteProtected
= FALSE
;
2107 // After Get Media Status Command completes,
2108 // Set Features/Disable Media Command should be sent.
2110 Status
= LS120EnableMediaStatus (IdeDev
, FALSE
);
2111 if (EFI_ERROR (Status
)) {
2112 return EFI_DEVICE_ERROR
;