]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
Add missing file in INF file.
[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
7c3eaa27 571 Digit = 0;\r
572\r
6a690e23 573 //\r
574 // Find out how many hex characters the string has.\r
575 //\r
576 HexBuf = HexStr;\r
577 if ((HexBuf[0] == '0') && ((HexBuf[1] == 'x') || (HexBuf[1] == 'X'))) {\r
578 HexBuf += 2;\r
579 }\r
580\r
581 for (Index = 0, HexCount = 0; IsHexDigit (&Digit, HexBuf[Index]); Index++, HexCount++)\r
582 ;\r
583\r
584 if (HexCount == 0) {\r
585 *BinLength = 0;\r
586 return EFI_SUCCESS;\r
587 }\r
588 //\r
589 // Test if buffer is passed enough.\r
590 //\r
591 if (((HexCount + 1) / 2) > *BinLength) {\r
592 *BinLength = (HexCount + 1) / 2;\r
593 return EFI_BUFFER_TOO_SMALL;\r
594 }\r
595\r
596 *BinLength = (HexCount + 1) / 2;\r
597\r
598 for (Index = 0; Index < HexCount; Index++) {\r
599\r
600 IsHexDigit (&Digit, HexBuf[HexCount - 1 - Index]);\r
601\r
602 if ((Index & 1) == 0) {\r
603 Byte = Digit;\r
604 } else {\r
605 Byte = BinBuffer[*BinLength - 1 - Index / 2];\r
606 Byte &= 0x0F;\r
69b0882d 607 Byte = (UINT8) (Byte | (Digit << 4));\r
6a690e23 608 }\r
609\r
610 BinBuffer[*BinLength - 1 - Index / 2] = Byte;\r
611 }\r
612\r
613 return EFI_SUCCESS;\r
614}\r
615\r
616VOID\r
617IScsiGenRandom (\r
618 IN OUT UINT8 *Rand,\r
619 IN UINTN RandLength\r
620 )\r
621/*++\r
622\r
623Routine Description:\r
624\r
625 Generate random numbers.\r
626\r
627Arguments:\r
628\r
629 Rand - The buffer to contain random numbers.\r
630 RandLength - The length of the Rand buffer.\r
631\r
632Returns:\r
633\r
634 None.\r
635\r
636--*/\r
637{\r
638 UINT32 Random;\r
639\r
640 while (RandLength > 0) {\r
641 Random = NET_RANDOM (NetRandomInitSeed ());\r
642 *Rand++ = (UINT8) (Random);\r
643 RandLength--;\r
644 }\r
645}\r
646\r
647ISCSI_DRIVER_DATA *\r
648IScsiCreateDriverData (\r
649 IN EFI_HANDLE Image,\r
650 IN EFI_HANDLE Controller\r
651 )\r
652/*++\r
653\r
654Routine Description:\r
655\r
656 Create the iSCSI driver data..\r
657\r
658Arguments:\r
659\r
660 Image - The handle of the driver image.\r
661 Controller - The handle of the controller.\r
662\r
663Returns:\r
664\r
665 The iSCSI driver data created.\r
666\r
667--*/\r
668{\r
669 ISCSI_DRIVER_DATA *Private;\r
670 EFI_STATUS Status;\r
671\r
e48e37fc 672 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
6a690e23 673 if (Private == NULL) {\r
674 return NULL;\r
675 }\r
676\r
677 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
678 Private->Image = Image;\r
679 Private->Controller = Controller;\r
680\r
681 //\r
682 // Create an event to be signal when the BS to RT transition is triggerd so\r
683 // as to abort the iSCSI session.\r
684 //\r
685 Status = gBS->CreateEvent (\r
686 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
687 TPL_CALLBACK,\r
688 IScsiOnExitBootService,\r
689 Private,\r
690 &Private->ExitBootServiceEvent\r
691 );\r
692 if (EFI_ERROR (Status)) {\r
e48e37fc 693 gBS->FreePool (Private);\r
6a690e23 694 return NULL;\r
695 }\r
696\r
e48e37fc 697 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
6a690e23 698\r
699 //\r
700 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
701 //\r
702 Private->ExtScsiPassThruMode.AdapterId = 2;\r
703 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
704 Private->ExtScsiPassThruMode.IoAlign = 4;\r
705 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
706\r
707 //\r
708 // Install the Ext SCSI PASS THRU protocol.\r
709 //\r
710 Status = gBS->InstallProtocolInterface (\r
711 &Private->ExtScsiPassThruHandle,\r
712 &gEfiExtScsiPassThruProtocolGuid,\r
713 EFI_NATIVE_INTERFACE,\r
714 &Private->IScsiExtScsiPassThru\r
715 );\r
716 if (EFI_ERROR (Status)) {\r
717 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
e48e37fc 718 gBS->FreePool (Private);\r
6a690e23 719\r
720 return NULL;\r
721 }\r
722\r
723 IScsiSessionInit (&Private->Session, FALSE);\r
724\r
725 return Private;\r
726}\r
727\r
728VOID\r
729IScsiCleanDriverData (\r
730 IN ISCSI_DRIVER_DATA *Private\r
731 )\r
732/*++\r
733\r
734Routine Description:\r
735\r
736 Clean the iSCSI driver data.\r
737\r
738Arguments:\r
739\r
740 Private - The iSCSI driver data.\r
741\r
742Returns:\r
743\r
744 None.\r
745\r
746--*/\r
747{\r
748 if (Private->DevicePath != NULL) {\r
749 gBS->UninstallProtocolInterface (\r
750 Private->ExtScsiPassThruHandle,\r
751 &gEfiDevicePathProtocolGuid,\r
752 Private->DevicePath\r
753 );\r
754\r
e48e37fc 755 gBS->FreePool (Private->DevicePath);\r
6a690e23 756 }\r
757\r
758 if (Private->ExtScsiPassThruHandle != NULL) {\r
759 gBS->UninstallProtocolInterface (\r
760 Private->ExtScsiPassThruHandle,\r
761 &gEfiExtScsiPassThruProtocolGuid,\r
762 &Private->IScsiExtScsiPassThru\r
763 );\r
764 }\r
765\r
766 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
767\r
e48e37fc 768 gBS->FreePool (Private);\r
6a690e23 769}\r
770\r
771EFI_STATUS\r
772IScsiGetConfigData (\r
773 IN ISCSI_DRIVER_DATA *Private\r
774 )\r
775/*++\r
776\r
777Routine Description:\r
778\r
779 Get the various configuration data of this iSCSI instance.\r
780\r
781Arguments:\r
782\r
783 Private - The iSCSI driver data.\r
784\r
785Returns:\r
786\r
787 EFI_SUCCESS - The configuration of this instance is got.\r
788 EFI_NOT_FOUND - This iSCSI instance is not configured yet.\r
789\r
790--*/\r
791{\r
792 EFI_STATUS Status;\r
793 ISCSI_SESSION *Session;\r
794 UINTN BufferSize;\r
795 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
796 EFI_SIMPLE_NETWORK_MODE *Mode;\r
797 CHAR16 MacString[65];\r
798\r
799 //\r
800 // get the iSCSI Initiator Name\r
801 //\r
802 Session = &Private->Session;\r
803 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
804 Status = gIScsiInitiatorName.Get (\r
805 &gIScsiInitiatorName,\r
806 &Session->InitiatorNameLength,\r
807 Session->InitiatorName\r
808 );\r
809 if (EFI_ERROR (Status)) {\r
810 return Status;\r
811 }\r
812\r
813 Status = gBS->HandleProtocol (\r
814 Private->Controller,\r
815 &gEfiSimpleNetworkProtocolGuid,\r
69b0882d 816 (VOID **)&Snp\r
6a690e23 817 );\r
818 if (EFI_ERROR (Status)) {\r
819 return Status;\r
820 }\r
821\r
822 Mode = Snp->Mode;\r
823\r
824 //\r
825 // Get the mac string, it's the name of various variable\r
826 //\r
827 IScsiMacAddrToStr (&Mode->PermanentAddress, Mode->HwAddressSize, MacString);\r
828\r
829 //\r
830 // Get the normal configuration.\r
831 //\r
832 BufferSize = sizeof (Session->ConfigData.NvData);\r
833 Status = gRT->GetVariable (\r
834 MacString,\r
835 &gEfiIScsiInitiatorNameProtocolGuid,\r
836 NULL,\r
837 &BufferSize,\r
838 &Session->ConfigData.NvData\r
839 );\r
840 if (EFI_ERROR (Status)) {\r
841 return Status;\r
842 }\r
843\r
844 if (!Session->ConfigData.NvData.Enabled) {\r
845 return EFI_ABORTED;\r
846 }\r
847 //\r
848 // Get the CHAP Auth information.\r
849 //\r
850 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
851 Status = gRT->GetVariable (\r
852 MacString,\r
853 &mIScsiCHAPAuthInfoGuid,\r
854 NULL,\r
855 &BufferSize,\r
856 &Session->AuthData.AuthConfig\r
857 );\r
858\r
859 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
860 //\r
861 // Start dhcp.\r
862 //\r
863 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
864 }\r
865\r
866 return Status;\r
867}\r
868\r
869EFI_DEVICE_PATH_PROTOCOL *\r
870IScsiGetTcpConnDevicePath (\r
871 IN ISCSI_DRIVER_DATA *Private\r
872 )\r
873/*++\r
874\r
875Routine Description:\r
876\r
877 Get the device path of the iSCSI tcp connection and update it.\r
878\r
879Arguments:\r
880\r
881 Private - The iSCSI driver data.\r
882\r
883Returns:\r
884\r
885 The updated device path.\r
886\r
887--*/\r
888{\r
889 ISCSI_SESSION *Session;\r
890 ISCSI_CONNECTION *Conn;\r
891 TCP4_IO *Tcp4Io;\r
892 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
893 EFI_STATUS Status;\r
894 EFI_DEV_PATH *DPathNode;\r
895\r
896 Session = &Private->Session;\r
897 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
898 return NULL;\r
899 }\r
900\r
901 Conn = NET_LIST_USER_STRUCT_S (\r
902 Session->Conns.ForwardLink,\r
903 ISCSI_CONNECTION,\r
904 Link,\r
905 ISCSI_CONNECTION_SIGNATURE\r
906 );\r
907 Tcp4Io = &Conn->Tcp4Io;\r
908\r
909 Status = gBS->HandleProtocol (\r
910 Tcp4Io->Handle,\r
911 &gEfiDevicePathProtocolGuid,\r
69b0882d 912 (VOID **)&DevicePath\r
6a690e23 913 );\r
914 if (EFI_ERROR (Status)) {\r
915 return NULL;\r
916 }\r
917 //\r
918 // Duplicate it.\r
919 //\r
920 DevicePath = DuplicateDevicePath (DevicePath);\r
921\r
922 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
923\r
924 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
925 if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&\r
926 (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)\r
927 ) {\r
928\r
929 DPathNode->Ipv4.LocalPort = 0;\r
69b0882d 930 DPathNode->Ipv4.StaticIpAddress = (BOOLEAN) (!Session->ConfigData.NvData.InitiatorInfoFromDhcp);\r
6a690e23 931 break;\r
932 }\r
933\r
934 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
935 }\r
936\r
937 return DevicePath;\r
938}\r
939\r
940VOID\r
941EFIAPI\r
942IScsiOnExitBootService (\r
943 IN EFI_EVENT Event,\r
944 IN VOID *Context\r
945 )\r
946/*++\r
947\r
948Routine Description:\r
949\r
950 Abort the session when the transition from BS to RT is initiated.\r
951\r
952Arguments:\r
953\r
954 Event - The event signaled.\r
955 Context - The iSCSI driver data.\r
956\r
957Returns:\r
958\r
959 None.\r
960\r
961--*/\r
962{\r
963 ISCSI_DRIVER_DATA *Private;\r
964\r
965 Private = (ISCSI_DRIVER_DATA *) Context;\r
966 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
967\r
968 IScsiSessionAbort (&Private->Session);\r
969}\r