sfc: Use fixed-size buffers for MCDI NVRAM requests
authorBen Hutchings <bhutchings@solarflare.com>
Mon, 25 Jan 2010 23:49:59 +0000 (15:49 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Jan 2010 23:49:59 +0000 (15:49 -0800)
The low-level MCDI code always uses 32-bit MMIO operations, and
callers must pad input and output buffers to multiples of 4 bytes.
The MCDI NVRAM functions are not doing this.  Also, their buffers are
declared as variable-length arrays with no explicit maximum length.

Switch to a fixed buffer size based on the chunk size used by the
MTD driver (which is a multiple of 4).

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sfc/mcdi.c
drivers/net/sfc/mcdi.h
drivers/net/sfc/mtd.c

index 0d4eba7266ec3396a336a8be0041e3a8179ee9b1..9f035b9f03503245ca38c44d058cf350958d3884 100644 (file)
@@ -804,7 +804,7 @@ int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
                        loff_t offset, u8 *buffer, size_t length)
 {
        u8 inbuf[MC_CMD_NVRAM_READ_IN_LEN];
-       u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(length)];
+       u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
        size_t outlen;
        int rc;
 
@@ -828,7 +828,7 @@ fail:
 int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
                           loff_t offset, const u8 *buffer, size_t length)
 {
-       u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(length)];
+       u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
        int rc;
 
        MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
@@ -838,7 +838,8 @@ int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
 
        BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
 
-       rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf, sizeof(inbuf),
+       rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
+                         ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
                          NULL, 0, NULL);
        if (rc)
                goto fail;
index de916728c2e38d0bb308a7f6a6950118c7481cc0..10ce98f4c0fb40d3d466986d53c0a8f0228ca870 100644 (file)
@@ -111,6 +111,7 @@ extern int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
 extern int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
                                loff_t offset, const u8 *buffer,
                                size_t length);
+#define EFX_MCDI_NVRAM_LEN_MAX 128
 extern int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
                                loff_t offset, size_t length);
 extern int efx_mcdi_nvram_update_finish(struct efx_nic *efx,
index 3a464529a46bd64c6e8548b6c6ac6dab29976576..407bbaddfea6e88a95fcd5a869f6715aae4511a5 100644 (file)
@@ -23,7 +23,6 @@
 #include "mcdi_pcol.h"
 
 #define EFX_SPI_VERIFY_BUF_LEN 16
-#define EFX_MCDI_CHUNK_LEN 128
 
 struct efx_mtd_partition {
        struct mtd_info mtd;
@@ -428,7 +427,7 @@ static int siena_mtd_read(struct mtd_info *mtd, loff_t start,
        int rc = 0;
 
        while (offset < end) {
-               chunk = min_t(size_t, end - offset, EFX_MCDI_CHUNK_LEN);
+               chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
                rc = efx_mcdi_nvram_read(efx, part->mcdi.nvram_type, offset,
                                         buffer, chunk);
                if (rc)
@@ -491,7 +490,7 @@ static int siena_mtd_write(struct mtd_info *mtd, loff_t start,
        }
 
        while (offset < end) {
-               chunk = min_t(size_t, end - offset, EFX_MCDI_CHUNK_LEN);
+               chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
                rc = efx_mcdi_nvram_write(efx, part->mcdi.nvram_type, offset,
                                          buffer, chunk);
                if (rc)