svn commit: r213847 - user/weongyo/usb/sys/dev/usb
Weongyo Jeong
weongyo at FreeBSD.org
Thu Oct 14 20:04:05 UTC 2010
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);
More information about the svn-src-user
mailing list