Date: Thu, 14 Oct 2010 20:04:05 +0000 (UTC) From: Weongyo Jeong <weongyo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r213847 - user/weongyo/usb/sys/dev/usb Message-ID: <201010142004.o9EK458X035369@svn.freebsd.org>
index | next in thread | raw e-mail
Author: weongyo Date: Thu Oct 14 20:04:05 2010 New Revision: 213847 URL: http://svn.freebsd.org/changeset/base/213847 Log: Hooks the USB transfer taps at two points that one of them is at usbd_pipe_start() where is a location before calling the host controller-dependent code which normally enqueues a xfer into scheduler then adds it into the interrupt queue. It means it hooks all USB transfers before going into the interrupt queue. Other is at usbd_callback_wrapper() where is a function to call the developer-defined callback with status, USB_ST_TRANSFERRED or USB_ST_ERROR that we don't tap if the status is USB_ST_SETUP. Currently sizeof(struct usbpf_pkthdr) == 128 bytes for further works. Modified: user/weongyo/usb/sys/dev/usb/usb_pf.c user/weongyo/usb/sys/dev/usb/usb_pf.h user/weongyo/usb/sys/dev/usb/usb_transfer.c Modified: user/weongyo/usb/sys/dev/usb/usb_pf.c ============================================================================== --- user/weongyo/usb/sys/dev/usb/usb_pf.c Thu Oct 14 19:30:44 2010 (r213846) +++ user/weongyo/usb/sys/dev/usb/usb_pf.c Thu Oct 14 20:04:05 2010 (r213847) @@ -47,9 +47,11 @@ __FBSDID("$FreeBSD$"); #include <dev/usb/usbdi.h> #include <dev/usb/usb_busdma.h> #include <dev/usb/usb_controller.h> +#include <dev/usb/usb_core.h> #include <dev/usb/usb_device.h> #include <dev/usb/usb_bus.h> #include <dev/usb/usb_pf.h> +#include <dev/usb/usb_transfer.h> /* * All usbpf implementations are extracted from bpf(9) APIs and it's @@ -1663,7 +1665,7 @@ catchpacket(struct usbpf_d *ud, u_char * * by each process' filter, and if accepted, stashed into the corresponding * buffer. */ -void +static void usbpf_tap(struct usbpf_if *uif, u_char *pkt, u_int pktlen) { struct bintime bt; @@ -1689,6 +1691,76 @@ usbpf_tap(struct usbpf_if *uif, u_char * USBPFIF_UNLOCK(uif); } +void +usbpf_xfertap(struct usb_xfer *xfer, int type) +{ +#define USBPF_PAGE_SIZE (4 * 1024) + struct usb_endpoint *ep = xfer->endpoint; + struct usb_page_search res; + struct usb_xfer_root *info = xfer->xroot; + struct usb_bus *bus = info->bus; + struct usbpf_pkthdr *up; + int i; + char *buf, *ptr, *end; + + /* + * XXX TODO + * Allocating the buffer here causes copy operations twice what's + * really inefficient. Copying usbpf_pkthdr and data is for USB packet + * read filter to pass a virtually linear buffer. + */ + buf = ptr = malloc(sizeof(struct usbpf_pkthdr) + (USBPF_PAGE_SIZE * 5), + M_USBPF, M_NOWAIT); + if (buf == NULL) { + printf("usbpf_xfertap: out of memory\n"); /* XXX */ + return; + } + end = buf + sizeof(struct usbpf_pkthdr) + (USBPF_PAGE_SIZE * 5); + + bzero(ptr, sizeof(struct usbpf_pkthdr)); + up = (struct usbpf_pkthdr *)ptr; + up->up_busunit = device_get_unit(bus->bdev); + up->up_type = type; + up->up_xfertype = ep->edesc->bmAttributes & UE_XFERTYPE; + up->up_address = xfer->address; + up->up_endpoint = xfer->endpointno; + up->up_flags = xfer->flags; + up->up_status = xfer->status; + switch (type) { + case USBPF_XFERTAP_SUBMIT: + up->up_length = xfer->sumlen; + up->up_frames = xfer->nframes; + break; + case USBPF_XFERTAP_DONE: + up->up_length = xfer->actlen; + up->up_frames = xfer->aframes; + break; + default: + panic("wrong usbpf type (%d)", type); + } + + up->up_error = xfer->error; + up->up_interval = xfer->interval; + ptr += sizeof(struct usbpf_pkthdr); + + for (i = 0; i < up->up_frames; i++) { + if (ptr + sizeof(u_int32_t) >= end) + goto done; + *((u_int32_t *)ptr) = xfer->frlengths[i]; + ptr += sizeof(u_int32_t); + + if (ptr + xfer->frlengths[i] >= end) + goto done; + usbd_get_page(&xfer->frbuffers[i], 0, &res); + bcopy(res.buffer, ptr, xfer->frlengths[i]); + ptr += xfer->frlengths[i]; + } + + usbpf_tap(bus->uif, buf, ptr - buf); +done: + free(buf, M_USBPF); +} + static void usbpf_append_bytes(struct usbpf_d *ud, caddr_t buf, u_int offset, void *src, u_int len) Modified: user/weongyo/usb/sys/dev/usb/usb_pf.h ============================================================================== --- user/weongyo/usb/sys/dev/usb/usb_pf.h Thu Oct 14 19:30:44 2010 (r213846) +++ user/weongyo/usb/sys/dev/usb/usb_pf.h Thu Oct 14 20:04:05 2010 (r213847) @@ -151,6 +151,22 @@ struct usbpf_xhdr { #define USBPF_BUFMODE_BUFFER 1 /* Kernel buffers with read(). */ #define USBPF_BUFMODE_ZBUF 2 /* Zero-copy buffers. */ +struct usbpf_pkthdr { + int up_busunit; /* Host controller unit number */ + u_char up_address; /* USB device address */ + u_char up_endpoint; /* USB endpoint */ + u_char up_type; /* points SUBMIT / DONE */ + u_char up_xfertype; /* Transfer type */ + u_int32_t up_flags; /* Transfer flags */ + u_int32_t up_status; /* Transfer status */ + u_int32_t up_length; /* Total data length (submit/actual) */ + u_int32_t up_frames; /* USB frame number (submit/actual) */ + u_int32_t up_error; /* usb_error_t */ + u_int32_t up_interval; /* for interrupt and isoc */ + /* sizeof(struct usbpf_pkthdr) == 128 bytes */ + u_char up_reserved[96]; +} __packed; + struct usbpf_version { u_short uv_major; u_short uv_minor; @@ -181,6 +197,8 @@ struct usbpf_program { void usbpf_attach(struct usb_bus *, struct usbpf_if **); void usbpf_detach(struct usb_bus *); -void usbpf_tap(struct usbpf_if *, u_char *, u_int); +#define USBPF_XFERTAP_SUBMIT 0 +#define USBPF_XFERTAP_DONE 1 +void usbpf_xfertap(struct usb_xfer *, int); #endif Modified: user/weongyo/usb/sys/dev/usb/usb_transfer.c ============================================================================== --- user/weongyo/usb/sys/dev/usb/usb_transfer.c Thu Oct 14 19:30:44 2010 (r213846) +++ user/weongyo/usb/sys/dev/usb/usb_transfer.c Thu Oct 14 20:04:05 2010 (r213847) @@ -59,6 +59,7 @@ #include <dev/usb/usb_controller.h> #include <dev/usb/usb_bus.h> +#include <dev/usb/usb_pf.h> struct usb_std_packet_size { struct { @@ -2059,6 +2060,9 @@ usbd_callback_wrapper(struct usb_xfer_qu } } + if (xfer->usb_state != USB_ST_SETUP) + usbpf_xfertap(xfer, USBPF_XFERTAP_DONE); + /* call processing routine */ (xfer->callback) (xfer, xfer->error); @@ -2426,6 +2430,8 @@ usbd_pipe_start(struct usb_xfer_queue *p } DPRINTF("start\n"); + usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT); + /* start USB transfer */ (ep->methods->start) (xfer);help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010142004.o9EK458X035369>
