diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-01-28 14:38:25 -0700 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-01-28 14:38:25 -0700 |
commit | 0ada0a73120c28cc432bcdbac061781465c2f48f (patch) | |
tree | d17cadd4ea47e25d9e48e7d409a39c84268fbd27 /drivers/usb/mon/mon_text.c | |
parent | 6016a363f6b56b46b24655bcfc0499b715851cf3 (diff) | |
parent | 92dcffb916d309aa01778bf8963a6932e4014d07 (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.c | 23 |
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; } |