]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BootOption.c:
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiMisc.c
CommitLineData
6a690e23 1/*++\r
2\r
7a444476 3Copyright (c) 2004 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 11\r
12Module Name:\r
13\r
14 IScsiMisc.c\r
15\r
16Abstract:\r
17\r
18 Miscellaneous routines for iSCSI driver.\r
19\r
20--*/\r
21\r
22#include "IScsiImpl.h"\r
23\r
24STATIC CONST CHAR8 IScsiHexString[] = "0123456789ABCDEFabcdef";\r
25\r
26static\r
27BOOLEAN\r
28IsHexDigit (\r
29 OUT UINT8 *Digit,\r
30 IN CHAR16 Char\r
31 )\r
32/*++\r
33\r
34 Routine Description:\r
35 Determines if a Unicode character is a hexadecimal digit.\r
36 The test is case insensitive.\r
37\r
38 Arguments:\r
39 Digit - Pointer to byte that receives the value of the hex character.\r
40 Char - Unicode character to test.\r
41\r
42 Returns:\r
43 TRUE - If the character is a hexadecimal digit.\r
44 FALSE - Otherwise.\r
45\r
46--*/\r
47{\r
48 if ((Char >= L'0') && (Char <= L'9')) {\r
49 *Digit = (UINT8) (Char - L'0');\r
50 return TRUE;\r
51 }\r
52\r
53 if ((Char >= L'A') && (Char <= L'F')) {\r
54 *Digit = (UINT8) (Char - L'A' + 0x0A);\r
55 return TRUE;\r
56 }\r
57\r
58 if ((Char >= L'a') && (Char <= L'f')) {\r
59 *Digit = (UINT8) (Char - L'a' + 0x0A);\r
60 return TRUE;\r
61 }\r
62\r
63 return FALSE;\r
64}\r
65\r
66static\r
67VOID\r
68StrTrim (\r
69 IN OUT CHAR16 *str,\r
70 IN CHAR16 CharC\r
71 )\r
72/*++\r
73\r
74Routine Description:\r
75 \r
76 Removes (trims) specified leading and trailing characters from a string.\r
77 \r
78Arguments: \r
79 \r
80 str - Pointer to the null-terminated string to be trimmed. On return, \r
81 str will hold the trimmed string. \r
82 CharC - Character will be trimmed from str.\r
83 \r
84Returns:\r
85\r
86--*/\r
87{\r
88 CHAR16 *p1;\r
89 CHAR16 *p2;\r
90 \r
91 if (*str == 0) {\r
92 return;\r
93 }\r
94 \r
95 //\r
96 // Trim off the leading and trailing characters c\r
97 //\r
98 for (p1 = str; *p1 && *p1 == CharC; p1++) {\r
99 ;\r
100 }\r
101 \r
102 p2 = str;\r
103 if (p2 == p1) {\r
104 while (*p1) {\r
105 p2++;\r
106 p1++;\r
107 }\r
108 } else {\r
109 while (*p1) { \r
110 *p2 = *p1; \r
111 p1++;\r
112 p2++;\r
113 }\r
114 *p2 = 0;\r
115 }\r
116 \r
117 \r
118 for (p1 = str + StrLen(str) - 1; p1 >= str && *p1 == CharC; p1--) {\r
119 ;\r
120 }\r
121 if (p1 != str + StrLen(str) - 1) { \r
122 *(p1 + 1) = 0;\r
123 }\r
124}\r
125\r
126UINT8\r
127IScsiGetSubnetMaskPrefixLength (\r
128 IN EFI_IPv4_ADDRESS *SubnetMask\r
129 )\r
130/*++\r
131\r
132Routine Description:\r
133\r
134 Calculate the prefix length of the IPv4 subnet mask.\r
135\r
136Arguments:\r
137\r
138 SubnetMask - The IPv4 subnet mask.\r
139\r
140Returns:\r
141\r
142 The prefix length of the subnet mask.\r
143\r
144--*/\r
145{\r
146 UINT8 Len;\r
147 UINT32 ReverseMask;\r
148\r
149 //\r
150 // The SubnetMask is in network byte order.\r
151 //\r
152 ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);\r
153\r
154 //\r
155 // Reverse it.\r
156 //\r
157 ReverseMask = ~ReverseMask;\r
158\r
159 if (ReverseMask & (ReverseMask + 1)) {\r
160 return 0;\r
161 }\r
162\r
163 Len = 0;\r
164\r
165 while (ReverseMask != 0) {\r
166 ReverseMask = ReverseMask >> 1;\r
167 Len++;\r
168 }\r
169\r
69b0882d 170 return (UINT8) (32 - Len);\r
6a690e23 171}\r
172\r
173EFI_STATUS\r
174IScsiAsciiStrToLun (\r
175 IN CHAR8 *Str,\r
176 OUT UINT8 *Lun\r
177 )\r
178/*++\r
179\r
180Routine Description:\r
181\r
182 Convert the hexadecimal encoded LUN string into the 64-bit LUN. \r
183\r
184Arguments:\r
185\r
186 Str - The hexadecimal encoded LUN string.\r
187 Lun - Storage to return the 64-bit LUN.\r
188\r
189Returns:\r
190\r
191 EFI_SUCCESS - The 64-bit LUN is stored in Lun.\r
192 EFI_INVALID_PARAMETER - The string is malformatted.\r
193\r
194--*/\r
195{\r
196 UINT32 Index;\r
197 CHAR8 *LunUnitStr[4];\r
198 CHAR8 Digit;\r
69b0882d 199 UINTN Temp;\r
6a690e23 200\r
e48e37fc 201 ZeroMem (Lun, 8);\r
202 ZeroMem (LunUnitStr, sizeof (LunUnitStr));\r
6a690e23 203\r
204 Index = 0;\r
205 LunUnitStr[0] = Str;\r
206\r
69b0882d 207 if (!IsHexDigit ((UINT8 *) &Digit, *Str)) {\r
6a690e23 208 return EFI_INVALID_PARAMETER;\r
209 }\r
210\r
211 while (*Str != '\0') {\r
212 //\r
213 // Legal representations of LUN:\r
214 // 4752-3A4F-6b7e-2F99,\r
215 // 6734-9-156f-127,\r
216 // 4186-9\r
217 //\r
218 if (*Str == '-') {\r
219 *Str = '\0';\r
220 Index++;\r
221\r
222 if (*(Str + 1) != '\0') {\r
69b0882d 223 if (!IsHexDigit ((UINT8 *) &Digit, *(Str + 1))) {\r
6a690e23 224 return EFI_INVALID_PARAMETER;\r
225 }\r
226\r
227 LunUnitStr[Index] = Str + 1;\r
228 }\r
69b0882d 229 } else if (!IsHexDigit ((UINT8 *) &Digit, *Str)) {\r
6a690e23 230 return EFI_INVALID_PARAMETER;\r
231 }\r
232\r
233 Str++;\r
234 }\r
235\r
236 for (Index = 0; (Index < 4) && (LunUnitStr[Index] != NULL); Index++) {\r
237 if (AsciiStrLen (LunUnitStr[Index]) > 4) {\r
238 return EFI_INVALID_PARAMETER;\r
239 }\r
240\r
69b0882d 241 Temp = AsciiStrHexToUintn (LunUnitStr[Index]);\r
242 *((UINT16 *) &Lun[Index * 2]) = HTONS (Temp);\r
6a690e23 243 }\r
244\r
245 return EFI_SUCCESS;\r
246}\r
247\r
248VOID\r
249IScsiLunToUnicodeStr (\r
250 IN UINT8 *Lun,\r
251 OUT CHAR16 *Str\r
252 )\r
253/*++\r
254\r
255Routine Description:\r
256\r
257 Convert the 64-bit LUN into the hexadecimal encoded LUN string.\r
258\r
259Arguments:\r
260\r
261 Lun - The 64-bit LUN.\r
262 Str - The storage to return the hexadecimal encoded LUN string.\r
263\r
264Returns:\r
265\r
266 None.\r
267\r
268--*/\r
269{\r
270 UINTN Index;\r
271 CHAR16 *TempStr;\r
272\r
273 TempStr = Str;\r
274\r
275 for (Index = 0; Index < 4; Index++) {\r
276\r
277 if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {\r
278 StrCpy (TempStr, L"0-");\r
279 } else {\r
280 TempStr[0] = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];\r
281 TempStr[1] = (CHAR16) IScsiHexString[Lun[2 * Index] & 0xf];\r
282 TempStr[2] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];\r
283 TempStr[3] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0xf];\r
284 TempStr[4] = L'-';\r
285 TempStr[5] = 0;\r
286\r
287 StrTrim (TempStr, L'0');\r
288 }\r
289\r
290 TempStr += StrLen (TempStr);\r
291 }\r
292\r
293 Str[StrLen (Str) - 1] = 0;\r
294\r
295 for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {\r
296 if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {\r
297 Str[Index - 1] = 0;\r
298 } else {\r
299 break;\r
300 }\r
301 }\r
302}\r
303\r
304CHAR16 *\r
305IScsiAsciiStrToUnicodeStr (\r
306 IN CHAR8 *Source,\r
307 OUT CHAR16 *Destination\r
308 )\r
309/*++\r
310\r
311Routine Description:\r
312\r
313 Convert the ASCII string into a UNICODE string.\r
314\r
315Arguments:\r
316\r
317 Source - The ASCII string.\r
318 Destination - The storage to return the UNICODE string.\r
319\r
320Returns:\r
321\r
322 Pointer to the UNICODE string.\r
323\r
324--*/\r
325{\r
326 ASSERT (Destination != NULL);\r
327 ASSERT (Source != NULL);\r
328\r
329 while (*Source != '\0') {\r
330 *(Destination++) = (CHAR16) *(Source++);\r
331 }\r
332\r
333 *Destination = '\0';\r
334\r
335 return Destination;\r
336}\r
337\r
338CHAR8 *\r
339IScsiUnicodeStrToAsciiStr (\r
340 IN CHAR16 *Source,\r
341 OUT CHAR8 *Destination\r
342 )\r
343/*++\r
344\r
345Routine Description:\r
346\r
347 Convert the UNICODE string into an ASCII string.\r
348\r
349Arguments:\r
350\r
351 Source - The UNICODE string.\r
352 Destination - The storage to return the ASCII string.\r
353\r
354Returns:\r
355\r
356 Pointer to the ASCII string.\r
357\r
358--*/\r
359{\r
360 ASSERT (Destination != NULL);\r
361 ASSERT (Source != NULL);\r
362\r
363 while (*Source != '\0') {\r
364 //\r
365 // If any Unicode characters in Source contain\r
366 // non-zero value in the upper 8 bits, then ASSERT().\r
367 //\r
368 ASSERT (*Source < 0x100);\r
369 *(Destination++) = (CHAR8) *(Source++);\r
370 }\r
371\r
372 *Destination = '\0';\r
373\r
374 return Destination;\r
375}\r
376\r
377EFI_STATUS\r
378IScsiAsciiStrToIp (\r
379 IN CHAR8 *Str,\r
380 OUT EFI_IPv4_ADDRESS *Ip\r
381 )\r
382/*++\r
383\r
384Routine Description:\r
385\r
386 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
387\r
388Arguments:\r
389\r
390 Str - The UNICODE string.\r
391 Ip - The storage to return the ASCII string.\r
392\r
393Returns:\r
394\r
395 EFI_SUCCESS - The binary IP address is returned in Ip.\r
396 EFI_INVALID_PARAMETER - The IP string is malformatted.\r
397\r
398--*/\r
399{\r
400 UINTN Index;\r
401 UINTN Number;\r
402\r
403 Index = 0;\r
404\r
405 while (*Str) {\r
406\r
407 if (Index > 3) {\r
408 return EFI_INVALID_PARAMETER;\r
409 }\r
410\r
411 Number = 0;\r
412 while (NET_IS_DIGIT (*Str)) {\r
413 Number = Number * 10 + (*Str - '0');\r
414 Str++;\r
415 }\r
416\r
417 if (Number > 0xFF) {\r
418 return EFI_INVALID_PARAMETER;\r
419 }\r
420\r
421 Ip->Addr[Index] = (UINT8) Number;\r
422\r
423 if ((*Str != '\0') && (*Str != '.')) {\r
424 //\r
425 // The current character should be either the NULL terminator or\r
426 // the dot delimiter.\r
427 //\r
428 return EFI_INVALID_PARAMETER;\r
429 }\r
430\r
431 if (*Str == '.') {\r
432 //\r
433 // Skip the delimiter.\r
434 //\r
435 Str++;\r
436 }\r
437\r
438 Index++;\r
439 }\r
440\r
441 if (Index != 4) {\r
442 return EFI_INVALID_PARAMETER;\r
443 }\r
444\r
445 return EFI_SUCCESS;\r
446}\r
447\r
448VOID\r
449IScsiMacAddrToStr (\r
450 IN EFI_MAC_ADDRESS *Mac,\r
451 IN UINT32 Len,\r
452 OUT CHAR16 *Str\r
453 )\r
454/*++\r
455\r
456Routine Description:\r
457\r
458 Convert the mac address into a hexadecimal encoded "-" seperated string.\r
459\r
460Arguments:\r
461\r
462 Mac - The mac address.\r
463 Len - Length in bytes of the mac address.\r
464 Str - The storage to return the mac string.\r
465\r
466Returns:\r
467\r
468 None.\r
469\r
470--*/\r
471{\r
472 UINT32 Index;\r
473\r
474 for (Index = 0; Index < Len; Index++) {\r
69b0882d 475 Str[3 * Index] = NibbleToHexChar ((UINT8) (Mac->Addr[Index] >> 4));\r
6a690e23 476 Str[3 * Index + 1] = NibbleToHexChar (Mac->Addr[Index]);\r
477 Str[3 * Index + 2] = L'-';\r
478 }\r
479\r
480 Str[3 * Index - 1] = L'\0';\r
481}\r
482\r
483EFI_STATUS\r
484IScsiBinToHex (\r
485 IN UINT8 *BinBuffer,\r
486 IN UINT32 BinLength,\r
487 IN OUT CHAR8 *HexStr,\r
488 IN OUT UINT32 *HexLength\r
489 )\r
490/*++\r
491\r
492Routine Description:\r
493\r
494 Convert the binary encoded buffer into a hexadecimal encoded string.\r
495\r
496Arguments:\r
497\r
498 BinBuffer - The buffer containing the binary data.\r
499 BinLength - Length of the binary buffer.\r
500 HexStr - Pointer to the string.\r
501 HexLength - The length of the string.\r
502\r
503Returns:\r
504\r
505 EFI_SUCCESS - The binary data is converted to the hexadecimal string \r
506 and the length of the string is updated.\r
507 EFI_BUFFER_TOO_SMALL - The string is too small.\r
508\r
509--*/\r
510{\r
511 UINTN Index;\r
512\r
513 if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {\r
514 return EFI_INVALID_PARAMETER;\r
515 }\r
516\r
517 if (((*HexLength) - 3) < BinLength * 2) {\r
518 *HexLength = BinLength * 2 + 3;\r
519 return EFI_BUFFER_TOO_SMALL;\r
520 }\r
521\r
522 *HexLength = BinLength * 2 + 3;\r
523 //\r
524 // Prefix for Hex String\r
525 //\r
526 HexStr[0] = '0';\r
527 HexStr[1] = 'x';\r
528\r
529 for (Index = 0; Index < BinLength; Index++) {\r
530 HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];\r
531 HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];\r
532 }\r
533\r
534 HexStr[Index * 2 + 2] = '\0';\r
535\r
536 return EFI_SUCCESS;\r
537}\r
538\r
539EFI_STATUS\r
540IScsiHexToBin (\r
541 IN OUT UINT8 *BinBuffer,\r
542 IN OUT UINT32 *BinLength,\r
543 IN CHAR8 *HexStr\r
544 )\r
545/*++\r
546\r
547Routine Description:\r
548\r
549 Convert the hexadecimal string into a binary encoded buffer.\r
550\r
551Arguments:\r
552\r
553 BinBuffer - The binary buffer.\r
554 BinLength - Length of the binary buffer.\r
555 HexStr - The hexadecimal string.\r
556\r
557Returns:\r
558\r
559 EFI_SUCCESS - The hexadecimal string is converted into a binary \r
560 encoded buffer.\r
561 EFI_BUFFER_TOO_SMALL - The binary buffer is too small to hold the converted data.s\r
562\r
563--*/\r
564{\r
565 UINTN Index;\r
566 UINT32 HexCount;\r
567 CHAR8 *HexBuf;\r
568 UINT8 Digit;\r
569 UINT8 Byte;\r
570\r
571 //\r
572 // Find out how many hex characters the string has.\r
573 //\r
574 HexBuf = HexStr;\r
575 if ((HexBuf[0] == '0') && ((HexBuf[1] == 'x') || (HexBuf[1] == 'X'))) {\r
576 HexBuf += 2;\r
577 }\r
578\r
579 for (Index = 0, HexCount = 0; IsHexDigit (&Digit, HexBuf[Index]); Index++, HexCount++)\r
580 ;\r
581\r
582 if (HexCount == 0) {\r
583 *BinLength = 0;\r
584 return EFI_SUCCESS;\r
585 }\r
586 //\r
587 // Test if buffer is passed enough.\r
588 //\r
589 if (((HexCount + 1) / 2) > *BinLength) {\r
590 *BinLength = (HexCount + 1) / 2;\r
591 return EFI_BUFFER_TOO_SMALL;\r
592 }\r
593\r
594 *BinLength = (HexCount + 1) / 2;\r
595\r
596 for (Index = 0; Index < HexCount; Index++) {\r
597\r
598 IsHexDigit (&Digit, HexBuf[HexCount - 1 - Index]);\r
599\r
600 if ((Index & 1) == 0) {\r
601 Byte = Digit;\r
602 } else {\r
603 Byte = BinBuffer[*BinLength - 1 - Index / 2];\r
604 Byte &= 0x0F;\r
69b0882d 605 Byte = (UINT8) (Byte | (Digit << 4));\r
6a690e23 606 }\r
607\r
608 BinBuffer[*BinLength - 1 - Index / 2] = Byte;\r
609 }\r
610\r
611 return EFI_SUCCESS;\r
612}\r
613\r
614VOID\r
615IScsiGenRandom (\r
616 IN OUT UINT8 *Rand,\r
617 IN UINTN RandLength\r
618 )\r
619/*++\r
620\r
621Routine Description:\r
622\r
623 Generate random numbers.\r
624\r
625Arguments:\r
626\r
627 Rand - The buffer to contain random numbers.\r
628 RandLength - The length of the Rand buffer.\r
629\r
630Returns:\r
631\r
632 None.\r
633\r
634--*/\r
635{\r
636 UINT32 Random;\r
637\r
638 while (RandLength > 0) {\r
639 Random = NET_RANDOM (NetRandomInitSeed ());\r
640 *Rand++ = (UINT8) (Random);\r
641 RandLength--;\r
642 }\r
643}\r
644\r
645ISCSI_DRIVER_DATA *\r
646IScsiCreateDriverData (\r
647 IN EFI_HANDLE Image,\r
648 IN EFI_HANDLE Controller\r
649 )\r
650/*++\r
651\r
652Routine Description:\r
653\r
654 Create the iSCSI driver data..\r
655\r
656Arguments:\r
657\r
658 Image - The handle of the driver image.\r
659 Controller - The handle of the controller.\r
660\r
661Returns:\r
662\r
663 The iSCSI driver data created.\r
664\r
665--*/\r
666{\r
667 ISCSI_DRIVER_DATA *Private;\r
668 EFI_STATUS Status;\r
669\r
e48e37fc 670 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
6a690e23 671 if (Private == NULL) {\r
672 return NULL;\r
673 }\r
674\r
675 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
676 Private->Image = Image;\r
677 Private->Controller = Controller;\r
678\r
679 //\r
680 // Create an event to be signal when the BS to RT transition is triggerd so\r
681 // as to abort the iSCSI session.\r
682 //\r
683 Status = gBS->CreateEvent (\r
684 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
685 TPL_CALLBACK,\r
686 IScsiOnExitBootService,\r
687 Private,\r
688 &Private->ExitBootServiceEvent\r
689 );\r
690 if (EFI_ERROR (Status)) {\r
e48e37fc 691 gBS->FreePool (Private);\r
6a690e23 692 return NULL;\r
693 }\r
694\r
e48e37fc 695 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
6a690e23 696\r
697 //\r
698 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
699 //\r
700 Private->ExtScsiPassThruMode.AdapterId = 2;\r
701 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
702 Private->ExtScsiPassThruMode.IoAlign = 4;\r
703 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
704\r
705 //\r
706 // Install the Ext SCSI PASS THRU protocol.\r
707 //\r
708 Status = gBS->InstallProtocolInterface (\r
709 &Private->ExtScsiPassThruHandle,\r
710 &gEfiExtScsiPassThruProtocolGuid,\r
711 EFI_NATIVE_INTERFACE,\r
712 &Private->IScsiExtScsiPassThru\r
713 );\r
714 if (EFI_ERROR (Status)) {\r
715 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
e48e37fc 716 gBS->FreePool (Private);\r
6a690e23 717\r
718 return NULL;\r
719 }\r
720\r
721 IScsiSessionInit (&Private->Session, FALSE);\r
722\r
723 return Private;\r
724}\r
725\r
726VOID\r
727IScsiCleanDriverData (\r
728 IN ISCSI_DRIVER_DATA *Private\r
729 )\r
730/*++\r
731\r
732Routine Description:\r
733\r
734 Clean the iSCSI driver data.\r
735\r
736Arguments:\r
737\r
738 Private - The iSCSI driver data.\r
739\r
740Returns:\r
741\r
742 None.\r
743\r
744--*/\r
745{\r
746 if (Private->DevicePath != NULL) {\r
747 gBS->UninstallProtocolInterface (\r
748 Private->ExtScsiPassThruHandle,\r
749 &gEfiDevicePathProtocolGuid,\r
750 Private->DevicePath\r
751 );\r
752\r
e48e37fc 753 gBS->FreePool (Private->DevicePath);\r
6a690e23 754 }\r
755\r
756 if (Private->ExtScsiPassThruHandle != NULL) {\r
757 gBS->UninstallProtocolInterface (\r
758 Private->ExtScsiPassThruHandle,\r
759 &gEfiExtScsiPassThruProtocolGuid,\r
760 &Private->IScsiExtScsiPassThru\r
761 );\r
762 }\r
763\r
764 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
765\r
e48e37fc 766 gBS->FreePool (Private);\r
6a690e23 767}\r
768\r
769EFI_STATUS\r
770IScsiGetConfigData (\r
771 IN ISCSI_DRIVER_DATA *Private\r
772 )\r
773/*++\r
774\r
775Routine Description:\r
776\r
777 Get the various configuration data of this iSCSI instance.\r
778\r
779Arguments:\r
780\r
781 Private - The iSCSI driver data.\r
782\r
783Returns:\r
784\r
785 EFI_SUCCESS - The configuration of this instance is got.\r
786 EFI_NOT_FOUND - This iSCSI instance is not configured yet.\r
787\r
788--*/\r
789{\r
790 EFI_STATUS Status;\r
791 ISCSI_SESSION *Session;\r
792 UINTN BufferSize;\r
793 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
794 EFI_SIMPLE_NETWORK_MODE *Mode;\r
795 CHAR16 MacString[65];\r
796\r
797 //\r
798 // get the iSCSI Initiator Name\r
799 //\r
800 Session = &Private->Session;\r
801 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
802 Status = gIScsiInitiatorName.Get (\r
803 &gIScsiInitiatorName,\r
804 &Session->InitiatorNameLength,\r
805 Session->InitiatorName\r
806 );\r
807 if (EFI_ERROR (Status)) {\r
808 return Status;\r
809 }\r
810\r
811 Status = gBS->HandleProtocol (\r
812 Private->Controller,\r
813 &gEfiSimpleNetworkProtocolGuid,\r
69b0882d 814 (VOID **)&Snp\r
6a690e23 815 );\r
816 if (EFI_ERROR (Status)) {\r
817 return Status;\r
818 }\r
819\r
820 Mode = Snp->Mode;\r
821\r
822 //\r
823 // Get the mac string, it's the name of various variable\r
824 //\r
825 IScsiMacAddrToStr (&Mode->PermanentAddress, Mode->HwAddressSize, MacString);\r
826\r
827 //\r
828 // Get the normal configuration.\r
829 //\r
830 BufferSize = sizeof (Session->ConfigData.NvData);\r
831 Status = gRT->GetVariable (\r
832 MacString,\r
833 &gEfiIScsiInitiatorNameProtocolGuid,\r
834 NULL,\r
835 &BufferSize,\r
836 &Session->ConfigData.NvData\r
837 );\r
838 if (EFI_ERROR (Status)) {\r
839 return Status;\r
840 }\r
841\r
842 if (!Session->ConfigData.NvData.Enabled) {\r
843 return EFI_ABORTED;\r
844 }\r
845 //\r
846 // Get the CHAP Auth information.\r
847 //\r
848 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
849 Status = gRT->GetVariable (\r
850 MacString,\r
851 &mIScsiCHAPAuthInfoGuid,\r
852 NULL,\r
853 &BufferSize,\r
854 &Session->AuthData.AuthConfig\r
855 );\r
856\r
857 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
858 //\r
859 // Start dhcp.\r
860 //\r
861 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
862 }\r
863\r
864 return Status;\r
865}\r
866\r
867EFI_DEVICE_PATH_PROTOCOL *\r
868IScsiGetTcpConnDevicePath (\r
869 IN ISCSI_DRIVER_DATA *Private\r
870 )\r
871/*++\r
872\r
873Routine Description:\r
874\r
875 Get the device path of the iSCSI tcp connection and update it.\r
876\r
877Arguments:\r
878\r
879 Private - The iSCSI driver data.\r
880\r
881Returns:\r
882\r
883 The updated device path.\r
884\r
885--*/\r
886{\r
887 ISCSI_SESSION *Session;\r
888 ISCSI_CONNECTION *Conn;\r
889 TCP4_IO *Tcp4Io;\r
890 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
891 EFI_STATUS Status;\r
892 EFI_DEV_PATH *DPathNode;\r
893\r
894 Session = &Private->Session;\r
895 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
896 return NULL;\r
897 }\r
898\r
899 Conn = NET_LIST_USER_STRUCT_S (\r
900 Session->Conns.ForwardLink,\r
901 ISCSI_CONNECTION,\r
902 Link,\r
903 ISCSI_CONNECTION_SIGNATURE\r
904 );\r
905 Tcp4Io = &Conn->Tcp4Io;\r
906\r
907 Status = gBS->HandleProtocol (\r
908 Tcp4Io->Handle,\r
909 &gEfiDevicePathProtocolGuid,\r
69b0882d 910 (VOID **)&DevicePath\r
6a690e23 911 );\r
912 if (EFI_ERROR (Status)) {\r
913 return NULL;\r
914 }\r
915 //\r
916 // Duplicate it.\r
917 //\r
918 DevicePath = DuplicateDevicePath (DevicePath);\r
919\r
920 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
921\r
922 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
923 if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&\r
924 (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)\r
925 ) {\r
926\r
927 DPathNode->Ipv4.LocalPort = 0;\r
69b0882d 928 DPathNode->Ipv4.StaticIpAddress = (BOOLEAN) (!Session->ConfigData.NvData.InitiatorInfoFromDhcp);\r
6a690e23 929 break;\r
930 }\r
931\r
932 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
933 }\r
934\r
935 return DevicePath;\r
936}\r
937\r
938VOID\r
939EFIAPI\r
940IScsiOnExitBootService (\r
941 IN EFI_EVENT Event,\r
942 IN VOID *Context\r
943 )\r
944/*++\r
945\r
946Routine Description:\r
947\r
948 Abort the session when the transition from BS to RT is initiated.\r
949\r
950Arguments:\r
951\r
952 Event - The event signaled.\r
953 Context - The iSCSI driver data.\r
954\r
955Returns:\r
956\r
957 None.\r
958\r
959--*/\r
960{\r
961 ISCSI_DRIVER_DATA *Private;\r
962\r
963 Private = (ISCSI_DRIVER_DATA *) Context;\r
964 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
965\r
966 IScsiSessionAbort (&Private->Session);\r
967}\r