X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fmon%2Fmon_text.c;h=611612146ae976ef4a2a48799d8da4db2969b1e8;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=755a4570477fdeb5a5f3fd714df3a7500948903e;hpb=b14c9c33594c5c8da3a20863d663f3709ed508ec;p=linux-2.6.git diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 755a45704..611612146 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -18,12 +18,17 @@ */ #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,11 +71,39 @@ 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 mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); + 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) { int pipe = urb->pipe; - unsigned char *data; + + if (len <= 0) + return 'L'; + if (len >= DATA_MAX) + len = DATA_MAX; + + if (usb_pipein(pipe)) { + if (ev_type == 'S') + return '<'; + } else { + if (ev_type == 'C') + return '>'; + } /* * The check to see if it's safe to poke at data has an enormous @@ -80,32 +115,11 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, * set DMA for the HCD. */ if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) - return 'D'; - - if (len <= 0) - return 'L'; + return mon_dmapeek(ep->data, urb->transfer_dma, len); - if ((data = urb->transfer_buffer) == NULL) + if (urb->transfer_buffer == NULL) return 'Z'; /* '0' would be not as pretty. */ - /* - * 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. - */ - if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) { - if (usb_pipein(pipe)) { - if (ev_type == 'S') - return '<'; - } else { - if (ev_type == 'C') - return '>'; - } - } - - if (len >= DATA_MAX) - len = DATA_MAX; memcpy(ep->data, urb->transfer_buffer, len); return 0; } @@ -144,6 +158,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 +314,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) {