|
@@ -45,6 +45,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
45
|
45
|
{ 0x03207ce2, 0xd9c7, 0x11dc, \
|
46
|
46
|
{ 0xa9, 0x4d, 0x00, 0x19, 0x7d, 0x89, 0x02, 0x38 } }
|
47
|
47
|
|
|
48
|
+#define IBM_BOFM_DRIVER_CONFIGURATION2_PROTOCOL_GUID \
|
|
49
|
+ { 0xe82a9763, 0x0584, 0x4e41, \
|
|
50
|
+ { 0xbb, 0x39, 0xe0, 0xcd, 0xb8, 0xc1, 0xf0, 0xfc } }
|
|
51
|
+
|
48
|
52
|
typedef struct {
|
49
|
53
|
UINT8 Id;
|
50
|
54
|
UINT8 ResultByte;
|
|
@@ -114,6 +118,15 @@ struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL {
|
114
|
118
|
IBM_BOFM_DRIVER_CONFIGURATION_SUPPORT RegisterSupport;
|
115
|
119
|
};
|
116
|
120
|
|
|
121
|
+typedef struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 {
|
|
122
|
+ UINT32 Signature;
|
|
123
|
+ UINT32 Reserved1;
|
|
124
|
+ UINT64 Reserved2;
|
|
125
|
+ IBM_BOFM_DRIVER_CONFIGURATION_STATUS SetStatus;
|
|
126
|
+ IBM_BOFM_DRIVER_CONFIGURATION_SUPPORT RegisterSupport;
|
|
127
|
+ IBM_BOFM_TABLE BofmTable;
|
|
128
|
+} IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2;
|
|
129
|
+
|
117
|
130
|
/***************************************************************************
|
118
|
131
|
*
|
119
|
132
|
* EFI BOFM interface
|
|
@@ -121,10 +134,14 @@ struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL {
|
121
|
134
|
***************************************************************************
|
122
|
135
|
*/
|
123
|
136
|
|
124
|
|
-/** BOFM protocol GUID */
|
125
|
|
-static EFI_GUID bofm_protocol_guid =
|
|
137
|
+/** BOFM1 protocol GUID */
|
|
138
|
+static EFI_GUID bofm1_protocol_guid =
|
126
|
139
|
IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL_GUID;
|
127
|
140
|
|
|
141
|
+/** BOFM2 protocol GUID */
|
|
142
|
+static EFI_GUID bofm2_protocol_guid =
|
|
143
|
+ IBM_BOFM_DRIVER_CONFIGURATION2_PROTOCOL_GUID;
|
|
144
|
+
|
128
|
145
|
/**
|
129
|
146
|
* Check if device is supported
|
130
|
147
|
*
|
|
@@ -141,9 +158,9 @@ efi_bofm_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
141
|
158
|
container_of ( driver, struct efi_driver, driver );
|
142
|
159
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
143
|
160
|
union {
|
144
|
|
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *bofm;
|
|
161
|
+ IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *bofm1;
|
145
|
162
|
void *interface;
|
146
|
|
- } u;
|
|
163
|
+ } bofm1;
|
147
|
164
|
struct efi_pci_device *efipci;
|
148
|
165
|
EFI_STATUS efirc;
|
149
|
166
|
int rc;
|
|
@@ -166,8 +183,8 @@ efi_bofm_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
166
|
183
|
}
|
167
|
184
|
|
168
|
185
|
/* Locate BOFM protocol */
|
169
|
|
- if ( ( efirc = bs->LocateProtocol ( &bofm_protocol_guid, NULL,
|
170
|
|
- &u.interface ) ) != 0 ) {
|
|
186
|
+ if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
|
|
187
|
+ &bofm1.interface ) ) != 0 ) {
|
171
|
188
|
DBGC ( efidrv, "BOFM " PCI_FMT " cannot find BOFM protocol\n",
|
172
|
189
|
PCI_ARGS ( &efipci->pci ) );
|
173
|
190
|
efirc = EFI_UNSUPPORTED;
|
|
@@ -175,10 +192,10 @@ efi_bofm_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
175
|
192
|
}
|
176
|
193
|
|
177
|
194
|
/* Register support for this device */
|
178
|
|
- if ( ( efirc = u.bofm->RegisterSupport ( u.bofm, device,
|
179
|
|
- 0x04 /* Can change MAC */,
|
180
|
|
- 0x00 /* No iSCSI */,
|
181
|
|
- 0x01 /* Version */ ) ) != 0 ) {
|
|
195
|
+ if ( ( efirc = bofm1.bofm1->RegisterSupport ( bofm1.bofm1, device,
|
|
196
|
+ 0x04 /* Can change MAC */,
|
|
197
|
+ 0x00 /* No iSCSI */,
|
|
198
|
+ 0x02 /* Version */ ))!=0){
|
182
|
199
|
DBGC ( efidrv, "BOFM " PCI_FMT " could not register support: "
|
183
|
200
|
"%s\n", PCI_ARGS ( &efipci->pci ),
|
184
|
201
|
efi_strerror ( efirc ) );
|
|
@@ -216,10 +233,15 @@ static EFI_STATUS EFIAPI efi_bofm_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
216
|
233
|
container_of ( driver, struct efi_driver, driver );
|
217
|
234
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
218
|
235
|
union {
|
219
|
|
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *bofm;
|
|
236
|
+ IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *bofm1;
|
220
|
237
|
void *interface;
|
221
|
|
- } u;
|
|
238
|
+ } bofm1;
|
|
239
|
+ union {
|
|
240
|
+ IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 *bofm2;
|
|
241
|
+ void *interface;
|
|
242
|
+ } bofm2;
|
222
|
243
|
struct efi_pci_device *efipci;
|
|
244
|
+ userptr_t bofmtab;
|
223
|
245
|
EFI_STATUS efirc;
|
224
|
246
|
int bofmrc;
|
225
|
247
|
|
|
@@ -237,21 +259,44 @@ static EFI_STATUS EFIAPI efi_bofm_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
237
|
259
|
goto err_enable;
|
238
|
260
|
|
239
|
261
|
/* Locate BOFM protocol */
|
240
|
|
- if ( ( efirc = bs->LocateProtocol ( &bofm_protocol_guid, NULL,
|
241
|
|
- &u.interface ) ) != 0 ) {
|
|
262
|
+ if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
|
|
263
|
+ &bofm1.interface ) ) != 0 ) {
|
242
|
264
|
DBGC ( efidrv, "BOFM " PCI_FMT " cannot find BOFM protocol\n",
|
243
|
265
|
PCI_ARGS ( &efipci->pci ) );
|
244
|
266
|
goto err_locate_bofm;
|
245
|
267
|
}
|
246
|
268
|
|
|
269
|
+ /* Locate BOFM2 protocol, if available */
|
|
270
|
+ if ( ( efirc = bs->LocateProtocol ( &bofm2_protocol_guid, NULL,
|
|
271
|
+ &bofm2.interface ) ) != 0 ) {
|
|
272
|
+ DBGC ( efidrv, "BOFM " PCI_FMT " cannot find BOFM2 protocol\n",
|
|
273
|
+ PCI_ARGS ( &efipci->pci ) );
|
|
274
|
+ /* Not a fatal error; may be a BOFM1-only system */
|
|
275
|
+ bofm2.bofm2 = NULL;
|
|
276
|
+ }
|
|
277
|
+
|
|
278
|
+ /* Select appropriate BOFM table (v1 or v2) to use */
|
|
279
|
+ if ( bofm2.bofm2 ) {
|
|
280
|
+ DBGC ( efidrv, "BOFM " PCI_FMT " using version 2 BOFM table\n",
|
|
281
|
+ PCI_ARGS ( &efipci->pci ) );
|
|
282
|
+ assert ( bofm2.bofm2->RegisterSupport ==
|
|
283
|
+ bofm1.bofm1->RegisterSupport );
|
|
284
|
+ assert ( bofm2.bofm2->SetStatus == bofm1.bofm1->SetStatus );
|
|
285
|
+ bofmtab = virt_to_user ( &bofm2.bofm2->BofmTable );
|
|
286
|
+ } else {
|
|
287
|
+ DBGC ( efidrv, "BOFM " PCI_FMT " using version 1 BOFM table\n",
|
|
288
|
+ PCI_ARGS ( &efipci->pci ) );
|
|
289
|
+ bofmtab = virt_to_user ( &bofm1.bofm1->BofmTable );
|
|
290
|
+ }
|
|
291
|
+
|
247
|
292
|
/* Process BOFM table */
|
248
|
|
- bofmrc = bofm ( virt_to_user ( &u.bofm->BofmTable ), &efipci->pci );
|
|
293
|
+ bofmrc = bofm ( bofmtab, &efipci->pci );
|
249
|
294
|
DBGC ( efidrv, "BOFM " PCI_FMT " status %08x\n",
|
250
|
295
|
PCI_ARGS ( &efipci->pci ), bofmrc );
|
251
|
296
|
|
252
|
297
|
/* Return BOFM status */
|
253
|
|
- if ( ( efirc = u.bofm->SetStatus ( u.bofm, device, FALSE,
|
254
|
|
- bofmrc ) ) != 0 ) {
|
|
298
|
+ if ( ( efirc = bofm1.bofm1->SetStatus ( bofm1.bofm1, device, FALSE,
|
|
299
|
+ bofmrc ) ) != 0 ) {
|
255
|
300
|
DBGC ( efidrv, "BOFM " PCI_FMT " could not set BOFM status: "
|
256
|
301
|
"%s\n", PCI_ARGS ( &efipci->pci ),
|
257
|
302
|
efi_strerror ( efirc ) );
|