summaryrefslogtreecommitdiffstats
path: root/drivers/usb/mon/mon_text.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-01-28 14:38:25 -0700
committerGrant Likely <grant.likely@secretlab.ca>2010-01-28 14:38:25 -0700
commit0ada0a73120c28cc432bcdbac061781465c2f48f (patch)
treed17cadd4ea47e25d9e48e7d409a39c84268fbd27 /drivers/usb/mon/mon_text.c
parent6016a363f6b56b46b24655bcfc0499b715851cf3 (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (diff)
Merge commit 'v2.6.33-rc5' into secretlab/test-devicetree
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 9f1a9227ebe..047568ff223 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;
}