VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeBusDxe/Ata.c@ 33540

Last change on this file since 33540 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

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