1 /** @file
2 Private Include file for IdeBus PEIM.
3 
4 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
5 
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution.  The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11 
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #ifndef _RECOVERY_ATAPI_H_
18 #define _RECOVERY_ATAPI_H_
19 
20 #include <PiPei.h>
21 
22 #include <Ppi/BlockIo.h>
23 #include <Ppi/BlockIo2.h>
24 #include <Ppi/AtaController.h>
25 
26 #include <Library/DebugLib.h>
27 #include <Library/TimerLib.h>
28 #include <Library/PeimEntryPoint.h>
29 #include <Library/PeiServicesLib.h>
30 #include <Library/BaseMemoryLib.h>
31 #include <Library/IoLib.h>
32 #include <Library/PeiServicesTablePointerLib.h>
33 #include <Library/MemoryAllocationLib.h>
34 #include <Library/PcdLib.h>
35 
36 
37 #include <IndustryStandard/Atapi.h>
38 
39 #define MAX_SENSE_KEY_COUNT 6
40 #define MAX_IDE_CHANNELS    4  // Ide and Sata Primary, Secondary Channel.
41 #define MAX_IDE_DEVICES     8  // Ide, Sata Primary, Secondary and Master, Slave device.
42 
43 typedef enum {
44   IdePrimary    = 0,
45   IdeSecondary  = 1,
46   IdeMaxChannel = 2
47 } EFI_IDE_CHANNEL;
48 
49 typedef enum {
50   IdeMaster     = 0,
51   IdeSlave      = 1,
52   IdeMaxDevice  = 2
53 } EFI_IDE_DEVICE;
54 
55 //
56 // IDE Registers
57 //
58 typedef union {
59   UINT16  Command;        /* when write */
60   UINT16  Status;         /* when read */
61 } IDE_CMD_OR_STATUS;
62 
63 typedef union {
64   UINT16  Error;          /* when read */
65   UINT16  Feature;        /* when write */
66 } IDE_ERROR_OR_FEATURE;
67 
68 typedef union {
69   UINT16  AltStatus;      /* when read */
70   UINT16  DeviceControl;  /* when write */
71 } IDE_ALTSTATUS_OR_DEVICECONTROL;
72 
73 //
74 // IDE registers set
75 //
76 typedef struct {
77   UINT16                          Data;
78   IDE_ERROR_OR_FEATURE            Reg1;
79   UINT16                          SectorCount;
80   UINT16                          SectorNumber;
81   UINT16                          CylinderLsb;
82   UINT16                          CylinderMsb;
83   UINT16                          Head;
84   IDE_CMD_OR_STATUS               Reg;
85 
86   IDE_ALTSTATUS_OR_DEVICECONTROL  Alt;
87   UINT16                          DriveAddress;
88 } IDE_BASE_REGISTERS;
89 
90 typedef struct {
91 
92   UINTN                   DevicePosition;
93   EFI_PEI_BLOCK_IO_MEDIA  MediaInfo;
94   EFI_PEI_BLOCK_IO2_MEDIA MediaInfo2;
95 
96 } PEI_ATAPI_DEVICE_INFO;
97 
98 #define ATAPI_BLK_IO_DEV_SIGNATURE  SIGNATURE_32 ('a', 'b', 'i', 'o')
99 typedef struct {
100   UINTN                           Signature;
101 
102   EFI_PEI_RECOVERY_BLOCK_IO_PPI   AtapiBlkIo;
103   EFI_PEI_RECOVERY_BLOCK_IO2_PPI  AtapiBlkIo2;
104   EFI_PEI_PPI_DESCRIPTOR          PpiDescriptor;
105   EFI_PEI_PPI_DESCRIPTOR          PpiDescriptor2;
106   PEI_ATA_CONTROLLER_PPI          *AtaControllerPpi;
107 
108   UINTN                           DeviceCount;
109   PEI_ATAPI_DEVICE_INFO           DeviceInfo[MAX_IDE_DEVICES];   //for max 8 device
110   IDE_BASE_REGISTERS              IdeIoPortReg[MAX_IDE_CHANNELS]; //for max 4 channel.
111 } ATAPI_BLK_IO_DEV;
112 
113 #define PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS(a) CR (a, ATAPI_BLK_IO_DEV, AtapiBlkIo, ATAPI_BLK_IO_DEV_SIGNATURE)
114 #define PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS(a) CR (a, ATAPI_BLK_IO_DEV, AtapiBlkIo2, ATAPI_BLK_IO_DEV_SIGNATURE)
115 
116 
117 #define STALL_1_MILLI_SECOND  1000  // stall 1 ms
118 #define STALL_1_SECONDS       1000 * STALL_1_MILLI_SECOND
119 
120 //
121 // Time Out Value For IDE Device Polling
122 //
123 // ATATIMEOUT is used for waiting time out for ATA device
124 //
125 #define ATATIMEOUT  1000  // 1 second
126 // ATAPITIMEOUT is used for waiting operation
127 // except read and write time out for ATAPI device
128 //
129 #define ATAPITIMEOUT  1000  // 1 second
130 // ATAPILONGTIMEOUT is used for waiting read and
131 // write operation timeout for ATAPI device
132 //
133 #define CDROMLONGTIMEOUT  2000  // 2 seconds
134 #define ATAPILONGTIMEOUT  5000  // 5 seconds
135 
136 //
137 // PEI Recovery Block I/O PPI
138 //
139 
140 /**
141   Gets the count of block I/O devices that one specific block driver detects.
142 
143   This function is used for getting the count of block I/O devices that one
144   specific block driver detects.  To the PEI ATAPI driver, it returns the number
145   of all the detected ATAPI devices it detects during the enumeration process.
146   To the PEI legacy floppy driver, it returns the number of all the legacy
147   devices it finds during its enumeration process. If no device is detected,
148   then the function will return zero.
149 
150   @param[in]  PeiServices          General-purpose services that are available
151                                    to every PEIM.
152   @param[in]  This                 Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
153                                    instance.
154   @param[out] NumberBlockDevices   The number of block I/O devices discovered.
155 
156   @retval     EFI_SUCCESS          Operation performed successfully.
157 
158 **/
159 EFI_STATUS
160 EFIAPI
161 AtapiGetNumberOfBlockDevices (
162   IN   EFI_PEI_SERVICES                  **PeiServices,
163   IN   EFI_PEI_RECOVERY_BLOCK_IO_PPI     *This,
164   OUT  UINTN                             *NumberBlockDevices
165   );
166 
167 /**
168   Gets a block device's media information.
169 
170   This function will provide the caller with the specified block device's media
171   information. If the media changes, calling this function will update the media
172   information accordingly.
173 
174   @param[in]  PeiServices   General-purpose services that are available to every
175                             PEIM
176   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
177   @param[in]  DeviceIndex   Specifies the block device to which the function wants
178                             to talk. Because the driver that implements Block I/O
179                             PPIs will manage multiple block devices, the PPIs that
180                             want to talk to a single device must specify the
181                             device index that was assigned during the enumeration
182                             process. This index is a number from one to
183                             NumberBlockDevices.
184   @param[out] MediaInfo     The media information of the specified block media.
185                             The caller is responsible for the ownership of this
186                             data structure.
187 
188   @retval EFI_SUCCESS           Media information about the specified block device
189                                 was obtained successfully.
190   @retval EFI_DEVICE_ERROR      Cannot get the media information due to a hardware
191                                 error.
192   @retval Others                Other failure occurs.
193 
194 **/
195 EFI_STATUS
196 EFIAPI
197 AtapiGetBlockDeviceMediaInfo (
198   IN   EFI_PEI_SERVICES                     **PeiServices,
199   IN   EFI_PEI_RECOVERY_BLOCK_IO_PPI        *This,
200   IN   UINTN                                DeviceIndex,
201   OUT  EFI_PEI_BLOCK_IO_MEDIA               *MediaInfo
202   );
203 
204 /**
205   Reads the requested number of blocks from the specified block device.
206 
207   The function reads the requested number of blocks from the device. All the
208   blocks are read, or an error is returned. If there is no media in the device,
209   the function returns EFI_NO_MEDIA.
210 
211   @param[in]  PeiServices   General-purpose services that are available to
212                             every PEIM.
213   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
214   @param[in]  DeviceIndex   Specifies the block device to which the function wants
215                             to talk. Because the driver that implements Block I/O
216                             PPIs will manage multiple block devices, the PPIs that
217                             want to talk to a single device must specify the device
218                             index that was assigned during the enumeration process.
219                             This index is a number from one to NumberBlockDevices.
220   @param[in]  StartLBA      The starting logical block address (LBA) to read from
221                             on the device
222   @param[in]  BufferSize    The size of the Buffer in bytes. This number must be
223                             a multiple of the intrinsic block size of the device.
224   @param[out] Buffer        A pointer to the destination buffer for the data.
225                             The caller is responsible for the ownership of the
226                             buffer.
227 
228   @retval EFI_SUCCESS             The data was read correctly from the device.
229   @retval EFI_DEVICE_ERROR        The device reported an error while attempting
230                                   to perform the read operation.
231   @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not
232                                   valid, or the buffer is not properly aligned.
233   @retval EFI_NO_MEDIA            There is no media in the device.
234   @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of
235                                   the intrinsic block size of the device.
236 
237 **/
238 EFI_STATUS
239 EFIAPI
240 AtapiReadBlocks (
241   IN   EFI_PEI_SERVICES                  **PeiServices,
242   IN   EFI_PEI_RECOVERY_BLOCK_IO_PPI     *This,
243   IN   UINTN                             DeviceIndex,
244   IN   EFI_PEI_LBA                       StartLBA,
245   IN   UINTN                             BufferSize,
246   OUT  VOID                              *Buffer
247   );
248 
249 /**
250   Gets the count of block I/O devices that one specific block driver detects.
251 
252   This function is used for getting the count of block I/O devices that one
253   specific block driver detects.  To the PEI ATAPI driver, it returns the number
254   of all the detected ATAPI devices it detects during the enumeration process.
255   To the PEI legacy floppy driver, it returns the number of all the legacy
256   devices it finds during its enumeration process. If no device is detected,
257   then the function will return zero.
258 
259   @param[in]  PeiServices          General-purpose services that are available
260                                    to every PEIM.
261   @param[in]  This                 Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI
262                                    instance.
263   @param[out] NumberBlockDevices   The number of block I/O devices discovered.
264 
265   @retval     EFI_SUCCESS          Operation performed successfully.
266 
267 **/
268 EFI_STATUS
269 EFIAPI
270 AtapiGetNumberOfBlockDevices2 (
271   IN   EFI_PEI_SERVICES                  **PeiServices,
272   IN   EFI_PEI_RECOVERY_BLOCK_IO2_PPI    *This,
273   OUT  UINTN                             *NumberBlockDevices
274   );
275 
276 /**
277   Gets a block device's media information.
278 
279   This function will provide the caller with the specified block device's media
280   information. If the media changes, calling this function will update the media
281   information accordingly.
282 
283   @param[in]  PeiServices   General-purpose services that are available to every
284                             PEIM
285   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
286   @param[in]  DeviceIndex   Specifies the block device to which the function wants
287                             to talk. Because the driver that implements Block I/O
288                             PPIs will manage multiple block devices, the PPIs that
289                             want to talk to a single device must specify the
290                             device index that was assigned during the enumeration
291                             process. This index is a number from one to
292                             NumberBlockDevices.
293   @param[out] MediaInfo     The media information of the specified block media.
294                             The caller is responsible for the ownership of this
295                             data structure.
296 
297   @retval EFI_SUCCESS           Media information about the specified block device
298                                 was obtained successfully.
299   @retval EFI_DEVICE_ERROR      Cannot get the media information due to a hardware
300                                 error.
301   @retval Others                Other failure occurs.
302 
303 **/
304 EFI_STATUS
305 EFIAPI
306 AtapiGetBlockDeviceMediaInfo2 (
307   IN   EFI_PEI_SERVICES                     **PeiServices,
308   IN   EFI_PEI_RECOVERY_BLOCK_IO2_PPI       *This,
309   IN   UINTN                                DeviceIndex,
310   OUT  EFI_PEI_BLOCK_IO2_MEDIA              *MediaInfo
311   );
312 
313 /**
314   Reads the requested number of blocks from the specified block device.
315 
316   The function reads the requested number of blocks from the device. All the
317   blocks are read, or an error is returned. If there is no media in the device,
318   the function returns EFI_NO_MEDIA.
319 
320   @param[in]  PeiServices   General-purpose services that are available to
321                             every PEIM.
322   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
323   @param[in]  DeviceIndex   Specifies the block device to which the function wants
324                             to talk. Because the driver that implements Block I/O
325                             PPIs will manage multiple block devices, the PPIs that
326                             want to talk to a single device must specify the device
327                             index that was assigned during the enumeration process.
328                             This index is a number from one to NumberBlockDevices.
329   @param[in]  StartLBA      The starting logical block address (LBA) to read from
330                             on the device
331   @param[in]  BufferSize    The size of the Buffer in bytes. This number must be
332                             a multiple of the intrinsic block size of the device.
333   @param[out] Buffer        A pointer to the destination buffer for the data.
334                             The caller is responsible for the ownership of the
335                             buffer.
336 
337   @retval EFI_SUCCESS             The data was read correctly from the device.
338   @retval EFI_DEVICE_ERROR        The device reported an error while attempting
339                                   to perform the read operation.
340   @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not
341                                   valid, or the buffer is not properly aligned.
342   @retval EFI_NO_MEDIA            There is no media in the device.
343   @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of
344                                   the intrinsic block size of the device.
345 
346 **/
347 EFI_STATUS
348 EFIAPI
349 AtapiReadBlocks2 (
350   IN   EFI_PEI_SERVICES                  **PeiServices,
351   IN   EFI_PEI_RECOVERY_BLOCK_IO2_PPI    *This,
352   IN   UINTN                             DeviceIndex,
353   IN   EFI_PEI_LBA                       StartLBA,
354   IN   UINTN                             BufferSize,
355   OUT  VOID                              *Buffer
356   );
357 
358 //
359 // Internal functions
360 //
361 
362 /**
363   Enumerate Atapi devices.
364 
365   This function is used to enumerate Atatpi device in Ide channel.
366 
367   @param[in]  AtapiBlkIoDev  A pointer to atapi block IO device
368 
369 **/
370 VOID
371 AtapiEnumerateDevices (
372   IN  ATAPI_BLK_IO_DEV  *AtapiBlkIoDev
373   );
374 
375 /**
376   Detect Atapi devices.
377 
378   @param[in]  AtapiBlkIoDev   A pointer to atapi block IO device.
379   @param[in]  DevicePosition  An integer to signify device position.
380   @param[out] MediaInfo       The media information of the specified block media.
381   @param[out] MediaInfo2      The media information 2 of the specified block media.
382 
383   @retval TRUE                Atapi device exists in specified position.
384   @retval FALSE               Atapi device does not exist in specified position.
385 
386 **/
387 BOOLEAN
388 DiscoverAtapiDevice (
389   IN  ATAPI_BLK_IO_DEV              *AtapiBlkIoDev,
390   IN  UINTN                         DevicePosition,
391   OUT EFI_PEI_BLOCK_IO_MEDIA        *MediaInfo,
392   OUT EFI_PEI_BLOCK_IO2_MEDIA       *MediaInfo2
393   );
394 
395 /**
396   Detect if an IDE controller exists in specified position.
397 
398   @param[in]  AtapiBlkIoDev   A pointer to atapi block IO device.
399   @param[in]  DevicePosition  An integer to signify device position.
400 
401   @retval TRUE         The Atapi device exists.
402   @retval FALSE        The Atapi device does not present.
403 
404 **/
405 BOOLEAN
406 DetectIDEController (
407   IN  ATAPI_BLK_IO_DEV   *AtapiBlkIoDev,
408   IN  UINTN              DevicePosition
409   );
410 
411 /**
412   Wait specified time interval to poll for BSY bit clear in the Status Register.
413 
414   @param[in]  AtapiBlkIoDev          A pointer to atapi block IO device.
415   @param[in]  IdeIoRegisters         A pointer to IDE IO registers.
416   @param[in]  TimeoutInMilliSeconds  Time specified in milliseconds.
417 
418   @retval EFI_SUCCESS        BSY bit is cleared in the specified time interval.
419   @retval EFI_TIMEOUT        BSY bit is not cleared in the specified time interval.
420 
421 **/
422 EFI_STATUS
423 WaitForBSYClear (
424   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
425   IN  IDE_BASE_REGISTERS  *IdeIoRegisters,
426   IN  UINTN               TimeoutInMilliSeconds
427   );
428 
429 /**
430   Wait specified time interval to poll for DRDY bit set in the Status register.
431 
432   @param[in]  AtapiBlkIoDev          A pointer to atapi block IO device.
433   @param[in]  IdeIoRegisters         A pointer to IDE IO registers.
434   @param[in]  TimeoutInMilliSeconds  Time specified in milliseconds.
435 
436   @retval EFI_SUCCESS        DRDY bit is set in the specified time interval.
437   @retval EFI_TIMEOUT        DRDY bit is not set in the specified time interval.
438 
439 **/
440 EFI_STATUS
441 DRDYReady (
442   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
443   IN  IDE_BASE_REGISTERS  *IdeIoRegisters,
444   IN  UINTN               TimeoutInMilliSeconds
445   );
446 
447 /**
448   Wait specified time interval to poll for DRQ bit clear in the Status Register.
449 
450   @param[in]  AtapiBlkIoDev          A pointer to atapi block IO device.
451   @param[in]  IdeIoRegisters         A pointer to IDE IO registers.
452   @param[in]  TimeoutInMilliSeconds  Time specified in milliseconds.
453 
454   @retval EFI_SUCCESS        DRQ bit is cleared in the specified time interval.
455   @retval EFI_TIMEOUT        DRQ bit is not cleared in the specified time interval.
456 
457 **/
458 EFI_STATUS
459 DRQClear (
460   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
461   IN  IDE_BASE_REGISTERS  *IdeIoRegisters,
462   IN  UINTN               TimeoutInMilliSeconds
463   );
464 
465 /**
466   Wait specified time interval to poll for DRQ bit clear in the Alternate Status Register.
467 
468   @param[in]  AtapiBlkIoDev          A pointer to atapi block IO device.
469   @param[in]  IdeIoRegisters         A pointer to IDE IO registers.
470   @param[in]  TimeoutInMilliSeconds  Time specified in milliseconds.
471 
472   @retval EFI_SUCCESS        DRQ bit is cleared in the specified time interval.
473   @retval EFI_TIMEOUT        DRQ bit is not cleared in the specified time interval.
474 
475 **/
476 EFI_STATUS
477 DRQClear2 (
478   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
479   IN  IDE_BASE_REGISTERS  *IdeIoRegisters,
480   IN  UINTN               TimeoutInMilliSeconds
481   );
482 
483 /**
484   Wait specified time interval to poll for DRQ bit set in the Status Register.
485 
486   @param[in]  AtapiBlkIoDev          A pointer to atapi block IO device.
487   @param[in]  IdeIoRegisters         A pointer to IDE IO registers.
488   @param[in]  TimeoutInMilliSeconds  Time specified in milliseconds.
489 
490   @retval EFI_SUCCESS        DRQ bit is set in the specified time interval.
491   @retval EFI_TIMEOUT        DRQ bit is not set in the specified time interval.
492   @retval EFI_ABORTED        Operation Aborted.
493 
494 **/
495 EFI_STATUS
496 DRQReady (
497   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
498   IN  IDE_BASE_REGISTERS  *IdeIoRegisters,
499   IN  UINTN               TimeoutInMilliSeconds
500   );
501 
502 /**
503   Wait specified time interval to poll for DRQ bit set in the Alternate Status Register.
504 
505   @param[in]  AtapiBlkIoDev          A pointer to atapi block IO device.
506   @param[in]  IdeIoRegisters         A pointer to IDE IO registers.
507   @param[in]  TimeoutInMilliSeconds  Time specified in milliseconds.
508 
509   @retval EFI_SUCCESS        DRQ bit is set in the specified time interval.
510   @retval EFI_TIMEOUT        DRQ bit is not set in the specified time interval.
511   @retval EFI_ABORTED        Operation Aborted.
512 
513 **/
514 EFI_STATUS
515 DRQReady2 (
516   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
517   IN  IDE_BASE_REGISTERS  *IdeIoRegisters,
518   IN  UINTN               TimeoutInMilliSeconds
519   );
520 
521 /**
522   Check if there is an error in Status Register.
523 
524   @param[in]  AtapiBlkIoDev     A pointer to atapi block IO device.
525   @param[in]  StatusReg         The address to IDE IO registers.
526 
527   @retval EFI_SUCCESS        Operation success.
528   @retval EFI_DEVICE_ERROR   Device error.
529 
530 **/
531 EFI_STATUS
532 CheckErrorStatus (
533   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
534   IN  UINT16              StatusReg
535   );
536 
537 /**
538   Idendify Atapi devices.
539 
540   @param[in]  AtapiBlkIoDev     A pointer to atapi block IO device.
541   @param[in]  DevicePosition    An integer to signify device position.
542 
543   @retval EFI_SUCCESS        Identify successfully.
544   @retval EFI_DEVICE_ERROR   Device cannot be identified successfully.
545 
546 **/
547 EFI_STATUS
548 ATAPIIdentify (
549   IN  ATAPI_BLK_IO_DEV        *AtapiBlkIoDev,
550   IN  UINTN                   DevicePosition
551   );
552 
553 /**
554   Sends out ATAPI Test Unit Ready Packet Command to the specified device
555   to find out whether device is accessible.
556 
557   @param[in]  AtapiBlkIoDev     A pointer to atapi block IO device.
558   @param[in]  DevicePosition    An integer to signify device position.
559 
560   @retval EFI_SUCCESS        TestUnit command executed successfully.
561   @retval EFI_DEVICE_ERROR   Device cannot be executed TestUnit command successfully.
562 
563 **/
564 EFI_STATUS
565 TestUnitReady (
566   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
567   IN  UINTN               DevicePosition
568   ) ;
569 
570 /**
571   Send out ATAPI commands conforms to the Packet Command with PIO Data In Protocol.
572 
573   @param[in]  AtapiBlkIoDev         A pointer to atapi block IO device.
574   @param[in]  DevicePosition        An integer to signify device position.
575   @param[in]  Packet                A pointer to ATAPI command packet.
576   @param[in]  Buffer                Buffer to contain requested transfer data from device.
577   @param[in]  ByteCount             Requested transfer data length.
578   @param[in]  TimeoutInMilliSeconds Time out value, in unit of milliseconds.
579 
580   @retval EFI_SUCCESS        Command executed successfully.
581   @retval EFI_DEVICE_ERROR   Device cannot be executed command successfully.
582 
583 **/
584 EFI_STATUS
585 AtapiPacketCommandIn (
586   IN  ATAPI_BLK_IO_DEV      *AtapiBlkIoDev,
587   IN  UINTN                 DevicePosition,
588   IN  ATAPI_PACKET_COMMAND  *Packet,
589   IN  UINT16                *Buffer,
590   IN  UINT32                ByteCount,
591   IN  UINTN                 TimeoutInMilliSeconds
592   );
593 
594 /**
595   Sends out ATAPI Inquiry Packet Command to the specified device.
596   This command will return INQUIRY data of the device.
597 
598   @param[in]  AtapiBlkIoDev   A pointer to atapi block IO device.
599   @param[in]  DevicePosition  An integer to signify device position.
600   @param[out] MediaInfo       The media information of the specified block media.
601   @param[out] MediaInfo2      The media information 2 of the specified block media.
602 
603   @retval EFI_SUCCESS        Command executed successfully.
604   @retval EFI_DEVICE_ERROR   Device cannot be executed command successfully.
605   @retval EFI_UNSUPPORTED    Unsupported device type.
606 
607 **/
608 EFI_STATUS
609 Inquiry (
610   IN  ATAPI_BLK_IO_DEV              *AtapiBlkIoDev,
611   IN  UINTN                         DevicePosition,
612   OUT EFI_PEI_BLOCK_IO_MEDIA        *MediaInfo,
613   OUT EFI_PEI_BLOCK_IO2_MEDIA       *MediaInfo2
614   );
615 
616 /**
617   Used before read/write blocks from/to ATAPI device media.
618   Since ATAPI device media is removable, it is necessary to detect
619   whether media is present and get current present media's information.
620 
621   @param[in]  AtapiBlkIoDev     A pointer to atapi block IO device.
622   @param[in]  DevicePosition    An integer to signify device position.
623   @param[in, out] MediaInfo     The media information of the specified block media.
624   @param[in, out] MediaInfo2    The media information 2 of the specified block media.
625 
626   @retval EFI_SUCCESS           Command executed successfully.
627   @retval EFI_DEVICE_ERROR      Some device errors happen.
628   @retval EFI_OUT_OF_RESOURCES  Can not allocate required resources.
629 
630 **/
631 EFI_STATUS
632 DetectMedia (
633   IN  ATAPI_BLK_IO_DEV              *AtapiBlkIoDev,
634   IN  UINTN                         DevicePosition,
635   IN OUT EFI_PEI_BLOCK_IO_MEDIA     *MediaInfo,
636   IN OUT EFI_PEI_BLOCK_IO2_MEDIA    *MediaInfo2
637   );
638 
639 /**
640   Reset specified Atapi device.
641 
642   @param[in]  AtapiBlkIoDev     A pointer to atapi block IO device.
643   @param[in]  DevicePosition    An integer to signify device position.
644   @param[in]  Extensive         If TRUE, use ATA soft reset, otherwise use Atapi soft reset.
645 
646   @retval EFI_SUCCESS           Command executed successfully.
647   @retval EFI_DEVICE_ERROR      Some device errors happen.
648 
649 **/
650 EFI_STATUS
651 ResetDevice (
652   IN  ATAPI_BLK_IO_DEV  *AtapiBlkIoDev,
653   IN  UINTN             DevicePosition,
654   IN  BOOLEAN           Extensive
655   );
656 
657 /**
658   Sends out ATAPI Request Sense Packet Command to the specified device.
659 
660   @param[in]      AtapiBlkIoDev   A pointer to atapi block IO device.
661   @param[in]      DevicePosition  An integer to signify device position.
662   @param[in]      SenseBuffers    Pointer to sense buffer.
663   @param[in, out] SenseCounts     Length of sense buffer.
664 
665   @retval EFI_SUCCESS           Command executed successfully.
666   @retval EFI_DEVICE_ERROR      Some device errors happen.
667 
668 **/
669 EFI_STATUS
670 RequestSense (
671   IN  ATAPI_BLK_IO_DEV          *AtapiBlkIoDev,
672   IN  UINTN                     DevicePosition,
673   IN  ATAPI_REQUEST_SENSE_DATA  *SenseBuffers,
674   IN OUT  UINT8                 *SenseCounts
675   );
676 
677 /**
678   Sends out ATAPI Read Capacity Packet Command to the specified device.
679   This command will return the information regarding the capacity of the
680   media in the device.
681 
682   @param[in]  AtapiBlkIoDev   A pointer to atapi block IO device.
683   @param[in]  DevicePosition  An integer to signify device position.
684   @param[in, out] MediaInfo   The media information of the specified block media.
685   @param[in, out] MediaInfo2  The media information 2 of the specified block media.
686 
687   @retval EFI_SUCCESS           Command executed successfully.
688   @retval EFI_DEVICE_ERROR      Some device errors happen.
689 
690 **/
691 EFI_STATUS
692 ReadCapacity (
693   IN  ATAPI_BLK_IO_DEV              *AtapiBlkIoDev,
694   IN  UINTN                         DevicePosition,
695   IN OUT EFI_PEI_BLOCK_IO_MEDIA     *MediaInfo,
696   IN OUT EFI_PEI_BLOCK_IO2_MEDIA    *MediaInfo2
697   );
698 
699 /**
700   Perform read from disk in block unit.
701 
702   @param[in]  AtapiBlkIoDev   A pointer to atapi block IO device.
703   @param[in]  DevicePosition  An integer to signify device position.
704   @param[in]  Buffer          Buffer to contain read data.
705   @param[in]  StartLba        Starting LBA address.
706   @param[in]  NumberOfBlocks  Number of blocks to read.
707   @param[in]  BlockSize       Size of each block.
708 
709   @retval EFI_SUCCESS           Command executed successfully.
710   @retval EFI_DEVICE_ERROR      Some device errors happen.
711 
712 **/
713 EFI_STATUS
714 ReadSectors (
715   IN  ATAPI_BLK_IO_DEV    *AtapiBlkIoDev,
716   IN  UINTN               DevicePosition,
717   IN  VOID                *Buffer,
718   IN  EFI_PEI_LBA         StartLba,
719   IN  UINTN               NumberOfBlocks,
720   IN  UINTN               BlockSize
721   );
722 
723 /**
724   Check if there is media according to sense data.
725 
726   @param[in]  SenseData   Pointer to sense data.
727   @param[in]  SenseCounts Count of sense data.
728 
729   @retval TRUE    No media
730   @retval FALSE   Media exists
731 
732 **/
733 BOOLEAN
734 IsNoMedia (
735   IN  ATAPI_REQUEST_SENSE_DATA    *SenseData,
736   IN  UINTN                 SenseCounts
737   );
738 
739 /**
740   Check if device state is unclear according to sense data.
741 
742   @param[in]  SenseData   Pointer to sense data.
743   @param[in]  SenseCounts Count of sense data.
744 
745   @retval TRUE    Device state is unclear
746   @retval FALSE   Device state is clear
747 
748 **/
749 BOOLEAN
750 IsDeviceStateUnclear (
751   IN  ATAPI_REQUEST_SENSE_DATA    *SenseData,
752   IN  UINTN                 SenseCounts
753   );
754 
755 /**
756   Check if there is media error according to sense data.
757 
758   @param[in]  SenseData   Pointer to sense data.
759   @param[in]  SenseCounts Count of sense data.
760 
761   @retval TRUE    Media error
762   @retval FALSE   No media error
763 
764 **/
765 BOOLEAN
766 IsMediaError (
767   IN  ATAPI_REQUEST_SENSE_DATA    *SenseData,
768   IN  UINTN                 SenseCounts
769   );
770 
771 /**
772   Check if drive is ready according to sense data.
773 
774   @param[in]  SenseData   Pointer to sense data.
775   @param[in]  SenseCounts Count of sense data.
776   @param[out] NeedRetry   Indicate if retry is needed.
777 
778   @retval TRUE    Drive ready
779   @retval FALSE   Drive not ready
780 
781 **/
782 BOOLEAN
783 IsDriveReady (
784   IN  ATAPI_REQUEST_SENSE_DATA    *SenseData,
785   IN  UINTN                 SenseCounts,
786   OUT BOOLEAN               *NeedRetry
787   );
788 
789 #endif
790