]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiIbft.c
1)update function header coding style issue
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiIbft.c
CommitLineData
12618416 1/** @file\r
2 Implementation for iSCSI Boot Firmware Table publication.\r
6a690e23 3\r
d8c04564 4Copyright (c) 2004 - 2008, Intel Corporation.<BR>\r
7a444476 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 12\r
12618416 13**/\r
6a690e23 14\r
15#include "IScsiImpl.h"\r
16\r
12618416 17/**\r
18 Initialize the header of the iSCSI Boot Firmware Table.\r
19 \r
d8c04564 20 @param[in] Header The header of the iSCSI Boot Firmware Table.\r
12618416 21**/\r
6a690e23 22VOID\r
23IScsiInitIbfTableHeader (\r
24 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header\r
25 )\r
6a690e23 26{\r
e48e37fc 27 ZeroMem (Header, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER));\r
6a690e23 28\r
29 Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;\r
30 Header->Length = IBFT_HEAP_OFFSET;\r
31 Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;\r
32 Header->Checksum = 0;\r
33\r
34 Header->OemId[0] = 'I';\r
35 Header->OemId[1] = 'N';\r
36 Header->OemId[2] = 'T';\r
37 Header->OemId[3] = 'E';\r
38 Header->OemId[4] = 'L';\r
39}\r
40\r
12618416 41/**\r
42 Initialize the control section of the iSCSI Boot Firmware Table.\r
43 \r
d8c04564 44 @param[in] Table The ACPI table.\r
45 @param[in] HandleCount The number of the handles associated with iSCSI sessions, it's\r
12618416 46 equal to the number of iSCSI sessions.\r
12618416 47**/\r
6a690e23 48VOID\r
49IScsiInitControlSection (\r
50 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
51 IN UINTN HandleCount\r
52 )\r
6a690e23 53{\r
54 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
55 UINTN NumOffset;\r
56\r
57 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
58\r
e48e37fc 59 ZeroMem (Control, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE));\r
6a690e23 60\r
61 Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;\r
62 Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;\r
63 Control->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);\r
64\r
65 //\r
66 // Each session occupies two offsets, one for the NIC section,\r
67 // the other for the Target section.\r
68 //\r
69 NumOffset = 2 * HandleCount;\r
70 if (NumOffset > 4) {\r
71 //\r
72 // Need expand the control section if more than 2 NIC/Target sections\r
73 // exist.\r
74 //\r
69b0882d 75 Control->Header.Length = (UINT16) (Control->Header.Length + (NumOffset - 4) * sizeof (UINT16));\r
6a690e23 76 }\r
77}\r
78\r
12618416 79/**\r
80 Add one item into the heap.\r
81\r
d8c04564 82 @param[in, out] Heap On input, the current address of the heap; On output, the address of\r
83 the heap after the item is added.\r
84 @param[in] Data The data to add into the heap.\r
85 @param[in] Len Length of the Data in byte.\r
12618416 86**/\r
6a690e23 87VOID\r
88IScsiAddHeapItem (\r
89 IN OUT UINT8 **Heap,\r
90 IN VOID *Data,\r
91 IN UINTN Len\r
92 )\r
6a690e23 93{\r
94 //\r
95 // Add one byte for the NULL delimiter.\r
96 //\r
97 *Heap -= Len + 1;\r
98\r
e48e37fc 99 CopyMem (*Heap, Data, Len);\r
6a690e23 100 *(*Heap + Len) = 0;\r
101}\r
102\r
12618416 103/**\r
104 Fill the Initiator section of the iSCSI Boot Firmware Table.\r
105\r
d8c04564 106 @param[in] Table The ACPI table.\r
107 @param[in, out] Heap The heap.\r
108 @param[in] Handle The handle associated with the iSCSI session.\r
12618416 109**/\r
6a690e23 110VOID\r
111IScsiFillInitiatorSection (\r
112 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
113 IN OUT UINT8 **Heap,\r
114 IN EFI_HANDLE Handle\r
115 )\r
6a690e23 116{\r
117 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
118 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;\r
119 ISCSI_DRIVER_DATA *DriverData;\r
120 ISCSI_SESSION *Session;\r
121 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
122 EFI_STATUS Status;\r
123\r
124 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
125\r
126 //\r
127 // Initiator section immediately follows the control section.\r
128 //\r
129 Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *) ((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length));\r
130\r
131 Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table);\r
132\r
e48e37fc 133 ZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE));\r
6a690e23 134\r
135 Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;\r
136 Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;\r
137 Initiator->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);\r
138 Initiator->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BOOT_SELECTED;\r
139\r
140 //\r
141 // Get the identifier from the handle.\r
142 //\r
69b0882d 143 Status = gBS->HandleProtocol (Handle, &mIScsiPrivateGuid, (VOID **) &IScsiIdentifier);\r
6a690e23 144 if (EFI_ERROR (Status)) {\r
145 ASSERT (FALSE);\r
146 return ;\r
147 }\r
148\r
149 DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
150 Session = &DriverData->Session;\r
151\r
152 //\r
153 // Fill the iSCSI Initiator Name into the heap.\r
154 //\r
155 IScsiAddHeapItem (Heap, Session->InitiatorName, Session->InitiatorNameLength - 1);\r
156\r
157 Initiator->IScsiNameLength = (UINT16) (Session->InitiatorNameLength - 1);\r
158 Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
159}\r
160\r
12618416 161/**\r
162 Map the v4 IP address into v6 IP address.\r
163\r
d8c04564 164 @param[in] V4 The v4 IP address.\r
165 @param[out] V6 The v6 IP address.\r
12618416 166**/\r
6a690e23 167VOID\r
168IScsiMapV4ToV6Addr (\r
169 IN EFI_IPv4_ADDRESS *V4,\r
170 OUT EFI_IPv6_ADDRESS *V6\r
171 )\r
6a690e23 172{\r
173 UINTN Index;\r
174\r
e48e37fc 175 ZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));\r
6a690e23 176\r
177 V6->Addr[10] = 0xff;\r
178 V6->Addr[11] = 0xff;\r
179\r
180 for (Index = 0; Index < 4; Index++) {\r
181 V6->Addr[12 + Index] = V4->Addr[Index];\r
182 }\r
183}\r
184\r
12618416 185/**\r
6a690e23 186 Get the NIC's PCI location and return it accroding to the composited\r
187 format defined in iSCSI Boot Firmware Table.\r
6a690e23 188\r
d8c04564 189 @param[in] Controller The handle of the controller.\r
6a690e23 190\r
d8c04564 191 @return UINT16 The composited representation of the NIC PCI location.\r
963dbb30 192 @retval 0 Other errors as indicated.\r
12618416 193**/\r
12618416 194UINT16\r
195IScsiGetNICPciLocation (\r
196 IN EFI_HANDLE Controller\r
197 )\r
6a690e23 198{\r
199 EFI_STATUS Status;\r
200 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
201 EFI_HANDLE PciIoHandle;\r
202 EFI_PCI_IO_PROTOCOL *PciIo;\r
203 UINTN Segment;\r
204 UINTN Bus;\r
205 UINTN Device;\r
206 UINTN Function;\r
207\r
208 Status = gBS->HandleProtocol (\r
209 Controller,\r
210 &gEfiDevicePathProtocolGuid,\r
69b0882d 211 (VOID **)&DevicePath\r
6a690e23 212 );\r
213 if (EFI_ERROR (Status)) {\r
214 return 0;\r
215 }\r
216\r
217 Status = gBS->LocateDevicePath (\r
218 &gEfiPciIoProtocolGuid,\r
219 &DevicePath,\r
220 &PciIoHandle\r
221 );\r
222 if (EFI_ERROR (Status)) {\r
223 return 0;\r
224 }\r
225\r
69b0882d 226 Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);\r
6a690e23 227 if (EFI_ERROR (Status)) {\r
228 return 0;\r
229 }\r
230\r
231 Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
232 if (EFI_ERROR (Status)) {\r
233 return 0;\r
234 }\r
235\r
236 return (UINT16) ((Bus << 8) | (Device << 3) | Function);\r
237}\r
238\r
12618416 239/**\r
240 Get the MAC address of the controller.\r
241 \r
d8c04564 242 @param[in] Controller The handle of the controller.\r
12618416 243\r
d8c04564 244 @return EFI_MAC_ADDRESS * The mac address.\r
12618416 245**/\r
6a690e23 246EFI_MAC_ADDRESS *\r
247IScsiGetMacAddress (\r
248 IN EFI_HANDLE Controller\r
249 )\r
6a690e23 250{\r
251 EFI_STATUS Status;\r
252 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
253\r
254 Status = gBS->HandleProtocol (\r
255 Controller,\r
256 &gEfiSimpleNetworkProtocolGuid,\r
69b0882d 257 (VOID **) &Snp\r
6a690e23 258 );\r
259 ASSERT_EFI_ERROR (Status);\r
260\r
261 return &Snp->Mode->PermanentAddress;\r
262}\r
263\r
12618416 264/**\r
265 Fill the NIC and target sections in iSCSI Boot Firmware Table.\r
266\r
d8c04564 267 @param[in] Table The buffer of the ACPI table.\r
268 @param[in, out] Heap The heap buffer used to store the variable length parameters such as iSCSI name.\r
269 @param[in] HandleCount Count The number of handles having iSCSI private protocol installed.\r
270 @param[in] Handles The handle buffer.\r
12618416 271**/\r
6a690e23 272VOID\r
273IScsiFillNICAndTargetSections (\r
274 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
275 IN OUT UINT8 **Heap,\r
276 IN UINTN HandleCount,\r
277 IN EFI_HANDLE *Handles\r
278 )\r
6a690e23 279{\r
280 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
281 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;\r
282 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;\r
283 ISCSI_DRIVER_DATA *DriverData;\r
284 ISCSI_SESSION_CONFIG_DATA *SessionConfigData;\r
285 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;\r
286 UINT16 *SectionOffset;\r
287 UINTN Index;\r
288 UINT16 Length;\r
289 EFI_MAC_ADDRESS *Mac;\r
290 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
291 EFI_STATUS Status;\r
292\r
293 //\r
294 // Get the offset of the first Nic and Target section.\r
295 //\r
296 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
297 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +\r
298 Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));\r
299 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
300 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
301\r
302 SectionOffset = &Control->NIC0Offset;\r
303\r
304 for (Index = 0; Index < HandleCount; Index++) {\r
69b0882d 305 Status = gBS->HandleProtocol (Handles[Index], &mIScsiPrivateGuid, (VOID **)&IScsiIdentifier);\r
6a690e23 306 if (EFI_ERROR (Status)) {\r
307 ASSERT (FALSE);\r
308 return ;\r
309 }\r
310\r
311 DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
312 SessionConfigData = &DriverData->Session.ConfigData;\r
313 AuthConfig = &DriverData->Session.AuthData.AuthConfig;\r
314\r
315 //\r
316 // Fill the Nic section.\r
317 //\r
e48e37fc 318 ZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));\r
6a690e23 319\r
320 Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;\r
321 Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;\r
322 Nic->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);\r
323 Nic->Header.Index = (UINT8) Index;\r
324 Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |\r
325 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED |\r
326 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;\r
327\r
328 //\r
329 // Get the subnet mask prefix length.\r
330 //\r
331 Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask);\r
332\r
333 if (SessionConfigData->NvData.InitiatorInfoFromDhcp) {\r
334 Nic->Origin = IpPrefixOriginDhcp;\r
335 } else {\r
336 Nic->Origin = IpPrefixOriginManual;\r
337 }\r
338 //\r
339 // Map the various v4 addresses into v6 addresses.\r
340 //\r
341 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip);\r
342 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway);\r
343 IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns);\r
344 IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns);\r
345 IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer);\r
346\r
347 Mac = IScsiGetMacAddress (DriverData->Controller);\r
e48e37fc 348 CopyMem (Nic->Mac, Mac, sizeof (Nic->Mac));\r
6a690e23 349\r
350 //\r
351 // Get the PCI location of the Nic.\r
352 //\r
353 Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller);\r
354\r
355 *SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table);\r
356 SectionOffset++;\r
357\r
358 //\r
359 // Fill the Target section.\r
360 //\r
e48e37fc 361 ZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));\r
6a690e23 362\r
363 Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;\r
364 Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;\r
365 Target->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);\r
366 Target->Header.Index = (UINT8) Index;\r
367 Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED;\r
368 Target->Port = SessionConfigData->NvData.TargetPort;\r
369 Target->CHAPType = AuthConfig->CHAPType;\r
370 Target->NicIndex = (UINT8) Index;\r
371\r
372 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip);\r
e48e37fc 373 CopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));\r
6a690e23 374\r
375 //\r
376 // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.\r
377 //\r
378 Length = (UINT16) AsciiStrLen (SessionConfigData->NvData.TargetName);\r
379 IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length);\r
380\r
381 Target->IScsiNameLength = Length;\r
382 Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
383\r
384 if (Target->CHAPType != ISCSI_CHAP_NONE) {\r
385 //\r
386 // CHAP Name\r
387 //\r
388 Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName);\r
389 IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);\r
390 Target->CHAPNameLength = Length;\r
391 Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
392\r
393 //\r
394 // CHAP Secret\r
395 //\r
396 Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret);\r
397 IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);\r
398 Target->CHAPSecretLength = Length;\r
399 Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
400\r
401 if (Target->CHAPType == ISCSI_CHAP_MUTUAL) {\r
402 //\r
403 // Reverse CHAP Name\r
404 //\r
405 Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName);\r
406 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);\r
407 Target->ReverseCHAPNameLength = Length;\r
408 Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
409\r
410 //\r
411 // Reverse CHAP Secret\r
412 //\r
413 Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret);\r
414 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);\r
415 Target->ReverseCHAPSecretLength = Length;\r
416 Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
417 }\r
418 }\r
419\r
420 *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);\r
421 SectionOffset++;\r
422\r
423 //\r
424 // Advance to the next NIC/Target pair\r
425 //\r
426 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +\r
427 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));\r
428 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
429 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
430 }\r
431}\r
432\r
12618416 433/**\r
6a690e23 434 Publish and remove the iSCSI Boot Firmware Table according to the iSCSI\r
435 session status.\r
12618416 436**/\r
437VOID\r
438IScsiPublishIbft (\r
d8c04564 439 VOID \r
12618416 440 )\r
6a690e23 441{\r
442 EFI_STATUS Status;\r
443 UINTN TableHandle;\r
444 EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;\r
445 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;\r
446 UINTN HandleCount;\r
447 EFI_HANDLE *HandleBuffer;\r
448 UINT8 *Heap;\r
449 INTN Index;\r
450 EFI_ACPI_TABLE_VERSION Version;\r
451 UINT32 Signature;\r
452\r
69b0882d 453 Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, (VOID **)&AcpiSupport);\r
6a690e23 454 if (EFI_ERROR (Status)) {\r
455 return ;\r
456 }\r
457 //\r
458 // Try to remove the old iSCSI Boot Firmware Table.\r
459 //\r
460 for (Index = 0;; Index++) {\r
461 Status = AcpiSupport->GetAcpiTable (\r
462 AcpiSupport,\r
463 Index,\r
69b0882d 464 (VOID **)&Table,\r
6a690e23 465 &Version,\r
466 &TableHandle\r
467 );\r
468 if (EFI_ERROR (Status)) {\r
469 break;\r
470 }\r
471\r
472 Signature = Table->Signature;\r
e48e37fc 473 gBS->FreePool (Table);\r
6a690e23 474\r
475 if (Signature == EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE) {\r
476 //\r
477 // Remove the table.\r
478 //\r
479 Status = AcpiSupport->SetAcpiTable (\r
480 AcpiSupport,\r
481 NULL,\r
482 FALSE,\r
483 Version,\r
484 &TableHandle\r
485 );\r
486 if (EFI_ERROR (Status)) {\r
487 return ;\r
488 }\r
489\r
490 break;\r
491 }\r
492 }\r
493 //\r
494 // Get all iSCSI private protocols.\r
495 //\r
496 Status = gBS->LocateHandleBuffer (\r
497 ByProtocol,\r
498 &mIScsiPrivateGuid,\r
499 NULL,\r
500 &HandleCount,\r
501 &HandleBuffer\r
502 );\r
503 if (EFI_ERROR (Status)) {\r
504 return ;\r
505 }\r
506 //\r
507 // Allocate 4k bytes to hold the ACPI table.\r
508 //\r
e48e37fc 509 Table = AllocatePool (IBFT_MAX_SIZE);\r
6a690e23 510 if (Table == NULL) {\r
511 return ;\r
512 }\r
513\r
69b0882d 514 Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;\r
6a690e23 515\r
516 //\r
517 // Fill in the various section of the iSCSI Boot Firmware Table.\r
518 //\r
519 IScsiInitIbfTableHeader (Table);\r
520 IScsiInitControlSection (Table, HandleCount);\r
521 IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);\r
522 IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);\r
523\r
e48e37fc 524 gBS->FreePool (HandleBuffer);\r
6a690e23 525\r
526 TableHandle = 0;\r
527\r
528 //\r
529 // Install or update the iBFT table.\r
530 //\r
531 Status = AcpiSupport->SetAcpiTable (\r
532 AcpiSupport,\r
533 Table,\r
534 TRUE,\r
535 EFI_ACPI_TABLE_VERSION_3_0,\r
536 &TableHandle\r
537 );\r
538 if (!EFI_ERROR (Status)) {\r
539 AcpiSupport->PublishTables (AcpiSupport, EFI_ACPI_TABLE_VERSION_3_0);\r
540 }\r
541\r
e48e37fc 542 gBS->FreePool (Table);\r
6a690e23 543}\r