VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxIdeBusDxe/Ata.c@ 48947

Last change on this file since 48947 was 48947, checked in by vboxsync, 11 years ago

Devices: Whitespace and svn:keyword cleanups by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 82.2 KB
Line 
1/* $Id: Ata.c 48947 2013-10-07 21:41:00Z vboxsync $ */
2/** @file
3 * Ata.c
4 */
5
6/*
7 * Copyright (C) 2009-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/** @file
28 This file contains all helper functions on the ATA command
29
30 Copyright (c) 2006 - 2008, Intel Corporation.<BR>
31 All rights reserved. This program and the accompanying materials
32 are licensed and made available under the terms and conditions of the BSD License
33 which accompanies this distribution. The full text of the license may be found at
34 http://opensource.org/licenses/bsd-license.php
35
36 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
37 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
38
39 @par Revision Reference:
40 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
41 update - ATAIdentify() func
42 update - AtaBlockIoReadBlocks() func
43 update - AtaBlockIoWriteBlocks() func
44 add - AtaAtapi6Identify() func
45 add - AtaReadSectorsExt() func
46 add - AtaWriteSectorsExt() func
47 add - AtaPioDataInExt() func
48 add - AtaPioDataOutExt() func
49
50**/
51
52#include "IdeBus.h"
53/**
54 This function is called by ATAIdentify() to identity whether this disk
55 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
56
57 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
58 all the information of the IDE device.
59
60 @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one and
61 48-bit addressing must be used
62 @retval EFI_UNSUPPORTED The disk doesn't not support Atapi6 or it supports but the
63 capacity is below 120G, 48bit addressing is not needed
64 @retval EFI_DEVICE_ERROR The identify data in IdeDev is incorrect
65 @retval EFI_INVALID_PARAMETER The identify data in IdeDev is NULL.
66
67 @note This function must be called after DEVICE_IDENTITY command has been
68 successfully returned
69
70**/
71EFI_STATUS
72AtaAtapi6Identify (
73 IN IDE_BLK_IO_DEV *IdeDev
74 )
75{
76 UINT8 Index;
77 EFI_LBA TmpLba;
78 EFI_LBA Capacity;
79 EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;
80
81 if (IdeDev->IdData == NULL) {
82 return EFI_INVALID_PARAMETER;
83 }
84
85 Atapi6IdentifyStruct = IdeDev->IdData;
86
87 if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & (BIT15 | BIT14)) != 0x4000) {
88 //
89 // Per ATA-6 spec, word83: bit15 is zero and bit14 is one
90 //
91 return EFI_DEVICE_ERROR;
92 }
93
94 if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {
95 //
96 // The device doesn't support 48 bit addressing
97 //
98 return EFI_UNSUPPORTED;
99 }
100
101 //
102 // 48 bit address feature set is supported, get maximum capacity
103 //
104 Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];
105 for (Index = 1; Index < 4; Index++) {
106 //
107 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
108 //
109 TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];
110 Capacity |= LShiftU64 (TmpLba, 16 * Index);
111 }
112
113 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
114 //
115 // Capacity exceeds 120GB. 48-bit addressing is really needed
116 //
117 IdeDev->Type = Ide48bitAddressingHardDisk;
118
119 //
120 // Fill block media information:Media->LogicalPartition ,
121 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
122 //
123 IdeDev->BlkIo.Media->IoAlign = 4;
124 IdeDev->BlkIo.Media->MediaId = 1;
125 IdeDev->BlkIo.Media->RemovableMedia = FALSE;
126 IdeDev->BlkIo.Media->MediaPresent = TRUE;
127 IdeDev->BlkIo.Media->ReadOnly = FALSE;
128 IdeDev->BlkIo.Media->BlockSize = 0x200;
129 IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
130
131 return EFI_SUCCESS;
132 }
133
134 return EFI_UNSUPPORTED;
135}
136/**
137 Enable SMART of the disk if supported
138
139 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
140 all the information of the IDE device.
141**/
142VOID
143AtaSMARTSupport (
144 IN IDE_BLK_IO_DEV *IdeDev
145 )
146{
147 EFI_STATUS Status;
148 BOOLEAN SMARTSupported;
149 UINT8 Device;
150 EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;
151 UINT8 DeviceSelect;
152 UINT8 LBAMid;
153 UINT8 LBAHigh;
154
155 //
156 // Detect if the device supports S.M.A.R.T.
157 //
158 if ((IdeDev->IdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {
159 //
160 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
161 //
162 return ;
163 } else {
164 if ((IdeDev->IdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
165 //
166 // S.M.A.R.T is not supported by the device
167 //
168 SMARTSupported = FALSE;
169 } else {
170 SMARTSupported = TRUE;
171 }
172 }
173
174 if (!SMARTSupported) {
175 //
176 // Report nonsupport status code
177 //
178 REPORT_STATUS_CODE (
179 EFI_ERROR_CODE | EFI_ERROR_MINOR,
180 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
181 );
182 } else {
183 //
184 // Enable this feature
185 //
186 REPORT_STATUS_CODE (
187 EFI_PROGRESS_CODE,
188 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
189 );
190
191 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
192 Status = AtaNonDataCommandIn (
193 IdeDev,
194 ATA_CMD_SMART,
195 Device,
196 ATA_SMART_ENABLE_OPERATION,
197 0,
198 0,
199 ATA_CONSTANT_4F,
200 ATA_CONSTANT_C2
201 );
202 //
203 // Detect if this feature is enabled
204 //
205 TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));
206 if (TmpAtaIdentifyPointer == NULL) {
207 return;
208 }
209
210 DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
211 Status = AtaPioDataIn (
212 IdeDev,
213 (VOID *) TmpAtaIdentifyPointer,
214 sizeof (EFI_IDENTIFY_DATA),
215 ATA_CMD_IDENTIFY_DRIVE,
216 DeviceSelect,
217 0,
218 0,
219 0,
220 0
221 );
222 if (EFI_ERROR (Status)) {
223 gBS->FreePool (TmpAtaIdentifyPointer);
224 return ;
225 }
226
227 //
228 // Check if the feature is enabled
229 //
230 if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {
231 //
232 // Read status data
233 //
234 AtaNonDataCommandIn (
235 IdeDev,
236 ATA_CMD_SMART,
237 Device,
238 ATA_SMART_RETURN_STATUS,
239 0,
240 0,
241 ATA_CONSTANT_4F,
242 ATA_CONSTANT_C2
243 );
244 LBAMid = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);
245 LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);
246
247 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
248 //
249 // The threshold exceeded condition is not detected by the device
250 //
251 REPORT_STATUS_CODE (
252 EFI_PROGRESS_CODE,
253 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
254 );
255
256 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
257 //
258 // The threshold exceeded condition is detected by the device
259 //
260 REPORT_STATUS_CODE (
261 EFI_PROGRESS_CODE,
262 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
263 );
264 }
265
266 } else {
267 //
268 // Report disabled status code
269 //
270 REPORT_STATUS_CODE (
271 EFI_ERROR_CODE | EFI_ERROR_MINOR,
272 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
273 );
274 }
275
276 gBS->FreePool (TmpAtaIdentifyPointer);
277 }
278
279 return ;
280}
281/**
282 Sends out an ATA Identify Command to the specified device.
283
284 This function is called by DiscoverIdeDevice() during its device
285 identification. It sends out the ATA Identify Command to the
286 specified device. Only ATA device responses to this command. If
287 the command succeeds, it returns the Identify data structure which
288 contains information about the device. This function extracts the
289 information it needs to fill the IDE_BLK_IO_DEV data structure,
290 including device type, media block size, media capacity, and etc.
291
292 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
293 all the information of the IDE device.
294
295 @retval EFI_SUCCESS Identify ATA device successfully.
296 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
297 @note parameter IdeDev will be updated in this function.
298
299**/
300EFI_STATUS
301ATAIdentify (
302 IN IDE_BLK_IO_DEV *IdeDev
303 )
304{
305 EFI_STATUS Status;
306 EFI_IDENTIFY_DATA *AtaIdentifyPointer;
307 UINT32 Capacity;
308 UINT8 DeviceSelect;
309 UINTN Retry;
310
311 //
312 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
313 // the ATA Identify command
314 //
315 AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));
316 if (AtaIdentifyPointer == NULL) {
317 return EFI_OUT_OF_RESOURCES;
318 }
319
320 //
321 // use ATA PIO Data In protocol to send ATA Identify command
322 // and receive data from device
323 //
324 DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
325
326
327 Retry = 3;
328 while (Retry > 0) {
329 Status = AtaPioDataIn (
330 IdeDev,
331 (VOID *) AtaIdentifyPointer,
332 sizeof (EFI_IDENTIFY_DATA),
333 ATA_CMD_IDENTIFY_DRIVE,
334 DeviceSelect,
335 0,
336 0,
337 0,
338 0
339 );
340 //
341 // If ATA Identify command succeeds, then according to the received
342 // IDENTIFY data,
343 // identify the device type ( ATA or not ).
344 // If ATA device, fill the information in IdeDev.
345 // If not ATA device, return IDE_DEVICE_ERROR
346 //
347 if (!EFI_ERROR (Status)) {
348
349 IdeDev->IdData = AtaIdentifyPointer;
350
351 //
352 // Print ATA Module Name
353 //
354 PrintAtaModuleName (IdeDev);
355
356 //
357 // bit 15 of pAtaIdentify->config is used to identify whether device is
358 // ATA device or ATAPI device.
359 // if 0, means ATA device; if 1, means ATAPI device.
360 //
361 if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {
362 //
363 // Detect if support S.M.A.R.T. If yes, enable it as default
364 //
365 AtaSMARTSupport (IdeDev);
366
367 //
368 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
369 //
370 Status = AtaAtapi6Identify (IdeDev);
371 if (!EFI_ERROR (Status)) {
372 //
373 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
374 //
375 return EFI_SUCCESS;
376 } else if (Status == EFI_DEVICE_ERROR) {
377 //
378 // Some disk with big capacity (>200GB) is slow when being identified
379 // and will return all zero for word83.
380 // We try twice at first. If it fails, we do a SoftRest and try again.
381 //
382 Retry--;
383 if (Retry == 1) {
384 //
385 // Do a SoftRest before the third attempt.
386 //
387 AtaSoftReset (IdeDev);
388 }
389 continue;
390 }
391 //
392 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
393 //
394 IdeDev->Type = IdeHardDisk;
395
396 //
397 // Block Media Information:
398 // Media->LogicalPartition , Media->WriteCaching will be filled
399 // in the DiscoverIdeDevcie() function.
400 //
401 IdeDev->BlkIo.Media->IoAlign = 4;
402 IdeDev->BlkIo.Media->MediaId = 1;
403 IdeDev->BlkIo.Media->RemovableMedia = FALSE;
404 IdeDev->BlkIo.Media->MediaPresent = TRUE;
405 IdeDev->BlkIo.Media->ReadOnly = FALSE;
406 IdeDev->BlkIo.Media->BlockSize = 0x200;
407
408 //
409 // Calculate device capacity
410 //
411 Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |
412 AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ;
413 IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
414
415 return EFI_SUCCESS;
416 }
417
418 }
419 break;
420 }
421
422 gBS->FreePool (AtaIdentifyPointer);
423 //
424 // Make sure the pIdData will not be freed again.
425 //
426 IdeDev->IdData = NULL;
427
428 return EFI_DEVICE_ERROR;
429}
430
431/**
432 This function is a helper function used to change the char order in a string. It
433 is designed specially for the PrintAtaModuleName() function. After the IDE device
434 is detected, the IDE driver gets the device module name by sending ATA command
435 called ATA Identify Command or ATAPI Identify Command to the specified IDE device.
436 The module name returned is a string of ASCII characters: the first character is bit8--bit15
437 of the first word, the second character is BIT0--bit7 of the first word and so on. Thus
438 the string can not be print directly before it is preprocessed by this func to change
439 the order of characters in each word in the string.
440
441 @param Destination Indicates the destination string.
442 @param Source Indicates the source string.
443 @param Size the length of the string
444**/
445VOID
446SwapStringChars (
447 IN CHAR8 *Destination,
448 IN CHAR8 *Source,
449 IN UINT32 Size
450 )
451{
452 UINT32 Index;
453 CHAR8 Temp;
454
455 for (Index = 0; Index < Size; Index += 2) {
456
457 Temp = Source[Index + 1];
458 Destination[Index + 1] = Source[Index];
459 Destination[Index] = Temp;
460 }
461}
462/**
463 This function is called by ATAIdentify() or ATAPIIdentify() to print device's module name.
464
465 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
466 all the information of the IDE device.
467**/
468VOID
469PrintAtaModuleName (
470 IN IDE_BLK_IO_DEV *IdeDev
471 )
472{
473 if (IdeDev->IdData == NULL) {
474 return ;
475 }
476
477 SwapStringChars (IdeDev->ModelName, IdeDev->IdData->AtaData.ModelName, 40);
478 IdeDev->ModelName[40] = 0x00;
479}
480
481/**
482 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
483
484 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
485 all the information of the IDE device.
486 @param Buffer buffer contained data transferred from device to host.
487 @param ByteCount data size in byte unit of the buffer.
488 @param AtaCommand value of the Command Register
489 @param Head value of the Head/Device Register
490 @param SectorCount value of the Sector Count Register
491 @param SectorNumber value of the Sector Number Register
492 @param CylinderLsb value of the low byte of the Cylinder Register
493 @param CylinderMsb value of the high byte of the Cylinder Register
494
495 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
496 @retval EFI_DEVICE_ERROR command sent failed.
497
498**/
499EFI_STATUS
500AtaPioDataIn (
501 IN IDE_BLK_IO_DEV *IdeDev,
502 IN VOID *Buffer,
503 IN UINT32 ByteCount,
504 IN UINT8 AtaCommand,
505 IN UINT8 Head,
506 IN UINT8 SectorCount,
507 IN UINT8 SectorNumber,
508 IN UINT8 CylinderLsb,
509 IN UINT8 CylinderMsb
510 )
511{
512 UINTN WordCount;
513 UINTN Increment;
514 UINT16 *Buffer16;
515 EFI_STATUS Status;
516
517 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
518 if (EFI_ERROR (Status)) {
519 return EFI_DEVICE_ERROR;
520 }
521
522 //
523 // e0:1110,0000-- bit7 and bit5 are reserved bits.
524 // bit6 set means LBA mode
525 //
526 IDEWritePortB (
527 IdeDev->PciIo,
528 IdeDev->IoPort->Head,
529 (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)
530 );
531
532 //
533 // All ATAPI device's ATA commands can be issued regardless of the
534 // state of the DRDY
535 //
536 if (IdeDev->Type == IdeHardDisk) {
537
538 Status = DRDYReady (IdeDev, ATATIMEOUT);
539 if (EFI_ERROR (Status)) {
540 return EFI_DEVICE_ERROR;
541 }
542 }
543 //
544 // set all the command parameters
545 // Before write to all the following registers, BSY and DRQ must be 0.
546 //
547 Status = DRQClear2 (IdeDev, ATATIMEOUT);
548 if (EFI_ERROR (Status)) {
549 return EFI_DEVICE_ERROR;
550 }
551
552 if (AtaCommand == ATA_CMD_SET_FEATURES) {
553 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);
554 }
555
556 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);
557 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);
558 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);
559 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);
560
561 //
562 // send command via Command Register
563 //
564 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
565
566 Buffer16 = (UINT16 *) Buffer;
567
568 //
569 // According to PIO data in protocol, host can perform a series of reads to
570 // the data register after each time device set DRQ ready;
571 // The data size of "a series of read" is command specific.
572 // For most ATA command, data size received from device will not exceed
573 // 1 sector, hence the data size for "a series of read" can be the whole data
574 // size of one command request.
575 // For ATA command such as Read Sector command, the data size of one ATA
576 // command request is often larger than 1 sector, according to the
577 // Read Sector command, the data size of "a series of read" is exactly 1
578 // sector.
579 // Here for simplification reason, we specify the data size for
580 // "a series of read" to 1 sector (256 words) if data size of one ATA command
581 // request is larger than 256 words.
582 //
583 Increment = 256;
584
585 //
586 // used to record bytes of currently transferred data
587 //
588 WordCount = 0;
589
590 while (WordCount < ByteCount / 2) {
591 //
592 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
593 //
594 Status = DRQReady2 (IdeDev, ATATIMEOUT);
595 if (EFI_ERROR (Status)) {
596 return EFI_DEVICE_ERROR;
597 }
598
599 Status = CheckErrorStatus (IdeDev);
600 if (EFI_ERROR (Status)) {
601 return EFI_DEVICE_ERROR;
602 }
603
604 //
605 // Get the byte count for one series of read
606 //
607 if ((WordCount + Increment) > ByteCount / 2) {
608 Increment = ByteCount / 2 - WordCount;
609 }
610
611 IDEReadPortWMultiple (
612 IdeDev->PciIo,
613 IdeDev->IoPort->Data,
614 Increment,
615 Buffer16
616 );
617
618 WordCount += Increment;
619 Buffer16 += Increment;
620
621 }
622
623 DRQClear (IdeDev, ATATIMEOUT);
624
625 return CheckErrorStatus (IdeDev);
626}
627
628/**
629 This function is used to send out ATA commands conforms to the
630 PIO Data Out Protocol.
631
632 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
633 to record all the information of the IDE device.
634 @param *Buffer buffer contained data transferred from host to device.
635 @param ByteCount data size in byte unit of the buffer.
636 @param AtaCommand value of the Command Register
637 @param Head value of the Head/Device Register
638 @param SectorCount value of the Sector Count Register
639 @param SectorNumber value of the Sector Number Register
640 @param CylinderLsb value of the low byte of the Cylinder Register
641 @param CylinderMsb value of the high byte of the Cylinder Register
642
643 @retval EFI_SUCCESS send out the ATA command and device received required
644 data successfully.
645 @retval EFI_DEVICE_ERROR command sent failed.
646
647**/
648EFI_STATUS
649AtaPioDataOut (
650 IN IDE_BLK_IO_DEV *IdeDev,
651 IN VOID *Buffer,
652 IN UINT32 ByteCount,
653 IN UINT8 AtaCommand,
654 IN UINT8 Head,
655 IN UINT8 SectorCount,
656 IN UINT8 SectorNumber,
657 IN UINT8 CylinderLsb,
658 IN UINT8 CylinderMsb
659 )
660{
661 UINTN WordCount;
662 UINTN Increment;
663 UINT16 *Buffer16;
664 EFI_STATUS Status;
665
666 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
667 if (EFI_ERROR (Status)) {
668 return EFI_DEVICE_ERROR;
669 }
670
671 //
672 // select device via Head/Device register.
673 // Before write Head/Device register, BSY and DRQ must be 0.
674 //
675 Status = DRQClear2 (IdeDev, ATATIMEOUT);
676 if (EFI_ERROR (Status)) {
677 return EFI_DEVICE_ERROR;
678 }
679
680 //
681 // e0:1110,0000-- bit7 and bit5 are reserved bits.
682 // bit6 set means LBA mode
683 //
684 IDEWritePortB (
685 IdeDev->PciIo,
686 IdeDev->IoPort->Head,
687 (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)
688 );
689
690 Status = DRDYReady (IdeDev, ATATIMEOUT);
691 if (EFI_ERROR (Status)) {
692 return EFI_DEVICE_ERROR;
693 }
694
695 //
696 // set all the command parameters
697 // Before write to all the following registers, BSY and DRQ must be 0.
698 //
699 Status = DRQClear2 (IdeDev, ATATIMEOUT);
700 if (EFI_ERROR (Status)) {
701 return EFI_DEVICE_ERROR;
702 }
703
704 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);
705 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);
706 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);
707 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);
708
709 //
710 // send command via Command Register
711 //
712 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
713
714 Buffer16 = (UINT16 *) Buffer;
715
716 //
717 // According to PIO data out protocol, host can perform a series of
718 // writes to the data register after each time device set DRQ ready;
719 // The data size of "a series of read" is command specific.
720 // For most ATA command, data size written to device will not exceed 1 sector,
721 // hence the data size for "a series of write" can be the data size of one
722 // command request.
723 // For ATA command such as Write Sector command, the data size of one
724 // ATA command request is often larger than 1 sector, according to the
725 // Write Sector command, the data size of "a series of read" is exactly
726 // 1 sector.
727 // Here for simplification reason, we specify the data size for
728 // "a series of write" to 1 sector (256 words) if data size of one ATA command
729 // request is larger than 256 words.
730 //
731 Increment = 256;
732 WordCount = 0;
733
734 while (WordCount < ByteCount / 2) {
735
736 //
737 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
738 // data transfer can be performed only when DRQ is ready.
739 //
740 Status = DRQReady2 (IdeDev, ATATIMEOUT);
741 if (EFI_ERROR (Status)) {
742 return EFI_DEVICE_ERROR;
743 }
744
745 Status = CheckErrorStatus (IdeDev);
746 if (EFI_ERROR (Status)) {
747 return EFI_DEVICE_ERROR;
748 }
749
750 //
751 // Check the remaining byte count is less than 512 bytes
752 //
753 if ((WordCount + Increment) > ByteCount / 2) {
754 Increment = ByteCount / 2 - WordCount;
755 }
756 //
757 // perform a series of write without check DRQ ready
758 //
759
760 IDEWritePortWMultiple (
761 IdeDev->PciIo,
762 IdeDev->IoPort->Data,
763 Increment,
764 Buffer16
765 );
766 WordCount += Increment;
767 Buffer16 += Increment;
768
769 }
770
771 DRQClear (IdeDev, ATATIMEOUT);
772
773 return CheckErrorStatus (IdeDev);
774}
775
776/**
777 This function is used to analyze the Status Register and print out
778 some debug information and if there is ERR bit set in the Status
779 Register, the Error Register's value is also be parsed and print out.
780
781 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to
782 record all the information of the IDE device.
783
784 @retval EFI_SUCCESS No err information in the Status Register.
785 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
786
787**/
788EFI_STATUS
789CheckErrorStatus (
790 IN IDE_BLK_IO_DEV *IdeDev
791 )
792{
793 UINT8 StatusRegister;
794 UINT8 ErrorRegister;
795
796 StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);
797
798 DEBUG_CODE_BEGIN ();
799
800 if ((StatusRegister & ATA_STSREG_DWF) != 0) {
801 DEBUG (
802 (EFI_D_BLKIO,
803 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
804 StatusRegister)
805 );
806 }
807
808 if ((StatusRegister & ATA_STSREG_CORR) != 0) {
809 DEBUG (
810 (EFI_D_BLKIO,
811 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
812 StatusRegister)
813 );
814 }
815
816 if ((StatusRegister & ATA_STSREG_ERR) != 0) {
817 ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);
818
819 if ((ErrorRegister & ATA_ERRREG_BBK) != 0) {
820 DEBUG (
821 (EFI_D_BLKIO,
822 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
823 ErrorRegister)
824 );
825 }
826
827 if ((ErrorRegister & ATA_ERRREG_UNC) != 0) {
828 DEBUG (
829 (EFI_D_BLKIO,
830 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
831 ErrorRegister)
832 );
833 }
834
835 if ((ErrorRegister & ATA_ERRREG_MC) != 0) {
836 DEBUG (
837 (EFI_D_BLKIO,
838 "CheckErrorStatus()-- %02x : Error : Media Change\n",
839 ErrorRegister)
840 );
841 }
842
843 if ((ErrorRegister & ATA_ERRREG_ABRT) != 0) {
844 DEBUG (
845 (EFI_D_BLKIO,
846 "CheckErrorStatus()-- %02x : Error : Abort\n",
847 ErrorRegister)
848 );
849 }
850
851 if ((ErrorRegister & ATA_ERRREG_TK0NF) != 0) {
852 DEBUG (
853 (EFI_D_BLKIO,
854 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
855 ErrorRegister)
856 );
857 }
858
859 if ((ErrorRegister & ATA_ERRREG_AMNF) != 0) {
860 DEBUG (
861 (EFI_D_BLKIO,
862 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
863 ErrorRegister)
864 );
865 }
866 }
867
868 DEBUG_CODE_END ();
869
870 if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {
871 return EFI_SUCCESS;
872 }
873
874 return EFI_DEVICE_ERROR;
875
876}
877
878/**
879 This function is called by the AtaBlkIoReadBlocks() to perform reading from
880 media in block unit.
881
882 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
883 all the information of the IDE device.
884 @param DataBuffer A pointer to the destination buffer for the data.
885 @param Lba The starting logical block address to read from on the device media.
886 @param NumberOfBlocks The number of transfer data blocks.
887
888 @return status is fully dependent on the return status of AtaPioDataIn() function.
889
890**/
891EFI_STATUS
892AtaReadSectors (
893 IN IDE_BLK_IO_DEV *IdeDev,
894 IN VOID *DataBuffer,
895 IN EFI_LBA Lba,
896 IN UINTN NumberOfBlocks
897 )
898{
899 EFI_STATUS Status;
900 UINTN BlocksRemaining;
901 UINT32 Lba32;
902 UINT8 Lba0;
903 UINT8 Lba1;
904 UINT8 Lba2;
905 UINT8 Lba3;
906 UINT8 AtaCommand;
907 UINT8 SectorCount8;
908 UINT16 SectorCount;
909 UINTN ByteCount;
910 VOID *Buffer;
911
912 Buffer = DataBuffer;
913
914 //
915 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
916 //
917 AtaCommand = ATA_CMD_READ_SECTORS;
918
919
920 BlocksRemaining = NumberOfBlocks;
921
922 Lba32 = (UINT32) Lba;
923
924 Status = EFI_SUCCESS;
925
926 while (BlocksRemaining > 0) {
927
928 //
929 // in ATA-3 spec, LBA is in 28 bit width
930 //
931 Lba0 = (UINT8) Lba32;
932 Lba1 = (UINT8) (Lba32 >> 8);
933 Lba2 = (UINT8) (Lba32 >> 16);
934 //
935 // low 4 bit of Lba3 stands for LBA bit24~bit27.
936 //
937 Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);
938
939 if (BlocksRemaining >= 0x100) {
940
941 //
942 // SectorCount8 is sent to Sector Count register, 0x00 means 256
943 // sectors to be read
944 //
945 SectorCount8 = 0x00;
946 //
947 // SectorCount is used to record the number of sectors to be read
948 //
949 SectorCount = 256;
950 } else {
951
952 SectorCount8 = (UINT8) BlocksRemaining;
953 SectorCount = (UINT16) BlocksRemaining;
954 }
955
956 //
957 // ByteCount is the number of bytes that will be read
958 //
959 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
960
961 //
962 // call AtaPioDataIn() to send Read Sector Command and receive data read
963 //
964 Status = AtaPioDataIn (
965 IdeDev,
966 Buffer,
967 (UINT32) ByteCount,
968 AtaCommand,
969 Lba3,
970 SectorCount8,
971 Lba0,
972 Lba1,
973 Lba2
974 );
975 if (EFI_ERROR (Status)) {
976 return Status;
977 }
978
979 Lba32 += SectorCount;
980 Buffer = ((UINT8 *) Buffer + ByteCount);
981 BlocksRemaining -= SectorCount;
982 }
983
984 return Status;
985}
986
987/**
988 This function is called by the AtaBlkIoWriteBlocks() to perform writing onto
989 media in block unit.
990
991 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
992 all the information of the IDE device.
993 @param BufferData A pointer to the source buffer for the data.
994 @param Lba The starting logical block address to write onto the device media.
995 @param NumberOfBlocks The number of transfer data blocks.
996
997 @return status is fully dependent on the return status of AtaPioDataIn() function.
998
999**/
1000EFI_STATUS
1001AtaWriteSectors (
1002 IN IDE_BLK_IO_DEV *IdeDev,
1003 IN VOID *BufferData,
1004 IN EFI_LBA Lba,
1005 IN UINTN NumberOfBlocks
1006 )
1007{
1008 EFI_STATUS Status;
1009 UINTN BlocksRemaining;
1010 UINT32 Lba32;
1011 UINT8 Lba0;
1012 UINT8 Lba1;
1013 UINT8 Lba2;
1014 UINT8 Lba3;
1015 UINT8 AtaCommand;
1016 UINT8 SectorCount8;
1017 UINT16 SectorCount;
1018 UINTN ByteCount;
1019 VOID *Buffer;
1020
1021 Buffer = BufferData;
1022
1023 //
1024 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
1025 //
1026 AtaCommand = ATA_CMD_WRITE_SECTORS;
1027
1028 BlocksRemaining = NumberOfBlocks;
1029
1030 Lba32 = (UINT32) Lba;
1031
1032 Status = EFI_SUCCESS;
1033
1034 while (BlocksRemaining > 0) {
1035
1036 Lba0 = (UINT8) Lba32;
1037 Lba1 = (UINT8) (Lba32 >> 8);
1038 Lba2 = (UINT8) (Lba32 >> 16);
1039 Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);
1040
1041 if (BlocksRemaining >= 0x100) {
1042
1043 //
1044 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
1045 // to be written
1046 //
1047 SectorCount8 = 0x00;
1048 //
1049 // SectorCount is used to record the number of sectors to be written
1050 //
1051 SectorCount = 256;
1052 } else {
1053
1054 SectorCount8 = (UINT8) BlocksRemaining;
1055 SectorCount = (UINT16) BlocksRemaining;
1056 }
1057
1058 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
1059
1060 Status = AtaPioDataOut (
1061 IdeDev,
1062 Buffer,
1063 (UINT32) ByteCount,
1064 AtaCommand,
1065 Lba3,
1066 SectorCount8,
1067 Lba0,
1068 Lba1,
1069 Lba2
1070 );
1071 if (EFI_ERROR (Status)) {
1072 return Status;
1073 }
1074
1075 Lba32 += SectorCount;
1076 Buffer = ((UINT8 *) Buffer + ByteCount);
1077 BlocksRemaining -= SectorCount;
1078 }
1079
1080 return Status;
1081}
1082/**
1083 This function is used to implement the Soft Reset on the specified device. But,
1084 the ATA Soft Reset mechanism is so strong a reset method that it will force
1085 resetting on both devices connected to the same cable.
1086
1087 It is called by IdeBlkIoReset(), a interface function of Block
1088 I/O protocol.
1089
1090 This function can also be used by the ATAPI device to perform reset when
1091 ATAPI Reset command is failed.
1092
1093 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1094 all the information of the IDE device.
1095 @retval EFI_SUCCESS Soft reset completes successfully.
1096 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
1097
1098 @note The registers initial values after ATA soft reset are different
1099 to the ATA device and ATAPI device.
1100**/
1101EFI_STATUS
1102AtaSoftReset (
1103 IN IDE_BLK_IO_DEV *IdeDev
1104 )
1105{
1106
1107 UINT8 DeviceControl;
1108
1109 DeviceControl = 0;
1110 //
1111 // set SRST bit to initiate soft reset
1112 //
1113 DeviceControl |= ATA_CTLREG_SRST;
1114
1115 //
1116 // disable Interrupt
1117 //
1118 DeviceControl |= BIT1;
1119
1120 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
1121
1122 //
1123 // SRST should assert for at least 5 us, we use 10 us for
1124 // better compatibility
1125 //
1126 gBS->Stall (10);
1127
1128 //
1129 // Enable interrupt to support UDMA, and clear SRST bit
1130 //
1131 DeviceControl = 0;
1132 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
1133
1134 //
1135 // Wait for at least 2 ms to check BSY status, we use 10 ms
1136 // for better compatibility
1137 //
1138 gBS->Stall(10000);
1139 //
1140 // slave device needs at most 31s to clear BSY
1141 //
1142 if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) {
1143 return EFI_DEVICE_ERROR;
1144 }
1145
1146 return EFI_SUCCESS;
1147}
1148/**
1149 This function is used to send out ATA commands conforms to the PIO Data In
1150 Protocol, supporting ATA/ATAPI-6 standard
1151
1152 Comparing with ATA-3 data in protocol, we have two differences here:
1153 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1154 wait will frequently fail... cause writing function return error)
1155
1156 2. Do NOT wait for DRQ clear after all data read.(the wait greatly
1157 slow down writing performance by 100 times!)
1158
1159 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1160 to record all the information of the IDE device.
1161 @param Buffer buffer contained data transferred from device to host.
1162 @param ByteCount data size in byte unit of the buffer.
1163 @param AtaCommand value of the Command Register
1164 @param StartLba the start LBA of this transaction
1165 @param SectorCount the count of sectors to be transferred
1166
1167 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1168 @retval EFI_DEVICE_ERROR command sent failed.
1169
1170**/
1171EFI_STATUS
1172AtaPioDataInExt (
1173 IN IDE_BLK_IO_DEV *IdeDev,
1174 IN OUT VOID *Buffer,
1175 IN UINT32 ByteCount,
1176 IN UINT8 AtaCommand,
1177 IN EFI_LBA StartLba,
1178 IN UINT16 SectorCount
1179 )
1180{
1181 UINT8 DevSel;
1182 UINT8 SectorCount8;
1183 UINT8 LbaLow;
1184 UINT8 LbaMid;
1185 UINT8 LbaHigh;
1186 UINTN WordCount;
1187 UINTN Increment;
1188 UINT16 *Buffer16;
1189 EFI_STATUS Status;
1190
1191 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
1192 if (EFI_ERROR (Status)) {
1193 return EFI_DEVICE_ERROR;
1194 }
1195
1196 //
1197 // Select device, set bit6 as 1 to indicate LBA mode is used
1198 //
1199 DevSel = (UINT8) (IdeDev->Device << 4);
1200 DevSel |= 0x40;
1201 IDEWritePortB (
1202 IdeDev->PciIo,
1203 IdeDev->IoPort->Head,
1204 DevSel
1205 );
1206
1207 //
1208 // Wait for DRDY signal asserting. ATAPI device needn't wait
1209 //
1210 if ( (IdeDev->Type == IdeHardDisk) ||
1211 (IdeDev->Type == Ide48bitAddressingHardDisk)) {
1212
1213 Status = DRDYReady (IdeDev, ATATIMEOUT);
1214 if (EFI_ERROR (Status)) {
1215 return EFI_DEVICE_ERROR;
1216 }
1217 }
1218
1219 //
1220 // Fill feature register if needed
1221 //
1222 if (AtaCommand == ATA_CMD_SET_FEATURES) {
1223 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);
1224 }
1225
1226 //
1227 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1228 //
1229 SectorCount8 = (UINT8) (SectorCount >> 8);
1230 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1231
1232 SectorCount8 = (UINT8) SectorCount;
1233 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1234
1235 //
1236 // Fill the start LBA registers, which are also two-byte FIFO
1237 //
1238 LbaLow = (UINT8) RShiftU64 (StartLba, 24);
1239 LbaMid = (UINT8) RShiftU64 (StartLba, 32);
1240 LbaHigh = (UINT8) RShiftU64 (StartLba, 40);
1241 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1242 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1243 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1244
1245 LbaLow = (UINT8) StartLba;
1246 LbaMid = (UINT8) RShiftU64 (StartLba, 8);
1247 LbaHigh = (UINT8) RShiftU64 (StartLba, 16);
1248 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1249 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1250 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1251
1252 //
1253 // Send command via Command Register, invoking the processing of this command
1254 //
1255 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
1256
1257 Buffer16 = (UINT16 *) Buffer;
1258
1259 //
1260 // According to PIO data in protocol, host can perform a series of reads to
1261 // the data register after each time device set DRQ ready;
1262 //
1263
1264 //
1265 // 256 words
1266 //
1267 Increment = 256;
1268
1269 //
1270 // used to record bytes of currently transferred data
1271 //
1272 WordCount = 0;
1273
1274 while (WordCount < ByteCount / 2) {
1275 //
1276 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1277 //
1278 Status = DRQReady2 (IdeDev, ATATIMEOUT);
1279 if (EFI_ERROR (Status)) {
1280 return EFI_DEVICE_ERROR;
1281 }
1282
1283 Status = CheckErrorStatus (IdeDev);
1284 if (EFI_ERROR (Status)) {
1285 return EFI_DEVICE_ERROR;
1286 }
1287
1288 //
1289 // Get the byte count for one series of read
1290 //
1291 if ((WordCount + Increment) > ByteCount / 2) {
1292 Increment = ByteCount / 2 - WordCount;
1293 }
1294
1295 IDEReadPortWMultiple (
1296 IdeDev->PciIo,
1297 IdeDev->IoPort->Data,
1298 Increment,
1299 Buffer16
1300 );
1301
1302 WordCount += Increment;
1303 Buffer16 += Increment;
1304
1305 }
1306
1307 return CheckErrorStatus (IdeDev);
1308}
1309/**
1310 Send ATA Ext command into device with NON_DATA protocol.
1311
1312 @param IdeDev Standard IDE device private data structure
1313 @param AtaCommand The ATA command to be sent
1314 @param Device The value in Device register
1315 @param Feature The value in Feature register
1316 @param SectorCount The value in SectorCount register
1317 @param LbaAddress The LBA address in 48-bit mode
1318
1319 @retval EFI_SUCCESS Reading succeed
1320 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1321
1322**/
1323EFI_STATUS
1324AtaCommandIssueExt (
1325 IN IDE_BLK_IO_DEV *IdeDev,
1326 IN UINT8 AtaCommand,
1327 IN UINT8 Device,
1328 IN UINT16 Feature,
1329 IN UINT16 SectorCount,
1330 IN EFI_LBA LbaAddress
1331 )
1332{
1333 EFI_STATUS Status;
1334 UINT8 SectorCount8;
1335 UINT8 Feature8;
1336 UINT8 LbaLow;
1337 UINT8 LbaMid;
1338 UINT8 LbaHigh;
1339
1340 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
1341 if (EFI_ERROR (Status)) {
1342 return EFI_DEVICE_ERROR;
1343 }
1344
1345 //
1346 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1347 //
1348 IDEWritePortB (
1349 IdeDev->PciIo,
1350 IdeDev->IoPort->Head,
1351 (UINT8) ((IdeDev->Device << 4) | 0xe0)
1352 );
1353
1354 //
1355 // ATA commands for ATA device must be issued when DRDY is set
1356 //
1357 Status = DRDYReady (IdeDev, ATATIMEOUT);
1358 if (EFI_ERROR (Status)) {
1359 return EFI_DEVICE_ERROR;
1360 }
1361
1362 //
1363 // Pass parameter into device register block
1364 //
1365 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
1366
1367 //
1368 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1369 //
1370 Feature8 = (UINT8) (Feature >> 8);
1371 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
1372
1373 Feature8 = (UINT8) Feature;
1374 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
1375
1376 //
1377 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1378 //
1379 SectorCount8 = (UINT8) (SectorCount >> 8);
1380 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1381
1382 SectorCount8 = (UINT8) SectorCount;
1383 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1384
1385 //
1386 // Fill the start LBA registers, which are also two-byte FIFO
1387 //
1388 LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);
1389 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1390 LbaLow = (UINT8) LbaAddress;
1391 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1392
1393 LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);
1394 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1395 LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);
1396 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1397
1398 LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);
1399 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1400 LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);
1401 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1402
1403 //
1404 // Work around for Segate 160G disk writing
1405 //
1406 gBS->Stall (1800);
1407
1408 //
1409 // Send command via Command Register
1410 //
1411 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
1412
1413 //
1414 // Stall at least 400ns
1415 //
1416 gBS->Stall (100);
1417
1418 return EFI_SUCCESS;
1419}
1420/**
1421 Send ATA Ext command into device with NON_DATA protocol
1422
1423 @param IdeDev Standard IDE device private data structure
1424 @param AtaCommand The ATA command to be sent
1425 @param Device The value in Device register
1426 @param Feature The value in Feature register
1427 @param SectorCount The value in SectorCount register
1428 @param LbaAddress The LBA address in 48-bit mode
1429
1430 @retval EFI_SUCCESS Reading succeed
1431 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1432
1433**/
1434EFI_STATUS
1435AtaCommandIssue (
1436 IN IDE_BLK_IO_DEV *IdeDev,
1437 IN UINT8 AtaCommand,
1438 IN UINT8 Device,
1439 IN UINT16 Feature,
1440 IN UINT16 SectorCount,
1441 IN EFI_LBA LbaAddress
1442 )
1443{
1444 EFI_STATUS Status;
1445 UINT8 SectorCount8;
1446 UINT8 Feature8;
1447 UINT8 Lba0;
1448 UINT8 Lba1;
1449 UINT8 Lba2;
1450 UINT8 Lba3;
1451
1452 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
1453 if (EFI_ERROR (Status)) {
1454 return EFI_DEVICE_ERROR;
1455 }
1456
1457 //
1458 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1459 //
1460 IDEWritePortB (
1461 IdeDev->PciIo,
1462 IdeDev->IoPort->Head,
1463 (UINT8) ((IdeDev->Device << 4) | 0xe0)
1464 );
1465
1466 //
1467 // ATA commands for ATA device must be issued when DRDY is set
1468 //
1469 Status = DRDYReady (IdeDev, ATATIMEOUT);
1470 if (EFI_ERROR (Status)) {
1471 return EFI_DEVICE_ERROR;
1472 }
1473
1474 Lba0 = (UINT8) LbaAddress;
1475 Lba1 = (UINT8) RShiftU64 (LbaAddress, 8);
1476 Lba2 = (UINT8) RShiftU64 (LbaAddress, 16);
1477 Lba3 = (UINT8) RShiftU64 (LbaAddress, 24);
1478 Device = (UINT8) (Device | Lba3);
1479
1480 //
1481 // Pass parameter into device register block
1482 //
1483 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
1484
1485 //
1486 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1487 //
1488 Feature8 = (UINT8) Feature;
1489 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
1490
1491 //
1492 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1493 //
1494 SectorCount8 = (UINT8) SectorCount;
1495 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1496
1497 //
1498 // Fill the start LBA registers, which are also two-byte FIFO
1499 //
1500
1501 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);
1502 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);
1503 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);
1504
1505 //
1506 // Send command via Command Register
1507 //
1508 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
1509
1510 //
1511 // Stall at least 400ns
1512 //
1513 gBS->Stall (100);
1514
1515 return EFI_SUCCESS;
1516}
1517/**
1518 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1519
1520 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1521 to record all the information of the IDE device.
1522 @param DataBuffer A pointer to the source buffer for the data.
1523 @param StartLba The starting logical block address to write to
1524 on the device media.
1525 @param NumberOfBlocks The number of transfer data blocks.
1526 @param UdmaOp The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
1527 AtaUdmaWriteOp, AtaUdmaWriteExOp
1528
1529 @retval EFI_SUCCESS the operation is successful.
1530 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1531 @retval EFI_UNSUPPORTED Unknown channel or operations command
1532 @retval EFI_DEVICE_ERROR Ata command execute failed
1533
1534**/
1535EFI_STATUS
1536DoAtaUdma (
1537 IN IDE_BLK_IO_DEV *IdeDev,
1538 IN VOID *DataBuffer,
1539 IN EFI_LBA StartLba,
1540 IN UINTN NumberOfBlocks,
1541 IN ATA_UDMA_OPERATION UdmaOp
1542 )
1543{
1544 IDE_DMA_PRD *PrdAddr;
1545 IDE_DMA_PRD *UsedPrdAddr;
1546 IDE_DMA_PRD *TempPrdAddr;
1547 UINT8 RegisterValue;
1548 UINT8 Device;
1549 UINT64 IoPortForBmic;
1550 UINT64 IoPortForBmis;
1551 UINT64 IoPortForBmid;
1552 EFI_STATUS Status;
1553 UINTN PrdTableNum;
1554 UINTN ByteCount;
1555 UINTN ByteAvailable;
1556 UINT8 *PrdBuffer;
1557 UINTN RemainBlockNum;
1558 UINT8 DeviceControl;
1559 UINT32 Count;
1560 UINTN PageCount;
1561 VOID *Map;
1562 VOID *MemPage;
1563 EFI_PHYSICAL_ADDRESS DeviceAddress;
1564 UINTN MaxDmaCommandSectors;
1565 EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp;
1566 UINT8 AtaCommand;
1567
1568 switch (UdmaOp) {
1569 case AtaUdmaReadOp:
1570 MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;
1571 PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;
1572 AtaCommand = ATA_CMD_READ_DMA;
1573 break;
1574 case AtaUdmaReadExtOp:
1575 MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;
1576 PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;
1577 AtaCommand = ATA_CMD_READ_DMA_EXT;
1578 break;
1579 case AtaUdmaWriteOp:
1580 MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;
1581 PciIoProtocolOp = EfiPciIoOperationBusMasterRead;
1582 AtaCommand = ATA_CMD_WRITE_DMA;
1583 break;
1584 case AtaUdmaWriteExtOp:
1585 MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;
1586 PciIoProtocolOp = EfiPciIoOperationBusMasterRead;
1587 AtaCommand = ATA_CMD_WRITE_DMA_EXT;
1588 break;
1589 default:
1590 return EFI_UNSUPPORTED;
1591 break;
1592 }
1593
1594 //
1595 // Select device
1596 //
1597 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
1598 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
1599
1600 //
1601 // Enable interrupt to support UDMA
1602 //
1603 DeviceControl = 0;
1604 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
1605
1606 if (IdePrimary == IdeDev->Channel) {
1607 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
1608 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
1609 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
1610 } else {
1611 if (IdeSecondary == IdeDev->Channel) {
1612 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
1613 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
1614 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
1615 } else {
1616 return EFI_UNSUPPORTED;
1617 }
1618 }
1619
1620 //
1621 // Read BMIS register and clear ERROR and INTR bit
1622 //
1623 IdeDev->PciIo->Io.Read (
1624 IdeDev->PciIo,
1625 EfiPciIoWidthUint8,
1626 EFI_PCI_IO_PASS_THROUGH_BAR,
1627 IoPortForBmis,
1628 1,
1629 &RegisterValue
1630 );
1631
1632 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1633
1634 IdeDev->PciIo->Io.Write (
1635 IdeDev->PciIo,
1636 EfiPciIoWidthUint8,
1637 EFI_PCI_IO_PASS_THROUGH_BAR,
1638 IoPortForBmis,
1639 1,
1640 &RegisterValue
1641 );
1642
1643 Status = EFI_SUCCESS;
1644
1645 RemainBlockNum = NumberOfBlocks;
1646 while (RemainBlockNum > 0) {
1647
1648 if (RemainBlockNum >= MaxDmaCommandSectors) {
1649 //
1650 // SectorCount is used to record the number of sectors to be read
1651 // Max 65536 sectors can be transferred at a time.
1652 //
1653 NumberOfBlocks = MaxDmaCommandSectors;
1654 RemainBlockNum -= MaxDmaCommandSectors;
1655 } else {
1656 NumberOfBlocks = (UINT16) RemainBlockNum;
1657 RemainBlockNum = 0;
1658 }
1659
1660 //
1661 // Calculate the number of PRD table to make sure the memory region
1662 // not cross 64K boundary
1663 //
1664 ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
1665 PrdTableNum = ((ByteCount >> 16) + 1) + 1;
1666
1667 //
1668 // Build PRD table
1669 //
1670 PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));
1671 Status = IdeDev->PciIo->AllocateBuffer (
1672 IdeDev->PciIo,
1673 AllocateAnyPages,
1674 EfiBootServicesData,
1675 PageCount,
1676 &MemPage,
1677 0
1678 );
1679 if (EFI_ERROR (Status)) {
1680 return EFI_OUT_OF_RESOURCES;
1681 }
1682 ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));
1683
1684 PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);
1685 //
1686 // To make sure PRD is allocated in one 64K page
1687 //
1688 if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
1689 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
1690 } else {
1691 if ((UINTN) PrdAddr & 0x03) {
1692 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
1693 } else {
1694 UsedPrdAddr = PrdAddr;
1695 }
1696 }
1697
1698 //
1699 // Build the PRD table
1700 //
1701 Status = IdeDev->PciIo->Map (
1702 IdeDev->PciIo,
1703 PciIoProtocolOp,
1704 DataBuffer,
1705 &ByteCount,
1706 &DeviceAddress,
1707 &Map
1708 );
1709 if (EFI_ERROR (Status)) {
1710 IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
1711 return EFI_OUT_OF_RESOURCES;
1712 }
1713 PrdBuffer = (VOID *) ((UINTN) DeviceAddress);
1714 TempPrdAddr = UsedPrdAddr;
1715 while (TRUE) {
1716
1717 ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
1718
1719 if (ByteCount <= ByteAvailable) {
1720 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
1721 TempPrdAddr->ByteCount = (UINT16) ByteCount;
1722 TempPrdAddr->EndOfTable = 0x8000;
1723 break;
1724 }
1725
1726 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
1727 TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
1728
1729 ByteCount -= ByteAvailable;
1730 PrdBuffer += ByteAvailable;
1731 TempPrdAddr++;
1732 }
1733
1734 //
1735 // Set the base address to BMID register
1736 //
1737 IdeDev->PciIo->Io.Write (
1738 IdeDev->PciIo,
1739 EfiPciIoWidthUint32,
1740 EFI_PCI_IO_PASS_THROUGH_BAR,
1741 IoPortForBmid,
1742 1,
1743 &UsedPrdAddr
1744 );
1745
1746 //
1747 // Set BMIC register to identify the operation direction
1748 //
1749 IdeDev->PciIo->Io.Read (
1750 IdeDev->PciIo,
1751 EfiPciIoWidthUint8,
1752 EFI_PCI_IO_PASS_THROUGH_BAR,
1753 IoPortForBmic,
1754 1,
1755 &RegisterValue
1756 );
1757
1758 if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {
1759 RegisterValue |= BMIC_NREAD;
1760 } else {
1761 RegisterValue &= ~((UINT8) BMIC_NREAD);
1762 }
1763
1764 IdeDev->PciIo->Io.Write (
1765 IdeDev->PciIo,
1766 EfiPciIoWidthUint8,
1767 EFI_PCI_IO_PASS_THROUGH_BAR,
1768 IoPortForBmic,
1769 1,
1770 &RegisterValue
1771 );
1772
1773 if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {
1774 Status = AtaCommandIssueExt (
1775 IdeDev,
1776 AtaCommand,
1777 Device,
1778 0,
1779 (UINT16) NumberOfBlocks,
1780 StartLba
1781 );
1782 } else {
1783 Status = AtaCommandIssue (
1784 IdeDev,
1785 AtaCommand,
1786 Device,
1787 0,
1788 (UINT16) NumberOfBlocks,
1789 StartLba
1790 );
1791 }
1792
1793 if (EFI_ERROR (Status)) {
1794 IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
1795 IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
1796 return EFI_DEVICE_ERROR;
1797 }
1798
1799 //
1800 // Set START bit of BMIC register
1801 //
1802 IdeDev->PciIo->Io.Read (
1803 IdeDev->PciIo,
1804 EfiPciIoWidthUint8,
1805 EFI_PCI_IO_PASS_THROUGH_BAR,
1806 IoPortForBmic,
1807 1,
1808 &RegisterValue
1809 );
1810
1811 RegisterValue |= BMIC_START;
1812
1813 IdeDev->PciIo->Io.Write (
1814 IdeDev->PciIo,
1815 EfiPciIoWidthUint8,
1816 EFI_PCI_IO_PASS_THROUGH_BAR,
1817 IoPortForBmic,
1818 1,
1819 &RegisterValue
1820 );
1821
1822 //
1823 // Check the INTERRUPT and ERROR bit of BMIS
1824 // Max transfer number of sectors for one command is 65536(32Mbyte),
1825 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1826 // So set the variable Count to 2000, for about 2 second timeout time.
1827 //
1828 Status = EFI_SUCCESS;
1829 Count = 2000;
1830 while (TRUE) {
1831
1832 IdeDev->PciIo->Io.Read (
1833 IdeDev->PciIo,
1834 EfiPciIoWidthUint8,
1835 EFI_PCI_IO_PASS_THROUGH_BAR,
1836 IoPortForBmis,
1837 1,
1838 &RegisterValue
1839 );
1840 if (((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) != 0) || (Count == 0)) {
1841 if (((RegisterValue & BMIS_ERROR) != 0) || (Count == 0)) {
1842 Status = EFI_DEVICE_ERROR;
1843 break;
1844 }
1845 break;
1846 }
1847
1848 gBS->Stall (1000);
1849 Count --;
1850 }
1851
1852 IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
1853 IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
1854 //
1855 // Read BMIS register and clear ERROR and INTR bit
1856 //
1857 IdeDev->PciIo->Io.Read (
1858 IdeDev->PciIo,
1859 EfiPciIoWidthUint8,
1860 EFI_PCI_IO_PASS_THROUGH_BAR,
1861 IoPortForBmis,
1862 1,
1863 &RegisterValue
1864 );
1865
1866 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1867
1868 IdeDev->PciIo->Io.Write (
1869 IdeDev->PciIo,
1870 EfiPciIoWidthUint8,
1871 EFI_PCI_IO_PASS_THROUGH_BAR,
1872 IoPortForBmis,
1873 1,
1874 &RegisterValue
1875 );
1876 //
1877 // Read Status Register of IDE device to clear interrupt
1878 //
1879 RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
1880 //
1881 // Clear START bit of BMIC register
1882 //
1883 IdeDev->PciIo->Io.Read (
1884 IdeDev->PciIo,
1885 EfiPciIoWidthUint8,
1886 EFI_PCI_IO_PASS_THROUGH_BAR,
1887 IoPortForBmic,
1888 1,
1889 &RegisterValue
1890 );
1891
1892 RegisterValue &= ~((UINT8) BMIC_START);
1893
1894 IdeDev->PciIo->Io.Write (
1895 IdeDev->PciIo,
1896 EfiPciIoWidthUint8,
1897 EFI_PCI_IO_PASS_THROUGH_BAR,
1898 IoPortForBmic,
1899 1,
1900 &RegisterValue
1901 );
1902
1903 if ((RegisterValue & BMIS_ERROR) != 0) {
1904 return EFI_DEVICE_ERROR;
1905 }
1906
1907 if (EFI_ERROR (Status)) {
1908 break;
1909 }
1910 DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
1911 StartLba += NumberOfBlocks;
1912 }
1913
1914 //
1915 // Disable interrupt of Select device
1916 //
1917 IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);
1918 DeviceControl |= ATA_CTLREG_IEN_L;
1919 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
1920
1921 return Status;
1922}
1923
1924
1925/**
1926 This function is called by the AtaBlkIoReadBlocks() to perform reading from
1927 media in block unit. The function has been enhanced to support >120GB access
1928 and transfer at most 65536 blocks per command
1929
1930 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1931 all the information of the IDE device.
1932 @param DataBuffer A pointer to the destination buffer for the data.
1933 @param StartLba The starting logical block address to read from on the device media.
1934 @param NumberOfBlocks The number of transfer data blocks.
1935
1936 @return status depends on the function DoAtaUdma() returns.
1937**/
1938EFI_STATUS
1939AtaUdmaReadExt (
1940 IN IDE_BLK_IO_DEV *IdeDev,
1941 IN VOID *DataBuffer,
1942 IN EFI_LBA StartLba,
1943 IN UINTN NumberOfBlocks
1944 )
1945{
1946 return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);
1947}
1948/**
1949 This function is called by the AtaBlkIoReadBlocks() to perform
1950 reading from media in block unit. The function has been enhanced to
1951 support >120GB access and transfer at most 65536 blocks per command
1952
1953 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1954 all the information of the IDE device.
1955 @param DataBuffer A pointer to the destination buffer for the data.
1956 @param StartLba The starting logical block address to read from
1957 on the device media.
1958 @param NumberOfBlocks The number of transfer data blocks.
1959
1960 @return status depends on the function DoAtaUdma() returns.
1961**/
1962EFI_STATUS
1963AtaUdmaRead (
1964 IN IDE_BLK_IO_DEV *IdeDev,
1965 IN VOID *DataBuffer,
1966 IN EFI_LBA StartLba,
1967 IN UINTN NumberOfBlocks
1968 )
1969{
1970 return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);
1971}
1972
1973/**
1974 This function is called by the AtaBlkIoReadBlocks() to perform
1975 reading from media in block unit. The function has been enhanced to
1976 support >120GB access and transfer at most 65536 blocks per command
1977
1978 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1979 all the information of the IDE device.
1980 @param DataBuffer A pointer to the destination buffer for the data.
1981 @param StartLba The starting logical block address to read from on the device media.
1982 @param NumberOfBlocks The number of transfer data blocks.
1983
1984 @return status is fully dependent on the return status of AtaPioDataInExt() function.
1985**/
1986EFI_STATUS
1987AtaReadSectorsExt (
1988 IN IDE_BLK_IO_DEV *IdeDev,
1989 IN VOID *DataBuffer,
1990 IN EFI_LBA StartLba,
1991 IN UINTN NumberOfBlocks
1992 )
1993{
1994 EFI_STATUS Status;
1995 UINTN BlocksRemaining;
1996 EFI_LBA Lba64;
1997 UINT8 AtaCommand;
1998 UINT16 SectorCount;
1999 UINT32 ByteCount;
2000 VOID *Buffer;
2001
2002 //
2003 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
2004 //
2005 AtaCommand = ATA_CMD_READ_SECTORS_EXT;
2006 Buffer = DataBuffer;
2007 BlocksRemaining = NumberOfBlocks;
2008 Lba64 = StartLba;
2009 Status = EFI_SUCCESS;
2010
2011 while (BlocksRemaining > 0) {
2012
2013 if (BlocksRemaining >= 0x10000) {
2014 //
2015 // SectorCount is used to record the number of sectors to be read
2016 // Max 65536 sectors can be transferred at a time.
2017 //
2018 SectorCount = 0xffff;
2019 } else {
2020 SectorCount = (UINT16) BlocksRemaining;
2021 }
2022
2023 //
2024 // ByteCount is the number of bytes that will be read
2025 //
2026 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
2027
2028 //
2029 // call AtaPioDataInExt() to send Read Sector Command and receive data read
2030 //
2031 Status = AtaPioDataInExt (
2032 IdeDev,
2033 Buffer,
2034 ByteCount,
2035 AtaCommand,
2036 Lba64,
2037 SectorCount
2038 );
2039 if (EFI_ERROR (Status)) {
2040 return Status;
2041 }
2042
2043 Lba64 += SectorCount;
2044 Buffer = ((UINT8 *) Buffer + ByteCount);
2045 BlocksRemaining -= SectorCount;
2046 }
2047
2048 return Status;
2049}
2050/**
2051 This function is the ATA implementation for ReadBlocks in the
2052 Block I/O Protocol interface.
2053
2054 @param IdeBlkIoDevice Indicates the calling context.
2055 @param MediaId The media id that the read request is for.
2056 @param Lba The starting logical block address to read from on the device.
2057 @param BufferSize The size of the Buffer in bytes. This must be a multiple
2058 of the intrinsic block size of the device.
2059
2060 @param Buffer A pointer to the destination buffer for the data. The caller
2061 is responsible for either having implicit or explicit ownership
2062 of the memory that data is read into.
2063
2064 @retval EFI_SUCCESS Read Blocks successfully.
2065 @retval EFI_DEVICE_ERROR Read Blocks failed.
2066 @retval EFI_NO_MEDIA There is no media in the device.
2067 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
2068 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
2069 intrinsic block size of the device.
2070 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
2071 or the data buffer is not valid.
2072
2073 @note If Read Block error because of device error, this function will call
2074 AtaSoftReset() function to reset device.
2075
2076**/
2077EFI_STATUS
2078AtaBlkIoReadBlocks (
2079 IN IDE_BLK_IO_DEV *IdeBlkIoDevice,
2080 IN UINT32 MediaId,
2081 IN EFI_LBA Lba,
2082 IN UINTN BufferSize,
2083 OUT VOID *Buffer
2084 )
2085{
2086 EFI_BLOCK_IO_MEDIA *Media;
2087 UINTN BlockSize;
2088 UINTN NumberOfBlocks;
2089 EFI_STATUS Status;
2090
2091 if (Buffer == NULL) {
2092 return EFI_INVALID_PARAMETER;
2093 }
2094
2095 if (BufferSize == 0) {
2096 return EFI_SUCCESS;
2097 }
2098
2099 Status = EFI_SUCCESS;
2100
2101 //
2102 // Get the intrinsic block size
2103 //
2104 Media = IdeBlkIoDevice->BlkIo.Media;
2105 BlockSize = Media->BlockSize;
2106
2107 NumberOfBlocks = BufferSize / BlockSize;
2108
2109 if (MediaId != Media->MediaId) {
2110 return EFI_MEDIA_CHANGED;
2111 }
2112
2113 if (BufferSize % BlockSize != 0) {
2114 return EFI_BAD_BUFFER_SIZE;
2115 }
2116
2117 if (!(Media->MediaPresent)) {
2118 return EFI_NO_MEDIA;
2119 }
2120
2121 if (Lba > Media->LastBlock) {
2122 return EFI_INVALID_PARAMETER;
2123 }
2124
2125 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
2126 return EFI_INVALID_PARAMETER;
2127 }
2128
2129 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
2130 return EFI_INVALID_PARAMETER;
2131 }
2132
2133 Status = EFI_SUCCESS;
2134 if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
2135 //
2136 // For ATA/ATAPI-6 device(capacity > 120GB), use ATA-6 read block mechanism
2137 //
2138 if (IdeBlkIoDevice->UdmaMode.Valid) {
2139 Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2140 } else {
2141 Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2142 }
2143 } else {
2144 //
2145 // For ATA-3 compatible device, use ATA-3 read block mechanism
2146 //
2147 if (IdeBlkIoDevice->UdmaMode.Valid) {
2148 Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2149 } else {
2150 Status = AtaReadSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2151 }
2152 }
2153
2154 if (EFI_ERROR (Status)) {
2155 AtaSoftReset (IdeBlkIoDevice);
2156 return EFI_DEVICE_ERROR;
2157 }
2158
2159 return EFI_SUCCESS;
2160
2161}
2162/**
2163 This function is used to send out ATA commands conforms to the
2164 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
2165
2166 Comparing with ATA-3 data out protocol, we have two differences here:<BR>
2167 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
2168 wait will frequently fail... cause writing function return error)
2169
2170 2. Do NOT wait for DRQ clear after all data read.(the wait greatly
2171 slow down writing performance by 100 times!)
2172
2173 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2174 to record all the information of the IDE device.
2175 @param Buffer buffer contained data transferred from host to device.
2176 @param ByteCount data size in byte unit of the buffer.
2177 @param AtaCommand value of the Command Register
2178 @param StartLba the start LBA of this transaction
2179 @param SectorCount the count of sectors to be transferred
2180
2181 @retval EFI_SUCCESS send out the ATA command and device receive required
2182 data successfully.
2183 @retval EFI_DEVICE_ERROR command sent failed.
2184
2185**/
2186EFI_STATUS
2187AtaPioDataOutExt (
2188 IN IDE_BLK_IO_DEV *IdeDev,
2189 IN VOID *Buffer,
2190 IN UINT32 ByteCount,
2191 IN UINT8 AtaCommand,
2192 IN EFI_LBA StartLba,
2193 IN UINT16 SectorCount
2194 )
2195{
2196 UINT8 DevSel;
2197 UINT8 SectorCount8;
2198 UINT8 LbaLow;
2199 UINT8 LbaMid;
2200 UINT8 LbaHigh;
2201 UINTN WordCount;
2202 UINTN Increment;
2203 UINT16 *Buffer16;
2204 EFI_STATUS Status;
2205
2206 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2207 if (EFI_ERROR (Status)) {
2208 return EFI_DEVICE_ERROR;
2209 }
2210
2211 //
2212 // Select device. Set bit6 as 1 to indicate LBA mode is used
2213 //
2214 DevSel = (UINT8) (IdeDev->Device << 4);
2215 DevSel |= 0x40;
2216 IDEWritePortB (
2217 IdeDev->PciIo,
2218 IdeDev->IoPort->Head,
2219 DevSel
2220 );
2221
2222 //
2223 // Wait for DRDY signal asserting.
2224 //
2225 Status = DRDYReady (IdeDev, ATATIMEOUT);
2226 if (EFI_ERROR (Status)) {
2227 return EFI_DEVICE_ERROR;
2228 }
2229
2230 //
2231 // Fill feature register if needed
2232 //
2233 if (AtaCommand == ATA_CMD_SET_FEATURES) {
2234 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);
2235 }
2236
2237 //
2238 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2239 //
2240 SectorCount8 = (UINT8) (SectorCount >> 8);
2241 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2242
2243 SectorCount8 = (UINT8) SectorCount;
2244 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2245
2246 //
2247 // Fill the start LBA registers, which are also two-byte FIFO
2248 //
2249 LbaLow = (UINT8) RShiftU64 (StartLba, 24);
2250 LbaMid = (UINT8) RShiftU64 (StartLba, 32);
2251 LbaHigh = (UINT8) RShiftU64 (StartLba, 40);
2252 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2253 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
2254 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2255
2256 LbaLow = (UINT8) StartLba;
2257 LbaMid = (UINT8) RShiftU64 (StartLba, 8);
2258 LbaHigh = (UINT8) RShiftU64 (StartLba, 16);
2259 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2260 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
2261 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2262
2263 //
2264 // Send command via Command Register, invoking the processing of this command
2265 //
2266 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
2267
2268 Buffer16 = (UINT16 *) Buffer;
2269
2270 //
2271 // According to PIO Data Out protocol, host can perform a series of writes to
2272 // the data register after each time device set DRQ ready;
2273 //
2274 Increment = 256;
2275
2276 //
2277 // used to record bytes of currently transferred data
2278 //
2279 WordCount = 0;
2280
2281 while (WordCount < ByteCount / 2) {
2282 //
2283 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
2284 //
2285 Status = DRQReady2 (IdeDev, ATATIMEOUT);
2286 if (EFI_ERROR (Status)) {
2287 return EFI_DEVICE_ERROR;
2288 }
2289
2290 Status = CheckErrorStatus (IdeDev);
2291 if (EFI_ERROR (Status)) {
2292 return EFI_DEVICE_ERROR;
2293 }
2294
2295 //
2296 // Write data into device by one series of writing to data register
2297 //
2298 if ((WordCount + Increment) > ByteCount / 2) {
2299 Increment = ByteCount / 2 - WordCount;
2300 }
2301
2302 IDEWritePortWMultiple (
2303 IdeDev->PciIo,
2304 IdeDev->IoPort->Data,
2305 Increment,
2306 Buffer16
2307 );
2308
2309 WordCount += Increment;
2310 Buffer16 += Increment;
2311
2312 }
2313 return CheckErrorStatus (IdeDev);
2314}
2315/**
2316 This function is called by the AtaBlkIoWriteBlocks() to perform
2317 writing to media in block unit. The function has been enhanced to
2318 support >120GB access and transfer at most 65536 blocks per command
2319
2320 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2321 to record all the information of the IDE device.
2322 @param DataBuffer A pointer to the source buffer for the data.
2323 @param StartLba The starting logical block address to write to
2324 on the device media.
2325 @param NumberOfBlocks The number of transfer data blocks.
2326
2327 @return status depends on the function DoAtaUdma() returns.
2328**/
2329EFI_STATUS
2330AtaUdmaWriteExt (
2331 IN IDE_BLK_IO_DEV *IdeDev,
2332 IN VOID *DataBuffer,
2333 IN EFI_LBA StartLba,
2334 IN UINTN NumberOfBlocks
2335 )
2336{
2337 return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);
2338}
2339
2340/**
2341 This function is called by the AtaBlkIoWriteBlocks() to perform
2342 writing to media in block unit.
2343
2344 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2345 to record all the information of the IDE device.
2346 @param DataBuffer A pointer to the source buffer for the data.
2347 @param StartLba The starting logical block address to write to
2348 on the device media.
2349 @param NumberOfBlocks The number of transfer data blocks.
2350
2351 @return status depends on the function DoAtaUdma() returns.
2352**/
2353EFI_STATUS
2354AtaUdmaWrite (
2355 IN IDE_BLK_IO_DEV *IdeDev,
2356 IN VOID *DataBuffer,
2357 IN EFI_LBA StartLba,
2358 IN UINTN NumberOfBlocks
2359 )
2360{
2361 return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp);
2362}
2363/**
2364 This function is called by the AtaBlkIoWriteBlocks() to perform
2365 writing onto media in block unit. The function has been enhanced to
2366 support >120GB access and transfer at most 65536 blocks per command
2367
2368 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used
2369 to record all the information of the IDE device.
2370 @param DataBuffer A pointer to the source buffer for the data.
2371 @param StartLba The starting logical block address to write onto the device
2372 media.
2373 @param NumberOfBlocks The number of transfer data blocks.
2374
2375 @return status is fully dependent on the return status of AtaPioDataOutExt() function.
2376**/
2377EFI_STATUS
2378AtaWriteSectorsExt (
2379 IN IDE_BLK_IO_DEV *IdeDev,
2380 IN VOID *DataBuffer,
2381 IN EFI_LBA StartLba,
2382 IN UINTN NumberOfBlocks
2383 )
2384{
2385 EFI_STATUS Status;
2386 EFI_LBA Lba64;
2387 UINTN BlocksRemaining;
2388 UINT8 AtaCommand;
2389 UINT16 SectorCount;
2390 UINT32 ByteCount;
2391 VOID *Buffer;
2392
2393 //
2394 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
2395 //
2396 AtaCommand = ATA_CMD_WRITE_SECTORS_EXT;
2397 Lba64 = StartLba;
2398 Buffer = DataBuffer;
2399 BlocksRemaining = NumberOfBlocks;
2400
2401 Status = EFI_SUCCESS;
2402
2403 while (BlocksRemaining > 0) {
2404
2405 if (BlocksRemaining >= 0x10000) {
2406 //
2407 // SectorCount is used to record the number of sectors to be written.
2408 // Max 65536 sectors can be transferred at a time.
2409 //
2410 SectorCount = 0xffff;
2411 } else {
2412 SectorCount = (UINT16) BlocksRemaining;
2413 }
2414
2415 //
2416 // ByteCount is the number of bytes that will be written
2417 //
2418 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
2419
2420 //
2421 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
2422 //
2423 Status = AtaPioDataOutExt (
2424 IdeDev,
2425 Buffer,
2426 ByteCount,
2427 AtaCommand,
2428 Lba64,
2429 SectorCount
2430 );
2431 if (EFI_ERROR (Status)) {
2432 return Status;
2433 }
2434
2435 Lba64 += SectorCount;
2436 Buffer = ((UINT8 *) Buffer + ByteCount);
2437 BlocksRemaining -= SectorCount;
2438 }
2439
2440 return Status;
2441}
2442/**
2443 This function is the ATA implementation for WriteBlocks in the
2444 Block I/O Protocol interface.
2445
2446 @param IdeBlkIoDevice Indicates the calling context.
2447 @param MediaId The media id that the write request is for.
2448 @param Lba The starting logical block address to write onto the device.
2449 @param BufferSize The size of the Buffer in bytes. This must be a multiple
2450 of the intrinsic block size of the device.
2451 @param Buffer A pointer to the source buffer for the data.The caller
2452 is responsible for either having implicit or explicit
2453 ownership of the memory that data is written from.
2454
2455 @retval EFI_SUCCESS Write Blocks successfully.
2456 @retval EFI_DEVICE_ERROR Write Blocks failed.
2457 @retval EFI_NO_MEDIA There is no media in the device.
2458 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
2459
2460 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
2461 intrinsic block size of the device.
2462 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
2463 or the data buffer is not valid.
2464
2465 @note If Write Block error because of device error, this function will call
2466 AtaSoftReset() function to reset device.
2467**/
2468EFI_STATUS
2469AtaBlkIoWriteBlocks (
2470 IN IDE_BLK_IO_DEV *IdeBlkIoDevice,
2471 IN UINT32 MediaId,
2472 IN EFI_LBA Lba,
2473 IN UINTN BufferSize,
2474 OUT VOID *Buffer
2475 )
2476{
2477
2478 EFI_BLOCK_IO_MEDIA *Media;
2479 UINTN BlockSize;
2480 UINTN NumberOfBlocks;
2481 EFI_STATUS Status;
2482
2483 if (Buffer == NULL) {
2484 return EFI_INVALID_PARAMETER;
2485 }
2486
2487 if (BufferSize == 0) {
2488 return EFI_SUCCESS;
2489 }
2490
2491 Status = EFI_SUCCESS;
2492
2493 //
2494 // Get the intrinsic block size
2495 //
2496 Media = IdeBlkIoDevice->BlkIo.Media;
2497 BlockSize = Media->BlockSize;
2498 NumberOfBlocks = BufferSize / BlockSize;
2499
2500 if (MediaId != Media->MediaId) {
2501 return EFI_MEDIA_CHANGED;
2502 }
2503
2504 if (BufferSize % BlockSize != 0) {
2505 return EFI_BAD_BUFFER_SIZE;
2506 }
2507
2508 if (Lba > Media->LastBlock) {
2509 return EFI_INVALID_PARAMETER;
2510 }
2511
2512 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
2513 return EFI_INVALID_PARAMETER;
2514 }
2515
2516 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
2517 return EFI_INVALID_PARAMETER;
2518 }
2519
2520 Status = EFI_SUCCESS;
2521 if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
2522 //
2523 // For ATA/ATAPI-6 device(capacity > 120GB), use ATA-6 write block mechanism
2524 //
2525 if (IdeBlkIoDevice->UdmaMode.Valid) {
2526 Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2527 } else {
2528 Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2529 }
2530 } else {
2531 //
2532 // For ATA-3 compatible device, use ATA-3 write block mechanism
2533 //
2534 if (IdeBlkIoDevice->UdmaMode.Valid) {
2535 Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2536 } else {
2537 Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
2538 }
2539 }
2540
2541 if (EFI_ERROR (Status)) {
2542 AtaSoftReset (IdeBlkIoDevice);
2543 return EFI_DEVICE_ERROR;
2544 }
2545
2546 return EFI_SUCCESS;
2547}
2548/**
2549 Enable Long Physical Sector Feature for ATA device.
2550
2551 @param IdeDev The IDE device data
2552
2553 @retval EFI_SUCCESS The ATA device supports Long Physical Sector feature
2554 and corresponding fields in BlockIo structure is updated.
2555 @retval EFI_UNSUPPORTED The device is not ATA device or Long Physical Sector
2556 feature is not supported.
2557**/
2558EFI_STATUS
2559AtaEnableLongPhysicalSector (
2560 IN IDE_BLK_IO_DEV *IdeDev
2561 )
2562{
2563 EFI_ATA_IDENTIFY_DATA *AtaIdentifyData;
2564 UINT16 PhyLogicSectorSupport;
2565
2566 ASSERT (IdeDev->IdData != NULL);
2567 //
2568 // Only valid for ATA device
2569 //
2570 AtaIdentifyData = (EFI_ATA_IDENTIFY_DATA *) &IdeDev->IdData->AtaData;
2571 if ((AtaIdentifyData->config & 0x8000) != 0) {
2572 return EFI_UNSUPPORTED;
2573 }
2574 PhyLogicSectorSupport = AtaIdentifyData->phy_logic_sector_support;
2575 //
2576 // Check whether Long Physical Sector Feature is supported
2577 //
2578 if ((PhyLogicSectorSupport & 0xc000) == 0x4000) {
2579 IdeDev->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;
2580 IdeDev->BlkIo.Media->LowestAlignedLba = 0;
2581 //
2582 // Check whether one physical block contains multiple physical blocks
2583 //
2584 if ((PhyLogicSectorSupport & 0x2000) != 0) {
2585 IdeDev->BlkIo.Media->LogicalBlocksPerPhysicalBlock =
2586 (UINT32) (1 << (PhyLogicSectorSupport & 0x000f));
2587 //
2588 // Check lowest alignment of logical blocks within physical block
2589 //
2590 if ((AtaIdentifyData->alignment_logic_in_phy_blocks & 0xc000) == 0x4000) {
2591 IdeDev->BlkIo.Media->LowestAlignedLba =
2592 (EFI_LBA) (AtaIdentifyData->alignment_logic_in_phy_blocks & 0x3fff);
2593 }
2594 }
2595 //
2596 // Check logical block size
2597 //
2598 IdeDev->BlkIo.Media->BlockSize = 0x200;
2599 if ((PhyLogicSectorSupport & 0x1000) != 0) {
2600 IdeDev->BlkIo.Media->BlockSize = (UINT32) (
2601 ((AtaIdentifyData->logic_sector_size_hi << 16) |
2602 AtaIdentifyData->logic_sector_size_lo) * sizeof (UINT16)
2603 );
2604 }
2605 return EFI_SUCCESS;
2606 } else {
2607 return EFI_UNSUPPORTED;
2608 }
2609}
2610/**
2611 Send ATA command into device with NON_DATA protocol
2612
2613 @param IdeDev Standard IDE device private data structure
2614 @param AtaCommand The ATA command to be sent
2615 @param Device The value in Device register
2616 @param Feature The value in Feature register
2617 @param SectorCount The value in SectorCount register
2618 @param LbaLow The value in LBA_LOW register
2619 @param LbaMiddle The value in LBA_MIDDLE register
2620 @param LbaHigh The value in LBA_HIGH register
2621
2622 @retval EFI_SUCCESS Reading succeed
2623 @retval EFI_ABORTED Command failed
2624 @retval EFI_DEVICE_ERROR Device status error.
2625
2626**/
2627EFI_STATUS
2628AtaNonDataCommandIn (
2629 IN IDE_BLK_IO_DEV *IdeDev,
2630 IN UINT8 AtaCommand,
2631 IN UINT8 Device,
2632 IN UINT8 Feature,
2633 IN UINT8 SectorCount,
2634 IN UINT8 LbaLow,
2635 IN UINT8 LbaMiddle,
2636 IN UINT8 LbaHigh
2637 )
2638{
2639 EFI_STATUS Status;
2640 UINT8 StatusRegister;
2641
2642 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2643 if (EFI_ERROR (Status)) {
2644 return EFI_DEVICE_ERROR;
2645 }
2646
2647 //
2648 // Select device (bit4), set Lba mode(bit6) (use 0xe0 for compatibility)
2649 //
2650 IDEWritePortB (
2651 IdeDev->PciIo,
2652 IdeDev->IoPort->Head,
2653 (UINT8) ((IdeDev->Device << 4) | 0xe0)
2654 );
2655
2656 //
2657 // ATA commands for ATA device must be issued when DRDY is set
2658 //
2659 Status = DRDYReady (IdeDev, ATATIMEOUT);
2660 if (EFI_ERROR (Status)) {
2661 return EFI_DEVICE_ERROR;
2662 }
2663
2664 //
2665 // Pass parameter into device register block
2666 //
2667 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
2668 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature);
2669 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);
2670 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2671 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle);
2672 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2673
2674 //
2675 // Send command via Command Register
2676 //
2677 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
2678
2679 //
2680 // Wait for command completion
2681 // For ATAPI_SMART_CMD, we may need more timeout to let device
2682 // adjust internal states.
2683 //
2684 if (AtaCommand == ATA_CMD_SMART) {
2685 Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT);
2686 } else {
2687 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2688 }
2689 if (EFI_ERROR (Status)) {
2690 return EFI_DEVICE_ERROR;
2691 }
2692
2693 StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);
2694 if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
2695 //
2696 // Failed to execute command, abort operation
2697 //
2698 return EFI_ABORTED;
2699 }
2700
2701 return EFI_SUCCESS;
2702}
2703
2704/**
2705 Send ATA Ext command into device with NON_DATA protocol
2706
2707 @param IdeDev Standard IDE device private data structure
2708 @param AtaCommand The ATA command to be sent
2709 @param Device The value in Device register
2710 @param Feature The value in Feature register
2711 @param SectorCount The value in SectorCount register
2712 @param LbaAddress The LBA address in 48-bit mode
2713
2714 @retval EFI_SUCCESS Reading succeed
2715 @retval EFI_ABORTED Command failed
2716 @retval EFI_DEVICE_ERROR Device status error.
2717
2718**/
2719EFI_STATUS
2720AtaNonDataCommandInExt (
2721 IN IDE_BLK_IO_DEV *IdeDev,
2722 IN UINT8 AtaCommand,
2723 IN UINT8 Device,
2724 IN UINT16 Feature,
2725 IN UINT16 SectorCount,
2726 IN EFI_LBA LbaAddress
2727 )
2728{
2729 EFI_STATUS Status;
2730 UINT8 StatusRegister;
2731 UINT8 SectorCount8;
2732 UINT8 Feature8;
2733 UINT8 LbaLow;
2734 UINT8 LbaMid;
2735 UINT8 LbaHigh;
2736
2737 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2738 if (EFI_ERROR (Status)) {
2739 return EFI_DEVICE_ERROR;
2740 }
2741
2742 //
2743 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2744 //
2745 IDEWritePortB (
2746 IdeDev->PciIo,
2747 IdeDev->IoPort->Head,
2748 (UINT8) ((IdeDev->Device << 4) | 0xe0)
2749 );
2750
2751 //
2752 // ATA commands for ATA device must be issued when DRDY is set
2753 //
2754 Status = DRDYReady (IdeDev, ATATIMEOUT);
2755 if (EFI_ERROR (Status)) {
2756 return EFI_DEVICE_ERROR;
2757 }
2758
2759 //
2760 // Pass parameter into device register block
2761 //
2762 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
2763
2764 //
2765 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2766 //
2767 Feature8 = (UINT8) (Feature >> 8);
2768 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
2769
2770 Feature8 = (UINT8) Feature;
2771 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
2772
2773 //
2774 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2775 //
2776 SectorCount8 = (UINT8) (SectorCount >> 8);
2777 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2778
2779 SectorCount8 = (UINT8) SectorCount;
2780 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2781
2782 //
2783 // Fill the start LBA registers, which are also two-byte FIFO
2784 //
2785 LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);
2786 LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);
2787 LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);
2788 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2789 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
2790 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2791
2792 LbaLow = (UINT8) LbaAddress;
2793 LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);
2794 LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);
2795 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2796 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
2797 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2798
2799 //
2800 // Send command via Command Register
2801 //
2802 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
2803
2804 //
2805 // Wait for command completion
2806 //
2807 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2808 if (EFI_ERROR (Status)) {
2809 return EFI_DEVICE_ERROR;
2810 }
2811
2812 StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);
2813 if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
2814 //
2815 // Failed to execute command, abort operation
2816 //
2817 return EFI_ABORTED;
2818 }
2819
2820 return EFI_SUCCESS;
2821}
2822
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette