blob: 19c416d69eb9335e15d7fa46900e2b163a85130a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * The USB Monitor, inspired by Dave Harding's USBMon.
3 *
4 * This is a text format reader.
5 */
6
7#include <linux/kernel.h>
8#include <linux/list.h>
9#include <linux/usb.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090010#include <linux/slab.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010011#include <linux/sched/signal.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/time.h>
Tina Ruchandaniec4dca82015-10-29 22:58:28 -070013#include <linux/ktime.h>
Paul Gortmakerf940fcd2011-05-27 09:56:31 -040014#include <linux/export.h>
Arjan van de Ven4186ecf2006-01-11 15:55:29 +010015#include <linux/mutex.h>
Pete Zaitcev6f23ee12006-12-30 22:43:10 -080016#include <linux/debugfs.h>
Alan Sternb375e112009-11-06 12:32:23 -050017#include <linux/scatterlist.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080018#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
20#include "usb_mon.h"
21
22/*
23 * No, we do not want arbitrarily long data strings.
24 * Use the binary interface if you want to capture bulk data!
25 */
26#define DATA_MAX 32
27
28/*
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -070029 * Defined by USB 2.0 clause 9.3, table 9.2.
30 */
31#define SETUP_MAX 8
32
33/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 * This limit exists to prevent OOMs when the user process stops reading.
Pete Zaitcev5b1c6742006-06-09 20:10:10 -070035 * If usbmon were available to unprivileged processes, it might be open
36 * to a local DoS. But we have to keep to root in order to prevent
37 * password sniffing from HID devices.
Linus Torvalds1da177e2005-04-16 15:20:36 -070038 */
Pete Zaitcevf1c9e302007-02-24 19:27:33 -080039#define EVENT_MAX (4*PAGE_SIZE / sizeof(struct mon_event_text))
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Pete Zaitcevf1c9e302007-02-24 19:27:33 -080041/*
42 * Potentially unlimited number; we limit it for similar allocations.
43 * The usbfs limits this to 128, but we're not quite as generous.
44 */
45#define ISODESC_MAX 5
46
47#define PRINTF_DFL 250 /* with 5 ISOs segs */
48
49struct mon_iso_desc {
50 int status;
51 unsigned int offset;
52 unsigned int length; /* Unsigned here, signed in URB. Historic. */
53};
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55struct mon_event_text {
56 struct list_head e_link;
57 int type; /* submit, complete, etc. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 unsigned long id; /* From pointer, most of the time */
59 unsigned int tstamp;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -080060 int busnum;
Pete Zaitcev30c74312007-08-14 00:33:40 -070061 char devnum;
62 char epnum;
63 char is_in;
64 char xfertype;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 int length; /* Depends on type: xfer length or act length */
66 int status;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -080067 int interval;
68 int start_frame;
69 int error_count;
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -070070 char setup_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 char data_flag;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -080072 int numdesc; /* Full number */
73 struct mon_iso_desc isodesc[ISODESC_MAX];
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -070074 unsigned char setup[SETUP_MAX];
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 unsigned char data[DATA_MAX];
76};
77
78#define SLAB_NAME_SZ 30
79struct mon_reader_text {
Christoph Lametere18b8902006-12-06 20:33:20 -080080 struct kmem_cache *e_slab;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 int nevents;
82 struct list_head e_list;
83 struct mon_reader r; /* In C, parent class can be placed anywhere */
84
85 wait_queue_head_t wait;
86 int printf_size;
87 char *printf_buf;
Arjan van de Ven4186ecf2006-01-11 15:55:29 +010088 struct mutex printf_lock;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
90 char slab_name[SLAB_NAME_SZ];
91};
92
Pete Zaitcev6f23ee12006-12-30 22:43:10 -080093static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */
94
Alexey Dobriyan51cc5062008-07-25 19:45:34 -070095static void mon_text_ctor(void *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Pete Zaitcevf1c9e302007-02-24 19:27:33 -080097struct mon_text_ptr {
98 int cnt, limit;
99 char *pbuf;
100};
101
102static struct mon_event_text *
103 mon_text_read_wait(struct mon_reader_text *rp, struct file *file);
104static void mon_text_read_head_t(struct mon_reader_text *rp,
105 struct mon_text_ptr *p, const struct mon_event_text *ep);
106static void mon_text_read_head_u(struct mon_reader_text *rp,
107 struct mon_text_ptr *p, const struct mon_event_text *ep);
108static void mon_text_read_statset(struct mon_reader_text *rp,
109 struct mon_text_ptr *p, const struct mon_event_text *ep);
110static void mon_text_read_intstat(struct mon_reader_text *rp,
111 struct mon_text_ptr *p, const struct mon_event_text *ep);
112static void mon_text_read_isostat(struct mon_reader_text *rp,
113 struct mon_text_ptr *p, const struct mon_event_text *ep);
114static void mon_text_read_isodesc(struct mon_reader_text *rp,
115 struct mon_text_ptr *p, const struct mon_event_text *ep);
116static void mon_text_read_data(struct mon_reader_text *rp,
117 struct mon_text_ptr *p, const struct mon_event_text *ep);
118
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119/*
120 * mon_text_submit
121 * mon_text_complete
122 *
123 * May be called from an interrupt.
124 *
125 * This is called with the whole mon_bus locked, so no additional lock.
126 */
127
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700128static inline char mon_text_get_setup(struct mon_event_text *ep,
Alan Stern4d6cd482006-08-30 11:35:21 -0400129 struct urb *urb, char ev_type, struct mon_bus *mbus)
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700130{
131
Alan Stern18ea5d02007-07-30 17:10:36 -0400132 if (ep->xfertype != USB_ENDPOINT_XFER_CONTROL || ev_type != 'S')
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700133 return '-';
134
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700135 if (urb->setup_packet == NULL)
136 return 'Z'; /* '0' would be not as pretty. */
137
138 memcpy(ep->setup, urb->setup_packet, SETUP_MAX);
139 return 0;
140}
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
Alan Stern4d6cd482006-08-30 11:35:21 -0400143 int len, char ev_type, struct mon_bus *mbus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144{
Alan Sternb375e112009-11-06 12:32:23 -0500145 void *src;
146
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 if (len <= 0)
148 return 'L';
Pete Zaitcev02568392005-08-15 16:53:57 -0700149 if (len >= DATA_MAX)
150 len = DATA_MAX;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
Alan Stern18ea5d02007-07-30 17:10:36 -0400152 if (ep->is_in) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800153 if (ev_type != 'C')
Pete Zaitcevb9b09422005-12-03 21:52:10 -0800154 return '<';
155 } else {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800156 if (ev_type != 'S')
Pete Zaitcevb9b09422005-12-03 21:52:10 -0800157 return '>';
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 }
159
Alan Sternb375e112009-11-06 12:32:23 -0500160 if (urb->num_sgs == 0) {
161 src = urb->transfer_buffer;
162 if (src == NULL)
163 return 'Z'; /* '0' would be not as pretty. */
164 } else {
Matthew Wilcox910f8d02010-05-01 12:20:01 -0600165 struct scatterlist *sg = urb->sg;
Pete Zaitcev02568392005-08-15 16:53:57 -0700166
Alan Sternff9c8952010-04-02 13:27:28 -0400167 if (PageHighMem(sg_page(sg)))
Alan Sternb375e112009-11-06 12:32:23 -0500168 return 'D';
169
170 /* For the text interface we copy only the first sg buffer */
171 len = min_t(int, sg->length, len);
172 src = sg_virt(sg);
173 }
174
175 memcpy(ep->data, src, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 return 0;
177}
178
179static inline unsigned int mon_get_timestamp(void)
180{
Tina Ruchandaniec4dca82015-10-29 22:58:28 -0700181 struct timespec64 now;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 unsigned int stamp;
183
Tina Ruchandaniec4dca82015-10-29 22:58:28 -0700184 ktime_get_ts64(&now);
185 stamp = now.tv_sec & 0xFFF; /* 2^32 = 4294967296. Limit to 4096s. */
186 stamp = stamp * USEC_PER_SEC + now.tv_nsec / NSEC_PER_USEC;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 return stamp;
188}
189
190static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
Alan Stern9347d512007-08-24 15:41:41 -0400191 char ev_type, int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192{
193 struct mon_event_text *ep;
194 unsigned int stamp;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800195 struct usb_iso_packet_descriptor *fp;
196 struct mon_iso_desc *dp;
197 int i, ndesc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
199 stamp = mon_get_timestamp();
200
201 if (rp->nevents >= EVENT_MAX ||
Christoph Lameter54e6ecb2006-12-06 20:33:16 -0800202 (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 rp->r.m_bus->cnt_text_lost++;
204 return;
205 }
206
207 ep->type = ev_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 ep->id = (unsigned long) urb;
Pete Zaitcevecb658d2007-04-11 13:47:26 -0700209 ep->busnum = urb->dev->bus->busnum;
Alan Stern18ea5d02007-07-30 17:10:36 -0400210 ep->devnum = urb->dev->devnum;
211 ep->epnum = usb_endpoint_num(&urb->ep->desc);
212 ep->xfertype = usb_endpoint_type(&urb->ep->desc);
213 ep->is_in = usb_urb_dir_in(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 ep->tstamp = stamp;
215 ep->length = (ev_type == 'S') ?
216 urb->transfer_buffer_length : urb->actual_length;
217 /* Collecting status makes debugging sense for submits, too */
Alan Stern9347d512007-08-24 15:41:41 -0400218 ep->status = status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
Alan Stern18ea5d02007-07-30 17:10:36 -0400220 if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800221 ep->interval = urb->interval;
Alan Stern18ea5d02007-07-30 17:10:36 -0400222 } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800223 ep->interval = urb->interval;
224 ep->start_frame = urb->start_frame;
225 ep->error_count = urb->error_count;
226 }
227 ep->numdesc = urb->number_of_packets;
Alan Stern18ea5d02007-07-30 17:10:36 -0400228 if (ep->xfertype == USB_ENDPOINT_XFER_ISOC &&
229 urb->number_of_packets > 0) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800230 if ((ndesc = urb->number_of_packets) > ISODESC_MAX)
231 ndesc = ISODESC_MAX;
232 fp = urb->iso_frame_desc;
233 dp = ep->isodesc;
234 for (i = 0; i < ndesc; i++) {
235 dp->status = fp->status;
236 dp->offset = fp->offset;
237 dp->length = (ev_type == 'S') ?
238 fp->length : fp->actual_length;
239 fp++;
240 dp++;
241 }
Pete Zaitcevd25bc4d2011-02-03 22:01:36 -0700242 /* Wasteful, but simple to understand: ISO 'C' is sparse. */
243 if (ev_type == 'C')
244 ep->length = urb->transfer_buffer_length;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800245 }
246
Alan Stern4d6cd482006-08-30 11:35:21 -0400247 ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus);
248 ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type,
249 rp->r.m_bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250
251 rp->nevents++;
252 list_add_tail(&ep->e_link, &rp->e_list);
253 wake_up(&rp->wait);
254}
255
256static void mon_text_submit(void *data, struct urb *urb)
257{
258 struct mon_reader_text *rp = data;
Alan Stern9347d512007-08-24 15:41:41 -0400259 mon_text_event(rp, urb, 'S', -EINPROGRESS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260}
261
Alan Stern9347d512007-08-24 15:41:41 -0400262static void mon_text_complete(void *data, struct urb *urb, int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263{
264 struct mon_reader_text *rp = data;
Alan Stern9347d512007-08-24 15:41:41 -0400265 mon_text_event(rp, urb, 'C', status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266}
267
Pete Zaitcev12e72fe2006-06-09 22:03:32 -0700268static void mon_text_error(void *data, struct urb *urb, int error)
269{
270 struct mon_reader_text *rp = data;
271 struct mon_event_text *ep;
272
273 if (rp->nevents >= EVENT_MAX ||
Christoph Lameter54e6ecb2006-12-06 20:33:16 -0800274 (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
Pete Zaitcev12e72fe2006-06-09 22:03:32 -0700275 rp->r.m_bus->cnt_text_lost++;
276 return;
277 }
278
279 ep->type = 'E';
Pete Zaitcev12e72fe2006-06-09 22:03:32 -0700280 ep->id = (unsigned long) urb;
Pete Zaitcev2bc0d1092010-01-05 11:50:07 -0700281 ep->busnum = urb->dev->bus->busnum;
Alan Stern18ea5d02007-07-30 17:10:36 -0400282 ep->devnum = urb->dev->devnum;
283 ep->epnum = usb_endpoint_num(&urb->ep->desc);
284 ep->xfertype = usb_endpoint_type(&urb->ep->desc);
285 ep->is_in = usb_urb_dir_in(urb);
Pete Zaitcev2bc0d1092010-01-05 11:50:07 -0700286 ep->tstamp = mon_get_timestamp();
Pete Zaitcev12e72fe2006-06-09 22:03:32 -0700287 ep->length = 0;
288 ep->status = error;
289
290 ep->setup_flag = '-';
291 ep->data_flag = 'E';
292
293 rp->nevents++;
294 list_add_tail(&ep->e_link, &rp->e_list);
295 wake_up(&rp->wait);
296}
297
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298/*
299 * Fetch next event from the circular buffer.
300 */
301static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
302 struct mon_bus *mbus)
303{
304 struct list_head *p;
305 unsigned long flags;
306
307 spin_lock_irqsave(&mbus->lock, flags);
308 if (list_empty(&rp->e_list)) {
309 spin_unlock_irqrestore(&mbus->lock, flags);
310 return NULL;
311 }
312 p = rp->e_list.next;
313 list_del(p);
314 --rp->nevents;
315 spin_unlock_irqrestore(&mbus->lock, flags);
316 return list_entry(p, struct mon_event_text, e_link);
317}
318
319/*
320 */
321static int mon_text_open(struct inode *inode, struct file *file)
322{
323 struct mon_bus *mbus;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 struct mon_reader_text *rp;
325 int rc;
326
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100327 mutex_lock(&mon_lock);
Theodore Ts'o8e18e292006-09-27 01:50:46 -0700328 mbus = inode->i_private;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100330 rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 if (rp == NULL) {
332 rc = -ENOMEM;
333 goto err_alloc;
334 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 INIT_LIST_HEAD(&rp->e_list);
336 init_waitqueue_head(&rp->wait);
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100337 mutex_init(&rp->printf_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
339 rp->printf_size = PRINTF_DFL;
340 rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL);
341 if (rp->printf_buf == NULL) {
342 rc = -ENOMEM;
343 goto err_alloc_pr;
344 }
345
346 rp->r.m_bus = mbus;
347 rp->r.r_data = rp;
348 rp->r.rnf_submit = mon_text_submit;
Pete Zaitcev12e72fe2006-06-09 22:03:32 -0700349 rp->r.rnf_error = mon_text_error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 rp->r.rnf_complete = mon_text_complete;
351
Pete Zaitcevecb658d2007-04-11 13:47:26 -0700352 snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 rp->e_slab = kmem_cache_create(rp->slab_name,
354 sizeof(struct mon_event_text), sizeof(long), 0,
Paul Mundt20c2df82007-07-20 10:11:58 +0900355 mon_text_ctor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 if (rp->e_slab == NULL) {
357 rc = -ENOMEM;
358 goto err_slab;
359 }
360
361 mon_reader_add(mbus, &rp->r);
362
363 file->private_data = rp;
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100364 mutex_unlock(&mon_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 return 0;
366
367// err_busy:
368// kmem_cache_destroy(rp->e_slab);
369err_slab:
370 kfree(rp->printf_buf);
371err_alloc_pr:
372 kfree(rp);
373err_alloc:
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100374 mutex_unlock(&mon_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 return rc;
376}
377
378/*
379 * For simplicity, we read one record in one system call and throw out
380 * what does not fit. This means that the following does not work:
381 * dd if=/dbg/usbmon/0t bs=10
382 * Also, we do not allow seeks and do not bother advancing the offset.
383 */
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800384static ssize_t mon_text_read_t(struct file *file, char __user *buf,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 size_t nbytes, loff_t *ppos)
386{
387 struct mon_reader_text *rp = file->private_data;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800388 struct mon_event_text *ep;
389 struct mon_text_ptr ptr;
390
Julia Lawall46c236d2015-12-26 22:57:44 +0100391 ep = mon_text_read_wait(rp, file);
392 if (IS_ERR(ep))
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800393 return PTR_ERR(ep);
394 mutex_lock(&rp->printf_lock);
395 ptr.cnt = 0;
396 ptr.pbuf = rp->printf_buf;
397 ptr.limit = rp->printf_size;
398
399 mon_text_read_head_t(rp, &ptr, ep);
400 mon_text_read_statset(rp, &ptr, ep);
401 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
402 " %d", ep->length);
403 mon_text_read_data(rp, &ptr, ep);
404
405 if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
406 ptr.cnt = -EFAULT;
407 mutex_unlock(&rp->printf_lock);
408 kmem_cache_free(rp->e_slab, ep);
409 return ptr.cnt;
410}
411
412static ssize_t mon_text_read_u(struct file *file, char __user *buf,
413 size_t nbytes, loff_t *ppos)
414{
415 struct mon_reader_text *rp = file->private_data;
416 struct mon_event_text *ep;
417 struct mon_text_ptr ptr;
418
Julia Lawall46c236d2015-12-26 22:57:44 +0100419 ep = mon_text_read_wait(rp, file);
420 if (IS_ERR(ep))
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800421 return PTR_ERR(ep);
422 mutex_lock(&rp->printf_lock);
423 ptr.cnt = 0;
424 ptr.pbuf = rp->printf_buf;
425 ptr.limit = rp->printf_size;
426
427 mon_text_read_head_u(rp, &ptr, ep);
428 if (ep->type == 'E') {
429 mon_text_read_statset(rp, &ptr, ep);
Alan Stern18ea5d02007-07-30 17:10:36 -0400430 } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800431 mon_text_read_isostat(rp, &ptr, ep);
432 mon_text_read_isodesc(rp, &ptr, ep);
Alan Stern18ea5d02007-07-30 17:10:36 -0400433 } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800434 mon_text_read_intstat(rp, &ptr, ep);
435 } else {
436 mon_text_read_statset(rp, &ptr, ep);
437 }
438 ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
439 " %d", ep->length);
440 mon_text_read_data(rp, &ptr, ep);
441
442 if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
443 ptr.cnt = -EFAULT;
444 mutex_unlock(&rp->printf_lock);
445 kmem_cache_free(rp->e_slab, ep);
446 return ptr.cnt;
447}
448
449static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
450 struct file *file)
451{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 struct mon_bus *mbus = rp->r.m_bus;
453 DECLARE_WAITQUEUE(waita, current);
454 struct mon_event_text *ep;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455
456 add_wait_queue(&rp->wait, &waita);
457 set_current_state(TASK_INTERRUPTIBLE);
458 while ((ep = mon_text_fetch(rp, mbus)) == NULL) {
459 if (file->f_flags & O_NONBLOCK) {
460 set_current_state(TASK_RUNNING);
461 remove_wait_queue(&rp->wait, &waita);
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800462 return ERR_PTR(-EWOULDBLOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 }
464 /*
465 * We do not count nwaiters, because ->release is supposed
466 * to be called when all openers are gone only.
467 */
468 schedule();
469 if (signal_pending(current)) {
470 remove_wait_queue(&rp->wait, &waita);
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800471 return ERR_PTR(-EINTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 }
473 set_current_state(TASK_INTERRUPTIBLE);
474 }
475 set_current_state(TASK_RUNNING);
476 remove_wait_queue(&rp->wait, &waita);
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800477 return ep;
478}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800480static void mon_text_read_head_t(struct mon_reader_text *rp,
481 struct mon_text_ptr *p, const struct mon_event_text *ep)
482{
483 char udir, utype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
Alan Stern18ea5d02007-07-30 17:10:36 -0400485 udir = (ep->is_in ? 'i' : 'o');
486 switch (ep->xfertype) {
487 case USB_ENDPOINT_XFER_ISOC: utype = 'Z'; break;
488 case USB_ENDPOINT_XFER_INT: utype = 'I'; break;
489 case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 default: /* PIPE_BULK */ utype = 'B';
491 }
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800492 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700493 "%lx %u %c %c%c:%03u:%02u",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 ep->id, ep->tstamp, ep->type,
Alan Stern18ea5d02007-07-30 17:10:36 -0400495 utype, udir, ep->devnum, ep->epnum);
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800496}
497
498static void mon_text_read_head_u(struct mon_reader_text *rp,
499 struct mon_text_ptr *p, const struct mon_event_text *ep)
500{
501 char udir, utype;
502
Alan Stern18ea5d02007-07-30 17:10:36 -0400503 udir = (ep->is_in ? 'i' : 'o');
504 switch (ep->xfertype) {
505 case USB_ENDPOINT_XFER_ISOC: utype = 'Z'; break;
506 case USB_ENDPOINT_XFER_INT: utype = 'I'; break;
507 case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break;
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800508 default: /* PIPE_BULK */ utype = 'B';
509 }
510 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
511 "%lx %u %c %c%c:%d:%03u:%u",
512 ep->id, ep->tstamp, ep->type,
Alan Stern18ea5d02007-07-30 17:10:36 -0400513 utype, udir, ep->busnum, ep->devnum, ep->epnum);
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800514}
515
516static void mon_text_read_statset(struct mon_reader_text *rp,
517 struct mon_text_ptr *p, const struct mon_event_text *ep)
518{
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700519
520 if (ep->setup_flag == 0) { /* Setup packet is present and captured */
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800521 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700522 " s %02x %02x %04x %04x %04x",
523 ep->setup[0],
524 ep->setup[1],
525 (ep->setup[3] << 8) | ep->setup[2],
526 (ep->setup[5] << 8) | ep->setup[4],
527 (ep->setup[7] << 8) | ep->setup[6]);
528 } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800529 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700530 " %c __ __ ____ ____ ____", ep->setup_flag);
531 } else { /* No setup for this kind of URB */
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800532 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
533 " %d", ep->status);
Pete Zaitcevae0d6cc2005-06-25 14:32:59 -0700534 }
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800535}
536
537static void mon_text_read_intstat(struct mon_reader_text *rp,
538 struct mon_text_ptr *p, const struct mon_event_text *ep)
539{
540 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
541 " %d:%d", ep->status, ep->interval);
542}
543
544static void mon_text_read_isostat(struct mon_reader_text *rp,
545 struct mon_text_ptr *p, const struct mon_event_text *ep)
546{
547 if (ep->type == 'S') {
548 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
549 " %d:%d:%d", ep->status, ep->interval, ep->start_frame);
550 } else {
551 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
552 " %d:%d:%d:%d",
553 ep->status, ep->interval, ep->start_frame, ep->error_count);
554 }
555}
556
557static void mon_text_read_isodesc(struct mon_reader_text *rp,
558 struct mon_text_ptr *p, const struct mon_event_text *ep)
559{
560 int ndesc; /* Display this many */
561 int i;
562 const struct mon_iso_desc *dp;
563
564 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
565 " %d", ep->numdesc);
566 ndesc = ep->numdesc;
567 if (ndesc > ISODESC_MAX)
568 ndesc = ISODESC_MAX;
569 if (ndesc < 0)
570 ndesc = 0;
571 dp = ep->isodesc;
572 for (i = 0; i < ndesc; i++) {
573 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
574 " %d:%u:%u", dp->status, dp->offset, dp->length);
575 dp++;
576 }
577}
578
579static void mon_text_read_data(struct mon_reader_text *rp,
580 struct mon_text_ptr *p, const struct mon_event_text *ep)
581{
582 int data_len, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583
584 if ((data_len = ep->length) > 0) {
585 if (ep->data_flag == 0) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800586 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
587 " =");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 if (data_len >= DATA_MAX)
589 data_len = DATA_MAX;
590 for (i = 0; i < data_len; i++) {
591 if (i % 4 == 0) {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800592 p->cnt += snprintf(p->pbuf + p->cnt,
593 p->limit - p->cnt,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 " ");
595 }
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800596 p->cnt += snprintf(p->pbuf + p->cnt,
597 p->limit - p->cnt,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 "%02x", ep->data[i]);
599 }
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800600 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
601 "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 } else {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800603 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 " %c\n", ep->data_flag);
605 }
606 } else {
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800607 p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609}
610
611static int mon_text_release(struct inode *inode, struct file *file)
612{
613 struct mon_reader_text *rp = file->private_data;
614 struct mon_bus *mbus;
615 /* unsigned long flags; */
616 struct list_head *p;
617 struct mon_event_text *ep;
618
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100619 mutex_lock(&mon_lock);
Theodore Ts'o8e18e292006-09-27 01:50:46 -0700620 mbus = inode->i_private;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
622 if (mbus->nreaders <= 0) {
623 printk(KERN_ERR TAG ": consistency error on close\n");
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100624 mutex_unlock(&mon_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 return 0;
626 }
627 mon_reader_del(mbus, &rp->r);
628
629 /*
630 * In theory, e_list is protected by mbus->lock. However,
631 * after mon_reader_del has finished, the following is the case:
632 * - we are not on reader list anymore, so new events won't be added;
633 * - whole mbus may be dropped if it was orphaned.
634 * So, we better not touch mbus.
635 */
636 /* spin_lock_irqsave(&mbus->lock, flags); */
637 while (!list_empty(&rp->e_list)) {
638 p = rp->e_list.next;
639 ep = list_entry(p, struct mon_event_text, e_link);
640 list_del(p);
641 --rp->nevents;
642 kmem_cache_free(rp->e_slab, ep);
643 }
644 /* spin_unlock_irqrestore(&mbus->lock, flags); */
645
646 kmem_cache_destroy(rp->e_slab);
647 kfree(rp->printf_buf);
648 kfree(rp);
649
Arjan van de Ven4186ecf2006-01-11 15:55:29 +0100650 mutex_unlock(&mon_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 return 0;
652}
653
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800654static const struct file_operations mon_fops_text_t = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 .owner = THIS_MODULE,
656 .open = mon_text_open,
657 .llseek = no_llseek,
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800658 .read = mon_text_read_t,
659 .release = mon_text_release,
660};
661
662static const struct file_operations mon_fops_text_u = {
663 .owner = THIS_MODULE,
664 .open = mon_text_open,
665 .llseek = no_llseek,
666 .read = mon_text_read_u,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 .release = mon_text_release,
668};
669
Pete Zaitcevce7cd137f2007-05-03 16:51:16 -0700670int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800671{
672 struct dentry *d;
673 enum { NAMESZ = 10 };
674 char name[NAMESZ];
Pete Zaitcevce7cd137f2007-05-03 16:51:16 -0700675 int busnum = ubus? ubus->busnum: 0;
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800676 int rc;
677
Tobias Klauser8dec92b2011-07-07 09:28:21 +0200678 if (mon_dir == NULL)
679 return 0;
680
Pete Zaitcevce7cd137f2007-05-03 16:51:16 -0700681 if (ubus != NULL) {
682 rc = snprintf(name, NAMESZ, "%dt", busnum);
683 if (rc <= 0 || rc >= NAMESZ)
684 goto err_print_t;
685 d = debugfs_create_file(name, 0600, mon_dir, mbus,
686 &mon_fops_text_t);
687 if (d == NULL)
688 goto err_create_t;
689 mbus->dent_t = d;
690 }
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800691
Pete Zaitcevecb658d2007-04-11 13:47:26 -0700692 rc = snprintf(name, NAMESZ, "%du", busnum);
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800693 if (rc <= 0 || rc >= NAMESZ)
694 goto err_print_u;
695 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u);
696 if (d == NULL)
697 goto err_create_u;
698 mbus->dent_u = d;
699
Pete Zaitcevecb658d2007-04-11 13:47:26 -0700700 rc = snprintf(name, NAMESZ, "%ds", busnum);
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800701 if (rc <= 0 || rc >= NAMESZ)
702 goto err_print_s;
703 d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat);
704 if (d == NULL)
705 goto err_create_s;
706 mbus->dent_s = d;
707
708 return 1;
709
710err_create_s:
711err_print_s:
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800712 debugfs_remove(mbus->dent_u);
713 mbus->dent_u = NULL;
714err_create_u:
715err_print_u:
Pete Zaitcevce7cd137f2007-05-03 16:51:16 -0700716 if (ubus != NULL) {
717 debugfs_remove(mbus->dent_t);
718 mbus->dent_t = NULL;
719 }
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800720err_create_t:
721err_print_t:
722 return 0;
723}
724
725void mon_text_del(struct mon_bus *mbus)
726{
Pete Zaitcevf1c9e302007-02-24 19:27:33 -0800727 debugfs_remove(mbus->dent_u);
Pete Zaitcevce7cd137f2007-05-03 16:51:16 -0700728 if (mbus->dent_t != NULL)
729 debugfs_remove(mbus->dent_t);
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800730 debugfs_remove(mbus->dent_s);
731}
732
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733/*
734 * Slab interface: constructor.
735 */
Alexey Dobriyan51cc5062008-07-25 19:45:34 -0700736static void mon_text_ctor(void *mem)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737{
738 /*
739 * Nothing to initialize. No, really!
740 * So, we fill it with garbage to emulate a reused object.
741 */
742 memset(mem, 0xe5, sizeof(struct mon_event_text));
743}
744
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800745int __init mon_text_init(void)
746{
747 struct dentry *mondir;
748
Greg Kroah-Hartmanf49ce962009-04-24 15:15:49 -0700749 mondir = debugfs_create_dir("usbmon", usb_debug_root);
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800750 if (IS_ERR(mondir)) {
Tobias Klauser8dec92b2011-07-07 09:28:21 +0200751 /* debugfs not available, but we can use usbmon without it */
752 return 0;
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800753 }
754 if (mondir == NULL) {
755 printk(KERN_NOTICE TAG ": unable to create usbmon directory\n");
Tobias Klauser8dec92b2011-07-07 09:28:21 +0200756 return -ENOMEM;
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800757 }
758 mon_dir = mondir;
759 return 0;
760}
761
Pete Zaitcev21641e32007-02-20 10:37:52 -0800762void mon_text_exit(void)
Pete Zaitcev6f23ee12006-12-30 22:43:10 -0800763{
764 debugfs_remove(mon_dir);
765}