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