mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
usb_host: backport xhci bounce-buffer fix
This commit backports the Linux upstream commit (d4a6106) [*] that introduces a check to prevent the sglist from being used unconditionally. [*] 'xhci: fix bounce buffer usage for non-sg list case' Fixes #4116.
This commit is contained in:
parent
c7b2314d23
commit
d0f084d449
@ -348,7 +348,34 @@ diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
|
||||
index daa94c3..028891a 100644
|
||||
--- a/drivers/usb/host/xhci-ring.c
|
||||
+++ b/drivers/usb/host/xhci-ring.c
|
||||
@@ -1141,7 +1141,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
|
||||
@@ -656,6 +656,7 @@
|
||||
struct device *dev = xhci_to_hcd(xhci)->self.controller;
|
||||
struct xhci_segment *seg = td->bounce_seg;
|
||||
struct urb *urb = td->urb;
|
||||
+ size_t len;
|
||||
|
||||
if (!ring || !seg || !urb)
|
||||
return;
|
||||
@@ -667,8 +668,16 @@
|
||||
}
|
||||
|
||||
/* for in tranfers we need to copy the data from bounce to sg */
|
||||
- sg_pcopy_from_buffer(urb->sg, urb->num_mapped_sgs, seg->bounce_buf,
|
||||
- seg->bounce_len, seg->bounce_offs);
|
||||
+ if (urb->num_sgs) {
|
||||
+ len = sg_pcopy_from_buffer(urb->sg, urb->num_mapped_sgs, seg->bounce_buf,
|
||||
+ seg->bounce_len, seg->bounce_offs);
|
||||
+ if (len != seg->bounce_len)
|
||||
+ xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
|
||||
+ len, seg->bounce_len);
|
||||
+ } else {
|
||||
+ memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf,
|
||||
+ seg->bounce_len);
|
||||
+ }
|
||||
dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
|
||||
DMA_FROM_DEVICE);
|
||||
seg->bounce_len = 0;
|
||||
@@ -1141,7 +1150,7 @@
|
||||
if (xhci->quirks & XHCI_RESET_EP_QUIRK) {
|
||||
struct xhci_command *command;
|
||||
|
||||
@ -357,7 +384,7 @@ index daa94c3..028891a 100644
|
||||
if (!command)
|
||||
return;
|
||||
|
||||
@@ -1821,7 +1821,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
|
||||
@@ -1821,7 +1830,7 @@
|
||||
{
|
||||
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
|
||||
struct xhci_command *command;
|
||||
@ -366,7 +393,35 @@ index daa94c3..028891a 100644
|
||||
if (!command)
|
||||
return;
|
||||
|
||||
@@ -3906,7 +3906,7 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
||||
@@ -3136,6 +3145,7 @@
|
||||
unsigned int unalign;
|
||||
unsigned int max_pkt;
|
||||
u32 new_buff_len;
|
||||
+ size_t len;
|
||||
|
||||
max_pkt = usb_endpoint_maxp(&urb->ep->desc);
|
||||
unalign = (enqd_len + *trb_buff_len) % max_pkt;
|
||||
@@ -3166,8 +3176,17 @@
|
||||
|
||||
/* create a max max_pkt sized bounce buffer pointed to by last trb */
|
||||
if (usb_urb_dir_out(urb)) {
|
||||
- sg_pcopy_to_buffer(urb->sg, urb->num_mapped_sgs,
|
||||
- seg->bounce_buf, new_buff_len, enqd_len);
|
||||
+ if (urb->num_sgs) {
|
||||
+ len = sg_pcopy_to_buffer(urb->sg, urb->num_mapped_sgs,
|
||||
+ seg->bounce_buf, new_buff_len, enqd_len);
|
||||
+ if (len != new_buff_len) {
|
||||
+ xhci_warn(xhci, "WARN Wrong bounce buffer write length: %zu != %d\n",
|
||||
+ len, new_buff_len);
|
||||
+ }
|
||||
+ } else {
|
||||
+ memcpy(seg->bounce_buf, urb->transfer_buffer + enqd_len,
|
||||
+ new_buff_len);
|
||||
+ }
|
||||
seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
|
||||
max_pkt, DMA_TO_DEVICE);
|
||||
} else {
|
||||
@@ -3906,7 +3925,7 @@
|
||||
reserved_trbs++;
|
||||
|
||||
ret = prepare_ring(xhci, xhci->cmd_ring, EP_STATE_RUNNING,
|
||||
@ -375,7 +430,7 @@ index daa94c3..028891a 100644
|
||||
if (ret < 0) {
|
||||
xhci_err(xhci, "ERR: No room for command on command ring\n");
|
||||
if (command_must_succeed)
|
||||
@@ -4040,7 +4040,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
|
||||
@@ -4040,7 +4059,7 @@
|
||||
}
|
||||
|
||||
/* This function gets called from contexts where it cannot sleep */
|
||||
|
@ -1 +1 @@
|
||||
fb5909112c26bcbc48cadae5ccf18d5546c6e86c
|
||||
f18ed96081c46c0bef2a9db80253d51b48a4f07d
|
||||
|
Loading…
x
Reference in New Issue
Block a user