[efi] Connect driver to devices as part of installation
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
8de6b973c4
commit
2602965806
@ -118,6 +118,70 @@ efi_driver_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
|
|||||||
return EFI_UNSUPPORTED;
|
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
|
* Install EFI driver
|
||||||
*
|
*
|
||||||
@ -159,6 +223,10 @@ int efi_driver_install ( struct efi_driver *efidrv ) {
|
|||||||
return rc;
|
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 );
|
DBGC ( efidrv, "EFIDRV %s installed\n", efidrv->name );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -170,29 +238,10 @@ int efi_driver_install ( struct efi_driver *efidrv ) {
|
|||||||
*/
|
*/
|
||||||
void efi_driver_uninstall ( struct efi_driver *efidrv ) {
|
void efi_driver_uninstall ( struct efi_driver *efidrv ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
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 */
|
/* 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 );
|
DBGC ( efidrv, "EFIDRV %s disconnecting devices\n", efidrv->name );
|
||||||
for ( i = 0 ; i < num_handles ; i++ ) {
|
efi_driver_handles ( efidrv, efi_driver_disconnect );
|
||||||
bs->DisconnectController ( handles[i],
|
|
||||||
efidrv->driver.DriverBindingHandle,
|
|
||||||
NULL );
|
|
||||||
}
|
|
||||||
bs->FreePool ( handles );
|
|
||||||
|
|
||||||
/* Uninstall the driver */
|
/* Uninstall the driver */
|
||||||
bs->UninstallMultipleProtocolInterfaces (
|
bs->UninstallMultipleProtocolInterfaces (
|
||||||
|
Reference in New Issue
Block a user