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

Reply via email to