aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorxypron.glpk@gmx.de2017-07-11 22:06:14 +0200
committerAlexander Graf2017-07-19 14:14:23 +0200
commitb5349f742a7684aabd3fb8f0e20c67ba033deec7 (patch)
treebaf7e6b7647f4274ed1b3c11c71b01a5aba88730 /lib
parent8d3a25685e4aac7070365a2b3c53c2c81b27930f (diff)
efi_loader: refactor efi_open_protocol
efi_open_protocol was implemented to call a protocol specific open function to retrieve the protocol interface. The UEFI specification does not know of such a function. It is not possible to implement InstallProtocolInterface with the current design. With the patch the protocol interface itself is stored in the list of installed protocols of an efi_object instead of an open function. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> [agraf: fix efi gop support] Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_boottime.c18
-rw-r--r--lib/efi_loader/efi_disk.c29
-rw-r--r--lib/efi_loader/efi_gop.c2
-rw-r--r--lib/efi_loader/efi_image_loader.c8
-rw-r--r--lib/efi_loader/efi_net.c30
5 files changed, 21 insertions, 66 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 27e51a253fc..5c72f924742 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -442,7 +442,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
.protocols = {
{
.guid = &efi_guid_loaded_image,
- .open = &efi_return_handle,
},
},
};
@@ -452,6 +451,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
file_path, source_buffer, source_size, image_handle);
info = malloc(sizeof(*info));
+ loaded_image_info_obj.protocols[0].protocol_interface = info;
obj = malloc(sizeof(loaded_image_info_obj));
memset(info, 0, sizeof(*info));
memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj));
@@ -723,6 +723,13 @@ static efi_status_t EFIAPI efi_open_protocol(
EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol,
protocol_interface, agent_handle, controller_handle,
attributes);
+
+ if (!protocol_interface && attributes !=
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
list_for_each(lhandle, &efi_obj_list) {
struct efi_object *efiobj;
efiobj = list_entry(lhandle, struct efi_object, link);
@@ -736,9 +743,12 @@ static efi_status_t EFIAPI efi_open_protocol(
if (!hprotocol)
break;
if (!guidcmp(hprotocol, protocol)) {
- r = handler->open(handle, protocol,
- protocol_interface, agent_handle,
- controller_handle, attributes);
+ if (attributes !=
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
+ *protocol_interface =
+ handler->protocol_interface;
+ }
+ r = EFI_SUCCESS;
goto out;
}
}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 39e602a8689..3ad7706472c 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -35,29 +35,6 @@ struct efi_disk_obj {
const struct blk_desc *desc;
};
-static efi_status_t EFIAPI efi_disk_open_block(void *handle,
- efi_guid_t *protocol, void **protocol_interface,
- void *agent_handle, void *controller_handle,
- uint32_t attributes)
-{
- struct efi_disk_obj *diskobj = handle;
-
- *protocol_interface = &diskobj->ops;
-
- return EFI_SUCCESS;
-}
-
-static efi_status_t EFIAPI efi_disk_open_dp(void *handle, efi_guid_t *protocol,
- void **protocol_interface, void *agent_handle,
- void *controller_handle, uint32_t attributes)
-{
- struct efi_disk_obj *diskobj = handle;
-
- *protocol_interface = diskobj->dp;
-
- return EFI_SUCCESS;
-}
-
static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this,
char extended_verification)
{
@@ -210,10 +187,11 @@ static void efi_disk_add_dev(const char *name,
diskobj = calloc(1, objlen);
/* Fill in object data */
+ dp = (void *)&diskobj[1];
diskobj->parent.protocols[0].guid = &efi_block_io_guid;
- diskobj->parent.protocols[0].open = efi_disk_open_block;
+ diskobj->parent.protocols[0].protocol_interface = &diskobj->ops;
diskobj->parent.protocols[1].guid = &efi_guid_device_path;
- diskobj->parent.protocols[1].open = efi_disk_open_dp;
+ diskobj->parent.protocols[1].protocol_interface = dp;
diskobj->parent.handle = diskobj;
diskobj->ops = block_io_disk_template;
diskobj->ifname = if_typename;
@@ -230,7 +208,6 @@ static void efi_disk_add_dev(const char *name,
diskobj->ops.media = &diskobj->media;
/* Fill in device path */
- dp = (void*)&diskobj[1];
diskobj->dp = dp;
dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
index 286ad830976..db1fd18a348 100644
--- a/lib/efi_loader/efi_gop.c
+++ b/lib/efi_loader/efi_gop.c
@@ -172,7 +172,7 @@ int efi_gop_register(void)
/* Fill in object data */
gopobj->parent.protocols[0].guid = &efi_gop_guid;
- gopobj->parent.protocols[0].open = efi_return_handle;
+ gopobj->parent.protocols[0].protocol_interface = &gopobj->ops;
gopobj->parent.handle = &gopobj->ops;
gopobj->ops.query_mode = gop_query_mode;
gopobj->ops.set_mode = gop_set_mode;
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index d4c62e677c6..f961407f50a 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -18,14 +18,6 @@ DECLARE_GLOBAL_DATA_PTR;
const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID;
const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID;
-efi_status_t EFIAPI efi_return_handle(void *handle, efi_guid_t *protocol,
- void **protocol_interface, void *agent_handle,
- void *controller_handle, uint32_t attributes)
-{
- *protocol_interface = handle;
- return EFI_SUCCESS;
-}
-
static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
unsigned long rel_size, void *efi_reloc)
{
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 604ac6e0408..0b949d86e8d 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -199,30 +199,6 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
return EFI_EXIT(EFI_SUCCESS);
}
-static efi_status_t EFIAPI efi_net_open_dp(void *handle, efi_guid_t *protocol,
- void **protocol_interface, void *agent_handle,
- void *controller_handle, uint32_t attributes)
-{
- struct efi_simple_network *net = handle;
- struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
-
- *protocol_interface = &netobj->dp_mac;
-
- return EFI_SUCCESS;
-}
-
-static efi_status_t EFIAPI efi_net_open_pxe(void *handle, efi_guid_t *protocol,
- void **protocol_interface, void *agent_handle,
- void *controller_handle, uint32_t attributes)
-{
- struct efi_simple_network *net = handle;
- struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
-
- *protocol_interface = &netobj->pxe;
-
- return EFI_SUCCESS;
-}
-
void efi_net_set_dhcp_ack(void *pkt, int len)
{
int maxsize = sizeof(*dhcp_ack);
@@ -258,11 +234,11 @@ int efi_net_register(void **handle)
/* Fill in object data */
netobj->parent.protocols[0].guid = &efi_net_guid;
- netobj->parent.protocols[0].open = efi_return_handle;
+ netobj->parent.protocols[0].protocol_interface = &netobj->net;
netobj->parent.protocols[1].guid = &efi_guid_device_path;
- netobj->parent.protocols[1].open = efi_net_open_dp;
+ netobj->parent.protocols[1].protocol_interface = &netobj->dp_mac;
netobj->parent.protocols[2].guid = &efi_pxe_guid;
- netobj->parent.protocols[2].open = efi_net_open_pxe;
+ netobj->parent.protocols[2].protocol_interface = &netobj->pxe;
netobj->parent.handle = &netobj->net;
netobj->net.start = efi_net_start;
netobj->net.stop = efi_net_stop;