From owner-svn-src-user@FreeBSD.ORG Thu Oct 14 20:04:05 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 71ED9106564A; Thu, 14 Oct 2010 20:04:05 +0000 (UTC) (envelope-from weongyo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 606F28FC12; Thu, 14 Oct 2010 20:04:05 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o9EK45dn035373; Thu, 14 Oct 2010 20:04:05 GMT (envelope-from weongyo@svn.freebsd.org) Received: (from weongyo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o9EK458X035369; Thu, 14 Oct 2010 20:04:05 GMT (envelope-from weongyo@svn.freebsd.org) Message-Id: <201010142004.o9EK458X035369@svn.freebsd.org> From: Weongyo Jeong Date: Thu, 14 Oct 2010 20:04:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r213847 - user/weongyo/usb/sys/dev/usb X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Oct 2010 20:04:05 -0000 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 #include #include +#include #include #include #include +#include /* * 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 #include +#include 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);