summaryrefslogtreecommitdiff
path: root/drivers/usb/mon/mon_text.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-11-06 17:32:23 (GMT)
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 19:55:20 (GMT)
commitb375e1169d8ecc9e9db3ecba8147d484b5510833 (patch)
tree6e82dd614c4a36d725b7250ced5a48a76c301607 /drivers/usb/mon/mon_text.c
parent40f8db8f8f5af2cafeb976ae15e11aca641a931d (diff)
downloadlinux-fsl-qoriq-b375e1169d8ecc9e9db3ecba8147d484b5510833.tar.xz
USB: add scatter-gather support to usbmon
This patch (as1301) adds support to usbmon for scatter-gather URBs. The text interface looks at only the first scatterlist element, since it never copies more than 32 bytes of data anyway. The binary interface copies as much data as possible up to the first non-addressable buffer. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: Pete Zaitcev <zaitcev@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/mon/mon_text.c')
-rw-r--r--drivers/usb/mon/mon_text.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 9f1a922..047568f 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -10,6 +10,7 @@
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/debugfs.h>
+#include <linux/scatterlist.h>
#include <asm/uaccess.h>
#include "usb_mon.h"
@@ -137,6 +138,8 @@ static inline char mon_text_get_setup(struct mon_event_text *ep,
static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
int len, char ev_type, struct mon_bus *mbus)
{
+ void *src;
+
if (len <= 0)
return 'L';
if (len >= DATA_MAX)
@@ -150,10 +153,24 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
return '>';
}
- if (urb->transfer_buffer == NULL)
- return 'Z'; /* '0' would be not as pretty. */
+ if (urb->num_sgs == 0) {
+ src = urb->transfer_buffer;
+ if (src == NULL)
+ return 'Z'; /* '0' would be not as pretty. */
+ } else {
+ struct scatterlist *sg = urb->sg->sg;
+
+ /* If IOMMU coalescing occurred, we cannot trust sg_page */
+ if (urb->sg->nents != urb->num_sgs ||
+ PageHighMem(sg_page(sg)))
+ return 'D';
+
+ /* For the text interface we copy only the first sg buffer */
+ len = min_t(int, sg->length, len);
+ src = sg_virt(sg);
+ }
- memcpy(ep->data, urb->transfer_buffer, len);
+ memcpy(ep->data, src, len);
return 0;
}