aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/mon/mon_text.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/mon/mon_text.c')
-rw-r--r--drivers/usb/mon/mon_text.c315
1 files changed, 266 insertions, 49 deletions
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 494ee3b9a226..ec0cc51e39ac 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
@@ -84,8 +124,10 @@ static inline char mon_text_get_setup(struct mon_event_text *ep,
84 if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') 124 if (!usb_pipecontrol(urb->pipe) || ev_type != 'S')
85 return '-'; 125 return '-';
86 126
87 if (mbus->uses_dma && (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) 127 if (urb->dev->bus->uses_dma &&
128 (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
88 return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); 129 return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX);
130 }
89 if (urb->setup_packet == NULL) 131 if (urb->setup_packet == NULL)
90 return 'Z'; /* '0' would be not as pretty. */ 132 return 'Z'; /* '0' would be not as pretty. */
91 133
@@ -104,10 +146,10 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
104 len = DATA_MAX; 146 len = DATA_MAX;
105 147
106 if (usb_pipein(pipe)) { 148 if (usb_pipein(pipe)) {
107 if (ev_type == 'S') 149 if (ev_type != 'C')
108 return '<'; 150 return '<';
109 } else { 151 } else {
110 if (ev_type == 'C') 152 if (ev_type != 'S')
111 return '>'; 153 return '>';
112 } 154 }
113 155
@@ -120,8 +162,10 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
120 * contain non-NULL garbage in case the upper level promised to 162 * contain non-NULL garbage in case the upper level promised to
121 * set DMA for the HCD. 163 * set DMA for the HCD.
122 */ 164 */
123 if (mbus->uses_dma && (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) 165 if (urb->dev->bus->uses_dma &&
166 (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
124 return mon_dmapeek(ep->data, urb->transfer_dma, len); 167 return mon_dmapeek(ep->data, urb->transfer_dma, len);
168 }
125 169
126 if (urb->transfer_buffer == NULL) 170 if (urb->transfer_buffer == NULL)
127 return 'Z'; /* '0' would be not as pretty. */ 171 return 'Z'; /* '0' would be not as pretty. */
@@ -146,6 +190,9 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
146{ 190{
147 struct mon_event_text *ep; 191 struct mon_event_text *ep;
148 unsigned int stamp; 192 unsigned int stamp;
193 struct usb_iso_packet_descriptor *fp;
194 struct mon_iso_desc *dp;
195 int i, ndesc;
149 196
150 stamp = mon_get_timestamp(); 197 stamp = mon_get_timestamp();
151 198
@@ -158,12 +205,36 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
158 ep->type = ev_type; 205 ep->type = ev_type;
159 ep->pipe = urb->pipe; 206 ep->pipe = urb->pipe;
160 ep->id = (unsigned long) urb; 207 ep->id = (unsigned long) urb;
208 ep->busnum = urb->dev->bus->busnum;
161 ep->tstamp = stamp; 209 ep->tstamp = stamp;
162 ep->length = (ev_type == 'S') ? 210 ep->length = (ev_type == 'S') ?
163 urb->transfer_buffer_length : urb->actual_length; 211 urb->transfer_buffer_length : urb->actual_length;
164 /* Collecting status makes debugging sense for submits, too */ 212 /* Collecting status makes debugging sense for submits, too */
165 ep->status = urb->status; 213 ep->status = urb->status;
166 214
215 if (usb_pipeint(urb->pipe)) {
216 ep->interval = urb->interval;
217 } else if (usb_pipeisoc(urb->pipe)) {
218 ep->interval = urb->interval;
219 ep->start_frame = urb->start_frame;
220 ep->error_count = urb->error_count;
221 }
222 ep->numdesc = urb->number_of_packets;
223 if (usb_pipeisoc(urb->pipe) && urb->number_of_packets > 0) {
224 if ((ndesc = urb->number_of_packets) > ISODESC_MAX)
225 ndesc = ISODESC_MAX;
226 fp = urb->iso_frame_desc;
227 dp = ep->isodesc;
228 for (i = 0; i < ndesc; i++) {
229 dp->status = fp->status;
230 dp->offset = fp->offset;
231 dp->length = (ev_type == 'S') ?
232 fp->length : fp->actual_length;
233 fp++;
234 dp++;
235 }
236 }
237
167 ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus); 238 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, 239 ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type,
169 rp->r.m_bus); 240 rp->r.m_bus);
@@ -199,6 +270,7 @@ static void mon_text_error(void *data, struct urb *urb, int error)
199 ep->type = 'E'; 270 ep->type = 'E';
200 ep->pipe = urb->pipe; 271 ep->pipe = urb->pipe;
201 ep->id = (unsigned long) urb; 272 ep->id = (unsigned long) urb;
273 ep->busnum = 0;
202 ep->tstamp = 0; 274 ep->tstamp = 0;
203 ep->length = 0; 275 ep->length = 0;
204 ep->status = error; 276 ep->status = error;
@@ -237,13 +309,11 @@ static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
237static int mon_text_open(struct inode *inode, struct file *file) 309static int mon_text_open(struct inode *inode, struct file *file)
238{ 310{
239 struct mon_bus *mbus; 311 struct mon_bus *mbus;
240 struct usb_bus *ubus;
241 struct mon_reader_text *rp; 312 struct mon_reader_text *rp;
242 int rc; 313 int rc;
243 314
244 mutex_lock(&mon_lock); 315 mutex_lock(&mon_lock);
245 mbus = inode->i_private; 316 mbus = inode->i_private;
246 ubus = mbus->u_bus;
247 317
248 rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); 318 rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL);
249 if (rp == NULL) { 319 if (rp == NULL) {
@@ -267,8 +337,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
267 rp->r.rnf_error = mon_text_error; 337 rp->r.rnf_error = mon_text_error;
268 rp->r.rnf_complete = mon_text_complete; 338 rp->r.rnf_complete = mon_text_complete;
269 339
270 snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, 340 snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp);
271 (long)rp);
272 rp->e_slab = kmem_cache_create(rp->slab_name, 341 rp->e_slab = kmem_cache_create(rp->slab_name,
273 sizeof(struct mon_event_text), sizeof(long), 0, 342 sizeof(struct mon_event_text), sizeof(long), 0,
274 mon_text_ctor, NULL); 343 mon_text_ctor, NULL);
@@ -300,17 +369,75 @@ err_alloc:
300 * dd if=/dbg/usbmon/0t bs=10 369 * dd if=/dbg/usbmon/0t bs=10
301 * Also, we do not allow seeks and do not bother advancing the offset. 370 * Also, we do not allow seeks and do not bother advancing the offset.
302 */ 371 */
303static ssize_t mon_text_read(struct file *file, char __user *buf, 372static ssize_t mon_text_read_t(struct file *file, char __user *buf,
304 size_t nbytes, loff_t *ppos) 373 size_t nbytes, loff_t *ppos)
305{ 374{
306 struct mon_reader_text *rp = file->private_data; 375 struct mon_reader_text *rp = file->private_data;
376 struct mon_event_text *ep;
377 struct mon_text_ptr ptr;
378
379 if (IS_ERR(ep = mon_text_read_wait(rp, file)))
380 return PTR_ERR(ep);
381 mutex_lock(&rp->printf_lock);
382 ptr.cnt = 0;
383 ptr.pbuf = rp->printf_buf;
384 ptr.limit = rp->printf_size;
385
386 mon_text_read_head_t(rp, &ptr, ep);
387 mon_text_read_statset(rp, &ptr, ep);
388 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
389 " %d", ep->length);
390 mon_text_read_data(rp, &ptr, ep);
391
392 if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
393 ptr.cnt = -EFAULT;
394 mutex_unlock(&rp->printf_lock);
395 kmem_cache_free(rp->e_slab, ep);
396 return ptr.cnt;
397}
398
399static ssize_t mon_text_read_u(struct file *file, char __user *buf,
400 size_t nbytes, loff_t *ppos)
401{
402 struct mon_reader_text *rp = file->private_data;
403 struct mon_event_text *ep;
404 struct mon_text_ptr ptr;
405
406 if (IS_ERR(ep = mon_text_read_wait(rp, file)))
407 return PTR_ERR(ep);
408 mutex_lock(&rp->printf_lock);
409 ptr.cnt = 0;
410 ptr.pbuf = rp->printf_buf;
411 ptr.limit = rp->printf_size;
412
413 mon_text_read_head_u(rp, &ptr, ep);
414 if (ep->type == 'E') {
415 mon_text_read_statset(rp, &ptr, ep);
416 } else if (usb_pipeisoc(ep->pipe)) {
417 mon_text_read_isostat(rp, &ptr, ep);
418 mon_text_read_isodesc(rp, &ptr, ep);
419 } else if (usb_pipeint(ep->pipe)) {
420 mon_text_read_intstat(rp, &ptr, ep);
421 } else {
422 mon_text_read_statset(rp, &ptr, ep);
423 }
424 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
425 " %d", ep->length);
426 mon_text_read_data(rp, &ptr, ep);
427
428 if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
429 ptr.cnt = -EFAULT;
430 mutex_unlock(&rp->printf_lock);
431 kmem_cache_free(rp->e_slab, ep);
432 return ptr.cnt;
433}
434
435static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
436 struct file *file)
437{
307 struct mon_bus *mbus = rp->r.m_bus; 438 struct mon_bus *mbus = rp->r.m_bus;
308 DECLARE_WAITQUEUE(waita, current); 439 DECLARE_WAITQUEUE(waita, current);
309 struct mon_event_text *ep; 440 struct mon_event_text *ep;
310 int cnt, limit;
311 char *pbuf;
312 char udir, utype;
313 int data_len, i;
314 441
315 add_wait_queue(&rp->wait, &waita); 442 add_wait_queue(&rp->wait, &waita);
316 set_current_state(TASK_INTERRUPTIBLE); 443 set_current_state(TASK_INTERRUPTIBLE);
@@ -318,7 +445,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
318 if (file->f_flags & O_NONBLOCK) { 445 if (file->f_flags & O_NONBLOCK) {
319 set_current_state(TASK_RUNNING); 446 set_current_state(TASK_RUNNING);
320 remove_wait_queue(&rp->wait, &waita); 447 remove_wait_queue(&rp->wait, &waita);
321 return -EWOULDBLOCK; /* Same as EAGAIN in Linux */ 448 return ERR_PTR(-EWOULDBLOCK);
322 } 449 }
323 /* 450 /*
324 * We do not count nwaiters, because ->release is supposed 451 * We do not count nwaiters, because ->release is supposed
@@ -327,17 +454,19 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
327 schedule(); 454 schedule();
328 if (signal_pending(current)) { 455 if (signal_pending(current)) {
329 remove_wait_queue(&rp->wait, &waita); 456 remove_wait_queue(&rp->wait, &waita);
330 return -EINTR; 457 return ERR_PTR(-EINTR);
331 } 458 }
332 set_current_state(TASK_INTERRUPTIBLE); 459 set_current_state(TASK_INTERRUPTIBLE);
333 } 460 }
334 set_current_state(TASK_RUNNING); 461 set_current_state(TASK_RUNNING);
335 remove_wait_queue(&rp->wait, &waita); 462 remove_wait_queue(&rp->wait, &waita);
463 return ep;
464}
336 465
337 mutex_lock(&rp->printf_lock); 466static void mon_text_read_head_t(struct mon_reader_text *rp,
338 cnt = 0; 467 struct mon_text_ptr *p, const struct mon_event_text *ep)
339 pbuf = rp->printf_buf; 468{
340 limit = rp->printf_size; 469 char udir, utype;
341 470
342 udir = usb_pipein(ep->pipe) ? 'i' : 'o'; 471 udir = usb_pipein(ep->pipe) ? 'i' : 'o';
343 switch (usb_pipetype(ep->pipe)) { 472 switch (usb_pipetype(ep->pipe)) {
@@ -346,13 +475,38 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
346 case PIPE_CONTROL: utype = 'C'; break; 475 case PIPE_CONTROL: utype = 'C'; break;
347 default: /* PIPE_BULK */ utype = 'B'; 476 default: /* PIPE_BULK */ utype = 'B';
348 } 477 }
349 cnt += snprintf(pbuf + cnt, limit - cnt, 478 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
350 "%lx %u %c %c%c:%03u:%02u", 479 "%lx %u %c %c%c:%03u:%02u",
351 ep->id, ep->tstamp, ep->type, 480 ep->id, ep->tstamp, ep->type,
352 utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); 481 utype, udir,
482 usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));
483}
484
485static void mon_text_read_head_u(struct mon_reader_text *rp,
486 struct mon_text_ptr *p, const struct mon_event_text *ep)
487{
488 char udir, utype;
489
490 udir = usb_pipein(ep->pipe) ? 'i' : 'o';
491 switch (usb_pipetype(ep->pipe)) {
492 case PIPE_ISOCHRONOUS: utype = 'Z'; break;
493 case PIPE_INTERRUPT: utype = 'I'; break;
494 case PIPE_CONTROL: utype = 'C'; break;
495 default: /* PIPE_BULK */ utype = 'B';
496 }
497 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
498 "%lx %u %c %c%c:%d:%03u:%u",
499 ep->id, ep->tstamp, ep->type,
500 utype, udir,
501 ep->busnum, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));
502}
503
504static void mon_text_read_statset(struct mon_reader_text *rp,
505 struct mon_text_ptr *p, const struct mon_event_text *ep)
506{
353 507
354 if (ep->setup_flag == 0) { /* Setup packet is present and captured */ 508 if (ep->setup_flag == 0) { /* Setup packet is present and captured */
355 cnt += snprintf(pbuf + cnt, limit - cnt, 509 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
356 " s %02x %02x %04x %04x %04x", 510 " s %02x %02x %04x %04x %04x",
357 ep->setup[0], 511 ep->setup[0],
358 ep->setup[1], 512 ep->setup[1],
@@ -360,40 +514,86 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
360 (ep->setup[5] << 8) | ep->setup[4], 514 (ep->setup[5] << 8) | ep->setup[4],
361 (ep->setup[7] << 8) | ep->setup[6]); 515 (ep->setup[7] << 8) | ep->setup[6]);
362 } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */ 516 } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
363 cnt += snprintf(pbuf + cnt, limit - cnt, 517 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
364 " %c __ __ ____ ____ ____", ep->setup_flag); 518 " %c __ __ ____ ____ ____", ep->setup_flag);
365 } else { /* No setup for this kind of URB */ 519 } else { /* No setup for this kind of URB */
366 cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status); 520 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
521 " %d", ep->status);
367 } 522 }
368 cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length); 523}
524
525static void mon_text_read_intstat(struct mon_reader_text *rp,
526 struct mon_text_ptr *p, const struct mon_event_text *ep)
527{
528 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
529 " %d:%d", ep->status, ep->interval);
530}
531
532static void mon_text_read_isostat(struct mon_reader_text *rp,
533 struct mon_text_ptr *p, const struct mon_event_text *ep)
534{
535 if (ep->type == 'S') {
536 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
537 " %d:%d:%d", ep->status, ep->interval, ep->start_frame);
538 } else {
539 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
540 " %d:%d:%d:%d",
541 ep->status, ep->interval, ep->start_frame, ep->error_count);
542 }
543}
544
545static void mon_text_read_isodesc(struct mon_reader_text *rp,
546 struct mon_text_ptr *p, const struct mon_event_text *ep)
547{
548 int ndesc; /* Display this many */
549 int i;
550 const struct mon_iso_desc *dp;
551
552 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
553 " %d", ep->numdesc);
554 ndesc = ep->numdesc;
555 if (ndesc > ISODESC_MAX)
556 ndesc = ISODESC_MAX;
557 if (ndesc < 0)
558 ndesc = 0;
559 dp = ep->isodesc;
560 for (i = 0; i < ndesc; i++) {
561 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
562 " %d:%u:%u", dp->status, dp->offset, dp->length);
563 dp++;
564 }
565}
566
567static void mon_text_read_data(struct mon_reader_text *rp,
568 struct mon_text_ptr *p, const struct mon_event_text *ep)
569{
570 int data_len, i;
369 571
370 if ((data_len = ep->length) > 0) { 572 if ((data_len = ep->length) > 0) {
371 if (ep->data_flag == 0) { 573 if (ep->data_flag == 0) {
372 cnt += snprintf(pbuf + cnt, limit - cnt, " ="); 574 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
575 " =");
373 if (data_len >= DATA_MAX) 576 if (data_len >= DATA_MAX)
374 data_len = DATA_MAX; 577 data_len = DATA_MAX;
375 for (i = 0; i < data_len; i++) { 578 for (i = 0; i < data_len; i++) {
376 if (i % 4 == 0) { 579 if (i % 4 == 0) {
377 cnt += snprintf(pbuf + cnt, limit - cnt, 580 p->cnt += snprintf(p->pbuf + p->cnt,
581 p->limit - p->cnt,
378 " "); 582 " ");
379 } 583 }
380 cnt += snprintf(pbuf + cnt, limit - cnt, 584 p->cnt += snprintf(p->pbuf + p->cnt,
585 p->limit - p->cnt,
381 "%02x", ep->data[i]); 586 "%02x", ep->data[i]);
382 } 587 }
383 cnt += snprintf(pbuf + cnt, limit - cnt, "\n"); 588 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
589 "\n");
384 } else { 590 } else {
385 cnt += snprintf(pbuf + cnt, limit - cnt, 591 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
386 " %c\n", ep->data_flag); 592 " %c\n", ep->data_flag);
387 } 593 }
388 } else { 594 } else {
389 cnt += snprintf(pbuf + cnt, limit - cnt, "\n"); 595 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, "\n");
390 } 596 }
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} 597}
398 598
399static int mon_text_release(struct inode *inode, struct file *file) 599static int mon_text_release(struct inode *inode, struct file *file)
@@ -439,34 +639,46 @@ static int mon_text_release(struct inode *inode, struct file *file)
439 return 0; 639 return 0;
440} 640}
441 641
442static const struct file_operations mon_fops_text = { 642static const struct file_operations mon_fops_text_t = {
443 .owner = THIS_MODULE, 643 .owner = THIS_MODULE,
444 .open = mon_text_open, 644 .open = mon_text_open,
445 .llseek = no_llseek, 645 .llseek = no_llseek,
446 .read = mon_text_read, 646 .read = mon_text_read_t,
447 /* .write = mon_text_write, */
448 /* .poll = mon_text_poll, */
449 /* .ioctl = mon_text_ioctl, */
450 .release = mon_text_release, 647 .release = mon_text_release,
451}; 648};
452 649
453int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) 650static const struct file_operations mon_fops_text_u = {
651 .owner = THIS_MODULE,
652 .open = mon_text_open,
653 .llseek = no_llseek,
654 .read = mon_text_read_u,
655 .release = mon_text_release,
656};
657
658int mon_text_add(struct mon_bus *mbus, int busnum)
454{ 659{
455 struct dentry *d; 660 struct dentry *d;
456 enum { NAMESZ = 10 }; 661 enum { NAMESZ = 10 };
457 char name[NAMESZ]; 662 char name[NAMESZ];
458 int rc; 663 int rc;
459 664
460 rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); 665 rc = snprintf(name, NAMESZ, "%dt", busnum);
461 if (rc <= 0 || rc >= NAMESZ) 666 if (rc <= 0 || rc >= NAMESZ)
462 goto err_print_t; 667 goto err_print_t;
463 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text); 668 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t);
464 if (d == NULL) 669 if (d == NULL)
465 goto err_create_t; 670 goto err_create_t;
466 mbus->dent_t = d; 671 mbus->dent_t = d;
467 672
468 /* XXX The stats do not belong to here (text API), but oh well... */ 673 rc = snprintf(name, NAMESZ, "%du", busnum);
469 rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); 674 if (rc <= 0 || rc >= NAMESZ)
675 goto err_print_u;
676 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u);
677 if (d == NULL)
678 goto err_create_u;
679 mbus->dent_u = d;
680
681 rc = snprintf(name, NAMESZ, "%ds", busnum);
470 if (rc <= 0 || rc >= NAMESZ) 682 if (rc <= 0 || rc >= NAMESZ)
471 goto err_print_s; 683 goto err_print_s;
472 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); 684 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat);
@@ -478,6 +690,10 @@ int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
478 690
479err_create_s: 691err_create_s:
480err_print_s: 692err_print_s:
693 debugfs_remove(mbus->dent_u);
694 mbus->dent_u = NULL;
695err_create_u:
696err_print_u:
481 debugfs_remove(mbus->dent_t); 697 debugfs_remove(mbus->dent_t);
482 mbus->dent_t = NULL; 698 mbus->dent_t = NULL;
483err_create_t: 699err_create_t:
@@ -487,6 +703,7 @@ err_print_t:
487 703
488void mon_text_del(struct mon_bus *mbus) 704void mon_text_del(struct mon_bus *mbus)
489{ 705{
706 debugfs_remove(mbus->dent_u);
490 debugfs_remove(mbus->dent_t); 707 debugfs_remove(mbus->dent_t);
491 debugfs_remove(mbus->dent_s); 708 debugfs_remove(mbus->dent_s);
492} 709}