IN EFI_EVENT Event OPTIONAL\r
)\r
{\r
- NVME_CONTROLLER_PRIVATE_DATA *Private;\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- NVME_SQ *Sq;\r
- NVME_CQ *Cq;\r
- UINT16 QueueId;\r
- UINT32 Bytes;\r
- UINT16 Offset;\r
- EFI_EVENT TimerEvent;\r
- EFI_PCI_IO_PROTOCOL_OPERATION Flag;\r
- EFI_PHYSICAL_ADDRESS PhyAddr;\r
- VOID *MapData;\r
- VOID *MapMeta;\r
- VOID *MapPrpList;\r
- UINTN MapLength;\r
- UINT64 *Prp;\r
- VOID *PrpListHost;\r
- UINTN PrpListNo;\r
- UINT32 Data;\r
- NVME_PASS_THRU_ASYNC_REQ *AsyncRequest;\r
- EFI_TPL OldTpl;\r
+ NVME_CONTROLLER_PRIVATE_DATA *Private;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ NVME_SQ *Sq;\r
+ NVME_CQ *Cq;\r
+ UINT16 QueueId;\r
+ UINT32 Bytes;\r
+ UINT16 Offset;\r
+ EFI_EVENT TimerEvent;\r
+ EFI_PCI_IO_PROTOCOL_OPERATION Flag;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+ VOID *MapData;\r
+ VOID *MapMeta;\r
+ VOID *MapPrpList;\r
+ UINTN MapLength;\r
+ UINT64 *Prp;\r
+ VOID *PrpListHost;\r
+ UINTN PrpListNo;\r
+ UINT32 Attributes;\r
+ UINT32 IoAlign;\r
+ UINT32 MaxTransLen;\r
+ UINT32 Data;\r
+ NVME_PASS_THRU_ASYNC_REQ *AsyncRequest;\r
+ EFI_TPL OldTpl;\r
\r
//\r
// check the data fields in Packet parameter.\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ //\r
+ // 'Attributes' with neither EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL nor\r
+ // EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL set is an illegal\r
+ // configuration.\r
+ //\r
+ Attributes = This->Mode->Attributes;\r
+ if ((Attributes & (EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL |\r
+ EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL)) == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Buffer alignment check for TransferBuffer & MetadataBuffer.\r
+ //\r
+ IoAlign = This->Mode->IoAlign;\r
+ if (IoAlign > 0 && (((UINTN) Packet->TransferBuffer & (IoAlign - 1)) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (IoAlign > 0 && (((UINTN) Packet->MetadataBuffer & (IoAlign - 1)) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This);\r
+\r
+ //\r
+ // Check NamespaceId is valid or not.\r
+ //\r
+ if ((NamespaceId > Private->ControllerData->Nn) &&\r
+ (NamespaceId != (UINT32) -1)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check whether TransferLength exceeds the maximum data transfer size.\r
+ //\r
+ if (Private->ControllerData->Mdts != 0) {\r
+ MaxTransLen = (1 << (Private->ControllerData->Mdts)) *\r
+ (1 << (Private->Cap.Mpsmin + 12));\r
+ if (Packet->TransferLength > MaxTransLen) {\r
+ Packet->TransferLength = MaxTransLen;\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+ }\r
+\r
PciIo = Private->PciIo;\r
MapData = NULL;\r
MapMeta = NULL;\r
// processor and a PCI Bus Master. It's caller's responsbility to ensure this.\r
//\r
if (((Sq->Opc & (BIT0 | BIT1)) != 0) && (Sq->Opc != NVME_ADMIN_CRIOCQ_CMD) && (Sq->Opc != NVME_ADMIN_CRIOSQ_CMD)) {\r
+ if ((Packet->TransferLength == 0) || (Packet->TransferBuffer == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
if ((Sq->Opc & BIT0) != 0) {\r
Flag = EfiPciIoOperationBusMasterRead;\r
} else {\r
Sq->Prp[0] = PhyAddr;\r
Sq->Prp[1] = 0;\r
\r
- MapLength = Packet->MetadataLength;\r
- if(Packet->MetadataBuffer != NULL) {\r
+ if((Packet->MetadataLength != 0) && (Packet->MetadataBuffer != NULL)) {\r
MapLength = Packet->MetadataLength;\r
Status = PciIo->Map (\r
PciIo,\r