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