Parcourir la source

[efi] Connect driver to devices as part of installation

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown il y a 10 ans
Parent
révision
2602965806
1 fichiers modifiés avec 69 ajouts et 20 suppressions
  1. 69
    20
      src/interface/efi/efi_driver.c

+ 69
- 20
src/interface/efi/efi_driver.c Voir le fichier

@@ -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 (

Chargement…
Annuler
Enregistrer