# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.380 -> 1.381 # drivers/usb/uhci.c 1.26 -> 1.27 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/02/20 johannes@erdfelt.com 1.381 # [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. # -------------------------------------------- # diff -Nru a/drivers/usb/uhci.c b/drivers/usb/uhci.c --- a/drivers/usb/uhci.c Wed Feb 20 16:55:54 2002 +++ b/drivers/usb/uhci.c Wed Feb 20 16:55:54 2002 @@ -715,14 +715,18 @@ 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, 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, urb->transfer_buffer_length, usb_pipein(urb->pipe) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + urbp->transfer_buffer_dma_handle = 0; + } urb->hcpriv = NULL; kmem_cache_free(uhci_up_cachep, urbp); @@ -2288,14 +2292,6 @@ 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) pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle, urb->transfer_buffer_length, usb_pipein(urb->pipe) ? @@ -2304,6 +2300,14 @@ if (urbp->setup_packet_dma_handle) pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle, 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; if (urb->complete) {