/* Read or write specified device descriptor of a UFS device. */
EFI_STATUS UfsRwDeviceDesc(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN BOOLEAN Read, IN UINT8 DescId, IN UINT8 Index, IN UINT8 Selector, IN OUT VOID *Descriptor, IN OUT UINT32 *DescSize)
/* Read or write specified device descriptor of a UFS device. */
EFI_STATUS UfsRwDeviceDesc(IN UFS_PASS_THRU_PRIVATE_DATA *Private, IN BOOLEAN Read, IN UINT8 DescId, IN UINT8 Index, IN UINT8 Selector, IN OUT VOID *Descriptor, IN OUT UINT32 *DescSize)
{
  UFS_DEVICE_MANAGEMENT_REQUEST_PACKET  Packet;
  EFI_STATUS                            Status;
  if (DescSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));
  if (Read) {
    Packet.DataDirection = UfsDataIn;
    Packet.Opcode        = UtpQueryFuncOpcodeRdDesc;
  } else {
    Packet.DataDirection = UfsDataOut;
    Packet.Opcode        = UtpQueryFuncOpcodeWrDesc;
  }
  Packet.DataBuffer     = Descriptor;
  Packet.TransferLength = *DescSize;
  Packet.DescId         = DescId;
  Packet.Index          = Index;
  Packet.Selector       = Selector;
  Packet.Timeout        = UFS_TIMEOUT;
  Status = UfsSendDmRequest (Private, &Packet);
  if (EFI_ERROR (Status)) {
    *DescSize = 0;
  } else {
    *DescSize = Packet.TransferLength;
  }
  return Status;
}