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