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