]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/iScsi/IScsiMisc.c
add iSCSI protocol
[mirror_edk2.git] / MdeModulePkg / Universal / iScsi / IScsiMisc.c
CommitLineData
6a690e23 1/*++\r
2\r
3Copyright (c) 2007 Intel Corporation. All rights reserved\r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
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
170 return 32 - Len;\r
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
199\r
200 NetZeroMem (Lun, 8);\r
201 NetZeroMem (LunUnitStr, sizeof (LunUnitStr));\r
202\r
203 Index = 0;\r
204 LunUnitStr[0] = Str;\r
205\r
206 if (!IsHexDigit (&Digit, *Str)) {\r
207 return EFI_INVALID_PARAMETER;\r
208 }\r
209\r
210 while (*Str != '\0') {\r
211 //\r
212 // Legal representations of LUN:\r
213 // 4752-3A4F-6b7e-2F99,\r
214 // 6734-9-156f-127,\r
215 // 4186-9\r
216 //\r
217 if (*Str == '-') {\r
218 *Str = '\0';\r
219 Index++;\r
220\r
221 if (*(Str + 1) != '\0') {\r
222 if (!IsHexDigit (&Digit, *(Str + 1))) {\r
223 return EFI_INVALID_PARAMETER;\r
224 }\r
225\r
226 LunUnitStr[Index] = Str + 1;\r
227 }\r
228 } else if (!IsHexDigit (&Digit, *Str)) {\r
229 return EFI_INVALID_PARAMETER;\r
230 }\r
231\r
232 Str++;\r
233 }\r
234\r
235 for (Index = 0; (Index < 4) && (LunUnitStr[Index] != NULL); Index++) {\r
236 if (AsciiStrLen (LunUnitStr[Index]) > 4) {\r
237 return EFI_INVALID_PARAMETER;\r
238 }\r
239\r
240 *((UINT16 *) &Lun[Index * 2]) = HTONS (AsciiStrHexToUintn (LunUnitStr[Index]));\r
241 }\r
242\r
243 return EFI_SUCCESS;\r
244}\r
245\r
246VOID\r
247IScsiLunToUnicodeStr (\r
248 IN UINT8 *Lun,\r
249 OUT CHAR16 *Str\r
250 )\r
251/*++\r
252\r
253Routine Description:\r
254\r
255 Convert the 64-bit LUN into the hexadecimal encoded LUN string.\r
256\r
257Arguments:\r
258\r
259 Lun - The 64-bit LUN.\r
260 Str - The storage to return the hexadecimal encoded LUN string.\r
261\r
262Returns:\r
263\r
264 None.\r
265\r
266--*/\r
267{\r
268 UINTN Index;\r
269 CHAR16 *TempStr;\r
270\r
271 TempStr = Str;\r
272\r
273 for (Index = 0; Index < 4; Index++) {\r
274\r
275 if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {\r
276 StrCpy (TempStr, L"0-");\r
277 } else {\r
278 TempStr[0] = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];\r
279 TempStr[1] = (CHAR16) IScsiHexString[Lun[2 * Index] & 0xf];\r
280 TempStr[2] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];\r
281 TempStr[3] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0xf];\r
282 TempStr[4] = L'-';\r
283 TempStr[5] = 0;\r
284\r
285 StrTrim (TempStr, L'0');\r
286 }\r
287\r
288 TempStr += StrLen (TempStr);\r
289 }\r
290\r
291 Str[StrLen (Str) - 1] = 0;\r
292\r
293 for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {\r
294 if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {\r
295 Str[Index - 1] = 0;\r
296 } else {\r
297 break;\r
298 }\r
299 }\r
300}\r
301\r
302CHAR16 *\r
303IScsiAsciiStrToUnicodeStr (\r
304 IN CHAR8 *Source,\r
305 OUT CHAR16 *Destination\r
306 )\r
307/*++\r
308\r
309Routine Description:\r
310\r
311 Convert the ASCII string into a UNICODE string.\r
312\r
313Arguments:\r
314\r
315 Source - The ASCII string.\r
316 Destination - The storage to return the UNICODE string.\r
317\r
318Returns:\r
319\r
320 Pointer to the UNICODE string.\r
321\r
322--*/\r
323{\r
324 ASSERT (Destination != NULL);\r
325 ASSERT (Source != NULL);\r
326\r
327 while (*Source != '\0') {\r
328 *(Destination++) = (CHAR16) *(Source++);\r
329 }\r
330\r
331 *Destination = '\0';\r
332\r
333 return Destination;\r
334}\r
335\r
336CHAR8 *\r
337IScsiUnicodeStrToAsciiStr (\r
338 IN CHAR16 *Source,\r
339 OUT CHAR8 *Destination\r
340 )\r
341/*++\r
342\r
343Routine Description:\r
344\r
345 Convert the UNICODE string into an ASCII string.\r
346\r
347Arguments:\r
348\r
349 Source - The UNICODE string.\r
350 Destination - The storage to return the ASCII string.\r
351\r
352Returns:\r
353\r
354 Pointer to the ASCII string.\r
355\r
356--*/\r
357{\r
358 ASSERT (Destination != NULL);\r
359 ASSERT (Source != NULL);\r
360\r
361 while (*Source != '\0') {\r
362 //\r
363 // If any Unicode characters in Source contain\r
364 // non-zero value in the upper 8 bits, then ASSERT().\r
365 //\r
366 ASSERT (*Source < 0x100);\r
367 *(Destination++) = (CHAR8) *(Source++);\r
368 }\r
369\r
370 *Destination = '\0';\r
371\r
372 return Destination;\r
373}\r
374\r
375EFI_STATUS\r
376IScsiAsciiStrToIp (\r
377 IN CHAR8 *Str,\r
378 OUT EFI_IPv4_ADDRESS *Ip\r
379 )\r
380/*++\r
381\r
382Routine Description:\r
383\r
384 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
385\r
386Arguments:\r
387\r
388 Str - The UNICODE string.\r
389 Ip - The storage to return the ASCII string.\r
390\r
391Returns:\r
392\r
393 EFI_SUCCESS - The binary IP address is returned in Ip.\r
394 EFI_INVALID_PARAMETER - The IP string is malformatted.\r
395\r
396--*/\r
397{\r
398 UINTN Index;\r
399 UINTN Number;\r
400\r
401 Index = 0;\r
402\r
403 while (*Str) {\r
404\r
405 if (Index > 3) {\r
406 return EFI_INVALID_PARAMETER;\r
407 }\r
408\r
409 Number = 0;\r
410 while (NET_IS_DIGIT (*Str)) {\r
411 Number = Number * 10 + (*Str - '0');\r
412 Str++;\r
413 }\r
414\r
415 if (Number > 0xFF) {\r
416 return EFI_INVALID_PARAMETER;\r
417 }\r
418\r
419 Ip->Addr[Index] = (UINT8) Number;\r
420\r
421 if ((*Str != '\0') && (*Str != '.')) {\r
422 //\r
423 // The current character should be either the NULL terminator or\r
424 // the dot delimiter.\r
425 //\r
426 return EFI_INVALID_PARAMETER;\r
427 }\r
428\r
429 if (*Str == '.') {\r
430 //\r
431 // Skip the delimiter.\r
432 //\r
433 Str++;\r
434 }\r
435\r
436 Index++;\r
437 }\r
438\r
439 if (Index != 4) {\r
440 return EFI_INVALID_PARAMETER;\r
441 }\r
442\r
443 return EFI_SUCCESS;\r
444}\r
445\r
446VOID\r
447IScsiMacAddrToStr (\r
448 IN EFI_MAC_ADDRESS *Mac,\r
449 IN UINT32 Len,\r
450 OUT CHAR16 *Str\r
451 )\r
452/*++\r
453\r
454Routine Description:\r
455\r
456 Convert the mac address into a hexadecimal encoded "-" seperated string.\r
457\r
458Arguments:\r
459\r
460 Mac - The mac address.\r
461 Len - Length in bytes of the mac address.\r
462 Str - The storage to return the mac string.\r
463\r
464Returns:\r
465\r
466 None.\r
467\r
468--*/\r
469{\r
470 UINT32 Index;\r
471\r
472 for (Index = 0; Index < Len; Index++) {\r
473 Str[3 * Index] = NibbleToHexChar (Mac->Addr[Index] >> 4);\r
474 Str[3 * Index + 1] = NibbleToHexChar (Mac->Addr[Index]);\r
475 Str[3 * Index + 2] = L'-';\r
476 }\r
477\r
478 Str[3 * Index - 1] = L'\0';\r
479}\r
480\r
481EFI_STATUS\r
482IScsiBinToHex (\r
483 IN UINT8 *BinBuffer,\r
484 IN UINT32 BinLength,\r
485 IN OUT CHAR8 *HexStr,\r
486 IN OUT UINT32 *HexLength\r
487 )\r
488/*++\r
489\r
490Routine Description:\r
491\r
492 Convert the binary encoded buffer into a hexadecimal encoded string.\r
493\r
494Arguments:\r
495\r
496 BinBuffer - The buffer containing the binary data.\r
497 BinLength - Length of the binary buffer.\r
498 HexStr - Pointer to the string.\r
499 HexLength - The length of the string.\r
500\r
501Returns:\r
502\r
503 EFI_SUCCESS - The binary data is converted to the hexadecimal string \r
504 and the length of the string is updated.\r
505 EFI_BUFFER_TOO_SMALL - The string is too small.\r
506\r
507--*/\r
508{\r
509 UINTN Index;\r
510\r
511 if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {\r
512 return EFI_INVALID_PARAMETER;\r
513 }\r
514\r
515 if (((*HexLength) - 3) < BinLength * 2) {\r
516 *HexLength = BinLength * 2 + 3;\r
517 return EFI_BUFFER_TOO_SMALL;\r
518 }\r
519\r
520 *HexLength = BinLength * 2 + 3;\r
521 //\r
522 // Prefix for Hex String\r
523 //\r
524 HexStr[0] = '0';\r
525 HexStr[1] = 'x';\r
526\r
527 for (Index = 0; Index < BinLength; Index++) {\r
528 HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];\r
529 HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];\r
530 }\r
531\r
532 HexStr[Index * 2 + 2] = '\0';\r
533\r
534 return EFI_SUCCESS;\r
535}\r
536\r
537EFI_STATUS\r
538IScsiHexToBin (\r
539 IN OUT UINT8 *BinBuffer,\r
540 IN OUT UINT32 *BinLength,\r
541 IN CHAR8 *HexStr\r
542 )\r
543/*++\r
544\r
545Routine Description:\r
546\r
547 Convert the hexadecimal string into a binary encoded buffer.\r
548\r
549Arguments:\r
550\r
551 BinBuffer - The binary buffer.\r
552 BinLength - Length of the binary buffer.\r
553 HexStr - The hexadecimal string.\r
554\r
555Returns:\r
556\r
557 EFI_SUCCESS - The hexadecimal string is converted into a binary \r
558 encoded buffer.\r
559 EFI_BUFFER_TOO_SMALL - The binary buffer is too small to hold the converted data.s\r
560\r
561--*/\r
562{\r
563 UINTN Index;\r
564 UINT32 HexCount;\r
565 CHAR8 *HexBuf;\r
566 UINT8 Digit;\r
567 UINT8 Byte;\r
568\r
569 //\r
570 // Find out how many hex characters the string has.\r
571 //\r
572 HexBuf = HexStr;\r
573 if ((HexBuf[0] == '0') && ((HexBuf[1] == 'x') || (HexBuf[1] == 'X'))) {\r
574 HexBuf += 2;\r
575 }\r
576\r
577 for (Index = 0, HexCount = 0; IsHexDigit (&Digit, HexBuf[Index]); Index++, HexCount++)\r
578 ;\r
579\r
580 if (HexCount == 0) {\r
581 *BinLength = 0;\r
582 return EFI_SUCCESS;\r
583 }\r
584 //\r
585 // Test if buffer is passed enough.\r
586 //\r
587 if (((HexCount + 1) / 2) > *BinLength) {\r
588 *BinLength = (HexCount + 1) / 2;\r
589 return EFI_BUFFER_TOO_SMALL;\r
590 }\r
591\r
592 *BinLength = (HexCount + 1) / 2;\r
593\r
594 for (Index = 0; Index < HexCount; Index++) {\r
595\r
596 IsHexDigit (&Digit, HexBuf[HexCount - 1 - Index]);\r
597\r
598 if ((Index & 1) == 0) {\r
599 Byte = Digit;\r
600 } else {\r
601 Byte = BinBuffer[*BinLength - 1 - Index / 2];\r
602 Byte &= 0x0F;\r
603 Byte |= Digit << 4;\r
604 }\r
605\r
606 BinBuffer[*BinLength - 1 - Index / 2] = Byte;\r
607 }\r
608\r
609 return EFI_SUCCESS;\r
610}\r
611\r
612VOID\r
613IScsiGenRandom (\r
614 IN OUT UINT8 *Rand,\r
615 IN UINTN RandLength\r
616 )\r
617/*++\r
618\r
619Routine Description:\r
620\r
621 Generate random numbers.\r
622\r
623Arguments:\r
624\r
625 Rand - The buffer to contain random numbers.\r
626 RandLength - The length of the Rand buffer.\r
627\r
628Returns:\r
629\r
630 None.\r
631\r
632--*/\r
633{\r
634 UINT32 Random;\r
635\r
636 while (RandLength > 0) {\r
637 Random = NET_RANDOM (NetRandomInitSeed ());\r
638 *Rand++ = (UINT8) (Random);\r
639 RandLength--;\r
640 }\r
641}\r
642\r
643ISCSI_DRIVER_DATA *\r
644IScsiCreateDriverData (\r
645 IN EFI_HANDLE Image,\r
646 IN EFI_HANDLE Controller\r
647 )\r
648/*++\r
649\r
650Routine Description:\r
651\r
652 Create the iSCSI driver data..\r
653\r
654Arguments:\r
655\r
656 Image - The handle of the driver image.\r
657 Controller - The handle of the controller.\r
658\r
659Returns:\r
660\r
661 The iSCSI driver data created.\r
662\r
663--*/\r
664{\r
665 ISCSI_DRIVER_DATA *Private;\r
666 EFI_STATUS Status;\r
667\r
668 Private = NetAllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
669 if (Private == NULL) {\r
670 return NULL;\r
671 }\r
672\r
673 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
674 Private->Image = Image;\r
675 Private->Controller = Controller;\r
676\r
677 //\r
678 // Create an event to be signal when the BS to RT transition is triggerd so\r
679 // as to abort the iSCSI session.\r
680 //\r
681 Status = gBS->CreateEvent (\r
682 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
683 TPL_CALLBACK,\r
684 IScsiOnExitBootService,\r
685 Private,\r
686 &Private->ExitBootServiceEvent\r
687 );\r
688 if (EFI_ERROR (Status)) {\r
689 NetFreePool (Private);\r
690 return NULL;\r
691 }\r
692\r
693 NetCopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
694\r
695 //\r
696 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
697 //\r
698 Private->ExtScsiPassThruMode.AdapterId = 2;\r
699 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
700 Private->ExtScsiPassThruMode.IoAlign = 4;\r
701 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
702\r
703 //\r
704 // Install the Ext SCSI PASS THRU protocol.\r
705 //\r
706 Status = gBS->InstallProtocolInterface (\r
707 &Private->ExtScsiPassThruHandle,\r
708 &gEfiExtScsiPassThruProtocolGuid,\r
709 EFI_NATIVE_INTERFACE,\r
710 &Private->IScsiExtScsiPassThru\r
711 );\r
712 if (EFI_ERROR (Status)) {\r
713 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
714 NetFreePool (Private);\r
715\r
716 return NULL;\r
717 }\r
718\r
719 IScsiSessionInit (&Private->Session, FALSE);\r
720\r
721 return Private;\r
722}\r
723\r
724VOID\r
725IScsiCleanDriverData (\r
726 IN ISCSI_DRIVER_DATA *Private\r
727 )\r
728/*++\r
729\r
730Routine Description:\r
731\r
732 Clean the iSCSI driver data.\r
733\r
734Arguments:\r
735\r
736 Private - The iSCSI driver data.\r
737\r
738Returns:\r
739\r
740 None.\r
741\r
742--*/\r
743{\r
744 if (Private->DevicePath != NULL) {\r
745 gBS->UninstallProtocolInterface (\r
746 Private->ExtScsiPassThruHandle,\r
747 &gEfiDevicePathProtocolGuid,\r
748 Private->DevicePath\r
749 );\r
750\r
751 NetFreePool (Private->DevicePath);\r
752 }\r
753\r
754 if (Private->ExtScsiPassThruHandle != NULL) {\r
755 gBS->UninstallProtocolInterface (\r
756 Private->ExtScsiPassThruHandle,\r
757 &gEfiExtScsiPassThruProtocolGuid,\r
758 &Private->IScsiExtScsiPassThru\r
759 );\r
760 }\r
761\r
762 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
763\r
764 NetFreePool (Private);\r
765}\r
766\r
767EFI_STATUS\r
768IScsiGetConfigData (\r
769 IN ISCSI_DRIVER_DATA *Private\r
770 )\r
771/*++\r
772\r
773Routine Description:\r
774\r
775 Get the various configuration data of this iSCSI instance.\r
776\r
777Arguments:\r
778\r
779 Private - The iSCSI driver data.\r
780\r
781Returns:\r
782\r
783 EFI_SUCCESS - The configuration of this instance is got.\r
784 EFI_NOT_FOUND - This iSCSI instance is not configured yet.\r
785\r
786--*/\r
787{\r
788 EFI_STATUS Status;\r
789 ISCSI_SESSION *Session;\r
790 UINTN BufferSize;\r
791 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
792 EFI_SIMPLE_NETWORK_MODE *Mode;\r
793 CHAR16 MacString[65];\r
794\r
795 //\r
796 // get the iSCSI Initiator Name\r
797 //\r
798 Session = &Private->Session;\r
799 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
800 Status = gIScsiInitiatorName.Get (\r
801 &gIScsiInitiatorName,\r
802 &Session->InitiatorNameLength,\r
803 Session->InitiatorName\r
804 );\r
805 if (EFI_ERROR (Status)) {\r
806 return Status;\r
807 }\r
808\r
809 Status = gBS->HandleProtocol (\r
810 Private->Controller,\r
811 &gEfiSimpleNetworkProtocolGuid,\r
812 &Snp\r
813 );\r
814 if (EFI_ERROR (Status)) {\r
815 return Status;\r
816 }\r
817\r
818 Mode = Snp->Mode;\r
819\r
820 //\r
821 // Get the mac string, it's the name of various variable\r
822 //\r
823 IScsiMacAddrToStr (&Mode->PermanentAddress, Mode->HwAddressSize, MacString);\r
824\r
825 //\r
826 // Get the normal configuration.\r
827 //\r
828 BufferSize = sizeof (Session->ConfigData.NvData);\r
829 Status = gRT->GetVariable (\r
830 MacString,\r
831 &gEfiIScsiInitiatorNameProtocolGuid,\r
832 NULL,\r
833 &BufferSize,\r
834 &Session->ConfigData.NvData\r
835 );\r
836 if (EFI_ERROR (Status)) {\r
837 return Status;\r
838 }\r
839\r
840 if (!Session->ConfigData.NvData.Enabled) {\r
841 return EFI_ABORTED;\r
842 }\r
843 //\r
844 // Get the CHAP Auth information.\r
845 //\r
846 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
847 Status = gRT->GetVariable (\r
848 MacString,\r
849 &mIScsiCHAPAuthInfoGuid,\r
850 NULL,\r
851 &BufferSize,\r
852 &Session->AuthData.AuthConfig\r
853 );\r
854\r
855 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
856 //\r
857 // Start dhcp.\r
858 //\r
859 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
860 }\r
861\r
862 return Status;\r
863}\r
864\r
865EFI_DEVICE_PATH_PROTOCOL *\r
866IScsiGetTcpConnDevicePath (\r
867 IN ISCSI_DRIVER_DATA *Private\r
868 )\r
869/*++\r
870\r
871Routine Description:\r
872\r
873 Get the device path of the iSCSI tcp connection and update it.\r
874\r
875Arguments:\r
876\r
877 Private - The iSCSI driver data.\r
878\r
879Returns:\r
880\r
881 The updated device path.\r
882\r
883--*/\r
884{\r
885 ISCSI_SESSION *Session;\r
886 ISCSI_CONNECTION *Conn;\r
887 TCP4_IO *Tcp4Io;\r
888 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
889 EFI_STATUS Status;\r
890 EFI_DEV_PATH *DPathNode;\r
891\r
892 Session = &Private->Session;\r
893 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
894 return NULL;\r
895 }\r
896\r
897 Conn = NET_LIST_USER_STRUCT_S (\r
898 Session->Conns.ForwardLink,\r
899 ISCSI_CONNECTION,\r
900 Link,\r
901 ISCSI_CONNECTION_SIGNATURE\r
902 );\r
903 Tcp4Io = &Conn->Tcp4Io;\r
904\r
905 Status = gBS->HandleProtocol (\r
906 Tcp4Io->Handle,\r
907 &gEfiDevicePathProtocolGuid,\r
908 &DevicePath\r
909 );\r
910 if (EFI_ERROR (Status)) {\r
911 return NULL;\r
912 }\r
913 //\r
914 // Duplicate it.\r
915 //\r
916 DevicePath = DuplicateDevicePath (DevicePath);\r
917\r
918 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
919\r
920 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
921 if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&\r
922 (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)\r
923 ) {\r
924\r
925 DPathNode->Ipv4.LocalPort = 0;\r
926 DPathNode->Ipv4.StaticIpAddress = !Session->ConfigData.NvData.InitiatorInfoFromDhcp;\r
927 break;\r
928 }\r
929\r
930 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
931 }\r
932\r
933 return DevicePath;\r
934}\r
935\r
936VOID\r
937EFIAPI\r
938IScsiOnExitBootService (\r
939 IN EFI_EVENT Event,\r
940 IN VOID *Context\r
941 )\r
942/*++\r
943\r
944Routine Description:\r
945\r
946 Abort the session when the transition from BS to RT is initiated.\r
947\r
948Arguments:\r
949\r
950 Event - The event signaled.\r
951 Context - The iSCSI driver data.\r
952\r
953Returns:\r
954\r
955 None.\r
956\r
957--*/\r
958{\r
959 ISCSI_DRIVER_DATA *Private;\r
960\r
961 Private = (ISCSI_DRIVER_DATA *) Context;\r
962 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
963\r
964 IScsiSessionAbort (&Private->Session);\r
965}\r