Verified ChildHandle, and correct the name for a child.
[mirror_edk2.git] / NetworkPkg / IScsiDxe / ComponentName.c
1 /** @file\r
2   UEFI Component Name(2) protocol implementation for iSCSI.\r
3 \r
4 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution.  The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9 \r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13 **/\r
14 \r
15 #include "IScsiImpl.h"\r
16 \r
17 //\r
18 // EFI Component Name Protocol\r
19 //\r
20 GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName = {\r
21   IScsiComponentNameGetDriverName,\r
22   IScsiComponentNameGetControllerName,\r
23   "eng"\r
24 };\r
25 \r
26 //\r
27 // EFI Component Name 2 Protocol\r
28 //\r
29 GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2 = {\r
30   (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) IScsiComponentNameGetDriverName,\r
31   (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) IScsiComponentNameGetControllerName,\r
32   "en"\r
33 };\r
34 \r
35 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE     mIScsiDriverNameTable[] = {\r
36   {\r
37     "eng;en",\r
38     L"iSCSI Driver"\r
39   },\r
40   {\r
41     NULL,\r
42     NULL\r
43   }\r
44 };\r
45 \r
46 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE  *gIScsiControllerNameTable = NULL;\r
47 \r
48 /**\r
49   Retrieves a Unicode string that is the user readable name of the driver.\r
50 \r
51   This function retrieves the user readable name of a driver in the form of a\r
52   Unicode string. If the driver specified by This has a user readable name in\r
53   the language specified by Language, then a pointer to the driver name is\r
54   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
55   by This does not support the language specified by Language,\r
56   then EFI_UNSUPPORTED is returned.\r
57 \r
58   @param[in]  This              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
59                                 EFI_COMPONENT_NAME_PROTOCOL instance.\r
60 \r
61   @param[in]  Language          A pointer to a Null-terminated ASCII string\r
62                                 array indicating the language. This is the\r
63                                 language of the driver name that the caller is\r
64                                 requesting, and it must match one of the\r
65                                 languages specified in SupportedLanguages. The\r
66                                 number of languages supported by a driver is up\r
67                                 to the driver writer. Language is specified\r
68                                 in RFC 4646 or ISO 639-2 language code format.\r
69 \r
70   @param[out]  DriverName       A pointer to the Unicode string to return.\r
71                                 This Unicode string is the name of the\r
72                                 driver specified by This in the language\r
73                                 specified by Language.\r
74 \r
75   @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
76                                 This and the language specified by Language was\r
77                                 returned in DriverName.\r
78 \r
79   @retval EFI_INVALID_PARAMETER Language is NULL.\r
80 \r
81   @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
82 \r
83   @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
84                                 the language specified by Language.\r
85 \r
86 **/\r
87 EFI_STATUS\r
88 EFIAPI\r
89 IScsiComponentNameGetDriverName (\r
90   IN  EFI_COMPONENT_NAME_PROTOCOL   *This,\r
91   IN  CHAR8                         *Language,\r
92   OUT CHAR16                        **DriverName\r
93   )\r
94 {\r
95   return LookupUnicodeString2 (\r
96            Language,\r
97            This->SupportedLanguages,\r
98            mIScsiDriverNameTable,\r
99            DriverName,\r
100            (BOOLEAN) (This == &gIScsiComponentName)\r
101            );\r
102 }\r
103 \r
104 /**\r
105   Update the component name for the iSCSI instance.\r
106 \r
107   @param[in]  IScsiExtScsiPassThru  A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.\r
108   @param[in]  Ipv6Flag              TRUE if IP6 network stack is used.\r
109   \r
110   @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.\r
111   @retval EFI_INVALID_PARAMETER     The input parameter is invalid.\r
112   @retval EFI_UNSUPPORTED           Can't get the corresponding NIC info from the Controller handle.\r
113   \r
114 **/\r
115 EFI_STATUS\r
116 UpdateName (\r
117   IN   EFI_EXT_SCSI_PASS_THRU_PROTOCOL *IScsiExtScsiPassThru,\r
118   IN   BOOLEAN     Ipv6Flag\r
119   )\r
120 {\r
121   EFI_STATUS                       Status;\r
122   CHAR16                           HandleName[80];\r
123   ISCSI_DRIVER_DATA                *Private;\r
124   UINT8                            NicIndex;\r
125 \r
126   if (IScsiExtScsiPassThru == NULL) {\r
127     return EFI_INVALID_PARAMETER;\r
128   }\r
129   \r
130   Private  = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (IScsiExtScsiPassThru);\r
131   NicIndex = Private->Session->ConfigData->NicIndex;\r
132     \r
133   UnicodeSPrint (\r
134     HandleName,\r
135     sizeof (HandleName),\r
136     L"iSCSI (%s, NicIndex=%d)",\r
137     Ipv6Flag ? L"IPv6" : L"IPv4",\r
138     NicIndex\r
139   );\r
140 \r
141   if (gIScsiControllerNameTable != NULL) {\r
142     FreeUnicodeStringTable (gIScsiControllerNameTable);\r
143     gIScsiControllerNameTable = NULL;\r
144   }\r
145 \r
146   Status = AddUnicodeString2 (\r
147              "eng",\r
148              gIScsiComponentName.SupportedLanguages,\r
149              &gIScsiControllerNameTable,\r
150              HandleName,\r
151              TRUE\r
152              );\r
153   if (EFI_ERROR (Status)) {\r
154     return Status;\r
155   }\r
156 \r
157   return AddUnicodeString2 (\r
158            "en",\r
159            gIScsiComponentName2.SupportedLanguages,\r
160            &gIScsiControllerNameTable,\r
161            HandleName,\r
162            FALSE\r
163            );\r
164 }\r
165 \r
166 /**\r
167   Retrieves a Unicode string that is the user readable name of the controller\r
168   that is being managed by a driver.\r
169 \r
170   This function retrieves the user readable name of the controller specified by\r
171   ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
172   driver specified by This has a user readable name in the language specified by\r
173   Language, then a pointer to the controller name is returned in ControllerName,\r
174   and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
175   managing the controller specified by ControllerHandle and ChildHandle,\r
176   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
177   support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
178 \r
179   @param[in]  This              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
180                                 EFI_COMPONENT_NAME_PROTOCOL instance.\r
181 \r
182   @param[in]  ControllerHandle  The handle of a controller that the driver\r
183                                 specified by This is managing.  This handle\r
184                                 specifies the controller whose name is to be\r
185                                 returned.\r
186 \r
187   @param[in]  ChildHandle       The handle of the child controller to retrieve\r
188                                 the name of.  This is an optional parameter that\r
189                                 may be NULL.  It will be NULL for device\r
190                                 drivers.  It will also be NULL for a bus drivers\r
191                                 that wish to retrieve the name of the bus\r
192                                 controller.  It will not be NULL for a bus\r
193                                 driver that wishes to retrieve the name of a\r
194                                 child controller.\r
195 \r
196   @param[in]  Language          A pointer to a Null-terminated ASCII string\r
197                                 array indicating the language.  This is the\r
198                                 language of the driver name that the caller is\r
199                                 requesting, and it must match one of the\r
200                                 languages specified in SupportedLanguages. The\r
201                                 number of languages supported by a driver is up\r
202                                 to the driver writer. Language is specified in\r
203                                 RFC 4646 or ISO 639-2 language code format.\r
204 \r
205   @param[out]  ControllerName   A pointer to the Unicode string to return.\r
206                                 This Unicode string is the name of the\r
207                                 controller specified by ControllerHandle and\r
208                                 ChildHandle in the language specified by\r
209                                 Language, from the point of view of the driver\r
210                                 specified by This.\r
211 \r
212   @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
213                                 the language specified by Language for the\r
214                                 driver specified by This was returned in\r
215                                 DriverName.\r
216 \r
217   @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
218 \r
219   @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid\r
220                                 EFI_HANDLE.\r
221 \r
222   @retval EFI_INVALID_PARAMETER Language is NULL.\r
223 \r
224   @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
225 \r
226   @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
227                                 managing the controller specified by\r
228                                 ControllerHandle and ChildHandle.\r
229 \r
230   @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
231                                 the language specified by Language.\r
232 \r
233 **/\r
234 EFI_STATUS\r
235 EFIAPI\r
236 IScsiComponentNameGetControllerName (\r
237   IN  EFI_COMPONENT_NAME_PROTOCOL   *This,\r
238   IN  EFI_HANDLE                    ControllerHandle,\r
239   IN  EFI_HANDLE                    ChildHandle        OPTIONAL,\r
240   IN  CHAR8                         *Language,\r
241   OUT CHAR16                        **ControllerName\r
242   )\r
243 {\r
244   EFI_STATUS                      Status;\r
245   \r
246   EFI_HANDLE                      IScsiController;\r
247   BOOLEAN                         Ipv6Flag;\r
248   EFI_GUID                        *IScsiPrivateGuid;\r
249   ISCSI_PRIVATE_PROTOCOL          *IScsiIdentifier;\r
250   \r
251   EFI_EXT_SCSI_PASS_THRU_PROTOCOL *IScsiExtScsiPassThru;\r
252   \r
253   if (ControllerHandle == NULL) {\r
254     return EFI_UNSUPPORTED;\r
255   }\r
256 \r
257   //\r
258   // Get the handle of the controller we are controling.\r
259   //\r
260   IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
261   if (IScsiController != NULL) {\r
262     IScsiPrivateGuid = &gIScsiV4PrivateGuid;\r
263     Ipv6Flag = FALSE;\r
264   } else {\r
265     IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);\r
266     if (IScsiController != NULL) {\r
267       IScsiPrivateGuid = &gIScsiV6PrivateGuid;\r
268       Ipv6Flag = TRUE;\r
269     } else {\r
270       return EFI_UNSUPPORTED;\r
271     }\r
272   }\r
273 \r
274   Status = gBS->OpenProtocol (\r
275                   IScsiController,\r
276                   IScsiPrivateGuid,\r
277                   (VOID **) &IScsiIdentifier,\r
278                   NULL,\r
279                   NULL,\r
280                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
281                   );\r
282   if (EFI_ERROR (Status)) {\r
283     return Status;\r
284   }\r
285 \r
286   if(ChildHandle != NULL) {\r
287     if(!Ipv6Flag) {\r
288       //\r
289       // Make sure this driver produced ChildHandle\r
290       //\r
291       Status = EfiTestChildHandle (\r
292                  ControllerHandle,\r
293                  ChildHandle,\r
294                  &gEfiTcp4ProtocolGuid\r
295                  );\r
296       if (EFI_ERROR (Status)) {\r
297         return Status;\r
298       }\r
299     } else {\r
300       //\r
301       // Make sure this driver produced ChildHandle\r
302       //\r
303       Status = EfiTestChildHandle (\r
304                  ControllerHandle,\r
305                  ChildHandle,\r
306                  &gEfiTcp6ProtocolGuid\r
307                  );\r
308       if (EFI_ERROR (Status)) {\r
309         return Status;\r
310       }\r
311     }\r
312     \r
313     //\r
314     // Retrieve an instance of a produced protocol from ChildHandle\r
315     //\r
316     Status = gBS->OpenProtocol (\r
317                     ChildHandle,\r
318                     &gEfiExtScsiPassThruProtocolGuid,\r
319                    (VOID **)&IScsiExtScsiPassThru,\r
320                     NULL,\r
321                     NULL,\r
322                     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
323                     );\r
324     if (EFI_ERROR (Status)) {\r
325       return Status;\r
326     }\r
327     \r
328     //\r
329     // Update the component name for this child handle.\r
330     //\r
331     Status = UpdateName (IScsiExtScsiPassThru, Ipv6Flag);\r
332     if (EFI_ERROR (Status)) {\r
333       return Status;\r
334     }\r
335   }\r
336 \r
337   return LookupUnicodeString2 (\r
338            Language,\r
339            This->SupportedLanguages,\r
340            gIScsiControllerNameTable,\r
341            ControllerName,\r
342            (BOOLEAN)(This == &gIScsiComponentName)\r
343            );\r
344 }\r