root/drivers/usb/mon/mon_text.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mon_text_get_setup
  2. mon_text_get_data
  3. mon_get_timestamp
  4. mon_text_event
  5. mon_text_submit
  6. mon_text_complete
  7. mon_text_error
  8. mon_text_fetch
  9. mon_text_open
  10. mon_text_copy_to_user
  11. mon_text_read_t
  12. mon_text_read_u
  13. mon_text_read_wait
  14. mon_text_read_head_t
  15. mon_text_read_head_u
  16. mon_text_read_statset
  17. mon_text_read_intstat
  18. mon_text_read_isostat
  19. mon_text_read_isodesc
  20. mon_text_read_data
  21. mon_text_release
  22. mon_text_add
  23. mon_text_del
  24. mon_text_ctor
  25. mon_text_init
  26. mon_text_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * The USB Monitor, inspired by Dave Harding's USBMon.
   4  *
   5  * This is a text format reader.
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/list.h>
  10 #include <linux/usb.h>
  11 #include <linux/slab.h>
  12 #include <linux/sched/signal.h>
  13 #include <linux/time.h>
  14 #include <linux/ktime.h>
  15 #include <linux/export.h>
  16 #include <linux/mutex.h>
  17 #include <linux/debugfs.h>
  18 #include <linux/scatterlist.h>
  19 #include <linux/uaccess.h>
  20 
  21 #include "usb_mon.h"
  22 
  23 /*
  24  * No, we do not want arbitrarily long data strings.
  25  * Use the binary interface if you want to capture bulk data!
  26  */
  27 #define DATA_MAX  32
  28 
  29 /*
  30  * Defined by USB 2.0 clause 9.3, table 9.2.
  31  */
  32 #define SETUP_MAX  8
  33 
  34 /*
  35  * This limit exists to prevent OOMs when the user process stops reading.
  36  * If usbmon were available to unprivileged processes, it might be open
  37  * to a local DoS. But we have to keep to root in order to prevent
  38  * password sniffing from HID devices.
  39  */
  40 #define EVENT_MAX  (4*PAGE_SIZE / sizeof(struct mon_event_text))
  41 
  42 /*
  43  * Potentially unlimited number; we limit it for similar allocations.
  44  * The usbfs limits this to 128, but we're not quite as generous.
  45  */
  46 #define ISODESC_MAX   5
  47 
  48 #define PRINTF_DFL  250   /* with 5 ISOs segs */
  49 
  50 struct mon_iso_desc {
  51         int status;
  52         unsigned int offset;
  53         unsigned int length;    /* Unsigned here, signed in URB. Historic. */
  54 };
  55 
  56 struct mon_event_text {
  57         struct list_head e_link;
  58         int type;               /* submit, complete, etc. */
  59         unsigned long id;       /* From pointer, most of the time */
  60         unsigned int tstamp;
  61         int busnum;
  62         char devnum;
  63         char epnum;
  64         char is_in;
  65         char xfertype;
  66         int length;             /* Depends on type: xfer length or act length */
  67         int status;
  68         int interval;
  69         int start_frame;
  70         int error_count;
  71         char setup_flag;
  72         char data_flag;
  73         int numdesc;            /* Full number */
  74         struct mon_iso_desc isodesc[ISODESC_MAX];
  75         unsigned char setup[SETUP_MAX];
  76         unsigned char data[DATA_MAX];
  77 };
  78 
  79 #define SLAB_NAME_SZ  30
  80 struct mon_reader_text {
  81         struct kmem_cache *e_slab;
  82         int nevents;
  83         struct list_head e_list;
  84         struct mon_reader r;    /* In C, parent class can be placed anywhere */
  85 
  86         wait_queue_head_t wait;
  87         int printf_size;
  88         size_t printf_offset;
  89         size_t printf_togo;
  90         char *printf_buf;
  91         struct mutex printf_lock;
  92 
  93         char slab_name[SLAB_NAME_SZ];
  94 };
  95 
  96 static struct dentry *mon_dir;          /* Usually /sys/kernel/debug/usbmon */
  97 
  98 static void mon_text_ctor(void *);
  99 
 100 struct mon_text_ptr {
 101         int cnt, limit;
 102         char *pbuf;
 103 };
 104 
 105 static struct mon_event_text *
 106     mon_text_read_wait(struct mon_reader_text *rp, struct file *file);
 107 static void mon_text_read_head_t(struct mon_reader_text *rp,
 108         struct mon_text_ptr *p, const struct mon_event_text *ep);
 109 static void mon_text_read_head_u(struct mon_reader_text *rp,
 110         struct mon_text_ptr *p, const struct mon_event_text *ep);
 111 static void mon_text_read_statset(struct mon_reader_text *rp,
 112         struct mon_text_ptr *p, const struct mon_event_text *ep);
 113 static void mon_text_read_intstat(struct mon_reader_text *rp,
 114         struct mon_text_ptr *p, const struct mon_event_text *ep);
 115 static void mon_text_read_isostat(struct mon_reader_text *rp,
 116         struct mon_text_ptr *p, const struct mon_event_text *ep);
 117 static void mon_text_read_isodesc(struct mon_reader_text *rp,
 118         struct mon_text_ptr *p, const struct mon_event_text *ep);
 119 static void mon_text_read_data(struct mon_reader_text *rp,
 120     struct mon_text_ptr *p, const struct mon_event_text *ep);
 121 
 122 /*
 123  * mon_text_submit
 124  * mon_text_complete
 125  *
 126  * May be called from an interrupt.
 127  *
 128  * This is called with the whole mon_bus locked, so no additional lock.
 129  */
 130 
 131 static inline char mon_text_get_setup(struct mon_event_text *ep,
 132     struct urb *urb, char ev_type, struct mon_bus *mbus)
 133 {
 134 
 135         if (ep->xfertype != USB_ENDPOINT_XFER_CONTROL || ev_type != 'S')
 136                 return '-';
 137 
 138         if (urb->setup_packet == NULL)
 139                 return 'Z';     /* '0' would be not as pretty. */
 140 
 141         memcpy(ep->setup, urb->setup_packet, SETUP_MAX);
 142         return 0;
 143 }
 144 
 145 static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
 146     int len, char ev_type, struct mon_bus *mbus)
 147 {
 148         void *src;
 149 
 150         if (len <= 0)
 151                 return 'L';
 152         if (len >= DATA_MAX)
 153                 len = DATA_MAX;
 154 
 155         if (ep->is_in) {
 156                 if (ev_type != 'C')
 157                         return '<';
 158         } else {
 159                 if (ev_type != 'S')
 160                         return '>';
 161         }
 162 
 163         if (urb->num_sgs == 0) {
 164                 src = urb->transfer_buffer;
 165                 if (src == NULL)
 166                         return 'Z';     /* '0' would be not as pretty. */
 167         } else {
 168                 struct scatterlist *sg = urb->sg;
 169 
 170                 if (PageHighMem(sg_page(sg)))
 171                         return 'D';
 172 
 173                 /* For the text interface we copy only the first sg buffer */
 174                 len = min_t(int, sg->length, len);
 175                 src = sg_virt(sg);
 176         }
 177 
 178         memcpy(ep->data, src, len);
 179         return 0;
 180 }
 181 
 182 static inline unsigned int mon_get_timestamp(void)
 183 {
 184         struct timespec64 now;
 185         unsigned int stamp;
 186 
 187         ktime_get_ts64(&now);
 188         stamp = now.tv_sec & 0xFFF;  /* 2^32 = 4294967296. Limit to 4096s. */
 189         stamp = stamp * USEC_PER_SEC + now.tv_nsec / NSEC_PER_USEC;
 190         return stamp;
 191 }
 192 
 193 static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
 194     char ev_type, int status)
 195 {
 196         struct mon_event_text *ep;
 197         unsigned int stamp;
 198         struct usb_iso_packet_descriptor *fp;
 199         struct mon_iso_desc *dp;
 200         int i, ndesc;
 201 
 202         stamp = mon_get_timestamp();
 203 
 204         if (rp->nevents >= EVENT_MAX ||
 205             (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
 206                 rp->r.m_bus->cnt_text_lost++;
 207                 return;
 208         }
 209 
 210         ep->type = ev_type;
 211         ep->id = (unsigned long) urb;
 212         ep->busnum = urb->dev->bus->busnum;
 213         ep->devnum = urb->dev->devnum;
 214         ep->epnum = usb_endpoint_num(&urb->ep->desc);
 215         ep->xfertype = usb_endpoint_type(&urb->ep->desc);
 216         ep->is_in = usb_urb_dir_in(urb);
 217         ep->tstamp = stamp;
 218         ep->length = (ev_type == 'S') ?
 219             urb->transfer_buffer_length : urb->actual_length;
 220         /* Collecting status makes debugging sense for submits, too */
 221         ep->status = status;
 222 
 223         if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
 224                 ep->interval = urb->interval;
 225         } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
 226                 ep->interval = urb->interval;
 227                 ep->start_frame = urb->start_frame;
 228                 ep->error_count = urb->error_count;
 229         }
 230         ep->numdesc = urb->number_of_packets;
 231         if (ep->xfertype == USB_ENDPOINT_XFER_ISOC &&
 232                         urb->number_of_packets > 0) {
 233                 if ((ndesc = urb->number_of_packets) > ISODESC_MAX)
 234                         ndesc = ISODESC_MAX;
 235                 fp = urb->iso_frame_desc;
 236                 dp = ep->isodesc;
 237                 for (i = 0; i < ndesc; i++) {
 238                         dp->status = fp->status;
 239                         dp->offset = fp->offset;
 240                         dp->length = (ev_type == 'S') ?
 241                             fp->length : fp->actual_length;
 242                         fp++;
 243                         dp++;
 244                 }
 245                 /* Wasteful, but simple to understand: ISO 'C' is sparse. */
 246                 if (ev_type == 'C')
 247                         ep->length = urb->transfer_buffer_length;
 248         }
 249 
 250         ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus);
 251         ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type,
 252                         rp->r.m_bus);
 253 
 254         rp->nevents++;
 255         list_add_tail(&ep->e_link, &rp->e_list);
 256         wake_up(&rp->wait);
 257 }
 258 
 259 static void mon_text_submit(void *data, struct urb *urb)
 260 {
 261         struct mon_reader_text *rp = data;
 262         mon_text_event(rp, urb, 'S', -EINPROGRESS);
 263 }
 264 
 265 static void mon_text_complete(void *data, struct urb *urb, int status)
 266 {
 267         struct mon_reader_text *rp = data;
 268         mon_text_event(rp, urb, 'C', status);
 269 }
 270 
 271 static void mon_text_error(void *data, struct urb *urb, int error)
 272 {
 273         struct mon_reader_text *rp = data;
 274         struct mon_event_text *ep;
 275 
 276         if (rp->nevents >= EVENT_MAX ||
 277             (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
 278                 rp->r.m_bus->cnt_text_lost++;
 279                 return;
 280         }
 281 
 282         ep->type = 'E';
 283         ep->id = (unsigned long) urb;
 284         ep->busnum = urb->dev->bus->busnum;
 285         ep->devnum = urb->dev->devnum;
 286         ep->epnum = usb_endpoint_num(&urb->ep->desc);
 287         ep->xfertype = usb_endpoint_type(&urb->ep->desc);
 288         ep->is_in = usb_urb_dir_in(urb);
 289         ep->tstamp = mon_get_timestamp();
 290         ep->length = 0;
 291         ep->status = error;
 292 
 293         ep->setup_flag = '-';
 294         ep->data_flag = 'E';
 295 
 296         rp->nevents++;
 297         list_add_tail(&ep->e_link, &rp->e_list);
 298         wake_up(&rp->wait);
 299 }
 300 
 301 /*
 302  * Fetch next event from the circular buffer.
 303  */
 304 static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
 305     struct mon_bus *mbus)
 306 {
 307         struct list_head *p;
 308         unsigned long flags;
 309 
 310         spin_lock_irqsave(&mbus->lock, flags);
 311         if (list_empty(&rp->e_list)) {
 312                 spin_unlock_irqrestore(&mbus->lock, flags);
 313                 return NULL;
 314         }
 315         p = rp->e_list.next;
 316         list_del(p);
 317         --rp->nevents;
 318         spin_unlock_irqrestore(&mbus->lock, flags);
 319         return list_entry(p, struct mon_event_text, e_link);
 320 }
 321 
 322 /*
 323  */
 324 static int mon_text_open(struct inode *inode, struct file *file)
 325 {
 326         struct mon_bus *mbus;
 327         struct mon_reader_text *rp;
 328         int rc;
 329 
 330         mutex_lock(&mon_lock);
 331         mbus = inode->i_private;
 332 
 333         rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL);
 334         if (rp == NULL) {
 335                 rc = -ENOMEM;
 336                 goto err_alloc;
 337         }
 338         INIT_LIST_HEAD(&rp->e_list);
 339         init_waitqueue_head(&rp->wait);
 340         mutex_init(&rp->printf_lock);
 341 
 342         rp->printf_size = PRINTF_DFL;
 343         rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL);
 344         if (rp->printf_buf == NULL) {
 345                 rc = -ENOMEM;
 346                 goto err_alloc_pr;
 347         }
 348 
 349         rp->r.m_bus = mbus;
 350         rp->r.r_data = rp;
 351         rp->r.rnf_submit = mon_text_submit;
 352         rp->r.rnf_error = mon_text_error;
 353         rp->r.rnf_complete = mon_text_complete;
 354 
 355         snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp);
 356         rp->e_slab = kmem_cache_create(rp->slab_name,
 357             sizeof(struct mon_event_text), sizeof(long), 0,
 358             mon_text_ctor);
 359         if (rp->e_slab == NULL) {
 360                 rc = -ENOMEM;
 361                 goto err_slab;
 362         }
 363 
 364         mon_reader_add(mbus, &rp->r);
 365 
 366         file->private_data = rp;
 367         mutex_unlock(&mon_lock);
 368         return 0;
 369 
 370 // err_busy:
 371 //      kmem_cache_destroy(rp->e_slab);
 372 err_slab:
 373         kfree(rp->printf_buf);
 374 err_alloc_pr:
 375         kfree(rp);
 376 err_alloc:
 377         mutex_unlock(&mon_lock);
 378         return rc;
 379 }
 380 
 381 static ssize_t mon_text_copy_to_user(struct mon_reader_text *rp,
 382     char __user * const buf, const size_t nbytes)
 383 {
 384         const size_t togo = min(nbytes, rp->printf_togo);
 385 
 386         if (copy_to_user(buf, &rp->printf_buf[rp->printf_offset], togo))
 387                 return -EFAULT;
 388         rp->printf_togo -= togo;
 389         rp->printf_offset += togo;
 390         return togo;
 391 }
 392 
 393 /* ppos is not advanced since the llseek operation is not permitted. */
 394 static ssize_t mon_text_read_t(struct file *file, char __user *buf,
 395     size_t nbytes, loff_t *ppos)
 396 {
 397         struct mon_reader_text *rp = file->private_data;
 398         struct mon_event_text *ep;
 399         struct mon_text_ptr ptr;
 400         ssize_t ret;
 401 
 402         mutex_lock(&rp->printf_lock);
 403 
 404         if (rp->printf_togo == 0) {
 405 
 406                 ep = mon_text_read_wait(rp, file);
 407                 if (IS_ERR(ep)) {
 408                         mutex_unlock(&rp->printf_lock);
 409                         return PTR_ERR(ep);
 410                 }
 411                 ptr.cnt = 0;
 412                 ptr.pbuf = rp->printf_buf;
 413                 ptr.limit = rp->printf_size;
 414 
 415                 mon_text_read_head_t(rp, &ptr, ep);
 416                 mon_text_read_statset(rp, &ptr, ep);
 417                 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
 418                     " %d", ep->length);
 419                 mon_text_read_data(rp, &ptr, ep);
 420 
 421                 rp->printf_togo = ptr.cnt;
 422                 rp->printf_offset = 0;
 423 
 424                 kmem_cache_free(rp->e_slab, ep);
 425         }
 426 
 427         ret = mon_text_copy_to_user(rp, buf, nbytes);
 428         mutex_unlock(&rp->printf_lock);
 429         return ret;
 430 }
 431 
 432 /* ppos is not advanced since the llseek operation is not permitted. */
 433 static ssize_t mon_text_read_u(struct file *file, char __user *buf,
 434     size_t nbytes, loff_t *ppos)
 435 {
 436         struct mon_reader_text *rp = file->private_data;
 437         struct mon_event_text *ep;
 438         struct mon_text_ptr ptr;
 439         ssize_t ret;
 440 
 441         mutex_lock(&rp->printf_lock);
 442 
 443         if (rp->printf_togo == 0) {
 444 
 445                 ep = mon_text_read_wait(rp, file);
 446                 if (IS_ERR(ep)) {
 447                         mutex_unlock(&rp->printf_lock);
 448                         return PTR_ERR(ep);
 449                 }
 450                 ptr.cnt = 0;
 451                 ptr.pbuf = rp->printf_buf;
 452                 ptr.limit = rp->printf_size;
 453 
 454                 mon_text_read_head_u(rp, &ptr, ep);
 455                 if (ep->type == 'E') {
 456                         mon_text_read_statset(rp, &ptr, ep);
 457                 } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
 458                         mon_text_read_isostat(rp, &ptr, ep);
 459                         mon_text_read_isodesc(rp, &ptr, ep);
 460                 } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
 461                         mon_text_read_intstat(rp, &ptr, ep);
 462                 } else {
 463                         mon_text_read_statset(rp, &ptr, ep);
 464                 }
 465                 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
 466                     " %d", ep->length);
 467                 mon_text_read_data(rp, &ptr, ep);
 468 
 469                 rp->printf_togo = ptr.cnt;
 470                 rp->printf_offset = 0;
 471 
 472                 kmem_cache_free(rp->e_slab, ep);
 473         }
 474 
 475         ret = mon_text_copy_to_user(rp, buf, nbytes);
 476         mutex_unlock(&rp->printf_lock);
 477         return ret;
 478 }
 479 
 480 static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
 481     struct file *file)
 482 {
 483         struct mon_bus *mbus = rp->r.m_bus;
 484         DECLARE_WAITQUEUE(waita, current);
 485         struct mon_event_text *ep;
 486 
 487         add_wait_queue(&rp->wait, &waita);
 488         set_current_state(TASK_INTERRUPTIBLE);
 489         while ((ep = mon_text_fetch(rp, mbus)) == NULL) {
 490                 if (file->f_flags & O_NONBLOCK) {
 491                         set_current_state(TASK_RUNNING);
 492                         remove_wait_queue(&rp->wait, &waita);
 493                         return ERR_PTR(-EWOULDBLOCK);
 494                 }
 495                 /*
 496                  * We do not count nwaiters, because ->release is supposed
 497                  * to be called when all openers are gone only.
 498                  */
 499                 schedule();
 500                 if (signal_pending(current)) {
 501                         remove_wait_queue(&rp->wait, &waita);
 502                         return ERR_PTR(-EINTR);
 503                 }
 504                 set_current_state(TASK_INTERRUPTIBLE);
 505         }
 506         set_current_state(TASK_RUNNING);
 507         remove_wait_queue(&rp->wait, &waita);
 508         return ep;
 509 }
 510 
 511 static void mon_text_read_head_t(struct mon_reader_text *rp,
 512         struct mon_text_ptr *p, const struct mon_event_text *ep)
 513 {
 514         char udir, utype;
 515 
 516         udir = (ep->is_in ? 'i' : 'o');
 517         switch (ep->xfertype) {
 518         case USB_ENDPOINT_XFER_ISOC:    utype = 'Z'; break;
 519         case USB_ENDPOINT_XFER_INT:     utype = 'I'; break;
 520         case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break;
 521         default: /* PIPE_BULK */  utype = 'B';
 522         }
 523         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 524             "%lx %u %c %c%c:%03u:%02u",
 525             ep->id, ep->tstamp, ep->type,
 526             utype, udir, ep->devnum, ep->epnum);
 527 }
 528 
 529 static void mon_text_read_head_u(struct mon_reader_text *rp,
 530         struct mon_text_ptr *p, const struct mon_event_text *ep)
 531 {
 532         char udir, utype;
 533 
 534         udir = (ep->is_in ? 'i' : 'o');
 535         switch (ep->xfertype) {
 536         case USB_ENDPOINT_XFER_ISOC:    utype = 'Z'; break;
 537         case USB_ENDPOINT_XFER_INT:     utype = 'I'; break;
 538         case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break;
 539         default: /* PIPE_BULK */  utype = 'B';
 540         }
 541         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 542             "%lx %u %c %c%c:%d:%03u:%u",
 543             ep->id, ep->tstamp, ep->type,
 544             utype, udir, ep->busnum, ep->devnum, ep->epnum);
 545 }
 546 
 547 static void mon_text_read_statset(struct mon_reader_text *rp,
 548         struct mon_text_ptr *p, const struct mon_event_text *ep)
 549 {
 550 
 551         if (ep->setup_flag == 0) {   /* Setup packet is present and captured */
 552                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 553                     " s %02x %02x %04x %04x %04x",
 554                     ep->setup[0],
 555                     ep->setup[1],
 556                     (ep->setup[3] << 8) | ep->setup[2],
 557                     (ep->setup[5] << 8) | ep->setup[4],
 558                     (ep->setup[7] << 8) | ep->setup[6]);
 559         } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
 560                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 561                     " %c __ __ ____ ____ ____", ep->setup_flag);
 562         } else {                     /* No setup for this kind of URB */
 563                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 564                     " %d", ep->status);
 565         }
 566 }
 567 
 568 static void mon_text_read_intstat(struct mon_reader_text *rp,
 569         struct mon_text_ptr *p, const struct mon_event_text *ep)
 570 {
 571         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 572             " %d:%d", ep->status, ep->interval);
 573 }
 574 
 575 static void mon_text_read_isostat(struct mon_reader_text *rp,
 576         struct mon_text_ptr *p, const struct mon_event_text *ep)
 577 {
 578         if (ep->type == 'S') {
 579                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 580                     " %d:%d:%d", ep->status, ep->interval, ep->start_frame);
 581         } else {
 582                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 583                     " %d:%d:%d:%d",
 584                     ep->status, ep->interval, ep->start_frame, ep->error_count);
 585         }
 586 }
 587 
 588 static void mon_text_read_isodesc(struct mon_reader_text *rp,
 589         struct mon_text_ptr *p, const struct mon_event_text *ep)
 590 {
 591         int ndesc;      /* Display this many */
 592         int i;
 593         const struct mon_iso_desc *dp;
 594 
 595         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 596             " %d", ep->numdesc);
 597         ndesc = ep->numdesc;
 598         if (ndesc > ISODESC_MAX)
 599                 ndesc = ISODESC_MAX;
 600         if (ndesc < 0)
 601                 ndesc = 0;
 602         dp = ep->isodesc;
 603         for (i = 0; i < ndesc; i++) {
 604                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 605                     " %d:%u:%u", dp->status, dp->offset, dp->length);
 606                 dp++;
 607         }
 608 }
 609 
 610 static void mon_text_read_data(struct mon_reader_text *rp,
 611     struct mon_text_ptr *p, const struct mon_event_text *ep)
 612 {
 613         int data_len, i;
 614 
 615         if ((data_len = ep->length) > 0) {
 616                 if (ep->data_flag == 0) {
 617                         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 618                             " =");
 619                         if (data_len >= DATA_MAX)
 620                                 data_len = DATA_MAX;
 621                         for (i = 0; i < data_len; i++) {
 622                                 if (i % 4 == 0) {
 623                                         p->cnt += snprintf(p->pbuf + p->cnt,
 624                                             p->limit - p->cnt,
 625                                             " ");
 626                                 }
 627                                 p->cnt += snprintf(p->pbuf + p->cnt,
 628                                     p->limit - p->cnt,
 629                                     "%02x", ep->data[i]);
 630                         }
 631                         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 632                             "\n");
 633                 } else {
 634                         p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
 635                             " %c\n", ep->data_flag);
 636                 }
 637         } else {
 638                 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, "\n");
 639         }
 640 }
 641 
 642 static int mon_text_release(struct inode *inode, struct file *file)
 643 {
 644         struct mon_reader_text *rp = file->private_data;
 645         struct mon_bus *mbus;
 646         /* unsigned long flags; */
 647         struct list_head *p;
 648         struct mon_event_text *ep;
 649 
 650         mutex_lock(&mon_lock);
 651         mbus = inode->i_private;
 652 
 653         if (mbus->nreaders <= 0) {
 654                 printk(KERN_ERR TAG ": consistency error on close\n");
 655                 mutex_unlock(&mon_lock);
 656                 return 0;
 657         }
 658         mon_reader_del(mbus, &rp->r);
 659 
 660         /*
 661          * In theory, e_list is protected by mbus->lock. However,
 662          * after mon_reader_del has finished, the following is the case:
 663          *  - we are not on reader list anymore, so new events won't be added;
 664          *  - whole mbus may be dropped if it was orphaned.
 665          * So, we better not touch mbus.
 666          */
 667         /* spin_lock_irqsave(&mbus->lock, flags); */
 668         while (!list_empty(&rp->e_list)) {
 669                 p = rp->e_list.next;
 670                 ep = list_entry(p, struct mon_event_text, e_link);
 671                 list_del(p);
 672                 --rp->nevents;
 673                 kmem_cache_free(rp->e_slab, ep);
 674         }
 675         /* spin_unlock_irqrestore(&mbus->lock, flags); */
 676 
 677         kmem_cache_destroy(rp->e_slab);
 678         kfree(rp->printf_buf);
 679         kfree(rp);
 680 
 681         mutex_unlock(&mon_lock);
 682         return 0;
 683 }
 684 
 685 static const struct file_operations mon_fops_text_t = {
 686         .owner =        THIS_MODULE,
 687         .open =         mon_text_open,
 688         .llseek =       no_llseek,
 689         .read =         mon_text_read_t,
 690         .release =      mon_text_release,
 691 };
 692 
 693 static const struct file_operations mon_fops_text_u = {
 694         .owner =        THIS_MODULE,
 695         .open =         mon_text_open,
 696         .llseek =       no_llseek,
 697         .read =         mon_text_read_u,
 698         .release =      mon_text_release,
 699 };
 700 
 701 int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
 702 {
 703         enum { NAMESZ = 10 };
 704         char name[NAMESZ];
 705         int busnum = ubus? ubus->busnum: 0;
 706         int rc;
 707 
 708         if (mon_dir == NULL)
 709                 return 0;
 710 
 711         if (ubus != NULL) {
 712                 rc = snprintf(name, NAMESZ, "%dt", busnum);
 713                 if (rc <= 0 || rc >= NAMESZ)
 714                         goto err_print_t;
 715                 mbus->dent_t = debugfs_create_file(name, 0600, mon_dir, mbus,
 716                                                              &mon_fops_text_t);
 717         }
 718 
 719         rc = snprintf(name, NAMESZ, "%du", busnum);
 720         if (rc <= 0 || rc >= NAMESZ)
 721                 goto err_print_u;
 722         mbus->dent_u = debugfs_create_file(name, 0600, mon_dir, mbus,
 723                                            &mon_fops_text_u);
 724 
 725         rc = snprintf(name, NAMESZ, "%ds", busnum);
 726         if (rc <= 0 || rc >= NAMESZ)
 727                 goto err_print_s;
 728         mbus->dent_s = debugfs_create_file(name, 0600, mon_dir, mbus,
 729                                            &mon_fops_stat);
 730 
 731         return 1;
 732 
 733 err_print_s:
 734         debugfs_remove(mbus->dent_u);
 735         mbus->dent_u = NULL;
 736 err_print_u:
 737         if (ubus != NULL) {
 738                 debugfs_remove(mbus->dent_t);
 739                 mbus->dent_t = NULL;
 740         }
 741 err_print_t:
 742         return 0;
 743 }
 744 
 745 void mon_text_del(struct mon_bus *mbus)
 746 {
 747         debugfs_remove(mbus->dent_u);
 748         debugfs_remove(mbus->dent_t);
 749         debugfs_remove(mbus->dent_s);
 750 }
 751 
 752 /*
 753  * Slab interface: constructor.
 754  */
 755 static void mon_text_ctor(void *mem)
 756 {
 757         /*
 758          * Nothing to initialize. No, really!
 759          * So, we fill it with garbage to emulate a reused object.
 760          */
 761         memset(mem, 0xe5, sizeof(struct mon_event_text));
 762 }
 763 
 764 int __init mon_text_init(void)
 765 {
 766         mon_dir = debugfs_create_dir("usbmon", usb_debug_root);
 767         return 0;
 768 }
 769 
 770 void mon_text_exit(void)
 771 {
 772         debugfs_remove(mon_dir);
 773 }

/* [<][>][^][v][top][bottom][index][help] */