]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
1)update function header coding style issue
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiDriver.c
CommitLineData
12618416 1/** @file\r
fd82de4e 2 The entry point of IScsi driver.\r
6a690e23 3\r
fd82de4e 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
17EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {\r
18 IScsiDriverBindingSupported,\r
19 IScsiDriverBindingStart,\r
20 IScsiDriverBindingStop,\r
21 0xa,\r
22 NULL,\r
23 NULL\r
24};\r
25\r
26EFI_GUID mIScsiPrivateGuid = ISCSI_PRIVATE_GUID;\r
27\r
6a690e23 28\r
fd82de4e 29/**\r
30 Tests to see if this driver supports a given controller. If a child device is provided, \r
31 it further tests to see if this driver supports creating a handle for the specified child device.\r
32\r
33 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
34 @param[in] ControllerHandle The handle of the controller to test. This handle \r
35 must support a protocol interface that supplies \r
36 an I/O abstraction to the driver.\r
37 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
38 This parameter is ignored by device drivers, and is optional for bus drivers.\r
39\r
40\r
41 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
42 RemainingDevicePath is supported by the driver specified by This.\r
43 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
44 RemainingDevicePath is already being managed by the driver\r
45 specified by This.\r
46 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
47 RemainingDevicePath is already being managed by a different\r
48 driver or an application that requires exclusive acces.\r
49 Currently not implemented.\r
50 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
51 RemainingDevicePath is not supported by the driver specified by This.\r
12618416 52**/\r
53EFI_STATUS\r
54EFIAPI\r
55IScsiDriverBindingSupported (\r
fd82de4e 56 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
12618416 57 IN EFI_HANDLE ControllerHandle,\r
fd82de4e 58 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
12618416 59 )\r
6a690e23 60{\r
61 EFI_STATUS Status;\r
62 EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
63\r
64 Status = gBS->OpenProtocol (\r
65 ControllerHandle,\r
66 &mIScsiPrivateGuid,\r
67 NULL,\r
68 This->DriverBindingHandle,\r
69 ControllerHandle,\r
70 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
71 );\r
72 if (!EFI_ERROR (Status)) {\r
73 return EFI_ALREADY_STARTED;\r
74 }\r
75\r
76 Status = gBS->OpenProtocol (\r
77 ControllerHandle,\r
78 &gEfiTcp4ServiceBindingProtocolGuid,\r
79 NULL,\r
80 This->DriverBindingHandle,\r
81 ControllerHandle,\r
82 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
83 );\r
84 if (EFI_ERROR (Status)) {\r
85 return EFI_UNSUPPORTED;\r
86 }\r
87\r
88 CurrentDevicePath = RemainingDevicePath;\r
89 if (CurrentDevicePath != NULL) {\r
90 while (!IsDevicePathEnd (CurrentDevicePath)) {\r
91 if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {\r
92 return EFI_SUCCESS;\r
93 }\r
94\r
95 CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);\r
96 }\r
97\r
98 return EFI_UNSUPPORTED;\r
99 }\r
100\r
101 return EFI_SUCCESS;\r
102}\r
103\r
12618416 104/**\r
fd82de4e 105 Start this driver on ControllerHandle. The Start() function is designed to be \r
106 invoked from the EFI boot service ConnectController(). As a result, much of \r
107 the error checking on the parameters to Start() has been moved into this \r
108 common boot service. It is legal to call Start() from other locations, \r
109 but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
110 1. ControllerHandle must be a valid EFI_HANDLE.\r
111 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
112 EFI_DEVICE_PATH_PROTOCOL.\r
113 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
114 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. \r
115\r
116 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
117 @param[in] ControllerHandle The handle of the controller to start. This handle \r
118 must support a protocol interface that supplies \r
119 an I/O abstraction to the driver.\r
120 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
121 This parameter is ignored by device drivers, and is optional for bus drivers.\r
122\r
123 @retval EFI_SUCCESS The device was started.\r
124 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.\r
125 Currently not implemented.\r
126 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
127 @retval Others The driver failded to start the device.\r
12618416 128**/\r
6a690e23 129EFI_STATUS\r
130EFIAPI\r
131IScsiDriverBindingStart (\r
fd82de4e 132 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
6a690e23 133 IN EFI_HANDLE ControllerHandle,\r
fd82de4e 134 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
6a690e23 135 )\r
6a690e23 136{\r
137 EFI_STATUS Status;\r
138 ISCSI_DRIVER_DATA *Private;\r
139\r
140 //\r
141 // Try to add a port configuration page for this controller.\r
142 //\r
143 IScsiConfigUpdateForm (This->DriverBindingHandle, ControllerHandle, TRUE);\r
144\r
145 Private = IScsiCreateDriverData (This->DriverBindingHandle, ControllerHandle);\r
146 if (Private == NULL) {\r
147 return EFI_OUT_OF_RESOURCES;\r
148 }\r
149 //\r
150 // Get the iSCSI configuration data of this controller.\r
151 //\r
152 Status = IScsiGetConfigData (Private);\r
153 if (EFI_ERROR (Status)) {\r
154 goto ON_ERROR;\r
155 }\r
156 //\r
157 // Try to login and create an iSCSI session according to the configuration.\r
158 //\r
159 Status = IScsiSessionLogin (Private);\r
160 if (Status == EFI_MEDIA_CHANGED) {\r
161 //\r
162 // The specified target is not available and the redirection information is\r
163 // got, login the session again with the updated target address.\r
164 //\r
165 Status = IScsiSessionLogin (Private);\r
166 }\r
167\r
168 if (EFI_ERROR (Status)) {\r
169 goto ON_ERROR;\r
170 }\r
171 //\r
172 // Duplicate the Session's tcp connection device path. The source port field\r
173 // will be set to zero as one iSCSI session is comprised of several iSCSI\r
174 // connections.\r
175 //\r
176 Private->DevicePath = IScsiGetTcpConnDevicePath (Private);\r
177 if (Private->DevicePath == NULL) {\r
178 goto ON_ERROR;\r
179 }\r
180 //\r
181 // Install the updated device path onto the ExtScsiPassThruHandle.\r
182 //\r
183 Status = gBS->InstallProtocolInterface (\r
184 &Private->ExtScsiPassThruHandle,\r
185 &gEfiDevicePathProtocolGuid,\r
186 EFI_NATIVE_INTERFACE,\r
187 Private->DevicePath\r
188 );\r
189 if (EFI_ERROR (Status)) {\r
190 goto ON_ERROR;\r
191 }\r
192 //\r
193 // Install the iSCSI private stuff as a flag to indicate this controller\r
194 // is already controlled by iSCSI driver.\r
195 //\r
196 Status = gBS->InstallProtocolInterface (\r
197 &ControllerHandle,\r
198 &mIScsiPrivateGuid,\r
199 EFI_NATIVE_INTERFACE,\r
200 &Private->IScsiIdentifier\r
201 );\r
202 if (EFI_ERROR (Status)) {\r
203 goto ON_ERROR;\r
204 }\r
205 //\r
206 // Update/Publish the iSCSI Boot Firmware Table.\r
207 //\r
208 IScsiPublishIbft ();\r
209\r
210 return EFI_SUCCESS;\r
211\r
212ON_ERROR:\r
213\r
214 IScsiSessionAbort (&Private->Session);\r
215 IScsiCleanDriverData (Private);\r
216\r
217 return Status;\r
218}\r
219\r
12618416 220/**\r
fd82de4e 221 Stop this driver on ControllerHandle. \r
222 \r
223 Release the control of this controller and remove the IScsi functions. The Stop()\r
224 function is designed to be invoked from the EFI boot service DisconnectController(). \r
225 As a result, much of the error checking on the parameters to Stop() has been moved \r
226 into this common boot service. It is legal to call Stop() from other locations, \r
227 but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
228 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
229 same driver's Start() function.\r
230 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
231 EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
232 Start() function, and the Start() function must have called OpenProtocol() on\r
233 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
234 \r
235 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
236 @param[in] ControllerHandle A handle to the device being stopped. The handle must \r
237 support a bus specific I/O protocol for the driver \r
238 to use to stop the device.\r
239 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.Not used.\r
240 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL \r
241 if NumberOfChildren is 0.Not used.\r
242\r
243 @retval EFI_SUCCESS The device was stopped.\r
244 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
12618416 245**/\r
6a690e23 246EFI_STATUS\r
247EFIAPI\r
248IScsiDriverBindingStop (\r
249 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
250 IN EFI_HANDLE ControllerHandle,\r
251 IN UINTN NumberOfChildren,\r
252 IN EFI_HANDLE *ChildHandleBuffer\r
253 )\r
6a690e23 254{\r
255 EFI_HANDLE IScsiController;\r
256 EFI_STATUS Status;\r
257 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
258 ISCSI_DRIVER_DATA *Private;\r
259 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
260 ISCSI_CONNECTION *Conn;\r
261\r
262 if (NumberOfChildren != 0) {\r
263 //\r
264 // We should have only one child.\r
265 //\r
266 Status = gBS->OpenProtocol (\r
267 ChildHandleBuffer[0],\r
268 &gEfiExtScsiPassThruProtocolGuid,\r
269 (VOID **) &PassThru,\r
270 This->DriverBindingHandle,\r
271 ControllerHandle,\r
272 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
273 );\r
274 if (EFI_ERROR (Status)) {\r
275 return EFI_DEVICE_ERROR;\r
276 }\r
277\r
278 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);\r
279 Conn = NET_LIST_HEAD (&Private->Session.Conns, ISCSI_CONNECTION, Link);\r
280\r
281 //\r
282 // Previously the TCP4 protocol is opened BY_CHILD_CONTROLLER. Just close\r
283 // the protocol here but not uninstall the device path protocol and\r
284 // EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.\r
285 //\r
286 gBS->CloseProtocol (\r
287 Conn->Tcp4Io.Handle,\r
288 &gEfiTcp4ProtocolGuid,\r
289 Private->Image,\r
290 Private->ExtScsiPassThruHandle\r
291 );\r
292\r
293 return EFI_SUCCESS;\r
294 }\r
295 //\r
296 // Get the handle of the controller we are controling.\r
297 //\r
298 IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
299\r
300 Status = gBS->OpenProtocol (\r
301 IScsiController,\r
302 &mIScsiPrivateGuid,\r
303 (VOID **)&IScsiIdentifier,\r
304 This->DriverBindingHandle,\r
305 ControllerHandle,\r
306 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
307 );\r
308 if (EFI_ERROR (Status)) {\r
309 return EFI_DEVICE_ERROR;\r
310 }\r
311\r
312 Private = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
313\r
314 //\r
315 // Uninstall the private protocol.\r
316 //\r
317 gBS->UninstallProtocolInterface (\r
318 IScsiController,\r
319 &mIScsiPrivateGuid,\r
320 &Private->IScsiIdentifier\r
321 );\r
322\r
323 //\r
324 // Update the iSCSI Boot Firware Table.\r
325 //\r
326 IScsiPublishIbft ();\r
327\r
328 IScsiSessionAbort (&Private->Session);\r
329 IScsiCleanDriverData (Private);\r
330\r
331 return EFI_SUCCESS;\r
332}\r
333\r
12618416 334/**\r
fd82de4e 335 Unloads an image(the iSCSI driver).\r
6a690e23 336\r
fd82de4e 337 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
6a690e23 338\r
fd82de4e 339 @retval EFI_SUCCESS The image has been unloaded.\r
963dbb30 340 @retval Others Other errors as indicated.\r
12618416 341**/\r
342EFI_STATUS\r
343EFIAPI\r
344EfiIScsiUnload (\r
345 IN EFI_HANDLE ImageHandle\r
346 )\r
6a690e23 347{\r
348 EFI_STATUS Status;\r
349 UINTN DeviceHandleCount;\r
350 EFI_HANDLE *DeviceHandleBuffer;\r
351 UINTN Index;\r
352\r
353 //\r
354 // Try to disonnect the driver from the devices it's controlling.\r
355 //\r
356 Status = gBS->LocateHandleBuffer (\r
357 AllHandles,\r
358 NULL,\r
359 NULL,\r
360 &DeviceHandleCount,\r
361 &DeviceHandleBuffer\r
362 );\r
363 if (!EFI_ERROR (Status)) {\r
364 for (Index = 0; Index < DeviceHandleCount; Index++) {\r
365 Status = gBS->DisconnectController (\r
366 DeviceHandleBuffer[Index],\r
367 ImageHandle,\r
368 NULL\r
369 );\r
370 }\r
371\r
372 if (DeviceHandleBuffer != NULL) {\r
e48e37fc 373 gBS->FreePool (DeviceHandleBuffer);\r
6a690e23 374 }\r
375 }\r
376 //\r
377 // Unload the iSCSI configuration form.\r
378 //\r
379 IScsiConfigFormUnload (gIScsiDriverBinding.DriverBindingHandle);\r
380\r
381 //\r
382 // Uninstall the protocols installed by iSCSI driver.\r
383 //\r
384 Status = gBS->UninstallMultipleProtocolInterfaces (\r
385 ImageHandle,\r
386 &gEfiDriverBindingProtocolGuid,\r
387 &gIScsiDriverBinding,\r
388 &gEfiComponentName2ProtocolGuid,\r
389 &gIScsiComponentName2,\r
390 &gEfiComponentNameProtocolGuid,\r
391 &gIScsiComponentName,\r
392 &gEfiIScsiInitiatorNameProtocolGuid,\r
393 &gIScsiInitiatorName,\r
394 NULL\r
395 );\r
396\r
397 return Status;\r
398}\r
399\r
12618416 400/**\r
fd82de4e 401 This is the declaration of an EFI image entry point. This entry point is\r
402 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
403 both device drivers and bus drivers. It initialize the global variables and \r
404 publish the driver binding protocol.\r
6a690e23 405\r
fd82de4e 406 @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
407 @param[in] SystemTable A pointer to the EFI System Table.\r
6a690e23 408\r
fd82de4e 409 @retval EFI_SUCCESS The operation completed successfully.\r
410 @retval EFI_ACCESS_DENIED EFI_ISCSI_INITIATOR_NAME_PROTOCOL was installed unexpectedly.\r
963dbb30 411 @retval Others Other errors as indicated.\r
12618416 412**/\r
413EFI_STATUS\r
414EFIAPI\r
415IScsiDriverEntryPoint (\r
416 IN EFI_HANDLE ImageHandle,\r
417 IN EFI_SYSTEM_TABLE *SystemTable\r
418 )\r
6a690e23 419{\r
f2a94e25 420 EFI_STATUS Status;\r
421 EFI_ISCSI_INITIATOR_NAME_PROTOCOL *IScsiInitiatorName;\r
422\r
423 //\r
424 // There should be only one EFI_ISCSI_INITIATOR_NAME_PROTOCOL.\r
425 //\r
426 Status = gBS->LocateProtocol (\r
427 &gEfiIScsiInitiatorNameProtocolGuid,\r
428 NULL,\r
b4df5011 429 (VOID**) &IScsiInitiatorName\r
f2a94e25 430 );\r
431\r
432 if (!EFI_ERROR (Status)) {\r
433 return EFI_ACCESS_DENIED;\r
434 }\r
6a690e23 435\r
436 //\r
437 // Initialize the EFI Driver Library\r
438 //\r
439 Status = EfiLibInstallDriverBindingComponentName2 (\r
440 ImageHandle,\r
441 SystemTable,\r
442 &gIScsiDriverBinding,\r
443 ImageHandle,\r
444 &gIScsiComponentName,\r
445 &gIScsiComponentName2\r
446 );\r
6a690e23 447\r
448 if (!EFI_ERROR (Status)) {\r
f2a94e25 449 //\r
450 // Install the iSCSI Initiator Name Protocol.\r
451 //\r
6a690e23 452 Status = gBS->InstallProtocolInterface (\r
453 &ImageHandle,\r
454 &gEfiIScsiInitiatorNameProtocolGuid,\r
455 EFI_NATIVE_INTERFACE,\r
456 &gIScsiInitiatorName\r
457 );\r
458 if (EFI_ERROR (Status)) {\r
459 gBS->UninstallMultipleProtocolInterfaces (\r
460 ImageHandle,\r
461 &gEfiDriverBindingProtocolGuid,\r
462 &gIScsiDriverBinding,\r
463 &gEfiComponentName2ProtocolGuid,\r
464 &gIScsiComponentName2,\r
465 &gEfiComponentNameProtocolGuid,\r
466 &gIScsiComponentName,\r
467 NULL\r
468 );\r
f2a94e25 469 return Status;\r
470 }\r
471 \r
472 //\r
473 // Initialize the configuration form of iSCSI.\r
474 //\r
963dbb30 475 Status = IScsiConfigFormInit ();\r
f2a94e25 476 if (EFI_ERROR (Status)) {\r
477 gBS->UninstallMultipleProtocolInterfaces (\r
478 ImageHandle,\r
479 &gEfiDriverBindingProtocolGuid,\r
480 &gIScsiDriverBinding,\r
481 &gEfiComponentName2ProtocolGuid,\r
482 &gIScsiComponentName2,\r
483 &gEfiComponentNameProtocolGuid,\r
484 &gIScsiComponentName,\r
485 &gEfiIScsiInitiatorNameProtocolGuid,\r
486 &gIScsiInitiatorName,\r
487 NULL\r
488 );\r
6a690e23 489 }\r
490 }\r
6a690e23 491 return Status;\r
492}\r
493\r