]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/IdeMode.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / IdeMode.c
1 /** @file
2 Header file for AHCI mode of ATA host controller.
3
4 Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "AtaAtapiPassThru.h"
10
11 /**
12 read a one-byte data from a IDE port.
13
14 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
15 @param Port The IDE Port number
16
17 @return the one-byte data read from IDE port
18 **/
19 UINT8
20 EFIAPI
21 IdeReadPortB (
22 IN EFI_PCI_IO_PROTOCOL *PciIo,
23 IN UINT16 Port
24 )
25 {
26 UINT8 Data;
27
28 ASSERT (PciIo != NULL);
29
30 Data = 0;
31 //
32 // perform 1-byte data read from register
33 //
34 PciIo->Io.Read (
35 PciIo,
36 EfiPciIoWidthUint8,
37 EFI_PCI_IO_PASS_THROUGH_BAR,
38 (UINT64)Port,
39 1,
40 &Data
41 );
42 return Data;
43 }
44
45 /**
46 write a 1-byte data to a specific IDE port.
47
48 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
49 @param Port The IDE port to be written
50 @param Data The data to write to the port
51 **/
52 VOID
53 EFIAPI
54 IdeWritePortB (
55 IN EFI_PCI_IO_PROTOCOL *PciIo,
56 IN UINT16 Port,
57 IN UINT8 Data
58 )
59 {
60 ASSERT (PciIo != NULL);
61
62 //
63 // perform 1-byte data write to register
64 //
65 PciIo->Io.Write (
66 PciIo,
67 EfiPciIoWidthUint8,
68 EFI_PCI_IO_PASS_THROUGH_BAR,
69 (UINT64)Port,
70 1,
71 &Data
72 );
73 }
74
75 /**
76 write a 1-word data to a specific IDE port.
77
78 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
79 @param Port The IDE port to be written
80 @param Data The data to write to the port
81 **/
82 VOID
83 EFIAPI
84 IdeWritePortW (
85 IN EFI_PCI_IO_PROTOCOL *PciIo,
86 IN UINT16 Port,
87 IN UINT16 Data
88 )
89 {
90 ASSERT (PciIo != NULL);
91
92 //
93 // perform 1-word data write to register
94 //
95 PciIo->Io.Write (
96 PciIo,
97 EfiPciIoWidthUint16,
98 EFI_PCI_IO_PASS_THROUGH_BAR,
99 (UINT64)Port,
100 1,
101 &Data
102 );
103 }
104
105 /**
106 write a 2-word data to a specific IDE port.
107
108 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
109 @param Port The IDE port to be written
110 @param Data The data to write to the port
111 **/
112 VOID
113 EFIAPI
114 IdeWritePortDW (
115 IN EFI_PCI_IO_PROTOCOL *PciIo,
116 IN UINT16 Port,
117 IN UINT32 Data
118 )
119 {
120 ASSERT (PciIo != NULL);
121
122 //
123 // perform 2-word data write to register
124 //
125 PciIo->Io.Write (
126 PciIo,
127 EfiPciIoWidthUint32,
128 EFI_PCI_IO_PASS_THROUGH_BAR,
129 (UINT64)Port,
130 1,
131 &Data
132 );
133 }
134
135 /**
136 Write multiple words of data to the IDE data port.
137 Call the IO abstraction once to do the complete read,
138 not one word at a time
139
140 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
141 @param Port IO port to read
142 @param Count No. of UINT16's to read
143 @param Buffer Pointer to the data buffer for read
144
145 **/
146 VOID
147 EFIAPI
148 IdeWritePortWMultiple (
149 IN EFI_PCI_IO_PROTOCOL *PciIo,
150 IN UINT16 Port,
151 IN UINTN Count,
152 IN VOID *Buffer
153 )
154 {
155 ASSERT (PciIo != NULL);
156 ASSERT (Buffer != NULL);
157
158 //
159 // perform UINT16 data write to the FIFO
160 //
161 PciIo->Io.Write (
162 PciIo,
163 EfiPciIoWidthFifoUint16,
164 EFI_PCI_IO_PASS_THROUGH_BAR,
165 (UINT64)Port,
166 Count,
167 (UINT16 *)Buffer
168 );
169 }
170
171 /**
172 Reads multiple words of data from the IDE data port.
173 Call the IO abstraction once to do the complete read,
174 not one word at a time
175
176 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
177 @param Port IO port to read
178 @param Count Number of UINT16's to read
179 @param Buffer Pointer to the data buffer for read
180
181 **/
182 VOID
183 EFIAPI
184 IdeReadPortWMultiple (
185 IN EFI_PCI_IO_PROTOCOL *PciIo,
186 IN UINT16 Port,
187 IN UINTN Count,
188 IN VOID *Buffer
189 )
190 {
191 ASSERT (PciIo != NULL);
192 ASSERT (Buffer != NULL);
193
194 //
195 // Perform UINT16 data read from FIFO
196 //
197 PciIo->Io.Read (
198 PciIo,
199 EfiPciIoWidthFifoUint16,
200 EFI_PCI_IO_PASS_THROUGH_BAR,
201 (UINT64)Port,
202 Count,
203 (UINT16 *)Buffer
204 );
205 }
206
207 /**
208 This function is used to analyze the Status Register and print out
209 some debug information and if there is ERR bit set in the Status
210 Register, the Error Register's value is also be parsed and print out.
211
212 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
213 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
214 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
215
216 **/
217 VOID
218 EFIAPI
219 DumpAllIdeRegisters (
220 IN EFI_PCI_IO_PROTOCOL *PciIo,
221 IN EFI_IDE_REGISTERS *IdeRegisters,
222 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
223 )
224 {
225 EFI_ATA_STATUS_BLOCK StatusBlock;
226
227 ASSERT (PciIo != NULL);
228 ASSERT (IdeRegisters != NULL);
229
230 ZeroMem (&StatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
231
232 StatusBlock.AtaStatus = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
233 StatusBlock.AtaError = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
234 StatusBlock.AtaSectorCount = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
235 StatusBlock.AtaSectorCountExp = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
236 StatusBlock.AtaSectorNumber = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
237 StatusBlock.AtaSectorNumberExp = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
238 StatusBlock.AtaCylinderLow = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
239 StatusBlock.AtaCylinderLowExp = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
240 StatusBlock.AtaCylinderHigh = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
241 StatusBlock.AtaCylinderHighExp = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
242 StatusBlock.AtaDeviceHead = IdeReadPortB (PciIo, IdeRegisters->Head);
243
244 if (AtaStatusBlock != NULL) {
245 //
246 // Dump the content of all ATA registers.
247 //
248 CopyMem (AtaStatusBlock, &StatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
249 }
250
251 DEBUG_CODE_BEGIN ();
252 if ((StatusBlock.AtaStatus & ATA_STSREG_DWF) != 0) {
253 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock.AtaStatus));
254 }
255
256 if ((StatusBlock.AtaStatus & ATA_STSREG_CORR) != 0) {
257 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock.AtaStatus));
258 }
259
260 if ((StatusBlock.AtaStatus & ATA_STSREG_ERR) != 0) {
261 if ((StatusBlock.AtaError & ATA_ERRREG_BBK) != 0) {
262 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock.AtaError));
263 }
264
265 if ((StatusBlock.AtaError & ATA_ERRREG_UNC) != 0) {
266 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock.AtaError));
267 }
268
269 if ((StatusBlock.AtaError & ATA_ERRREG_MC) != 0) {
270 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock.AtaError));
271 }
272
273 if ((StatusBlock.AtaError & ATA_ERRREG_ABRT) != 0) {
274 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock.AtaError));
275 }
276
277 if ((StatusBlock.AtaError & ATA_ERRREG_TK0NF) != 0) {
278 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock.AtaError));
279 }
280
281 if ((StatusBlock.AtaError & ATA_ERRREG_AMNF) != 0) {
282 DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock.AtaError));
283 }
284 }
285
286 DEBUG_CODE_END ();
287 }
288
289 /**
290 This function is used to analyze the Status Register at the condition that BSY is zero.
291 if there is ERR bit set in the Status Register, then return error.
292
293 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
294 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
295
296 @retval EFI_SUCCESS No err information in the Status Register.
297 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
298
299 **/
300 EFI_STATUS
301 EFIAPI
302 CheckStatusRegister (
303 IN EFI_PCI_IO_PROTOCOL *PciIo,
304 IN EFI_IDE_REGISTERS *IdeRegisters
305 )
306 {
307 UINT8 StatusRegister;
308
309 ASSERT (PciIo != NULL);
310 ASSERT (IdeRegisters != NULL);
311
312 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
313
314 if ((StatusRegister & ATA_STSREG_BSY) == 0) {
315 if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {
316 return EFI_SUCCESS;
317 } else {
318 return EFI_DEVICE_ERROR;
319 }
320 }
321
322 return EFI_SUCCESS;
323 }
324
325 /**
326 This function is used to poll for the DRQ bit clear in the Status
327 Register. DRQ is cleared when the device is finished transferring data.
328 So this function is called after data transfer is finished.
329
330 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
331 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
332 @param Timeout The time to complete the command, uses 100ns as a unit.
333
334 @retval EFI_SUCCESS DRQ bit clear within the time out.
335
336 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
337
338 @note
339 Read Status Register will clear interrupt status.
340
341 **/
342 EFI_STATUS
343 EFIAPI
344 DRQClear (
345 IN EFI_PCI_IO_PROTOCOL *PciIo,
346 IN EFI_IDE_REGISTERS *IdeRegisters,
347 IN UINT64 Timeout
348 )
349 {
350 UINT64 Delay;
351 UINT8 StatusRegister;
352 BOOLEAN InfiniteWait;
353
354 ASSERT (PciIo != NULL);
355 ASSERT (IdeRegisters != NULL);
356
357 if (Timeout == 0) {
358 InfiniteWait = TRUE;
359 } else {
360 InfiniteWait = FALSE;
361 }
362
363 Delay = DivU64x32 (Timeout, 1000) + 1;
364 do {
365 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
366
367 //
368 // Wait for BSY == 0, then judge if DRQ is clear
369 //
370 if ((StatusRegister & ATA_STSREG_BSY) == 0) {
371 if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
372 return EFI_DEVICE_ERROR;
373 } else {
374 return EFI_SUCCESS;
375 }
376 }
377
378 //
379 // Stall for 100 microseconds.
380 //
381 MicroSecondDelay (100);
382
383 Delay--;
384 } while (InfiniteWait || (Delay > 0));
385
386 return EFI_TIMEOUT;
387 }
388
389 /**
390 This function is used to poll for the DRQ bit clear in the Alternate
391 Status Register. DRQ is cleared when the device is finished
392 transferring data. So this function is called after data transfer
393 is finished.
394
395 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
396 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
397 @param Timeout The time to complete the command, uses 100ns as a unit.
398
399 @retval EFI_SUCCESS DRQ bit clear within the time out.
400
401 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
402 @note Read Alternate Status Register will not clear interrupt status.
403
404 **/
405 EFI_STATUS
406 EFIAPI
407 DRQClear2 (
408 IN EFI_PCI_IO_PROTOCOL *PciIo,
409 IN EFI_IDE_REGISTERS *IdeRegisters,
410 IN UINT64 Timeout
411 )
412 {
413 UINT64 Delay;
414 UINT8 AltRegister;
415 BOOLEAN InfiniteWait;
416
417 ASSERT (PciIo != NULL);
418 ASSERT (IdeRegisters != NULL);
419
420 if (Timeout == 0) {
421 InfiniteWait = TRUE;
422 } else {
423 InfiniteWait = FALSE;
424 }
425
426 Delay = DivU64x32 (Timeout, 1000) + 1;
427 do {
428 AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
429
430 //
431 // Wait for BSY == 0, then judge if DRQ is clear
432 //
433 if ((AltRegister & ATA_STSREG_BSY) == 0) {
434 if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
435 return EFI_DEVICE_ERROR;
436 } else {
437 return EFI_SUCCESS;
438 }
439 }
440
441 //
442 // Stall for 100 microseconds.
443 //
444 MicroSecondDelay (100);
445
446 Delay--;
447 } while (InfiniteWait || (Delay > 0));
448
449 return EFI_TIMEOUT;
450 }
451
452 /**
453 This function is used to poll for the DRQ bit set in the
454 Status Register.
455 DRQ is set when the device is ready to transfer data. So this function
456 is called after the command is sent to the device and before required
457 data is transferred.
458
459 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
460 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
461 @param Timeout The time to complete the command, uses 100ns as a unit.
462
463 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
464 timeout.
465
466 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
467
468 @retval EFI_ABORTED Polling abandoned due to command abort.
469
470 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
471
472 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
473 reported "command complete" by clearing DRQ
474 bit.
475
476 @note Read Status Register will clear interrupt status.
477
478 **/
479 EFI_STATUS
480 EFIAPI
481 DRQReady (
482 IN EFI_PCI_IO_PROTOCOL *PciIo,
483 IN EFI_IDE_REGISTERS *IdeRegisters,
484 IN UINT64 Timeout
485 )
486 {
487 UINT64 Delay;
488 UINT8 StatusRegister;
489 UINT8 ErrorRegister;
490 BOOLEAN InfiniteWait;
491
492 ASSERT (PciIo != NULL);
493 ASSERT (IdeRegisters != NULL);
494
495 if (Timeout == 0) {
496 InfiniteWait = TRUE;
497 } else {
498 InfiniteWait = FALSE;
499 }
500
501 Delay = DivU64x32 (Timeout, 1000) + 1;
502 do {
503 //
504 // Read Status Register will clear interrupt
505 //
506 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
507
508 //
509 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
510 //
511 if ((StatusRegister & ATA_STSREG_BSY) == 0) {
512 if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
513 ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
514
515 if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
516 return EFI_ABORTED;
517 }
518
519 return EFI_DEVICE_ERROR;
520 }
521
522 if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
523 return EFI_SUCCESS;
524 } else {
525 return EFI_NOT_READY;
526 }
527 }
528
529 //
530 // Stall for 100 microseconds.
531 //
532 MicroSecondDelay (100);
533
534 Delay--;
535 } while (InfiniteWait || (Delay > 0));
536
537 return EFI_TIMEOUT;
538 }
539
540 /**
541 This function is used to poll for the DRQ bit set in the Alternate Status Register.
542 DRQ is set when the device is ready to transfer data. So this function is called after
543 the command is sent to the device and before required data is transferred.
544
545 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
546 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
547 @param Timeout The time to complete the command, uses 100ns as a unit.
548
549 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
550 timeout.
551
552 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
553
554 @retval EFI_ABORTED Polling abandoned due to command abort.
555
556 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
557
558 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
559 reported "command complete" by clearing DRQ
560 bit.
561
562 @note Read Alternate Status Register will not clear interrupt status.
563
564 **/
565 EFI_STATUS
566 EFIAPI
567 DRQReady2 (
568 IN EFI_PCI_IO_PROTOCOL *PciIo,
569 IN EFI_IDE_REGISTERS *IdeRegisters,
570 IN UINT64 Timeout
571 )
572 {
573 UINT64 Delay;
574 UINT8 AltRegister;
575 UINT8 ErrorRegister;
576 BOOLEAN InfiniteWait;
577
578 ASSERT (PciIo != NULL);
579 ASSERT (IdeRegisters != NULL);
580
581 if (Timeout == 0) {
582 InfiniteWait = TRUE;
583 } else {
584 InfiniteWait = FALSE;
585 }
586
587 Delay = DivU64x32 (Timeout, 1000) + 1;
588
589 do {
590 //
591 // Read Alternate Status Register will not clear interrupt status
592 //
593 AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
594 //
595 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
596 //
597 if ((AltRegister & ATA_STSREG_BSY) == 0) {
598 if ((AltRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
599 ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
600
601 if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
602 return EFI_ABORTED;
603 }
604
605 return EFI_DEVICE_ERROR;
606 }
607
608 if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
609 return EFI_SUCCESS;
610 } else {
611 return EFI_NOT_READY;
612 }
613 }
614
615 //
616 // Stall for 100 microseconds.
617 //
618 MicroSecondDelay (100);
619
620 Delay--;
621 } while (InfiniteWait || (Delay > 0));
622
623 return EFI_TIMEOUT;
624 }
625
626 /**
627 This function is used to poll for the BSY bit clear in the Status Register. BSY
628 is clear when the device is not busy. Every command must be sent after device is not busy.
629
630 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
631 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
632 @param Timeout The time to complete the command, uses 100ns as a unit.
633
634 @retval EFI_SUCCESS BSY bit clear within the time out.
635 @retval EFI_TIMEOUT BSY bit not clear within the time out.
636
637 @note Read Status Register will clear interrupt status.
638 **/
639 EFI_STATUS
640 EFIAPI
641 WaitForBSYClear (
642 IN EFI_PCI_IO_PROTOCOL *PciIo,
643 IN EFI_IDE_REGISTERS *IdeRegisters,
644 IN UINT64 Timeout
645 )
646 {
647 UINT64 Delay;
648 UINT8 StatusRegister;
649 BOOLEAN InfiniteWait;
650
651 ASSERT (PciIo != NULL);
652 ASSERT (IdeRegisters != NULL);
653
654 if (Timeout == 0) {
655 InfiniteWait = TRUE;
656 } else {
657 InfiniteWait = FALSE;
658 }
659
660 Delay = DivU64x32 (Timeout, 1000) + 1;
661 do {
662 StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
663
664 if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {
665 return EFI_SUCCESS;
666 }
667
668 //
669 // Stall for 100 microseconds.
670 //
671 MicroSecondDelay (100);
672
673 Delay--;
674 } while (InfiniteWait || (Delay > 0));
675
676 return EFI_TIMEOUT;
677 }
678
679 /**
680 Get IDE i/o port registers' base addresses by mode.
681
682 In 'Compatibility' mode, use fixed addresses.
683 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
684 Configuration Space.
685
686 The steps to get IDE i/o port registers' base addresses for each channel
687 as follows:
688
689 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
690 controller's Configuration Space to determine the operating mode.
691
692 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
693 ___________________________________________
694 | | Command Block | Control Block |
695 | Channel | Registers | Registers |
696 |___________|_______________|_______________|
697 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
698 |___________|_______________|_______________|
699 | Secondary | 170h - 177h | 376h - 377h |
700 |___________|_______________|_______________|
701
702 Table 1. Compatibility resource mappings
703
704 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
705 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
706 ___________________________________________________
707 | | Command Block | Control Block |
708 | Channel | Registers | Registers |
709 |___________|___________________|___________________|
710 | Primary | BAR at offset 0x10| BAR at offset 0x14|
711 |___________|___________________|___________________|
712 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
713 |___________|___________________|___________________|
714
715 Table 2. BARs for Register Mapping
716
717 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
718 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
719 store the IDE i/o port registers' base addresses
720
721 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
722 @retval EFI_SUCCESS Get the Base address successfully
723 @retval Other Read the pci configuration data error
724
725 **/
726 EFI_STATUS
727 EFIAPI
728 GetIdeRegisterIoAddr (
729 IN EFI_PCI_IO_PROTOCOL *PciIo,
730 IN OUT EFI_IDE_REGISTERS *IdeRegisters
731 )
732 {
733 EFI_STATUS Status;
734 PCI_TYPE00 PciData;
735 UINT16 CommandBlockBaseAddr;
736 UINT16 ControlBlockBaseAddr;
737 UINT16 BusMasterBaseAddr;
738
739 if ((PciIo == NULL) || (IdeRegisters == NULL)) {
740 return EFI_INVALID_PARAMETER;
741 }
742
743 Status = PciIo->Pci.Read (
744 PciIo,
745 EfiPciIoWidthUint8,
746 0,
747 sizeof (PciData),
748 &PciData
749 );
750
751 if (EFI_ERROR (Status)) {
752 return Status;
753 }
754
755 BusMasterBaseAddr = (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));
756
757 if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
758 CommandBlockBaseAddr = 0x1f0;
759 ControlBlockBaseAddr = 0x3f6;
760 } else {
761 //
762 // The BARs should be of IO type
763 //
764 if (((PciData.Device.Bar[0] & BIT0) == 0) ||
765 ((PciData.Device.Bar[1] & BIT0) == 0))
766 {
767 return EFI_UNSUPPORTED;
768 }
769
770 CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[0] & 0x0000fff8);
771 ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[1] & 0x0000fffc) + 2);
772 }
773
774 //
775 // Calculate IDE primary channel I/O register base address.
776 //
777 IdeRegisters[EfiIdePrimary].Data = CommandBlockBaseAddr;
778 IdeRegisters[EfiIdePrimary].ErrOrFeature = (UINT16)(CommandBlockBaseAddr + 0x01);
779 IdeRegisters[EfiIdePrimary].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x02);
780 IdeRegisters[EfiIdePrimary].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x03);
781 IdeRegisters[EfiIdePrimary].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x04);
782 IdeRegisters[EfiIdePrimary].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x05);
783 IdeRegisters[EfiIdePrimary].Head = (UINT16)(CommandBlockBaseAddr + 0x06);
784 IdeRegisters[EfiIdePrimary].CmdOrStatus = (UINT16)(CommandBlockBaseAddr + 0x07);
785 IdeRegisters[EfiIdePrimary].AltOrDev = ControlBlockBaseAddr;
786 IdeRegisters[EfiIdePrimary].BusMasterBaseAddr = BusMasterBaseAddr;
787
788 if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
789 CommandBlockBaseAddr = 0x170;
790 ControlBlockBaseAddr = 0x376;
791 } else {
792 //
793 // The BARs should be of IO type
794 //
795 if (((PciData.Device.Bar[2] & BIT0) == 0) ||
796 ((PciData.Device.Bar[3] & BIT0) == 0))
797 {
798 return EFI_UNSUPPORTED;
799 }
800
801 CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[2] & 0x0000fff8);
802 ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[3] & 0x0000fffc) + 2);
803 }
804
805 //
806 // Calculate IDE secondary channel I/O register base address.
807 //
808 IdeRegisters[EfiIdeSecondary].Data = CommandBlockBaseAddr;
809 IdeRegisters[EfiIdeSecondary].ErrOrFeature = (UINT16)(CommandBlockBaseAddr + 0x01);
810 IdeRegisters[EfiIdeSecondary].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x02);
811 IdeRegisters[EfiIdeSecondary].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x03);
812 IdeRegisters[EfiIdeSecondary].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x04);
813 IdeRegisters[EfiIdeSecondary].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x05);
814 IdeRegisters[EfiIdeSecondary].Head = (UINT16)(CommandBlockBaseAddr + 0x06);
815 IdeRegisters[EfiIdeSecondary].CmdOrStatus = (UINT16)(CommandBlockBaseAddr + 0x07);
816 IdeRegisters[EfiIdeSecondary].AltOrDev = ControlBlockBaseAddr;
817 IdeRegisters[EfiIdeSecondary].BusMasterBaseAddr = (UINT16)(BusMasterBaseAddr + 0x8);
818
819 return EFI_SUCCESS;
820 }
821
822 /**
823 Send ATA Ext command into device with NON_DATA protocol.
824
825 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
826 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
827 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
828 @param Timeout The time to complete the command, uses 100ns as a unit.
829
830 @retval EFI_SUCCESS Reading succeed
831 @retval EFI_DEVICE_ERROR Error executing commands on this device.
832
833 **/
834 EFI_STATUS
835 EFIAPI
836 AtaIssueCommand (
837 IN EFI_PCI_IO_PROTOCOL *PciIo,
838 IN EFI_IDE_REGISTERS *IdeRegisters,
839 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
840 IN UINT64 Timeout
841 )
842 {
843 EFI_STATUS Status;
844 UINT8 DeviceHead;
845 UINT8 AtaCommand;
846
847 ASSERT (PciIo != NULL);
848 ASSERT (IdeRegisters != NULL);
849 ASSERT (AtaCommandBlock != NULL);
850
851 DeviceHead = AtaCommandBlock->AtaDeviceHead;
852 AtaCommand = AtaCommandBlock->AtaCommand;
853
854 Status = WaitForBSYClear (PciIo, IdeRegisters, Timeout);
855 if (EFI_ERROR (Status)) {
856 return EFI_DEVICE_ERROR;
857 }
858
859 //
860 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
861 //
862 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
863
864 //
865 // set all the command parameters
866 // Before write to all the following registers, BSY and DRQ must be 0.
867 //
868 Status = DRQClear2 (PciIo, IdeRegisters, Timeout);
869 if (EFI_ERROR (Status)) {
870 return EFI_DEVICE_ERROR;
871 }
872
873 //
874 // Fill the feature register, which is a two-byte FIFO. Need write twice.
875 //
876 IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeaturesExp);
877 IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeatures);
878
879 //
880 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
881 //
882 IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCountExp);
883 IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCount);
884
885 //
886 // Fill the start LBA registers, which are also two-byte FIFO
887 //
888 IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumberExp);
889 IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumber);
890
891 IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLowExp);
892 IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLow);
893
894 IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHighExp);
895 IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHigh);
896
897 //
898 // Send command via Command Register
899 //
900 IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, AtaCommand);
901
902 //
903 // Stall at least 400 microseconds.
904 //
905 MicroSecondDelay (400);
906
907 return EFI_SUCCESS;
908 }
909
910 /**
911 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
912
913 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
914 structure.
915 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
916 @param[in, out] Buffer A pointer to the source buffer for the data.
917 @param[in] ByteCount The length of the data.
918 @param[in] Read Flag used to determine the data transfer direction.
919 Read equals 1, means data transferred from device
920 to host;Read equals 0, means data transferred
921 from host to device.
922 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
923 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
924 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
925 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
926 used by non-blocking mode.
927
928 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
929 @retval EFI_DEVICE_ERROR command sent failed.
930
931 **/
932 EFI_STATUS
933 EFIAPI
934 AtaPioDataInOut (
935 IN EFI_PCI_IO_PROTOCOL *PciIo,
936 IN EFI_IDE_REGISTERS *IdeRegisters,
937 IN OUT VOID *Buffer,
938 IN UINT64 ByteCount,
939 IN BOOLEAN Read,
940 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
941 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
942 IN UINT64 Timeout,
943 IN ATA_NONBLOCK_TASK *Task
944 )
945 {
946 UINTN WordCount;
947 UINTN Increment;
948 UINT16 *Buffer16;
949 EFI_STATUS Status;
950
951 if ((PciIo == NULL) || (IdeRegisters == NULL) || (Buffer == NULL) || (AtaCommandBlock == NULL)) {
952 return EFI_INVALID_PARAMETER;
953 }
954
955 //
956 // Issue ATA command
957 //
958 Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
959 if (EFI_ERROR (Status)) {
960 Status = EFI_DEVICE_ERROR;
961 goto Exit;
962 }
963
964 Buffer16 = (UINT16 *)Buffer;
965
966 //
967 // According to PIO data in protocol, host can perform a series of reads to
968 // the data register after each time device set DRQ ready;
969 // The data size of "a series of read" is command specific.
970 // For most ATA command, data size received from device will not exceed
971 // 1 sector, hence the data size for "a series of read" can be the whole data
972 // size of one command request.
973 // For ATA command such as Read Sector command, the data size of one ATA
974 // command request is often larger than 1 sector, according to the
975 // Read Sector command, the data size of "a series of read" is exactly 1
976 // sector.
977 // Here for simplification reason, we specify the data size for
978 // "a series of read" to 1 sector (256 words) if data size of one ATA command
979 // request is larger than 256 words.
980 //
981 Increment = 256;
982
983 //
984 // used to record bytes of currently transferred data
985 //
986 WordCount = 0;
987
988 while (WordCount < RShiftU64 (ByteCount, 1)) {
989 //
990 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
991 //
992 Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
993 if (EFI_ERROR (Status)) {
994 Status = EFI_DEVICE_ERROR;
995 goto Exit;
996 }
997
998 //
999 // Get the byte count for one series of read
1000 //
1001 if ((WordCount + Increment) > RShiftU64 (ByteCount, 1)) {
1002 Increment = (UINTN)(RShiftU64 (ByteCount, 1) - WordCount);
1003 }
1004
1005 if (Read) {
1006 IdeReadPortWMultiple (
1007 PciIo,
1008 IdeRegisters->Data,
1009 Increment,
1010 Buffer16
1011 );
1012 } else {
1013 IdeWritePortWMultiple (
1014 PciIo,
1015 IdeRegisters->Data,
1016 Increment,
1017 Buffer16
1018 );
1019 }
1020
1021 Status = CheckStatusRegister (PciIo, IdeRegisters);
1022 if (EFI_ERROR (Status)) {
1023 Status = EFI_DEVICE_ERROR;
1024 goto Exit;
1025 }
1026
1027 WordCount += Increment;
1028 Buffer16 += Increment;
1029 }
1030
1031 Status = DRQClear (PciIo, IdeRegisters, Timeout);
1032 if (EFI_ERROR (Status)) {
1033 Status = EFI_DEVICE_ERROR;
1034 goto Exit;
1035 }
1036
1037 Exit:
1038 //
1039 // Dump All Ide registers to ATA_STATUS_BLOCK
1040 //
1041 DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1042
1043 //
1044 // Not support the Non-blocking now,just do the blocking process.
1045 //
1046 return Status;
1047 }
1048
1049 /**
1050 Send ATA command into device with NON_DATA protocol
1051
1052 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1053 data structure.
1054 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1055 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1056 structure.
1057 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1058 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1059 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1060 used by non-blocking mode.
1061
1062 @retval EFI_SUCCESS Reading succeed
1063 @retval EFI_ABORTED Command failed
1064 @retval EFI_DEVICE_ERROR Device status error.
1065
1066 **/
1067 EFI_STATUS
1068 EFIAPI
1069 AtaNonDataCommandIn (
1070 IN EFI_PCI_IO_PROTOCOL *PciIo,
1071 IN EFI_IDE_REGISTERS *IdeRegisters,
1072 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1073 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1074 IN UINT64 Timeout,
1075 IN ATA_NONBLOCK_TASK *Task
1076 )
1077 {
1078 EFI_STATUS Status;
1079
1080 if ((PciIo == NULL) || (IdeRegisters == NULL) || (AtaCommandBlock == NULL)) {
1081 return EFI_INVALID_PARAMETER;
1082 }
1083
1084 //
1085 // Issue ATA command
1086 //
1087 Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1088 if (EFI_ERROR (Status)) {
1089 Status = EFI_DEVICE_ERROR;
1090 goto Exit;
1091 }
1092
1093 //
1094 // Wait for command completion
1095 //
1096 Status = WaitForBSYClear (PciIo, IdeRegisters, Timeout);
1097 if (EFI_ERROR (Status)) {
1098 Status = EFI_DEVICE_ERROR;
1099 goto Exit;
1100 }
1101
1102 Status = CheckStatusRegister (PciIo, IdeRegisters);
1103 if (EFI_ERROR (Status)) {
1104 Status = EFI_DEVICE_ERROR;
1105 goto Exit;
1106 }
1107
1108 Exit:
1109 //
1110 // Dump All Ide registers to ATA_STATUS_BLOCK
1111 //
1112 DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1113
1114 //
1115 // Not support the Non-blocking now,just do the blocking process.
1116 //
1117 return Status;
1118 }
1119
1120 /**
1121 Wait for memory to be set.
1122
1123 @param[in] PciIo The PCI IO protocol instance.
1124 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1125 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1126
1127 @retval EFI_DEVICE_ERROR The memory is not set.
1128 @retval EFI_TIMEOUT The memory setting is time out.
1129 @retval EFI_SUCCESS The memory is correct set.
1130
1131 **/
1132 EFI_STATUS
1133 AtaUdmStatusWait (
1134 IN EFI_PCI_IO_PROTOCOL *PciIo,
1135 IN EFI_IDE_REGISTERS *IdeRegisters,
1136 IN UINT64 Timeout
1137 )
1138 {
1139 UINT8 RegisterValue;
1140 EFI_STATUS Status;
1141 UINT16 IoPortForBmis;
1142 UINT64 Delay;
1143 BOOLEAN InfiniteWait;
1144
1145 if (Timeout == 0) {
1146 InfiniteWait = TRUE;
1147 } else {
1148 InfiniteWait = FALSE;
1149 }
1150
1151 Delay = DivU64x32 (Timeout, 1000) + 1;
1152
1153 do {
1154 Status = CheckStatusRegister (PciIo, IdeRegisters);
1155 if (EFI_ERROR (Status)) {
1156 Status = EFI_DEVICE_ERROR;
1157 break;
1158 }
1159
1160 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1161 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1162 if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {
1163 DEBUG ((DEBUG_ERROR, "ATA UDMA operation fails\n"));
1164 Status = EFI_DEVICE_ERROR;
1165 break;
1166 }
1167
1168 if ((RegisterValue & BMIS_INTERRUPT) != 0) {
1169 Status = EFI_SUCCESS;
1170 break;
1171 }
1172
1173 //
1174 // Stall for 100 microseconds.
1175 //
1176 MicroSecondDelay (100);
1177 Delay--;
1178 } while (InfiniteWait || (Delay > 0));
1179
1180 return Status;
1181 }
1182
1183 /**
1184 Check if the memory to be set.
1185
1186 @param[in] PciIo The PCI IO protocol instance.
1187 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1188 used by non-blocking mode.
1189 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1190
1191 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1192 @retval EFI_NOT_READY The memory is not set.
1193 @retval EFI_TIMEOUT The memory setting is time out.
1194 @retval EFI_SUCCESS The memory is correct set.
1195
1196 **/
1197 EFI_STATUS
1198 AtaUdmStatusCheck (
1199 IN EFI_PCI_IO_PROTOCOL *PciIo,
1200 IN ATA_NONBLOCK_TASK *Task,
1201 IN EFI_IDE_REGISTERS *IdeRegisters
1202 )
1203 {
1204 UINT8 RegisterValue;
1205 UINT16 IoPortForBmis;
1206 EFI_STATUS Status;
1207
1208 Task->RetryTimes--;
1209
1210 Status = CheckStatusRegister (PciIo, IdeRegisters);
1211 if (EFI_ERROR (Status)) {
1212 return EFI_DEVICE_ERROR;
1213 }
1214
1215 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1216 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1217
1218 if ((RegisterValue & BMIS_ERROR) != 0) {
1219 DEBUG ((DEBUG_ERROR, "ATA UDMA operation fails\n"));
1220 return EFI_DEVICE_ERROR;
1221 }
1222
1223 if ((RegisterValue & BMIS_INTERRUPT) != 0) {
1224 return EFI_SUCCESS;
1225 }
1226
1227 if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {
1228 return EFI_TIMEOUT;
1229 } else {
1230 //
1231 // The memory is not set.
1232 //
1233 return EFI_NOT_READY;
1234 }
1235 }
1236
1237 /**
1238 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1239
1240 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1241 structure.
1242 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1243 @param[in] Read Flag used to determine the data transfer
1244 direction. Read equals 1, means data transferred
1245 from device to host;Read equals 0, means data
1246 transferred from host to device.
1247 @param[in] DataBuffer A pointer to the source buffer for the data.
1248 @param[in] DataLength The length of the data.
1249 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1250 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1251 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1252 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1253 used by non-blocking mode.
1254
1255 @retval EFI_SUCCESS the operation is successful.
1256 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1257 @retval EFI_UNSUPPORTED Unknown channel or operations command
1258 @retval EFI_DEVICE_ERROR Ata command execute failed
1259
1260 **/
1261 EFI_STATUS
1262 EFIAPI
1263 AtaUdmaInOut (
1264 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
1265 IN EFI_IDE_REGISTERS *IdeRegisters,
1266 IN BOOLEAN Read,
1267 IN VOID *DataBuffer,
1268 IN UINT64 DataLength,
1269 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1270 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1271 IN UINT64 Timeout,
1272 IN ATA_NONBLOCK_TASK *Task
1273 )
1274 {
1275 EFI_STATUS Status;
1276 UINT16 IoPortForBmic;
1277 UINT16 IoPortForBmis;
1278 UINT16 IoPortForBmid;
1279
1280 UINTN PrdTableSize;
1281 EFI_PHYSICAL_ADDRESS PrdTableMapAddr;
1282 VOID *PrdTableMap;
1283 EFI_PHYSICAL_ADDRESS PrdTableBaseAddr;
1284 EFI_ATA_DMA_PRD *TempPrdBaseAddr;
1285 UINTN PrdTableNum;
1286
1287 UINT8 RegisterValue;
1288 UINTN PageCount;
1289 UINTN ByteCount;
1290 UINTN ByteRemaining;
1291 UINT8 DeviceControl;
1292
1293 VOID *BufferMap;
1294 EFI_PHYSICAL_ADDRESS BufferMapAddress;
1295 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;
1296
1297 UINT8 DeviceHead;
1298 EFI_PCI_IO_PROTOCOL *PciIo;
1299 EFI_TPL OldTpl;
1300
1301 UINTN AlignmentMask;
1302 UINTN RealPageCount;
1303 EFI_PHYSICAL_ADDRESS BaseAddr;
1304 EFI_PHYSICAL_ADDRESS BaseMapAddr;
1305
1306 Status = EFI_SUCCESS;
1307 PrdTableMap = NULL;
1308 BufferMap = NULL;
1309 PageCount = 0;
1310 RealPageCount = 0;
1311 BaseAddr = 0;
1312 PciIo = Instance->PciIo;
1313
1314 if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {
1315 return EFI_INVALID_PARAMETER;
1316 }
1317
1318 //
1319 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1320 // BlockIO tasks.
1321 // Delay 1ms to simulate the blocking time out checking.
1322 //
1323 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1324 while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
1325 AsyncNonBlockingTransferRoutine (NULL, Instance);
1326 //
1327 // Stall for 1 milliseconds.
1328 //
1329 MicroSecondDelay (1000);
1330 }
1331
1332 gBS->RestoreTPL (OldTpl);
1333
1334 //
1335 // The data buffer should be even alignment
1336 //
1337 if (((UINTN)DataBuffer & 0x1) != 0) {
1338 return EFI_INVALID_PARAMETER;
1339 }
1340
1341 //
1342 // Set relevant IO Port address.
1343 //
1344 IoPortForBmic = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
1345 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1346 IoPortForBmid = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
1347
1348 //
1349 // For Blocking mode, start the command.
1350 // For non-blocking mode, when the command is not started, start it, otherwise
1351 // go to check the status.
1352 //
1353 if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {
1354 //
1355 // Calculate the number of PRD entry.
1356 // Every entry in PRD table can specify a 64K memory region.
1357 //
1358 PrdTableNum = (UINTN)(RShiftU64 (DataLength, 16) + 1);
1359
1360 //
1361 // Make sure that the memory region of PRD table is not cross 64K boundary
1362 //
1363 PrdTableSize = PrdTableNum * sizeof (EFI_ATA_DMA_PRD);
1364 if (PrdTableSize > 0x10000) {
1365 return EFI_INVALID_PARAMETER;
1366 }
1367
1368 //
1369 // Allocate buffer for PRD table initialization.
1370 // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
1371 // boundary and the table cannot cross a 64K boundary in memory.
1372 //
1373 PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);
1374 RealPageCount = PageCount + EFI_SIZE_TO_PAGES (SIZE_64KB);
1375
1376 //
1377 // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
1378 //
1379 ASSERT (RealPageCount > PageCount);
1380
1381 Status = PciIo->AllocateBuffer (
1382 PciIo,
1383 AllocateAnyPages,
1384 EfiBootServicesData,
1385 RealPageCount,
1386 (VOID **)&BaseAddr,
1387 0
1388 );
1389 if (EFI_ERROR (Status)) {
1390 return EFI_OUT_OF_RESOURCES;
1391 }
1392
1393 ByteCount = EFI_PAGES_TO_SIZE (RealPageCount);
1394 Status = PciIo->Map (
1395 PciIo,
1396 EfiPciIoOperationBusMasterCommonBuffer,
1397 (VOID *)(UINTN)BaseAddr,
1398 &ByteCount,
1399 &BaseMapAddr,
1400 &PrdTableMap
1401 );
1402 if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (RealPageCount))) {
1403 //
1404 // If the data length actually mapped is not equal to the requested amount,
1405 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1406 // Can't handle this case.
1407 //
1408 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);
1409 return EFI_OUT_OF_RESOURCES;
1410 }
1411
1412 ZeroMem ((VOID *)((UINTN)BaseAddr), ByteCount);
1413
1414 //
1415 // Calculate the 64K align address as PRD Table base address.
1416 //
1417 AlignmentMask = SIZE_64KB - 1;
1418 PrdTableBaseAddr = ((UINTN)BaseAddr + AlignmentMask) & ~AlignmentMask;
1419 PrdTableMapAddr = ((UINTN)BaseMapAddr + AlignmentMask) & ~AlignmentMask;
1420
1421 //
1422 // Map the host address of DataBuffer to DMA master address.
1423 //
1424 if (Read) {
1425 PciIoOperation = EfiPciIoOperationBusMasterWrite;
1426 } else {
1427 PciIoOperation = EfiPciIoOperationBusMasterRead;
1428 }
1429
1430 ByteCount = (UINTN)DataLength;
1431 Status = PciIo->Map (
1432 PciIo,
1433 PciIoOperation,
1434 DataBuffer,
1435 &ByteCount,
1436 &BufferMapAddress,
1437 &BufferMap
1438 );
1439 if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
1440 PciIo->Unmap (PciIo, PrdTableMap);
1441 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);
1442 return EFI_OUT_OF_RESOURCES;
1443 }
1444
1445 //
1446 // According to Ata spec, it requires the buffer address and size to be even.
1447 //
1448 ASSERT ((BufferMapAddress & 0x1) == 0);
1449 ASSERT ((ByteCount & 0x1) == 0);
1450
1451 //
1452 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1453 //
1454 ByteRemaining = ByteCount;
1455 TempPrdBaseAddr = (EFI_ATA_DMA_PRD *)(UINTN)PrdTableBaseAddr;
1456 while (ByteRemaining != 0) {
1457 if (ByteRemaining <= 0x10000) {
1458 TempPrdBaseAddr->RegionBaseAddr = (UINT32)((UINTN)BufferMapAddress);
1459 TempPrdBaseAddr->ByteCount = (UINT16)ByteRemaining;
1460 TempPrdBaseAddr->EndOfTable = 0x8000;
1461 break;
1462 }
1463
1464 TempPrdBaseAddr->RegionBaseAddr = (UINT32)((UINTN)BufferMapAddress);
1465 TempPrdBaseAddr->ByteCount = (UINT16)0x0;
1466
1467 ByteRemaining -= 0x10000;
1468 BufferMapAddress += 0x10000;
1469 TempPrdBaseAddr++;
1470 }
1471
1472 //
1473 // Start to enable the DMA operation
1474 //
1475 DeviceHead = AtaCommandBlock->AtaDeviceHead;
1476
1477 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
1478
1479 //
1480 // Enable interrupt to support UDMA
1481 //
1482 DeviceControl = 0;
1483 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1484
1485 //
1486 // Read BMIS register and clear ERROR and INTR bit
1487 //
1488 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1489 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1490 IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
1491
1492 //
1493 // Set the base address to BMID register
1494 //
1495 IdeWritePortDW (PciIo, IoPortForBmid, (UINT32)PrdTableMapAddr);
1496
1497 //
1498 // Set BMIC register to identify the operation direction
1499 //
1500 RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);
1501 if (Read) {
1502 RegisterValue |= BMIC_NREAD;
1503 } else {
1504 RegisterValue &= ~((UINT8)BMIC_NREAD);
1505 }
1506
1507 IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1508
1509 if (Task != NULL) {
1510 Task->Map = BufferMap;
1511 Task->TableMap = PrdTableMap;
1512 Task->MapBaseAddress = (EFI_ATA_DMA_PRD *)(UINTN)BaseAddr;
1513 Task->PageCount = RealPageCount;
1514 Task->IsStart = TRUE;
1515 }
1516
1517 //
1518 // Issue ATA command
1519 //
1520 Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1521
1522 if (EFI_ERROR (Status)) {
1523 Status = EFI_DEVICE_ERROR;
1524 goto Exit;
1525 }
1526
1527 Status = CheckStatusRegister (PciIo, IdeRegisters);
1528 if (EFI_ERROR (Status)) {
1529 Status = EFI_DEVICE_ERROR;
1530 goto Exit;
1531 }
1532
1533 //
1534 // Set START bit of BMIC register
1535 //
1536 RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);
1537 RegisterValue |= BMIC_START;
1538 IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1539 }
1540
1541 //
1542 // Check the INTERRUPT and ERROR bit of BMIS
1543 //
1544 if (Task != NULL) {
1545 Status = AtaUdmStatusCheck (PciIo, Task, IdeRegisters);
1546 } else {
1547 Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);
1548 }
1549
1550 //
1551 // For blocking mode, clear registers and free buffers.
1552 // For non blocking mode, when the related registers have been set or time
1553 // out, or a error has been happened, it needs to clear the register and free
1554 // buffer.
1555 //
1556 if ((Task == NULL) || (Status != EFI_NOT_READY)) {
1557 //
1558 // Read BMIS register and clear ERROR and INTR bit
1559 //
1560 RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
1561 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1562 IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
1563
1564 //
1565 // Read Status Register of IDE device to clear interrupt
1566 //
1567 RegisterValue = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
1568
1569 //
1570 // Clear START bit of BMIC register
1571 //
1572 RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);
1573 RegisterValue &= ~((UINT8)BMIC_START);
1574 IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1575
1576 //
1577 // Disable interrupt of Select device
1578 //
1579 DeviceControl = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1580 DeviceControl |= ATA_CTLREG_IEN_L;
1581 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1582 //
1583 // Stall for 10 milliseconds.
1584 //
1585 MicroSecondDelay (10000);
1586 }
1587
1588 Exit:
1589 //
1590 // Free all allocated resource
1591 //
1592 if ((Task == NULL) || (Status != EFI_NOT_READY)) {
1593 if (Task != NULL) {
1594 PciIo->Unmap (PciIo, Task->TableMap);
1595 PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);
1596 PciIo->Unmap (PciIo, Task->Map);
1597 } else {
1598 PciIo->Unmap (PciIo, PrdTableMap);
1599 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);
1600 PciIo->Unmap (PciIo, BufferMap);
1601 }
1602
1603 //
1604 // Dump All Ide registers to ATA_STATUS_BLOCK
1605 //
1606 DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1607 }
1608
1609 return Status;
1610 }
1611
1612 /**
1613 This function reads the pending data in the device.
1614
1615 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1616 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1617
1618 @retval EFI_SUCCESS Successfully read.
1619 @retval EFI_NOT_READY The BSY is set avoiding reading.
1620
1621 **/
1622 EFI_STATUS
1623 EFIAPI
1624 AtaPacketReadPendingData (
1625 IN EFI_PCI_IO_PROTOCOL *PciIo,
1626 IN EFI_IDE_REGISTERS *IdeRegisters
1627 )
1628 {
1629 UINT8 AltRegister;
1630 UINT16 TempWordBuffer;
1631
1632 AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1633 if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {
1634 return EFI_NOT_READY;
1635 }
1636
1637 if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1638 TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1639 while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1640 IdeReadPortWMultiple (
1641 PciIo,
1642 IdeRegisters->Data,
1643 1,
1644 &TempWordBuffer
1645 );
1646 TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1647 }
1648 }
1649
1650 return EFI_SUCCESS;
1651 }
1652
1653 /**
1654 This function is called by AtaPacketCommandExecute().
1655 It is used to transfer data between host and device. The data direction is specified
1656 by the fourth parameter.
1657
1658 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1659 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1660 @param Buffer Buffer contained data transferred between host and device.
1661 @param ByteCount Data size in byte unit of the buffer.
1662 @param Read Flag used to determine the data transfer direction.
1663 Read equals 1, means data transferred from device to host;
1664 Read equals 0, means data transferred from host to device.
1665 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1666 , uses 100ns as a unit.
1667
1668 @retval EFI_SUCCESS data is transferred successfully.
1669 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1670 **/
1671 EFI_STATUS
1672 EFIAPI
1673 AtaPacketReadWrite (
1674 IN EFI_PCI_IO_PROTOCOL *PciIo,
1675 IN EFI_IDE_REGISTERS *IdeRegisters,
1676 IN OUT VOID *Buffer,
1677 IN OUT UINT32 *ByteCount,
1678 IN BOOLEAN Read,
1679 IN UINT64 Timeout
1680 )
1681 {
1682 UINT32 RequiredWordCount;
1683 UINT32 ActualWordCount;
1684 UINT32 WordCount;
1685 EFI_STATUS Status;
1686 UINT16 *PtrBuffer;
1687
1688 PtrBuffer = Buffer;
1689 RequiredWordCount = *ByteCount >> 1;
1690
1691 //
1692 // No data transfer is permitted.
1693 //
1694 if (RequiredWordCount == 0) {
1695 return EFI_SUCCESS;
1696 }
1697
1698 //
1699 // ActualWordCount means the word count of data really transferred.
1700 //
1701 ActualWordCount = 0;
1702
1703 while (ActualWordCount < RequiredWordCount) {
1704 //
1705 // before each data transfer stream, the host should poll DRQ bit ready,
1706 // to see whether indicates device is ready to transfer data.
1707 //
1708 Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
1709 if (EFI_ERROR (Status)) {
1710 if (Status == EFI_NOT_READY) {
1711 //
1712 // Device provided less data than we intended to read, or wanted less
1713 // data than we intended to write, but it may still be successful.
1714 //
1715 break;
1716 } else {
1717 return Status;
1718 }
1719 }
1720
1721 //
1722 // get current data transfer size from Cylinder Registers.
1723 //
1724 WordCount = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb) << 8;
1725 WordCount = WordCount | IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
1726 WordCount = WordCount & 0xffff;
1727 WordCount /= 2;
1728
1729 WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));
1730
1731 if (Read) {
1732 IdeReadPortWMultiple (
1733 PciIo,
1734 IdeRegisters->Data,
1735 WordCount,
1736 PtrBuffer
1737 );
1738 } else {
1739 IdeWritePortWMultiple (
1740 PciIo,
1741 IdeRegisters->Data,
1742 WordCount,
1743 PtrBuffer
1744 );
1745 }
1746
1747 //
1748 // read status register to check whether error happens.
1749 //
1750 Status = CheckStatusRegister (PciIo, IdeRegisters);
1751 if (EFI_ERROR (Status)) {
1752 return EFI_DEVICE_ERROR;
1753 }
1754
1755 PtrBuffer += WordCount;
1756 ActualWordCount += WordCount;
1757 }
1758
1759 if (Read) {
1760 //
1761 // In the case where the drive wants to send more data than we need to read,
1762 // the DRQ bit will be set and cause delays from DRQClear2().
1763 // We need to read data from the drive until it clears DRQ so we can move on.
1764 //
1765 AtaPacketReadPendingData (PciIo, IdeRegisters);
1766 }
1767
1768 //
1769 // read status register to check whether error happens.
1770 //
1771 Status = CheckStatusRegister (PciIo, IdeRegisters);
1772 if (EFI_ERROR (Status)) {
1773 return EFI_DEVICE_ERROR;
1774 }
1775
1776 //
1777 // After data transfer is completed, normally, DRQ bit should clear.
1778 //
1779 Status = DRQClear (PciIo, IdeRegisters, Timeout);
1780 if (EFI_ERROR (Status)) {
1781 return EFI_DEVICE_ERROR;
1782 }
1783
1784 *ByteCount = ActualWordCount << 1;
1785 return Status;
1786 }
1787
1788 /**
1789 This function is used to send out ATAPI commands conforms to the Packet Command
1790 with PIO Data In Protocol.
1791
1792 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
1793 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
1794 store the IDE i/o port registers' base addresses
1795 @param[in] Channel The channel number of device.
1796 @param[in] Device The device number of device.
1797 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
1798
1799 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1800 and device sends data successfully.
1801 @retval EFI_DEVICE_ERROR the device failed to send data.
1802
1803 **/
1804 EFI_STATUS
1805 EFIAPI
1806 AtaPacketCommandExecute (
1807 IN EFI_PCI_IO_PROTOCOL *PciIo,
1808 IN EFI_IDE_REGISTERS *IdeRegisters,
1809 IN UINT8 Channel,
1810 IN UINT8 Device,
1811 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
1812 )
1813 {
1814 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1815 EFI_STATUS Status;
1816 UINT8 Count;
1817 UINT8 PacketCommand[12];
1818
1819 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1820
1821 //
1822 // Fill ATAPI Command Packet according to CDB.
1823 // For Atapi cmd, its length should be less than or equal to 12 bytes.
1824 //
1825 if (Packet->CdbLength > 12) {
1826 return EFI_INVALID_PARAMETER;
1827 }
1828
1829 ZeroMem (PacketCommand, 12);
1830 CopyMem (PacketCommand, Packet->Cdb, Packet->CdbLength);
1831
1832 //
1833 // No OVL; No DMA
1834 //
1835 AtaCommandBlock.AtaFeatures = 0x00;
1836 //
1837 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1838 // determine how many data should be transferred.
1839 //
1840 AtaCommandBlock.AtaCylinderLow = (UINT8)(ATAPI_MAX_BYTE_COUNT & 0x00ff);
1841 AtaCommandBlock.AtaCylinderHigh = (UINT8)(ATAPI_MAX_BYTE_COUNT >> 8);
1842 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
1843 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET;
1844
1845 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | (Device << 0x4)));
1846 //
1847 // Disable interrupt
1848 //
1849 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, ATA_DEFAULT_CTL);
1850
1851 //
1852 // Issue ATA PACKET command firstly
1853 //
1854 Status = AtaIssueCommand (PciIo, IdeRegisters, &AtaCommandBlock, Packet->Timeout);
1855 if (EFI_ERROR (Status)) {
1856 return Status;
1857 }
1858
1859 Status = DRQReady (PciIo, IdeRegisters, Packet->Timeout);
1860 if (EFI_ERROR (Status)) {
1861 return Status;
1862 }
1863
1864 //
1865 // Send out ATAPI command packet
1866 //
1867 for (Count = 0; Count < 6; Count++) {
1868 IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16 *)PacketCommand + Count));
1869 //
1870 // Stall for 10 microseconds.
1871 //
1872 MicroSecondDelay (10);
1873 }
1874
1875 //
1876 // Read/Write the data of ATAPI Command
1877 //
1878 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1879 Status = AtaPacketReadWrite (
1880 PciIo,
1881 IdeRegisters,
1882 Packet->InDataBuffer,
1883 &Packet->InTransferLength,
1884 TRUE,
1885 Packet->Timeout
1886 );
1887 } else {
1888 Status = AtaPacketReadWrite (
1889 PciIo,
1890 IdeRegisters,
1891 Packet->OutDataBuffer,
1892 &Packet->OutTransferLength,
1893 FALSE,
1894 Packet->Timeout
1895 );
1896 }
1897
1898 return Status;
1899 }
1900
1901 /**
1902 Set the calculated Best transfer mode to a detected device.
1903
1904 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1905 @param Channel The channel number of device.
1906 @param Device The device number of device.
1907 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
1908 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1909
1910 @retval EFI_SUCCESS Set transfer mode successfully.
1911 @retval EFI_DEVICE_ERROR Set transfer mode failed.
1912 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
1913
1914 **/
1915 EFI_STATUS
1916 EFIAPI
1917 SetDeviceTransferMode (
1918 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
1919 IN UINT8 Channel,
1920 IN UINT8 Device,
1921 IN EFI_ATA_TRANSFER_MODE *TransferMode,
1922 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1923 )
1924 {
1925 EFI_STATUS Status;
1926 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1927
1928 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1929
1930 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
1931 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
1932 AtaCommandBlock.AtaFeatures = 0x03;
1933 AtaCommandBlock.AtaSectorCount = *((UINT8 *)TransferMode);
1934
1935 //
1936 // Send SET FEATURE command (sub command 0x03) to set pio mode.
1937 //
1938 Status = AtaNonDataCommandIn (
1939 Instance->PciIo,
1940 &Instance->IdeRegisters[Channel],
1941 &AtaCommandBlock,
1942 AtaStatusBlock,
1943 ATA_ATAPI_TIMEOUT,
1944 NULL
1945 );
1946
1947 return Status;
1948 }
1949
1950 /**
1951 Set drive parameters for devices not support PACKETS command.
1952
1953 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1954 @param Channel The channel number of device.
1955 @param Device The device number of device.
1956 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
1957 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1958
1959 @retval EFI_SUCCESS Set drive parameter successfully.
1960 @retval EFI_DEVICE_ERROR Set drive parameter failed.
1961 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
1962
1963 **/
1964 EFI_STATUS
1965 EFIAPI
1966 SetDriveParameters (
1967 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
1968 IN UINT8 Channel,
1969 IN UINT8 Device,
1970 IN EFI_ATA_DRIVE_PARMS *DriveParameters,
1971 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1972 )
1973 {
1974 EFI_STATUS Status;
1975 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1976
1977 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1978
1979 AtaCommandBlock.AtaCommand = ATA_CMD_INIT_DRIVE_PARAM;
1980 AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;
1981 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) + DriveParameters->Heads);
1982
1983 //
1984 // Send Init drive parameters
1985 //
1986 Status = AtaNonDataCommandIn (
1987 Instance->PciIo,
1988 &Instance->IdeRegisters[Channel],
1989 &AtaCommandBlock,
1990 AtaStatusBlock,
1991 ATA_ATAPI_TIMEOUT,
1992 NULL
1993 );
1994
1995 //
1996 // Send Set Multiple parameters
1997 //
1998 AtaCommandBlock.AtaCommand = ATA_CMD_SET_MULTIPLE_MODE;
1999 AtaCommandBlock.AtaSectorCount = DriveParameters->MultipleSector;
2000 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2001
2002 Status = AtaNonDataCommandIn (
2003 Instance->PciIo,
2004 &Instance->IdeRegisters[Channel],
2005 &AtaCommandBlock,
2006 AtaStatusBlock,
2007 ATA_ATAPI_TIMEOUT,
2008 NULL
2009 );
2010
2011 return Status;
2012 }
2013
2014 /**
2015 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2016
2017 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2018 @param Channel The channel number of device.
2019 @param Device The device number of device.
2020 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2021
2022 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2023 @retval Others Fail to get return status data.
2024
2025 **/
2026 EFI_STATUS
2027 EFIAPI
2028 IdeAtaSmartReturnStatusCheck (
2029 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
2030 IN UINT8 Channel,
2031 IN UINT8 Device,
2032 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2033 )
2034 {
2035 EFI_STATUS Status;
2036 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2037 UINT8 LBAMid;
2038 UINT8 LBAHigh;
2039
2040 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2041
2042 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
2043 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS;
2044 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
2045 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2046 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2047
2048 //
2049 // Send S.M.A.R.T Read Return Status command to device
2050 //
2051 Status = AtaNonDataCommandIn (
2052 Instance->PciIo,
2053 &Instance->IdeRegisters[Channel],
2054 &AtaCommandBlock,
2055 AtaStatusBlock,
2056 ATA_ATAPI_TIMEOUT,
2057 NULL
2058 );
2059
2060 if (EFI_ERROR (Status)) {
2061 REPORT_STATUS_CODE (
2062 EFI_ERROR_CODE | EFI_ERROR_MINOR,
2063 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
2064 );
2065 return EFI_DEVICE_ERROR;
2066 }
2067
2068 REPORT_STATUS_CODE (
2069 EFI_PROGRESS_CODE,
2070 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
2071 );
2072
2073 LBAMid = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderLsb);
2074 LBAHigh = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderMsb);
2075
2076 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
2077 //
2078 // The threshold exceeded condition is not detected by the device
2079 //
2080 DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2081 REPORT_STATUS_CODE (
2082 EFI_PROGRESS_CODE,
2083 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
2084 );
2085 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
2086 //
2087 // The threshold exceeded condition is detected by the device
2088 //
2089 DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2090 REPORT_STATUS_CODE (
2091 EFI_PROGRESS_CODE,
2092 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
2093 );
2094 }
2095
2096 return EFI_SUCCESS;
2097 }
2098
2099 /**
2100 Enable SMART command of the disk if supported.
2101
2102 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2103 @param Channel The channel number of device.
2104 @param Device The device number of device.
2105 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2106 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2107
2108 **/
2109 VOID
2110 EFIAPI
2111 IdeAtaSmartSupport (
2112 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
2113 IN UINT8 Channel,
2114 IN UINT8 Device,
2115 IN EFI_IDENTIFY_DATA *IdentifyData,
2116 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2117 )
2118 {
2119 EFI_STATUS Status;
2120 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2121
2122 //
2123 // Detect if the device supports S.M.A.R.T.
2124 //
2125 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
2126 //
2127 // S.M.A.R.T is not supported by the device
2128 //
2129 DEBUG ((
2130 DEBUG_INFO,
2131 "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2132 (Channel == 1) ? "secondary" : "primary",
2133 (Device == 1) ? "slave" : "master"
2134 ));
2135 REPORT_STATUS_CODE (
2136 EFI_ERROR_CODE | EFI_ERROR_MINOR,
2137 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
2138 );
2139 } else {
2140 //
2141 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2142 //
2143 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
2144 REPORT_STATUS_CODE (
2145 EFI_PROGRESS_CODE,
2146 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
2147 );
2148
2149 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2150
2151 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
2152 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION;
2153 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
2154 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2155 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2156
2157 //
2158 // Send S.M.A.R.T Enable command to device
2159 //
2160 Status = AtaNonDataCommandIn (
2161 Instance->PciIo,
2162 &Instance->IdeRegisters[Channel],
2163 &AtaCommandBlock,
2164 AtaStatusBlock,
2165 ATA_ATAPI_TIMEOUT,
2166 NULL
2167 );
2168
2169 if (!EFI_ERROR (Status)) {
2170 //
2171 // Send S.M.A.R.T AutoSave command to device
2172 //
2173 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2174
2175 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
2176 AtaCommandBlock.AtaFeatures = 0xD2;
2177 AtaCommandBlock.AtaSectorCount = 0xF1;
2178 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
2179 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2180 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2181
2182 Status = AtaNonDataCommandIn (
2183 Instance->PciIo,
2184 &Instance->IdeRegisters[Channel],
2185 &AtaCommandBlock,
2186 AtaStatusBlock,
2187 ATA_ATAPI_TIMEOUT,
2188 NULL
2189 );
2190 if (!EFI_ERROR (Status)) {
2191 Status = IdeAtaSmartReturnStatusCheck (
2192 Instance,
2193 Channel,
2194 Device,
2195 AtaStatusBlock
2196 );
2197 }
2198 }
2199 }
2200
2201 DEBUG ((
2202 DEBUG_INFO,
2203 "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2204 (Channel == 1) ? "secondary" : "primary",
2205 (Device == 1) ? "slave" : "master"
2206 ));
2207 }
2208
2209 return;
2210 }
2211
2212 /**
2213 Sends out an ATA Identify Command to the specified device.
2214
2215 This function is called by DiscoverIdeDevice() during its device
2216 identification. It sends out the ATA Identify Command to the
2217 specified device. Only ATA device responses to this command. If
2218 the command succeeds, it returns the Identify data structure which
2219 contains information about the device. This function extracts the
2220 information it needs to fill the IDE_BLK_IO_DEV data structure,
2221 including device type, media block size, media capacity, and etc.
2222
2223 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2224 @param Channel The channel number of device.
2225 @param Device The device number of device.
2226 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2227 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2228
2229 @retval EFI_SUCCESS Identify ATA device successfully.
2230 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2231 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2232
2233 **/
2234 EFI_STATUS
2235 EFIAPI
2236 AtaIdentify (
2237 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
2238 IN UINT8 Channel,
2239 IN UINT8 Device,
2240 IN OUT EFI_IDENTIFY_DATA *Buffer,
2241 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2242 )
2243 {
2244 EFI_STATUS Status;
2245 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2246
2247 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2248
2249 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
2250 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2251
2252 Status = AtaPioDataInOut (
2253 Instance->PciIo,
2254 &Instance->IdeRegisters[Channel],
2255 Buffer,
2256 sizeof (EFI_IDENTIFY_DATA),
2257 TRUE,
2258 &AtaCommandBlock,
2259 AtaStatusBlock,
2260 ATA_ATAPI_TIMEOUT,
2261 NULL
2262 );
2263
2264 return Status;
2265 }
2266
2267 /**
2268 This function is called by DiscoverIdeDevice() during its device
2269 identification.
2270 Its main purpose is to get enough information for the device media
2271 to fill in the Media data structure of the Block I/O Protocol interface.
2272
2273 There are 5 steps to reach such objective:
2274 1. Sends out the ATAPI Identify Command to the specified device.
2275 Only ATAPI device responses to this command. If the command succeeds,
2276 it returns the Identify data structure which filled with information
2277 about the device. Since the ATAPI device contains removable media,
2278 the only meaningful information is the device module name.
2279 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2280 This command will return inquiry data of the device, which contains
2281 the device type information.
2282 3. Allocate sense data space for future use. We don't detect the media
2283 presence here to improvement boot performance, especially when CD
2284 media is present. The media detection will be performed just before
2285 each BLK_IO read/write
2286
2287 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2288 @param Channel The channel number of device.
2289 @param Device The device number of device.
2290 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2291 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2292
2293 @retval EFI_SUCCESS Identify ATAPI device successfully.
2294 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2295 is not supported by this IDE driver.
2296 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2297
2298 **/
2299 EFI_STATUS
2300 EFIAPI
2301 AtaIdentifyPacket (
2302 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
2303 IN UINT8 Channel,
2304 IN UINT8 Device,
2305 IN OUT EFI_IDENTIFY_DATA *Buffer,
2306 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
2307 )
2308 {
2309 EFI_STATUS Status;
2310 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2311
2312 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2313
2314 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
2315 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2316
2317 //
2318 // Send ATAPI Identify Command to get IDENTIFY data.
2319 //
2320 Status = AtaPioDataInOut (
2321 Instance->PciIo,
2322 &Instance->IdeRegisters[Channel],
2323 (VOID *)Buffer,
2324 sizeof (EFI_IDENTIFY_DATA),
2325 TRUE,
2326 &AtaCommandBlock,
2327 AtaStatusBlock,
2328 ATA_ATAPI_TIMEOUT,
2329 NULL
2330 );
2331
2332 return Status;
2333 }
2334
2335 /**
2336 This function is used for detect whether the IDE device exists in the
2337 specified Channel as the specified Device Number.
2338
2339 There is two IDE channels: one is Primary Channel, the other is
2340 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2341 Different channel has different register group.
2342
2343 On each IDE channel, at most two IDE devices attach,
2344 one is called Device 0 (Master device), the other is called Device 1
2345 (Slave device). The devices on the same channel co-use the same register
2346 group, so before sending out a command for a specified device via command
2347 register, it is a must to select the current device to accept the command
2348 by set the device number in the Head/Device Register.
2349
2350 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2351 @param IdeChannel The channel number of device.
2352
2353 @retval EFI_SUCCESS successfully detects device.
2354 @retval other any failure during detection process will return this value.
2355
2356 **/
2357 EFI_STATUS
2358 EFIAPI
2359 DetectAndConfigIdeDevice (
2360 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
2361 IN UINT8 IdeChannel
2362 )
2363 {
2364 EFI_STATUS Status;
2365 UINT8 SectorCountReg;
2366 UINT8 LBALowReg;
2367 UINT8 LBAMidReg;
2368 UINT8 LBAHighReg;
2369 EFI_ATA_DEVICE_TYPE DeviceType;
2370 UINT8 IdeDevice;
2371 EFI_IDE_REGISTERS *IdeRegisters;
2372 EFI_IDENTIFY_DATA Buffer;
2373
2374 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
2375 EFI_PCI_IO_PROTOCOL *PciIo;
2376
2377 EFI_ATA_COLLECTIVE_MODE *SupportedModes;
2378 EFI_ATA_TRANSFER_MODE TransferMode;
2379 EFI_ATA_DRIVE_PARMS DriveParameters;
2380
2381 IdeRegisters = &Instance->IdeRegisters[IdeChannel];
2382 IdeInit = Instance->IdeControllerInit;
2383 PciIo = Instance->PciIo;
2384
2385 for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
2386 //
2387 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2388 //
2389 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2390
2391 //
2392 // Send ATA Device Execut Diagnostic command.
2393 // This command should work no matter DRDY is ready or not
2394 //
2395 IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG);
2396
2397 Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000);
2398 if (EFI_ERROR (Status)) {
2399 DEBUG ((DEBUG_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));
2400 continue;
2401 }
2402
2403 //
2404 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2405 //
2406 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2407 //
2408 // Stall for 1 milliseconds.
2409 //
2410 MicroSecondDelay (1000);
2411
2412 SectorCountReg = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
2413 LBALowReg = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
2414 LBAMidReg = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
2415 LBAHighReg = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
2416
2417 //
2418 // Refer to ATA/ATAPI 4 Spec, section 9.1
2419 //
2420 if ((SectorCountReg == 0x1) && (LBALowReg == 0x1) && (LBAMidReg == 0x0) && (LBAHighReg == 0x0)) {
2421 DeviceType = EfiIdeHarddisk;
2422 } else if ((LBAMidReg == 0x14) && (LBAHighReg == 0xeb)) {
2423 DeviceType = EfiIdeCdrom;
2424 } else {
2425 continue;
2426 }
2427
2428 //
2429 // Send IDENTIFY cmd to the device to test if it is really attached.
2430 //
2431 if (DeviceType == EfiIdeHarddisk) {
2432 Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2433 //
2434 // if identifying ata device is failure, then try to send identify packet cmd.
2435 //
2436 if (EFI_ERROR (Status)) {
2437 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
2438
2439 DeviceType = EfiIdeCdrom;
2440 Status = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2441 }
2442 } else {
2443 Status = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2444 //
2445 // if identifying atapi device is failure, then try to send identify cmd.
2446 //
2447 if (EFI_ERROR (Status)) {
2448 DeviceType = EfiIdeHarddisk;
2449 Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2450 }
2451 }
2452
2453 if (EFI_ERROR (Status)) {
2454 //
2455 // No device is found at this port
2456 //
2457 continue;
2458 }
2459
2460 DEBUG ((
2461 DEBUG_INFO,
2462 "[%a] channel [%a] [%a] device\n",
2463 (IdeChannel == 1) ? "secondary" : "primary ",
2464 (IdeDevice == 1) ? "slave " : "master",
2465 DeviceType == EfiIdeCdrom ? "cdrom " : "harddisk"
2466 ));
2467 //
2468 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2469 //
2470 if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
2471 IdeAtaSmartSupport (
2472 Instance,
2473 IdeChannel,
2474 IdeDevice,
2475 &Buffer,
2476 NULL
2477 );
2478 }
2479
2480 //
2481 // Submit identify data to IDE controller init driver
2482 //
2483 IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &Buffer);
2484
2485 //
2486 // Now start to config ide device parameter and transfer mode.
2487 //
2488 Status = IdeInit->CalculateMode (
2489 IdeInit,
2490 IdeChannel,
2491 IdeDevice,
2492 &SupportedModes
2493 );
2494 if (EFI_ERROR (Status)) {
2495 DEBUG ((DEBUG_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
2496 continue;
2497 }
2498
2499 //
2500 // Set best supported PIO mode on this IDE device
2501 //
2502 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
2503 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2504 } else {
2505 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2506 }
2507
2508 TransferMode.ModeNumber = (UINT8)(SupportedModes->PioMode.Mode);
2509
2510 if (SupportedModes->ExtModeCount == 0) {
2511 Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2512
2513 if (EFI_ERROR (Status)) {
2514 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2515 continue;
2516 }
2517 }
2518
2519 //
2520 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
2521 // be set together. Only one DMA mode can be set to a device. If setting
2522 // DMA mode operation fails, we can continue moving on because we only use
2523 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2524 //
2525 if (SupportedModes->UdmaMode.Valid) {
2526 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2527 TransferMode.ModeNumber = (UINT8)(SupportedModes->UdmaMode.Mode);
2528 Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2529
2530 if (EFI_ERROR (Status)) {
2531 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2532 continue;
2533 }
2534 } else if (SupportedModes->MultiWordDmaMode.Valid) {
2535 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2536 TransferMode.ModeNumber = (UINT8)SupportedModes->MultiWordDmaMode.Mode;
2537 Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2538
2539 if (EFI_ERROR (Status)) {
2540 DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2541 continue;
2542 }
2543 }
2544
2545 //
2546 // Set Parameters for the device:
2547 // 1) Init
2548 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2549 //
2550 if (DeviceType == EfiIdeHarddisk) {
2551 //
2552 // Init driver parameters
2553 //
2554 DriveParameters.Sector = (UINT8)((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;
2555 DriveParameters.Heads = (UINT8)(((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);
2556 DriveParameters.MultipleSector = (UINT8)((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;
2557
2558 Status = SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);
2559 }
2560
2561 //
2562 // Set IDE controller Timing Blocks in the PCI Configuration Space
2563 //
2564 IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
2565
2566 //
2567 // IDE controller and IDE device timing is configured successfully.
2568 // Now insert the device into device list.
2569 //
2570 Status = CreateNewDeviceInfo (Instance, IdeChannel, IdeDevice, DeviceType, &Buffer);
2571 if (EFI_ERROR (Status)) {
2572 continue;
2573 }
2574
2575 if (DeviceType == EfiIdeHarddisk) {
2576 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
2577 }
2578 }
2579
2580 return EFI_SUCCESS;
2581 }
2582
2583 /**
2584 Initialize ATA host controller at IDE mode.
2585
2586 The function is designed to initialize ATA host controller.
2587
2588 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2589
2590 **/
2591 EFI_STATUS
2592 EFIAPI
2593 IdeModeInitialization (
2594 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
2595 )
2596 {
2597 EFI_STATUS Status;
2598 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
2599 EFI_PCI_IO_PROTOCOL *PciIo;
2600 UINT8 Channel;
2601 UINT8 IdeChannel;
2602 BOOLEAN ChannelEnabled;
2603 UINT8 MaxDevices;
2604
2605 IdeInit = Instance->IdeControllerInit;
2606 PciIo = Instance->PciIo;
2607 Channel = IdeInit->ChannelCount;
2608
2609 //
2610 // Obtain IDE IO port registers' base addresses
2611 //
2612 Status = GetIdeRegisterIoAddr (PciIo, Instance->IdeRegisters);
2613 if (EFI_ERROR (Status)) {
2614 goto ErrorExit;
2615 }
2616
2617 for (IdeChannel = 0; IdeChannel < Channel; IdeChannel++) {
2618 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
2619
2620 //
2621 // now obtain channel information fron IdeControllerInit protocol.
2622 //
2623 Status = IdeInit->GetChannelInfo (
2624 IdeInit,
2625 IdeChannel,
2626 &ChannelEnabled,
2627 &MaxDevices
2628 );
2629 if (EFI_ERROR (Status)) {
2630 DEBUG ((DEBUG_ERROR, "[GetChannel, Status=%x]", Status));
2631 continue;
2632 }
2633
2634 if (!ChannelEnabled) {
2635 continue;
2636 }
2637
2638 ASSERT (MaxDevices <= 2);
2639 //
2640 // Now inform the IDE Controller Init Module.
2641 //
2642 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
2643
2644 //
2645 // No reset channel function implemented.
2646 //
2647 IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
2648
2649 //
2650 // Now inform the IDE Controller Init Module.
2651 //
2652 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, IdeChannel);
2653
2654 //
2655 // Detect all attached ATA devices and set the transfer mode for each device.
2656 //
2657 DetectAndConfigIdeDevice (Instance, IdeChannel);
2658 }
2659
2660 //
2661 // All configurations done! Notify IdeController to do post initialization
2662 // work such as saving IDE controller PCI settings for S3 resume
2663 //
2664 IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
2665
2666 ErrorExit:
2667 return Status;
2668 }