@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
+#include <linux/dma-mapping.h>
#include "usb_mon.h"
@@ -142,6 +143,12 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status)
{
struct mon_bus *mbus;
+ if (urb->transfer_flags & URB_USBMON_NEED_SYNC)
+ dma_sync_single_for_cpu(ubus->sysdev,
+ urb->transfer_dma,
+ urb->transfer_buffer_length,
+ DMA_FROM_DEVICE);
+
mbus = ubus->mon_bus;
if (mbus != NULL)
mon_bus_complete(mbus, urb, status);
@@ -1368,6 +1368,7 @@ extern int usb_disabled(void);
#define URB_ISO_ASAP 0x0002 /* iso-only; use the first unexpired
* slot in the schedule */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
+#define URB_USBMON_NEED_SYNC 0x0008 /* usb monitor need do dma sync for cpu read */
#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt
* needed */
The urb->transfer_dma may not be dma coherent, in this case usb monitor may get old data. For example, commit "20e1dbf2bbe2 media: uvcvideo: Use dma_alloc_noncontiguous API" is allocating non-coherent buffer. To make usbmon result more reliable, this will add a flag URB_USBMON_NEED_SYNC to indicate that usb monitor need do dma sync before reading buffer data. Signed-off-by: Xu Yang <xu.yang_2@nxp.com> --- drivers/usb/mon/mon_main.c | 7 +++++++ include/linux/usb.h | 1 + 2 files changed, 8 insertions(+)