1 /** @file
2   Header file for AHCI mode of ATA host controller.
3 
4   Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
5   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_PHYSICAL_ADDRESS          PrdTableBaseAddr;
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   UINTN                         AlignmentMask;
1547   UINTN                         RealPageCount;
1548   EFI_PHYSICAL_ADDRESS          BaseAddr;
1549   EFI_PHYSICAL_ADDRESS          BaseMapAddr;
1550 
1551   Status        = EFI_SUCCESS;
1552   PrdTableMap   = NULL;
1553   BufferMap     = NULL;
1554   PageCount     = 0;
1555   RealPageCount = 0;
1556   BaseAddr      = 0;
1557   PciIo         = Instance->PciIo;
1558 
1559   if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {
1560     return EFI_INVALID_PARAMETER;
1561   }
1562 
1563   //
1564   // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1565   // BlockIO tasks.
1566   // Delay 1ms to simulate the blocking time out checking.
1567   //
1568   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1569   while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
1570     AsyncNonBlockingTransferRoutine (NULL, Instance);
1571     //
1572     // Stall for 1 milliseconds.
1573     //
1574     MicroSecondDelay (1000);
1575   }
1576   gBS->RestoreTPL (OldTpl);
1577 
1578   //
1579   // The data buffer should be even alignment
1580   //
1581   if (((UINTN)DataBuffer & 0x1) != 0) {
1582     return EFI_INVALID_PARAMETER;
1583   }
1584 
1585   //
1586   // Set relevant IO Port address.
1587   //
1588   IoPortForBmic = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
1589   IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1590   IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
1591 
1592   //
1593   // For Blocking mode, start the command.
1594   // For non-blocking mode, when the command is not started, start it, otherwise
1595   // go to check the status.
1596   //
1597   if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {
1598     //
1599     // Calculate the number of PRD entry.
1600     // Every entry in PRD table can specify a 64K memory region.
1601     //
1602     PrdTableNum   = (UINTN)(RShiftU64(DataLength, 16) + 1);
1603 
1604     //
1605     // Make sure that the memory region of PRD table is not cross 64K boundary
1606     //
1607     PrdTableSize = PrdTableNum * sizeof (EFI_ATA_DMA_PRD);
1608     if (PrdTableSize > 0x10000) {
1609       return EFI_INVALID_PARAMETER;
1610     }
1611 
1612     //
1613     // Allocate buffer for PRD table initialization.
1614     // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
1615     // boundary and the table cannot cross a 64K boundary in memory.
1616     //
1617     PageCount     = EFI_SIZE_TO_PAGES (PrdTableSize);
1618     RealPageCount = PageCount + EFI_SIZE_TO_PAGES (SIZE_64KB);
1619 
1620     //
1621     // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
1622     //
1623     ASSERT (RealPageCount > PageCount);
1624 
1625     Status    = PciIo->AllocateBuffer (
1626                          PciIo,
1627                          AllocateAnyPages,
1628                          EfiBootServicesData,
1629                          RealPageCount,
1630                          (VOID **)&BaseAddr,
1631                          0
1632                          );
1633     if (EFI_ERROR (Status)) {
1634       return EFI_OUT_OF_RESOURCES;
1635     }
1636 
1637     ByteCount = EFI_PAGES_TO_SIZE (RealPageCount);
1638     Status    = PciIo->Map (
1639                          PciIo,
1640                          EfiPciIoOperationBusMasterCommonBuffer,
1641                          (VOID*)(UINTN)BaseAddr,
1642                          &ByteCount,
1643                          &BaseMapAddr,
1644                          &PrdTableMap
1645                          );
1646     if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (RealPageCount))) {
1647       //
1648       // If the data length actually mapped is not equal to the requested amount,
1649       // it means the DMA operation may be broken into several discontinuous smaller chunks.
1650       // Can't handle this case.
1651       //
1652       PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);
1653       return EFI_OUT_OF_RESOURCES;
1654     }
1655 
1656     ZeroMem ((VOID *) ((UINTN) BaseAddr), ByteCount);
1657 
1658     //
1659     // Calculate the 64K align address as PRD Table base address.
1660     //
1661     AlignmentMask    = SIZE_64KB - 1;
1662     PrdTableBaseAddr = ((UINTN) BaseAddr + AlignmentMask) & ~AlignmentMask;
1663     PrdTableMapAddr  = ((UINTN) BaseMapAddr + AlignmentMask) & ~AlignmentMask;
1664 
1665     //
1666     // Map the host address of DataBuffer to DMA master address.
1667     //
1668     if (Read) {
1669       PciIoOperation = EfiPciIoOperationBusMasterWrite;
1670     } else {
1671       PciIoOperation = EfiPciIoOperationBusMasterRead;
1672     }
1673 
1674     ByteCount = (UINTN)DataLength;
1675     Status    = PciIo->Map (
1676                          PciIo,
1677                          PciIoOperation,
1678                          DataBuffer,
1679                          &ByteCount,
1680                          &BufferMapAddress,
1681                          &BufferMap
1682                          );
1683     if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
1684       PciIo->Unmap (PciIo, PrdTableMap);
1685       PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);
1686       return EFI_OUT_OF_RESOURCES;
1687     }
1688 
1689     //
1690     // According to Ata spec, it requires the buffer address and size to be even.
1691     //
1692     ASSERT ((BufferMapAddress & 0x1) == 0);
1693     ASSERT ((ByteCount & 0x1) == 0);
1694 
1695     //
1696     // Fill the PRD table with appropriate bus master address of data buffer and data length.
1697     //
1698     ByteRemaining   = ByteCount;
1699     TempPrdBaseAddr = (EFI_ATA_DMA_PRD*)(UINTN)PrdTableBaseAddr;
1700     while (ByteRemaining != 0) {
1701       if (ByteRemaining <= 0x10000) {
1702         TempPrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
1703         TempPrdBaseAddr->ByteCount      = (UINT16) ByteRemaining;
1704         TempPrdBaseAddr->EndOfTable     = 0x8000;
1705         break;
1706       }
1707 
1708       TempPrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
1709       TempPrdBaseAddr->ByteCount      = (UINT16) 0x0;
1710 
1711       ByteRemaining    -= 0x10000;
1712       BufferMapAddress += 0x10000;
1713       TempPrdBaseAddr++;
1714     }
1715 
1716     //
1717     // Start to enable the DMA operation
1718     //
1719     DeviceHead = AtaCommandBlock->AtaDeviceHead;
1720 
1721     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
1722 
1723     //
1724     // Enable interrupt to support UDMA
1725     //
1726     DeviceControl = 0;
1727     IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1728 
1729     //
1730     // Read BMIS register and clear ERROR and INTR bit
1731     //
1732     RegisterValue  = IdeReadPortB(PciIo, IoPortForBmis);
1733     RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1734     IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
1735 
1736     //
1737     // Set the base address to BMID register
1738     //
1739     IdeWritePortDW (PciIo, IoPortForBmid, (UINT32)PrdTableMapAddr);
1740 
1741     //
1742     // Set BMIC register to identify the operation direction
1743     //
1744     RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
1745     if (Read) {
1746       RegisterValue |= BMIC_NREAD;
1747     } else {
1748       RegisterValue &= ~((UINT8) BMIC_NREAD);
1749     }
1750     IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1751 
1752     if (Task != NULL) {
1753       Task->Map            = BufferMap;
1754       Task->TableMap       = PrdTableMap;
1755       Task->MapBaseAddress = (EFI_ATA_DMA_PRD*)(UINTN)BaseAddr;
1756       Task->PageCount      = RealPageCount;
1757       Task->IsStart        = TRUE;
1758     }
1759 
1760     //
1761     // Issue ATA command
1762     //
1763     Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1764 
1765     if (EFI_ERROR (Status)) {
1766       Status = EFI_DEVICE_ERROR;
1767       goto Exit;
1768     }
1769 
1770     Status = CheckStatusRegister (PciIo, IdeRegisters);
1771     if (EFI_ERROR (Status)) {
1772       Status = EFI_DEVICE_ERROR;
1773       goto Exit;
1774     }
1775     //
1776     // Set START bit of BMIC register
1777     //
1778     RegisterValue  = IdeReadPortB(PciIo, IoPortForBmic);
1779     RegisterValue |= BMIC_START;
1780     IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);
1781 
1782   }
1783 
1784   //
1785   // Check the INTERRUPT and ERROR bit of BMIS
1786   //
1787   if (Task != NULL) {
1788     Status = AtaUdmStatusCheck (PciIo, Task, IdeRegisters);
1789   } else {
1790     Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);
1791   }
1792 
1793   //
1794   // For blocking mode, clear registers and free buffers.
1795   // For non blocking mode, when the related registers have been set or time
1796   // out, or a error has been happened, it needs to clear the register and free
1797   // buffer.
1798   //
1799   if ((Task == NULL) || Status != EFI_NOT_READY) {
1800     //
1801     // Read BMIS register and clear ERROR and INTR bit
1802     //
1803     RegisterValue  = IdeReadPortB (PciIo, IoPortForBmis);
1804     RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1805     IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
1806 
1807     //
1808     // Read Status Register of IDE device to clear interrupt
1809     //
1810     RegisterValue  = IdeReadPortB(PciIo, IdeRegisters->CmdOrStatus);
1811 
1812     //
1813     // Clear START bit of BMIC register
1814     //
1815     RegisterValue  = IdeReadPortB(PciIo, IoPortForBmic);
1816     RegisterValue &= ~((UINT8) BMIC_START);
1817     IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
1818 
1819     //
1820     // Disable interrupt of Select device
1821     //
1822     DeviceControl  = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1823     DeviceControl |= ATA_CTLREG_IEN_L;
1824     IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1825     //
1826     // Stall for 10 milliseconds.
1827     //
1828     MicroSecondDelay (10000);
1829 
1830   }
1831 
1832 Exit:
1833   //
1834   // Free all allocated resource
1835   //
1836   if ((Task == NULL) || Status != EFI_NOT_READY) {
1837     if (Task != NULL) {
1838       PciIo->Unmap (PciIo, Task->TableMap);
1839       PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);
1840       PciIo->Unmap (PciIo, Task->Map);
1841     } else {
1842       PciIo->Unmap (PciIo, PrdTableMap);
1843       PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);
1844       PciIo->Unmap (PciIo, BufferMap);
1845     }
1846 
1847     //
1848     // Dump All Ide registers to ATA_STATUS_BLOCK
1849     //
1850     DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
1851   }
1852 
1853   return Status;
1854 }
1855 
1856 /**
1857   This function reads the pending data in the device.
1858 
1859   @param PciIo         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1860   @param IdeRegisters  A pointer to EFI_IDE_REGISTERS data structure.
1861 
1862   @retval EFI_SUCCESS   Successfully read.
1863   @retval EFI_NOT_READY The BSY is set avoiding reading.
1864 
1865 **/
1866 EFI_STATUS
1867 EFIAPI
AtaPacketReadPendingData(IN EFI_PCI_IO_PROTOCOL * PciIo,IN EFI_IDE_REGISTERS * IdeRegisters)1868 AtaPacketReadPendingData (
1869   IN  EFI_PCI_IO_PROTOCOL       *PciIo,
1870   IN  EFI_IDE_REGISTERS         *IdeRegisters
1871   )
1872 {
1873   UINT8     AltRegister;
1874   UINT16    TempWordBuffer;
1875 
1876   AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1877   if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {
1878     return EFI_NOT_READY;
1879   }
1880 
1881   if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1882     TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1883     while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1884       IdeReadPortWMultiple (
1885         PciIo,
1886         IdeRegisters->Data,
1887         1,
1888         &TempWordBuffer
1889         );
1890       TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1891     }
1892   }
1893   return EFI_SUCCESS;
1894 }
1895 
1896 /**
1897   This function is called by AtaPacketCommandExecute().
1898   It is used to transfer data between host and device. The data direction is specified
1899   by the fourth parameter.
1900 
1901   @param PciIo         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1902   @param IdeRegisters  A pointer to EFI_IDE_REGISTERS data structure.
1903   @param Buffer        Buffer contained data transferred between host and device.
1904   @param ByteCount     Data size in byte unit of the buffer.
1905   @param Read          Flag used to determine the data transfer direction.
1906                        Read equals 1, means data transferred from device to host;
1907                        Read equals 0, means data transferred from host to device.
1908   @param Timeout       Timeout value for wait DRQ ready before each data stream's transfer
1909                        , uses 100ns as a unit.
1910 
1911   @retval EFI_SUCCESS      data is transferred successfully.
1912   @retval EFI_DEVICE_ERROR the device failed to transfer data.
1913 **/
1914 EFI_STATUS
1915 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)1916 AtaPacketReadWrite (
1917   IN     EFI_PCI_IO_PROTOCOL       *PciIo,
1918   IN     EFI_IDE_REGISTERS         *IdeRegisters,
1919   IN OUT VOID                      *Buffer,
1920   IN     UINT64                    ByteCount,
1921   IN     BOOLEAN                   Read,
1922   IN     UINT64                    Timeout
1923   )
1924 {
1925   UINT32      RequiredWordCount;
1926   UINT32      ActualWordCount;
1927   UINT32      WordCount;
1928   EFI_STATUS  Status;
1929   UINT16      *PtrBuffer;
1930 
1931   //
1932   // No data transfer is premitted.
1933   //
1934   if (ByteCount == 0) {
1935     return EFI_SUCCESS;
1936   }
1937 
1938   PtrBuffer         = Buffer;
1939   RequiredWordCount = (UINT32)RShiftU64(ByteCount, 1);
1940   //
1941   // ActuralWordCount means the word count of data really transferred.
1942   //
1943   ActualWordCount = 0;
1944 
1945   while (ActualWordCount < RequiredWordCount) {
1946     //
1947     // before each data transfer stream, the host should poll DRQ bit ready,
1948     // to see whether indicates device is ready to transfer data.
1949     //
1950     Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
1951     if (EFI_ERROR (Status)) {
1952       return Status;
1953     }
1954 
1955     //
1956     // get current data transfer size from Cylinder Registers.
1957     //
1958     WordCount  = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb) << 8;
1959     WordCount  = WordCount | IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
1960     WordCount  = WordCount & 0xffff;
1961     WordCount /= 2;
1962 
1963     WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));
1964 
1965     if (Read) {
1966       IdeReadPortWMultiple (
1967         PciIo,
1968         IdeRegisters->Data,
1969         WordCount,
1970         PtrBuffer
1971         );
1972     } else {
1973       IdeWritePortWMultiple (
1974         PciIo,
1975         IdeRegisters->Data,
1976         WordCount,
1977         PtrBuffer
1978         );
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     PtrBuffer       += WordCount;
1990     ActualWordCount += WordCount;
1991   }
1992 
1993   if (Read) {
1994     //
1995     // In the case where the drive wants to send more data than we need to read,
1996     // the DRQ bit will be set and cause delays from DRQClear2().
1997     // We need to read data from the drive until it clears DRQ so we can move on.
1998     //
1999     AtaPacketReadPendingData (PciIo, IdeRegisters);
2000   }
2001 
2002   //
2003   // read status register to check whether error happens.
2004   //
2005   Status = CheckStatusRegister (PciIo, IdeRegisters);
2006   if (EFI_ERROR (Status)) {
2007     return EFI_DEVICE_ERROR;
2008   }
2009 
2010   //
2011   // After data transfer is completed, normally, DRQ bit should clear.
2012   //
2013   Status = DRQClear (PciIo, IdeRegisters, Timeout);
2014   if (EFI_ERROR (Status)) {
2015     return EFI_DEVICE_ERROR;
2016   }
2017 
2018   return Status;
2019 }
2020 
2021 /**
2022   This function is used to send out ATAPI commands conforms to the Packet Command
2023   with PIO Data In Protocol.
2024 
2025   @param[in] PciIo          Pointer to the EFI_PCI_IO_PROTOCOL instance
2026   @param[in] IdeRegisters   Pointer to EFI_IDE_REGISTERS which is used to
2027                             store the IDE i/o port registers' base addresses
2028   @param[in] Channel        The channel number of device.
2029   @param[in] Device         The device number of device.
2030   @param[in] Packet         A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
2031 
2032   @retval EFI_SUCCESS       send out the ATAPI packet command successfully
2033                             and device sends data successfully.
2034   @retval EFI_DEVICE_ERROR  the device failed to send data.
2035 
2036 **/
2037 EFI_STATUS
2038 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)2039 AtaPacketCommandExecute (
2040   IN  EFI_PCI_IO_PROTOCOL                           *PciIo,
2041   IN  EFI_IDE_REGISTERS                             *IdeRegisters,
2042   IN  UINT8                                         Channel,
2043   IN  UINT8                                         Device,
2044   IN  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
2045   )
2046 {
2047   EFI_ATA_COMMAND_BLOCK       AtaCommandBlock;
2048   EFI_STATUS                  Status;
2049   UINT8                       Count;
2050   UINT8                       PacketCommand[12];
2051 
2052   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2053 
2054   //
2055   // Fill ATAPI Command Packet according to CDB.
2056   // For Atapi cmd, its length should be less than or equal to 12 bytes.
2057   //
2058   if (Packet->CdbLength > 12) {
2059     return EFI_INVALID_PARAMETER;
2060   }
2061 
2062   ZeroMem (PacketCommand, 12);
2063   CopyMem (PacketCommand, Packet->Cdb, Packet->CdbLength);
2064 
2065   //
2066   // No OVL; No DMA
2067   //
2068   AtaCommandBlock.AtaFeatures = 0x00;
2069   //
2070   // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
2071   // determine how many data should be transferred.
2072   //
2073   AtaCommandBlock.AtaCylinderLow  = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff);
2074   AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8);
2075   AtaCommandBlock.AtaDeviceHead   = (UINT8) (Device << 0x4);
2076   AtaCommandBlock.AtaCommand      = ATA_CMD_PACKET;
2077 
2078   IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | (Device << 0x4)));
2079   //
2080   //  Disable interrupt
2081   //
2082   IdeWritePortB (PciIo, IdeRegisters->AltOrDev, ATA_DEFAULT_CTL);
2083 
2084   //
2085   // Issue ATA PACKET command firstly
2086   //
2087   Status = AtaIssueCommand (PciIo, IdeRegisters, &AtaCommandBlock, Packet->Timeout);
2088   if (EFI_ERROR (Status)) {
2089     return Status;
2090   }
2091 
2092   Status = DRQReady (PciIo, IdeRegisters, Packet->Timeout);
2093   if (EFI_ERROR (Status)) {
2094     return Status;
2095   }
2096 
2097   //
2098   // Send out ATAPI command packet
2099   //
2100   for (Count = 0; Count < 6; Count++) {
2101     IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16*)PacketCommand + Count));
2102     //
2103     // Stall for 10 microseconds.
2104     //
2105     MicroSecondDelay (10);
2106   }
2107 
2108   //
2109   // Read/Write the data of ATAPI Command
2110   //
2111   if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
2112     Status = AtaPacketReadWrite (
2113                PciIo,
2114                IdeRegisters,
2115                Packet->InDataBuffer,
2116                Packet->InTransferLength,
2117                TRUE,
2118                Packet->Timeout
2119                );
2120   } else {
2121     Status = AtaPacketReadWrite (
2122                PciIo,
2123                IdeRegisters,
2124                Packet->OutDataBuffer,
2125                Packet->OutTransferLength,
2126                FALSE,
2127                Packet->Timeout
2128                );
2129   }
2130 
2131   return Status;
2132 }
2133 
2134 
2135 /**
2136   Set the calculated Best transfer mode to a detected device.
2137 
2138   @param Instance               A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2139   @param Channel                The channel number of device.
2140   @param Device                 The device number of device.
2141   @param TransferMode           A pointer to EFI_ATA_TRANSFER_MODE data structure.
2142   @param AtaStatusBlock         A pointer to EFI_ATA_STATUS_BLOCK data structure.
2143 
2144   @retval EFI_SUCCESS          Set transfer mode successfully.
2145   @retval EFI_DEVICE_ERROR     Set transfer mode failed.
2146   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2147 
2148 **/
2149 EFI_STATUS
2150 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)2151 SetDeviceTransferMode (
2152   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2153   IN     UINT8                         Channel,
2154   IN     UINT8                         Device,
2155   IN     EFI_ATA_TRANSFER_MODE         *TransferMode,
2156   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
2157   )
2158 {
2159   EFI_STATUS              Status;
2160   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
2161 
2162   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2163 
2164   AtaCommandBlock.AtaCommand     = ATA_CMD_SET_FEATURES;
2165   AtaCommandBlock.AtaDeviceHead  = (UINT8)(Device << 0x4);
2166   AtaCommandBlock.AtaFeatures    = 0x03;
2167   AtaCommandBlock.AtaSectorCount = *((UINT8 *)TransferMode);
2168 
2169   //
2170   // Send SET FEATURE command (sub command 0x03) to set pio mode.
2171   //
2172   Status = AtaNonDataCommandIn (
2173              Instance->PciIo,
2174              &Instance->IdeRegisters[Channel],
2175              &AtaCommandBlock,
2176              AtaStatusBlock,
2177              ATA_ATAPI_TIMEOUT,
2178              NULL
2179              );
2180 
2181   return Status;
2182 }
2183 
2184 /**
2185   Set drive parameters for devices not support PACKETS command.
2186 
2187   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2188   @param Channel          The channel number of device.
2189   @param Device           The device number of device.
2190   @param DriveParameters  A pointer to EFI_ATA_DRIVE_PARMS data structure.
2191   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
2192 
2193   @retval EFI_SUCCESS          Set drive parameter successfully.
2194   @retval EFI_DEVICE_ERROR     Set drive parameter failed.
2195   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2196 
2197 **/
2198 EFI_STATUS
2199 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)2200 SetDriveParameters (
2201   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2202   IN     UINT8                         Channel,
2203   IN     UINT8                         Device,
2204   IN     EFI_ATA_DRIVE_PARMS           *DriveParameters,
2205   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
2206   )
2207 {
2208   EFI_STATUS              Status;
2209   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
2210 
2211   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2212 
2213   AtaCommandBlock.AtaCommand     = ATA_CMD_INIT_DRIVE_PARAM;
2214   AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;
2215   AtaCommandBlock.AtaDeviceHead  = (UINT8) ((Device << 0x4) + DriveParameters->Heads);
2216 
2217   //
2218   // Send Init drive parameters
2219   //
2220   Status = AtaNonDataCommandIn (
2221              Instance->PciIo,
2222              &Instance->IdeRegisters[Channel],
2223              &AtaCommandBlock,
2224              AtaStatusBlock,
2225              ATA_ATAPI_TIMEOUT,
2226              NULL
2227              );
2228 
2229   //
2230   // Send Set Multiple parameters
2231   //
2232   AtaCommandBlock.AtaCommand     = ATA_CMD_SET_MULTIPLE_MODE;
2233   AtaCommandBlock.AtaSectorCount = DriveParameters->MultipleSector;
2234   AtaCommandBlock.AtaDeviceHead  = (UINT8)(Device << 0x4);
2235 
2236   Status = AtaNonDataCommandIn (
2237              Instance->PciIo,
2238              &Instance->IdeRegisters[Channel],
2239              &AtaCommandBlock,
2240              AtaStatusBlock,
2241              ATA_ATAPI_TIMEOUT,
2242              NULL
2243              );
2244 
2245   return Status;
2246 }
2247 
2248 /**
2249   Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2250 
2251   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2252   @param Channel          The channel number of device.
2253   @param Device           The device number of device.
2254   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
2255 
2256   @retval EFI_SUCCESS     Successfully get the return status of S.M.A.R.T command execution.
2257   @retval Others          Fail to get return status data.
2258 
2259 **/
2260 EFI_STATUS
2261 EFIAPI
IdeAtaSmartReturnStatusCheck(IN ATA_ATAPI_PASS_THRU_INSTANCE * Instance,IN UINT8 Channel,IN UINT8 Device,IN OUT EFI_ATA_STATUS_BLOCK * AtaStatusBlock)2262 IdeAtaSmartReturnStatusCheck (
2263   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2264   IN     UINT8                         Channel,
2265   IN     UINT8                         Device,
2266   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
2267   )
2268 {
2269   EFI_STATUS              Status;
2270   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
2271   UINT8                   LBAMid;
2272   UINT8                   LBAHigh;
2273 
2274   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2275 
2276   AtaCommandBlock.AtaCommand      = ATA_CMD_SMART;
2277   AtaCommandBlock.AtaFeatures     = ATA_SMART_RETURN_STATUS;
2278   AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;
2279   AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2280   AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);
2281 
2282   //
2283   // Send S.M.A.R.T Read Return Status command to device
2284   //
2285   Status = AtaNonDataCommandIn (
2286              Instance->PciIo,
2287              &Instance->IdeRegisters[Channel],
2288              &AtaCommandBlock,
2289              AtaStatusBlock,
2290              ATA_ATAPI_TIMEOUT,
2291              NULL
2292              );
2293 
2294   if (EFI_ERROR (Status)) {
2295     REPORT_STATUS_CODE (
2296       EFI_ERROR_CODE | EFI_ERROR_MINOR,
2297       (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
2298       );
2299     return EFI_DEVICE_ERROR;
2300   }
2301 
2302   REPORT_STATUS_CODE (
2303     EFI_PROGRESS_CODE,
2304     (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
2305     );
2306 
2307   LBAMid  = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderLsb);
2308   LBAHigh = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderMsb);
2309 
2310   if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
2311     //
2312     // The threshold exceeded condition is not detected by the device
2313     //
2314     DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2315     REPORT_STATUS_CODE (
2316           EFI_PROGRESS_CODE,
2317           (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
2318           );
2319   } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
2320     //
2321     // The threshold exceeded condition is detected by the device
2322     //
2323     DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2324     REPORT_STATUS_CODE (
2325          EFI_PROGRESS_CODE,
2326          (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
2327          );
2328   }
2329 
2330   return EFI_SUCCESS;
2331 }
2332 
2333 /**
2334   Enable SMART command of the disk if supported.
2335 
2336   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2337   @param Channel          The channel number of device.
2338   @param Device           The device number of device.
2339   @param IdentifyData     A pointer to data buffer which is used to contain IDENTIFY data.
2340   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
2341 
2342 **/
2343 VOID
2344 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)2345 IdeAtaSmartSupport (
2346   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2347   IN     UINT8                         Channel,
2348   IN     UINT8                         Device,
2349   IN     EFI_IDENTIFY_DATA             *IdentifyData,
2350   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
2351   )
2352 {
2353   EFI_STATUS              Status;
2354   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
2355 
2356   //
2357   // Detect if the device supports S.M.A.R.T.
2358   //
2359   if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
2360     //
2361     // S.M.A.R.T is not supported by the device
2362     //
2363     DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2364             (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));
2365     REPORT_STATUS_CODE (
2366       EFI_ERROR_CODE | EFI_ERROR_MINOR,
2367       (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
2368       );
2369   } else {
2370     //
2371     // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2372     //
2373     if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
2374 
2375       REPORT_STATUS_CODE (
2376         EFI_PROGRESS_CODE,
2377         (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
2378         );
2379 
2380       ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2381 
2382       AtaCommandBlock.AtaCommand      = ATA_CMD_SMART;
2383       AtaCommandBlock.AtaFeatures     = ATA_SMART_ENABLE_OPERATION;
2384       AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;
2385       AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2386       AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);
2387 
2388       //
2389       // Send S.M.A.R.T Enable command to device
2390       //
2391       Status = AtaNonDataCommandIn (
2392                  Instance->PciIo,
2393                  &Instance->IdeRegisters[Channel],
2394                  &AtaCommandBlock,
2395                  AtaStatusBlock,
2396                  ATA_ATAPI_TIMEOUT,
2397                  NULL
2398                  );
2399 
2400       if (!EFI_ERROR (Status)) {
2401         //
2402         // Send S.M.A.R.T AutoSave command to device
2403         //
2404         ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2405 
2406         AtaCommandBlock.AtaCommand      = ATA_CMD_SMART;
2407         AtaCommandBlock.AtaFeatures     = 0xD2;
2408         AtaCommandBlock.AtaSectorCount  = 0xF1;
2409         AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;
2410         AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
2411         AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);
2412 
2413         Status = AtaNonDataCommandIn (
2414                    Instance->PciIo,
2415                    &Instance->IdeRegisters[Channel],
2416                    &AtaCommandBlock,
2417                    AtaStatusBlock,
2418                    ATA_ATAPI_TIMEOUT,
2419                    NULL
2420                    );
2421         if (!EFI_ERROR (Status)) {
2422           Status = IdeAtaSmartReturnStatusCheck (
2423                      Instance,
2424                      Channel,
2425                      Device,
2426                      AtaStatusBlock
2427                      );
2428         }
2429       }
2430     }
2431 
2432     DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2433            (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));
2434 
2435   }
2436 
2437   return ;
2438 }
2439 
2440 
2441 /**
2442   Sends out an ATA Identify Command to the specified device.
2443 
2444   This function is called by DiscoverIdeDevice() during its device
2445   identification. It sends out the ATA Identify Command to the
2446   specified device. Only ATA device responses to this command. If
2447   the command succeeds, it returns the Identify data structure which
2448   contains information about the device. This function extracts the
2449   information it needs to fill the IDE_BLK_IO_DEV data structure,
2450   including device type, media block size, media capacity, and etc.
2451 
2452   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2453   @param Channel          The channel number of device.
2454   @param Device           The device number of device.
2455   @param Buffer           A pointer to data buffer which is used to contain IDENTIFY data.
2456   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
2457 
2458   @retval EFI_SUCCESS          Identify ATA device successfully.
2459   @retval EFI_DEVICE_ERROR     ATA Identify Device Command failed or device is not ATA device.
2460   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2461 
2462 **/
2463 EFI_STATUS
2464 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)2465 AtaIdentify (
2466   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2467   IN     UINT8                         Channel,
2468   IN     UINT8                         Device,
2469   IN OUT EFI_IDENTIFY_DATA             *Buffer,
2470   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
2471   )
2472 {
2473   EFI_STATUS             Status;
2474   EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;
2475 
2476   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2477 
2478   AtaCommandBlock.AtaCommand    = ATA_CMD_IDENTIFY_DRIVE;
2479   AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2480 
2481   Status = AtaPioDataInOut (
2482              Instance->PciIo,
2483              &Instance->IdeRegisters[Channel],
2484              Buffer,
2485              sizeof (EFI_IDENTIFY_DATA),
2486              TRUE,
2487              &AtaCommandBlock,
2488              AtaStatusBlock,
2489              ATA_ATAPI_TIMEOUT,
2490              NULL
2491              );
2492 
2493   return Status;
2494 }
2495 
2496 /**
2497   This function is called by DiscoverIdeDevice() during its device
2498   identification.
2499   Its main purpose is to get enough information for the device media
2500   to fill in the Media data structure of the Block I/O Protocol interface.
2501 
2502   There are 5 steps to reach such objective:
2503   1. Sends out the ATAPI Identify Command to the specified device.
2504   Only ATAPI device responses to this command. If the command succeeds,
2505   it returns the Identify data structure which filled with information
2506   about the device. Since the ATAPI device contains removable media,
2507   the only meaningful information is the device module name.
2508   2. Sends out ATAPI Inquiry Packet Command to the specified device.
2509   This command will return inquiry data of the device, which contains
2510   the device type information.
2511   3. Allocate sense data space for future use. We don't detect the media
2512   presence here to improvement boot performance, especially when CD
2513   media is present. The media detection will be performed just before
2514   each BLK_IO read/write
2515 
2516   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2517   @param Channel          The channel number of device.
2518   @param Device           The device number of device.
2519   @param Buffer           A pointer to data buffer which is used to contain IDENTIFY data.
2520   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
2521 
2522   @retval EFI_SUCCESS          Identify ATAPI device successfully.
2523   @retval EFI_DEVICE_ERROR     ATA Identify Packet Device Command failed or device type
2524                                is not supported by this IDE driver.
2525   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2526 
2527 **/
2528 EFI_STATUS
2529 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)2530 AtaIdentifyPacket (
2531   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2532   IN     UINT8                         Channel,
2533   IN     UINT8                         Device,
2534   IN OUT EFI_IDENTIFY_DATA             *Buffer,
2535   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
2536   )
2537 {
2538   EFI_STATUS             Status;
2539   EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;
2540 
2541   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2542 
2543   AtaCommandBlock.AtaCommand    = ATA_CMD_IDENTIFY_DEVICE;
2544   AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2545 
2546   //
2547   // Send ATAPI Identify Command to get IDENTIFY data.
2548   //
2549   Status = AtaPioDataInOut (
2550              Instance->PciIo,
2551              &Instance->IdeRegisters[Channel],
2552              (VOID *) Buffer,
2553              sizeof (EFI_IDENTIFY_DATA),
2554              TRUE,
2555              &AtaCommandBlock,
2556              AtaStatusBlock,
2557              ATA_ATAPI_TIMEOUT,
2558              NULL
2559              );
2560 
2561   return Status;
2562 }
2563 
2564 
2565 /**
2566   This function is used for detect whether the IDE device exists in the
2567   specified Channel as the specified Device Number.
2568 
2569   There is two IDE channels: one is Primary Channel, the other is
2570   Secondary Channel.(Channel is the logical name for the physical "Cable".)
2571   Different channel has different register group.
2572 
2573   On each IDE channel, at most two IDE devices attach,
2574   one is called Device 0 (Master device), the other is called Device 1
2575   (Slave device). The devices on the same channel co-use the same register
2576   group, so before sending out a command for a specified device via command
2577   register, it is a must to select the current device to accept the command
2578   by set the device number in the Head/Device Register.
2579 
2580   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2581   @param IdeChannel       The channel number of device.
2582 
2583   @retval EFI_SUCCESS successfully detects device.
2584   @retval other       any failure during detection process will return this value.
2585 
2586 **/
2587 EFI_STATUS
2588 EFIAPI
DetectAndConfigIdeDevice(IN ATA_ATAPI_PASS_THRU_INSTANCE * Instance,IN UINT8 IdeChannel)2589 DetectAndConfigIdeDevice (
2590   IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
2591   IN  UINT8                         IdeChannel
2592   )
2593 {
2594   EFI_STATUS                        Status;
2595   UINT8                             SectorCountReg;
2596   UINT8                             LBALowReg;
2597   UINT8                             LBAMidReg;
2598   UINT8                             LBAHighReg;
2599   EFI_ATA_DEVICE_TYPE               DeviceType;
2600   UINT8                             IdeDevice;
2601   EFI_IDE_REGISTERS                 *IdeRegisters;
2602   EFI_IDENTIFY_DATA                 Buffer;
2603 
2604   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
2605   EFI_PCI_IO_PROTOCOL               *PciIo;
2606 
2607   EFI_ATA_COLLECTIVE_MODE           *SupportedModes;
2608   EFI_ATA_TRANSFER_MODE             TransferMode;
2609   EFI_ATA_DRIVE_PARMS               DriveParameters;
2610 
2611   IdeRegisters = &Instance->IdeRegisters[IdeChannel];
2612   IdeInit      = Instance->IdeControllerInit;
2613   PciIo        = Instance->PciIo;
2614 
2615   for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
2616     //
2617     // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2618     //
2619     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2620 
2621     //
2622     // Send ATA Device Execut Diagnostic command.
2623     // This command should work no matter DRDY is ready or not
2624     //
2625     IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG);
2626 
2627     Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000);
2628     if (EFI_ERROR (Status)) {
2629       DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));
2630       continue;
2631     }
2632 
2633     //
2634     // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2635     //
2636     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2637     //
2638     // Stall for 1 milliseconds.
2639     //
2640     MicroSecondDelay (1000);
2641 
2642     SectorCountReg = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
2643     LBALowReg      = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
2644     LBAMidReg      = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
2645     LBAHighReg     = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
2646 
2647     //
2648     // Refer to ATA/ATAPI 4 Spec, section 9.1
2649     //
2650     if ((SectorCountReg == 0x1) && (LBALowReg == 0x1) && (LBAMidReg == 0x0) && (LBAHighReg == 0x0)) {
2651       DeviceType = EfiIdeHarddisk;
2652     } else if ((LBAMidReg == 0x14) && (LBAHighReg == 0xeb)) {
2653       DeviceType = EfiIdeCdrom;
2654     } else {
2655       continue;
2656     }
2657 
2658     //
2659     // Send IDENTIFY cmd to the device to test if it is really attached.
2660     //
2661     if (DeviceType == EfiIdeHarddisk) {
2662       Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2663       //
2664       // if identifying ata device is failure, then try to send identify packet cmd.
2665       //
2666       if (EFI_ERROR (Status)) {
2667         REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
2668 
2669         DeviceType = EfiIdeCdrom;
2670         Status     = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2671       }
2672     } else {
2673       Status = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2674       //
2675       // if identifying atapi device is failure, then try to send identify cmd.
2676       //
2677       if (EFI_ERROR (Status)) {
2678         DeviceType = EfiIdeHarddisk;
2679         Status     = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
2680       }
2681     }
2682 
2683     if (EFI_ERROR (Status)) {
2684       //
2685       // No device is found at this port
2686       //
2687       continue;
2688     }
2689 
2690     DEBUG ((EFI_D_INFO, "[%a] channel [%a] [%a] device\n",
2691             (IdeChannel == 1) ? "secondary" : "primary  ", (IdeDevice == 1) ? "slave " : "master",
2692             DeviceType == EfiIdeCdrom ? "cdrom   " : "harddisk"));
2693     //
2694     // If the device is a hard disk, then try to enable S.M.A.R.T feature
2695     //
2696     if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
2697       IdeAtaSmartSupport (
2698         Instance,
2699         IdeChannel,
2700         IdeDevice,
2701         &Buffer,
2702         NULL
2703         );
2704     }
2705 
2706     //
2707     // Submit identify data to IDE controller init driver
2708     //
2709     IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &Buffer);
2710 
2711     //
2712     // Now start to config ide device parameter and transfer mode.
2713     //
2714     Status = IdeInit->CalculateMode (
2715                         IdeInit,
2716                         IdeChannel,
2717                         IdeDevice,
2718                         &SupportedModes
2719                         );
2720     if (EFI_ERROR (Status)) {
2721       DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
2722       continue;
2723     }
2724 
2725     //
2726     // Set best supported PIO mode on this IDE device
2727     //
2728     if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
2729       TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2730     } else {
2731       TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2732     }
2733 
2734     TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
2735 
2736     if (SupportedModes->ExtModeCount == 0){
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 supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2747     // be set together. Only one DMA mode can be set to a device. If setting
2748     // DMA mode operation fails, we can continue moving on because we only use
2749     // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2750     //
2751     if (SupportedModes->UdmaMode.Valid) {
2752       TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2753       TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);
2754       Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2755 
2756       if (EFI_ERROR (Status)) {
2757         DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2758         continue;
2759       }
2760     } else if (SupportedModes->MultiWordDmaMode.Valid) {
2761       TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2762       TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
2763       Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
2764 
2765       if (EFI_ERROR (Status)) {
2766         DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2767         continue;
2768       }
2769     }
2770 
2771     //
2772     // Set Parameters for the device:
2773     // 1) Init
2774     // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2775     //
2776     if (DeviceType == EfiIdeHarddisk) {
2777       //
2778       // Init driver parameters
2779       //
2780       DriveParameters.Sector         = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;
2781       DriveParameters.Heads          = (UINT8) (((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);
2782       DriveParameters.MultipleSector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;
2783 
2784       Status = SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);
2785     }
2786 
2787     //
2788     // Set IDE controller Timing Blocks in the PCI Configuration Space
2789     //
2790     IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
2791 
2792     //
2793     // IDE controller and IDE device timing is configured successfully.
2794     // Now insert the device into device list.
2795     //
2796     Status = CreateNewDeviceInfo (Instance, IdeChannel, IdeDevice, DeviceType, &Buffer);
2797     if (EFI_ERROR (Status)) {
2798       continue;
2799     }
2800 
2801     if (DeviceType == EfiIdeHarddisk) {
2802       REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
2803     }
2804   }
2805   return EFI_SUCCESS;
2806 }
2807 
2808 
2809 /**
2810   Initialize ATA host controller at IDE mode.
2811 
2812   The function is designed to initialize ATA host controller.
2813 
2814   @param[in]  Instance          A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2815 
2816 **/
2817 EFI_STATUS
2818 EFIAPI
IdeModeInitialization(IN ATA_ATAPI_PASS_THRU_INSTANCE * Instance)2819 IdeModeInitialization (
2820   IN  ATA_ATAPI_PASS_THRU_INSTANCE    *Instance
2821   )
2822 {
2823   EFI_STATUS                        Status;
2824   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
2825   EFI_PCI_IO_PROTOCOL               *PciIo;
2826   UINT8                             Channel;
2827   UINT8                             IdeChannel;
2828   BOOLEAN                           ChannelEnabled;
2829   UINT8                             MaxDevices;
2830 
2831   IdeInit = Instance->IdeControllerInit;
2832   PciIo   = Instance->PciIo;
2833   Channel = IdeInit->ChannelCount;
2834 
2835   //
2836   // Obtain IDE IO port registers' base addresses
2837   //
2838   Status = GetIdeRegisterIoAddr (PciIo, Instance->IdeRegisters);
2839   if (EFI_ERROR (Status)) {
2840     goto ErrorExit;
2841   }
2842 
2843   for (IdeChannel = 0; IdeChannel < Channel; IdeChannel++) {
2844     IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
2845 
2846     //
2847     // now obtain channel information fron IdeControllerInit protocol.
2848     //
2849     Status = IdeInit->GetChannelInfo (
2850                         IdeInit,
2851                         IdeChannel,
2852                         &ChannelEnabled,
2853                         &MaxDevices
2854                         );
2855     if (EFI_ERROR (Status)) {
2856       DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
2857       continue;
2858     }
2859 
2860     if (!ChannelEnabled) {
2861       continue;
2862     }
2863 
2864     ASSERT (MaxDevices <= 2);
2865     //
2866     // Now inform the IDE Controller Init Module.
2867     //
2868     IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
2869 
2870     //
2871     // No reset channel function implemented.
2872     //
2873     IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
2874 
2875     //
2876     // Now inform the IDE Controller Init Module.
2877     //
2878     IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, IdeChannel);
2879 
2880     //
2881     // Detect all attached ATA devices and set the transfer mode for each device.
2882     //
2883     DetectAndConfigIdeDevice (Instance, IdeChannel);
2884   }
2885 
2886   //
2887   // All configurations done! Notify IdeController to do post initialization
2888   // work such as saving IDE controller PCI settings for S3 resume
2889   //
2890   IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
2891 
2892 ErrorExit:
2893   return Status;
2894 }
2895 
2896