diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-04-02 13:27:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:37 -0400 |
commit | ff9c895f07d36193c75533bda8193bde8ca99d02 (patch) | |
tree | 386ca8e37734c4810e59a55eaba92e4e88275d14 /drivers/usb/core/usb.c | |
parent | 0ff8d1b3c858ea7c8daa54f7577971a76d04d283 (diff) |
USB: fix usbmon and DMA mapping for scatter-gather URBs
This patch (as1368) fixes a rather obscure bug in usbmon: When tracing
URBs sent by the scatter-gather library, it accesses the data buffers
while they are still mapped for DMA.
The solution is to move the mapping and unmapping out of the s-g
library and into the usual place in hcd.c. This requires the addition
of new URB flag bits to describe the kind of mapping needed, since we
have to call dma_map_sg() if the HCD supports native scatter-gather
operation and dma_map_page() if it doesn't. The nice thing about
having the new flags is that they simplify the testing for unmapping.
The patch removes the only caller of usb_buffer_[un]map_sg(), so those
functions are #if'ed out. A later patch will remove them entirely.
As a result of this change, urb->sg will be set in situations where
it wasn't set previously. Hence the xhci and whci drivers are
adjusted to test urb->num_sgs instead, which retains its original
meaning and is nonzero only when the HCD has to handle a scatterlist.
Finally, even when a submission error occurs we don't want to hand
URBs to usbmon before they are unmapped. The submission path is
rearranged so that map_urb_for_dma() is called only for non-root-hub
URBs and unmap_urb_for_dma() is called immediately after a submission
error. This simplifies the error handling.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r-- | drivers/usb/core/usb.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 097172e2ba06..8180ce533ebf 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -881,6 +881,7 @@ void usb_buffer_unmap(struct urb *urb) | |||
881 | EXPORT_SYMBOL_GPL(usb_buffer_unmap); | 881 | EXPORT_SYMBOL_GPL(usb_buffer_unmap); |
882 | #endif /* 0 */ | 882 | #endif /* 0 */ |
883 | 883 | ||
884 | #if 0 | ||
884 | /** | 885 | /** |
885 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint | 886 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint |
886 | * @dev: device to which the scatterlist will be mapped | 887 | * @dev: device to which the scatterlist will be mapped |
@@ -924,6 +925,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, int is_in, | |||
924 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE) ? : -ENOMEM; | 925 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE) ? : -ENOMEM; |
925 | } | 926 | } |
926 | EXPORT_SYMBOL_GPL(usb_buffer_map_sg); | 927 | EXPORT_SYMBOL_GPL(usb_buffer_map_sg); |
928 | #endif | ||
927 | 929 | ||
928 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 930 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
929 | * XXX please determine whether the sync is to transfer ownership of | 931 | * XXX please determine whether the sync is to transfer ownership of |
@@ -960,6 +962,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, | |||
960 | EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg); | 962 | EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg); |
961 | #endif | 963 | #endif |
962 | 964 | ||
965 | #if 0 | ||
963 | /** | 966 | /** |
964 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist | 967 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist |
965 | * @dev: device to which the scatterlist will be mapped | 968 | * @dev: device to which the scatterlist will be mapped |
@@ -985,6 +988,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, | |||
985 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 988 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
986 | } | 989 | } |
987 | EXPORT_SYMBOL_GPL(usb_buffer_unmap_sg); | 990 | EXPORT_SYMBOL_GPL(usb_buffer_unmap_sg); |
991 | #endif | ||
988 | 992 | ||
989 | /* To disable USB, kernel command line is 'nousb' not 'usbcore.nousb' */ | 993 | /* To disable USB, kernel command line is 'nousb' not 'usbcore.nousb' */ |
990 | #ifdef MODULE | 994 | #ifdef MODULE |