Hi Paul,

Apologies for the delayed reply.

[...]

> +static efi_status_t
> +export_spi_peripheral(struct efi_spi_bus *bus, struct udevice *dev)
> +{
> +     efi_string_t name_utf16, vendor_utf16, part_number_utf16;
> +     struct efi_spi_peripheral_priv *priv;
> +     efi_status_t status;
> +     efi_handle_t handle = NULL;
> +     struct udevice *dev_bus = dev->parent;
> +     struct spi_slave *target;
> +     const char *name = dev_read_name(dev);
> +     const char *vendor = dev_read_string(dev, "u-boot,uefi-spi-vendor");
> +     const char *part_number = dev_read_string(dev,
> +                     "u-boot,uefi-spi-part-number");
> +     efi_guid_t *guid = (efi_guid_t *)dev_read_u8_array_ptr(dev,
> +                     "u-boot,uefi-spi-io-guid", 16);
> +
> +     if (device_get_uclass_id(dev) == UCLASS_SPI_EMUL) {
> +             debug("Skipping emulated SPI peripheral %s\n", name);
> +             goto fail_1;
> +     }
> +
> +     if (!vendor || !part_number || !guid) {
> +             debug("Skipping SPI peripheral %s\n", name);
> +             status = EFI_UNSUPPORTED;
> +             goto fail_1;
> +     }
> +
> +     if (!device_active(dev)) {
> +             int ret = device_probe(dev);
> +             if (ret) {
> +                     debug("Skipping SPI peripheral %s, probe failed\n",
> +                           name);
> +                     goto fail_1;
> +             }
> +     }
> +
> +     target = dev_get_parent_priv(dev);
> +     if (!target) {
> +             debug("Skipping uninitialized SPI peripheral %s\n", name);
> +             status = EFI_UNSUPPORTED;
> +             goto fail_1;
> +     }
> +
> +     debug("Registering SPI dev %d:%d, name %s\n",
> +           dev_bus->seq_, spi_chip_select(dev), name);
> +
> +     priv = calloc(1, sizeof(*priv));
> +     if (!priv) {
> +             status = EFI_OUT_OF_RESOURCES;
> +             goto fail_1;
> +     }
> +
> +     vendor_utf16 = efi_convert_string(vendor);
> +     if (!vendor_utf16) {
> +             status = EFI_OUT_OF_RESOURCES;
> +             goto fail_2;
> +     }
> +
> +     part_number_utf16 = efi_convert_string(part_number);
> +     if (!part_number_utf16) {
> +             status = EFI_OUT_OF_RESOURCES;
> +             goto fail_3;
> +     }
> +
> +     name_utf16 = efi_convert_string(name);
> +     if (!name_utf16) {
> +             status = EFI_OUT_OF_RESOURCES;
> +             goto fail_4;
> +     }
> +
> +     priv->target = target;
> +
> +     efi_spi_init_part(&priv->part, target, vendor_utf16, part_number_utf16);
> +
> +     efi_spi_init_peripheral(&priv->peripheral, &priv->part,
> +                             bus, target, guid, name_utf16);
> +
> +     efi_spi_append_peripheral(&priv->peripheral, bus);
> +
> +     efi_spi_init_io_protocol(&priv->io_protocol, &priv->peripheral, target);
> +
> +     status = efi_install_multiple_protocol_interfaces(&handle, guid,
> +                                                       &priv->io_protocol,
> +                                                       NULL);

There's a protocols installed here as well as in
efi_spi_protocol_register().  But I don't see those being uninstalled
somewhere.  Shouldn't destroy_efi_spi_bus() call
efi_uninstall_multiple_protocol_interfaces() as well ?


> +     if (status != EFI_SUCCESS)
> +             goto fail_5;
> +
> +     debug("Added EFI_SPI_IO_PROTOCOL for %s with guid %pUl\n", name, guid);
> +     return EFI_SUCCESS;
> +
> +fail_5:
> +     free(name_utf16);
> +fail_4:
> +     free(part_number_utf16);
> +fail_3:
> +     free(vendor_utf16);
> +fail_2:
> +     free(priv);
> +fail_1:
> +     return status;
> +}
> +
> +static struct efi_spi_bus *export_spi_bus(int i)
> +{
> +     struct efi_spi_bus *bus;
> +     struct udevice *dev, *child;
> +     const char *name;
> +     int r;
> +
> +     r = uclass_get_device(UCLASS_SPI, i, &dev);
> +     if (r < 0) {
> +             debug("Failed to get SPI bus %d\n", i);
> +             goto fail_1;
> +     }
> +
> +     name = dev_read_name(dev);
> +     debug("Registering SPI bus %d, name %s\n", i, name);
> +
> +     bus = calloc(1, sizeof(*bus));
> +     if (!bus)
> +             goto fail_1;
> +
> +     bus->friendly_name = efi_convert_string(name);
> +     if (!bus->friendly_name)
> +             goto fail_2;
> +
> +     bus->peripheral_list = NULL;
> +     bus->clock = efi_spi_bus_clock;
> +     bus->clock_parameter = NULL;
> +
> +     /* For the purposes of the current implementation, we do not need to
> +      * expose the hardware device path to users of the SPI I/O protocol.
> +      */
> +     bus->controller_path = &null_device_path;
> +
> +     device_foreach_child(child, dev) {
> +             efi_status_t status = export_spi_peripheral(bus, child);
> +
> +             if (status == EFI_OUT_OF_RESOURCES)
> +                     goto fail_3;
> +     }
> +
> +     return bus;
> +
> +fail_3:
> +     destroy_efi_spi_bus(bus);
> +fail_2:
> +     free(bus);
> +fail_1:
> +     return NULL;
> +}
> +
> +efi_status_t efi_spi_protocol_register(void)
> +{
> +     efi_status_t status;
> +     efi_handle_t handle = NULL;
> +     struct efi_spi_configuration_protocol *proto;
> +     uint i;
> +
> +     debug("Registering EFI_SPI_CONFIGURATION_PROTOCOL\n");
> +
> +     proto = calloc(1, sizeof(*proto));
> +     if (!proto) {
> +             status = EFI_OUT_OF_RESOURCES;
> +             goto fail_1;
> +     }
> +
> +     proto->bus_count = uclass_id_count(UCLASS_SPI);
> +     proto->bus_list = calloc(proto->bus_count, sizeof(*proto->bus_list));
> +     if (!proto->bus_list) {
> +             status = EFI_OUT_OF_RESOURCES;
> +             goto fail_2;
> +     }
> +
> +     for (i = 0; i < proto->bus_count; i++) {
> +             proto->bus_list[i] = export_spi_bus(i);
> +             if (!proto->bus_list[i])
> +                     goto fail_3;
> +     }
> +
> +     status = efi_install_multiple_protocol_interfaces(&handle,
> +                                                       
> &efi_spi_configuration_guid,
> +                                                       proto, NULL);
> +     if (status != EFI_SUCCESS)
> +             goto fail_3;
> +
> +     return EFI_SUCCESS;
> +
> +fail_3:
> +     for (i = 0; i < proto->bus_count; i++) {
> +             if (proto->bus_list[i])
> +                     destroy_efi_spi_bus(proto->bus_list[i]);
> +     }
> +     free(proto->bus_list);
> +fail_2:
> +     free(proto);
> +fail_1:
> +     return status;
> +}
> diff --git a/lib/uuid.c b/lib/uuid.c
> index 465e1ac38f57..3f723b732588 100644
> --- a/lib/uuid.c
> +++ b/lib/uuid.c
> @@ -187,6 +187,10 @@ static const struct {
>               "TCG2",
>               EFI_TCG2_PROTOCOL_GUID,
>               },
> +     {
> +             "SPI Protocol Stack",
> +             EFI_SPI_CONFIGURATION_GUID
> +     },
>       {
>               "System Partition",
>               PARTITION_SYSTEM_GUID
> --
> 2.25.1
>


Regards
/Ilias

Reply via email to