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