Commit 640bcbba authored by Johannes Erdfelt's avatar Johannes Erdfelt Committed by Greg Kroah-Hartman

[PATCH] uhci.c, fix pci dma ordering issue

There was a bug where we unmap the PCI DMA mapping and then sync the
data afterwards. This reverses the ordering as well as insures we don't
unmap the region more than once.
parent cc115573
...@@ -715,14 +715,18 @@ static void uhci_destroy_urb_priv(struct urb *urb) ...@@ -715,14 +715,18 @@ static void uhci_destroy_urb_priv(struct urb *urb)
uhci_free_td(uhci, td); uhci_free_td(uhci, td);
} }
if (urbp->setup_packet_dma_handle) if (urbp->setup_packet_dma_handle) {
pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle, pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle,
sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE); sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
urbp->setup_packet_dma_handle = 0;
}
if (urbp->transfer_buffer_dma_handle) if (urbp->transfer_buffer_dma_handle) {
pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle, pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle,
urb->transfer_buffer_length, usb_pipein(urb->pipe) ? urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
urbp->transfer_buffer_dma_handle = 0;
}
urb->hcpriv = NULL; urb->hcpriv = NULL;
kmem_cache_free(uhci_up_cachep, urbp); kmem_cache_free(uhci_up_cachep, urbp);
...@@ -2288,14 +2292,6 @@ static void uhci_call_completion(struct urb *urb) ...@@ -2288,14 +2292,6 @@ static void uhci_call_completion(struct urb *urb)
is_ring = (nurb == urb); is_ring = (nurb == urb);
} }
status = urbp->status;
if (!resubmit_interrupt || killed)
/* We don't need urb_priv anymore */
uhci_destroy_urb_priv(urb);
if (!killed)
urb->status = status;
if (urbp->transfer_buffer_dma_handle) if (urbp->transfer_buffer_dma_handle)
pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle, pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle,
urb->transfer_buffer_length, usb_pipein(urb->pipe) ? urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
...@@ -2305,6 +2301,14 @@ static void uhci_call_completion(struct urb *urb) ...@@ -2305,6 +2301,14 @@ static void uhci_call_completion(struct urb *urb)
pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle, pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle,
sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE); sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
status = urbp->status;
if (!resubmit_interrupt || killed)
/* We don't need urb_priv anymore */
uhci_destroy_urb_priv(urb);
if (!killed)
urb->status = status;
urb->dev = NULL; urb->dev = NULL;
if (urb->complete) { if (urb->complete) {
urb->complete(urb); urb->complete(urb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment