@@ -1011,9 +1011,11 @@ NvmExpressDriverBindingStart (
1011
1011
EFI_PHYSICAL_ADDRESS MappedAddr ;
1012
1012
UINTN Bytes ;
1013
1013
EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL * Passthru ;
1014
- // MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1015
- UINTN QueuePageCount = PcdGetBool (PcdSupportAlternativeQueueSize ) ?
1016
- NVME_ALTERNATIVE_TOTAL_QUEUE_BUFFER_IN_PAGES : 6 ;
1014
+ // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer
1015
+ NVME_AQA * Aqa ;
1016
+ UINTN AdminQueuePageCount ; // MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1017
+
1018
+ // MU_CHANGE [END] - Allocate IO Queue Buffer
1017
1019
1018
1020
DEBUG ((DEBUG_INFO , "NvmExpressDriverBindingStart: start\n" ));
1019
1021
@@ -1087,9 +1089,41 @@ NvmExpressDriverBindingStart (
1087
1089
1088
1090
// MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1089
1091
1092
+ // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer
1090
1093
//
1091
- // Depending on PCD disablement, either support the default or alternative
1092
- // queue sizes.
1094
+ // Set the Admin Queue Atttributes
1095
+ //
1096
+ Aqa = AllocateZeroPool (sizeof (NVME_AQA ));
1097
+
1098
+ if (Aqa == NULL ) {
1099
+ DEBUG ((DEBUG_ERROR , "NvmExpressDriverBindingStart: allocating pool for Nvme Aqa Data failed!\n" ));
1100
+ Status = EFI_OUT_OF_RESOURCES ;
1101
+ goto Exit ;
1102
+ }
1103
+
1104
+ // Set the sizes of the admin submission & completion queues in number of entries
1105
+ Aqa -> Asqs = PcdGetBool (PcdSupportAlternativeQueueSize ) ? MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE , Private -> Cap .Mqes ) : NVME_ASQ_SIZE ;
1106
+ Aqa -> Rsvd1 = 0 ;
1107
+ Aqa -> Acqs = PcdGetBool (PcdSupportAlternativeQueueSize ) ? MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE , Private -> Cap .Mqes ) : NVME_ACQ_SIZE ;
1108
+ Aqa -> Rsvd2 = 0 ;
1109
+
1110
+ //
1111
+ // Save Queue Pair Data for admin queues in controller data structure
1112
+ //
1113
+ Private -> SqData [0 ].NumberOfEntries = Aqa -> Asqs ;
1114
+ Private -> CqData [0 ].NumberOfEntries = Aqa -> Acqs ;
1115
+
1116
+ //
1117
+ // Set admin queue entry size to default
1118
+ //
1119
+ Private -> SqData [0 ].EntrySize = NVME_IOSQES_MIN ;
1120
+ Private -> CqData [0 ].EntrySize = NVME_IOCQES_MIN ;
1121
+
1122
+ // Calculate the number of pages required for the admin queues
1123
+ // TODO create helper functions for calculating num pages for a queue.
1124
+ AdminQueuePageCount = EFI_SIZE_TO_PAGES (Private -> SqData [0 ].NumberOfEntries * LShiftU64 (2 , Private -> SqData [0 ].EntrySize ))
1125
+ + EFI_SIZE_TO_PAGES (Private -> CqData [0 ].NumberOfEntries * LShiftU64 (2 , CqData [0 ].EntrySize ));
1126
+ // MU_CHANGE [END] - Allocate IO Queue Buffer
1093
1127
//
1094
1128
// Default:
1095
1129
// 6 x 4kB aligned buffers will be carved out of this buffer.
@@ -1113,20 +1147,26 @@ NvmExpressDriverBindingStart (
1113
1147
//
1114
1148
// Allocate 15 pages of memory, then map it for bus master read and write.
1115
1149
//
1150
+
1151
+ // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer
1152
+ //
1153
+ // Allocate Admin Queues
1154
+ //
1116
1155
Status = PciIo -> AllocateBuffer (
1117
1156
PciIo ,
1118
1157
AllocateAnyPages ,
1119
1158
EfiBootServicesData ,
1120
- QueuePageCount ,
1159
+ AdminQueuePageCount ,
1121
1160
(VOID * * )& Private -> Buffer ,
1122
1161
0
1123
1162
);
1163
+ // MU_CHANGE [END] - Allocate IO Queue Buffer
1124
1164
if (EFI_ERROR (Status )) {
1125
1165
goto Exit ;
1126
1166
}
1127
1167
1128
1168
// MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1129
- Bytes = EFI_PAGES_TO_SIZE (QueuePageCount );
1169
+ Bytes = EFI_PAGES_TO_SIZE (AdminQueuePageCount ); // MU_CHANGE - Allocate IO Queue Buffer
1130
1170
Status = PciIo -> Map (
1131
1171
PciIo ,
1132
1172
EfiPciIoOperationBusMasterCommonBuffer ,
@@ -1137,7 +1177,8 @@ NvmExpressDriverBindingStart (
1137
1177
);
1138
1178
1139
1179
// MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1140
- if (EFI_ERROR (Status ) || (Bytes != EFI_PAGES_TO_SIZE (QueuePageCount ))) {
1180
+ if (EFI_ERROR (Status ) || (Bytes != EFI_PAGES_TO_SIZE (AdminQueuePageCount ))) {
1181
+ // MU_CHANGE - Allocate IO Queue Buffer
1141
1182
goto Exit ;
1142
1183
}
1143
1184
@@ -1158,7 +1199,7 @@ NvmExpressDriverBindingStart (
1158
1199
InitializeListHead (& Private -> AsyncPassThruQueue );
1159
1200
InitializeListHead (& Private -> UnsubmittedSubtasks );
1160
1201
1161
- Status = NvmeControllerInit (Private );
1202
+ Status = NvmeControllerInit (Private , Aqa ); // MU_CHANGE - Allocate IO Queue Buffer
1162
1203
if (EFI_ERROR (Status )) {
1163
1204
goto Exit ;
1164
1205
}
@@ -1256,7 +1297,14 @@ NvmExpressDriverBindingStart (
1256
1297
1257
1298
if ((Private != NULL ) && (Private -> Buffer != NULL )) {
1258
1299
// MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1259
- PciIo -> FreeBuffer (PciIo , QueuePageCount , Private -> Buffer );
1300
+ // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer
1301
+ Status = PciIo -> FreeBuffer (PciIo , AdminQueuePageCount , Private -> Buffer );
1302
+
1303
+ if (EFI_STATUS_ERROR (Status )) {
1304
+ DEBUG ((DEBUG_ERROR , "%a(%d): FreeBuffer failed with %r\n" , __FILE__ , __LINE__ , Status ));
1305
+ }
1306
+
1307
+ // MU_CHANGE [END] - Allocate IO Queue Buffer
1260
1308
}
1261
1309
1262
1310
if ((Private != NULL ) && (Private -> ControllerData != NULL )) {
@@ -1333,8 +1381,8 @@ NvmExpressDriverBindingStop (
1333
1381
BOOLEAN IsEmpty ;
1334
1382
EFI_TPL OldTpl ;
1335
1383
// MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1336
- UINT16 QueuePageCount = PcdGetBool ( PcdSupportAlternativeQueueSize ) ?
1337
- NVME_ALTERNATIVE_TOTAL_QUEUE_BUFFER_IN_PAGES : 6 ;
1384
+ // MU_CHANGE - Allocate IO Queue Buffer
1385
+ UINTN QueuePageCount ;
1338
1386
1339
1387
if (NumberOfChildren == 0 ) {
1340
1388
Status = gBS -> OpenProtocol (
@@ -1380,11 +1428,34 @@ NvmExpressDriverBindingStop (
1380
1428
Private -> PciIo -> Unmap (Private -> PciIo , Private -> Mapping );
1381
1429
}
1382
1430
1431
+ // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer
1432
+ QueuePageCount = EFI_SIZE_TO_PAGES (Private -> SqData [0 ].NumberOfEntries * LShiftU64 (2 , Private -> SqData [0 ].EntrySize ))
1433
+ + EFI_SIZE_TO_PAGES (Private -> CqData [0 ].NumberOfEntries * LShiftU64 (2 , Private -> CqData [0 ].EntrySize ));
1434
+ // MU_CHANGE [END] - Allocate IO Queue Buffer
1383
1435
if (Private -> Buffer != NULL ) {
1384
1436
// MU_CHANGE - Support alternative hardware queue sizes in NVME driver
1385
1437
Private -> PciIo -> FreeBuffer (Private -> PciIo , QueuePageCount , Private -> Buffer );
1386
1438
}
1387
1439
1440
+ // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer
1441
+ if (Private -> DataQueueMapping != NULL ) {
1442
+ Status = Private -> PciIo -> Unmap (Private -> PciIo , Private -> DataQueueMapping );
1443
+
1444
+ if (EFI_ERROR (Status )) {
1445
+ DEBUG ((DEBUG_ERROR , "%a(%d): Unmap DataQueueMapping failed %r\n" , __FILE__ , __LINE__ , Status ));
1446
+ }
1447
+ }
1448
+
1449
+ if (Private -> DataQueueBuffer != NULL ) {
1450
+ Status = Private -> PciIo -> FreeBuffer (Private -> PciIo , QueuePageCount * Private -> NumberOfDataQueuePairs , Private -> DataQueueBuffer );
1451
+
1452
+ if (EFI_ERROR (Status )) {
1453
+ DEBUG ((DEBUG_ERROR , "%a(%d): FreeBuffer DataQueueBuffer failed %r\n" , __FILE__ , __LINE__ , Status ));
1454
+ }
1455
+ }
1456
+
1457
+ // MU_CHANGE [END] - Allocate IO Queue Buffer
1458
+
1388
1459
FreePool (Private -> ControllerData );
1389
1460
FreePool (Private );
1390
1461
}
0 commit comments