1 /** @file
2   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
3   This program and the accompanying materials
4   are licensed and made available under the terms and conditions of the BSD License
5   which accompanies this distribution.  The full text of the license may be found at
6   http://opensource.org/licenses/bsd-license.php
7 
8   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 
11   Module Name:  AtapiPassThru.h
12 
13 **/
14 
15 #ifndef _APT_H
16 #define _APT_H
17 
18 
19 
20 #include <Uefi.h>
21 
22 #include <Protocol/ScsiPassThru.h>
23 #include <Protocol/ScsiPassThruExt.h>
24 #include <Protocol/PciIo.h>
25 #include <Protocol/DriverSupportedEfiVersion.h>
26 
27 #include <Library/DebugLib.h>
28 #include <Library/UefiDriverEntryPoint.h>
29 #include <Library/BaseLib.h>
30 #include <Library/UefiLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/MemoryAllocationLib.h>
33 #include <Library/UefiBootServicesTableLib.h>
34 #include <Library/PcdLib.h>
35 #include <Library/DevicePathLib.h>
36 
37 #include <IndustryStandard/Pci.h>
38 
39 #define MAX_TARGET_ID 4
40 
41 //
42 // IDE Registers
43 //
44 typedef union {
45   UINT16  Command;        /* when write */
46   UINT16  Status;         /* when read */
47 } IDE_CMD_OR_STATUS;
48 
49 typedef union {
50   UINT16  Error;          /* when read */
51   UINT16  Feature;        /* when write */
52 } IDE_ERROR_OR_FEATURE;
53 
54 typedef union {
55   UINT16  AltStatus;      /* when read */
56   UINT16  DeviceControl;  /* when write */
57 } IDE_AltStatus_OR_DeviceControl;
58 
59 
60 typedef enum {
61   IdePrimary    = 0,
62   IdeSecondary  = 1,
63   IdeMaxChannel = 2
64 } EFI_IDE_CHANNEL;
65 
66 ///
67 
68 
69 //
70 // Bit definitions in Programming Interface byte of the Class Code field
71 // in PCI IDE controller's Configuration Space
72 //
73 #define IDE_PRIMARY_OPERATING_MODE            BIT0
74 #define IDE_PRIMARY_PROGRAMMABLE_INDICATOR    BIT1
75 #define IDE_SECONDARY_OPERATING_MODE          BIT2
76 #define IDE_SECONDARY_PROGRAMMABLE_INDICATOR  BIT3
77 
78 
79 #define ATAPI_MAX_CHANNEL 2
80 
81 ///
82 /// IDE registers set
83 ///
84 typedef struct {
85   UINT16                          Data;
86   IDE_ERROR_OR_FEATURE            Reg1;
87   UINT16                          SectorCount;
88   UINT16                          SectorNumber;
89   UINT16                          CylinderLsb;
90   UINT16                          CylinderMsb;
91   UINT16                          Head;
92   IDE_CMD_OR_STATUS               Reg;
93   IDE_AltStatus_OR_DeviceControl  Alt;
94   UINT16                          DriveAddress;
95 } IDE_BASE_REGISTERS;
96 
97 #define ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE  SIGNATURE_32 ('a', 's', 'p', 't')
98 
99 typedef struct {
100   UINTN                            Signature;
101   EFI_HANDLE                       Handle;
102   EFI_SCSI_PASS_THRU_PROTOCOL      ScsiPassThru;
103   EFI_EXT_SCSI_PASS_THRU_PROTOCOL  ExtScsiPassThru;
104   EFI_PCI_IO_PROTOCOL              *PciIo;
105   UINT64                           OriginalPciAttributes;
106   //
107   // Local Data goes here
108   //
109   IDE_BASE_REGISTERS               *IoPort;
110   IDE_BASE_REGISTERS               AtapiIoPortRegisters[2];
111   UINT32                           LatestTargetId;
112   UINT64                           LatestLun;
113 } ATAPI_SCSI_PASS_THRU_DEV;
114 
115 //
116 // IDE registers' base addresses
117 //
118 typedef struct {
119   UINT16  CommandBlockBaseAddr;
120   UINT16  ControlBlockBaseAddr;
121 } IDE_REGISTERS_BASE_ADDR;
122 
123 #define ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
124   CR (a, \
125       ATAPI_SCSI_PASS_THRU_DEV, \
126       ScsiPassThru, \
127       ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
128       )
129 
130 #define ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
131   CR (a, \
132       ATAPI_SCSI_PASS_THRU_DEV, \
133       ExtScsiPassThru, \
134       ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
135       )
136 
137 //
138 // Global Variables
139 //
140 extern EFI_DRIVER_BINDING_PROTOCOL                gAtapiScsiPassThruDriverBinding;
141 extern EFI_COMPONENT_NAME_PROTOCOL                gAtapiScsiPassThruComponentName;
142 extern EFI_COMPONENT_NAME2_PROTOCOL               gAtapiScsiPassThruComponentName2;
143 extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gAtapiScsiPassThruDriverSupportedEfiVersion;
144 
145 //
146 // ATAPI Command op code
147 //
148 #define OP_INQUIRY                      0x12
149 #define OP_LOAD_UNLOAD_CD               0xa6
150 #define OP_MECHANISM_STATUS             0xbd
151 #define OP_MODE_SELECT_10               0x55
152 #define OP_MODE_SENSE_10                0x5a
153 #define OP_PAUSE_RESUME                 0x4b
154 #define OP_PLAY_AUDIO_10                0x45
155 #define OP_PLAY_AUDIO_MSF               0x47
156 #define OP_PLAY_CD                      0xbc
157 #define OP_PLAY_CD_MSF                  0xb4
158 #define OP_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
159 #define OP_READ_10                      0x28
160 #define OP_READ_12                      0xa8
161 #define OP_READ_CAPACITY                0x25
162 #define OP_READ_CD                      0xbe
163 #define OP_READ_CD_MSF                  0xb9
164 #define OP_READ_HEADER                  0x44
165 #define OP_READ_SUB_CHANNEL             0x42
166 #define OP_READ_TOC                     0x43
167 #define OP_REQUEST_SENSE                0x03
168 #define OP_SCAN                         0xba
169 #define OP_SEEK_10                      0x2b
170 #define OP_SET_CD_SPEED                 0xbb
171 #define OP_STOPPLAY_SCAN                0x4e
172 #define OP_START_STOP_UNIT              0x1b
173 #define OP_TEST_UNIT_READY              0x00
174 
175 #define OP_FORMAT_UNIT                  0x04
176 #define OP_READ_FORMAT_CAPACITIES       0x23
177 #define OP_VERIFY                       0x2f
178 #define OP_WRITE_10                     0x2a
179 #define OP_WRITE_12                     0xaa
180 #define OP_WRITE_AND_VERIFY             0x2e
181 
182 //
183 // ATA Command
184 //
185 #define ATAPI_SOFT_RESET_CMD  0x08
186 
187 typedef enum {
188   DataIn  = 0,
189   DataOut = 1,
190   DataBi  = 2,
191   NoData  = 3,
192   End     = 0xff
193 } DATA_DIRECTION;
194 
195 typedef struct {
196   UINT8           OpCode;
197   DATA_DIRECTION  Direction;
198 } SCSI_COMMAND_SET;
199 
200 #define MAX_CHANNEL         2
201 
202 #define ValidCdbLength(Len) ((Len) == 6 || (Len) == 10 || (Len) == 12) ? 1 : 0
203 
204 //
205 // IDE registers bit definitions
206 //
207 // ATA Err Reg bitmap
208 //
209 #define BBK_ERR   BIT7 ///< Bad block detected
210 #define UNC_ERR   BIT6 ///< Uncorrectable Data
211 #define MC_ERR    BIT5 ///< Media Change
212 #define IDNF_ERR  BIT4 ///< ID Not Found
213 #define MCR_ERR   BIT3 ///< Media Change Requested
214 #define ABRT_ERR  BIT2 ///< Aborted Command
215 #define TK0NF_ERR BIT1 ///< Track 0 Not Found
216 #define AMNF_ERR  BIT0 ///< Address Mark Not Found
217 
218 //
219 // ATAPI Err Reg bitmap
220 //
221 #define SENSE_KEY_ERR (BIT7 | BIT6 | BIT5 | BIT4)
222 #define EOM_ERR BIT1 ///< End of Media Detected
223 #define ILI_ERR BIT0 ///< Illegal Length Indication
224 
225 //
226 // Device/Head Reg
227 //
228 #define LBA_MODE  BIT6
229 #define DEV       BIT4
230 #define HS3       BIT3
231 #define HS2       BIT2
232 #define HS1       BIT1
233 #define HS0       BIT0
234 #define CHS_MODE  (0)
235 #define DRV0      (0)
236 #define DRV1      (1)
237 #define MST_DRV   DRV0
238 #define SLV_DRV   DRV1
239 
240 //
241 // Status Reg
242 //
243 #define BSY   BIT7 ///< Controller Busy
244 #define DRDY  BIT6 ///< Drive Ready
245 #define DWF   BIT5 ///< Drive Write Fault
246 #define DSC   BIT4 ///< Disk Seek Complete
247 #define DRQ   BIT3 ///< Data Request
248 #define CORR  BIT2 ///< Corrected Data
249 #define IDX   BIT1 ///< Index
250 #define ERR   BIT0 ///< Error
251 #define CHECK BIT0 ///< Check bit for ATAPI Status Reg
252 
253 //
254 // Device Control Reg
255 //
256 #define SRST  BIT2 ///< Software Reset
257 #define IEN_L BIT1 ///< Interrupt Enable
258 
259 //
260 // ATAPI Feature Register
261 //
262 #define OVERLAP BIT1
263 #define DMA     BIT0
264 
265 //
266 // ATAPI Interrupt Reason Reson Reg (ATA Sector Count Register)
267 //
268 #define RELEASE     BIT2
269 #define IO          BIT1
270 #define CoD         BIT0
271 
272 #define PACKET_CMD  0xA0
273 
274 #define DEFAULT_CMD (0xa0)
275 //
276 // default content of device control register, disable INT
277 //
278 #define DEFAULT_CTL           (0x0a)
279 #define MAX_ATAPI_BYTE_COUNT  (0xfffe)
280 
281 //
282 // function prototype
283 //
284 
285 EFI_STATUS
286 EFIAPI
287 AtapiScsiPassThruDriverBindingSupported (
288   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
289   IN EFI_HANDLE                   Controller,
290   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
291   );
292 
293 EFI_STATUS
294 EFIAPI
295 AtapiScsiPassThruDriverBindingStart (
296   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
297   IN EFI_HANDLE                   Controller,
298   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
299   );
300 
301 EFI_STATUS
302 EFIAPI
303 AtapiScsiPassThruDriverBindingStop (
304   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
305   IN  EFI_HANDLE                      Controller,
306   IN  UINTN                           NumberOfChildren,
307   IN  EFI_HANDLE                      *ChildHandleBuffer
308   );
309 
310 //
311 // EFI Component Name Functions
312 //
313 /**
314   Retrieves a Unicode string that is the user readable name of the driver.
315 
316   This function retrieves the user readable name of a driver in the form of a
317   Unicode string. If the driver specified by This has a user readable name in
318   the language specified by Language, then a pointer to the driver name is
319   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
320   by This does not support the language specified by Language,
321   then EFI_UNSUPPORTED is returned.
322 
323   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
324                                 EFI_COMPONENT_NAME_PROTOCOL instance.
325 
326   @param  Language[in]          A pointer to a Null-terminated ASCII string
327                                 array indicating the language. This is the
328                                 language of the driver name that the caller is
329                                 requesting, and it must match one of the
330                                 languages specified in SupportedLanguages. The
331                                 number of languages supported by a driver is up
332                                 to the driver writer. Language is specified
333                                 in RFC 4646 or ISO 639-2 language code format.
334 
335   @param  DriverName[out]       A pointer to the Unicode string to return.
336                                 This Unicode string is the name of the
337                                 driver specified by This in the language
338                                 specified by Language.
339 
340   @retval EFI_SUCCESS           The Unicode string for the Driver specified by
341                                 This and the language specified by Language was
342                                 returned in DriverName.
343 
344   @retval EFI_INVALID_PARAMETER Language is NULL.
345 
346   @retval EFI_INVALID_PARAMETER DriverName is NULL.
347 
348   @retval EFI_UNSUPPORTED       The driver specified by This does not support
349                                 the language specified by Language.
350 
351 **/
352 EFI_STATUS
353 EFIAPI
354 AtapiScsiPassThruComponentNameGetDriverName (
355   IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
356   IN  CHAR8                        *Language,
357   OUT CHAR16                       **DriverName
358   );
359 
360 
361 /**
362   Retrieves a Unicode string that is the user readable name of the controller
363   that is being managed by a driver.
364 
365   This function retrieves the user readable name of the controller specified by
366   ControllerHandle and ChildHandle in the form of a Unicode string. If the
367   driver specified by This has a user readable name in the language specified by
368   Language, then a pointer to the controller name is returned in ControllerName,
369   and EFI_SUCCESS is returned.  If the driver specified by This is not currently
370   managing the controller specified by ControllerHandle and ChildHandle,
371   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
372   support the language specified by Language, then EFI_UNSUPPORTED is returned.
373 
374   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
375                                 EFI_COMPONENT_NAME_PROTOCOL instance.
376 
377   @param  ControllerHandle[in]  The handle of a controller that the driver
378                                 specified by This is managing.  This handle
379                                 specifies the controller whose name is to be
380                                 returned.
381 
382   @param  ChildHandle[in]       The handle of the child controller to retrieve
383                                 the name of.  This is an optional parameter that
384                                 may be NULL.  It will be NULL for device
385                                 drivers.  It will also be NULL for a bus drivers
386                                 that wish to retrieve the name of the bus
387                                 controller.  It will not be NULL for a bus
388                                 driver that wishes to retrieve the name of a
389                                 child controller.
390 
391   @param  Language[in]          A pointer to a Null-terminated ASCII string
392                                 array indicating the language.  This is the
393                                 language of the driver name that the caller is
394                                 requesting, and it must match one of the
395                                 languages specified in SupportedLanguages. The
396                                 number of languages supported by a driver is up
397                                 to the driver writer. Language is specified in
398                                 RFC 4646 or ISO 639-2 language code format.
399 
400   @param  ControllerName[out]   A pointer to the Unicode string to return.
401                                 This Unicode string is the name of the
402                                 controller specified by ControllerHandle and
403                                 ChildHandle in the language specified by
404                                 Language from the point of view of the driver
405                                 specified by This.
406 
407   @retval EFI_SUCCESS           The Unicode string for the user readable name in
408                                 the language specified by Language for the
409                                 driver specified by This was returned in
410                                 DriverName.
411 
412   @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
413 
414   @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
415                                 EFI_HANDLE.
416 
417   @retval EFI_INVALID_PARAMETER Language is NULL.
418 
419   @retval EFI_INVALID_PARAMETER ControllerName is NULL.
420 
421   @retval EFI_UNSUPPORTED       The driver specified by This is not currently
422                                 managing the controller specified by
423                                 ControllerHandle and ChildHandle.
424 
425   @retval EFI_UNSUPPORTED       The driver specified by This does not support
426                                 the language specified by Language.
427 
428 **/
429 EFI_STATUS
430 EFIAPI
431 AtapiScsiPassThruComponentNameGetControllerName (
432   IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
433   IN  EFI_HANDLE                                      ControllerHandle,
434   IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
435   IN  CHAR8                                           *Language,
436   OUT CHAR16                                          **ControllerName
437   );
438 
439 
440 EFI_STATUS
441 EFIAPI
442 AtapiScsiPassThruDriverEntryPoint (
443   IN EFI_HANDLE         ImageHandle,
444   IN EFI_SYSTEM_TABLE   *SystemTable
445   )
446  /*++
447 
448 Routine Description:
449 
450   Entry point for EFI drivers.
451 
452 Arguments:
453 
454   ImageHandle - EFI_HANDLE
455   SystemTable - EFI_SYSTEM_TABLE
456 
457 Returns:
458 
459   EFI_SUCCESS
460   Others
461 
462 --*/
463 ;
464 
465 EFI_STATUS
466 RegisterAtapiScsiPassThru (
467   IN  EFI_DRIVER_BINDING_PROTOCOL *This,
468   IN  EFI_HANDLE                  Controller,
469   IN  EFI_PCI_IO_PROTOCOL         *PciIo,
470   IN  UINT64                      OriginalPciAttributes
471   )
472 /*++
473 
474 Routine Description:
475   Attaches SCSI Pass Thru Protocol for specified IDE channel.
476 
477 Arguments:
478   This              - Protocol instance pointer.
479   Controller        - Parent device handle to the IDE channel.
480   PciIo             - PCI I/O protocol attached on the "Controller".
481 
482 Returns:
483   Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.
484 
485 --*/
486 ;
487 
488 EFI_STATUS
489 EFIAPI
490 AtapiScsiPassThruFunction (
491   IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,
492   IN UINT32                                             Target,
493   IN UINT64                                             Lun,
494   IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,
495   IN EFI_EVENT                                          Event OPTIONAL
496   )
497 /*++
498 
499 Routine Description:
500 
501   Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
502 
503 Arguments:
504 
505   This:     The EFI_SCSI_PASS_THRU_PROTOCOL instance.
506   Target:   The Target ID of the ATAPI device to send the SCSI
507             Request Packet. To ATAPI devices attached on an IDE
508             Channel, Target ID 0 indicates Master device;Target
509             ID 1 indicates Slave device.
510   Lun:      The LUN of the ATAPI device to send the SCSI Request
511             Packet. To the ATAPI device, Lun is always 0.
512   Packet:   The SCSI Request Packet to send to the ATAPI device
513             specified by Target and Lun.
514   Event:    If non-blocking I/O is not supported then Event is ignored,
515             and blocking I/O is performed.
516             If Event is NULL, then blocking I/O is performed.
517             If Event is not NULL and non blocking I/O is supported,
518             then non-blocking I/O is performed, and Event will be signaled
519             when the SCSI Request Packet completes.
520 
521 Returns:
522 
523    EFI_STATUS
524 
525 --*/
526 ;
527 
528 EFI_STATUS
529 EFIAPI
530 AtapiScsiPassThruGetNextDevice (
531   IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
532   IN OUT UINT32                      *Target,
533   IN OUT UINT64                      *Lun
534   )
535 /*++
536 
537 Routine Description:
538 
539   Used to retrieve the list of legal Target IDs for SCSI devices
540   on a SCSI channel.
541 
542 Arguments:
543 
544   This                  - Protocol instance pointer.
545   Target                - On input, a pointer to the Target ID of a SCSI
546                           device present on the SCSI channel.  On output,
547                           a pointer to the Target ID of the next SCSI device
548                           present on a SCSI channel.  An input value of
549                           0xFFFFFFFF retrieves the Target ID of the first
550                           SCSI device present on a SCSI channel.
551   Lun                   - On input, a pointer to the LUN of a SCSI device
552                           present on the SCSI channel. On output, a pointer
553                           to the LUN of the next SCSI device present on
554                           a SCSI channel.
555 Returns:
556 
557   EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
558                           on the SCSI channel was returned in Target and Lun.
559   EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
560   EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
561                            returned on a previous call to GetNextDevice().
562 
563 --*/
564 ;
565 
566 EFI_STATUS
567 EFIAPI
568 AtapiScsiPassThruBuildDevicePath (
569   IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,
570   IN     UINT32                         Target,
571   IN     UINT64                         Lun,
572   IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath
573   )
574 /*++
575 
576 Routine Description:
577 
578   Used to allocate and build a device path node for a SCSI device
579   on a SCSI channel. Would not build device path for a SCSI Host Controller.
580 
581 Arguments:
582 
583   This                  - Protocol instance pointer.
584   Target                - The Target ID of the SCSI device for which
585                           a device path node is to be allocated and built.
586   Lun                   - The LUN of the SCSI device for which a device
587                           path node is to be allocated and built.
588   DevicePath            - A pointer to a single device path node that
589                           describes the SCSI device specified by
590                           Target and Lun. This function is responsible
591                           for allocating the buffer DevicePath with the boot
592                           service AllocatePool().  It is the caller's
593                           responsibility to free DevicePath when the caller
594                           is finished with DevicePath.
595   Returns:
596   EFI_SUCCESS           - The device path node that describes the SCSI device
597                           specified by Target and Lun was allocated and
598                           returned in DevicePath.
599   EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
600                           not exist on the SCSI channel.
601   EFI_INVALID_PARAMETER - DevicePath is NULL.
602   EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
603                           DevicePath.
604 
605 --*/
606 ;
607 
608 EFI_STATUS
609 EFIAPI
610 AtapiScsiPassThruGetTargetLun (
611   IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
612   IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
613   OUT UINT32                         *Target,
614   OUT UINT64                         *Lun
615   )
616 /*++
617 
618 Routine Description:
619 
620   Used to translate a device path node to a Target ID and LUN.
621 
622 Arguments:
623 
624   This                  - Protocol instance pointer.
625   DevicePath            - A pointer to the device path node that
626                           describes a SCSI device on the SCSI channel.
627   Target                - A pointer to the Target ID of a SCSI device
628                           on the SCSI channel.
629   Lun                   - A pointer to the LUN of a SCSI device on
630                           the SCSI channel.
631 Returns:
632 
633   EFI_SUCCESS           - DevicePath was successfully translated to a
634                           Target ID and LUN, and they were returned
635                           in Target and Lun.
636   EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
637   EFI_UNSUPPORTED       - This driver does not support the device path
638                           node type in DevicePath.
639   EFI_NOT_FOUND         - A valid translation from DevicePath to a
640                           Target ID and LUN does not exist.
641 
642 --*/
643 ;
644 
645 EFI_STATUS
646 EFIAPI
647 AtapiScsiPassThruResetChannel (
648   IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This
649   )
650 /*++
651 
652 Routine Description:
653 
654   Resets a SCSI channel.This operation resets all the
655   SCSI devices connected to the SCSI channel.
656 
657 Arguments:
658 
659   This                  - Protocol instance pointer.
660 
661 Returns:
662 
663   EFI_SUCCESS           - The SCSI channel was reset.
664   EFI_UNSUPPORTED       - The SCSI channel does not support
665                           a channel reset operation.
666   EFI_DEVICE_ERROR      - A device error occurred while
667                           attempting to reset the SCSI channel.
668   EFI_TIMEOUT           - A timeout occurred while attempting
669                           to reset the SCSI channel.
670 
671 --*/
672 ;
673 
674 EFI_STATUS
675 EFIAPI
676 AtapiScsiPassThruResetTarget (
677   IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,
678   IN UINT32                         Target,
679   IN UINT64                         Lun
680   )
681 /*++
682 
683 Routine Description:
684 
685   Resets a SCSI device that is connected to a SCSI channel.
686 
687 Arguments:
688 
689   This                  - Protocol instance pointer.
690   Target                - The Target ID of the SCSI device to reset.
691   Lun                   - The LUN of the SCSI device to reset.
692 
693 Returns:
694 
695   EFI_SUCCESS           - The SCSI device specified by Target and
696                           Lun was reset.
697   EFI_UNSUPPORTED       - The SCSI channel does not support a target
698                           reset operation.
699   EFI_INVALID_PARAMETER - Target or Lun are invalid.
700   EFI_DEVICE_ERROR      - A device error occurred while attempting
701                           to reset the SCSI device specified by Target
702                           and Lun.
703   EFI_TIMEOUT           - A timeout occurred while attempting to reset
704                           the SCSI device specified by Target and Lun.
705 
706 --*/
707 ;
708 
709 EFI_STATUS
710 EFIAPI
711 AtapiExtScsiPassThruFunction (
712   IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
713   IN UINT8                                              *Target,
714   IN UINT64                                             Lun,
715   IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
716   IN EFI_EVENT                                          Event OPTIONAL
717   )
718 /*++
719 
720 Routine Description:
721 
722   Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
723 
724 Arguments:
725 
726   This:     The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
727   Target:   The Target ID of the ATAPI device to send the SCSI
728             Request Packet. To ATAPI devices attached on an IDE
729             Channel, Target ID 0 indicates Master device;Target
730             ID 1 indicates Slave device.
731   Lun:      The LUN of the ATAPI device to send the SCSI Request
732             Packet. To the ATAPI device, Lun is always 0.
733   Packet:   The SCSI Request Packet to send to the ATAPI device
734             specified by Target and Lun.
735   Event:    If non-blocking I/O is not supported then Event is ignored,
736             and blocking I/O is performed.
737             If Event is NULL, then blocking I/O is performed.
738             If Event is not NULL and non blocking I/O is supported,
739             then non-blocking I/O is performed, and Event will be signaled
740             when the SCSI Request Packet completes.
741 
742 Returns:
743 
744   EFI_STATUS
745 
746 --*/
747 ;
748 
749 EFI_STATUS
750 EFIAPI
751 AtapiExtScsiPassThruGetNextTargetLun (
752   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
753   IN OUT UINT8                           **Target,
754   IN OUT UINT64                          *Lun
755   )
756 /*++
757 
758 Routine Description:
759 
760   Used to retrieve the list of legal Target IDs for SCSI devices
761   on a SCSI channel.
762 
763 Arguments:
764 
765   This                  - Protocol instance pointer.
766   Target                - On input, a pointer to the Target ID of a SCSI
767                           device present on the SCSI channel.  On output,
768                           a pointer to the Target ID of the next SCSI device
769                           present on a SCSI channel.  An input value of
770                           0xFFFFFFFF retrieves the Target ID of the first
771                           SCSI device present on a SCSI channel.
772   Lun                   - On input, a pointer to the LUN of a SCSI device
773                           present on the SCSI channel. On output, a pointer
774                           to the LUN of the next SCSI device present on
775                           a SCSI channel.
776 Returns:
777 
778   EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
779                           on the SCSI channel was returned in Target and Lun.
780   EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
781   EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
782                            returned on a previous call to GetNextDevice().
783 
784 --*/
785 ;
786 
787 EFI_STATUS
788 EFIAPI
789 AtapiExtScsiPassThruBuildDevicePath (
790   IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
791   IN     UINT8                              *Target,
792   IN     UINT64                             Lun,
793   IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
794   )
795 /*++
796 
797 Routine Description:
798 
799   Used to allocate and build a device path node for a SCSI device
800   on a SCSI channel. Would not build device path for a SCSI Host Controller.
801 
802 Arguments:
803 
804   This                  - Protocol instance pointer.
805   Target                - The Target ID of the SCSI device for which
806                           a device path node is to be allocated and built.
807   Lun                   - The LUN of the SCSI device for which a device
808                           path node is to be allocated and built.
809   DevicePath            - A pointer to a single device path node that
810                           describes the SCSI device specified by
811                           Target and Lun. This function is responsible
812                           for allocating the buffer DevicePath with the boot
813                           service AllocatePool().  It is the caller's
814                           responsibility to free DevicePath when the caller
815                           is finished with DevicePath.
816   Returns:
817   EFI_SUCCESS           - The device path node that describes the SCSI device
818                           specified by Target and Lun was allocated and
819                           returned in DevicePath.
820   EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
821                           not exist on the SCSI channel.
822   EFI_INVALID_PARAMETER - DevicePath is NULL.
823   EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
824                           DevicePath.
825 
826 --*/
827 ;
828 
829 EFI_STATUS
830 EFIAPI
831 AtapiExtScsiPassThruGetTargetLun (
832   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
833   IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
834   OUT UINT8                          **Target,
835   OUT UINT64                         *Lun
836   )
837 /*++
838 
839 Routine Description:
840 
841   Used to translate a device path node to a Target ID and LUN.
842 
843 Arguments:
844 
845   This                  - Protocol instance pointer.
846   DevicePath            - A pointer to the device path node that
847                           describes a SCSI device on the SCSI channel.
848   Target                - A pointer to the Target ID of a SCSI device
849                           on the SCSI channel.
850   Lun                   - A pointer to the LUN of a SCSI device on
851                           the SCSI channel.
852 Returns:
853 
854   EFI_SUCCESS           - DevicePath was successfully translated to a
855                           Target ID and LUN, and they were returned
856                           in Target and Lun.
857   EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
858   EFI_UNSUPPORTED       - This driver does not support the device path
859                           node type in DevicePath.
860   EFI_NOT_FOUND         - A valid translation from DevicePath to a
861                           Target ID and LUN does not exist.
862 
863 --*/
864 ;
865 
866 EFI_STATUS
867 EFIAPI
868 AtapiExtScsiPassThruResetChannel (
869   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
870   )
871 /*++
872 
873 Routine Description:
874 
875   Resets a SCSI channel.This operation resets all the
876   SCSI devices connected to the SCSI channel.
877 
878 Arguments:
879 
880   This                  - Protocol instance pointer.
881 
882 Returns:
883 
884   EFI_SUCCESS           - The SCSI channel was reset.
885   EFI_UNSUPPORTED       - The SCSI channel does not support
886                           a channel reset operation.
887   EFI_DEVICE_ERROR      - A device error occurred while
888                           attempting to reset the SCSI channel.
889   EFI_TIMEOUT           - A timeout occurred while attempting
890                           to reset the SCSI channel.
891 
892 --*/
893 ;
894 
895 EFI_STATUS
896 EFIAPI
897 AtapiExtScsiPassThruResetTarget (
898   IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
899   IN UINT8                              *Target,
900   IN UINT64                             Lun
901   )
902 /*++
903 
904 Routine Description:
905 
906   Resets a SCSI device that is connected to a SCSI channel.
907 
908 Arguments:
909 
910   This                  - Protocol instance pointer.
911   Target                - The Target ID of the SCSI device to reset.
912   Lun                   - The LUN of the SCSI device to reset.
913 
914 Returns:
915 
916   EFI_SUCCESS           - The SCSI device specified by Target and
917                           Lun was reset.
918   EFI_UNSUPPORTED       - The SCSI channel does not support a target
919                           reset operation.
920   EFI_INVALID_PARAMETER - Target or Lun are invalid.
921   EFI_DEVICE_ERROR      - A device error occurred while attempting
922                           to reset the SCSI device specified by Target
923                           and Lun.
924   EFI_TIMEOUT           - A timeout occurred while attempting to reset
925                           the SCSI device specified by Target and Lun.
926 
927 --*/
928 ;
929 
930 EFI_STATUS
931 EFIAPI
932 AtapiExtScsiPassThruGetNextTarget (
933   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
934   IN OUT UINT8                           **Target
935   )
936 /*++
937 
938 Routine Description:
939   Used to retrieve the list of legal Target IDs for SCSI devices
940   on a SCSI channel.
941 
942 Arguments:
943   This                  - Protocol instance pointer.
944   Target                - On input, a pointer to the Target ID of a SCSI
945                           device present on the SCSI channel.  On output,
946                           a pointer to the Target ID of the next SCSI device
947                            present on a SCSI channel.  An input value of
948                            0xFFFFFFFF retrieves the Target ID of the first
949                            SCSI device present on a SCSI channel.
950   Lun                   - On input, a pointer to the LUN of a SCSI device
951                           present on the SCSI channel. On output, a pointer
952                           to the LUN of the next SCSI device present on
953                           a SCSI channel.
954 
955 Returns:
956   EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
957                           on the SCSI channel was returned in Target and Lun.
958   EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
959   EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
960                           returned on a previous call to GetNextDevice().
961 
962 --*/
963 ;
964 
965 EFI_STATUS
966 CheckSCSIRequestPacket (
967   EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
968   )
969 /*++
970 
971 Routine Description:
972 
973   Checks the parameters in the SCSI Request Packet to make sure
974   they are valid for a SCSI Pass Thru request.
975 
976 Arguments:
977 
978   Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
979 
980 Returns:
981 
982   EFI_STATUS
983 
984 --*/
985 ;
986 
987 EFI_STATUS
988 SubmitBlockingIoCommand (
989   ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
990   UINT32                                    Target,
991   EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
992   )
993 /*++
994 
995 Routine Description:
996 
997   Performs blocking I/O request.
998 
999 Arguments:
1000 
1001   AtapiScsiPrivate:   Private data structure for the specified channel.
1002   Target:             The Target ID of the ATAPI device to send the SCSI
1003                       Request Packet. To ATAPI devices attached on an IDE
1004                       Channel, Target ID 0 indicates Master device;Target
1005                       ID 1 indicates Slave device.
1006   Packet:             The SCSI Request Packet to send to the ATAPI device
1007                       specified by Target.
1008 
1009   Returns:            EFI_STATUS
1010 
1011 --*/
1012 ;
1013 
1014 BOOLEAN
1015 IsCommandValid (
1016   EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
1017   )
1018  /*++
1019 
1020 Routine Description:
1021 
1022   Checks the requested SCSI command:
1023   Is it supported by this driver?
1024   Is the Data transfer direction reasonable?
1025 
1026 Arguments:
1027 
1028   Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
1029 
1030 Returns:
1031 
1032   EFI_STATUS
1033 
1034 --*/
1035 ;
1036 
1037 EFI_STATUS
1038 CheckExtSCSIRequestPacket (
1039   EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
1040   )
1041 /*++
1042 
1043 Routine Description:
1044 
1045   Checks the parameters in the SCSI Request Packet to make sure
1046   they are valid for a SCSI Pass Thru request.
1047 
1048 Arguments:
1049 
1050   Packet       - The pointer of EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
1051 
1052 Returns:
1053 
1054   EFI_STATUS
1055 
1056 --*/
1057 ;
1058 
1059 
1060 BOOLEAN
1061 IsExtCommandValid (
1062   EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
1063   )
1064 /*++
1065 
1066 Routine Description:
1067 
1068   Checks the requested SCSI command:
1069   Is it supported by this driver?
1070   Is the Data transfer direction reasonable?
1071 
1072 Arguments:
1073 
1074   Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
1075 
1076 Returns:
1077 
1078   EFI_STATUS
1079 
1080 --*/
1081 ;
1082 
1083 EFI_STATUS
1084 SubmitExtBlockingIoCommand (
1085   ATAPI_SCSI_PASS_THRU_DEV                      *AtapiScsiPrivate,
1086   UINT8                                         Target,
1087   EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
1088   )
1089 /*++
1090 
1091 Routine Description:
1092 
1093   Performs blocking I/O request.
1094 
1095 Arguments:
1096 
1097   AtapiScsiPrivate:   Private data structure for the specified channel.
1098   Target:             The Target ID of the ATAPI device to send the SCSI
1099                       Request Packet. To ATAPI devices attached on an IDE
1100                       Channel, Target ID 0 indicates Master device;Target
1101                       ID 1 indicates Slave device.
1102   Packet:             The SCSI Request Packet to send to the ATAPI device
1103                       specified by Target.
1104 
1105   Returns:            EFI_STATUS
1106 
1107 --*/
1108 ;
1109 
1110 EFI_STATUS
1111 RequestSenseCommand (
1112   ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
1113   UINT32                      Target,
1114   UINT64                      Timeout,
1115   VOID                        *SenseData,
1116   UINT8                       *SenseDataLength
1117   )
1118 /*++
1119 
1120 Routine Description:
1121 
1122   Sumbit request sense command
1123 
1124 Arguments:
1125 
1126   AtapiScsiPrivate  - The pionter of ATAPI_SCSI_PASS_THRU_DEV
1127   Target            - The target ID
1128   Timeout           - The time to complete the command
1129   SenseData         - The buffer to fill in sense data
1130   SenseDataLength   - The length of buffer
1131 
1132 Returns:
1133 
1134   EFI_STATUS
1135 
1136 --*/
1137 ;
1138 
1139 EFI_STATUS
1140 AtapiPacketCommand (
1141   ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
1142   UINT32                                    Target,
1143   UINT8                                     *PacketCommand,
1144   VOID                                      *Buffer,
1145   UINT32                                    *ByteCount,
1146   DATA_DIRECTION                            Direction,
1147   UINT64                                    TimeOutInMicroSeconds
1148   )
1149 /*++
1150 
1151 Routine Description:
1152 
1153   Submits ATAPI command packet to the specified ATAPI device.
1154 
1155 Arguments:
1156 
1157   AtapiScsiPrivate:   Private data structure for the specified channel.
1158   Target:             The Target ID of the ATAPI device to send the SCSI
1159                       Request Packet. To ATAPI devices attached on an IDE
1160                       Channel, Target ID 0 indicates Master device;Target
1161                       ID 1 indicates Slave device.
1162   PacketCommand:      Points to the ATAPI command packet.
1163   Buffer:             Points to the transferred data.
1164   ByteCount:          When input,indicates the buffer size; when output,
1165                       indicates the actually transferred data size.
1166   Direction:          Indicates the data transfer direction.
1167   TimeoutInMicroSeconds:
1168                       The timeout, in micro second units, to use for the
1169                       execution of this ATAPI command.
1170                       A TimeoutInMicroSeconds value of 0 means that
1171                       this function will wait indefinitely for the ATAPI
1172                       command to execute.
1173                       If TimeoutInMicroSeconds is greater than zero, then
1174                       this function will return EFI_TIMEOUT if the time
1175                       required to execute the ATAPI command is greater
1176                       than TimeoutInMicroSeconds.
1177 
1178 Returns:
1179 
1180   EFI_STATUS
1181 
1182 --*/
1183 ;
1184 
1185 
1186 UINT8
1187 ReadPortB (
1188   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
1189   IN  UINT16                Port
1190   )
1191 /*++
1192 
1193 Routine Description:
1194 
1195   Read one byte from a specified I/O port.
1196 
1197 Arguments:
1198 
1199   PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
1200   Port       - IO port
1201 
1202 Returns:
1203 
1204   A byte read out
1205 
1206 --*/
1207 ;
1208 
1209 
1210 UINT16
1211 ReadPortW (
1212   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
1213   IN  UINT16                Port
1214   )
1215 /*++
1216 
1217 Routine Description:
1218 
1219   Read one word from a specified I/O port.
1220 
1221 Arguments:
1222 
1223   PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
1224   Port       - IO port
1225 
1226 Returns:
1227 
1228   A word read out
1229 
1230 --*/
1231 ;
1232 
1233 
1234 VOID
1235 WritePortB (
1236   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
1237   IN  UINT16                Port,
1238   IN  UINT8                 Data
1239   )
1240 /*++
1241 
1242 Routine Description:
1243 
1244   Write one byte to a specified I/O port.
1245 
1246 Arguments:
1247 
1248   PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
1249   Port       - IO port
1250   Data       - The data to write
1251 
1252 Returns:
1253 
1254   NONE
1255 
1256 --*/
1257 ;
1258 
1259 
1260 VOID
1261 WritePortW (
1262   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
1263   IN  UINT16                Port,
1264   IN  UINT16                Data
1265   )
1266 /*++
1267 
1268 Routine Description:
1269 
1270   Write one word to a specified I/O port.
1271 
1272 Arguments:
1273 
1274   PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
1275   Port       - IO port
1276   Data       - The data to write
1277 
1278 Returns:
1279 
1280   NONE
1281 
1282 --*/
1283 ;
1284 
1285 EFI_STATUS
1286 StatusDRQClear (
1287   ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
1288   UINT64                          TimeOutInMicroSeconds
1289   )
1290 /*++
1291 
1292 Routine Description:
1293 
1294   Check whether DRQ is clear in the Status Register. (BSY must also be cleared)
1295   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1296   DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
1297   elapsed.
1298 
1299 Arguments:
1300 
1301   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1302   TimeoutInMicroSeconds       - The time to wait for
1303 
1304 Returns:
1305 
1306   EFI_STATUS
1307 
1308 --*/
1309 ;
1310 
1311 EFI_STATUS
1312 AltStatusDRQClear (
1313   ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
1314   UINT64                          TimeOutInMicroSeconds
1315   )
1316 /*++
1317 
1318 Routine Description:
1319 
1320   Check whether DRQ is clear in the Alternate Status Register.
1321   (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine should
1322   wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
1323   elapsed.
1324 
1325 Arguments:
1326 
1327   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1328   TimeoutInMicroSeconds       - The time to wait for
1329 
1330 Returns:
1331 
1332   EFI_STATUS
1333 
1334 --*/
1335 ;
1336 
1337 EFI_STATUS
1338 StatusDRQReady (
1339   ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
1340   UINT64                          TimeOutInMicroSeconds
1341   )
1342 /*++
1343 
1344 Routine Description:
1345 
1346   Check whether DRQ is ready in the Status Register. (BSY must also be cleared)
1347   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1348   DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
1349   elapsed.
1350 
1351 Arguments:
1352 
1353   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1354   TimeoutInMicroSeconds       - The time to wait for
1355 
1356 Returns:
1357 
1358   EFI_STATUS
1359 
1360 --*/
1361 ;
1362 
1363 EFI_STATUS
1364 AltStatusDRQReady (
1365   ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
1366   UINT64                          TimeOutInMicroSeconds
1367   )
1368 /*++
1369 
1370 Routine Description:
1371 
1372   Check whether DRQ is ready in the Alternate Status Register.
1373   (BSY must also be cleared)
1374   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1375   DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
1376   elapsed.
1377 
1378 Arguments:
1379 
1380   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1381   TimeoutInMicroSeconds       - The time to wait for
1382 
1383 Returns:
1384 
1385   EFI_STATUS
1386 
1387 --*/
1388 ;
1389 
1390 EFI_STATUS
1391 StatusWaitForBSYClear (
1392   ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
1393   UINT64                      TimeoutInMicroSeconds
1394   )
1395 /*++
1396 
1397 Routine Description:
1398 
1399   Check whether BSY is clear in the Status Register.
1400   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1401   BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
1402   elapsed.
1403 
1404 Arguments:
1405 
1406   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1407   TimeoutInMicroSeconds       - The time to wait for
1408 
1409 Returns:
1410 
1411   EFI_STATUS
1412 
1413 --*/
1414 ;
1415 
1416 EFI_STATUS
1417 AltStatusWaitForBSYClear (
1418   ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
1419   UINT64                      TimeoutInMicroSeconds
1420   )
1421 /*++
1422 
1423 Routine Description:
1424 
1425   Check whether BSY is clear in the Alternate Status Register.
1426   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1427   BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
1428   elapsed.
1429 
1430 Arguments:
1431 
1432   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1433   TimeoutInMicroSeconds       - The time to wait for
1434 
1435 Returns:
1436 
1437   EFI_STATUS
1438 
1439 --*/
1440 ;
1441 
1442 EFI_STATUS
1443 StatusDRDYReady (
1444   ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
1445   UINT64                      TimeoutInMicroSeconds
1446   )
1447 /*++
1448 
1449 Routine Description:
1450 
1451   Check whether DRDY is ready in the Status Register.
1452   (BSY must also be cleared)
1453   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1454   DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
1455   elapsed.
1456 
1457 Arguments:
1458 
1459   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1460   TimeoutInMicroSeconds       - The time to wait for
1461 
1462 Returns:
1463 
1464   EFI_STATUS
1465 
1466 --*/
1467 ;
1468 
1469 EFI_STATUS
1470 AltStatusDRDYReady (
1471   ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
1472   UINT64                      TimeoutInMicroSeconds
1473   )
1474 /*++
1475 
1476 Routine Description:
1477 
1478   Check whether DRDY is ready in the Alternate Status Register.
1479   (BSY must also be cleared)
1480   If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
1481   DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
1482   elapsed.
1483 
1484 Arguments:
1485 
1486   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1487   TimeoutInMicroSeconds       - The time to wait for
1488 
1489 Returns:
1490 
1491   EFI_STATUS
1492 
1493 --*/
1494 ;
1495 
1496 EFI_STATUS
1497 AtapiPassThruPioReadWriteData (
1498   ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,
1499   UINT16                    *Buffer,
1500   UINT32                    *ByteCount,
1501   DATA_DIRECTION            Direction,
1502   UINT64                    TimeOutInMicroSeconds
1503   )
1504 /*++
1505 
1506 Routine Description:
1507 
1508   Performs data transfer between ATAPI device and host after the
1509   ATAPI command packet is sent.
1510 
1511 Arguments:
1512 
1513   AtapiScsiPrivate:   Private data structure for the specified channel.
1514   Buffer:             Points to the transferred data.
1515   ByteCount:          When input,indicates the buffer size; when output,
1516                       indicates the actually transferred data size.
1517   Direction:          Indicates the data transfer direction.
1518   TimeoutInMicroSeconds:
1519                       The timeout, in micro second units, to use for the
1520                       execution of this ATAPI command.
1521                       A TimeoutInMicroSeconds value of 0 means that
1522                       this function will wait indefinitely for the ATAPI
1523                       command to execute.
1524                       If TimeoutInMicroSeconds is greater than zero, then
1525                       this function will return EFI_TIMEOUT if the time
1526                       required to execute the ATAPI command is greater
1527                       than TimeoutInMicroSeconds.
1528  Returns:
1529 
1530   EFI_STATUS
1531 
1532 --*/
1533 ;
1534 
1535 EFI_STATUS
1536 AtapiPassThruCheckErrorStatus (
1537   ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate
1538   )
1539 /*++
1540 
1541 Routine Description:
1542 
1543   Check Error Register for Error Information.
1544 
1545 Arguments:
1546 
1547   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1548 
1549 Returns:
1550 
1551   EFI_STATUS
1552 
1553 --*/
1554 ;
1555 
1556 
1557 EFI_STATUS
1558 GetIdeRegistersBaseAddr (
1559   IN  EFI_PCI_IO_PROTOCOL         *PciIo,
1560   OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr
1561   )
1562 /*++
1563 
1564 Routine Description:
1565   Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
1566   use fixed addresses. In Native-PCI mode, get base addresses from BARs in
1567   the PCI IDE controller's Configuration Space.
1568 
1569 Arguments:
1570   PciIo             - Pointer to the EFI_PCI_IO_PROTOCOL instance
1571   IdeRegsBaseAddr   - Pointer to IDE_REGISTERS_BASE_ADDR to
1572                       receive IDE IO port registers' base addresses
1573 
1574 Returns:
1575 
1576   EFI_STATUS
1577 
1578 --*/
1579 ;
1580 
1581 
1582 VOID
1583 InitAtapiIoPortRegisters (
1584   IN  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
1585   IN  IDE_REGISTERS_BASE_ADDR      *IdeRegsBaseAddr
1586   )
1587 /*++
1588 
1589 Routine Description:
1590 
1591   Initialize each Channel's Base Address of CommandBlock and ControlBlock.
1592 
1593 Arguments:
1594 
1595   AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
1596   IdeRegsBaseAddr             - The pointer of IDE_REGISTERS_BASE_ADDR
1597 
1598 Returns:
1599 
1600   None
1601 
1602 --*/
1603 ;
1604 
1605 /**
1606   Installs Scsi Pass Thru and/or Ext Scsi Pass Thru
1607   protocols based on feature flags.
1608 
1609   @param Controller         The controller handle to
1610                             install these protocols on.
1611   @param AtapiScsiPrivate   A pointer to the protocol private
1612                             data structure.
1613 
1614   @retval EFI_SUCCESS       The installation succeeds.
1615   @retval other             The installation fails.
1616 
1617 **/
1618 EFI_STATUS
1619 InstallScsiPassThruProtocols (
1620   IN EFI_HANDLE                 *ControllerHandle,
1621   IN ATAPI_SCSI_PASS_THRU_DEV   *AtapiScsiPrivate
1622   );
1623 
1624 #endif
1625