Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / usb / mon / mon_text.c
1 /*
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>
10 #include <linux/time.h>
11 #include <asm/uaccess.h>
12
13 #include "usb_mon.h"
14
15 /*
16  * No, we do not want arbitrarily long data strings.
17  * Use the binary interface if you want to capture bulk data!
18  */
19 #define DATA_MAX  32
20
21 /*
22  * This limit exists to prevent OOMs when the user process stops reading.
23  */
24 #define EVENT_MAX  25
25
26 #define PRINTF_DFL  120
27
28 struct mon_event_text {
29         struct list_head e_link;
30         int type;               /* submit, complete, etc. */
31         unsigned int pipe;      /* Pipe */
32         unsigned long id;       /* From pointer, most of the time */
33         unsigned int tstamp;
34         int length;             /* Depends on type: xfer length or act length */
35         int status;
36         char data_flag;
37         unsigned char data[DATA_MAX];
38 };
39
40 #define SLAB_NAME_SZ  30
41 struct mon_reader_text {
42         kmem_cache_t *e_slab;
43         int nevents;
44         struct list_head e_list;
45         struct mon_reader r;    /* In C, parent class can be placed anywhere */
46
47         wait_queue_head_t wait;
48         int printf_size;
49         char *printf_buf;
50         struct semaphore printf_lock;
51
52         char slab_name[SLAB_NAME_SZ];
53 };
54
55 static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
56 static void mon_text_dtor(void *, kmem_cache_t *, unsigned long);
57
58 /*
59  * mon_text_submit
60  * mon_text_complete
61  *
62  * May be called from an interrupt.
63  *
64  * This is called with the whole mon_bus locked, so no additional lock.
65  */
66
67 static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
68     int len, char ev_type)
69 {
70         int pipe = urb->pipe;
71         unsigned char *data;
72
73         /*
74          * The check to see if it's safe to poke at data has an enormous
75          * number of corner cases, but it seems that the following is
76          * more or less safe.
77          *
78          * We do not even try to look transfer_buffer, because it can
79          * contain non-NULL garbage in case the upper level promised to
80          * set DMA for the HCD.
81          */
82         if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
83                 return 'D';
84
85         if (len <= 0)
86                 return 'L';
87
88         if ((data = urb->transfer_buffer) == NULL)
89                 return 'Z';     /* '0' would be not as pretty. */
90
91         /*
92          * Bulk is easy to shortcut reliably. 
93          * XXX Control needs setup packet taken.
94          * XXX Other pipe types need consideration. Currently, we overdo it
95          * and collect garbage for them: better more than less.
96          */
97         if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) {
98                 if (usb_pipein(pipe)) {
99                         if (ev_type == 'S')
100                                 return '<';
101                 } else {
102                         if (ev_type == 'C')
103                                 return '>';
104                 }
105         }
106
107         if (len >= DATA_MAX)
108                 len = DATA_MAX;
109         memcpy(ep->data, urb->transfer_buffer, len);
110         return 0;
111 }
112
113 static inline unsigned int mon_get_timestamp(void)
114 {
115         struct timeval tval;
116         unsigned int stamp;
117
118         do_gettimeofday(&tval);
119         stamp = tval.tv_sec & 0xFFFF;   /* 2^32 = 4294967296. Limit to 4096s. */
120         stamp = stamp * 1000000 + tval.tv_usec;
121         return stamp;
122 }
123
124 static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
125     char ev_type)
126 {
127         struct mon_event_text *ep;
128         unsigned int stamp;
129
130         stamp = mon_get_timestamp();
131
132         if (rp->nevents >= EVENT_MAX ||
133             (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
134                 rp->r.m_bus->cnt_text_lost++;
135                 return;
136         }
137
138         ep->type = ev_type;
139         ep->pipe = urb->pipe;
140         ep->id = (unsigned long) urb;
141         ep->tstamp = stamp;
142         ep->length = (ev_type == 'S') ?
143             urb->transfer_buffer_length : urb->actual_length;
144         /* Collecting status makes debugging sense for submits, too */
145         ep->status = urb->status;
146
147         ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type);
148
149         rp->nevents++;
150         list_add_tail(&ep->e_link, &rp->e_list);
151         wake_up(&rp->wait);
152 }
153
154 static void mon_text_submit(void *data, struct urb *urb)
155 {
156         struct mon_reader_text *rp = data;
157         mon_text_event(rp, urb, 'S');
158 }
159
160 static void mon_text_complete(void *data, struct urb *urb)
161 {
162         struct mon_reader_text *rp = data;
163         mon_text_event(rp, urb, 'C');
164 }
165
166 /*
167  * Fetch next event from the circular buffer.
168  */
169 static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
170     struct mon_bus *mbus)
171 {
172         struct list_head *p;
173         unsigned long flags;
174
175         spin_lock_irqsave(&mbus->lock, flags);
176         if (list_empty(&rp->e_list)) {
177                 spin_unlock_irqrestore(&mbus->lock, flags);
178                 return NULL;
179         }
180         p = rp->e_list.next;
181         list_del(p);
182         --rp->nevents;
183         spin_unlock_irqrestore(&mbus->lock, flags);
184         return list_entry(p, struct mon_event_text, e_link);
185 }
186
187 /*
188  */
189 static int mon_text_open(struct inode *inode, struct file *file)
190 {
191         struct mon_bus *mbus;
192         struct usb_bus *ubus;
193         struct mon_reader_text *rp;
194         int rc;
195
196         down(&mon_lock);
197         mbus = inode->u.generic_ip;
198         ubus = mbus->u_bus;
199
200         rp = kmalloc(sizeof(struct mon_reader_text), GFP_KERNEL);
201         if (rp == NULL) {
202                 rc = -ENOMEM;
203                 goto err_alloc;
204         }
205         memset(rp, 0, sizeof(struct mon_reader_text));
206         INIT_LIST_HEAD(&rp->e_list);
207         init_waitqueue_head(&rp->wait);
208         init_MUTEX(&rp->printf_lock);
209
210         rp->printf_size = PRINTF_DFL;
211         rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL);
212         if (rp->printf_buf == NULL) {
213                 rc = -ENOMEM;
214                 goto err_alloc_pr;
215         }
216
217         rp->r.m_bus = mbus;
218         rp->r.r_data = rp;
219         rp->r.rnf_submit = mon_text_submit;
220         rp->r.rnf_complete = mon_text_complete;
221
222         snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum,
223             (long)rp);
224         rp->e_slab = kmem_cache_create(rp->slab_name,
225             sizeof(struct mon_event_text), sizeof(long), 0,
226             mon_text_ctor, mon_text_dtor);
227         if (rp->e_slab == NULL) {
228                 rc = -ENOMEM;
229                 goto err_slab;
230         }
231
232         mon_reader_add(mbus, &rp->r);
233
234         file->private_data = rp;
235         up(&mon_lock);
236         return 0;
237
238 // err_busy:
239 //      kmem_cache_destroy(rp->e_slab);
240 err_slab:
241         kfree(rp->printf_buf);
242 err_alloc_pr:
243         kfree(rp);
244 err_alloc:
245         up(&mon_lock);
246         return rc;
247 }
248
249 /*
250  * For simplicity, we read one record in one system call and throw out
251  * what does not fit. This means that the following does not work:
252  *   dd if=/dbg/usbmon/0t bs=10
253  * Also, we do not allow seeks and do not bother advancing the offset.
254  */
255 static ssize_t mon_text_read(struct file *file, char __user *buf,
256                                 size_t nbytes, loff_t *ppos)
257 {
258         struct mon_reader_text *rp = file->private_data;
259         struct mon_bus *mbus = rp->r.m_bus;
260         DECLARE_WAITQUEUE(waita, current);
261         struct mon_event_text *ep;
262         int cnt, limit;
263         char *pbuf;
264         char udir, utype;
265         int data_len, i;
266
267         add_wait_queue(&rp->wait, &waita);
268         set_current_state(TASK_INTERRUPTIBLE);
269         while ((ep = mon_text_fetch(rp, mbus)) == NULL) {
270                 if (file->f_flags & O_NONBLOCK) {
271                         set_current_state(TASK_RUNNING);
272                         remove_wait_queue(&rp->wait, &waita);
273                         return -EWOULDBLOCK;    /* Same as EAGAIN in Linux */
274                 }
275                 /*
276                  * We do not count nwaiters, because ->release is supposed
277                  * to be called when all openers are gone only.
278                  */
279                 schedule();
280                 if (signal_pending(current)) {
281                         remove_wait_queue(&rp->wait, &waita);
282                         return -EINTR;
283                 }
284                 set_current_state(TASK_INTERRUPTIBLE);
285         }
286         set_current_state(TASK_RUNNING);
287         remove_wait_queue(&rp->wait, &waita);
288
289         down(&rp->printf_lock);
290         cnt = 0;
291         pbuf = rp->printf_buf;
292         limit = rp->printf_size;
293
294         udir = usb_pipein(ep->pipe) ? 'i' : 'o';
295         switch (usb_pipetype(ep->pipe)) {
296         case PIPE_ISOCHRONOUS:  utype = 'Z'; break;
297         case PIPE_INTERRUPT:    utype = 'I'; break;
298         case PIPE_CONTROL:      utype = 'C'; break;
299         default: /* PIPE_BULK */  utype = 'B';
300         }
301         cnt += snprintf(pbuf + cnt, limit - cnt,
302             "%lx %u %c %c%c:%03u:%02u %d %d",
303             ep->id, ep->tstamp, ep->type,
304             utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe),
305             ep->status, ep->length);
306
307         if ((data_len = ep->length) > 0) {
308                 if (ep->data_flag == 0) {
309                         cnt += snprintf(pbuf + cnt, limit - cnt, " =");
310                         if (data_len >= DATA_MAX)
311                                 data_len = DATA_MAX;
312                         for (i = 0; i < data_len; i++) {
313                                 if (i % 4 == 0) {
314                                         cnt += snprintf(pbuf + cnt, limit - cnt,
315                                             " ");
316                                 }
317                                 cnt += snprintf(pbuf + cnt, limit - cnt,
318                                     "%02x", ep->data[i]);
319                         }
320                         cnt += snprintf(pbuf + cnt, limit - cnt, "\n");
321                 } else {
322                         cnt += snprintf(pbuf + cnt, limit - cnt,
323                             " %c\n", ep->data_flag);
324                 }
325         } else {
326                 cnt += snprintf(pbuf + cnt, limit - cnt, "\n");
327         }
328
329         if (copy_to_user(buf, rp->printf_buf, cnt))
330                 cnt = -EFAULT;
331         up(&rp->printf_lock);
332         kmem_cache_free(rp->e_slab, ep);
333         return cnt;
334 }
335
336 static int mon_text_release(struct inode *inode, struct file *file)
337 {
338         struct mon_reader_text *rp = file->private_data;
339         struct mon_bus *mbus;
340         /* unsigned long flags; */
341         struct list_head *p;
342         struct mon_event_text *ep;
343
344         down(&mon_lock);
345         mbus = inode->u.generic_ip;
346
347         if (mbus->nreaders <= 0) {
348                 printk(KERN_ERR TAG ": consistency error on close\n");
349                 up(&mon_lock);
350                 return 0;
351         }
352         mon_reader_del(mbus, &rp->r);
353
354         /*
355          * In theory, e_list is protected by mbus->lock. However,
356          * after mon_reader_del has finished, the following is the case:
357          *  - we are not on reader list anymore, so new events won't be added;
358          *  - whole mbus may be dropped if it was orphaned.
359          * So, we better not touch mbus.
360          */
361         /* spin_lock_irqsave(&mbus->lock, flags); */
362         while (!list_empty(&rp->e_list)) {
363                 p = rp->e_list.next;
364                 ep = list_entry(p, struct mon_event_text, e_link);
365                 list_del(p);
366                 --rp->nevents;
367                 kmem_cache_free(rp->e_slab, ep);
368         }
369         /* spin_unlock_irqrestore(&mbus->lock, flags); */
370
371         kmem_cache_destroy(rp->e_slab);
372         kfree(rp->printf_buf);
373         kfree(rp);
374
375         up(&mon_lock);
376         return 0;
377 }
378
379 struct file_operations mon_fops_text = {
380         .owner =        THIS_MODULE,
381         .open =         mon_text_open,
382         .llseek =       no_llseek,
383         .read =         mon_text_read,
384         /* .write =     mon_text_write, */
385         /* .poll =              mon_text_poll, */
386         /* .ioctl =     mon_text_ioctl, */
387         .release =      mon_text_release,
388 };
389
390 /*
391  * Slab interface: constructor.
392  */
393 static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
394 {
395         /*
396          * Nothing to initialize. No, really!
397          * So, we fill it with garbage to emulate a reused object.
398          */
399         memset(mem, 0xe5, sizeof(struct mon_event_text));
400 }
401
402 static void mon_text_dtor(void *mem, kmem_cache_t *slab, unsigned long sflags)
403 {
404         ;
405 }