Rework the logic to allocate an efi_net_obj and its members. An efi_net_obj now gets allocated only in efi_netobj_alloc.
Signed-off-by: Adriano Cordova <adriano.cord...@canonical.com> --- lib/efi_loader/efi_net.c | 131 ++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 51 deletions(-) diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index a40d319a27f..a14ecf3d182 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -1152,19 +1152,10 @@ static int efi_netobj_init(struct efi_net_obj *netobj) size_t *receive_lengths = NULL; int i, j; - if (!netobj || efi_netobj_is_active(netobj)) + if (!netobj || !netobj->net || efi_netobj_is_active(netobj)) return 0; dev = netobj->dev; - if (!dev) { - /* No network device active, don't expose any */ - return 0; - } - - if (!netobj->net) - netobj->net = calloc(1, sizeof(*netobj->net)); - if (!netobj->net) - goto out_of_resources; if (!netobj->net_mode) netobj->net_mode = calloc(1, sizeof(*netobj->net_mode)); @@ -1344,6 +1335,84 @@ efi_status_t efi_net_init(void) return EFI_SUCCESS; } +/** + * efi_netobj_alloc() - allocate an efi_net_obj from either a simple + * network protocol interface or a net udevice + * + * @handle: EFI handle + * @net: pointer to simple network protocol + * @dev: pointer to net udevice + * Return: pointer to EFI net object, NULL on error + */ +struct efi_net_obj *efi_netobj_alloc(efi_handle_t handle, + struct efi_simple_network *net, + struct udevice *dev) +{ + int i; + struct efi_net_obj *netobj; + + // Find a slot for this efi_net_obj + + // Try to recycle + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && !net_objs[i]->net && !net_objs[i]->dev && !net_objs[i]->handle) + break; + } + if (i == MAX_EFI_NET_OBJS) { + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (!net_objs[i]) + break; + } + } + if (i == MAX_EFI_NET_OBJS) + return NULL; + + if (!net_objs[i]) { + netobj = calloc(1, sizeof(*netobj)); + net_objs[i] = netobj; + } else { + netobj = net_objs[i]; + } + if (!netobj) + return NULL; + + if (netobj->net) { + if (netobj->net->mode) + free(netobj->net->mode); + free(netobj->net); + } + + if (handle) { + netobj->handle = handle; + } + else { + netobj->handle = calloc(1, sizeof(*netobj->handle)); + if (!netobj->handle) { + free(netobj); + return NULL; + } + } + + if (net) { + netobj->net = net; + netobj->net_mode = net->mode; + } else { + netobj->net = calloc(1, sizeof(*netobj->net)); + if (!netobj->net) { + free(netobj->handle); + free(netobj); + return NULL; + } + } + + netobj->dev = dev; + netobj->efi_seq_num = i; + + printf("\nefi_net: allocated EFI net device %d\n", netobj->efi_seq_num); + + return netobj; +} + /** * efi_net_register() - register a net device * @@ -1356,9 +1425,7 @@ efi_status_t efi_net_init(void) int efi_net_register(void *ctx, struct event *event) { struct udevice *dev; - int seq_num; enum uclass_id id; - struct efi_net_obj *netobj; int i; dev = event->data.dm.dev; @@ -1378,48 +1445,10 @@ int efi_net_register(void *ctx, struct event *event) } } - // Find a slot for this efi_net_obj - seq_num = -1; - // Try to recycle - for (i = 0; i < MAX_EFI_NET_OBJS; i++) { - if (net_objs[i] && !net_objs[i]->dev) { - seq_num = i; - break; - } - } - if (seq_num < 0) { - for (i = 0; i < MAX_EFI_NET_OBJS; i++) { - if (!net_objs[i]) { - seq_num = i; - break; - } - } - } - if (seq_num < 0) + if (!efi_netobj_alloc(NULL, NULL, dev)) return -1; - if (!net_objs[seq_num]) { - netobj = calloc(1, sizeof(*netobj)); - net_objs[seq_num] = netobj; - } else { - netobj = net_objs[seq_num]; - } - if (!netobj) - goto out_of_resources; - - netobj->handle = calloc(1, sizeof(*netobj->handle)); - if (!netobj->handle) { - free(netobj); - goto out_of_resources; - } - - netobj->dev = dev; - netobj->efi_seq_num = seq_num; - printf("efi_net registered device number %d\n", netobj->efi_seq_num); return 0; -out_of_resources: - printf("ERROR: Out of memory\n"); - return -1; } /** -- 2.48.1