diff options
Diffstat (limited to 'drivers/usb/mon')
-rw-r--r-- | drivers/usb/mon/Kconfig | 16 | ||||
-rw-r--r-- | drivers/usb/mon/Makefile | 3 | ||||
-rw-r--r-- | drivers/usb/mon/mon_main.c | 4 | ||||
-rw-r--r-- | drivers/usb/mon/mon_text.c | 48 | ||||
-rw-r--r-- | drivers/usb/mon/usb_mon.h | 2 |
5 files changed, 55 insertions, 18 deletions
diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig index 4e6152aa5f1..deb9ddffa40 100644 --- a/drivers/usb/mon/Kconfig +++ b/drivers/usb/mon/Kconfig @@ -2,21 +2,15 @@ # USB Monitor configuration # -# In normal life, it makes little sense to have usbmon as a module, and in fact -# it is harmful, because there is no way to autoload the module. -# The 'm' option is allowed for hackers who debug the usbmon itself, -# and for those who have usbcore as a module. config USB_MON - tristate "USB Monitor" - depends on USB + bool "USB Monitor" + depends on USB!=n default y help If you say Y here, a component which captures the USB traffic between peripheral-specific drivers and HC drivers will be built. - The USB_MON is similar in spirit and may be compatible with Dave - Harding's USBMon. + For more information, see <file:Documentation/usb/usbmon.txt>. - This is somewhat experimental at this time, but it should be safe, - as long as you aren't building this as a module and then removing it. + This is somewhat experimental at this time, but it should be safe. - If unsure, say Y. Do not say M. + If unsure, say Y. diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index 3cff8d444bb..b0015b8a1d1 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile @@ -4,4 +4,5 @@ usbmon-objs := mon_main.o mon_stat.o mon_text.o -obj-$(CONFIG_USB_MON) += usbmon.o +# This does not use CONFIG_USB_MON because we want this to use a tristate. +obj-$(CONFIG_USB) += usbmon.o diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index aa9d00808e4..508a21028db 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -2,6 +2,8 @@ * The USB Monitor, inspired by Dave Harding's USBMon. * * mon_main.c: Main file, module initiation and exit, registrations, etc. + * + * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com) */ #include <linux/kernel.h> @@ -311,7 +313,7 @@ static int __init mon_init(void) mondir = debugfs_create_dir("usbmon", NULL); if (IS_ERR(mondir)) { - printk(KERN_NOTICE TAG ": debugs is not available\n"); + printk(KERN_NOTICE TAG ": debugfs is not available\n"); return -ENODEV; } if (mondir == NULL) { diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 755a4570477..26266b30028 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -19,11 +19,16 @@ #define DATA_MAX 32 /* + * Defined by USB 2.0 clause 9.3, table 9.2. + */ +#define SETUP_MAX 8 + +/* * This limit exists to prevent OOMs when the user process stops reading. */ #define EVENT_MAX 25 -#define PRINTF_DFL 120 +#define PRINTF_DFL 130 struct mon_event_text { struct list_head e_link; @@ -33,7 +38,9 @@ struct mon_event_text { unsigned int tstamp; int length; /* Depends on type: xfer length or act length */ int status; + char setup_flag; char data_flag; + unsigned char setup[SETUP_MAX]; unsigned char data[DATA_MAX]; }; @@ -64,6 +71,22 @@ static void mon_text_dtor(void *, kmem_cache_t *, unsigned long); * This is called with the whole mon_bus locked, so no additional lock. */ +static inline char mon_text_get_setup(struct mon_event_text *ep, + struct urb *urb, char ev_type) +{ + + if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') + return '-'; + + if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) + return 'D'; + if (urb->setup_packet == NULL) + return 'Z'; /* '0' would be not as pretty. */ + + memcpy(ep->setup, urb->setup_packet, SETUP_MAX); + return 0; +} + static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, int len, char ev_type) { @@ -90,7 +113,6 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, /* * Bulk is easy to shortcut reliably. - * XXX Control needs setup packet taken. * XXX Other pipe types need consideration. Currently, we overdo it * and collect garbage for them: better more than less. */ @@ -144,6 +166,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, /* Collecting status makes debugging sense for submits, too */ ep->status = urb->status; + ep->setup_flag = mon_text_get_setup(ep, urb, ev_type); ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type); rp->nevents++; @@ -299,10 +322,25 @@ static ssize_t mon_text_read(struct file *file, char __user *buf, default: /* PIPE_BULK */ utype = 'B'; } cnt += snprintf(pbuf + cnt, limit - cnt, - "%lx %u %c %c%c:%03u:%02u %d %d", + "%lx %u %c %c%c:%03u:%02u", ep->id, ep->tstamp, ep->type, - utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe), - ep->status, ep->length); + utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); + + if (ep->setup_flag == 0) { /* Setup packet is present and captured */ + cnt += snprintf(pbuf + cnt, limit - cnt, + " s %02x %02x %04x %04x %04x", + ep->setup[0], + ep->setup[1], + (ep->setup[3] << 8) | ep->setup[2], + (ep->setup[5] << 8) | ep->setup[4], + (ep->setup[7] << 8) | ep->setup[6]); + } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */ + cnt += snprintf(pbuf + cnt, limit - cnt, + " %c __ __ ____ ____ ____", ep->setup_flag); + } else { /* No setup for this kind of URB */ + cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status); + } + cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length); if ((data_len = ep->length) > 0) { if (ep->data_flag == 0) { diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index ed35c18a5c4..9b06784d2c4 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h @@ -1,5 +1,7 @@ /* * The USB Monitor, inspired by Dave Harding's USBMon. + * + * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com) */ #ifndef __USB_MON_H |