get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/806933/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 806933,
    "url": "http://patchwork.ozlabs.org/api/patches/806933/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/skiboot/patch/20170829041922.4193-1-wak@google.com/",
    "project": {
        "id": 44,
        "url": "http://patchwork.ozlabs.org/api/projects/44/?format=api",
        "name": "skiboot firmware development",
        "link_name": "skiboot",
        "list_id": "skiboot.lists.ozlabs.org",
        "list_email": "skiboot@lists.ozlabs.org",
        "web_url": "http://github.com/open-power/skiboot",
        "scm_url": "http://github.com/open-power/skiboot",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170829041922.4193-1-wak@google.com>",
    "list_archive_url": null,
    "date": "2017-08-29T04:19:22",
    "name": "blocklevel_info: Refactor the passing of output data",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "57fe57339b068c434877dd8e17697b4dd15bbf77",
    "submitter": {
        "id": 70409,
        "url": "http://patchwork.ozlabs.org/api/people/70409/?format=api",
        "name": "William Kennington",
        "email": "wak@google.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/skiboot/patch/20170829041922.4193-1-wak@google.com/mbox/",
    "series": [
        {
            "id": 296,
            "url": "http://patchwork.ozlabs.org/api/series/296/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/skiboot/list/?series=296",
            "date": "2017-08-29T04:19:22",
            "name": "blocklevel_info: Refactor the passing of output data",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/296/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/806933/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/806933/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "skiboot@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "skiboot@lists.ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xhFlf0q40z9t2v\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 29 Aug 2017 14:19:42 +1000 (AEST)",
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xhFld6vG3zDqY8\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 29 Aug 2017 14:19:41 +1000 (AEST)",
            "from mail-pf0-x249.google.com (mail-pf0-x249.google.com\n\t[IPv6:2607:f8b0:400e:c00::249])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3xhFlP5cWbzDqMY\n\tfor <skiboot@lists.ozlabs.org>; Tue, 29 Aug 2017 14:19:29 +1000 (AEST)",
            "by mail-pf0-x249.google.com with SMTP id 27so5864937pfh.11\n\tfor <skiboot@lists.ozlabs.org>; Mon, 28 Aug 2017 21:19:29 -0700 (PDT)"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=google.com header.i=@google.com\n\theader.b=\"IoKlhonL\"; dkim-atps=neutral",
            "lists.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=google.com header.i=@google.com\n\theader.b=\"IoKlhonL\"; dkim-atps=neutral",
            "lists.ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=google.com header.i=@google.com\n\theader.b=\"IoKlhonL\"; dkim-atps=neutral"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n\ts=20161025; \n\th=mime-version:date:message-id:subject:from:to:cc;\n\tbh=ocxW0r3z6dqijsu2AVl0nNOFTzqupnOeE4J+qXPhE74=;\n\tb=IoKlhonLqBOi9SZwmfrNSoR3srRjm+o3mkKVJAX31E1y09CIkpa31xLlg7ydmDKKM1\n\taDRMSkhx9d1FyV6RKJqMWQqdDIMrDG6dA1Ozsw8nWsD7o4HAvOQPmmdzM2jf7HmVdQHL\n\ts5ncXx9SAnzeMYAOcGO+TWGwK0oAfAIqLqqgkSuecyvB4V9gjHF8oJQ1X7jQpnDvjkPG\n\tImNfwGbf8UxU9Nn+0ZmGj/+UmW+aOhM4bwYFZIZxhmQq2Z+o1zBTcYsu1HLmj10E639o\n\tRTdz8cAYGCWtx1pkUESGof+dOIKLPE0tgIBQibO0cuVnAb0AsI3nIDkJLhegAbwmDSmr\n\ttIFw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:date:message-id:subject:from:to:cc; \n\tbh=ocxW0r3z6dqijsu2AVl0nNOFTzqupnOeE4J+qXPhE74=;\n\tb=O8Z5YZdHiQXG2DaLE3L3POhqWstOO1zeq3qq8lzOx8fI/xJUrIwGZOu+M6D2kmLxwZ\n\tXlyYt7Qa12BGgewiT6sQE2mW3ziewxeatfEl5QJfgtPwKHbzUfTUXQ4ADzug6xzVbpw6\n\tIs8WLoWNWaPQTgqNkedlg+8DzckB94+xvIbjQwxtzw8a/kq9FCx9VX8kLqg1diCbuTJ1\n\tzj9wvfGt4stFboWJH2Ctozyuz1DmZqDbmW22SQKZjS9DjbeZFLTla32FBjzGj6gmu/H/\n\tZNm3jYvSQqQQSv0ES9p93DnRoXhsOo31aYh2ZfcGtsAQ0QSPETfjK7dckwfJXSgqrEjs\n\tMBdg==",
        "X-Gm-Message-State": "AHYfb5h5UrH3F2zZyiEKPVC+OUJiWIG1uhNUDYW6+Ng1TD3ENsoMHRJk\n\tOrPSNdgKnOAaoSfAdUljh8sA8iyshAYNU5nh+vUaEAwbXHfmvnSQEVx0XdE2VmE5yVhH+S7MD2P\n\tIh4oZyu8aby9TIZK5htHdU6J1gmQzO9Yg3JlwNir8BJ5jkMU=",
        "X-Google-Smtp-Source": "ADKCNb5Oi+ybQXVmbqJym5xh6i4Nj4TGR5yAGN114wgv+4zz8i+XcQ2i16LPHcRvoOa+vh2WzI+we5k=",
        "MIME-Version": "1.0",
        "X-Received": "by 10.99.1.78 with SMTP id 75mr1979348pgb.180.1503980366625; Mon,\n\t28 Aug 2017 21:19:26 -0700 (PDT)",
        "Date": "Mon, 28 Aug 2017 21:19:22 -0700",
        "Message-Id": "<20170829041922.4193-1-wak@google.com>",
        "X-Mailer": "git-send-email 2.13.1",
        "From": "\"William A. Kennington III\" <wak@google.com>",
        "To": "skiboot@lists.ozlabs.org",
        "Subject": "[Skiboot] [PATCH] blocklevel_info: Refactor the passing of output\n\tdata",
        "X-BeenThere": "skiboot@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "Mailing list for skiboot development <skiboot.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/skiboot/>",
        "List-Post": "<mailto:skiboot@lists.ozlabs.org>",
        "List-Help": "<mailto:skiboot-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org",
        "Sender": "\"Skiboot\"\n\t<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>"
    },
    "content": "This changes refactors all of the output variables from flash_get_info\ninto a new output struct. Callers now supply the info struct, and always\nget all of the info with each call. There are never any allocations done\nby this function so it shouldn't be much slower to always populate all\nof the information.\n\nSigned-off-by: William A. Kennington III <wak@google.com>\n---\n core/flash.c                           | 15 +++++------\n external/common/arch_flash_arm.c       |  6 ++---\n external/common/arch_flash_common.c    |  6 ++---\n external/gard/gard.c                   | 10 +++----\n external/opal-prd/pnor.c               | 12 ++++-----\n external/opal-prd/pnor.h               |  3 +--\n external/opal-prd/test/test_pnor_ops.c |  7 +++--\n external/pflash/pflash.c               | 46 ++++++++++++++++----------------\n libflash/blocklevel.c                  | 35 ++++++++++++-------------\n libflash/blocklevel.h                  | 16 +++++++++---\n libflash/file.c                        | 48 ++++++++++++++--------------------\n libflash/libffs.c                      |  8 +++---\n libflash/libflash.c                    | 15 +++++------\n libflash/mbox-flash.c                  | 19 ++++----------\n libflash/test/test-flash.c             |  6 ++---\n platforms/mambo/mambo.c                | 15 ++++-------\n 16 files changed, 125 insertions(+), 142 deletions(-)",
    "diff": "diff --git a/core/flash.c b/core/flash.c\nindex 53e6eba08..35a0c4c32 100644\n--- a/core/flash.c\n+++ b/core/flash.c\n@@ -254,21 +254,20 @@ static int num_flashes(void)\n \n int flash_register(struct blocklevel_device *bl)\n {\n-\tuint64_t size;\n-\tuint32_t block_size;\n+\tstruct blocklevel_info bl_info;\n \tstruct ffs_handle *ffs;\n \tstruct dt_node *node;\n \tstruct flash *flash;\n-\tconst char *name;\n \tint rc;\n \n-\trc = blocklevel_get_info(bl, &name, &size, &block_size);\n+\trc = blocklevel_get_info(bl, &bl_info);\n \tif (rc)\n \t\treturn rc;\n \n \tprlog(PR_INFO, \"FLASH: registering flash device %s \"\n \t\t\t\"(size 0x%llx, blocksize 0x%x)\\n\",\n-\t\t\tname ?: \"(unnamed)\", size, block_size);\n+\t\t\tbl_info.name ? bl_info.name : \"(unnamed)\", bl_info.size,\n+\t\t\tbl_info.erase_granule);\n \n \tlock(&flash_lock);\n \n@@ -281,8 +280,8 @@ int flash_register(struct blocklevel_device *bl)\n \n \tflash->busy = false;\n \tflash->bl = bl;\n-\tflash->size = size;\n-\tflash->block_size = block_size;\n+\tflash->size = bl_info.size;\n+\tflash->block_size = bl_info.erase_granule;\n \tflash->id = num_flashes();\n \n \tlist_add(&flashes, &flash->list);\n@@ -302,7 +301,7 @@ int flash_register(struct blocklevel_device *bl)\n \n \tnode = flash_add_dt_node(flash, flash->id);\n \n-\tsetup_system_flash(flash, node, name, ffs);\n+\tsetup_system_flash(flash, node, bl_info.name, ffs);\n \n \tif (ffs)\n \t\tffs_close(ffs);\ndiff --git a/external/common/arch_flash_arm.c b/external/common/arch_flash_arm.c\nindex 3cdd41ded..ac43de0c4 100644\n--- a/external/common/arch_flash_arm.c\n+++ b/external/common/arch_flash_arm.c\n@@ -303,13 +303,13 @@ int arch_flash_erase_chip(struct blocklevel_device *bl)\n \tif (!arch_data.flash_chip) {\n \t\t/* Just assume its a regular erase */\n \t\tint rc;\n-\t\tuint64_t total_size;\n+\t\tstruct blocklevel_info bl_info;\n \n-\t\trc = blocklevel_get_info(bl, NULL, &total_size, NULL);\n+\t\trc = blocklevel_get_info(bl, &bl_info);\n \t\tif (rc)\n \t\t\treturn rc;\n \n-\t\treturn blocklevel_erase(bl, 0, total_size);\n+\t\treturn blocklevel_erase(bl, 0, bl_info.size);\n \t}\n \n \treturn flash_erase_chip(arch_data.flash_chip);\ndiff --git a/external/common/arch_flash_common.c b/external/common/arch_flash_common.c\nindex 6bce7e1ba..41239662a 100644\n--- a/external/common/arch_flash_common.c\n+++ b/external/common/arch_flash_common.c\n@@ -31,13 +31,13 @@\n int __attribute__((weak)) arch_flash_erase_chip(struct blocklevel_device *bl)\n {\n \tint rc;\n-\tuint64_t total_size;\n+\tstruct blocklevel_info bl_info;\n \n-\trc = blocklevel_get_info(bl, NULL, &total_size, NULL);\n+\trc = blocklevel_get_info(bl, &bl_info);\n \tif (rc)\n \t\treturn rc;\n \n-\treturn blocklevel_erase(bl, 0, total_size);\n+\treturn blocklevel_erase(bl, 0, bl_info.size);\n }\n \n int __attribute__((weak,const)) arch_flash_4b_mode(struct blocklevel_device *bl, int set_4b)\ndiff --git a/external/gard/gard.c b/external/gard/gard.c\nindex c5cb93b88..3946cad6f 100644\n--- a/external/gard/gard.c\n+++ b/external/gard/gard.c\n@@ -596,7 +596,7 @@ int main(int argc, char **argv)\n \tconst char *action, *progname;\n \tchar *filename = NULL;\n \tstruct gard_ctx _ctx, *ctx;\n-\tuint64_t bl_size;\n+\tstruct blocklevel_info bl_info;\n \tint rc, i = 0;\n \tbool part = 0;\n \tbool ecc = 0;\n@@ -665,17 +665,17 @@ int main(int argc, char **argv)\n \t\tgoto out_free;\n \t}\n \n-\trc = blocklevel_get_info(ctx->bl, NULL, &bl_size, NULL);\n+\trc = blocklevel_get_info(ctx->bl, &bl_info);\n \tif (rc)\n \t\tgoto out;\n \n-\tif (bl_size > UINT_MAX) {\n+\tif (bl_info.size > UINT_MAX) {\n \t\tfprintf(stderr, \"MTD device bigger than %i: size: %\" PRIu64 \"\\n\",\n-\t\t\tUINT_MAX, bl_size);\n+\t\t\tUINT_MAX, bl_info.size);\n \t\trc = EXIT_FAILURE;\n \t\tgoto out;\n \t}\n-\tctx->f_size = bl_size;\n+\tctx->f_size = bl_info.size;\n \n \tif (!part) {\n \t\trc = ffs_init(0, ctx->f_size, ctx->bl, &ctx->ffs, 1);\ndiff --git a/external/opal-prd/pnor.c b/external/opal-prd/pnor.c\nindex c032421d1..afb6ccd1f 100644\n--- a/external/opal-prd/pnor.c\n+++ b/external/opal-prd/pnor.c\n@@ -64,13 +64,13 @@ int pnor_init(struct pnor *pnor)\n \t\treturn -1;\n \t}\n \n-\trc = blocklevel_get_info(pnor->bl, NULL, &(pnor->size), &(pnor->erasesize));\n+\trc = blocklevel_get_info(pnor->bl, &pnor->bl_info);\n \tif (rc) {\n \t\tpr_log(LOG_ERR, \"PNOR: blocklevel_get_info() failed. Can't use PNOR\");\n \t\tgoto out;\n \t}\n \n-\trc = ffs_init(0, pnor->size, pnor->bl, &pnor->ffsh, 0);\n+\trc = ffs_init(0, pnor->bl_info.size, pnor->bl, &pnor->ffsh, 0);\n \tif (rc) {\n \t\tpr_log(LOG_ERR, \"PNOR: Failed to open pnor partition table\");\n \t\tgoto out;\n@@ -121,8 +121,8 @@ static int mtd_write(struct pnor *pnor, void *data, uint64_t offset,\n {\n \tint rc;\n \n-\tif (len > pnor->size || offset > pnor->size ||\n-\t    len + offset > pnor->size)\n+\tif (len > pnor->bl_info.size || offset > pnor->bl_info.size ||\n+\t    len + offset > pnor->bl_info.size)\n \t\treturn -ERANGE;\n \n \trc = blocklevel_smart_write(pnor->bl, offset, data, len);\n@@ -137,8 +137,8 @@ static int mtd_read(struct pnor *pnor, void *data, uint64_t offset,\n {\n \tint rc;\n \n-\tif (len > pnor->size || offset > pnor->size ||\n-\t    len + offset > pnor->size)\n+\tif (len > pnor->bl_info.size || offset > pnor->bl_info.size ||\n+\t    len + offset > pnor->bl_info.size)\n \t\treturn -ERANGE;\n \n \trc = blocklevel_read(pnor->bl, offset, data, len);\ndiff --git a/external/opal-prd/pnor.h b/external/opal-prd/pnor.h\nindex 28571af64..1ee033659 100644\n--- a/external/opal-prd/pnor.h\n+++ b/external/opal-prd/pnor.h\n@@ -7,8 +7,7 @@\n struct pnor {\n \tchar\t\t\t*path;\n \tstruct ffs_handle\t*ffsh;\n-\tuint64_t\t\tsize;\n-\tuint32_t\t\terasesize;\n+\tstruct blocklevel_info bl_info;\n \tstruct blocklevel_device *bl;\n };\n \ndiff --git a/external/opal-prd/test/test_pnor_ops.c b/external/opal-prd/test/test_pnor_ops.c\nindex fd5e2c22a..3743362e1 100644\n--- a/external/opal-prd/test/test_pnor_ops.c\n+++ b/external/opal-prd/test/test_pnor_ops.c\n@@ -130,11 +130,14 @@ int main(int argc, char **argv)\n \tfor (i = 0; i < 2; i++)\n \t\twrite(fd, data, 16);\n \n+\t/* Unused */\n+\tpnor.bl_info.name = NULL;\n+\n \t/* Adjust this if making the file smaller */\n-\tpnor.size = 32;\n+\tpnor.bl_info.size = 32;\n \n \t/* This is fake. Make it smaller than the size */\n-\tpnor.erasesize = 4;\n+\tpnor.bl_info.erase_granule = 4;\n \n \tprintf(\"Write: \");\n \tmemset(data, 'A', sizeof(data));\ndiff --git a/external/pflash/pflash.c b/external/pflash/pflash.c\nindex bfc975fe5..3f501e583 100644\n--- a/external/pflash/pflash.c\n+++ b/external/pflash/pflash.c\n@@ -43,11 +43,9 @@\n \n struct flash_details {\n \tstruct blocklevel_device *bl;\n+\tstruct blocklevel_info bl_info;\n \tint need_relock;\n-\tconst char *name;\n \tuint64_t toc;\n-\tuint64_t total_size;\n-\tuint32_t erase_granule;\n };\n \n /* Full pflash version number (possibly includes gitid). */\n@@ -144,7 +142,7 @@ static struct ffs_handle *open_ffs(struct flash_details *flash)\n \tstruct ffs_handle *ffsh;\n \tint rc;\n \n-\trc = ffs_init(flash->toc, flash->total_size,\n+\trc = ffs_init(flash->toc, flash->bl_info.size,\n \t\t\tflash->bl, &ffsh, 0);\n \tif (rc) {\n \t\tfprintf(stderr, \"Error %d opening ffs !\\n\", rc);\n@@ -166,11 +164,11 @@ static void print_flash_info(struct flash_details *flash)\n \n \tprintf(\"Flash info:\\n\");\n \tprintf(\"-----------\\n\");\n-\tprintf(\"Name          = %s\\n\", flash->name);\n+\tprintf(\"Name          = %s\\n\", flash->bl_info.name);\n \tprintf(\"Total size    = %\" PRIu64 \"MB\\t Flags E:ECC, P:PRESERVED, R:READONLY\\n\",\n-\t\t\tflash->total_size >> 20);\n+\t\t\tflash->bl_info.size >> 20);\n \tprintf(\"Erase granule = %2d%-13sB:BACKUP, F:REPROVISION\\n\",\n-\t\t\tflash->erase_granule >> 10, \"KB\");\n+\t\t\tflash->bl_info.erase_granule >> 10, \"KB\");\n \n \tif (bmc_flash)\n \t\treturn;\n@@ -282,9 +280,11 @@ static int erase_chip(struct flash_details *flash)\n \t * likes the progress bars.\n \t * Lets do an erase block at a time erase then...\n \t */\n-\tprogress_init(flash->total_size);\n-\tfor (pos = 0; pos < flash->total_size; pos += flash->erase_granule) {\n-\t\trc = blocklevel_erase(flash->bl, pos, flash->erase_granule);\n+\tprogress_init(flash->bl_info.size);\n+\tfor (pos = 0; pos < flash->bl_info.size;\n+\t\t\tpos += flash->bl_info.erase_granule) {\n+\t\trc = blocklevel_erase(flash->bl, pos,\n+\t\t\t\tflash->bl_info.erase_granule);\n \t\tif (rc)\n \t\t\tbreak;\n \t\tprogress_tick(pos);\n@@ -303,7 +303,7 @@ static int erase_range(struct flash_details *flash,\n \t\tuint32_t start, uint32_t size, bool will_program,\n \t\tstruct ffs_handle *ffsh, int ffs_index)\n {\n-\tuint32_t done = 0, erase_mask = flash->erase_granule - 1;\n+\tuint32_t done = 0, erase_mask = flash->bl_info.erase_granule - 1;\n \tbool confirm;\n \tint rc;\n \n@@ -326,25 +326,26 @@ static int erase_range(struct flash_details *flash,\n \tif (start & erase_mask) {\n \t\t/* Align to next erase block */\n \t\trc = blocklevel_smart_erase(flash->bl, start,\n-\t\t\t\tflash->erase_granule - (start & erase_mask));\n+\t\t\t\tflash->bl_info.erase_granule - (start & erase_mask));\n \t\tif (rc) {\n \t\t\tfprintf(stderr, \"Failed to blocklevel_smart_erase(): %d\\n\", rc);\n \t\t\treturn 1;\n \t\t}\n-\t\tstart += flash->erase_granule - (start & erase_mask);\n-\t\tsize -= flash->erase_granule - (start & erase_mask);\n-\t\tdone = flash->erase_granule - (start & erase_mask);\n+\t\tstart += flash->bl_info.erase_granule - (start & erase_mask);\n+\t\tsize -= flash->bl_info.erase_granule - (start & erase_mask);\n+\t\tdone = flash->bl_info.erase_granule - (start & erase_mask);\n \t}\n \tprogress_tick(done);\n \twhile (size & ~(erase_mask)) {\n-\t\trc = blocklevel_smart_erase(flash->bl, start, flash->erase_granule);\n+\t\trc = blocklevel_smart_erase(flash->bl, start,\n+\t\t\t\tflash->bl_info.erase_granule);\n \t\tif (rc) {\n \t\t\tfprintf(stderr, \"Failed to blocklevel_smart_erase(): %d\\n\", rc);\n \t\t\treturn 1;\n \t\t}\n-\t\tstart += flash->erase_granule;\n-\t\tsize -= flash->erase_granule;\n-\t\tdone += flash->erase_granule;\n+\t\tstart += flash->bl_info.erase_granule;\n+\t\tsize -= flash->bl_info.erase_granule;\n+\t\tdone += flash->bl_info.erase_granule;\n \t\tprogress_tick(done);\n \t}\n \tif (size) {\n@@ -1003,8 +1004,7 @@ int main(int argc, char *argv[])\n \t\tgoto out;\n \t}\n \n-\trc = blocklevel_get_info(flash.bl, &flash.name,\n-\t\t\t    &flash.total_size, &flash.erase_granule);\n+\trc = blocklevel_get_info(flash.bl, &flash.bl_info);\n \tif (rc) {\n \t\tfprintf(stderr, \"Error %d getting flash info\\n\", rc);\n \t\trc = 1;\n@@ -1025,7 +1025,7 @@ int main(int argc, char *argv[])\n \n \t/* If read specified and no read_size, use flash size */\n \tif (do_read && !read_size && !part_name)\n-\t\tread_size = flash.total_size;\n+\t\tread_size = flash.bl_info.size;\n \n \t/* We have a partition, adjust read/write size if needed */\n \tif (part_name || print_detail) {\n@@ -1087,7 +1087,7 @@ int main(int argc, char *argv[])\n \t\t/* Set address */\n \t\taddress = pstart;\n \t} else if (erase) {\n-\t\tif ((address | write_size) & (flash.erase_granule - 1)) {\n+\t\tif ((address | write_size) & (flash.bl_info.erase_granule - 1)) {\n \t\t\tif (must_confirm) {\n \t\t\t\tprintf(\"ERROR: Erase at 0x%08x for 0x%08x isn't erase block aligned\\n\",\n \t\t\t\t\t\taddress, write_size);\ndiff --git a/libflash/blocklevel.c b/libflash/blocklevel.c\nindex 33d5c5d2f..3955be823 100644\n--- a/libflash/blocklevel.c\n+++ b/libflash/blocklevel.c\n@@ -229,12 +229,11 @@ int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len)\n \treturn rc;\n }\n \n-int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_t *total_size,\n-\t\tuint32_t *erase_granule)\n+int blocklevel_get_info(struct blocklevel_device *bl, struct blocklevel_info *bl_info)\n {\n \tint rc;\n \n-\tif (!bl || !bl->get_info) {\n+\tif (!bl || !bl->get_info || !bl_info) {\n \t\terrno = EINVAL;\n \t\treturn FLASH_ERR_PARM_ERROR;\n \t}\n@@ -243,12 +242,12 @@ int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_\n \tif (rc)\n \t\treturn rc;\n \n-\trc = bl->get_info(bl, name, total_size, erase_granule);\n+\trc = bl->get_info(bl, bl_info);\n \n \t/* Check the validity of what we are being told */\n-\tif (erase_granule && *erase_granule != bl->erase_mask + 1)\n+\tif (bl_info->erase_granule != bl->erase_mask + 1)\n \t\tFL_ERR(\"blocklevel_get_info: WARNING: erase_granule (0x%08x) and erase_mask\"\n-\t\t\t\t\" (0x%08x) don't match\\n\", *erase_granule, bl->erase_mask + 1);\n+\t\t\t\t\" (0x%08x) don't match\\n\", bl_info->erase_granule, bl->erase_mask + 1);\n \n \trelease(bl);\n \n@@ -417,7 +416,7 @@ out:\n \n int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len)\n {\n-\tuint32_t erase_size;\n+\tstruct blocklevel_info bl_info;\n \tconst void *write_buf = buf;\n \tvoid *write_buf_start = NULL;\n \tvoid *erase_buf;\n@@ -435,7 +434,7 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi\n \t\treturn blocklevel_write(bl, pos, buf, len);\n \t}\n \n-\trc = blocklevel_get_info(bl, NULL, NULL, &erase_size);\n+\trc = blocklevel_get_info(bl, &bl_info);\n \tif (rc)\n \t\treturn rc;\n \n@@ -458,7 +457,7 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi\n \t\twrite_buf = write_buf_start;\n \t}\n \n-\terase_buf = malloc(erase_size);\n+\terase_buf = malloc(bl_info.erase_granule);\n \tif (!erase_buf) {\n \t\terrno = ENOMEM;\n \t\trc = FLASH_ERR_MALLOC_FAILED;\n@@ -470,32 +469,32 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi\n \t\tgoto out_free;\n \n \twhile (len > 0) {\n-\t\tuint32_t erase_block = pos & ~(erase_size - 1);\n-\t\tuint32_t block_offset = pos & (erase_size - 1);\n-\t\tuint32_t size = erase_size > len ? len : erase_size;\n+\t\tuint32_t erase_block = pos & ~(bl_info.erase_granule - 1);\n+\t\tuint32_t block_offset = pos & (bl_info.erase_granule - 1);\n+\t\tuint32_t size = bl_info.erase_granule > len ? len : bl_info.erase_granule;\n \t\tint cmp;\n \n \t\t/* Write crosses an erase boundary, shrink the write to the boundary */\n-\t\tif (erase_size < block_offset + size) {\n-\t\t\tsize = erase_size - block_offset;\n+\t\tif (bl_info.erase_granule < block_offset + size) {\n+\t\t\tsize = bl_info.erase_granule - block_offset;\n \t\t}\n \n-\t\trc = bl->read(bl, erase_block, erase_buf, erase_size);\n+\t\trc = bl->read(bl, erase_block, erase_buf, bl_info.erase_granule);\n \t\tif (rc)\n \t\t\tgoto out;\n \n \t\tcmp = blocklevel_flashcmp(erase_buf + block_offset, write_buf, size);\n \t\tFL_DBG(\"%s: region 0x%08x..0x%08x \", __func__,\n-\t\t\t\terase_block, erase_size);\n+\t\t\t\terase_block, bl_info.erase_granule);\n \t\tif (cmp != 0) {\n \t\t\tFL_DBG(\"needs \");\n \t\t\tif (cmp == -1) {\n \t\t\t\tFL_DBG(\"erase and \");\n-\t\t\t\tbl->erase(bl, erase_block, erase_size);\n+\t\t\t\tbl->erase(bl, erase_block, bl_info.erase_granule);\n \t\t\t}\n \t\t\tFL_DBG(\"write\\n\");\n \t\t\tmemcpy(erase_buf + block_offset, write_buf, size);\n-\t\t\trc = bl->write(bl, erase_block, erase_buf, erase_size);\n+\t\t\trc = bl->write(bl, erase_block, erase_buf, bl_info.erase_granule);\n \t\t\tif (rc)\n \t\t\t\tgoto out;\n \t\t}\ndiff --git a/libflash/blocklevel.h b/libflash/blocklevel.h\nindex ba42c83d0..d2d269054 100644\n--- a/libflash/blocklevel.h\n+++ b/libflash/blocklevel.h\n@@ -34,6 +34,15 @@ enum blocklevel_flags {\n \tWRITE_NEED_ERASE = 1,\n };\n \n+struct blocklevel_info {\n+\t/* name is not owned by this struct and must persist for the\n+\t * liftime of blocklevel_info\n+\t */\n+\tconst char *name;\n+\tuint64_t size;\n+\tuint32_t erase_granule;\n+};\n+\n /*\n  * libffs may be used with different backends, all should provide these for\n  * libflash to get the information it needs\n@@ -45,8 +54,7 @@ struct blocklevel_device {\n \tint (*read)(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len);\n \tint (*write)(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len);\n \tint (*erase)(struct blocklevel_device *bl, uint64_t pos, uint64_t len);\n-\tint (*get_info)(struct blocklevel_device *bl, const char **name, uint64_t *total_size,\n-\t\t\tuint32_t *erase_granule);\n+\tint (*get_info)(struct blocklevel_device *bl, struct blocklevel_info *bl_info);\n \n \t/*\n \t * Keep the erase mask so that blocklevel_erase() can do sanity checking\n@@ -62,8 +70,8 @@ int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint6\n int blocklevel_raw_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len);\n int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len);\n int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len);\n-int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_t *total_size,\n-\t\tuint32_t *erase_granule);\n+\n+int blocklevel_get_info(struct blocklevel_device *bl, struct blocklevel_info *bl_info);\n \n /*\n  * blocklevel_smart_write() performs reads on the data to see if it\ndiff --git a/libflash/file.c b/libflash/file.c\nindex 7065eb4fa..b87679cd1 100644\n--- a/libflash/file.c\n+++ b/libflash/file.c\n@@ -212,6 +212,7 @@ static int get_info_name(struct file_data *file_data, char **name)\n \t}\n \tlpath[len] = '\\0';\n \n+\tfree(*name);\n \t*name = lpath;\n \n \tfree(path);\n@@ -219,8 +220,8 @@ static int get_info_name(struct file_data *file_data, char **name)\n }\n \n \n-static int mtd_get_info(struct blocklevel_device *bl, const char **name,\n-\t\tuint64_t *total_size, uint32_t *erase_granule)\n+static int mtd_get_info(struct blocklevel_device *bl,\n+\t\tstruct blocklevel_info *bl_info)\n {\n \tstruct file_data *file_data = container_of(bl, struct file_data, bl);\n \tstruct mtd_info_user mtd_info;\n@@ -230,24 +231,19 @@ static int mtd_get_info(struct blocklevel_device *bl, const char **name,\n \tif (rc == -1)\n \t\treturn FLASH_ERR_BAD_READ;\n \n-\tif (total_size)\n-\t\t*total_size = mtd_info.size;\n-\n-\tif (erase_granule)\n-\t\t*erase_granule = mtd_info.erasesize;\n+\trc = get_info_name(file_data, &(file_data->name));\n+\tif (rc)\n+\t\treturn rc;\n \n-\tif (name) {\n-\t\trc = get_info_name(file_data, &(file_data->name));\n-\t\tif (rc)\n-\t\t\treturn rc;\n-\t\t*name = file_data->name;\n-\t}\n+\tbl_info->name = file_data->name;\n+\tbl_info->size = mtd_info.size;\n+\tbl_info->erase_granule = mtd_info.erasesize;\n \n \treturn 0;\n }\n \n-static int file_get_info(struct blocklevel_device *bl, const char **name,\n-\t\tuint64_t *total_size, uint32_t *erase_granule)\n+static int file_get_info(struct blocklevel_device *bl,\n+\t\tstruct blocklevel_info *bl_info)\n {\n \tstruct file_data *file_data = container_of(bl, struct file_data, bl);\n \tstruct stat st;\n@@ -256,18 +252,13 @@ static int file_get_info(struct blocklevel_device *bl, const char **name,\n \tif (fstat(file_data->fd, &st))\n \t\treturn FLASH_ERR_PARM_ERROR;\n \n-\tif (total_size)\n-\t\t*total_size = st.st_size;\n-\n-\tif (erase_granule)\n-\t\t*erase_granule = 1;\n+\trc = get_info_name(file_data, &(file_data->name));\n+\tif (rc)\n+\t\treturn rc;\n \n-\tif (name) {\n-\t\trc = get_info_name(file_data, &(file_data->name));\n-\t\tif (rc)\n-\t\t\treturn rc;\n-\t\t*name = file_data->name;\n-\t}\n+\tbl_info->name = file_data->name;\n+\tbl_info->size = st.st_size;\n+\tbl_info->erase_granule = 1;\n \n \treturn 0;\n }\n@@ -315,8 +306,9 @@ int file_init(int fd, struct blocklevel_device **bl)\n \t\tfile_data->bl.erase = &mtd_erase;\n \t\tfile_data->bl.get_info = &mtd_get_info;\n \t\tfile_data->bl.flags = WRITE_NEED_ERASE;\n-\t\tmtd_get_info(&file_data->bl, NULL, NULL, &(file_data->bl.erase_mask));\n-\t\tfile_data->bl.erase_mask--;\n+\t\tstruct blocklevel_info bl_info;\n+\t\tmtd_get_info(&file_data->bl, &bl_info);\n+\t\tfile_data->bl.erase_mask = bl_info.erase_granule - 1;\n \t} else if (!S_ISREG(sbuf.st_mode)) {\n \t\t/* If not a char device or a regular file something went wrong */\n \t\tgoto out;\ndiff --git a/libflash/libffs.c b/libflash/libffs.c\nindex 038f59425..6fc23eee9 100644\n--- a/libflash/libffs.c\n+++ b/libflash/libffs.c\n@@ -216,25 +216,25 @@ int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,\n {\n \tstruct __ffs_hdr blank_hdr;\n \tstruct __ffs_hdr raw_hdr;\n+\tstruct blocklevel_info bl_info;\n \tstruct ffs_handle *f;\n-\tuint64_t total_size;\n \tint rc, i;\n \n \tif (!ffs || !bl)\n \t\treturn FLASH_ERR_PARM_ERROR;\n \t*ffs = NULL;\n \n-\trc = blocklevel_get_info(bl, NULL, &total_size, NULL);\n+\trc = blocklevel_get_info(bl, &bl_info);\n \tif (rc) {\n \t\tFL_ERR(\"FFS: Error %d retrieving flash info\\n\", rc);\n \t\treturn rc;\n \t}\n-\tif (total_size > UINT_MAX)\n+\tif (bl_info.size > UINT_MAX)\n \t\treturn FLASH_ERR_VERIFY_FAILURE;\n \tif ((offset + max_size) < offset)\n \t\treturn FLASH_ERR_PARM_ERROR;\n \n-\tif ((max_size > total_size))\n+\tif ((max_size > bl_info.size))\n \t\treturn FLASH_ERR_PARM_ERROR;\n \n \t/* Read flash header */\ndiff --git a/libflash/libflash.c b/libflash/libflash.c\nindex 38f87b86e..82a2baecc 100644\n--- a/libflash/libflash.c\n+++ b/libflash/libflash.c\n@@ -792,16 +792,15 @@ static int flash_configure(struct flash_chip *c)\n \treturn 0;\n }\n \n-static int flash_get_info(struct blocklevel_device *bl, const char **name,\n-\t\t   uint64_t *total_size, uint32_t *erase_granule)\n+static int flash_get_info(struct blocklevel_device *bl,\n+\t\tstruct blocklevel_info *bl_info)\n {\n \tstruct flash_chip *c = container_of(bl, struct flash_chip, bl);\n-\tif (name)\n-\t\t*name = c->info.name;\n-\tif (total_size)\n-\t\t*total_size = c->tsize;\n-\tif (erase_granule)\n-\t\t*erase_granule = c->min_erase_mask + 1;\n+\n+\tbl_info->name = c->info.name;\n+\tbl_info->size = c->tsize;\n+\tbl_info->erase_granule = c->min_erase_mask + 1;\n+\n \treturn 0;\n }\n \ndiff --git a/libflash/mbox-flash.c b/libflash/mbox-flash.c\nindex 950e24f05..d4200ce53 100644\n--- a/libflash/mbox-flash.c\n+++ b/libflash/mbox-flash.c\n@@ -745,8 +745,8 @@ static int mbox_flash_read(struct blocklevel_device *bl, uint64_t pos,\n \treturn rc;\n }\n \n-static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,\n-\t\tuint64_t *total_size, uint32_t *erase_granule)\n+static int mbox_flash_get_info(struct blocklevel_device *bl,\n+\t\tstruct blocklevel_info *bl_info)\n {\n \tstruct mbox_flash_data *mbox_flash;\n \tstruct bmc_mbox_msg *msg;\n@@ -761,14 +761,7 @@ static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,\n \tif (!msg)\n \t\treturn FLASH_ERR_MALLOC_FAILED;\n \n-\t/*\n-\t * We want to avoid runtime mallocs in skiboot. The expected\n-\t * behavour to uses of libflash is that one can free() the memory\n-\t * returned.\n-\t * NULL will do for now.\n-\t */\n-\tif (name)\n-\t\t*name = NULL;\n+\tbl_info->name = \"pnor_mbox\";\n \n \tmbox_flash->busy = true;\n \trc = msg_send(mbox_flash, msg);\n@@ -784,10 +777,8 @@ static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,\n \n \tmbox_flash->bl.erase_mask = mbox_flash->erase_granule - 1;\n \n-\tif (total_size)\n-\t\t*total_size = mbox_flash->total_size;\n-\tif (erase_granule)\n-\t\t*erase_granule = mbox_flash->erase_granule;\n+\tbl_info->size = mbox_flash->total_size;\n+\tbl_info->erase_granule = mbox_flash->erase_granule;\n \n out:\n \tmsg_free_memory(msg);\ndiff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c\nindex 3f77d6f3e..1ca467bb0 100644\n--- a/libflash/test/test-flash.c\n+++ b/libflash/test/test-flash.c\n@@ -367,9 +367,7 @@ struct spi_flash_ctrl sim_ctrl = {\n int main(void)\n {\n \tstruct blocklevel_device *bl;\n-\tuint64_t total_size;\n-\tuint32_t erase_granule;\n-\tconst char *name;\n+\tstruct blocklevel_info bl_info;\n \tuint16_t *test;\n \tstruct ecc64 *ecc_test;\n \tuint64_t *test64;\n@@ -384,7 +382,7 @@ int main(void)\n \t\tERR(\"flash_init failed with err %d\\n\", rc);\n \t\texit(1);\n \t}\n-\trc = flash_get_info(bl, &name, &total_size, &erase_granule);\n+\trc = flash_get_info(bl, &bl_info);\n \tif (rc) {\n \t\tERR(\"flash_get_info failed with err %d\\n\", rc);\n \t\texit(1);\ndiff --git a/platforms/mambo/mambo.c b/platforms/mambo/mambo.c\nindex cb6e103cc..dd7872a8e 100644\n--- a/platforms/mambo/mambo.c\n+++ b/platforms/mambo/mambo.c\n@@ -125,19 +125,14 @@ static int bogus_disk_erase(struct blocklevel_device *bl __unused,\n \treturn 0; /* NOP */\n }\n \n-static int bogus_disk_get_info(struct blocklevel_device *bl, const char **name,\n-\t\t\t      uint64_t *total_size, uint32_t *erase_granule)\n+static int bogus_disk_get_info(struct blocklevel_device *bl,\n+\t\t\tstruct blocklevel_info *bl_info)\n {\n \tstruct bogus_disk_info *bdi = bl->priv;\n \n-\tif (total_size)\n-\t\t*total_size = bdi->size;\n-\n-\tif (erase_granule)\n-\t\t*erase_granule = BD_SECT_SZ;\n-\n-\tif (name)\n-\t\t*name = \"mambobogus\";\n+\tbl_info->name = \"mambobogus\";\n+\tbl_info->size = bdi->size;\n+\tbl_info->erase_granule = BD_SECT_SZ;\n \n \treturn 0;\n }\n",
    "prefixes": []
}