.poll = nii_poll,
};
+/**
+ * Exclude existing drivers
+ *
+ * @v device EFI device handle
+ * @ret rc Return status code
+ */
+int nii_exclude ( EFI_HANDLE device ) {
+ EFI_GUID *protocol = &efi_nii31_protocol_guid;
+ int rc;
+
+ /* Exclude existing NII protocol drivers */
+ if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
+ DBGC ( device, "NII %s could not exclude drivers: %s\n",
+ efi_handle_name ( device ), strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
/**
* Attach driver to device
*
struct efi_device;
+extern int nii_exclude ( EFI_HANDLE device );
extern int nii_start ( struct efi_device *efidev );
extern void nii_stop ( struct efi_device *efidev );
/** EFI SNP driver */
struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_SNP ) = {
.name = "SNP",
- .exclude = &efi_simple_network_protocol_guid,
.supported = snp_supported,
+ .exclude = snpnet_exclude,
.start = snpnet_start,
.stop = snpnet_stop,
};
/** EFI NII driver */
struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NII ) = {
.name = "NII",
- .exclude = &efi_nii31_protocol_guid,
.supported = nii_supported,
+ .exclude = nii_exclude,
.start = nii_start,
.stop = nii_stop,
};
return 0;
}
+/**
+ * Exclude existing drivers
+ *
+ * @v device EFI device handle
+ * @ret rc Return status code
+ */
+int snpnet_exclude ( EFI_HANDLE device ) {
+ EFI_GUID *protocol = &efi_simple_network_protocol_guid;
+ int rc;
+
+ /* Exclude existing SNP drivers */
+ if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
+ DBGC ( device, "SNP %s could not exclude drivers: %s\n",
+ efi_handle_name ( device ), strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
/**
* Attach driver to device
*
struct efi_device;
extern int snpnet_supported ( EFI_HANDLE device, EFI_GUID *protocol );
+extern int snpnet_exclude ( EFI_HANDLE device );
extern int snpnet_start ( struct efi_device *efidev );
extern void snpnet_stop ( struct efi_device *efidev );
/** EFI SNP chainloading-device-only driver */
struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_SNP ) = {
.name = "SNPONLY",
- .exclude = &efi_simple_network_protocol_guid,
.supported = snponly_supported,
+ .exclude = snpnet_exclude,
.start = snpnet_start,
.stop = snpnet_stop,
};
/** EFI NII chainloading-device-only driver */
struct efi_driver niionly_driver __efi_driver ( EFI_DRIVER_NII ) = {
.name = "NIIONLY",
- .exclude = &efi_nii31_protocol_guid,
.supported = niionly_supported,
+ .exclude = nii_exclude,
.start = nii_start,
.stop = nii_stop,
};
return rc;
}
+/**
+ * Exclude existing drivers
+ *
+ * @v device EFI device handle
+ * @ret rc Return status code
+ */
+static int usbio_exclude ( EFI_HANDLE device ) {
+ EFI_GUID *protocol = &efi_usb_io_protocol_guid;
+ int rc;
+
+ /* Exclude existing USB I/O protocol drivers */
+ if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
+ DBGC ( device, "USBIO %s could not exclude drivers: %s\n",
+ efi_handle_name ( device ), strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
/**
* Attach driver to device
*
/** EFI USB I/O driver */
struct efi_driver usbio_driver __efi_driver ( EFI_DRIVER_HARDWARE ) = {
.name = "USBIO",
- .exclude = &efi_usb_io_protocol_guid,
.supported = usbio_supported,
+ .exclude = usbio_exclude,
.start = usbio_start,
.stop = usbio_stop,
};
struct efi_driver {
/** Name */
const char *name;
- /** Protocol to which exclusive access is required, if any */
- EFI_GUID *exclude;
+ /**
+ * Exclude existing drivers
+ *
+ * @v device EFI device handle
+ * @ret rc Return status code
+ */
+ int ( * exclude ) ( EFI_HANDLE device );
/**
* Check if driver supports device
*
extern struct efi_device * efidev_parent ( struct device *dev );
extern int efi_driver_install ( void );
extern void efi_driver_uninstall ( void );
+extern int efi_driver_exclude ( EFI_HANDLE device, EFI_GUID *protocol );
extern int efi_driver_connect_all ( void );
extern void efi_driver_disconnect_all ( void );
extern void efi_driver_reconnect_all ( void );
* @v protocol Protocol GUID
* @ret rc Return status code
*/
-static int efi_driver_exclude ( EFI_HANDLE device, EFI_GUID *protocol ) {
+int efi_driver_exclude ( EFI_HANDLE device, EFI_GUID *protocol ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *openers;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener;
}
/* Try to disconnect driver */
+ DBGC ( device, "EFIDRV %s disconnecting %s drivers\n",
+ efi_handle_name ( device ), efi_guid_ntoa ( protocol ) );
if ( driver ) {
DBGC ( device, "EFIDRV %s disconnecting %s driver ",
efi_handle_name ( device ), efi_guid_ntoa ( protocol ) );
EFI_HANDLE drivers[2] =
{ efi_driver_binding.DriverBindingHandle, NULL };
struct efi_driver *efidrv;
- EFI_GUID *exclude;
EFI_STATUS efirc;
int rc;
efi_handle_name ( device ) );
efi_driver_disconnecting = 1;
for_each_table_entry_reverse ( efidrv, EFI_DRIVERS ) {
- exclude = efidrv->exclude;
- if ( ! exclude )
+ if ( ! efidrv->exclude )
continue;
if ( ( rc = efidrv->supported ( device ) ) != 0 )
continue;
- DBGC ( device, "EFIDRV %s disconnecting %s drivers\n",
- efi_handle_name ( device ), efi_guid_ntoa ( exclude ) );
- if ( ( rc = efi_driver_exclude ( device, exclude ) ) != 0 ) {
- DBGC ( device, "EFIDRV %s could not disconnect %s "
+ if ( ( rc = efidrv->exclude ( device ) ) != 0 ) {
+ DBGC ( device, "EFIDRV %s could not disconnect "
"drivers: %s\n", efi_handle_name ( device ),
- efi_guid_ntoa ( exclude ), strerror ( rc ) );
+ strerror ( rc ) );
/* Ignore the error and attempt to connect anyway */
}
}
return 0;
}
+/**
+ * Exclude existing drivers
+ *
+ * @v device EFI device handle
+ * @ret rc Return status code
+ */
+static int efipci_exclude ( EFI_HANDLE device ) {
+ EFI_GUID *protocol = &efi_pci_io_protocol_guid;
+ int rc;
+
+ /* Exclude existing PCI I/O protocol drivers */
+ if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
+ DBGC ( device, "EFIPCI %s could not exclude drivers: %s\n",
+ efi_handle_name ( device ), strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
/**
* Attach driver to device
*
/** EFI PCI driver */
struct efi_driver efipci_driver __efi_driver ( EFI_DRIVER_HARDWARE ) = {
.name = "PCI",
- .exclude = &efi_pci_io_protocol_guid,
.supported = efipci_supported,
+ .exclude = efipci_exclude,
.start = efipci_start,
.stop = efipci_stop,
};