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