Skip to content

Commit ea0efd6

Browse files
shimodaygregkh
authored andcommitted
usb: renesas_usbhs: getting residue from callback_result
This driver assumed that dmaengine_tx_status() could return the residue even if the transfer was completed. However, this was not correct usage [1] and this caused to break getting the residue after the commit 24461d9 ("dmaengine: virt-dma: Fix access after free in vchan_complete()") actually. So, this is possible to get wrong received size if the usb controller gets a short packet. For example, g_zero driver causes "bad OUT byte" errors. The usb-dmac driver will support the callback_result, so this driver can use it to get residue correctly. Note that even if the usb-dmac driver has not supported the callback_result yet, this patch doesn't cause any side-effects. [1] https://lore.kernel.org/dmaengine/20200616165550.GP2324254@vkoul-mobl/ Reported-by: Hien Dang <[email protected]> Fixes: 24461d9 ("dmaengine: virt-dma: Fix access after free in vchan_complete()") Signed-off-by: Yoshihiro Shimoda <[email protected]> Link: https://lore.kernel.org/r/1592482277-19563-1-git-send-email-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ad38beb commit ea0efd6

File tree

2 files changed

+14
-11
lines changed

2 files changed

+14
-11
lines changed

drivers/usb/renesas_usbhs/fifo.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,8 @@ static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
803803
return info->dma_map_ctrl(chan->device->dev, pkt, map);
804804
}
805805

806-
static void usbhsf_dma_complete(void *arg);
806+
static void usbhsf_dma_complete(void *arg,
807+
const struct dmaengine_result *result);
807808
static void usbhsf_dma_xfer_preparing(struct usbhs_pkt *pkt)
808809
{
809810
struct usbhs_pipe *pipe = pkt->pipe;
@@ -813,6 +814,7 @@ static void usbhsf_dma_xfer_preparing(struct usbhs_pkt *pkt)
813814
struct dma_chan *chan;
814815
struct device *dev = usbhs_priv_to_dev(priv);
815816
enum dma_transfer_direction dir;
817+
dma_cookie_t cookie;
816818

817819
fifo = usbhs_pipe_to_fifo(pipe);
818820
if (!fifo)
@@ -827,11 +829,11 @@ static void usbhsf_dma_xfer_preparing(struct usbhs_pkt *pkt)
827829
if (!desc)
828830
return;
829831

830-
desc->callback = usbhsf_dma_complete;
831-
desc->callback_param = pipe;
832+
desc->callback_result = usbhsf_dma_complete;
833+
desc->callback_param = pkt;
832834

833-
pkt->cookie = dmaengine_submit(desc);
834-
if (pkt->cookie < 0) {
835+
cookie = dmaengine_submit(desc);
836+
if (cookie < 0) {
835837
dev_err(dev, "Failed to submit dma descriptor\n");
836838
return;
837839
}
@@ -1152,12 +1154,10 @@ static size_t usbhs_dma_calc_received_size(struct usbhs_pkt *pkt,
11521154
struct dma_chan *chan, int dtln)
11531155
{
11541156
struct usbhs_pipe *pipe = pkt->pipe;
1155-
struct dma_tx_state state;
11561157
size_t received_size;
11571158
int maxp = usbhs_pipe_get_maxpacket(pipe);
11581159

1159-
dmaengine_tx_status(chan, pkt->cookie, &state);
1160-
received_size = pkt->length - state.residue;
1160+
received_size = pkt->length - pkt->dma_result->residue;
11611161

11621162
if (dtln) {
11631163
received_size -= USBHS_USB_DMAC_XFER_SIZE;
@@ -1363,13 +1363,16 @@ static int usbhsf_irq_ready(struct usbhs_priv *priv,
13631363
return 0;
13641364
}
13651365

1366-
static void usbhsf_dma_complete(void *arg)
1366+
static void usbhsf_dma_complete(void *arg,
1367+
const struct dmaengine_result *result)
13671368
{
1368-
struct usbhs_pipe *pipe = arg;
1369+
struct usbhs_pkt *pkt = arg;
1370+
struct usbhs_pipe *pipe = pkt->pipe;
13691371
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
13701372
struct device *dev = usbhs_priv_to_dev(priv);
13711373
int ret;
13721374

1375+
pkt->dma_result = result;
13731376
ret = usbhsf_pkt_handler(pipe, USBHSF_PKT_DMA_DONE);
13741377
if (ret < 0)
13751378
dev_err(dev, "dma_complete run_error %d : %d\n",

drivers/usb/renesas_usbhs/fifo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct usbhs_pkt {
5050
struct usbhs_pkt *pkt);
5151
struct work_struct work;
5252
dma_addr_t dma;
53-
dma_cookie_t cookie;
53+
const struct dmaengine_result *dma_result;
5454
void *buf;
5555
int length;
5656
int trans;

0 commit comments

Comments
 (0)