Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174927
b: refs/heads/master
c: b375e11
h: refs/heads/master
i:
  174925: 7279e1f
  174923: 13151de
  174919: c0f93c4
  174911: e244c59
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Dec 11, 2009
1 parent c02409d commit 74b96e0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 40f8db8f8f5af2cafeb976ae15e11aca641a931d
refs/heads/master: b375e1169d8ecc9e9db3ecba8147d484b5510833
51 changes: 42 additions & 9 deletions trunk/drivers/usb/mon/mon_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/compat.h>
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/scatterlist.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -221,7 +222,7 @@ static void mon_free_buff(struct mon_pgmap *map, int npages);
/*
* This is a "chunked memcpy". It does not manipulate any counters.
*/
static void mon_copy_to_buff(const struct mon_reader_bin *this,
static unsigned int mon_copy_to_buff(const struct mon_reader_bin *this,
unsigned int off, const unsigned char *from, unsigned int length)
{
unsigned int step_len;
Expand All @@ -246,6 +247,7 @@ static void mon_copy_to_buff(const struct mon_reader_bin *this,
from += step_len;
length -= step_len;
}
return off;
}

/*
Expand Down Expand Up @@ -394,14 +396,44 @@ static inline char mon_bin_get_setup(unsigned char *setupb,
return 0;
}

static char mon_bin_get_data(const struct mon_reader_bin *rp,
unsigned int offset, struct urb *urb, unsigned int length)
static unsigned int mon_bin_get_data(const struct mon_reader_bin *rp,
unsigned int offset, struct urb *urb, unsigned int length,
char *flag)
{
int i;
struct scatterlist *sg;
unsigned int this_len;

*flag = 0;
if (urb->num_sgs == 0) {
if (urb->transfer_buffer == NULL) {
*flag = 'Z';
return length;
}
mon_copy_to_buff(rp, offset, urb->transfer_buffer, length);
length = 0;

if (urb->transfer_buffer == NULL)
return 'Z';
mon_copy_to_buff(rp, offset, urb->transfer_buffer, length);
return 0;
} else {
/* If IOMMU coalescing occurred, we cannot trust sg_page */
if (urb->sg->nents != urb->num_sgs) {
*flag = 'D';
return length;
}

/* Copy up to the first non-addressable segment */
for_each_sg(urb->sg->sg, sg, urb->num_sgs, i) {
if (length == 0 || PageHighMem(sg_page(sg)))
break;
this_len = min_t(unsigned int, sg->length, length);
offset = mon_copy_to_buff(rp, offset, sg_virt(sg),
this_len);
length -= this_len;
}
if (i == 0)
*flag = 'D';
}

return length;
}

static void mon_bin_get_isodesc(const struct mon_reader_bin *rp,
Expand Down Expand Up @@ -536,8 +568,9 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
}

if (length != 0) {
ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */
length = mon_bin_get_data(rp, offset, urb, length,
&ep->flag_data);
if (length > 0) {
delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
ep->len_cap -= length;
delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
Expand Down
23 changes: 20 additions & 3 deletions trunk/drivers/usb/mon/mon_text.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}

Expand Down

0 comments on commit 74b96e0

Please sign in to comment.