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