OSDN Git Service

spi: spi-mem: Adjust op len based on message/transfer size limitations
authorChuanhua Han <chuanhua.han@nxp.com>
Thu, 30 Aug 2018 08:43:24 +0000 (16:43 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Nov 2018 19:08:15 +0000 (11:08 -0800)
commit e757996cafbeb6b71234a17130674bcd8f44c59e upstream.

We need that to adjust the len of the 2nd transfer (called data in
spi-mem) if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory controllers")
Cc: <stable@vger.kernel.org>
Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/spi/spi-mem.c

index e43842c..eb72dba 100644 (file)
@@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
        struct spi_controller *ctlr = mem->spi->controller;
+       size_t len;
+
+       len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
 
        if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
                return ctlr->mem_ops->adjust_op_size(mem, op);
 
+       if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+               if (len > spi_max_transfer_size(mem->spi))
+                       return -EINVAL;
+
+               op->data.nbytes = min3((size_t)op->data.nbytes,
+                                      spi_max_transfer_size(mem->spi),
+                                      spi_max_message_size(mem->spi) -
+                                      len);
+               if (!op->data.nbytes)
+                       return -EINVAL;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);