|
@@ -118,6 +118,70 @@ efi_driver_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
|
118
|
118
|
return EFI_UNSUPPORTED;
|
119
|
119
|
}
|
120
|
120
|
|
|
121
|
+/**
|
|
122
|
+ * Try to connect EFI driver
|
|
123
|
+ *
|
|
124
|
+ * @v efidrv EFI driver
|
|
125
|
+ * @v handle Controller handle
|
|
126
|
+ */
|
|
127
|
+static void efi_driver_connect ( struct efi_driver *efidrv, EFI_HANDLE handle ){
|
|
128
|
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
|
129
|
+ EFI_HANDLE drivers[2] = { efidrv->driver.DriverBindingHandle, NULL };
|
|
130
|
+
|
|
131
|
+ bs->ConnectController ( handle, drivers, NULL, FALSE );
|
|
132
|
+}
|
|
133
|
+
|
|
134
|
+/**
|
|
135
|
+ * Try to disconnect EFI driver
|
|
136
|
+ *
|
|
137
|
+ * @v efidrv EFI driver
|
|
138
|
+ * @v handle Controller handle
|
|
139
|
+ */
|
|
140
|
+static void efi_driver_disconnect ( struct efi_driver *efidrv,
|
|
141
|
+ EFI_HANDLE handle ) {
|
|
142
|
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
|
143
|
+
|
|
144
|
+ bs->DisconnectController ( handle, efidrv->driver.DriverBindingHandle,
|
|
145
|
+ NULL );
|
|
146
|
+}
|
|
147
|
+
|
|
148
|
+/**
|
|
149
|
+ * Connect/disconnect EFI driver from all handles
|
|
150
|
+ *
|
|
151
|
+ * @v efidrv EFI driver
|
|
152
|
+ * @v method Connect/disconnect method
|
|
153
|
+ * @ret rc Return status code
|
|
154
|
+ */
|
|
155
|
+static int efi_driver_handles ( struct efi_driver *efidrv,
|
|
156
|
+ void ( * method ) ( struct efi_driver *efidrv,
|
|
157
|
+ EFI_HANDLE handle ) ) {
|
|
158
|
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
|
159
|
+ EFI_HANDLE *handles;
|
|
160
|
+ UINTN num_handles;
|
|
161
|
+ EFI_STATUS efirc;
|
|
162
|
+ UINTN i;
|
|
163
|
+ int rc;
|
|
164
|
+
|
|
165
|
+ /* Enumerate all handles */
|
|
166
|
+ if ( ( efirc = bs->LocateHandleBuffer ( AllHandles, NULL, NULL,
|
|
167
|
+ &num_handles,
|
|
168
|
+ &handles ) ) != 0 ) {
|
|
169
|
+ rc = -EEFI ( efirc );
|
|
170
|
+ DBGC ( efidrv, "EFIDRV %s could not list handles: %s\n",
|
|
171
|
+ efidrv->name, strerror ( rc ) );
|
|
172
|
+ return rc;
|
|
173
|
+ }
|
|
174
|
+
|
|
175
|
+ /* Connect/disconnect driver from all handles */
|
|
176
|
+ for ( i = 0 ; i < num_handles ; i++ )
|
|
177
|
+ method ( efidrv, handles[i] );
|
|
178
|
+
|
|
179
|
+ /* Free list of handles */
|
|
180
|
+ bs->FreePool ( handles );
|
|
181
|
+
|
|
182
|
+ return 0;
|
|
183
|
+}
|
|
184
|
+
|
121
|
185
|
/**
|
122
|
186
|
* Install EFI driver
|
123
|
187
|
*
|
|
@@ -159,6 +223,10 @@ int efi_driver_install ( struct efi_driver *efidrv ) {
|
159
|
223
|
return rc;
|
160
|
224
|
}
|
161
|
225
|
|
|
226
|
+ /* Connect devices */
|
|
227
|
+ DBGC ( efidrv, "EFIDRV %s connecting devices\n", efidrv->name );
|
|
228
|
+ efi_driver_handles ( efidrv, efi_driver_connect );
|
|
229
|
+
|
162
|
230
|
DBGC ( efidrv, "EFIDRV %s installed\n", efidrv->name );
|
163
|
231
|
return 0;
|
164
|
232
|
}
|
|
@@ -170,29 +238,10 @@ int efi_driver_install ( struct efi_driver *efidrv ) {
|
170
|
238
|
*/
|
171
|
239
|
void efi_driver_uninstall ( struct efi_driver *efidrv ) {
|
172
|
240
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
173
|
|
- EFI_HANDLE *handles;
|
174
|
|
- UINTN num_handles;
|
175
|
|
- EFI_STATUS efirc;
|
176
|
|
- UINTN i;
|
177
|
|
- int rc;
|
178
|
241
|
|
179
|
242
|
/* Disconnect the driver from its devices */
|
180
|
|
- if ( ( efirc = bs->LocateHandleBuffer ( AllHandles, NULL, NULL,
|
181
|
|
- &num_handles,
|
182
|
|
- &handles ) ) != 0 ) {
|
183
|
|
- rc = -EEFI ( efirc );
|
184
|
|
- DBGC ( efidrv, "EFIDRV %s could not list handles: %s\n",
|
185
|
|
- efidrv->name, strerror ( rc ) );
|
186
|
|
- /* No way to disconnect driver; leave it loaded */
|
187
|
|
- return;
|
188
|
|
- }
|
189
|
243
|
DBGC ( efidrv, "EFIDRV %s disconnecting devices\n", efidrv->name );
|
190
|
|
- for ( i = 0 ; i < num_handles ; i++ ) {
|
191
|
|
- bs->DisconnectController ( handles[i],
|
192
|
|
- efidrv->driver.DriverBindingHandle,
|
193
|
|
- NULL );
|
194
|
|
- }
|
195
|
|
- bs->FreePool ( handles );
|
|
244
|
+ efi_driver_handles ( efidrv, efi_driver_disconnect );
|
196
|
245
|
|
197
|
246
|
/* Uninstall the driver */
|
198
|
247
|
bs->UninstallMultipleProtocolInterfaces (
|