hello, I just noticed that the patch I posted in the previous message was broken due to line wrapping, so I re-post it.
Some more details about the patch: the urb information are split across multiple events. For example, for Control transfer, the 'S' event carry the setup header, and the 'C' event carry the transfer flags. For ISO transfer the 'C' event carry the transfer flags and the interval and a newly introduced 'P' event carry the start_frame, the number of packets and iso packet descriptors for all the packets used by this transfer. This scenario require the user level usbmon reader to maintain some kind of per transfer status in order to fully reconstruct the transfer information. ciao, Paolo -- Index: linux/drivers/usb/mon/mon_bin.c =================================================================== --- linux.orig/drivers/usb/mon/mon_bin.c +++ linux/drivers/usb/mon/mon_bin.c @@ -72,6 +72,15 @@ #define BUFF_MIN CHUNK_ALIGN(8*1024) /* + * The event union type contained into the event struct struct is + * specified by the flag_hdr field. If it does not hold any of the following + * values it's content are unspecified + */ +#define MON_BIN_SETUP 0x00 +#define MON_BIN_XFER 0x01 +#define MON_BIN_ISO 0x02 + +/* * The per-event API header (2 per URB). * * This structure is seen in userland as defined by the documentation. @@ -83,14 +92,24 @@ struct mon_bin_hdr { unsigned char epnum; /* Endpoint number and transfer direction */ unsigned char devnum; /* Device address */ unsigned short busnum; /* Bus number */ - char flag_setup; + char flag_hdr; char flag_data; s64 ts_sec; /* gettimeofday */ s32 ts_usec; /* gettimeofday */ int status; unsigned int len_urb; /* Length of data (submitted or actual) */ unsigned int len_cap; /* Delivered length */ - unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ + union { + unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ + struct { + int interval; + unsigned int xfer_flags; + } compl_hdr; /* For C/E-Type */ + struct { + int start_frame; + int number_of_packets; + } iso_hdr; /* For ISO P-Type */ + }; }; /* per file statistic */ @@ -170,6 +189,12 @@ static inline struct mon_bin_hdr *MON_OF (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); } +static inline struct usb_iso_packet_descriptor* MON_OFF2DSC( + const struct mon_reader_bin *rp, unsigned int offset) +{ + return (struct usb_iso_packet_descriptor*) + (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); +} #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) static struct class *mon_bin_class; @@ -385,6 +410,52 @@ static char mon_bin_get_data(const struc return 0; } +/* create extra event for ISO frames info; must be called with rp->b_lock hold */ +static void mon_bin_iso_event(struct mon_reader_bin *rp, struct urb *urb, + struct timeval* ts) +{ + int i,datalen; + unsigned int offset; + struct mon_bin_hdr *ep; + + datalen = urb->number_of_packets * sizeof(struct usb_iso_packet_descriptor); + offset = mon_buff_area_alloc_contiguous(rp, PKT_SIZE + datalen); + /* XXXX this is not a real event lost, should we increment rp->cnt_lost ?!?*/ + if (offset == ~0) + return; + + ep = MON_OFF2HDR(rp, offset); + if ((offset += PKT_SIZE) >= rp->b_size) + offset = 0; + ep->type = 'P'; + ep->xfer_type = usb_pipetype(urb->pipe); + ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); + ep->devnum = usb_pipedevice(urb->pipe); + ep->busnum = urb->dev->bus->busnum; + ep->id = (unsigned long) urb; + ep->ts_sec = ts->tv_sec; + ep->ts_usec = ts->tv_usec; + ep->status = urb->status; + ep->len_urb = datalen; + ep->len_cap = datalen; + ep->flag_data = 0; + ep->flag_hdr = MON_BIN_ISO; + ep->iso_hdr.start_frame = cpu_to_be32(urb->start_frame); + ep->iso_hdr.number_of_packets = cpu_to_be32(urb->number_of_packets); + for (i = 0; i< ep->iso_hdr.number_of_packets; ++i) { + struct usb_iso_packet_descriptor* pd = MON_OFF2DSC(rp, offset); + offset = (offset + sizeof(struct usb_iso_packet_descriptor)) % + rp->b_size; + + /* the frame data is going into the event data. For consistency + * with 'real' events keep this data in big endian byte order */ + pd->offset = cpu_to_be32(urb->iso_frame_desc[i].offset); + pd->length = cpu_to_be32(urb->iso_frame_desc[i].length); + pd->actual_length = cpu_to_be32(urb->iso_frame_desc[i].actual_length); + pd->status = cpu_to_be32(urb->iso_frame_desc[i].status); + } +} + static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, char ev_type) { @@ -452,7 +523,8 @@ static void mon_bin_event(struct mon_rea ep->len_urb = urb_length; ep->len_cap = length; - ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); + /* should we set flag_data accoringly to effective type this event union ?!?*/ + ep->flag_hdr = mon_bin_get_setup(ep->setup, urb, ev_type); if (length != 0) { ep->flag_data = mon_bin_get_data(rp, offset, urb, length); if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ @@ -462,6 +534,14 @@ static void mon_bin_event(struct mon_rea } else { ep->flag_data = data_tag; } + if (ev_type == 'C') { + ep->compl_hdr.xfer_flags = cpu_to_be32(urb->transfer_flags); + /* this field is meaningful only for ISO and interrupt transfer*/ + ep->compl_hdr.interval = cpu_to_be32(urb->interval); + ep->flag_hdr = MON_BIN_XFER; + } else if (usb_pipeisoc(urb->pipe)) + /* add extra info for iso frames only on submit event */ + mon_bin_iso_event(rp, urb, &ts); spin_unlock_irqrestore(&rp->b_lock, flags); @@ -508,8 +588,11 @@ static void mon_bin_error(void *data, st ep->id = (unsigned long) urb; ep->status = error; - ep->flag_setup = '-'; + ep->flag_hdr = MON_BIN_XFER; ep->flag_data = 'E'; + ep->compl_hdr.xfer_flags = cpu_to_be32(urb->transfer_flags); + /* this field is meaningful only for ISO and interrupt transfer*/ + ep->compl_hdr.interval = cpu_to_be32(urb->interval); spin_unlock_irqrestore(&rp->b_lock, flags); -- Email.it, the professional e-mail, gratis per te: http://www.email.it/f Sponsor: Fai crescere i tuoi sogni. Prestiti semplici e veloci * Rate da 20 euro al mese Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=6334&d=29-3 ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel