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