david/ipxe
Archived
1
0

[efi] Connect driver to devices as part of installation

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2014-03-11 15:34:47 +00:00
parent 8de6b973c4
commit 2602965806

View File

@ -118,6 +118,70 @@ efi_driver_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
return EFI_UNSUPPORTED;
}
/**
* Try to connect EFI driver
*
* @v efidrv EFI driver
* @v handle Controller handle
*/
static void efi_driver_connect ( struct efi_driver *efidrv, EFI_HANDLE handle ){
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_HANDLE drivers[2] = { efidrv->driver.DriverBindingHandle, NULL };
bs->ConnectController ( handle, drivers, NULL, FALSE );
}
/**
* Try to disconnect EFI driver
*
* @v efidrv EFI driver
* @v handle Controller handle
*/
static void efi_driver_disconnect ( struct efi_driver *efidrv,
EFI_HANDLE handle ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
bs->DisconnectController ( handle, efidrv->driver.DriverBindingHandle,
NULL );
}
/**
* Connect/disconnect EFI driver from all handles
*
* @v efidrv EFI driver
* @v method Connect/disconnect method
* @ret rc Return status code
*/
static int efi_driver_handles ( struct efi_driver *efidrv,
void ( * method ) ( struct efi_driver *efidrv,
EFI_HANDLE handle ) ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_HANDLE *handles;
UINTN num_handles;
EFI_STATUS efirc;
UINTN i;
int rc;
/* Enumerate all handles */
if ( ( efirc = bs->LocateHandleBuffer ( AllHandles, NULL, NULL,
&num_handles,
&handles ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( efidrv, "EFIDRV %s could not list handles: %s\n",
efidrv->name, strerror ( rc ) );
return rc;
}
/* Connect/disconnect driver from all handles */
for ( i = 0 ; i < num_handles ; i++ )
method ( efidrv, handles[i] );
/* Free list of handles */
bs->FreePool ( handles );
return 0;
}
/**
* Install EFI driver
*
@ -159,6 +223,10 @@ int efi_driver_install ( struct efi_driver *efidrv ) {
return rc;
}
/* Connect devices */
DBGC ( efidrv, "EFIDRV %s connecting devices\n", efidrv->name );
efi_driver_handles ( efidrv, efi_driver_connect );
DBGC ( efidrv, "EFIDRV %s installed\n", efidrv->name );
return 0;
}
@ -170,29 +238,10 @@ int efi_driver_install ( struct efi_driver *efidrv ) {
*/
void efi_driver_uninstall ( struct efi_driver *efidrv ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_HANDLE *handles;
UINTN num_handles;
EFI_STATUS efirc;
UINTN i;
int rc;
/* Disconnect the driver from its devices */
if ( ( efirc = bs->LocateHandleBuffer ( AllHandles, NULL, NULL,
&num_handles,
&handles ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( efidrv, "EFIDRV %s could not list handles: %s\n",
efidrv->name, strerror ( rc ) );
/* No way to disconnect driver; leave it loaded */
return;
}
DBGC ( efidrv, "EFIDRV %s disconnecting devices\n", efidrv->name );
for ( i = 0 ; i < num_handles ; i++ ) {
bs->DisconnectController ( handles[i],
efidrv->driver.DriverBindingHandle,
NULL );
}
bs->FreePool ( handles );
efi_driver_handles ( efidrv, efi_driver_disconnect );
/* Uninstall the driver */
bs->UninstallMultipleProtocolInterfaces (