1 /** @file
2 
3   Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
4   SPDX-License-Identifier: BSD-2-Clause-Patent
5 
6 **/
7 
8 #ifndef _UFS_PASS_THRU_H_
9 #define _UFS_PASS_THRU_H_
10 
11 #include <Uefi.h>
12 
13 #include <Protocol/ScsiPassThruExt.h>
14 #include <Protocol/UfsDeviceConfig.h>
15 #include <Protocol/UfsHostController.h>
16 #include <Protocol/UfsHostControllerPlatform.h>
17 
18 #include <Library/DebugLib.h>
19 #include <Library/UefiDriverEntryPoint.h>
20 #include <Library/BaseLib.h>
21 #include <Library/UefiLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/DevicePathLib.h>
26 #include <Library/TimerLib.h>
27 
28 #include "UfsPassThruHci.h"
29 
30 #define UFS_PASS_THRU_SIG           SIGNATURE_32 ('U', 'F', 'S', 'P')
31 
32 //
33 // Lun 0~7 is for 8 common luns.
34 // Lun 8~11 is for those 4 well known luns (Refer to UFS 2.0 spec Table 10.58 for details):
35 //  Lun 8:  REPORT LUNS
36 //  Lun 9:  UFS DEVICE
37 //  Lun 10: BOOT
38 //  Lun 11: RPMB
39 //
40 #define UFS_MAX_LUNS                12
41 #define UFS_WLUN_PREFIX             0xC1
42 
43 typedef struct {
44   UINT8    Lun[UFS_MAX_LUNS];
45   UINT16   BitMask:12;              // Bit 0~7 is 1/1 mapping to common luns. Bit 8~11 is 1/1 mapping to well-known luns.
46   UINT16   Rsvd:4;
47 } UFS_EXPOSED_LUNS;
48 
49 //
50 // Iterate through the double linked list. This is delete-safe.
51 // Do not touch NextEntry
52 //
53 #define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead)            \
54   for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\
55       Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink)
56 
57 typedef struct _UFS_PASS_THRU_PRIVATE_DATA {
58   UINT32                              Signature;
59   EFI_HANDLE                          Handle;
60   EFI_EXT_SCSI_PASS_THRU_MODE         ExtScsiPassThruMode;
61   EFI_EXT_SCSI_PASS_THRU_PROTOCOL     ExtScsiPassThru;
62   EFI_UFS_DEVICE_CONFIG_PROTOCOL      UfsDevConfig;
63   EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHostController;
64   UINTN                               UfsHcBase;
65   EDKII_UFS_HC_INFO                   UfsHcInfo;
66   EDKII_UFS_HC_DRIVER_INTERFACE       UfsHcDriverInterface;
67 
68   UINT8                               TaskTag;
69 
70   VOID                                *UtpTrlBase;
71   UINT8                               Nutrs;
72   VOID                                *TrlMapping;
73   VOID                                *UtpTmrlBase;
74   UINT8                               Nutmrs;
75   VOID                                *TmrlMapping;
76 
77   UFS_EXPOSED_LUNS                    Luns;
78 
79   //
80   // For Non-blocking operation.
81   //
82   EFI_EVENT                           TimerEvent;
83   LIST_ENTRY                          Queue;
84 } UFS_PASS_THRU_PRIVATE_DATA;
85 
86 #define UFS_PASS_THRU_TRANS_REQ_SIG   SIGNATURE_32 ('U', 'F', 'S', 'T')
87 
88 typedef struct {
89   UINT32                                        Signature;
90   LIST_ENTRY                                    TransferList;
91 
92   UINT8                                         Slot;
93   UTP_TRD                                       *Trd;
94   UINT32                                        CmdDescSize;
95   VOID                                          *CmdDescHost;
96   VOID                                          *CmdDescMapping;
97   VOID                                          *AlignedDataBuf;
98   UINTN                                         AlignedDataBufSize;
99   VOID                                          *DataBufMapping;
100 
101   EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet;
102   UINT64                                        TimeoutRemain;
103   EFI_EVENT                                     CallerEvent;
104 } UFS_PASS_THRU_TRANS_REQ;
105 
106 #define UFS_PASS_THRU_TRANS_REQ_FROM_THIS(a) \
107     CR(a, UFS_PASS_THRU_TRANS_REQ, TransferList, UFS_PASS_THRU_TRANS_REQ_SIG)
108 
109 #define UFS_TIMEOUT                   EFI_TIMER_PERIOD_SECONDS(3)
110 #define UFS_HC_ASYNC_TIMER            EFI_TIMER_PERIOD_MILLISECONDS(1)
111 
112 #define ROUNDUP8(x) (((x) % 8 == 0) ? (x) : ((x) / 8 + 1) * 8)
113 
114 #define IS_ALIGNED(addr, size)        (((UINTN) (addr) & (size - 1)) == 0)
115 
116 #define UFS_PASS_THRU_PRIVATE_DATA_FROM_THIS(a) \
117   CR (a, \
118       UFS_PASS_THRU_PRIVATE_DATA, \
119       ExtScsiPassThru, \
120       UFS_PASS_THRU_SIG \
121       )
122 
123 #define UFS_PASS_THRU_PRIVATE_DATA_FROM_DEV_CONFIG(a) \
124   CR (a, \
125       UFS_PASS_THRU_PRIVATE_DATA, \
126       UfsDevConfig, \
127       UFS_PASS_THRU_SIG \
128       )
129 
130 #define UFS_PASS_THRU_PRIVATE_DATA_FROM_DRIVER_INTF(a) \
131   CR (a, \
132       UFS_PASS_THRU_PRIVATE_DATA, \
133       UfsHcDriverInterface, \
134       UFS_PASS_THRU_SIG \
135       )
136 
137 typedef struct _UFS_DEVICE_MANAGEMENT_REQUEST_PACKET {
138   UINT64           Timeout;
139   VOID             *DataBuffer;
140   UINT8            Opcode;
141   UINT8            DescId;
142   UINT8            Index;
143   UINT8            Selector;
144   UINT32           TransferLength;
145   UINT8            DataDirection;
146 } UFS_DEVICE_MANAGEMENT_REQUEST_PACKET;
147 
148 //
149 // function prototype
150 //
151 /**
152   Tests to see if this driver supports a given controller. If a child device is provided,
153   it further tests to see if this driver supports creating a handle for the specified child device.
154 
155   This function checks to see if the driver specified by This supports the device specified by
156   ControllerHandle. Drivers will typically use the device path attached to
157   ControllerHandle and/or the services from the bus I/O abstraction attached to
158   ControllerHandle to determine if the driver supports ControllerHandle. This function
159   may be called many times during platform initialization. In order to reduce boot times, the tests
160   performed by this function must be very small, and take as little time as possible to execute. This
161   function must not change the state of any hardware devices, and this function must be aware that the
162   device specified by ControllerHandle may already be managed by the same driver or a
163   different driver. This function must match its calls to AllocatePages() with FreePages(),
164   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
165   Since ControllerHandle may have been previously started by the same driver, if a protocol is
166   already in the opened state, then it must not be closed with CloseProtocol(). This is required
167   to guarantee the state of ControllerHandle is not modified by this function.
168 
169   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
170   @param[in]  ControllerHandle     The handle of the controller to test. This handle
171                                    must support a protocol interface that supplies
172                                    an I/O abstraction to the driver.
173   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
174                                    parameter is ignored by device drivers, and is optional for bus
175                                    drivers. For bus drivers, if this parameter is not NULL, then
176                                    the bus driver must determine if the bus controller specified
177                                    by ControllerHandle and the child controller specified
178                                    by RemainingDevicePath are both supported by this
179                                    bus driver.
180 
181   @retval EFI_SUCCESS              The device specified by ControllerHandle and
182                                    RemainingDevicePath is supported by the driver specified by This.
183   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
184                                    RemainingDevicePath is already being managed by the driver
185                                    specified by This.
186   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
187                                    RemainingDevicePath is already being managed by a different
188                                    driver or an application that requires exclusive access.
189                                    Currently not implemented.
190   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
191                                    RemainingDevicePath is not supported by the driver specified by This.
192 **/
193 EFI_STATUS
194 EFIAPI
195 UfsPassThruDriverBindingSupported (
196   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
197   IN EFI_HANDLE                   Controller,
198   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
199   );
200 
201 /**
202   Starts a device controller or a bus controller.
203 
204   The Start() function is designed to be invoked from the EFI boot service ConnectController().
205   As a result, much of the error checking on the parameters to Start() has been moved into this
206   common boot service. It is legal to call Start() from other locations,
207   but the following calling restrictions must be followed or the system behavior will not be deterministic.
208   1. ControllerHandle must be a valid EFI_HANDLE.
209   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
210      EFI_DEVICE_PATH_PROTOCOL.
211   3. Prior to calling Start(), the Supported() function for the driver specified by This must
212      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
213 
214   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
215   @param[in]  ControllerHandle     The handle of the controller to start. This handle
216                                    must support a protocol interface that supplies
217                                    an I/O abstraction to the driver.
218   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
219                                    parameter is ignored by device drivers, and is optional for bus
220                                    drivers. For a bus driver, if this parameter is NULL, then handles
221                                    for all the children of Controller are created by this driver.
222                                    If this parameter is not NULL and the first Device Path Node is
223                                    not the End of Device Path Node, then only the handle for the
224                                    child device specified by the first Device Path Node of
225                                    RemainingDevicePath is created by this driver.
226                                    If the first Device Path Node of RemainingDevicePath is
227                                    the End of Device Path Node, no child handle is created by this
228                                    driver.
229 
230   @retval EFI_SUCCESS              The device was started.
231   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
232   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
233   @retval Others                   The driver failded to start the device.
234 
235 **/
236 EFI_STATUS
237 EFIAPI
238 UfsPassThruDriverBindingStart (
239   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
240   IN EFI_HANDLE                   Controller,
241   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
242   );
243 
244 /**
245   Stops a device controller or a bus controller.
246 
247   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
248   As a result, much of the error checking on the parameters to Stop() has been moved
249   into this common boot service. It is legal to call Stop() from other locations,
250   but the following calling restrictions must be followed or the system behavior will not be deterministic.
251   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
252      same driver's Start() function.
253   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
254      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
255      Start() function, and the Start() function must have called OpenProtocol() on
256      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
257 
258   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
259   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
260                                 support a bus specific I/O protocol for the driver
261                                 to use to stop the device.
262   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
263   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
264                                 if NumberOfChildren is 0.
265 
266   @retval EFI_SUCCESS           The device was stopped.
267   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
268 
269 **/
270 EFI_STATUS
271 EFIAPI
272 UfsPassThruDriverBindingStop (
273   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
274   IN  EFI_HANDLE                      Controller,
275   IN  UINTN                           NumberOfChildren,
276   IN  EFI_HANDLE                      *ChildHandleBuffer
277   );
278 
279 //
280 // EFI Component Name Functions
281 //
282 /**
283   Retrieves a Unicode string that is the user readable name of the driver.
284 
285   This function retrieves the user readable name of a driver in the form of a
286   Unicode string. If the driver specified by This has a user readable name in
287   the language specified by Language, then a pointer to the driver name is
288   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
289   by This does not support the language specified by Language,
290   then EFI_UNSUPPORTED is returned.
291 
292   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
293                                 EFI_COMPONENT_NAME_PROTOCOL instance.
294 
295   @param  Language[in]          A pointer to a Null-terminated ASCII string
296                                 array indicating the language. This is the
297                                 language of the driver name that the caller is
298                                 requesting, and it must match one of the
299                                 languages specified in SupportedLanguages. The
300                                 number of languages supported by a driver is up
301                                 to the driver writer. Language is specified
302                                 in RFC 4646 or ISO 639-2 language code format.
303 
304   @param  DriverName[out]       A pointer to the Unicode string to return.
305                                 This Unicode string is the name of the
306                                 driver specified by This in the language
307                                 specified by Language.
308 
309   @retval EFI_SUCCESS           The Unicode string for the Driver specified by
310                                 This and the language specified by Language was
311                                 returned in DriverName.
312 
313   @retval EFI_INVALID_PARAMETER Language is NULL.
314 
315   @retval EFI_INVALID_PARAMETER DriverName is NULL.
316 
317   @retval EFI_UNSUPPORTED       The driver specified by This does not support
318                                 the language specified by Language.
319 
320 **/
321 EFI_STATUS
322 EFIAPI
323 UfsPassThruComponentNameGetDriverName (
324   IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
325   IN  CHAR8                        *Language,
326   OUT CHAR16                       **DriverName
327   );
328 
329 
330 /**
331   Retrieves a Unicode string that is the user readable name of the controller
332   that is being managed by a driver.
333 
334   This function retrieves the user readable name of the controller specified by
335   ControllerHandle and ChildHandle in the form of a Unicode string. If the
336   driver specified by This has a user readable name in the language specified by
337   Language, then a pointer to the controller name is returned in ControllerName,
338   and EFI_SUCCESS is returned.  If the driver specified by This is not currently
339   managing the controller specified by ControllerHandle and ChildHandle,
340   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
341   support the language specified by Language, then EFI_UNSUPPORTED is returned.
342 
343   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
344                                 EFI_COMPONENT_NAME_PROTOCOL instance.
345 
346   @param  ControllerHandle[in]  The handle of a controller that the driver
347                                 specified by This is managing.  This handle
348                                 specifies the controller whose name is to be
349                                 returned.
350 
351   @param  ChildHandle[in]       The handle of the child controller to retrieve
352                                 the name of.  This is an optional parameter that
353                                 may be NULL.  It will be NULL for device
354                                 drivers.  It will also be NULL for a bus drivers
355                                 that wish to retrieve the name of the bus
356                                 controller.  It will not be NULL for a bus
357                                 driver that wishes to retrieve the name of a
358                                 child controller.
359 
360   @param  Language[in]          A pointer to a Null-terminated ASCII string
361                                 array indicating the language.  This is the
362                                 language of the driver name that the caller is
363                                 requesting, and it must match one of the
364                                 languages specified in SupportedLanguages. The
365                                 number of languages supported by a driver is up
366                                 to the driver writer. Language is specified in
367                                 RFC 4646 or ISO 639-2 language code format.
368 
369   @param  ControllerName[out]   A pointer to the Unicode string to return.
370                                 This Unicode string is the name of the
371                                 controller specified by ControllerHandle and
372                                 ChildHandle in the language specified by
373                                 Language from the point of view of the driver
374                                 specified by This.
375 
376   @retval EFI_SUCCESS           The Unicode string for the user readable name in
377                                 the language specified by Language for the
378                                 driver specified by This was returned in
379                                 DriverName.
380 
381   @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
382 
383   @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
384                                 EFI_HANDLE.
385 
386   @retval EFI_INVALID_PARAMETER Language is NULL.
387 
388   @retval EFI_INVALID_PARAMETER ControllerName is NULL.
389 
390   @retval EFI_UNSUPPORTED       The driver specified by This is not currently
391                                 managing the controller specified by
392                                 ControllerHandle and ChildHandle.
393 
394   @retval EFI_UNSUPPORTED       The driver specified by This does not support
395                                 the language specified by Language.
396 
397 **/
398 EFI_STATUS
399 EFIAPI
400 UfsPassThruComponentNameGetControllerName (
401   IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
402   IN  EFI_HANDLE                                      ControllerHandle,
403   IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
404   IN  CHAR8                                           *Language,
405   OUT CHAR16                                          **ControllerName
406   );
407 
408 /**
409   Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function
410   supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the
411   nonblocking I/O functionality is optional.
412 
413   @param  This    A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
414   @param  Target  The Target is an array of size TARGET_MAX_BYTES and it represents
415                   the id of the SCSI device to send the SCSI Request Packet. Each
416                   transport driver may choose to utilize a subset of this size to suit the needs
417                   of transport target representation. For example, a Fibre Channel driver
418                   may use only 8 bytes (WWN) to represent an FC target.
419   @param  Lun     The LUN of the SCSI device to send the SCSI Request Packet.
420   @param  Packet  A pointer to the SCSI Request Packet to send to the SCSI device
421                   specified by Target and Lun.
422   @param  Event   If nonblocking I/O is not supported then Event is ignored, and blocking
423                   I/O is performed. If Event is NULL, then blocking I/O is performed. If
424                   Event is not NULL and non blocking I/O is supported, then
425                   nonblocking I/O is performed, and Event will be signaled when the
426                   SCSI Request Packet completes.
427 
428   @retval EFI_SUCCESS           The SCSI Request Packet was sent by the host. For bi-directional
429                                 commands, InTransferLength bytes were transferred from
430                                 InDataBuffer. For write and bi-directional commands,
431                                 OutTransferLength bytes were transferred by
432                                 OutDataBuffer.
433   @retval EFI_BAD_BUFFER_SIZE   The SCSI Request Packet was not executed. The number of bytes that
434                                 could be transferred is returned in InTransferLength. For write
435                                 and bi-directional commands, OutTransferLength bytes were
436                                 transferred by OutDataBuffer.
437   @retval EFI_NOT_READY         The SCSI Request Packet could not be sent because there are too many
438                                 SCSI Request Packets already queued. The caller may retry again later.
439   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to send the SCSI Request
440                                 Packet.
441   @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket are invalid.
442   @retval EFI_UNSUPPORTED       The command described by the SCSI Request Packet is not supported
443                                 by the host adapter. This includes the case of Bi-directional SCSI
444                                 commands not supported by the implementation. The SCSI Request
445                                 Packet was not sent, so no additional status information is available.
446   @retval EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.
447 
448 **/
449 EFI_STATUS
450 EFIAPI
451 UfsPassThruPassThru (
452   IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
453   IN UINT8                                              *Target,
454   IN UINT64                                             Lun,
455   IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
456   IN EFI_EVENT                                          Event OPTIONAL
457   );
458 
459 /**
460   Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on a SCSI channel. These
461   can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal
462   Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the
463   Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI
464   channel.
465 
466   @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
467   @param  Target On input, a pointer to the Target ID (an array of size
468                  TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel.
469                  On output, a pointer to the Target ID (an array of
470                  TARGET_MAX_BYTES) of the next SCSI device present on a SCSI
471                  channel. An input value of 0xF(all bytes in the array are 0xF) in the
472                  Target array retrieves the Target ID of the first SCSI device present on a
473                  SCSI channel.
474   @param  Lun    On input, a pointer to the LUN of a SCSI device present on the SCSI
475                  channel. On output, a pointer to the LUN of the next SCSI device present
476                  on a SCSI channel.
477 
478   @retval EFI_SUCCESS           The Target ID and LUN of the next SCSI device on the SCSI
479                                 channel was returned in Target and Lun.
480   @retval EFI_INVALID_PARAMETER Target array is not all 0xF, and Target and Lun were
481                                 not returned on a previous call to GetNextTargetLun().
482   @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.
483 
484 **/
485 EFI_STATUS
486 EFIAPI
487 UfsPassThruGetNextTargetLun (
488   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
489   IN OUT UINT8                           **Target,
490   IN OUT UINT64                          *Lun
491   );
492 
493 /**
494   Used to allocate and build a device path node for a SCSI device on a SCSI channel.
495 
496   @param  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
497   @param  Target     The Target is an array of size TARGET_MAX_BYTES and it specifies the
498                      Target ID of the SCSI device for which a device path node is to be
499                      allocated and built. Transport drivers may chose to utilize a subset of
500                      this size to suit the representation of targets. For example, a Fibre
501                      Channel driver may use only 8 bytes (WWN) in the array to represent a
502                      FC target.
503   @param  Lun        The LUN of the SCSI device for which a device path node is to be
504                      allocated and built.
505   @param  DevicePath A pointer to a single device path node that describes the SCSI device
506                      specified by Target and Lun. This function is responsible for
507                      allocating the buffer DevicePath with the boot service
508                      AllocatePool(). It is the caller's responsibility to free
509                      DevicePath when the caller is finished with DevicePath.
510 
511   @retval EFI_SUCCESS           The device path node that describes the SCSI device specified by
512                                 Target and Lun was allocated and returned in
513                                 DevicePath.
514   @retval EFI_INVALID_PARAMETER DevicePath is NULL.
515   @retval EFI_NOT_FOUND         The SCSI devices specified by Target and Lun does not exist
516                                 on the SCSI channel.
517   @retval EFI_OUT_OF_RESOURCES  There are not enough resources to allocate DevicePath.
518 
519 **/
520 EFI_STATUS
521 EFIAPI
522 UfsPassThruBuildDevicePath (
523   IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
524   IN     UINT8                              *Target,
525   IN     UINT64                             Lun,
526   IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
527   );
528 
529 /**
530   Used to translate a device path node to a Target ID and LUN.
531 
532   @param  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
533   @param  DevicePath A pointer to a single device path node that describes the SCSI device
534                      on the SCSI channel.
535   @param  Target     A pointer to the Target Array which represents the ID of a SCSI device
536                      on the SCSI channel.
537   @param  Lun        A pointer to the LUN of a SCSI device on the SCSI channel.
538 
539   @retval EFI_SUCCESS           DevicePath was successfully translated to a Target ID and
540                                 LUN, and they were returned in Target and Lun.
541   @retval EFI_INVALID_PARAMETER DevicePath or Target or Lun is NULL.
542   @retval EFI_NOT_FOUND         A valid translation from DevicePath to a Target ID and LUN
543                                 does not exist.
544   @retval EFI_UNSUPPORTED       This driver does not support the device path node type in
545                                  DevicePath.
546 
547 **/
548 EFI_STATUS
549 EFIAPI
550 UfsPassThruGetTargetLun (
551   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
552   IN  EFI_DEVICE_PATH_PROTOCOL           *DevicePath,
553   OUT UINT8                              **Target,
554   OUT UINT64                             *Lun
555   );
556 
557 /**
558   Resets a SCSI channel. This operation resets all the SCSI devices connected to the SCSI channel.
559 
560   @param  This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
561 
562   @retval EFI_SUCCESS      The SCSI channel was reset.
563   @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI channel.
564   @retval EFI_TIMEOUT      A timeout occurred while attempting to reset the SCSI channel.
565   @retval EFI_UNSUPPORTED  The SCSI channel does not support a channel reset operation.
566 
567 **/
568 EFI_STATUS
569 EFIAPI
570 UfsPassThruResetChannel (
571   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
572   );
573 
574 /**
575   Resets a SCSI logical unit that is connected to a SCSI channel.
576 
577   @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
578   @param  Target The Target is an array of size TARGET_MAX_BYTE and it represents the
579                  target port ID of the SCSI device containing the SCSI logical unit to
580                  reset. Transport drivers may chose to utilize a subset of this array to suit
581                  the representation of their targets.
582   @param  Lun    The LUN of the SCSI device to reset.
583 
584   @retval EFI_SUCCESS           The SCSI device specified by Target and Lun was reset.
585   @retval EFI_INVALID_PARAMETER Target or Lun is NULL.
586   @retval EFI_TIMEOUT           A timeout occurred while attempting to reset the SCSI device
587                                 specified by Target and Lun.
588   @retval EFI_UNSUPPORTED       The SCSI channel does not support a target reset operation.
589   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to reset the SCSI device
590                                  specified by Target and Lun.
591 
592 **/
593 EFI_STATUS
594 EFIAPI
595 UfsPassThruResetTargetLun (
596   IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
597   IN UINT8                              *Target,
598   IN UINT64                             Lun
599   );
600 
601 /**
602   Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either
603   be the list SCSI devices that are actually present on the SCSI channel, or the list of legal Target IDs
604   for the SCSI channel. Regardless, the caller of this function must probe the Target ID returned to
605   see if a SCSI device is actually present at that location on the SCSI channel.
606 
607   @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
608   @param  Target (TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel.
609                  On output, a pointer to the Target ID (an array of
610                  TARGET_MAX_BYTES) of the next SCSI device present on a SCSI
611                  channel. An input value of 0xF(all bytes in the array are 0xF) in the
612                  Target array retrieves the Target ID of the first SCSI device present on a
613                  SCSI channel.
614 
615   @retval EFI_SUCCESS           The Target ID of the next SCSI device on the SCSI
616                                 channel was returned in Target.
617   @retval EFI_INVALID_PARAMETER Target or Lun is NULL.
618   @retval EFI_TIMEOUT           Target array is not all 0xF, and Target was not
619                                 returned on a previous call to GetNextTarget().
620   @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.
621 
622 **/
623 EFI_STATUS
624 EFIAPI
625 UfsPassThruGetNextTarget (
626   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
627   IN OUT UINT8                           **Target
628   );
629 
630 /**
631   Sends a UFS-supported SCSI Request Packet to a UFS device that is attached to the UFS host controller.
632 
633   @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
634   @param[in]      Lun           The LUN of the UFS device to send the SCSI Request Packet.
635   @param[in, out] Packet        A pointer to the SCSI Request Packet to send to a specified Lun of the
636                                 UFS device.
637   @param[in]      Event         If nonblocking I/O is not supported then Event is ignored, and blocking
638                                 I/O is performed. If Event is NULL, then blocking I/O is performed. If
639                                 Event is not NULL and non blocking I/O is supported, then
640                                 nonblocking I/O is performed, and Event will be signaled when the
641                                 SCSI Request Packet completes.
642 
643   @retval EFI_SUCCESS           The SCSI Request Packet was sent by the host. For bi-directional
644                                 commands, InTransferLength bytes were transferred from
645                                 InDataBuffer. For write and bi-directional commands,
646                                 OutTransferLength bytes were transferred by
647                                 OutDataBuffer.
648   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to send the SCSI Request
649                                 Packet.
650   @retval EFI_OUT_OF_RESOURCES  The resource for transfer is not available.
651   @retval EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.
652 
653 **/
654 EFI_STATUS
655 UfsExecScsiCmds (
656   IN     UFS_PASS_THRU_PRIVATE_DATA                  *Private,
657   IN     UINT8                                       Lun,
658   IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
659   IN     EFI_EVENT                                   Event    OPTIONAL
660   );
661 
662 /**
663   Initialize the UFS host controller.
664 
665   @param[in] Private                 The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
666 
667   @retval EFI_SUCCESS                The NVM Express Controller is initialized successfully.
668   @retval Others                     A device error occurred while initializing the controller.
669 
670 **/
671 EFI_STATUS
672 UfsControllerInit (
673   IN  UFS_PASS_THRU_PRIVATE_DATA     *Private
674   );
675 
676 /**
677   Stop the UFS host controller.
678 
679   @param[in] Private                 The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
680 
681   @retval EFI_SUCCESS                The Ufs Host Controller is stopped successfully.
682   @retval Others                     A device error occurred while stopping the controller.
683 
684 **/
685 EFI_STATUS
686 UfsControllerStop (
687   IN  UFS_PASS_THRU_PRIVATE_DATA     *Private
688   );
689 
690 /**
691   Allocate common buffer for host and UFS bus master access simultaneously.
692 
693   @param[in]  Private                The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
694   @param[in]  Size                   The length of buffer to be allocated.
695   @param[out] CmdDescHost            A pointer to store the base system memory address of the allocated range.
696   @param[out] CmdDescPhyAddr         The resulting map address for the UFS bus master to use to access the hosts CmdDescHost.
697   @param[out] CmdDescMapping         A resulting value to pass to Unmap().
698 
699   @retval EFI_SUCCESS                The common buffer was allocated successfully.
700   @retval EFI_DEVICE_ERROR           The allocation fails.
701   @retval EFI_OUT_OF_RESOURCES       The memory resource is insufficient.
702 
703 **/
704 EFI_STATUS
705 UfsAllocateAlignCommonBuffer (
706   IN     UFS_PASS_THRU_PRIVATE_DATA    *Private,
707   IN     UINTN                         Size,
708      OUT VOID                          **CmdDescHost,
709      OUT EFI_PHYSICAL_ADDRESS          *CmdDescPhyAddr,
710      OUT VOID                          **CmdDescMapping
711   );
712 
713 /**
714   Set specified flag to 1 on a UFS device.
715 
716   @param[in]  Private           The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
717   @param[in]  FlagId            The ID of flag to be set.
718 
719   @retval EFI_SUCCESS           The flag was set successfully.
720   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to set the flag.
721   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of setting the flag.
722 
723 **/
724 EFI_STATUS
725 UfsSetFlag (
726   IN  UFS_PASS_THRU_PRIVATE_DATA   *Private,
727   IN  UINT8                        FlagId
728   );
729 
730 /**
731   Read specified flag from a UFS device.
732 
733   @param[in]  Private           The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
734   @param[in]  FlagId            The ID of flag to be read.
735   @param[out] Value             The flag's value.
736 
737   @retval EFI_SUCCESS           The flag was read successfully.
738   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to read the flag.
739   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of reading the flag.
740 
741 **/
742 EFI_STATUS
743 UfsReadFlag (
744   IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,
745   IN     UINT8                        FlagId,
746      OUT UINT8                        *Value
747   );
748 
749 /**
750   Read or write specified flag of a UFS device.
751 
752   @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
753   @param[in]      Read          The boolean variable to show r/w direction.
754   @param[in]      FlagId        The ID of flag to be read or written.
755   @param[in, out] Value         The value to set or clear flag.
756 
757   @retval EFI_SUCCESS           The flag was read/written successfully.
758   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the flag.
759   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the flag.
760 
761 **/
762 EFI_STATUS
763 UfsRwFlags (
764   IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,
765   IN     BOOLEAN                      Read,
766   IN     UINT8                        FlagId,
767   IN OUT UINT8                        *Value
768   );
769 
770 /**
771   Read or write specified device descriptor of a UFS device.
772 
773   @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
774   @param[in]      Read          The boolean variable to show r/w direction.
775   @param[in]      DescId        The ID of device descriptor.
776   @param[in]      Index         The Index of device descriptor.
777   @param[in]      Selector      The Selector of device descriptor.
778   @param[in, out] Descriptor    The buffer of device descriptor to be read or written.
779   @param[in, out] DescSize      The size of device descriptor buffer. On input, the size, in bytes,
780                                 of the data buffer specified by Descriptor. On output, the number
781                                 of bytes that were actually transferred.
782 
783   @retval EFI_SUCCESS           The device descriptor was read/written successfully.
784   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the device descriptor.
785   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the device descriptor.
786 
787 **/
788 EFI_STATUS
789 UfsRwDeviceDesc (
790   IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,
791   IN     BOOLEAN                      Read,
792   IN     UINT8                        DescId,
793   IN     UINT8                        Index,
794   IN     UINT8                        Selector,
795   IN OUT VOID                         *Descriptor,
796   IN OUT UINT32                       *DescSize
797   );
798 
799 /**
800   Read or write specified attribute of a UFS device.
801 
802   @param[in]      Private       The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
803   @param[in]      Read          The boolean variable to show r/w direction.
804   @param[in]      AttrId        The ID of Attribute.
805   @param[in]      Index         The Index of Attribute.
806   @param[in]      Selector      The Selector of Attribute.
807   @param[in, out] Attributes    The value of Attribute to be read or written.
808 
809   @retval EFI_SUCCESS           The Attribute was read/written successfully.
810   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to r/w the Attribute.
811   @retval EFI_TIMEOUT           A timeout occurred while waiting for the completion of r/w the Attribute.
812 
813 **/
814 EFI_STATUS
815 UfsRwAttributes (
816   IN     UFS_PASS_THRU_PRIVATE_DATA   *Private,
817   IN     BOOLEAN                      Read,
818   IN     UINT8                        AttrId,
819   IN     UINT8                        Index,
820   IN     UINT8                        Selector,
821   IN OUT UINT32                       *Attributes
822   );
823 
824 /**
825   Sends NOP IN cmd to a UFS device for initialization process request.
826   For more details, please refer to UFS 2.0 spec Figure 13.3.
827 
828   @param[in]  Private           The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
829 
830   @retval EFI_SUCCESS           The NOP IN command was sent by the host. The NOP OUT response was
831                                 received successfully.
832   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to execute NOP IN command.
833   @retval EFI_OUT_OF_RESOURCES  The resource for transfer is not available.
834   @retval EFI_TIMEOUT           A timeout occurred while waiting for the NOP IN command to execute.
835 
836 **/
837 EFI_STATUS
838 UfsExecNopCmds (
839   IN  UFS_PASS_THRU_PRIVATE_DATA       *Private
840   );
841 
842 /**
843   Call back function when the timer event is signaled.
844 
845   @param[in]  Event     The Event this notify function registered to.
846   @param[in]  Context   Pointer to the context data registered to the Event.
847 
848 **/
849 VOID
850 EFIAPI
851 ProcessAsyncTaskList (
852   IN EFI_EVENT          Event,
853   IN VOID               *Context
854   );
855 
856 /**
857   Internal helper function which will signal the caller event and clean up
858   resources.
859 
860   @param[in] Private   The pointer to the UFS_PASS_THRU_PRIVATE_DATA data
861                        structure.
862   @param[in] TransReq  The pointer to the UFS_PASS_THRU_TRANS_REQ data
863                        structure.
864 
865 **/
866 VOID
867 EFIAPI
868 SignalCallerEvent (
869   IN UFS_PASS_THRU_PRIVATE_DATA      *Private,
870   IN UFS_PASS_THRU_TRANS_REQ         *TransReq
871   );
872 
873 /**
874   Read or write specified device descriptor of a UFS device.
875 
876   The function is used to read/write UFS device descriptors. The consumer of this API is
877   responsible for allocating the data buffer pointed by Descriptor.
878 
879   @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
880   @param[in]      Read          The boolean variable to show r/w direction.
881   @param[in]      DescId        The ID of device descriptor.
882   @param[in]      Index         The Index of device descriptor.
883   @param[in]      Selector      The Selector of device descriptor.
884   @param[in, out] Descriptor    The buffer of device descriptor to be read or written.
885   @param[in, out] DescSize      The size of device descriptor buffer. On input, the size, in bytes,
886                                 of the data buffer specified by Descriptor. On output, the number
887                                 of bytes that were actually transferred.
888 
889   @retval EFI_SUCCESS           The device descriptor is read/written successfully.
890   @retval EFI_INVALID_PARAMETER This is NULL or Descriptor is NULL or DescSize is NULL.
891                                 DescId, Index and Selector are invalid combination to point to a
892                                 type of UFS device descriptor.
893   @retval EFI_DEVICE_ERROR      The device descriptor is not read/written successfully.
894 
895 **/
896 EFI_STATUS
897 EFIAPI
898 UfsRwUfsDescriptor (
899   IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
900   IN BOOLEAN                           Read,
901   IN UINT8                             DescId,
902   IN UINT8                             Index,
903   IN UINT8                             Selector,
904   IN OUT UINT8                         *Descriptor,
905   IN OUT UINT32                        *DescSize
906   );
907 
908 /**
909   Read or write specified flag of a UFS device.
910 
911   The function is used to read/write UFS flag descriptors. The consumer of this API is responsible
912   for allocating the buffer pointed by Flag. The buffer size is 1 byte as UFS flag descriptor is
913   just a single Boolean value that represents a TRUE or FALSE, '0' or '1', ON or OFF type of value.
914 
915   @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
916   @param[in]      Read          The boolean variable to show r/w direction.
917   @param[in]      FlagId        The ID of flag to be read or written.
918   @param[in, out] Flag          The buffer to set or clear flag.
919 
920   @retval EFI_SUCCESS           The flag descriptor is set/clear successfully.
921   @retval EFI_INVALID_PARAMETER This is NULL or Flag is NULL.
922                                 FlagId is an invalid UFS flag ID.
923   @retval EFI_DEVICE_ERROR      The flag is not set/clear successfully.
924 
925 **/
926 EFI_STATUS
927 EFIAPI
928 UfsRwUfsFlag (
929   IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
930   IN BOOLEAN                           Read,
931   IN UINT8                             FlagId,
932   IN OUT UINT8                         *Flag
933   );
934 
935 /**
936   Read or write specified attribute of a UFS device.
937 
938   The function is used to read/write UFS attributes. The consumer of this API is responsible for
939   allocating the data buffer pointed by Attribute.
940 
941   @param[in]      This          The pointer to the EFI_UFS_DEVICE_CONFIG_PROTOCOL instance.
942   @param[in]      Read          The boolean variable to show r/w direction.
943   @param[in]      AttrId        The ID of Attribute.
944   @param[in]      Index         The Index of Attribute.
945   @param[in]      Selector      The Selector of Attribute.
946   @param[in, out] Attribute     The buffer of Attribute to be read or written.
947   @param[in, out] AttrSize      The size of Attribute buffer. On input, the size, in bytes, of the
948                                 data buffer specified by Attribute. On output, the number of bytes
949                                 that were actually transferred.
950 
951   @retval EFI_SUCCESS           The attribute is read/written successfully.
952   @retval EFI_INVALID_PARAMETER This is NULL or Attribute is NULL or AttrSize is NULL.
953                                 AttrId, Index and Selector are invalid combination to point to a
954                                 type of UFS attribute.
955   @retval EFI_DEVICE_ERROR      The attribute is not read/written successfully.
956 
957 **/
958 EFI_STATUS
959 EFIAPI
960 UfsRwUfsAttribute (
961   IN EFI_UFS_DEVICE_CONFIG_PROTOCOL    *This,
962   IN BOOLEAN                           Read,
963   IN UINT8                             AttrId,
964   IN UINT8                             Index,
965   IN UINT8                             Selector,
966   IN OUT UINT8                         *Attribute,
967   IN OUT UINT32                        *AttrSize
968   );
969 
970 /**
971   Execute UIC command.
972 
973   @param[in]      This        Pointer to driver interface produced by the UFS controller.
974   @param[in, out] UicCommand  Descriptor of the command that will be executed.
975 
976   @retval EFI_SUCCESS            Command executed successfully.
977   @retval EFI_INVALID_PARAMETER  This or UicCommand is NULL.
978   @retval Others                 Command failed to execute.
979 **/
980 EFI_STATUS
981 EFIAPI
982 UfsHcDriverInterfaceExecUicCommand (
983   IN     EDKII_UFS_HC_DRIVER_INTERFACE  *This,
984   IN OUT EDKII_UIC_COMMAND              *UicCommand
985   );
986 
987 /**
988   Initializes UfsHcInfo field in private data.
989 
990   @param[in] Private  Pointer to host controller private data.
991 
992   @retval EFI_SUCCESS  UfsHcInfo initialized successfully.
993   @retval Others       Failed to initalize UfsHcInfo.
994 **/
995 EFI_STATUS
996 GetUfsHcInfo (
997   IN UFS_PASS_THRU_PRIVATE_DATA  *Private
998   );
999 
1000 extern EFI_COMPONENT_NAME_PROTOCOL  gUfsPassThruComponentName;
1001 extern EFI_COMPONENT_NAME2_PROTOCOL gUfsPassThruComponentName2;
1002 extern EFI_DRIVER_BINDING_PROTOCOL  gUfsPassThruDriverBinding;
1003 extern EDKII_UFS_HC_PLATFORM_PROTOCOL  *mUfsHcPlatform;
1004 
1005 #endif
1006