xref: /openbmc/linux/drivers/usb/mon/mon_text.c (revision 1da177e4)
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 }
406