aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPete Zaitcev <zaitcev@redhat.com>2007-02-24 22:27:33 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 16:28:33 -0400
commitf1c9e30b5e4cdd8aae5f0ea87004b1b61ec41881 (patch)
tree9ea740745c04780171662529c520b0a9c02ca64d
parent2e85c91e2e0f4e58fb54354bb7f6cc7dd3466dd9 (diff)
usbmon: Extended text API
This patch adds a new text API, codenamed '1u', which captures more URB fields than old '1t' interface did. Also the '1u' text API is compatible with the future "bus zero" extension. Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/usb/usbmon.txt80
-rw-r--r--drivers/usb/mon/mon_text.c296
-rw-r--r--drivers/usb/mon/usb_mon.h1
3 files changed, 313 insertions, 64 deletions
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt
index 0f6808abd612..53ae866ae37b 100644
--- a/Documentation/usb/usbmon.txt
+++ b/Documentation/usb/usbmon.txt
@@ -16,7 +16,7 @@ situation as with tcpdump.
16 16
17Unlike the packet socket, usbmon has an interface which provides traces 17Unlike the packet socket, usbmon has an interface which provides traces
18in a text format. This is used for two purposes. First, it serves as a 18in a text format. This is used for two purposes. First, it serves as a
19common trace exchange format for tools while most sophisticated formats 19common trace exchange format for tools while more sophisticated formats
20are finalized. Second, humans can read it in case tools are not available. 20are finalized. Second, humans can read it in case tools are not available.
21 21
22To collect a raw text trace, execute following steps. 22To collect a raw text trace, execute following steps.
@@ -34,7 +34,7 @@ if usbmon is built into the kernel.
34Verify that bus sockets are present. 34Verify that bus sockets are present.
35 35
36# ls /sys/kernel/debug/usbmon 36# ls /sys/kernel/debug/usbmon
371s 1t 2s 2t 3s 3t 4s 4t 371s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u
38# 38#
39 39
402. Find which bus connects to the desired device 402. Find which bus connects to the desired device
@@ -54,7 +54,7 @@ Bus=03 means it's bus 3.
54 54
553. Start 'cat' 553. Start 'cat'
56 56
57# cat /sys/kernel/debug/usbmon/3t > /tmp/1.mon.out 57# cat /sys/kernel/debug/usbmon/3u > /tmp/1.mon.out
58 58
59This process will be reading until killed. Naturally, the output can be 59This process will be reading until killed. Naturally, the output can be
60redirected to a desirable location. This is preferred, because it is going 60redirected to a desirable location. This is preferred, because it is going
@@ -75,46 +75,80 @@ that the file size is not excessive for your favourite editor.
75 75
76* Raw text data format 76* Raw text data format
77 77
78The '1t' type data consists of a stream of events, such as URB submission, 78Two formats are supported currently: the original, or '1t' format, and
79the '1u' format. The '1t' format is deprecated in kernel 2.6.21. The '1u'
80format adds a few fields, such as ISO frame descriptors, interval, etc.
81It produces slightly longer lines, but otherwise is a perfect superset
82of '1t' format.
83
84If it is desired to recognize one from the other in a program, look at the
85"address" word (see below), where '1u' format adds a bus number. If 2 colons
86are present, it's the '1t' format, otherwise '1u'.
87
88Any text format data consists of a stream of events, such as URB submission,
79URB callback, submission error. Every event is a text line, which consists 89URB callback, submission error. Every event is a text line, which consists
80of whitespace separated words. The number or position of words may depend 90of whitespace separated words. The number or position of words may depend
81on the event type, but there is a set of words, common for all types. 91on the event type, but there is a set of words, common for all types.
82 92
83Here is the list of words, from left to right: 93Here is the list of words, from left to right:
94
84- URB Tag. This is used to identify URBs is normally a kernel mode address 95- URB Tag. This is used to identify URBs is normally a kernel mode address
85 of the URB structure in hexadecimal. 96 of the URB structure in hexadecimal.
97
86- Timestamp in microseconds, a decimal number. The timestamp's resolution 98- Timestamp in microseconds, a decimal number. The timestamp's resolution
87 depends on available clock, and so it can be much worse than a microsecond 99 depends on available clock, and so it can be much worse than a microsecond
88 (if the implementation uses jiffies, for example). 100 (if the implementation uses jiffies, for example).
101
89- Event Type. This type refers to the format of the event, not URB type. 102- Event Type. This type refers to the format of the event, not URB type.
90 Available types are: S - submission, C - callback, E - submission error. 103 Available types are: S - submission, C - callback, E - submission error.
91- "Pipe". The pipe concept is deprecated. This is a composite word, used to 104
92 be derived from information in pipes. It consists of three fields, separated 105- "Address" word (formerly a "pipe"). It consists of four fields, separated by
93 by colons: URB type and direction, Device address, Endpoint number. 106 colons: URB type and direction, Bus number, Device address, Endpoint number.
94 Type and direction are encoded with two bytes in the following manner: 107 Type and direction are encoded with two bytes in the following manner:
95 Ci Co Control input and output 108 Ci Co Control input and output
96 Zi Zo Isochronous input and output 109 Zi Zo Isochronous input and output
97 Ii Io Interrupt input and output 110 Ii Io Interrupt input and output
98 Bi Bo Bulk input and output 111 Bi Bo Bulk input and output
99 Device address and Endpoint number are 3-digit and 2-digit (respectively) 112 Bus number, Device address, and Endpoint are decimal numbers, but they may
100 decimal numbers, with leading zeroes. 113 have leading zeros, for the sake of human readers.
101- URB Status. In most cases, this field contains a number, sometimes negative, 114
102 which represents a "status" field of the URB. This field makes no sense for 115- URB Status word. This is either a letter, or several numbers separated
103 submissions, but is present anyway to help scripts with parsing. When an 116 by colons: URB status, interval, start frame, and error count. Unlike the
104 error occurs, the field contains the error code. In case of a submission of 117 "address" word, all fields save the status are optional. Interval is printed
105 a Control packet, this field contains a Setup Tag instead of an error code. 118 only for interrupt and isochronous URBs. Start frame is printed only for
106 It is easy to tell whether the Setup Tag is present because it is never a 119 isochronous URBs. Error count is printed only for isochronous callback
107 number. Thus if scripts find a number in this field, they proceed to read 120 events.
108 Data Length. If they find something else, like a letter, they read the setup 121
109 packet before reading the Data Length. 122 The status field is a decimal number, sometimes negative, which represents
123 a "status" field of the URB. This field makes no sense for submissions, but
124 is present anyway to help scripts with parsing. When an error occurs, the
125 field contains the error code.
126
127 In case of a submission of a Control packet, this field contains a Setup Tag
128 instead of an group of numbers. It is easy to tell whether the Setup Tag is
129 present because it is never a number. Thus if scripts find a set of numbers
130 in this word, they proceed to read Data Length (except for isochronous URBs).
131 If they find something else, like a letter, they read the setup packet before
132 reading the Data Length or isochronous descriptors.
133
110- Setup packet, if present, consists of 5 words: one of each for bmRequestType, 134- Setup packet, if present, consists of 5 words: one of each for bmRequestType,
111 bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. 135 bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
112 These words are safe to decode if Setup Tag was 's'. Otherwise, the setup 136 These words are safe to decode if Setup Tag was 's'. Otherwise, the setup
113 packet was present, but not captured, and the fields contain filler. 137 packet was present, but not captured, and the fields contain filler.
138
139- Number of isochronous frame descriptors and descriptors themselves.
140 If an Isochronous transfer event has a set of descriptors, a total number
141 of them in an URB is printed first, then a word per descriptor, up to a
142 total of 5. The word consists of 3 colon-separated decimal numbers for
143 status, offset, and length respectively. For submissions, initial length
144 is reported. For callbacks, actual length is reported.
145
114- Data Length. For submissions, this is the requested length. For callbacks, 146- Data Length. For submissions, this is the requested length. For callbacks,
115 this is the actual length. 147 this is the actual length.
148
116- Data tag. The usbmon may not always capture data, even if length is nonzero. 149- Data tag. The usbmon may not always capture data, even if length is nonzero.
117 The data words are present only if this tag is '='. 150 The data words are present only if this tag is '='.
151
118- Data words follow, in big endian hexadecimal format. Notice that they are 152- Data words follow, in big endian hexadecimal format. Notice that they are
119 not machine words, but really just a byte stream split into words to make 153 not machine words, but really just a byte stream split into words to make
120 it easier to read. Thus, the last word may contain from one to four bytes. 154 it easier to read. Thus, the last word may contain from one to four bytes.
@@ -153,20 +187,18 @@ class ParsedLine {
153 } 187 }
154} 188}
155 189
156This format may be changed in the future.
157
158Examples: 190Examples:
159 191
160An input control transfer to get a port status. 192An input control transfer to get a port status.
161 193
162d5ea89a0 3575914555 S Ci:001:00 s a3 00 0000 0003 0004 4 < 194d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
163d5ea89a0 3575914560 C Ci:001:00 0 4 = 01050000 195d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
164 196
165An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper 197An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
166to a storage device at address 5: 198to a storage device at address 5:
167 199
168dd65f0e8 4128379752 S Bo:005:02 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 200dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000
169dd65f0e8 4128379808 C Bo:005:02 0 31 > 201dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
170 202
171* Raw binary format and API 203* Raw binary format and API
172 204
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 494ee3b9a226..bbf54396e5f2 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -31,9 +31,21 @@
31 * to a local DoS. But we have to keep to root in order to prevent 31 * to a local DoS. But we have to keep to root in order to prevent
32 * password sniffing from HID devices. 32 * password sniffing from HID devices.
33 */ 33 */
34#define EVENT_MAX (2*PAGE_SIZE / sizeof(struct mon_event_text)) 34#define EVENT_MAX (4*PAGE_SIZE / sizeof(struct mon_event_text))
35 35
36#define PRINTF_DFL 160 36/*
37 * Potentially unlimited number; we limit it for similar allocations.
38 * The usbfs limits this to 128, but we're not quite as generous.
39 */
40#define ISODESC_MAX 5
41
42#define PRINTF_DFL 250 /* with 5 ISOs segs */
43
44struct mon_iso_desc {
45 int status;
46 unsigned int offset;
47 unsigned int length; /* Unsigned here, signed in URB. Historic. */
48};
37 49
38struct mon_event_text { 50struct mon_event_text {
39 struct list_head e_link; 51 struct list_head e_link;
@@ -41,10 +53,16 @@ struct mon_event_text {
41 unsigned int pipe; /* Pipe */ 53 unsigned int pipe; /* Pipe */
42 unsigned long id; /* From pointer, most of the time */ 54 unsigned long id; /* From pointer, most of the time */
43 unsigned int tstamp; 55 unsigned int tstamp;
56 int busnum;
44 int length; /* Depends on type: xfer length or act length */ 57 int length; /* Depends on type: xfer length or act length */
45 int status; 58 int status;
59 int interval;
60 int start_frame;
61 int error_count;
46 char setup_flag; 62 char setup_flag;
47 char data_flag; 63 char data_flag;
64 int numdesc; /* Full number */
65 struct mon_iso_desc isodesc[ISODESC_MAX];
48 unsigned char setup[SETUP_MAX]; 66 unsigned char setup[SETUP_MAX];
49 unsigned char data[DATA_MAX]; 67 unsigned char data[DATA_MAX];
50}; 68};
@@ -68,6 +86,28 @@ static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */
68 86
69static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); 87static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
70 88
89struct mon_text_ptr {
90 int cnt, limit;
91 char *pbuf;
92};
93
94static struct mon_event_text *
95 mon_text_read_wait(struct mon_reader_text *rp, struct file *file);
96static void mon_text_read_head_t(struct mon_reader_text *rp,
97 struct mon_text_ptr *p, const struct mon_event_text *ep);
98static void mon_text_read_head_u(struct mon_reader_text *rp,
99 struct mon_text_ptr *p, const struct mon_event_text *ep);
100static void mon_text_read_statset(struct mon_reader_text *rp,
101 struct mon_text_ptr *p, const struct mon_event_text *ep);
102static void mon_text_read_intstat(struct mon_reader_text *rp,
103 struct mon_text_ptr *p, const struct mon_event_text *ep);
104static void mon_text_read_isostat(struct mon_reader_text *rp,
105 struct mon_text_ptr *p, const struct mon_event_text *ep);
106static void mon_text_read_isodesc(struct mon_reader_text *rp,
107 struct mon_text_ptr *p, const struct mon_event_text *ep);
108static void mon_text_read_data(struct mon_reader_text *rp,
109 struct mon_text_ptr *p, const struct mon_event_text *ep);
110
71/* 111/*
72 * mon_text_submit 112 * mon_text_submit
73 * mon_text_complete 113 * mon_text_complete
@@ -104,10 +144,10 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
104 len = DATA_MAX; 144 len = DATA_MAX;
105 145
106 if (usb_pipein(pipe)) { 146 if (usb_pipein(pipe)) {
107 if (ev_type == 'S') 147 if (ev_type != 'C')
108 return '<'; 148 return '<';
109 } else { 149 } else {
110 if (ev_type == 'C') 150 if (ev_type != 'S')
111 return '>'; 151 return '>';
112 } 152 }
113 153
@@ -146,6 +186,9 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
146{ 186{
147 struct mon_event_text *ep; 187 struct mon_event_text *ep;
148 unsigned int stamp; 188 unsigned int stamp;
189 struct usb_iso_packet_descriptor *fp;
190 struct mon_iso_desc *dp;
191 int i, ndesc;
149 192
150 stamp = mon_get_timestamp(); 193 stamp = mon_get_timestamp();
151 194
@@ -158,12 +201,36 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
158 ep->type = ev_type; 201 ep->type = ev_type;
159 ep->pipe = urb->pipe; 202 ep->pipe = urb->pipe;
160 ep->id = (unsigned long) urb; 203 ep->id = (unsigned long) urb;
204 ep->busnum = rp->r.m_bus->u_bus->busnum;
161 ep->tstamp = stamp; 205 ep->tstamp = stamp;
162 ep->length = (ev_type == 'S') ? 206 ep->length = (ev_type == 'S') ?
163 urb->transfer_buffer_length : urb->actual_length; 207 urb->transfer_buffer_length : urb->actual_length;
164 /* Collecting status makes debugging sense for submits, too */ 208 /* Collecting status makes debugging sense for submits, too */
165 ep->status = urb->status; 209 ep->status = urb->status;
166 210
211 if (usb_pipeint(urb->pipe)) {
212 ep->interval = urb->interval;
213 } else if (usb_pipeisoc(urb->pipe)) {
214 ep->interval = urb->interval;
215 ep->start_frame = urb->start_frame;
216 ep->error_count = urb->error_count;
217 }
218 ep->numdesc = urb->number_of_packets;
219 if (usb_pipeisoc(urb->pipe) && urb->number_of_packets > 0) {
220 if ((ndesc = urb->number_of_packets) > ISODESC_MAX)
221 ndesc = ISODESC_MAX;
222 fp = urb->iso_frame_desc;
223 dp = ep->isodesc;
224 for (i = 0; i < ndesc; i++) {
225 dp->status = fp->status;
226 dp->offset = fp->offset;
227 dp->length = (ev_type == 'S') ?
228 fp->length : fp->actual_length;
229 fp++;
230 dp++;
231 }
232 }
233
167 ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus); 234 ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus);
168 ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type, 235 ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type,
169 rp->r.m_bus); 236 rp->r.m_bus);
@@ -199,6 +266,7 @@ static void mon_text_error(void *data, struct urb *urb, int error)
199 ep->type = 'E'; 266 ep->type = 'E';
200 ep->pipe = urb->pipe; 267 ep->pipe = urb->pipe;
201 ep->id = (unsigned long) urb; 268 ep->id = (unsigned long) urb;
269 ep->busnum = 0;
202 ep->tstamp = 0; 270 ep->tstamp = 0;
203 ep->length = 0; 271 ep->length = 0;
204 ep->status = error; 272 ep->status = error;
@@ -300,17 +368,75 @@ err_alloc:
300 * dd if=/dbg/usbmon/0t bs=10 368 * dd if=/dbg/usbmon/0t bs=10
301 * Also, we do not allow seeks and do not bother advancing the offset. 369 * Also, we do not allow seeks and do not bother advancing the offset.
302 */ 370 */
303static ssize_t mon_text_read(struct file *file, char __user *buf, 371static ssize_t mon_text_read_t(struct file *file, char __user *buf,
372 size_t nbytes, loff_t *ppos)
373{
374 struct mon_reader_text *rp = file->private_data;
375 struct mon_event_text *ep;
376 struct mon_text_ptr ptr;
377
378 if (IS_ERR(ep = mon_text_read_wait(rp, file)))
379 return PTR_ERR(ep);
380 mutex_lock(&rp->printf_lock);
381 ptr.cnt = 0;
382 ptr.pbuf = rp->printf_buf;
383 ptr.limit = rp->printf_size;
384
385 mon_text_read_head_t(rp, &ptr, ep);
386 mon_text_read_statset(rp, &ptr, ep);
387 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
388 " %d", ep->length);
389 mon_text_read_data(rp, &ptr, ep);
390
391 if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
392 ptr.cnt = -EFAULT;
393 mutex_unlock(&rp->printf_lock);
394 kmem_cache_free(rp->e_slab, ep);
395 return ptr.cnt;
396}
397
398static ssize_t mon_text_read_u(struct file *file, char __user *buf,
304 size_t nbytes, loff_t *ppos) 399 size_t nbytes, loff_t *ppos)
305{ 400{
306 struct mon_reader_text *rp = file->private_data; 401 struct mon_reader_text *rp = file->private_data;
402 struct mon_event_text *ep;
403 struct mon_text_ptr ptr;
404
405 if (IS_ERR(ep = mon_text_read_wait(rp, file)))
406 return PTR_ERR(ep);
407 mutex_lock(&rp->printf_lock);
408 ptr.cnt = 0;
409 ptr.pbuf = rp->printf_buf;
410 ptr.limit = rp->printf_size;
411
412 mon_text_read_head_u(rp, &ptr, ep);
413 if (ep->type == 'E') {
414 mon_text_read_statset(rp, &ptr, ep);
415 } else if (usb_pipeisoc(ep->pipe)) {
416 mon_text_read_isostat(rp, &ptr, ep);
417 mon_text_read_isodesc(rp, &ptr, ep);
418 } else if (usb_pipeint(ep->pipe)) {
419 mon_text_read_intstat(rp, &ptr, ep);
420 } else {
421 mon_text_read_statset(rp, &ptr, ep);
422 }
423 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
424 " %d", ep->length);
425 mon_text_read_data(rp, &ptr, ep);
426
427 if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
428 ptr.cnt = -EFAULT;
429 mutex_unlock(&rp->printf_lock);
430 kmem_cache_free(rp->e_slab, ep);
431 return ptr.cnt;
432}
433
434static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
435 struct file *file)
436{
307 struct mon_bus *mbus = rp->r.m_bus; 437 struct mon_bus *mbus = rp->r.m_bus;
308 DECLARE_WAITQUEUE(waita, current); 438 DECLARE_WAITQUEUE(waita, current);
309 struct mon_event_text *ep; 439 struct mon_event_text *ep;
310 int cnt, limit;
311 char *pbuf;
312 char udir, utype;
313 int data_len, i;
314 440
315 add_wait_queue(&rp->wait, &waita); 441 add_wait_queue(&rp->wait, &waita);
316 set_current_state(TASK_INTERRUPTIBLE); 442 set_current_state(TASK_INTERRUPTIBLE);
@@ -318,7 +444,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
318 if (file->f_flags & O_NONBLOCK) { 444 if (file->f_flags & O_NONBLOCK) {
319 set_current_state(TASK_RUNNING); 445 set_current_state(TASK_RUNNING);
320 remove_wait_queue(&rp->wait, &waita); 446 remove_wait_queue(&rp->wait, &waita);
321 return -EWOULDBLOCK; /* Same as EAGAIN in Linux */ 447 return ERR_PTR(-EWOULDBLOCK);
322 } 448 }
323 /* 449 /*
324 * We do not count nwaiters, because ->release is supposed 450 * We do not count nwaiters, because ->release is supposed
@@ -327,17 +453,19 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
327 schedule(); 453 schedule();
328 if (signal_pending(current)) { 454 if (signal_pending(current)) {
329 remove_wait_queue(&rp->wait, &waita); 455 remove_wait_queue(&rp->wait, &waita);
330 return -EINTR; 456 return ERR_PTR(-EINTR);
331 } 457 }
332 set_current_state(TASK_INTERRUPTIBLE); 458 set_current_state(TASK_INTERRUPTIBLE);
333 } 459 }
334 set_current_state(TASK_RUNNING); 460 set_current_state(TASK_RUNNING);
335 remove_wait_queue(&rp->wait, &waita); 461 remove_wait_queue(&rp->wait, &waita);
462 return ep;
463}
336 464
337 mutex_lock(&rp->printf_lock); 465static void mon_text_read_head_t(struct mon_reader_text *rp,
338 cnt = 0; 466 struct mon_text_ptr *p, const struct mon_event_text *ep)
339 pbuf = rp->printf_buf; 467{
340 limit = rp->printf_size; 468 char udir, utype;
341 469
342 udir = usb_pipein(ep->pipe) ? 'i' : 'o'; 470 udir = usb_pipein(ep->pipe) ? 'i' : 'o';
343 switch (usb_pipetype(ep->pipe)) { 471 switch (usb_pipetype(ep->pipe)) {
@@ -346,13 +474,38 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
346 case PIPE_CONTROL: utype = 'C'; break; 474 case PIPE_CONTROL: utype = 'C'; break;
347 default: /* PIPE_BULK */ utype = 'B'; 475 default: /* PIPE_BULK */ utype = 'B';
348 } 476 }
349 cnt += snprintf(pbuf + cnt, limit - cnt, 477 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
350 "%lx %u %c %c%c:%03u:%02u", 478 "%lx %u %c %c%c:%03u:%02u",
351 ep->id, ep->tstamp, ep->type, 479 ep->id, ep->tstamp, ep->type,
352 utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); 480 utype, udir,
481 usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));
482}
483
484static void mon_text_read_head_u(struct mon_reader_text *rp,
485 struct mon_text_ptr *p, const struct mon_event_text *ep)
486{
487 char udir, utype;
488
489 udir = usb_pipein(ep->pipe) ? 'i' : 'o';
490 switch (usb_pipetype(ep->pipe)) {
491 case PIPE_ISOCHRONOUS: utype = 'Z'; break;
492 case PIPE_INTERRUPT: utype = 'I'; break;
493 case PIPE_CONTROL: utype = 'C'; break;
494 default: /* PIPE_BULK */ utype = 'B';
495 }
496 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
497 "%lx %u %c %c%c:%d:%03u:%u",
498 ep->id, ep->tstamp, ep->type,
499 utype, udir,
500 ep->busnum, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));
501}
502
503static void mon_text_read_statset(struct mon_reader_text *rp,
504 struct mon_text_ptr *p, const struct mon_event_text *ep)
505{
353 506
354 if (ep->setup_flag == 0) { /* Setup packet is present and captured */ 507 if (ep->setup_flag == 0) { /* Setup packet is present and captured */
355 cnt += snprintf(pbuf + cnt, limit - cnt, 508 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
356 " s %02x %02x %04x %04x %04x", 509 " s %02x %02x %04x %04x %04x",
357 ep->setup[0], 510 ep->setup[0],
358 ep->setup[1], 511 ep->setup[1],
@@ -360,40 +513,86 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
360 (ep->setup[5] << 8) | ep->setup[4], 513 (ep->setup[5] << 8) | ep->setup[4],
361 (ep->setup[7] << 8) | ep->setup[6]); 514 (ep->setup[7] << 8) | ep->setup[6]);
362 } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */ 515 } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
363 cnt += snprintf(pbuf + cnt, limit - cnt, 516 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
364 " %c __ __ ____ ____ ____", ep->setup_flag); 517 " %c __ __ ____ ____ ____", ep->setup_flag);
365 } else { /* No setup for this kind of URB */ 518 } else { /* No setup for this kind of URB */
366 cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status); 519 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
520 " %d", ep->status);
521 }
522}
523
524static void mon_text_read_intstat(struct mon_reader_text *rp,
525 struct mon_text_ptr *p, const struct mon_event_text *ep)
526{
527 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
528 " %d:%d", ep->status, ep->interval);
529}
530
531static void mon_text_read_isostat(struct mon_reader_text *rp,
532 struct mon_text_ptr *p, const struct mon_event_text *ep)
533{
534 if (ep->type == 'S') {
535 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
536 " %d:%d:%d", ep->status, ep->interval, ep->start_frame);
537 } else {
538 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
539 " %d:%d:%d:%d",
540 ep->status, ep->interval, ep->start_frame, ep->error_count);
367 } 541 }
368 cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length); 542}
543
544static void mon_text_read_isodesc(struct mon_reader_text *rp,
545 struct mon_text_ptr *p, const struct mon_event_text *ep)
546{
547 int ndesc; /* Display this many */
548 int i;
549 const struct mon_iso_desc *dp;
550
551 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
552 " %d", ep->numdesc);
553 ndesc = ep->numdesc;
554 if (ndesc > ISODESC_MAX)
555 ndesc = ISODESC_MAX;
556 if (ndesc < 0)
557 ndesc = 0;
558 dp = ep->isodesc;
559 for (i = 0; i < ndesc; i++) {
560 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
561 " %d:%u:%u", dp->status, dp->offset, dp->length);
562 dp++;
563 }
564}
565
566static void mon_text_read_data(struct mon_reader_text *rp,
567 struct mon_text_ptr *p, const struct mon_event_text *ep)
568{
569 int data_len, i;
369 570
370 if ((data_len = ep->length) > 0) { 571 if ((data_len = ep->length) > 0) {
371 if (ep->data_flag == 0) { 572 if (ep->data_flag == 0) {
372 cnt += snprintf(pbuf + cnt, limit - cnt, " ="); 573 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
574 " =");
373 if (data_len >= DATA_MAX) 575 if (data_len >= DATA_MAX)
374 data_len = DATA_MAX; 576 data_len = DATA_MAX;
375 for (i = 0; i < data_len; i++) { 577 for (i = 0; i < data_len; i++) {
376 if (i % 4 == 0) { 578 if (i % 4 == 0) {
377 cnt += snprintf(pbuf + cnt, limit - cnt, 579 p->cnt += snprintf(p->pbuf + p->cnt,
580 p->limit - p->cnt,
378 " "); 581 " ");
379 } 582 }
380 cnt += snprintf(pbuf + cnt, limit - cnt, 583 p->cnt += snprintf(p->pbuf + p->cnt,
584 p->limit - p->cnt,
381 "%02x", ep->data[i]); 585 "%02x", ep->data[i]);
382 } 586 }
383 cnt += snprintf(pbuf + cnt, limit - cnt, "\n"); 587 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
588 "\n");
384 } else { 589 } else {
385 cnt += snprintf(pbuf + cnt, limit - cnt, 590 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
386 " %c\n", ep->data_flag); 591 " %c\n", ep->data_flag);
387 } 592 }
388 } else { 593 } else {
389 cnt += snprintf(pbuf + cnt, limit - cnt, "\n"); 594 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, "\n");
390 } 595 }
391
392 if (copy_to_user(buf, rp->printf_buf, cnt))
393 cnt = -EFAULT;
394 mutex_unlock(&rp->printf_lock);
395 kmem_cache_free(rp->e_slab, ep);
396 return cnt;
397} 596}
398 597
399static int mon_text_release(struct inode *inode, struct file *file) 598static int mon_text_release(struct inode *inode, struct file *file)
@@ -439,14 +638,19 @@ static int mon_text_release(struct inode *inode, struct file *file)
439 return 0; 638 return 0;
440} 639}
441 640
442static const struct file_operations mon_fops_text = { 641static const struct file_operations mon_fops_text_t = {
443 .owner = THIS_MODULE, 642 .owner = THIS_MODULE,
444 .open = mon_text_open, 643 .open = mon_text_open,
445 .llseek = no_llseek, 644 .llseek = no_llseek,
446 .read = mon_text_read, 645 .read = mon_text_read_t,
447 /* .write = mon_text_write, */ 646 .release = mon_text_release,
448 /* .poll = mon_text_poll, */ 647};
449 /* .ioctl = mon_text_ioctl, */ 648
649static const struct file_operations mon_fops_text_u = {
650 .owner = THIS_MODULE,
651 .open = mon_text_open,
652 .llseek = no_llseek,
653 .read = mon_text_read_u,
450 .release = mon_text_release, 654 .release = mon_text_release,
451}; 655};
452 656
@@ -460,12 +664,19 @@ int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
460 rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); 664 rc = snprintf(name, NAMESZ, "%dt", ubus->busnum);
461 if (rc <= 0 || rc >= NAMESZ) 665 if (rc <= 0 || rc >= NAMESZ)
462 goto err_print_t; 666 goto err_print_t;
463 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text); 667 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t);
464 if (d == NULL) 668 if (d == NULL)
465 goto err_create_t; 669 goto err_create_t;
466 mbus->dent_t = d; 670 mbus->dent_t = d;
467 671
468 /* XXX The stats do not belong to here (text API), but oh well... */ 672 rc = snprintf(name, NAMESZ, "%du", ubus->busnum);
673 if (rc <= 0 || rc >= NAMESZ)
674 goto err_print_u;
675 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u);
676 if (d == NULL)
677 goto err_create_u;
678 mbus->dent_u = d;
679
469 rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); 680 rc = snprintf(name, NAMESZ, "%ds", ubus->busnum);
470 if (rc <= 0 || rc >= NAMESZ) 681 if (rc <= 0 || rc >= NAMESZ)
471 goto err_print_s; 682 goto err_print_s;
@@ -478,6 +689,10 @@ int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
478 689
479err_create_s: 690err_create_s:
480err_print_s: 691err_print_s:
692 debugfs_remove(mbus->dent_u);
693 mbus->dent_u = NULL;
694err_create_u:
695err_print_u:
481 debugfs_remove(mbus->dent_t); 696 debugfs_remove(mbus->dent_t);
482 mbus->dent_t = NULL; 697 mbus->dent_t = NULL;
483err_create_t: 698err_create_t:
@@ -487,6 +702,7 @@ err_print_t:
487 702
488void mon_text_del(struct mon_bus *mbus) 703void mon_text_del(struct mon_bus *mbus)
489{ 704{
705 debugfs_remove(mbus->dent_u);
490 debugfs_remove(mbus->dent_t); 706 debugfs_remove(mbus->dent_t);
491 debugfs_remove(mbus->dent_s); 707 debugfs_remove(mbus->dent_s);
492} 708}
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index efdfd8993d9e..a1e2b8e9d777 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -22,6 +22,7 @@ struct mon_bus {
22 int text_inited; 22 int text_inited;
23 struct dentry *dent_s; /* Debugging file */ 23 struct dentry *dent_s; /* Debugging file */
24 struct dentry *dent_t; /* Text interface file */ 24 struct dentry *dent_t; /* Text interface file */
25 struct dentry *dent_u; /* Second text interface file */
25 int uses_dma; 26 int uses_dma;
26 27
27 /* Ref */ 28 /* Ref */