@@ -1539,29 +1539,26 @@ static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void
static int __nvmem_cell_read(struct nvmem_device *nvmem,
struct nvmem_cell_entry *cell,
- void *buf, size_t *len, const char *id, int index)
+ void **buf, size_t *len, const char *id, int index)
{
int rc;
- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
+ rc = nvmem_reg_read(nvmem, cell->offset, *buf, *len);
if (rc)
return rc;
/* shift bits in-place */
if (cell->bit_offset || cell->nbits)
- nvmem_shift_read_buffer_in_place(cell, buf);
+ nvmem_shift_read_buffer_in_place(cell, *buf);
if (cell->read_post_process) {
rc = cell->read_post_process(cell->priv, id, index,
- cell->offset, buf, cell->bytes);
+ cell->offset, buf, len);
if (rc)
return rc;
}
- if (len)
- *len = cell->bytes;
-
return 0;
}
@@ -1578,22 +1575,26 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
{
struct nvmem_device *nvmem = cell->entry->nvmem;
- u8 *buf;
+ size_t bytes = cell->entry->bytes;
+ void *buf;
int rc;
if (!nvmem)
return ERR_PTR(-EINVAL);
- buf = kzalloc(cell->entry->bytes, GFP_KERNEL);
+ buf = kzalloc(bytes, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
+ rc = __nvmem_cell_read(nvmem, cell->entry, &buf, &bytes, cell->id, cell->index);
if (rc) {
kfree(buf);
return ERR_PTR(rc);
}
+ if (len)
+ *len = bytes;
+
return buf;
}
EXPORT_SYMBOL_GPL(nvmem_cell_read);
@@ -1905,11 +1906,15 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
if (!nvmem)
return -EINVAL;
+ /* Cells with read_post_process hook may realloc buffer we can't allow here */
+ if (info->read_post_process)
+ return -EINVAL;
+
rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell);
if (rc)
return rc;
- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
+ rc = __nvmem_cell_read(nvmem, &cell, &buf, &cell.bytes, NULL, 0);
if (rc)
return rc;
@@ -223,15 +223,15 @@ static int imx_ocotp_read(void *context, unsigned int offset,
}
static int imx_ocotp_cell_pp(void *context, const char *id, int index,
- unsigned int offset, void *data, size_t bytes)
+ unsigned int offset, void **data, size_t *bytes)
{
- u8 *buf = data;
+ u8 *buf = *data;
int i;
/* Deal with some post processing of nvmem cell data */
if (id && !strcmp(id, "mac-address"))
- for (i = 0; i < bytes / 2; i++)
- swap(buf[i], buf[bytes - i - 1]);
+ for (i = 0; i < *bytes / 2; i++)
+ swap(buf[i], buf[*bytes - i - 1]);
return 0;
}
@@ -75,10 +75,9 @@ static const char *onie_tlv_cell_name(u8 type)
}
static int onie_tlv_mac_read_cb(void *priv, const char *id, int index,
- unsigned int offset, void *buf,
- size_t bytes)
+ unsigned int offset, void **buf, size_t *bytes)
{
- eth_addr_add(buf, index);
+ eth_addr_add(*buf, index);
return 0;
}
@@ -22,19 +22,19 @@ struct sl28vpd_v1 {
} __packed;
static int sl28vpd_mac_address_pp(void *priv, const char *id, int index,
- unsigned int offset, void *buf,
- size_t bytes)
+ unsigned int offset, void **buf,
+ size_t *bytes)
{
- if (bytes != ETH_ALEN)
+ if (*bytes != ETH_ALEN)
return -EINVAL;
if (index < 0)
return -EINVAL;
- if (!is_valid_ether_addr(buf))
+ if (!is_valid_ether_addr(*buf))
return -EINVAL;
- eth_addr_add(buf, index);
+ eth_addr_add(*buf, index);
return 0;
}
@@ -19,9 +19,8 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
void *val, size_t bytes);
/* used for vendor specific post processing of cell data */
-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
- unsigned int offset, void *buf,
- size_t bytes);
+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, unsigned int offset,
+ void **buf, size_t *bytes);
enum nvmem_type {
NVMEM_TYPE_UNKNOWN = 0,