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