Re: [PATCH] OF: DT-Overlay configfs interface (v3)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Hi Pantelis,

On Wed, Dec 3, 2014 at 12:23 PM, Pantelis Antoniou
<pantelis.antoniou@xxxxxxxxxxxx> wrote:
> Add a runtime interface to using configfs for generic device tree overlay
> usage. With it its possible to use device tree overlays without having
> to use a per-platform overlay manager.

When loading more than one overlay, I got strange behavior:

    __allocate_fw_buf: fw-r8a7791-koelsch-exio-a-scifb0.dtbo buf=ee27b140
    (NULL device *): firmware: direct-loading firmware
r8a7791-koelsch-exio-a-scifb0.dtbo
    fw_set_page_data: fw-r8a7791-koelsch-exio-a-scifb0.dtbo
buf=ee27b140 data=f0bee000 size=820

    [ loaded overlay is activated!! ]

    __fw_free_buf: fw-r8a7791-koelsch-exio-a-scifb0.dtbo buf=ee27b140
data=f0bee000 size=820
    __allocate_fw_buf: fw-8a7791-koelsch-exio-a-scifb0.dtbo buf=ee3d96c0
    (NULL device *): Direct firmware load for
8a7791-koelsch-exio-a-scifb0.dtbo failed with error -2
    __fw_free_buf: fw-8a7791-koelsch-exio-a-scifb0.dtbo buf=ee3d96c0
data=  (null) size=0

After that:
  - The overlay itself works fine,
  - The "status" file in configfs says "applied".
  - The "path" file in configfs is empty?

Note that an "r" was dropped from the filename in front of the "8a7791".
Hence I suspected some obscure memory corruption bug....


> --- /dev/null
> +++ b/drivers/of/configfs.c
> @@ -0,0 +1,332 @@

> +static int create_overlay(struct cfs_overlay_item *overlay, void *blob)
> +{
> +       int err;
> +
> +       /* unflatten the tree */
> +       of_fdt_unflatten_tree(blob, &overlay->overlay);
> +       if (overlay->overlay == NULL) {
> +               pr_err("%s: failed to unflatten tree\n", __func__);
> +               err = -EINVAL;
> +               goto out_err;
> +       }
> +       pr_debug("%s: unflattened OK\n", __func__);
> +
> +       /* mark it as detached */
> +       of_node_set_flag(overlay->overlay, OF_DETACHED);
> +
> +       /* perform resolution */
> +       err = of_resolve_phandles(overlay->overlay);
> +       if (err != 0) {
> +               pr_err("%s: Failed to resolve tree\n", __func__);
> +               goto out_err;
> +       }
> +       pr_debug("%s: resolved OK\n", __func__);
> +
> +       err = of_overlay_create(overlay->overlay);
> +       if (err < 0) {
> +               pr_err("%s: Failed to create overlay (err=%d)\n",
> +                               __func__, err);
> +               goto out_err;
> +       }
> +       overlay->ov_id = err;
> +
> +out_err:
> +       return err;

This returns either a strict negative error code, or a positive overlay ID.

> +}

> +static ssize_t cfs_overlay_item_path_store(struct cfs_overlay_item *overlay,
> +               const char *page, size_t count)
> +{
> +       const char *p = page;
> +       char *s;
> +       int err;
> +
> +       /* if it's set do not allow changes */
> +       if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
> +               return -EPERM;
> +
> +       /* copy to path buffer (and make sure it's always zero terminated */
> +       count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
> +       overlay->path[sizeof(overlay->path) - 1] = '\0';
> +
> +       /* strip trailing newlines */
> +       s = overlay->path + strlen(overlay->path);
> +       while (s > overlay->path && *--s == '\n')
> +               *s = '\0';
> +
> +       pr_debug("%s: path is '%s'\n", __func__, overlay->path);
> +
> +       err = request_firmware(&overlay->fw, overlay->path, NULL);
> +       if (err != 0)
> +               goto out_err;
> +
> +       err = create_overlay(overlay, (void *)overlay->fw->data);
> +       if (err != 0)

Woops, this test should be "if (err < 0)"!
For the first overlay, err == 0, and everything works fine.
For subsequent overlays, err > 0, and ...

> +               goto out_err;
> +
> +       return count;
> +
> +out_err:
> +
> +       release_firmware(overlay->fw);
> +       overlay->fw = NULL;
> +
> +       overlay->path[0] = '\0';

... the path is cleared...

> +       return err;

...and a positive number is returned, smaller than the passed filename length.
This makes VFS believe the write was truncated, hence it retries, writing only
the remaining part of the filename again. That explains the dropped first
character of the filename, and the firmware load failure.

> +}

> +ssize_t cfs_overlay_item_dtbo_write(struct cfs_overlay_item *overlay,
> +               const void *buf, size_t count)
> +{
> +       int err;
> +
> +       /* if it's set do not allow changes */
> +       if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
> +               return -EPERM;
> +
> +       /* copy the contents */
> +       overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
> +       if (overlay->dtbo == NULL)
> +               return -ENOMEM;
> +
> +       overlay->dtbo_size = count;
> +
> +       err = create_overlay(overlay, overlay->dtbo);
> +       if (err != 0)

Same here: "if (err < 0)"

> +               goto out_err;
> +
> +       return count;
> +
> +out_err:
> +       kfree(overlay->dtbo);
> +       overlay->dtbo = NULL;
> +       overlay->dtbo_size = 0;
> +
> +       return err;
> +}

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux