aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/mon/mon_text.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-11-06 12:32:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:20 -0500
commitb375e1169d8ecc9e9db3ecba8147d484b5510833 (patch)
tree6e82dd614c4a36d725b7250ced5a48a76c301607 /drivers/usb/mon/mon_text.c
parent40f8db8f8f5af2cafeb976ae15e11aca641a931d (diff)
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 9f1a9227ebe6..047568ff223d 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -10,6 +10,7 @@
10#include <linux/time.h> 10#include <linux/time.h>
11#include <linux/mutex.h> 11#include <linux/mutex.h>
12#include <linux/debugfs.h> 12#include <linux/debugfs.h>
13#include <linux/scatterlist.h>
13#include <asm/uaccess.h> 14#include <asm/uaccess.h>
14 15
15#include "usb_mon.h" 16#include "usb_mon.h"
@@ -137,6 +138,8 @@ static inline char mon_text_get_setup(struct mon_event_text *ep,
137static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, 138static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
138 int len, char ev_type, struct mon_bus *mbus) 139 int len, char ev_type, struct mon_bus *mbus)
139{ 140{
141 void *src;
142
140 if (len <= 0) 143 if (len <= 0)
141 return 'L'; 144 return 'L';
142 if (len >= DATA_MAX) 145 if (len >= DATA_MAX)
@@ -150,10 +153,24 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
150 return '>'; 153 return '>';
151 } 154 }
152 155
153 if (urb->transfer_buffer == NULL) 156 if (urb->num_sgs == 0) {
154 return 'Z'; /* '0' would be not as pretty. */ 157 src = urb->transfer_buffer;
158 if (src == NULL)
159 return 'Z'; /* '0' would be not as pretty. */
160 } else {
161 struct scatterlist *sg = urb->sg->sg;
162
163 /* If IOMMU coalescing occurred, we cannot trust sg_page */
164 if (urb->sg->nents != urb->num_sgs ||
165 PageHighMem(sg_page(sg)))
166 return 'D';
167
168 /* For the text interface we copy only the first sg buffer */
169 len = min_t(int, sg->length, len);
170 src = sg_virt(sg);
171 }
155 172
156 memcpy(ep->data, urb->transfer_buffer, len); 173 memcpy(ep->data, src, len);
157 return 0; 174 return 0;
158} 175}
159 176