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