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