]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiMisc.c
CommitLineData
12618416 1/** @file\r
55a64ae0 2 Miscellaneous routines for iSCSI driver.\r
6a690e23 3\r
d3215985 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
7a444476 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
d1102dba
LG
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
d1102dba 35\r
1055b68d 36 if (*Str == 0) {\r
6a690e23 37 return;\r
38 }\r
d1102dba 39\r
6a690e23 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
d1102dba 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
d1102dba
LG
54 while (*Pointer1 != 0) {\r
55 *Pointer2 = *Pointer1;\r
1055b68d 56 Pointer1++;\r
57 Pointer2++;\r
6a690e23 58 }\r
1055b68d 59 *Pointer2 = 0;\r
6a690e23 60 }\r
d1102dba
LG
61\r
62\r
1055b68d 63 for (Pointer1 = Str + StrLen(Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {\r
6a690e23 64 ;\r
65 }\r
d1102dba 66 if (Pointer1 != Str + StrLen(Str) - 1) {\r
1055b68d 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
963dbb30 77 @retval 0 Other errors as indicated.\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
d5893e0b 97 if ((ReverseMask & (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
d1102dba 112 Convert the hexadecimal encoded LUN string into the 64-bit LUN.\r
6a690e23 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
63d55bb9
LG
126 UINTN Index, IndexValue, IndexNum, SizeStr;\r
127 CHAR8 TemStr[2];\r
128 UINT8 TemValue;\r
f6b7393c 129 UINT16 Value[4];\r
d1102dba 130\r
e48e37fc 131 ZeroMem (Lun, 8);\r
63d55bb9
LG
132 ZeroMem (TemStr, 2);\r
133 ZeroMem ((UINT8 *) Value, sizeof (Value));\r
d1102dba 134 SizeStr = AsciiStrLen (Str);\r
63d55bb9
LG
135 IndexValue = 0;\r
136 IndexNum = 0;\r
137\r
138 for (Index = 0; Index < SizeStr; Index ++) {\r
139 TemStr[0] = Str[Index];\r
140 TemValue = (UINT8) AsciiStrHexToUint64 (TemStr);\r
141 if (TemValue == 0 && TemStr[0] != '0') {\r
142 if ((TemStr[0] != '-') || (IndexNum == 0)) {\r
143 //\r
144 // Invalid Lun Char\r
145 //\r
146 return EFI_INVALID_PARAMETER;\r
6a690e23 147 }\r
6a690e23 148 }\r
d1102dba 149\r
63d55bb9
LG
150 if ((TemValue == 0) && (TemStr[0] == '-')) {\r
151 //\r
152 // Next Lun value\r
153 //\r
154 if (++IndexValue >= 4) {\r
155 //\r
156 // Max 4 Lun value\r
157 //\r
158 return EFI_INVALID_PARAMETER;\r
159 }\r
160 //\r
161 // Restart str index for the next lun value\r
162 //\r
163 IndexNum = 0;\r
164 continue;\r
165 }\r
d1102dba 166\r
63d55bb9 167 if (++IndexNum > 4) {\r
d1102dba 168 //\r
63d55bb9
LG
169 // Each Lun Str can't exceed size 4, because it will be as UINT16 value\r
170 //\r
6a690e23 171 return EFI_INVALID_PARAMETER;\r
172 }\r
d1102dba 173\r
63d55bb9
LG
174 //\r
175 // Combine UINT16 value\r
176 //\r
177 Value[IndexValue] = (UINT16) ((Value[IndexValue] << 4) + TemValue);\r
6a690e23 178 }\r
d1102dba 179\r
63d55bb9
LG
180 for (Index = 0; Index <= IndexValue; Index ++) {\r
181 *((UINT16 *) &Lun[Index * 2]) = HTONS (Value[Index]);\r
182 }\r
d1102dba 183\r
6a690e23 184 return EFI_SUCCESS;\r
185}\r
186\r
12618416 187/**\r
6a690e23 188 Convert the 64-bit LUN into the hexadecimal encoded LUN string.\r
189\r
1055b68d 190 @param[in] Lun The 64-bit LUN.\r
191 @param[out] Str The storage to return the hexadecimal encoded LUN string.\r
12618416 192**/\r
193VOID\r
194IScsiLunToUnicodeStr (\r
195 IN UINT8 *Lun,\r
196 OUT CHAR16 *Str\r
197 )\r
6a690e23 198{\r
199 UINTN Index;\r
200 CHAR16 *TempStr;\r
201\r
202 TempStr = Str;\r
203\r
204 for (Index = 0; Index < 4; Index++) {\r
205\r
206 if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {\r
206b5f51 207 CopyMem(TempStr, L"0-", sizeof (L"0-"));\r
6a690e23 208 } else {\r
209 TempStr[0] = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];\r
ac7e320c 210 TempStr[1] = (CHAR16) IScsiHexString[Lun[2 * Index] & 0x0F];\r
6a690e23 211 TempStr[2] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];\r
ac7e320c 212 TempStr[3] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0x0F];\r
6a690e23 213 TempStr[4] = L'-';\r
214 TempStr[5] = 0;\r
215\r
216 StrTrim (TempStr, L'0');\r
217 }\r
218\r
219 TempStr += StrLen (TempStr);\r
220 }\r
221\r
523f48e7 222 ASSERT (StrLen(Str) >= 1);\r
6a690e23 223 Str[StrLen (Str) - 1] = 0;\r
224\r
225 for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {\r
226 if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {\r
227 Str[Index - 1] = 0;\r
228 } else {\r
229 break;\r
230 }\r
231 }\r
232}\r
233\r
12618416 234/**\r
6a690e23 235 Convert the ASCII string into a UNICODE string.\r
236\r
1055b68d 237 @param[in] Source The ASCII string.\r
238 @param[out] Destination The storage to return the UNICODE string.\r
6a690e23 239\r
1055b68d 240 @return CHAR16 * Pointer to the UNICODE string.\r
12618416 241**/\r
242CHAR16 *\r
243IScsiAsciiStrToUnicodeStr (\r
244 IN CHAR8 *Source,\r
245 OUT CHAR16 *Destination\r
246 )\r
6a690e23 247{\r
248 ASSERT (Destination != NULL);\r
249 ASSERT (Source != NULL);\r
250\r
251 while (*Source != '\0') {\r
252 *(Destination++) = (CHAR16) *(Source++);\r
253 }\r
254\r
255 *Destination = '\0';\r
256\r
257 return Destination;\r
258}\r
259\r
12618416 260/**\r
6a690e23 261 Convert the UNICODE string into an ASCII string.\r
262\r
1055b68d 263 @param[in] Source The UNICODE string.\r
264 @param[out] Destination The storage to return the ASCII string.\r
6a690e23 265\r
1055b68d 266 @return CHAR8 * Pointer to the ASCII string.\r
267**/\r
12618416 268CHAR8 *\r
269IScsiUnicodeStrToAsciiStr (\r
270 IN CHAR16 *Source,\r
271 OUT CHAR8 *Destination\r
272 )\r
6a690e23 273{\r
274 ASSERT (Destination != NULL);\r
275 ASSERT (Source != NULL);\r
276\r
277 while (*Source != '\0') {\r
278 //\r
279 // If any Unicode characters in Source contain\r
280 // non-zero value in the upper 8 bits, then ASSERT().\r
281 //\r
282 ASSERT (*Source < 0x100);\r
283 *(Destination++) = (CHAR8) *(Source++);\r
284 }\r
285\r
286 *Destination = '\0';\r
287\r
288 return Destination;\r
289}\r
290\r
12618416 291/**\r
6a690e23 292 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
293\r
1055b68d 294 @param[in] Str The UNICODE string.\r
295 @param[out] Ip The storage to return the ASCII string.\r
6a690e23 296\r
12618416 297 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
12618416 298 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
12618416 299**/\r
300EFI_STATUS\r
301IScsiAsciiStrToIp (\r
302 IN CHAR8 *Str,\r
303 OUT EFI_IPv4_ADDRESS *Ip\r
304 )\r
6a690e23 305{\r
306 UINTN Index;\r
307 UINTN Number;\r
308\r
309 Index = 0;\r
310\r
c5de0d55 311 while (*Str != 0) {\r
6a690e23 312\r
313 if (Index > 3) {\r
314 return EFI_INVALID_PARAMETER;\r
315 }\r
316\r
317 Number = 0;\r
318 while (NET_IS_DIGIT (*Str)) {\r
319 Number = Number * 10 + (*Str - '0');\r
320 Str++;\r
321 }\r
322\r
323 if (Number > 0xFF) {\r
324 return EFI_INVALID_PARAMETER;\r
325 }\r
326\r
327 Ip->Addr[Index] = (UINT8) Number;\r
328\r
329 if ((*Str != '\0') && (*Str != '.')) {\r
330 //\r
331 // The current character should be either the NULL terminator or\r
332 // the dot delimiter.\r
333 //\r
334 return EFI_INVALID_PARAMETER;\r
335 }\r
336\r
337 if (*Str == '.') {\r
338 //\r
339 // Skip the delimiter.\r
340 //\r
341 Str++;\r
342 }\r
343\r
344 Index++;\r
345 }\r
346\r
347 if (Index != 4) {\r
348 return EFI_INVALID_PARAMETER;\r
349 }\r
350\r
351 return EFI_SUCCESS;\r
352}\r
353\r
12618416 354/**\r
6a690e23 355 Convert the mac address into a hexadecimal encoded "-" seperated string.\r
356\r
779ae357 357 @param[in] Mac The mac address.\r
358 @param[in] Len Length in bytes of the mac address.\r
359 @param[in] VlanId VLAN ID of the network device.\r
360 @param[out] Str The storage to return the mac string.\r
12618416 361**/\r
362VOID\r
363IScsiMacAddrToStr (\r
364 IN EFI_MAC_ADDRESS *Mac,\r
365 IN UINT32 Len,\r
779ae357 366 IN UINT16 VlanId,\r
12618416 367 OUT CHAR16 *Str\r
368 )\r
6a690e23 369{\r
370 UINT32 Index;\r
779ae357 371 CHAR16 *String;\r
6a690e23 372\r
373 for (Index = 0; Index < Len; Index++) {\r
ac7e320c
LG
374 Str[3 * Index] = (CHAR16) IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];\r
375 Str[3 * Index + 1] = (CHAR16) IScsiHexString[Mac->Addr[Index] & 0x0F];\r
6a690e23 376 Str[3 * Index + 2] = L'-';\r
377 }\r
378\r
779ae357 379 String = &Str[3 * Index - 1] ;\r
380 if (VlanId != 0) {\r
381 String += UnicodeSPrint (String, 6 * sizeof (CHAR16), L"\\%04x", (UINTN) VlanId);\r
382 }\r
383\r
384 *String = L'\0';\r
6a690e23 385}\r
386\r
12618416 387/**\r
388 Convert the binary encoded buffer into a hexadecimal encoded string.\r
6a690e23 389\r
1055b68d 390 @param[in] BinBuffer The buffer containing the binary data.\r
391 @param[in] BinLength Length of the binary buffer.\r
392 @param[in, out] HexStr Pointer to the string.\r
393 @param[in, out] HexLength The length of the string.\r
6a690e23 394\r
d1102dba 395 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string\r
12618416 396 and the length of the string is updated.\r
12618416 397 @retval EFI_BUFFER_TOO_SMALL The string is too small.\r
1055b68d 398 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
12618416 399**/\r
400EFI_STATUS\r
401IScsiBinToHex (\r
402 IN UINT8 *BinBuffer,\r
403 IN UINT32 BinLength,\r
404 IN OUT CHAR8 *HexStr,\r
405 IN OUT UINT32 *HexLength\r
406 )\r
6a690e23 407{\r
408 UINTN Index;\r
409\r
410 if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {\r
411 return EFI_INVALID_PARAMETER;\r
412 }\r
413\r
414 if (((*HexLength) - 3) < BinLength * 2) {\r
415 *HexLength = BinLength * 2 + 3;\r
416 return EFI_BUFFER_TOO_SMALL;\r
417 }\r
418\r
419 *HexLength = BinLength * 2 + 3;\r
420 //\r
421 // Prefix for Hex String\r
422 //\r
423 HexStr[0] = '0';\r
424 HexStr[1] = 'x';\r
425\r
426 for (Index = 0; Index < BinLength; Index++) {\r
427 HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];\r
ac7e320c 428 HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0x0F];\r
6a690e23 429 }\r
430\r
431 HexStr[Index * 2 + 2] = '\0';\r
432\r
433 return EFI_SUCCESS;\r
434}\r
435\r
12618416 436/**\r
6a690e23 437 Convert the hexadecimal string into a binary encoded buffer.\r
438\r
1055b68d 439 @param[in, out] BinBuffer The binary buffer.\r
440 @param[in, out] BinLength Length of the binary buffer.\r
441 @param[in] HexStr The hexadecimal string.\r
6a690e23 442\r
12618416 443 @retval EFI_SUCCESS The hexadecimal string is converted into a binary\r
444 encoded buffer.\r
963dbb30 445 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.\r
12618416 446**/\r
447EFI_STATUS\r
448IScsiHexToBin (\r
449 IN OUT UINT8 *BinBuffer,\r
450 IN OUT UINT32 *BinLength,\r
451 IN CHAR8 *HexStr\r
452 )\r
6a690e23 453{\r
454 UINTN Index;\r
63d55bb9 455 UINTN Length;\r
6a690e23 456 UINT8 Digit;\r
63d55bb9 457 CHAR8 TemStr[2];\r
d1102dba 458\r
63d55bb9 459 ZeroMem (TemStr, sizeof (TemStr));\r
7c3eaa27 460\r
6a690e23 461 //\r
462 // Find out how many hex characters the string has.\r
463 //\r
63d55bb9
LG
464 if ((HexStr[0] == '0') && ((HexStr[1] == 'x') || (HexStr[1] == 'X'))) {\r
465 HexStr += 2;\r
6a690e23 466 }\r
d1102dba 467\r
63d55bb9 468 Length = AsciiStrLen (HexStr);\r
6a690e23 469\r
63d55bb9
LG
470 for (Index = 0; Index < Length; Index ++) {\r
471 TemStr[0] = HexStr[Index];\r
472 Digit = (UINT8) AsciiStrHexToUint64 (TemStr);\r
473 if (Digit == 0 && TemStr[0] != '0') {\r
474 //\r
475 // Invalid Lun Char\r
476 //\r
477 break;\r
478 }\r
6a690e23 479 if ((Index & 1) == 0) {\r
63d55bb9 480 BinBuffer [Index/2] = Digit;\r
6a690e23 481 } else {\r
63d55bb9 482 BinBuffer [Index/2] = (UINT8) ((BinBuffer [Index/2] << 4) + Digit);\r
6a690e23 483 }\r
6a690e23 484 }\r
d1102dba 485\r
63d55bb9 486 *BinLength = (UINT32) ((Index + 1)/2);\r
6a690e23 487\r
488 return EFI_SUCCESS;\r
489}\r
490\r
12618416 491/**\r
6a690e23 492 Generate random numbers.\r
493\r
1055b68d 494 @param[in, out] Rand The buffer to contain random numbers.\r
495 @param[in] RandLength The length of the Rand buffer.\r
12618416 496**/\r
497VOID\r
498IScsiGenRandom (\r
499 IN OUT UINT8 *Rand,\r
500 IN UINTN RandLength\r
501 )\r
6a690e23 502{\r
503 UINT32 Random;\r
504\r
505 while (RandLength > 0) {\r
506 Random = NET_RANDOM (NetRandomInitSeed ());\r
507 *Rand++ = (UINT8) (Random);\r
508 RandLength--;\r
509 }\r
510}\r
511\r
12618416 512/**\r
6a690e23 513 Create the iSCSI driver data..\r
514\r
1055b68d 515 @param[in] Image The handle of the driver image.\r
516 @param[in] Controller The handle of the controller.\r
6a690e23 517\r
1055b68d 518 @return The iSCSI driver data created.\r
963dbb30 519 @retval NULL Other errors as indicated.\r
12618416 520**/\r
521ISCSI_DRIVER_DATA *\r
522IScsiCreateDriverData (\r
523 IN EFI_HANDLE Image,\r
524 IN EFI_HANDLE Controller\r
525 )\r
6a690e23 526{\r
527 ISCSI_DRIVER_DATA *Private;\r
528 EFI_STATUS Status;\r
529\r
e48e37fc 530 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
6a690e23 531 if (Private == NULL) {\r
532 return NULL;\r
533 }\r
534\r
535 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
536 Private->Image = Image;\r
537 Private->Controller = Controller;\r
538\r
539 //\r
540 // Create an event to be signal when the BS to RT transition is triggerd so\r
541 // as to abort the iSCSI session.\r
542 //\r
01a5c994 543 Status = gBS->CreateEventEx (\r
544 EVT_NOTIFY_SIGNAL,\r
6a690e23 545 TPL_CALLBACK,\r
546 IScsiOnExitBootService,\r
547 Private,\r
01a5c994 548 &gEfiEventExitBootServicesGuid,\r
6a690e23 549 &Private->ExitBootServiceEvent\r
550 );\r
551 if (EFI_ERROR (Status)) {\r
766c7483 552 FreePool (Private);\r
6a690e23 553 return NULL;\r
554 }\r
555\r
e48e37fc 556 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
6a690e23 557\r
558 //\r
559 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
560 //\r
561 Private->ExtScsiPassThruMode.AdapterId = 2;\r
562 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
563 Private->ExtScsiPassThruMode.IoAlign = 4;\r
564 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
565\r
566 //\r
567 // Install the Ext SCSI PASS THRU protocol.\r
568 //\r
569 Status = gBS->InstallProtocolInterface (\r
570 &Private->ExtScsiPassThruHandle,\r
571 &gEfiExtScsiPassThruProtocolGuid,\r
572 EFI_NATIVE_INTERFACE,\r
573 &Private->IScsiExtScsiPassThru\r
574 );\r
575 if (EFI_ERROR (Status)) {\r
576 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
766c7483 577 FreePool (Private);\r
6a690e23 578\r
579 return NULL;\r
580 }\r
581\r
582 IScsiSessionInit (&Private->Session, FALSE);\r
583\r
584 return Private;\r
585}\r
586\r
12618416 587/**\r
6a690e23 588 Clean the iSCSI driver data.\r
589\r
e3761c71
ZL
590 @param[in] Private The iSCSI driver data.\r
591\r
6a270910 592 @retval EFI_SUCCESS The clean operation is successful.\r
e3761c71
ZL
593 @retval Others Other errors as indicated.\r
594\r
12618416 595**/\r
e3761c71 596EFI_STATUS\r
12618416 597IScsiCleanDriverData (\r
598 IN ISCSI_DRIVER_DATA *Private\r
599 )\r
6a690e23 600{\r
e3761c71
ZL
601 EFI_STATUS Status;\r
602\r
6a270910 603 Status = EFI_SUCCESS;\r
d1102dba 604\r
6a690e23 605 if (Private->DevicePath != NULL) {\r
e3761c71
ZL
606 Status = gBS->UninstallProtocolInterface (\r
607 Private->ExtScsiPassThruHandle,\r
608 &gEfiDevicePathProtocolGuid,\r
609 Private->DevicePath\r
610 );\r
611 if (EFI_ERROR (Status)) {\r
612 goto EXIT;\r
613 }\r
6a690e23 614\r
766c7483 615 FreePool (Private->DevicePath);\r
6a690e23 616 }\r
617\r
618 if (Private->ExtScsiPassThruHandle != NULL) {\r
e3761c71
ZL
619 Status = gBS->UninstallProtocolInterface (\r
620 Private->ExtScsiPassThruHandle,\r
621 &gEfiExtScsiPassThruProtocolGuid,\r
622 &Private->IScsiExtScsiPassThru\r
623 );\r
6a690e23 624 }\r
625\r
e3761c71 626EXIT:\r
d3215985
JW
627 if (Private->ExitBootServiceEvent != NULL) {\r
628 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
629 }\r
d1102dba 630\r
766c7483 631 FreePool (Private);\r
e3761c71 632 return Status;\r
6a690e23 633}\r
634\r
05a30011
WJ
635/**\r
636 Check wheather the Controller is configured to use DHCP protocol.\r
637\r
638 @param[in] Controller The handle of the controller.\r
d1102dba 639\r
05a30011
WJ
640 @retval TRUE The handle of the controller need the Dhcp protocol.\r
641 @retval FALSE The handle of the controller does not need the Dhcp protocol.\r
d1102dba 642\r
05a30011
WJ
643**/\r
644BOOLEAN\r
645IScsiDhcpIsConfigured (\r
646 IN EFI_HANDLE Controller\r
647 )\r
648{\r
649 EFI_STATUS Status;\r
650 EFI_MAC_ADDRESS MacAddress;\r
651 UINTN HwAddressSize;\r
652 UINT16 VlanId;\r
653 CHAR16 MacString[70];\r
654 ISCSI_SESSION_CONFIG_NVDATA *ConfigDataTmp;\r
655\r
656 //\r
657 // Get the mac string, it's the name of various variable\r
658 //\r
659 Status = NetLibGetMacAddress (Controller, &MacAddress, &HwAddressSize);\r
660 if (EFI_ERROR (Status)) {\r
661 return FALSE;\r
662 }\r
663 VlanId = NetLibGetVlanId (Controller);\r
664 IScsiMacAddrToStr (&MacAddress, (UINT32) HwAddressSize, VlanId, MacString);\r
665\r
666 //\r
667 // Get the normal configuration.\r
668 //\r
669 Status = GetVariable2 (\r
670 MacString,\r
671 &gEfiIScsiInitiatorNameProtocolGuid,\r
672 (VOID**)&ConfigDataTmp,\r
673 NULL\r
674 );\r
25a516ab 675 if (ConfigDataTmp == NULL || EFI_ERROR (Status)) {\r
05a30011
WJ
676 return FALSE;\r
677 }\r
05a30011
WJ
678\r
679 if (ConfigDataTmp->Enabled && ConfigDataTmp->InitiatorInfoFromDhcp) {\r
680 FreePool (ConfigDataTmp);\r
681 return TRUE;\r
682 }\r
683\r
684 FreePool (ConfigDataTmp);\r
685 return FALSE;\r
686}\r
687\r
12618416 688/**\r
6a690e23 689 Get the various configuration data of this iSCSI instance.\r
690\r
1055b68d 691 @param[in] Private The iSCSI driver data.\r
6a690e23 692\r
12618416 693 @retval EFI_SUCCESS The configuration of this instance is got.\r
1055b68d 694 @retval EFI_ABORTED The operation was aborted.\r
963dbb30 695 @retval Others Other errors as indicated.\r
12618416 696**/\r
697EFI_STATUS\r
698IScsiGetConfigData (\r
699 IN ISCSI_DRIVER_DATA *Private\r
700 )\r
6a690e23 701{\r
702 EFI_STATUS Status;\r
703 ISCSI_SESSION *Session;\r
704 UINTN BufferSize;\r
779ae357 705 EFI_MAC_ADDRESS MacAddress;\r
706 UINTN HwAddressSize;\r
707 UINT16 VlanId;\r
708 CHAR16 MacString[70];\r
6a690e23 709\r
710 //\r
711 // get the iSCSI Initiator Name\r
712 //\r
713 Session = &Private->Session;\r
714 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
715 Status = gIScsiInitiatorName.Get (\r
716 &gIScsiInitiatorName,\r
717 &Session->InitiatorNameLength,\r
718 Session->InitiatorName\r
719 );\r
720 if (EFI_ERROR (Status)) {\r
721 return Status;\r
722 }\r
723\r
6a690e23 724 //\r
725 // Get the mac string, it's the name of various variable\r
726 //\r
779ae357 727 Status = NetLibGetMacAddress (Private->Controller, &MacAddress, &HwAddressSize);\r
728 ASSERT (Status == EFI_SUCCESS);\r
729 VlanId = NetLibGetVlanId (Private->Controller);\r
730 IScsiMacAddrToStr (&MacAddress, (UINT32) HwAddressSize, VlanId, MacString);\r
6a690e23 731\r
732 //\r
733 // Get the normal configuration.\r
734 //\r
735 BufferSize = sizeof (Session->ConfigData.NvData);\r
736 Status = gRT->GetVariable (\r
737 MacString,\r
738 &gEfiIScsiInitiatorNameProtocolGuid,\r
739 NULL,\r
740 &BufferSize,\r
741 &Session->ConfigData.NvData\r
742 );\r
743 if (EFI_ERROR (Status)) {\r
744 return Status;\r
745 }\r
746\r
747 if (!Session->ConfigData.NvData.Enabled) {\r
748 return EFI_ABORTED;\r
749 }\r
750 //\r
751 // Get the CHAP Auth information.\r
752 //\r
753 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
754 Status = gRT->GetVariable (\r
755 MacString,\r
c8ad2d7a 756 &gIScsiCHAPAuthInfoGuid,\r
6a690e23 757 NULL,\r
758 &BufferSize,\r
759 &Session->AuthData.AuthConfig\r
760 );\r
761\r
762 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
763 //\r
764 // Start dhcp.\r
765 //\r
766 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
767 }\r
768\r
769 return Status;\r
770}\r
771\r
12618416 772/**\r
6a690e23 773 Get the device path of the iSCSI tcp connection and update it.\r
774\r
1055b68d 775 @param[in] Private The iSCSI driver data.\r
6a690e23 776\r
1055b68d 777 @return The updated device path.\r
963dbb30 778 @retval NULL Other errors as indicated.\r
12618416 779**/\r
780EFI_DEVICE_PATH_PROTOCOL *\r
781IScsiGetTcpConnDevicePath (\r
782 IN ISCSI_DRIVER_DATA *Private\r
783 )\r
6a690e23 784{\r
785 ISCSI_SESSION *Session;\r
786 ISCSI_CONNECTION *Conn;\r
787 TCP4_IO *Tcp4Io;\r
788 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
789 EFI_STATUS Status;\r
790 EFI_DEV_PATH *DPathNode;\r
791\r
792 Session = &Private->Session;\r
793 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
794 return NULL;\r
795 }\r
796\r
797 Conn = NET_LIST_USER_STRUCT_S (\r
798 Session->Conns.ForwardLink,\r
799 ISCSI_CONNECTION,\r
800 Link,\r
801 ISCSI_CONNECTION_SIGNATURE\r
802 );\r
803 Tcp4Io = &Conn->Tcp4Io;\r
804\r
805 Status = gBS->HandleProtocol (\r
806 Tcp4Io->Handle,\r
807 &gEfiDevicePathProtocolGuid,\r
69b0882d 808 (VOID **)&DevicePath\r
6a690e23 809 );\r
810 if (EFI_ERROR (Status)) {\r
811 return NULL;\r
812 }\r
813 //\r
814 // Duplicate it.\r
815 //\r
816 DevicePath = DuplicateDevicePath (DevicePath);\r
894d038a 817 if (DevicePath == NULL) {\r
818 return NULL;\r
819 }\r
6a690e23 820\r
821 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
822\r
823 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
824 if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&\r
825 (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)\r
826 ) {\r
827\r
828 DPathNode->Ipv4.LocalPort = 0;\r
d1102dba 829 DPathNode->Ipv4.StaticIpAddress =\r
501793fa
RN
830 (BOOLEAN) (!Session->ConfigData.NvData.InitiatorInfoFromDhcp);\r
831\r
7b0b3606 832 //\r
833 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.\r
834 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask\r
835 // do not exist.\r
836 // In new version of IPv4_DEVICE_PATH, structcure length is 27.\r
837 //\r
d1102dba 838 if (DevicePathNodeLength (&DPathNode->Ipv4) == IP4_NODE_LEN_NEW_VERSIONS) {\r
7b0b3606 839\r
840 IP4_COPY_ADDRESS (\r
841 &DPathNode->Ipv4.GatewayIpAddress,\r
842 &Session->ConfigData.NvData.Gateway\r
843 );\r
844\r
845 IP4_COPY_ADDRESS (\r
846 &DPathNode->Ipv4.SubnetMask,\r
847 &Session->ConfigData.NvData.SubnetMask\r
848 );\r
849 }\r
501793fa 850\r
6a690e23 851 break;\r
852 }\r
853\r
854 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
855 }\r
856\r
857 return DevicePath;\r
858}\r
859\r
12618416 860/**\r
861 Abort the session when the transition from BS to RT is initiated.\r
862\r
1055b68d 863 @param[in] Event The event signaled.\r
864 @param[in] Context The iSCSI driver data.\r
12618416 865**/\r
6a690e23 866VOID\r
867EFIAPI\r
868IScsiOnExitBootService (\r
869 IN EFI_EVENT Event,\r
870 IN VOID *Context\r
871 )\r
6a690e23 872{\r
873 ISCSI_DRIVER_DATA *Private;\r
874\r
875 Private = (ISCSI_DRIVER_DATA *) Context;\r
d1102dba 876\r
6a690e23 877 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
d3215985 878 Private->ExitBootServiceEvent = NULL;\r
6a690e23 879\r
880 IScsiSessionAbort (&Private->Session);\r
881}\r
18b24f92
FS
882\r
883/**\r
884 Tests whether a controller handle is being managed by IScsi driver.\r
885\r
886 This function tests whether the driver specified by DriverBindingHandle is\r
887 currently managing the controller specified by ControllerHandle. This test\r
888 is performed by evaluating if the the protocol specified by ProtocolGuid is\r
889 present on ControllerHandle and is was opened by DriverBindingHandle and Nic\r
d1102dba 890 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.\r
18b24f92
FS
891 If ProtocolGuid is NULL, then ASSERT().\r
892\r
893 @param ControllerHandle A handle for a controller to test.\r
894 @param DriverBindingHandle Specifies the driver binding handle for the\r
895 driver.\r
896 @param ProtocolGuid Specifies the protocol that the driver specified\r
897 by DriverBindingHandle opens in its Start()\r
898 function.\r
899\r
900 @retval EFI_SUCCESS ControllerHandle is managed by the driver\r
901 specified by DriverBindingHandle.\r
902 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver\r
903 specified by DriverBindingHandle.\r
904\r
905**/\r
906EFI_STATUS\r
907EFIAPI\r
908IScsiTestManagedDevice (\r
909 IN EFI_HANDLE ControllerHandle,\r
910 IN EFI_HANDLE DriverBindingHandle,\r
911 IN EFI_GUID *ProtocolGuid\r
912 )\r
913{\r
914 EFI_STATUS Status;\r
915 VOID *ManagedInterface;\r
916 EFI_HANDLE NicControllerHandle;\r
917\r
918 ASSERT (ProtocolGuid != NULL);\r
919\r
920 NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);\r
921 if (NicControllerHandle == NULL) {\r
922 return EFI_UNSUPPORTED;\r
923 }\r
924\r
925 Status = gBS->OpenProtocol (\r
926 ControllerHandle,\r
927 (EFI_GUID *) ProtocolGuid,\r
928 &ManagedInterface,\r
929 DriverBindingHandle,\r
930 NicControllerHandle,\r
931 EFI_OPEN_PROTOCOL_BY_DRIVER\r
932 );\r
933 if (!EFI_ERROR (Status)) {\r
934 gBS->CloseProtocol (\r
935 ControllerHandle,\r
936 (EFI_GUID *) ProtocolGuid,\r
937 DriverBindingHandle,\r
938 NicControllerHandle\r
939 );\r
940 return EFI_UNSUPPORTED;\r
941 }\r
942\r
943 if (Status != EFI_ALREADY_STARTED) {\r
944 return EFI_UNSUPPORTED;\r
945 }\r
946\r
947 return EFI_SUCCESS;\r
948}\r