Message ID | 1573115572-13513-75-git-send-email-biju.das@bp.renesas.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | Add RZ/G1C SD/eMMC support | expand |
Hi! > From: Chris Brandt <chris.brandt@renesas.com> > > commit b5dd7985e8d3357ff9537c0be231190ab1a131fe upstream. > > commit 9c284c41c0886f09e75c323a16278b6d353b0b4a upstream. > > The existing code gives an incorrect pointer value. > The buffer pointer 'buf' was of type unsigned short *, and 'count' was a > number in bytes. A cast of buf should have been used. > > However, instead of casting, just change the code to use u32 > pointers. Yep, I see, nasty; silent data corruption. Could this be merged to the patch that introduces the problem, or the original patch somehow modified that it will not corrupt data ... for example during bisection? > +++ b/drivers/mmc/host/tmio_mmc_core.c > @@ -446,30 +446,29 @@ static void tmio_mmc_transfer_data(struct tmio_mmc_host *host, > * Transfer the data > */ > if (host->pdata->flags & TMIO_MMC_32BIT_DATA_PORT) { > - u8 data[4] = { }; > + u32 data = 0; > + u32 *buf32 = (u32 *)buf; > > if (is_read) > - sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf, > + sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, buf32, > count >> 2); > else > - sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf, > + sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, buf32, > count >> 2); > > /* if count was multiple of 4 */ > if (!(count & 0x3)) > return; > > - buf8 = (u8 *)(buf + (count >> 2)); > + buf32 += count >> 2; > count %= 4; Can we do count &= 0x3, to keep style of if () above? Actually you can do count &= 0x3; if (!count) return; Plus, there's code handling 16 bit case just below this; it is different in style, and by using *buf8 = sd_ctrl_read16(host, CTL_SD_DATA_PORT) & 0xff; instead of read16_rep(), it is buggy on big endian (as comment says). Perhaps synchronizing to similar, non-buggy version would be good? Best regards, Pavel
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index 43209ea28..b6500a6 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -446,30 +446,29 @@ static void tmio_mmc_transfer_data(struct tmio_mmc_host *host, * Transfer the data */ if (host->pdata->flags & TMIO_MMC_32BIT_DATA_PORT) { - u8 data[4] = { }; + u32 data = 0; + u32 *buf32 = (u32 *)buf; if (is_read) - sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf, + sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, buf32, count >> 2); else - sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf, + sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, buf32, count >> 2); /* if count was multiple of 4 */ if (!(count & 0x3)) return; - buf8 = (u8 *)(buf + (count >> 2)); + buf32 += count >> 2; count %= 4; if (is_read) { - sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, - (u32 *)data, 1); - memcpy(buf8, data, count); + sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, &data, 1); + memcpy(buf32, &data, count); } else { - memcpy(data, buf8, count); - sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, - (u32 *)data, 1); + memcpy(&data, buf32, count); + sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, &data, 1); } return;