[efi] Do not raise TPL within EFI_DRIVER_BINDING_PROTOCOL.Supported()
[ipxe.git] / src / interface / efi / efi_driver.c
1 /*
2 * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stddef.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <ipxe/version.h>
28 #include <ipxe/efi/efi.h>
29 #include <ipxe/efi/Protocol/DriverBinding.h>
30 #include <ipxe/efi/Protocol/ComponentName2.h>
31 #include <ipxe/efi/Protocol/DevicePath.h>
32 #include <ipxe/efi/efi_strings.h>
33 #include <ipxe/efi/efi_utils.h>
34 #include <ipxe/efi/efi_driver.h>
35
36 /** @file
37 *
38 * EFI driver interface
39 *
40 */
41
42 static EFI_DRIVER_BINDING_PROTOCOL efi_driver_binding;
43
44 /** List of controlled EFI devices */
45 static LIST_HEAD ( efi_devices );
46
47 /** We are currently disconnecting drivers */
48 static int efi_driver_disconnecting;
49
50 /**
51 * Find EFI device
52 *
53 * @v device EFI device handle
54 * @ret efidev EFI device, or NULL if not found
55 */
56 static struct efi_device * efidev_find ( EFI_HANDLE device ) {
57 struct efi_device *efidev;
58
59 /* Look for an existing EFI device */
60 list_for_each_entry ( efidev, &efi_devices, dev.siblings ) {
61 if ( efidev->device == device )
62 return efidev;
63 }
64
65 return NULL;
66 }
67
68 /**
69 * Get parent EFI device
70 *
71 * @v dev Generic device
72 * @ret efidev Parent EFI device, or NULL
73 */
74 struct efi_device * efidev_parent ( struct device *dev ) {
75 struct device *parent;
76
77 /* Walk upwards until we find an EFI device */
78 while ( ( parent = dev->parent ) ) {
79 if ( parent->desc.bus_type == BUS_TYPE_EFI )
80 return container_of ( parent, struct efi_device, dev );
81 dev = parent;
82 }
83
84 return NULL;
85 }
86
87 /**
88 * Check to see if driver supports a device
89 *
90 * @v driver EFI driver
91 * @v device EFI device
92 * @v child Path to child device, if any
93 * @ret efirc EFI status code
94 */
95 static EFI_STATUS EFIAPI
96 efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
97 EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
98 struct efi_driver *efidrv;
99 int rc;
100
101 DBGCP ( device, "EFIDRV %s DRIVER_SUPPORTED",
102 efi_handle_name ( device ) );
103 if ( child )
104 DBGCP ( device, " (child %s)", efi_devpath_text ( child ) );
105 DBGCP ( device, "\n" );
106
107 /* Do nothing if we are already driving this device */
108 if ( efidev_find ( device ) != NULL ) {
109 DBGCP ( device, "EFIDRV %s is already started\n",
110 efi_handle_name ( device ) );
111 return EFI_ALREADY_STARTED;
112 }
113
114 /* Look for a driver claiming to support this device */
115 for_each_table_entry ( efidrv, EFI_DRIVERS ) {
116 if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
117 DBGC ( device, "EFIDRV %s has driver \"%s\"\n",
118 efi_handle_name ( device ), efidrv->name );
119 return 0;
120 }
121 }
122 DBGCP ( device, "EFIDRV %s has no driver\n",
123 efi_handle_name ( device ) );
124
125 return EFI_UNSUPPORTED;
126 }
127
128 /**
129 * Attach driver to device
130 *
131 * @v driver EFI driver
132 * @v device EFI device
133 * @v child Path to child device, if any
134 * @ret efirc EFI status code
135 */
136 static EFI_STATUS EFIAPI
137 efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
138 EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
139 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
140 struct efi_driver *efidrv;
141 struct efi_device *efidev;
142 union {
143 EFI_DEVICE_PATH_PROTOCOL *path;
144 void *interface;
145 } path;
146 EFI_DEVICE_PATH_PROTOCOL *path_end;
147 size_t path_len;
148 EFI_TPL saved_tpl;
149 EFI_STATUS efirc;
150 int rc;
151
152 DBGC ( device, "EFIDRV %s DRIVER_START", efi_handle_name ( device ) );
153 if ( child )
154 DBGC ( device, " (child %s)", efi_devpath_text ( child ) );
155 DBGC ( device, "\n" );
156
157 /* Do nothing if we are already driving this device */
158 efidev = efidev_find ( device );
159 if ( efidev ) {
160 DBGCP ( device, "EFIDRV %s is already started\n",
161 efi_handle_name ( device ) );
162 efirc = EFI_ALREADY_STARTED;
163 goto err_already_started;
164 }
165
166 /* Raise TPL */
167 saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
168
169 /* Do nothing if we are currently disconnecting drivers */
170 if ( efi_driver_disconnecting ) {
171 DBGC ( device, "EFIDRV %s refusing to start during "
172 "disconnection\n", efi_handle_name ( device ) );
173 efirc = EFI_NOT_READY;
174 goto err_disconnecting;
175 }
176
177 /* Open device path */
178 if ( ( efirc = bs->OpenProtocol ( device,
179 &efi_device_path_protocol_guid,
180 &path.interface, efi_image_handle,
181 device,
182 EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
183 rc = -EEFI ( efirc );
184 DBGC ( device, "EFIDRV %s could not open device path: %s\n",
185 efi_handle_name ( device ), strerror ( rc ) );
186 goto err_open_path;
187 }
188 path_len = ( efi_devpath_len ( path.path ) + sizeof ( *path_end ) );
189
190 /* Allocate and initialise structure */
191 efidev = zalloc ( sizeof ( *efidev ) + path_len );
192 if ( ! efidev ) {
193 efirc = EFI_OUT_OF_RESOURCES;
194 goto err_alloc;
195 }
196 efidev->device = device;
197 efidev->dev.desc.bus_type = BUS_TYPE_EFI;
198 efidev->path = ( ( ( void * ) efidev ) + sizeof ( *efidev ) );
199 memcpy ( efidev->path, path.path, path_len );
200 INIT_LIST_HEAD ( &efidev->dev.children );
201 list_add ( &efidev->dev.siblings, &efi_devices );
202
203 /* Close device path */
204 bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
205 efi_image_handle, device );
206 path.path = NULL;
207
208 /* Try to start this device */
209 for_each_table_entry ( efidrv, EFI_DRIVERS ) {
210 if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
211 DBGC ( device, "EFIDRV %s is not supported by driver "
212 "\"%s\": %s\n", efi_handle_name ( device ),
213 efidrv->name,
214 strerror ( rc ) );
215 continue;
216 }
217 if ( ( rc = efidrv->start ( efidev ) ) == 0 ) {
218 efidev->driver = efidrv;
219 DBGC ( device, "EFIDRV %s using driver \"%s\"\n",
220 efi_handle_name ( device ),
221 efidev->driver->name );
222 bs->RestoreTPL ( saved_tpl );
223 return 0;
224 }
225 DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
226 efi_handle_name ( device ), efidrv->name,
227 strerror ( rc ) );
228 }
229 efirc = EFI_UNSUPPORTED;
230
231 list_del ( &efidev->dev.siblings );
232 free ( efidev );
233 err_alloc:
234 if ( path.path ) {
235 bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
236 efi_image_handle, device );
237 }
238 err_open_path:
239 err_disconnecting:
240 bs->RestoreTPL ( saved_tpl );
241 err_already_started:
242 return efirc;
243 }
244
245 /**
246 * Detach driver from device
247 *
248 * @v driver EFI driver
249 * @v device EFI device
250 * @v pci PCI device
251 * @v num_children Number of child devices
252 * @v children List of child devices
253 * @ret efirc EFI status code
254 */
255 static EFI_STATUS EFIAPI
256 efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
257 EFI_HANDLE device, UINTN num_children,
258 EFI_HANDLE *children ) {
259 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
260 struct efi_driver *efidrv;
261 struct efi_device *efidev;
262 EFI_TPL saved_tpl;
263 UINTN i;
264
265 DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
266 for ( i = 0 ; i < num_children ; i++ ) {
267 DBGC ( device, "%s%s", ( i ? ", " : " child " ),
268 efi_handle_name ( children[i] ) );
269 }
270 DBGC ( device, "\n" );
271
272 /* Do nothing unless we are driving this device */
273 efidev = efidev_find ( device );
274 if ( ! efidev ) {
275 DBGCP ( device, "EFIDRV %s is not started\n",
276 efi_handle_name ( device ) );
277 return EFI_DEVICE_ERROR;
278 }
279
280 /* Raise TPL */
281 saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
282
283 /* Stop this device */
284 efidrv = efidev->driver;
285 assert ( efidrv != NULL );
286 efidrv->stop ( efidev );
287 list_del ( &efidev->dev.siblings );
288 free ( efidev );
289
290 bs->RestoreTPL ( saved_tpl );
291 return 0;
292 }
293
294 /** EFI driver binding protocol */
295 static EFI_DRIVER_BINDING_PROTOCOL efi_driver_binding = {
296 .Supported = efi_driver_supported,
297 .Start = efi_driver_start,
298 .Stop = efi_driver_stop,
299 };
300
301 /**
302 * Look up driver name
303 *
304 * @v wtf Component name protocol
305 * @v language Language to use
306 * @v driver_name Driver name to fill in
307 * @ret efirc EFI status code
308 */
309 static EFI_STATUS EFIAPI
310 efi_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
311 CHAR8 *language __unused, CHAR16 **driver_name ) {
312 const wchar_t *name;
313
314 name = ( product_wname[0] ? product_wname : build_wname );
315 *driver_name = ( ( wchar_t * ) name );
316 return 0;
317 }
318
319 /**
320 * Look up controller name
321 *
322 * @v wtf Component name protocol
323 * @v device Device
324 * @v child Child device, or NULL
325 * @v language Language to use
326 * @v driver_name Device name to fill in
327 * @ret efirc EFI status code
328 */
329 static EFI_STATUS EFIAPI
330 efi_driver_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
331 EFI_HANDLE device, EFI_HANDLE child,
332 CHAR8 *language, CHAR16 **controller_name ) {
333 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
334 union {
335 EFI_COMPONENT_NAME2_PROTOCOL *name2;
336 void *interface;
337 } name2;
338 EFI_STATUS efirc;
339
340 /* Delegate to the EFI_COMPONENT_NAME2_PROTOCOL instance
341 * installed on child handle, if present.
342 */
343 if ( ( child != NULL ) &&
344 ( ( efirc = bs->OpenProtocol (
345 child, &efi_component_name2_protocol_guid,
346 &name2.interface, NULL, NULL,
347 EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) == 0 ) ) {
348 return name2.name2->GetControllerName ( name2.name2, device,
349 child, language,
350 controller_name );
351 }
352
353 /* Otherwise, let EFI use the default Device Path Name */
354 return EFI_UNSUPPORTED;
355 }
356
357 /** EFI component name protocol */
358 static EFI_COMPONENT_NAME2_PROTOCOL efi_wtf = {
359 .GetDriverName = efi_driver_name,
360 .GetControllerName = efi_driver_controller_name,
361 .SupportedLanguages = "en",
362 };
363
364 /**
365 * Install EFI driver
366 *
367 * @ret rc Return status code
368 */
369 int efi_driver_install ( void ) {
370 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
371 EFI_STATUS efirc;
372 int rc;
373
374 /* Calculate driver version number. We use the build
375 * timestamp (in seconds since the Epoch) shifted right by six
376 * bits: this gives us an approximately one-minute resolution
377 * and a scheme which will last until the year 10680.
378 */
379 efi_driver_binding.Version = ( build_timestamp >> 6 );
380
381 /* Install protocols on image handle */
382 efi_driver_binding.ImageHandle = efi_image_handle;
383 efi_driver_binding.DriverBindingHandle = efi_image_handle;
384 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
385 &efi_image_handle,
386 &efi_driver_binding_protocol_guid, &efi_driver_binding,
387 &efi_component_name2_protocol_guid, &efi_wtf,
388 NULL ) ) != 0 ) {
389 rc = -EEFI ( efirc );
390 DBGC ( &efi_driver_binding, "EFIDRV could not install "
391 "protocols: %s\n", strerror ( rc ) );
392 return rc;
393 }
394
395 return 0;
396 }
397
398 /**
399 * Uninstall EFI driver
400 *
401 */
402 void efi_driver_uninstall ( void ) {
403 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
404
405 /* Uninstall protocols */
406 bs->UninstallMultipleProtocolInterfaces (
407 efi_image_handle,
408 &efi_driver_binding_protocol_guid, &efi_driver_binding,
409 &efi_component_name2_protocol_guid, &efi_wtf, NULL );
410 }
411
412 /**
413 * Try to connect EFI driver
414 *
415 * @v device EFI device
416 * @ret rc Return status code
417 */
418 static int efi_driver_connect ( EFI_HANDLE device ) {
419 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
420 EFI_HANDLE drivers[2] =
421 { efi_driver_binding.DriverBindingHandle, NULL };
422 EFI_STATUS efirc;
423 int rc;
424
425 /* Check if we want to drive this device */
426 if ( ( efirc = efi_driver_supported ( &efi_driver_binding, device,
427 NULL ) ) != 0 ) {
428 /* Not supported; not an error */
429 return 0;
430 }
431
432 /* Disconnect any existing drivers */
433 DBGC2 ( device, "EFIDRV %s before disconnecting:\n",
434 efi_handle_name ( device ) );
435 DBGC2_EFI_PROTOCOLS ( device, device );
436 DBGC ( device, "EFIDRV %s disconnecting existing drivers\n",
437 efi_handle_name ( device ) );
438 efi_driver_disconnecting = 1;
439 if ( ( efirc = bs->DisconnectController ( device, NULL,
440 NULL ) ) != 0 ) {
441 rc = -EEFI ( efirc );
442 DBGC ( device, "EFIDRV %s could not disconnect existing "
443 "drivers: %s\n", efi_handle_name ( device ),
444 strerror ( rc ) );
445 /* Ignore the error and attempt to connect our drivers */
446 }
447 efi_driver_disconnecting = 0;
448 DBGC2 ( device, "EFIDRV %s after disconnecting:\n",
449 efi_handle_name ( device ) );
450 DBGC2_EFI_PROTOCOLS ( device, device );
451
452 /* Connect our driver */
453 DBGC ( device, "EFIDRV %s connecting new drivers\n",
454 efi_handle_name ( device ) );
455 if ( ( efirc = bs->ConnectController ( device, drivers, NULL,
456 FALSE ) ) != 0 ) {
457 rc = -EEFI ( efirc );
458 DBGC ( device, "EFIDRV %s could not connect new drivers: "
459 "%s\n", efi_handle_name ( device ), strerror ( rc ) );
460 return rc;
461 }
462 DBGC2 ( device, "EFIDRV %s after connecting:\n",
463 efi_handle_name ( device ) );
464 DBGC2_EFI_PROTOCOLS ( device, device );
465
466 return 0;
467 }
468
469 /**
470 * Try to disconnect EFI driver
471 *
472 * @v device EFI device
473 * @ret rc Return status code
474 */
475 static int efi_driver_disconnect ( EFI_HANDLE device ) {
476 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
477
478 /* Disconnect our driver */
479 efi_driver_disconnecting = 1;
480 bs->DisconnectController ( device,
481 efi_driver_binding.DriverBindingHandle,
482 NULL );
483 efi_driver_disconnecting = 0;
484 return 0;
485 }
486
487 /**
488 * Reconnect original EFI driver
489 *
490 * @v device EFI device
491 * @ret rc Return status code
492 */
493 static int efi_driver_reconnect ( EFI_HANDLE device ) {
494 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
495
496 /* Reconnect any available driver */
497 bs->ConnectController ( device, NULL, NULL, FALSE );
498
499 return 0;
500 }
501
502 /**
503 * Connect/disconnect EFI driver from all handles
504 *
505 * @v method Connect/disconnect method
506 * @ret rc Return status code
507 */
508 static int efi_driver_handles ( int ( * method ) ( EFI_HANDLE handle ) ) {
509 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
510 EFI_HANDLE *handles;
511 UINTN num_handles;
512 EFI_STATUS efirc;
513 UINTN i;
514 int rc;
515
516 /* Enumerate all handles */
517 if ( ( efirc = bs->LocateHandleBuffer ( AllHandles, NULL, NULL,
518 &num_handles,
519 &handles ) ) != 0 ) {
520 rc = -EEFI ( efirc );
521 DBGC ( &efi_driver_binding, "EFIDRV could not list handles: "
522 "%s\n", strerror ( rc ) );
523 goto err_locate;
524 }
525
526 /* Connect/disconnect driver from all handles */
527 for ( i = 0 ; i < num_handles ; i++ ) {
528 if ( ( rc = method ( handles[i] ) ) != 0 ) {
529 /* Ignore errors and continue to process
530 * remaining handles.
531 */
532 }
533 }
534
535 /* Success */
536 rc = 0;
537
538 bs->FreePool ( handles );
539 err_locate:
540 return rc;
541 }
542
543 /**
544 * Connect EFI driver to all possible devices
545 *
546 * @ret rc Return status code
547 */
548 int efi_driver_connect_all ( void ) {
549
550 DBGC ( &efi_driver_binding, "EFIDRV connecting our drivers\n" );
551 return efi_driver_handles ( efi_driver_connect );
552 }
553
554 /**
555 * Disconnect EFI driver from all possible devices
556 *
557 * @ret rc Return status code
558 */
559 void efi_driver_disconnect_all ( void ) {
560
561 DBGC ( &efi_driver_binding, "EFIDRV disconnecting our drivers\n" );
562 efi_driver_handles ( efi_driver_disconnect );
563 }
564
565 /**
566 * Reconnect original EFI drivers to all possible devices
567 *
568 * @ret rc Return status code
569 */
570 void efi_driver_reconnect_all ( void ) {
571
572 DBGC ( &efi_driver_binding, "EFIDRV reconnecting old drivers\n" );
573 efi_driver_handles ( efi_driver_reconnect );
574 }