Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 4612
b: refs/heads/master
c: ae0d6cc
h: refs/heads/master
v: v3
  • Loading branch information
Pete Zaitcev authored and Greg Kroah-Hartman committed Jul 12, 2005
1 parent 6a996cd commit 20aa20d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 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: ead99eb00190a274e3b3666ecd431be12c2b7888
refs/heads/master: ae0d6cceb20eec57e7196c22999c62c465ffd5bf
29 changes: 21 additions & 8 deletions trunk/Documentation/usb/usbmon.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ Here is the list of words, from left to right:
or 3 and 2 positions, correspondingly.
- URB Status. This field makes no sense for submissions, but is present
to help scripts with parsing. In error case, it contains the error code.
In case of a setup packet, it contains a Setup Tag. If scripts read a number
in this field, the proceed to read Data Length. Otherwise, they read
the setup packet before reading the Data Length.
- Setup packet, if present, consists of 5 words: one of each for bmRequestType,
bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
These words are safe to decode if Setup Tag was 's'. Otherwise, the setup
packet was present, but not captured, and the fields contain filler.
- Data Length. This is the actual length in the URB.
- Data tag. The usbmon may not always capture data, even if length is nonzero.
Only if tag is '=', the data words are present.
Expand All @@ -125,25 +132,31 @@ class ParsedLine {
String data_str = st.nextToken();
int len = data_str.length() / 2;
int i;
int b; // byte is signed, apparently?! XXX
for (i = 0; i < len; i++) {
data[data_len] = Byte.parseByte(
data_str.substring(i*2, i*2 + 2),
16);
// data[data_len] = Byte.parseByte(
// data_str.substring(i*2, i*2 + 2),
// 16);
b = Integer.parseInt(
data_str.substring(i*2, i*2 + 2),
16);
if (b >= 128)
b *= -1;
data[data_len] = (byte) b;
data_len++;
}
}
}
}

This format is obviously deficient. For example, the setup packet for control
transfers is not delivered. This will change in the future.
This format may be changed in the future.

Examples:

An input control transfer to get a port status:
An input control transfer to get a port status.

d74ff9a0 2640288196 S Ci:001:00 -115 4 <
d74ff9a0 2640288202 C Ci:001:00 0 4 = 01010100
d5ea89a0 3575914555 S Ci:001:00 s a3 00 0000 0003 0004 4 <
d5ea89a0 3575914560 C Ci:001:00 0 4 = 01050000

An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
to a storage device at address 5:
Expand Down
48 changes: 43 additions & 5 deletions trunk/drivers/usb/mon/mon_text.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
*/
#define DATA_MAX 32

/*
* Defined by USB 2.0 clause 9.3, table 9.2.
*/
#define SETUP_MAX 8

/*
* This limit exists to prevent OOMs when the user process stops reading.
*/
#define EVENT_MAX 25

#define PRINTF_DFL 120
#define PRINTF_DFL 130

struct mon_event_text {
struct list_head e_link;
Expand All @@ -33,7 +38,9 @@ struct mon_event_text {
unsigned int tstamp;
int length; /* Depends on type: xfer length or act length */
int status;
char setup_flag;
char data_flag;
unsigned char setup[SETUP_MAX];
unsigned char data[DATA_MAX];
};

Expand Down Expand Up @@ -64,6 +71,22 @@ static void mon_text_dtor(void *, kmem_cache_t *, unsigned long);
* This is called with the whole mon_bus locked, so no additional lock.
*/

static inline char mon_text_get_setup(struct mon_event_text *ep,
struct urb *urb, char ev_type)
{

if (!usb_pipecontrol(urb->pipe) || ev_type != 'S')
return '-';

if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)
return 'D';
if (urb->setup_packet == NULL)
return 'Z'; /* '0' would be not as pretty. */

memcpy(ep->setup, urb->setup_packet, SETUP_MAX);
return 0;
}

static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
int len, char ev_type)
{
Expand All @@ -90,7 +113,6 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,

/*
* Bulk is easy to shortcut reliably.
* XXX Control needs setup packet taken.
* XXX Other pipe types need consideration. Currently, we overdo it
* and collect garbage for them: better more than less.
*/
Expand Down Expand Up @@ -144,6 +166,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
/* Collecting status makes debugging sense for submits, too */
ep->status = urb->status;

ep->setup_flag = mon_text_get_setup(ep, urb, ev_type);
ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type);

rp->nevents++;
Expand Down Expand Up @@ -299,10 +322,25 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
default: /* PIPE_BULK */ utype = 'B';
}
cnt += snprintf(pbuf + cnt, limit - cnt,
"%lx %u %c %c%c:%03u:%02u %d %d",
"%lx %u %c %c%c:%03u:%02u",
ep->id, ep->tstamp, ep->type,
utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe),
ep->status, ep->length);
utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));

if (ep->setup_flag == 0) { /* Setup packet is present and captured */
cnt += snprintf(pbuf + cnt, limit - cnt,
" s %02x %02x %04x %04x %04x",
ep->setup[0],
ep->setup[1],
(ep->setup[3] << 8) | ep->setup[2],
(ep->setup[5] << 8) | ep->setup[4],
(ep->setup[7] << 8) | ep->setup[6]);
} else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
cnt += snprintf(pbuf + cnt, limit - cnt,
" %c __ __ ____ ____ ____", ep->setup_flag);
} else { /* No setup for this kind of URB */
cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status);
}
cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length);

if ((data_len = ep->length) > 0) {
if (ep->data_flag == 0) {
Expand Down

0 comments on commit 20aa20d

Please sign in to comment.