]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
Use Mde library and definition instead of some native definitions in NetLib, to simpl...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiDriver.c
CommitLineData
6a690e23 1/*++\r
2\r
7a444476 3Copyright (c) 2004 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 11\r
12Module Name:\r
13\r
14 IScsiDriver.c\r
15\r
16Abstract:\r
17\r
18--*/\r
19\r
20#include "IScsiImpl.h"\r
21\r
22EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {\r
23 IScsiDriverBindingSupported,\r
24 IScsiDriverBindingStart,\r
25 IScsiDriverBindingStop,\r
26 0xa,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
31EFI_GUID mIScsiPrivateGuid = ISCSI_PRIVATE_GUID;\r
32\r
33EFI_STATUS\r
34EFIAPI\r
35IScsiDriverBindingSupported (\r
36 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
37 IN EFI_HANDLE ControllerHandle,\r
38 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
39 )\r
40/*++\r
41\r
42Routine Description:\r
43\r
44 Test to see if iSCSI driver supports the given controller. \r
45\r
46Arguments:\r
47\r
48 This - Protocol instance pointer.\r
49 ControllerHandle - Handle of controller to test.\r
50 RemainingDevicePath - Optional parameter use to pick a specific child device to start.\r
51\r
52Returns:\r
53\r
54 EFI_SUCCES - This driver supports the controller.\r
55 EFI_ALREADY_STARTED - This driver is already running on this device.\r
56 EFI_UNSUPPORTED - This driver doesn't support the controller.\r
57\r
58--*/\r
59{\r
60 EFI_STATUS Status;\r
61 EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
62\r
63 Status = gBS->OpenProtocol (\r
64 ControllerHandle,\r
65 &mIScsiPrivateGuid,\r
66 NULL,\r
67 This->DriverBindingHandle,\r
68 ControllerHandle,\r
69 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
70 );\r
71 if (!EFI_ERROR (Status)) {\r
72 return EFI_ALREADY_STARTED;\r
73 }\r
74\r
75 Status = gBS->OpenProtocol (\r
76 ControllerHandle,\r
77 &gEfiTcp4ServiceBindingProtocolGuid,\r
78 NULL,\r
79 This->DriverBindingHandle,\r
80 ControllerHandle,\r
81 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
82 );\r
83 if (EFI_ERROR (Status)) {\r
84 return EFI_UNSUPPORTED;\r
85 }\r
86\r
87 CurrentDevicePath = RemainingDevicePath;\r
88 if (CurrentDevicePath != NULL) {\r
89 while (!IsDevicePathEnd (CurrentDevicePath)) {\r
90 if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {\r
91 return EFI_SUCCESS;\r
92 }\r
93\r
94 CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);\r
95 }\r
96\r
97 return EFI_UNSUPPORTED;\r
98 }\r
99\r
100 return EFI_SUCCESS;\r
101}\r
102\r
103EFI_STATUS\r
104EFIAPI\r
105IScsiDriverBindingStart (\r
106 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
107 IN EFI_HANDLE ControllerHandle,\r
108 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
109 )\r
110/*++\r
111\r
112Routine Description:\r
113\r
114 Start to manage the controller. \r
115\r
116Arguments:\r
117\r
118 This - Protocol instance pointer.\r
119 ControllerHandle - Handle of the controller.\r
120 RemainingDevicePath - Optional parameter use to pick a specific child device to start.\r
121\r
122Returns:\r
123\r
124 EFI_SUCCES - This driver supports this device.\r
125 EFI_ALREADY_STARTED - This driver is already running on this device.\r
126\r
127--*/\r
128{\r
129 EFI_STATUS Status;\r
130 ISCSI_DRIVER_DATA *Private;\r
131\r
132 //\r
133 // Try to add a port configuration page for this controller.\r
134 //\r
135 IScsiConfigUpdateForm (This->DriverBindingHandle, ControllerHandle, TRUE);\r
136\r
137 Private = IScsiCreateDriverData (This->DriverBindingHandle, ControllerHandle);\r
138 if (Private == NULL) {\r
139 return EFI_OUT_OF_RESOURCES;\r
140 }\r
141 //\r
142 // Get the iSCSI configuration data of this controller.\r
143 //\r
144 Status = IScsiGetConfigData (Private);\r
145 if (EFI_ERROR (Status)) {\r
146 goto ON_ERROR;\r
147 }\r
148 //\r
149 // Try to login and create an iSCSI session according to the configuration.\r
150 //\r
151 Status = IScsiSessionLogin (Private);\r
152 if (Status == EFI_MEDIA_CHANGED) {\r
153 //\r
154 // The specified target is not available and the redirection information is\r
155 // got, login the session again with the updated target address.\r
156 //\r
157 Status = IScsiSessionLogin (Private);\r
158 }\r
159\r
160 if (EFI_ERROR (Status)) {\r
161 goto ON_ERROR;\r
162 }\r
163 //\r
164 // Duplicate the Session's tcp connection device path. The source port field\r
165 // will be set to zero as one iSCSI session is comprised of several iSCSI\r
166 // connections.\r
167 //\r
168 Private->DevicePath = IScsiGetTcpConnDevicePath (Private);\r
169 if (Private->DevicePath == NULL) {\r
170 goto ON_ERROR;\r
171 }\r
172 //\r
173 // Install the updated device path onto the ExtScsiPassThruHandle.\r
174 //\r
175 Status = gBS->InstallProtocolInterface (\r
176 &Private->ExtScsiPassThruHandle,\r
177 &gEfiDevicePathProtocolGuid,\r
178 EFI_NATIVE_INTERFACE,\r
179 Private->DevicePath\r
180 );\r
181 if (EFI_ERROR (Status)) {\r
182 goto ON_ERROR;\r
183 }\r
184 //\r
185 // Install the iSCSI private stuff as a flag to indicate this controller\r
186 // is already controlled by iSCSI driver.\r
187 //\r
188 Status = gBS->InstallProtocolInterface (\r
189 &ControllerHandle,\r
190 &mIScsiPrivateGuid,\r
191 EFI_NATIVE_INTERFACE,\r
192 &Private->IScsiIdentifier\r
193 );\r
194 if (EFI_ERROR (Status)) {\r
195 goto ON_ERROR;\r
196 }\r
197 //\r
198 // Update/Publish the iSCSI Boot Firmware Table.\r
199 //\r
200 IScsiPublishIbft ();\r
201\r
202 return EFI_SUCCESS;\r
203\r
204ON_ERROR:\r
205\r
206 IScsiSessionAbort (&Private->Session);\r
207 IScsiCleanDriverData (Private);\r
208\r
209 return Status;\r
210}\r
211\r
212EFI_STATUS\r
213EFIAPI\r
214IScsiDriverBindingStop (\r
215 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
216 IN EFI_HANDLE ControllerHandle,\r
217 IN UINTN NumberOfChildren,\r
218 IN EFI_HANDLE *ChildHandleBuffer\r
219 )\r
220/*++\r
221\r
222Routine Description:\r
223\r
224 Release the control of this controller and remove the iSCSI functions.\r
225\r
226Arguments:\r
227\r
228 This - Protocol instance pointer.\r
229 ControllerHandle - Handle of controller to stop.\r
230 NumberOfChildren - Not used.\r
231 ChildHandleBuffer - Not used.\r
232\r
233Returns:\r
234\r
235 EFI_SUCCES - This driver supports this device.\r
236\r
237--*/\r
238{\r
239 EFI_HANDLE IScsiController;\r
240 EFI_STATUS Status;\r
241 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
242 ISCSI_DRIVER_DATA *Private;\r
243 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
244 ISCSI_CONNECTION *Conn;\r
245\r
246 if (NumberOfChildren != 0) {\r
247 //\r
248 // We should have only one child.\r
249 //\r
250 Status = gBS->OpenProtocol (\r
251 ChildHandleBuffer[0],\r
252 &gEfiExtScsiPassThruProtocolGuid,\r
253 (VOID **) &PassThru,\r
254 This->DriverBindingHandle,\r
255 ControllerHandle,\r
256 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
257 );\r
258 if (EFI_ERROR (Status)) {\r
259 return EFI_DEVICE_ERROR;\r
260 }\r
261\r
262 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);\r
263 Conn = NET_LIST_HEAD (&Private->Session.Conns, ISCSI_CONNECTION, Link);\r
264\r
265 //\r
266 // Previously the TCP4 protocol is opened BY_CHILD_CONTROLLER. Just close\r
267 // the protocol here but not uninstall the device path protocol and\r
268 // EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.\r
269 //\r
270 gBS->CloseProtocol (\r
271 Conn->Tcp4Io.Handle,\r
272 &gEfiTcp4ProtocolGuid,\r
273 Private->Image,\r
274 Private->ExtScsiPassThruHandle\r
275 );\r
276\r
277 return EFI_SUCCESS;\r
278 }\r
279 //\r
280 // Get the handle of the controller we are controling.\r
281 //\r
282 IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
283\r
284 Status = gBS->OpenProtocol (\r
285 IScsiController,\r
286 &mIScsiPrivateGuid,\r
287 (VOID **)&IScsiIdentifier,\r
288 This->DriverBindingHandle,\r
289 ControllerHandle,\r
290 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
291 );\r
292 if (EFI_ERROR (Status)) {\r
293 return EFI_DEVICE_ERROR;\r
294 }\r
295\r
296 Private = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
297\r
298 //\r
299 // Uninstall the private protocol.\r
300 //\r
301 gBS->UninstallProtocolInterface (\r
302 IScsiController,\r
303 &mIScsiPrivateGuid,\r
304 &Private->IScsiIdentifier\r
305 );\r
306\r
307 //\r
308 // Update the iSCSI Boot Firware Table.\r
309 //\r
310 IScsiPublishIbft ();\r
311\r
312 IScsiSessionAbort (&Private->Session);\r
313 IScsiCleanDriverData (Private);\r
314\r
315 return EFI_SUCCESS;\r
316}\r
317\r
318EFI_STATUS\r
319EFIAPI\r
320EfiIScsiUnload (\r
321 IN EFI_HANDLE ImageHandle\r
322 )\r
323/*++\r
324\r
325Routine Description:\r
326\r
327 Unload the iSCSI driver.\r
328\r
329Arguments:\r
330\r
331 ImageHandle - The handle of the driver image.\r
332\r
333Returns:\r
334\r
335 EFI_SUCCESS - The driver is unloaded.\r
336 EFI_DEVICE_ERROR - Some unexpected error happened.\r
337\r
338--*/\r
339{\r
340 EFI_STATUS Status;\r
341 UINTN DeviceHandleCount;\r
342 EFI_HANDLE *DeviceHandleBuffer;\r
343 UINTN Index;\r
344\r
345 //\r
346 // Try to disonnect the driver from the devices it's controlling.\r
347 //\r
348 Status = gBS->LocateHandleBuffer (\r
349 AllHandles,\r
350 NULL,\r
351 NULL,\r
352 &DeviceHandleCount,\r
353 &DeviceHandleBuffer\r
354 );\r
355 if (!EFI_ERROR (Status)) {\r
356 for (Index = 0; Index < DeviceHandleCount; Index++) {\r
357 Status = gBS->DisconnectController (\r
358 DeviceHandleBuffer[Index],\r
359 ImageHandle,\r
360 NULL\r
361 );\r
362 }\r
363\r
364 if (DeviceHandleBuffer != NULL) {\r
e48e37fc 365 gBS->FreePool (DeviceHandleBuffer);\r
6a690e23 366 }\r
367 }\r
368 //\r
369 // Unload the iSCSI configuration form.\r
370 //\r
371 IScsiConfigFormUnload (gIScsiDriverBinding.DriverBindingHandle);\r
372\r
373 //\r
374 // Uninstall the protocols installed by iSCSI driver.\r
375 //\r
376 Status = gBS->UninstallMultipleProtocolInterfaces (\r
377 ImageHandle,\r
378 &gEfiDriverBindingProtocolGuid,\r
379 &gIScsiDriverBinding,\r
380 &gEfiComponentName2ProtocolGuid,\r
381 &gIScsiComponentName2,\r
382 &gEfiComponentNameProtocolGuid,\r
383 &gIScsiComponentName,\r
384 &gEfiIScsiInitiatorNameProtocolGuid,\r
385 &gIScsiInitiatorName,\r
386 NULL\r
387 );\r
388\r
389 return Status;\r
390}\r
391\r
392EFI_STATUS\r
393EFIAPI\r
394IScsiDriverEntryPoint (\r
395 IN EFI_HANDLE ImageHandle,\r
396 IN EFI_SYSTEM_TABLE *SystemTable\r
397 )\r
398/*++\r
399\r
400Routine Description:\r
401\r
402 Initialize the global variables publish the driver binding protocol.\r
403\r
404Arguments:\r
405\r
406 ImageHandle - The handle of the driver image.\r
407 SystemTable - The EFI system table.\r
408\r
409Returns:\r
410\r
411 EFI_SUCCESS - The protocols are installed.\r
412 EFI_DEVICE_ERROR - Some unexpected error happened.\r
413\r
414--*/\r
415{\r
416 EFI_STATUS Status;\r
417 //EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
418\r
419 //\r
420 // Initialize the EFI Driver Library\r
421 //\r
422 Status = EfiLibInstallDriverBindingComponentName2 (\r
423 ImageHandle,\r
424 SystemTable,\r
425 &gIScsiDriverBinding,\r
426 ImageHandle,\r
427 &gIScsiComponentName,\r
428 &gIScsiComponentName2\r
429 );\r
430 \r
431 if (EFI_ERROR (Status)) {\r
432 return Status;\r
433 }\r
434\r
435 if (!EFI_ERROR (Status)) {\r
436 Status = gBS->InstallProtocolInterface (\r
437 &ImageHandle,\r
438 &gEfiIScsiInitiatorNameProtocolGuid,\r
439 EFI_NATIVE_INTERFACE,\r
440 &gIScsiInitiatorName\r
441 );\r
442 if (EFI_ERROR (Status)) {\r
443 gBS->UninstallMultipleProtocolInterfaces (\r
444 ImageHandle,\r
445 &gEfiDriverBindingProtocolGuid,\r
446 &gIScsiDriverBinding,\r
447 &gEfiComponentName2ProtocolGuid,\r
448 &gIScsiComponentName2,\r
449 &gEfiComponentNameProtocolGuid,\r
450 &gIScsiComponentName,\r
451 NULL\r
452 );\r
453 }\r
454 }\r
455 //\r
456 // Initialize the configuration form of iSCSI.\r
457 //\r
458 IScsiConfigFormInit (gIScsiDriverBinding.DriverBindingHandle);\r
459\r
460 return Status;\r
461}\r
462\r