On 02/17/2020 01:40 AM, Tudor.Ambarus@xxxxxxxxxxxxx wrote: > Looks good. Just a nit below that I can fix it when applying. Let me know if > you're ok with the change. > > On Monday, January 27, 2020 10:28:05 PM EET Sergei Shtylyov wrote: >> EXTERNAL EMAIL: Do not click links or open attachments unless you know the >> content is safe >> >> spi_nor_spimem_xfer_data() being a helper function for the data reads/ >> writes contains 3 fragments that depend on the data direction; and I'm >> going to add another one to call the SPI dirmap API... >> I think this function should be split so that the common fragments are >> put into 2 functions, spi_nor_spimem_bounce() and spi_nor_spimem_exec_op() >> called from spi_nor_spimem_{read|write}_data(), and the data direction >> dependent bits moved back into those read/write functions -- that way we >> would be able to avoid *goto*s otherwise needed in the next patch adding >> the SPI dirmap support... >> >> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@xxxxxxxxxxxxxxxxxx> >> >> --- >> Changes in version 4: >> - new patch. >> >> drivers/mtd/spi-nor/spi-nor.c | 91 >> +++++++++++++++++++++++------------------- 1 file changed, 51 >> insertions(+), 40 deletions(-) >> >> Index: linux/drivers/mtd/spi-nor/spi-nor.c >> =================================================================== >> --- linux.orig/drivers/mtd/spi-nor/spi-nor.c >> +++ linux/drivers/mtd/spi-nor/spi-nor.c >> @@ -246,55 +246,45 @@ struct flash_info { >> #define JEDEC_MFR(info) ((info)->id[0]) >> >> /** >> - * spi_nor_spimem_xfer_data() - helper function to read/write data to >> - * flash's memory region >> + * spi_nor_spimem_bounce() - check if a bounce buffer is needed for the >> data + * transfer >> * @nor: pointer to 'struct spi_nor' >> * @op: pointer to 'struct spi_mem_op' template for transfer >> * >> - * Return: number of bytes transferred on success, -errno otherwise >> + * If we have to use the bounce buffer, the data field in @op will be >> updated. + * >> + * Return: true if the bounce buffer is needed, false if not >> */ >> -static ssize_t spi_nor_spimem_xfer_data(struct spi_nor *nor, >> - struct spi_mem_op *op) >> +static bool spi_nor_spimem_bounce(struct spi_nor *nor, struct spi_mem_op >> *op) { >> - bool usebouncebuf = false; >> - void *rdbuf = NULL; >> - const void *buf; >> - int ret; >> - >> - if (op->data.dir == SPI_MEM_DATA_IN) >> - buf = op->data.buf.in; >> - else >> - buf = op->data.buf.out; >> - >> - if (object_is_on_stack(buf) || !virt_addr_valid(buf)) >> - usebouncebuf = true; >> - >> - if (usebouncebuf) { >> + /* op->data.buf.in occupies the same memory as op->data.buf.out */ >> + if (object_is_on_stack(op->data.buf.in) || >> + !virt_addr_valid(op->data.buf.in)) { >> if (op->data.nbytes > nor->bouncebuf_size) >> op->data.nbytes = nor->bouncebuf_size; >> - >> - if (op->data.dir == SPI_MEM_DATA_IN) { >> - rdbuf = op->data.buf.in; >> - op->data.buf.in = nor->bouncebuf; >> - } else { >> - op->data.buf.out = nor->bouncebuf; >> - memcpy(nor->bouncebuf, buf, >> - op->data.nbytes); >> - } >> + op->data.buf.in = nor->bouncebuf; >> + return true; >> } >> >> - ret = spi_mem_adjust_op_size(nor->spimem, op); >> - if (ret) >> - return ret; >> - >> - ret = spi_mem_exec_op(nor->spimem, op); >> - if (ret) >> - return ret; >> + return false; >> +} >> + >> +/** >> + * spi_nor_spimem_exec_op() - execute a memory operation >> + * @nor: pointer to 'struct spi_nor' >> + * @op: pointer to 'struct spi_mem_op' template for transfer >> + * >> + * Return: 0 on success, -error otherwise. >> + */ >> +static int spi_nor_spimem_exec_op(struct spi_nor *nor, struct spi_mem_op >> *op) +{ >> + int error; >> >> - if (usebouncebuf && op->data.dir == SPI_MEM_DATA_IN) >> - memcpy(rdbuf, nor->bouncebuf, op->data.nbytes); >> + error = spi_mem_adjust_op_size(nor->spimem, op); >> + if (error) >> + return error; >> >> - return op->data.nbytes; >> + return spi_mem_exec_op(nor->spimem, op); >> } >> >> /** [...] >> @@ -364,6 +365,8 @@ static ssize_t spi_nor_spimem_write_data >> SPI_MEM_OP_ADDR(nor->addr_width, to, 1), >> SPI_MEM_OP_NO_DUMMY, >> SPI_MEM_OP_DATA_OUT(len, buf, 1)); >> + bool usebouncebuf; >> + int error; >> >> op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto); >> op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto); @@ >> -372,7 +375,15 @@ static ssize_t spi_nor_spimem_write_data >> if (nor->program_opcode == SPINOR_OP_AAI_WP && >> nor->sst_write_second) op.addr.nbytes = 0; >> >> - return spi_nor_spimem_xfer_data(nor, &op); >> + usebouncebuf = spi_nor_spimem_bounce(nor, &op); >> + if (usebouncebuf) >> + memcpy(nor->bouncebuf, buf, op.data.nbytes); > > How about memcpy(nor->bouncebuf, buf, len); instead? spi_nor_spimem_bounce() changes op.data.nbytes iff the original buffer is larger than the bounce buffer. I don't want to copy the data which I'm unable to write put anyway. > spi_nor_spimem_bounce() does not modify op.data.nbytes. Surely it does! > Using len is more > straight forward than op.data.bytes because the reader doesn't have to verify > if length was updated in spi_nor_spimem_bounce() or not. Sorry, I can't agree with your analysis... > Cheers, > ta MBR, Sergei ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/