Author: weongyo
Date: Wed Nov 24 19:11:32 2010
New Revision: 215802
URL: http://svn.freebsd.org/changeset/base/215802

Log:
  Removes all duplicated code with BPF that it's greatly simplified and
  take all benefits whenever BPF code is improved.
  
  Pointed by:   jkim
  Reviewed by:  thompsa

Modified:
  head/sys/dev/usb/controller/usb_controller.c
  head/sys/dev/usb/usb_bus.h
  head/sys/dev/usb/usb_pf.c
  head/sys/dev/usb/usb_pf.h

Modified: head/sys/dev/usb/controller/usb_controller.c
==============================================================================
--- head/sys/dev/usb/controller/usb_controller.c        Wed Nov 24 18:35:11 
2010        (r215801)
+++ head/sys/dev/usb/controller/usb_controller.c        Wed Nov 24 19:11:32 
2010        (r215802)
@@ -548,7 +548,7 @@ usb_bus_mem_alloc_all(struct usb_bus *bu
 
        TAILQ_INIT(&bus->intr_q.head);
 
-       usbpf_attach(bus, &bus->uif);
+       usbpf_attach(bus);
 
 #if USB_HAVE_BUSDMA
        usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,

Modified: head/sys/dev/usb/usb_bus.h
==============================================================================
--- head/sys/dev/usb/usb_bus.h  Wed Nov 24 18:35:11 2010        (r215801)
+++ head/sys/dev/usb/usb_bus.h  Wed Nov 24 19:11:32 2010        (r215802)
@@ -86,7 +86,7 @@ struct usb_bus {
        struct usb_bus_methods *methods;        /* filled by HC driver */
        struct usb_device **devices;
 
-       struct usbpf_if *uif;   /* USB Packet Filter */
+       struct ifnet *ifp;      /* only for USB Packet Filter */
 
        usb_power_mask_t hw_power_state;        /* see USB_HW_POWER_XXX */
        usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];

Modified: head/sys/dev/usb/usb_pf.c
==============================================================================
--- head/sys/dev/usb/usb_pf.c   Wed Nov 24 18:35:11 2010        (r215801)
+++ head/sys/dev/usb/usb_pf.c   Wed Nov 24 19:11:32 2010        (r215802)
@@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -55,1624 +57,39 @@ __FBSDID("$FreeBSD$");
 #include <dev/usb/usb_pf.h>
 #include <dev/usb/usb_transfer.h>
 
-/*
- * All usbpf implementations are extracted from bpf(9) APIs and it's
- * specialized for USB packet filtering between the driver and the host
- * controller.
- */
-
-MALLOC_DEFINE(M_USBPF, "USBPktFilter", "USB Packet Filter");
-
-/*
- * Rotate the packet buffers in descriptor ud.  Move the store buffer into the
- * hold slot, and the free buffer ino the store slot.  Zero the length of the
- * new store buffer.  Descriptor lock should be held.
- */
-#define        USBPF_ROTATE_BUFFERS(ud)        do {                            
\
-       (ud)->ud_hbuf = (ud)->ud_sbuf;                                  \
-       (ud)->ud_hlen = (ud)->ud_slen;                                  \
-       (ud)->ud_sbuf = (ud)->ud_fbuf;                                  \
-       (ud)->ud_slen = 0;                                              \
-       (ud)->ud_fbuf = NULL;                                           \
-       usbpf_bufheld(ud);                                              \
-} while (0)
-
-#ifndef __i386__
-#define        USBPF_ALIGN
-#endif
-
-#ifndef USBPF_ALIGN
-#define        USBPF_EXTRACT_SHORT(p)  ((u_int16_t)ntohs(*(u_int16_t *)p))
-#define        USBPF_EXTRACT_LONG(p)   (ntohl(*(u_int32_t *)p))
-#else
-#define        USBPF_EXTRACT_SHORT(p)                                          
\
-       ((u_int16_t)                                                    \
-           ((u_int16_t)*((u_char *)p+0)<<8|                            \
-               (u_int16_t)*((u_char *)p+1)<<0))
-#define        USBPF_EXTRACT_LONG(p)                                           
\
-       ((u_int32_t)*((u_char *)p+0)<<24|                               \
-           (u_int32_t)*((u_char *)p+1)<<16|                            \
-           (u_int32_t)*((u_char *)p+2)<<8|                             \
-           (u_int32_t)*((u_char *)p+3)<<0)
-#endif
-
-/*
- * Number of scratch memory words (for USBPF_LD|USBPF_MEM and USBPF_ST).
- */
-#define        USBPF_MEMWORDS           16
-
-/* Values for ud_state */
-#define        USBPF_IDLE              0       /* no select in progress */
-#define        USBPF_WAITING           1       /* waiting for read timeout in 
select */
-#define        USBPF_TIMED_OUT         2       /* read timeout has expired in 
select */
-
-#define        PRIUSB                  26      /* interruptible */
-
-/* Frame directions */
-enum usbpf_direction {
-       USBPF_D_IN,     /* See incoming frames */
-       USBPF_D_INOUT,  /* See incoming and outgoing frames */
-       USBPF_D_OUT     /* See outgoing frames */
-};
-
-static void    usbpf_append_bytes(struct usbpf_d *, caddr_t, u_int, void *,
-                   u_int);
-static void    usbpf_attachd(struct usbpf_d *, struct usbpf_if *);
-static void    usbpf_detachd(struct usbpf_d *);
-static int     usbpf_canfreebuf(struct usbpf_d *);
-static void    usbpf_buf_reclaimed(struct usbpf_d *);
-static int     usbpf_canwritebuf(struct usbpf_d *);
-
-static d_open_t        usbpf_open;
-static d_read_t        usbpf_read;
-static d_write_t       usbpf_write;
-static d_ioctl_t       usbpf_ioctl;
-static d_poll_t        usbpf_poll;
-static d_kqfilter_t    usbpf_kqfilter;
-
-static struct cdevsw usbpf_cdevsw = {
-       .d_version =    D_VERSION,
-       .d_open =       usbpf_open,
-       .d_read =       usbpf_read,
-       .d_write =      usbpf_write,
-       .d_ioctl =      usbpf_ioctl,
-       .d_poll =       usbpf_poll,
-       .d_name =       "usbpf",
-       .d_kqfilter =   usbpf_kqfilter,
-};
-
-static struct cdev *usbpf_cdev;
-static LIST_HEAD(, usbpf_if)   usbpf_iflist;
-static struct mtx      usbpf_mtx;              /* global lock */
-static int usbpf_uifd_cnt;
-
-static int usbpf_bufsize = 4096;
-#define        USBPF_MINBUFSIZE 32
-#define        USBPF_MAXBUFSIZE 0x80000
-static int usbpf_maxbufsize = USBPF_MAXBUFSIZE;
-#define        USBPF_MAXINSNS 512
-static int usbpf_maxinsns = USBPF_MAXINSNS;
-
-static void
-usbpf_buffer_init(struct usbpf_d *ud)
-{
-
-       ud->ud_bufsize = usbpf_bufsize;
-}
-
-/*
- * Free USBPF kernel buffers on device close.
- */
-static void
-usbpf_buffer_free(struct usbpf_d *ud)
-{
-
-       if (ud->ud_sbuf != NULL)
-               free(ud->ud_sbuf, M_USBPF);
-       if (ud->ud_hbuf != NULL)
-               free(ud->ud_hbuf, M_USBPF);
-       if (ud->ud_fbuf != NULL)
-               free(ud->ud_fbuf, M_USBPF);
-
-#ifdef INVARIANTS
-       ud->ud_sbuf = ud->ud_hbuf = ud->ud_fbuf = (caddr_t)~0;
-#endif
-}
-
-static void
-usbpf_buffer_alloc(struct usbpf_d *ud)
-{
-
-       KASSERT(ud->ud_fbuf == NULL, ("%s: ud_fbuf != NULL", __func__));
-       KASSERT(ud->ud_sbuf == NULL, ("%s: ud_sbuf != NULL", __func__));
-       KASSERT(ud->ud_hbuf == NULL, ("%s: ud_hbuf != NULL", __func__));
-
-       ud->ud_fbuf = (caddr_t)malloc(ud->ud_bufsize, M_USBPF, M_WAITOK);
-       ud->ud_sbuf = (caddr_t)malloc(ud->ud_bufsize, M_USBPF, M_WAITOK);
-       ud->ud_hbuf = NULL;
-       ud->ud_slen = 0;
-       ud->ud_hlen = 0;
-}
-
-/*
- * Copy buffer storage to user space in read().
- */
-static int
-usbpf_buffer_uiomove(struct usbpf_d *ud, caddr_t buf, u_int len,
-    struct uio *uio)
-{
-
-       return (uiomove(buf, len, uio));
-}
-
-/*
- * Simple data copy to the current kernel buffer.
- */
-static void
-usbpf_buffer_append_bytes(struct usbpf_d *ud, caddr_t buf, u_int offset,
-    void *src, u_int len)
-{
-       u_char *src_bytes;
-
-       src_bytes = (u_char *)src;
-       bcopy(src_bytes, buf + offset, len);
-}
-
-/*
- * Allocate or resize buffers.
- */
-static int
-usbpf_buffer_ioctl_sblen(struct usbpf_d *ud, u_int *i)
-{
-       u_int size;
-
-       USBPFD_LOCK(ud);
-       if (ud->ud_bif != NULL) {
-               USBPFD_UNLOCK(ud);
-               return (EINVAL);
-       }
-       size = *i;
-       if (size > usbpf_maxbufsize)
-               *i = size = usbpf_maxbufsize;
-       else if (size < USBPF_MINBUFSIZE)
-               *i = size = USBPF_MINBUFSIZE;
-       ud->ud_bufsize = size;
-       USBPFD_UNLOCK(ud);
-       return (0);
-}
-
-static const u_short   usbpf_code_map[] = {
-       0x10ff, /* 0x00-0x0f: 1111111100001000 */
-       0x3070, /* 0x10-0x1f: 0000111000001100 */
-       0x3131, /* 0x20-0x2f: 1000110010001100 */
-       0x3031, /* 0x30-0x3f: 1000110000001100 */
-       0x3131, /* 0x40-0x4f: 1000110010001100 */
-       0x1011, /* 0x50-0x5f: 1000100000001000 */
-       0x1013, /* 0x60-0x6f: 1100100000001000 */
-       0x1010, /* 0x70-0x7f: 0000100000001000 */
-       0x0093, /* 0x80-0x8f: 1100100100000000 */
-       0x0000, /* 0x90-0x9f: 0000000000000000 */
-       0x0000, /* 0xa0-0xaf: 0000000000000000 */
-       0x0002, /* 0xb0-0xbf: 0100000000000000 */
-       0x0000, /* 0xc0-0xcf: 0000000000000000 */
-       0x0000, /* 0xd0-0xdf: 0000000000000000 */
-       0x0000, /* 0xe0-0xef: 0000000000000000 */
-       0x0000  /* 0xf0-0xff: 0000000000000000 */
-};
-
-#define        USBPF_VALIDATE_CODE(c)  \
-    ((c) <= 0xff && (usbpf_code_map[(c) >> 4] & (1 << ((c) & 0xf))) != 0)
-
-/*
- * Return true if the 'fcode' is a valid filter program.
- * The constraints are that each jump be forward and to a valid
- * code.  The code must terminate with either an accept or reject.
- *
- * The kernel needs to be able to verify an application's filter code.
- * Otherwise, a bogus program could easily crash the system.
- */
-static int
-usbpf_validate(const struct usbpf_insn *f, int len)
-{
-       register int i;
-       register const struct usbpf_insn *p;
-
-       /* Do not accept negative length filter. */
-       if (len < 0)
-               return (0);
-
-       /* An empty filter means accept all. */
-       if (len == 0)
-               return (1);
-
-       for (i = 0; i < len; ++i) {
-               p = &f[i];
-               /*
-                * Check that the code is valid.
-                */
-               if (!USBPF_VALIDATE_CODE(p->code))
-                       return (0);
-               /*
-                * Check that that jumps are forward, and within
-                * the code block.
-                */
-               if (USBPF_CLASS(p->code) == USBPF_JMP) {
-                       register u_int offset;
-
-                       if (p->code == (USBPF_JMP|USBPF_JA))
-                               offset = p->k;
-                       else
-                               offset = p->jt > p->jf ? p->jt : p->jf;
-                       if (offset >= (u_int)(len - i) - 1)
-                               return (0);
-                       continue;
-               }
-               /*
-                * Check that memory operations use valid addresses.
-                */
-               if (p->code == USBPF_ST || p->code == USBPF_STX ||
-                   p->code == (USBPF_LD|USBPF_MEM) ||
-                   p->code == (USBPF_LDX|USBPF_MEM)) {
-                       if (p->k >= USBPF_MEMWORDS)
-                               return (0);
-                       continue;
-               }
-               /*
-                * Check for constant division by 0.
-                */
-               if (p->code == (USBPF_ALU|USBPF_DIV|USBPF_K) && p->k == 0)
-                       return (0);
-       }
-       return (USBPF_CLASS(f[len - 1].code) == USBPF_RET);
-}
-
-#ifdef _KERNEL
-#define        MINDEX(m, k) \
-{ \
-       register int len = m->m_len; \
- \
-       while (k >= len) { \
-               k -= len; \
-               m = m->m_next; \
-               if (m == 0) \
-                       return (0); \
-               len = m->m_len; \
-       } \
-}
-
-static u_int16_t       m_xhalf(struct mbuf *m, usbpf_u_int32 k, int *err);
-static u_int32_t       m_xword(struct mbuf *m, usbpf_u_int32 k, int *err);
-
-static u_int32_t
-m_xword(struct mbuf *m, usbpf_u_int32 k, int *err)
-{
-       size_t len;
-       u_char *cp, *np;
-       struct mbuf *m0;
-
-       len = m->m_len;
-       while (k >= len) {
-               k -= len;
-               m = m->m_next;
-               if (m == 0)
-                       goto bad;
-               len = m->m_len;
-       }
-       cp = mtod(m, u_char *) + k;
-       if (len - k >= 4) {
-               *err = 0;
-               return (USBPF_EXTRACT_LONG(cp));
-       }
-       m0 = m->m_next;
-       if (m0 == 0 || m0->m_len + len - k < 4)
-               goto bad;
-       *err = 0;
-       np = mtod(m0, u_char *);
-       switch (len - k) {
-       case 1:
-               return (((u_int32_t)cp[0] << 24) |
-                   ((u_int32_t)np[0] << 16) |
-                   ((u_int32_t)np[1] << 8)  |
-                   (u_int32_t)np[2]);
-
-       case 2:
-               return (((u_int32_t)cp[0] << 24) |
-                   ((u_int32_t)cp[1] << 16) |
-                   ((u_int32_t)np[0] << 8) |
-                   (u_int32_t)np[1]);
-
-       default:
-               return (((u_int32_t)cp[0] << 24) |
-                   ((u_int32_t)cp[1] << 16) |
-                   ((u_int32_t)cp[2] << 8) |
-                   (u_int32_t)np[0]);
-       }
-    bad:
-       *err = 1;
-       return (0);
-}
-
-static u_int16_t
-m_xhalf(struct mbuf *m, usbpf_u_int32 k, int *err)
-{
-       size_t len;
-       u_char *cp;
-       struct mbuf *m0;
-
-       len = m->m_len;
-       while (k >= len) {
-               k -= len;
-               m = m->m_next;
-               if (m == 0)
-                       goto bad;
-               len = m->m_len;
-       }
-       cp = mtod(m, u_char *) + k;
-       if (len - k >= 2) {
-               *err = 0;
-               return (USBPF_EXTRACT_SHORT(cp));
-       }
-       m0 = m->m_next;
-       if (m0 == 0)
-               goto bad;
-       *err = 0;
-       return ((cp[0] << 8) | mtod(m0, u_char *)[0]);
- bad:
-       *err = 1;
-       return (0);
-}
-#endif
-
-/*
- * Execute the filter program starting at pc on the packet p
- * wirelen is the length of the original packet
- * buflen is the amount of data present
- */
-static u_int
-usbpf_filter(const struct usbpf_insn *pc, u_char *p, u_int wirelen,
-    u_int buflen)
-{
-       u_int32_t A = 0, X = 0;
-       usbpf_u_int32 k;
-       u_int32_t mem[USBPF_MEMWORDS];
-
-       /*
-        * XXX temporarily the filter system is disabled because currently it
-        * could not handle the some machine code properly that leads to
-        * kernel crash by invalid usage.
-        */
-       return ((u_int)-1);
-
-       if (pc == NULL)
-               /*
-                * No filter means accept all.
-                */
-               return ((u_int)-1);
-
-       --pc;
-       while (1) {
-               ++pc;
-               switch (pc->code) {
-               default:
-#ifdef _KERNEL
-                       return (0);
-#else
-                       abort();
-#endif
-
-               case USBPF_RET|USBPF_K:
-                       return ((u_int)pc->k);
-
-               case USBPF_RET|USBPF_A:
-                       return ((u_int)A);
-
-               case USBPF_LD|USBPF_W|USBPF_ABS:
-                       k = pc->k;
-                       if (k > buflen || sizeof(int32_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xword((struct mbuf *)p, k, &merr);
-                               if (merr != 0)
-                                       return (0);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-#ifdef USBPF_ALIGN
-                       if (((intptr_t)(p + k) & 3) != 0)
-                               A = USBPF_EXTRACT_LONG(&p[k]);
-                       else
-#endif
-                               A = ntohl(*(int32_t *)(p + k));
-                       continue;
-
-               case USBPF_LD|USBPF_H|USBPF_ABS:
-                       k = pc->k;
-                       if (k > buflen || sizeof(int16_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xhalf((struct mbuf *)p, k, &merr);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = USBPF_EXTRACT_SHORT(&p[k]);
-                       continue;
-
-               case USBPF_LD|USBPF_B|USBPF_ABS:
-                       k = pc->k;
-                       if (k >= buflen) {
-#ifdef _KERNEL
-                               struct mbuf *m;
-
-                               if (buflen != 0)
-                                       return (0);
-                               m = (struct mbuf *)p;
-                               MINDEX(m, k);
-                               A = mtod(m, u_char *)[k];
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = p[k];
-                       continue;
-
-               case USBPF_LD|USBPF_W|USBPF_LEN:
-                       A = wirelen;
-                       continue;
-
-               case USBPF_LDX|USBPF_W|USBPF_LEN:
-                       X = wirelen;
-                       continue;
-
-               case USBPF_LD|USBPF_W|USBPF_IND:
-                       k = X + pc->k;
-                       if (pc->k > buflen || X > buflen - pc->k ||
-                           sizeof(int32_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xword((struct mbuf *)p, k, &merr);
-                               if (merr != 0)
-                                       return (0);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-#ifdef USBPF_ALIGN
-                       if (((intptr_t)(p + k) & 3) != 0)
-                               A = USBPF_EXTRACT_LONG(&p[k]);
-                       else
-#endif
-                               A = ntohl(*(int32_t *)(p + k));
-                       continue;
-
-               case USBPF_LD|USBPF_H|USBPF_IND:
-                       k = X + pc->k;
-                       if (X > buflen || pc->k > buflen - X ||
-                           sizeof(int16_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xhalf((struct mbuf *)p, k, &merr);
-                               if (merr != 0)
-                                       return (0);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = USBPF_EXTRACT_SHORT(&p[k]);
-                       continue;
-
-               case USBPF_LD|USBPF_B|USBPF_IND:
-                       k = X + pc->k;
-                       if (pc->k >= buflen || X >= buflen - pc->k) {
-#ifdef _KERNEL
-                               struct mbuf *m;
-
-                               if (buflen != 0)
-                                       return (0);
-                               m = (struct mbuf *)p;
-                               MINDEX(m, k);
-                               A = mtod(m, u_char *)[k];
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = p[k];
-                       continue;
-
-               case USBPF_LDX|USBPF_MSH|USBPF_B:
-                       k = pc->k;
-                       if (k >= buflen) {
-#ifdef _KERNEL
-                               register struct mbuf *m;
-
-                               if (buflen != 0)
-                                       return (0);
-                               m = (struct mbuf *)p;
-                               MINDEX(m, k);
-                               X = (mtod(m, u_char *)[k] & 0xf) << 2;
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       X = (p[pc->k] & 0xf) << 2;
-                       continue;
-
-               case USBPF_LD|USBPF_IMM:
-                       A = pc->k;
-                       continue;
-
-               case USBPF_LDX|USBPF_IMM:
-                       X = pc->k;
-                       continue;
-
-               case USBPF_LD|USBPF_MEM:
-                       A = mem[pc->k];
-                       continue;
-
-               case USBPF_LDX|USBPF_MEM:
-                       X = mem[pc->k];
-                       continue;
-
-               case USBPF_ST:
-                       mem[pc->k] = A;
-                       continue;
-
-               case USBPF_STX:
-                       mem[pc->k] = X;
-                       continue;
-
-               case USBPF_JMP|USBPF_JA:
-                       pc += pc->k;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGT|USBPF_K:
-                       pc += (A > pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGE|USBPF_K:
-                       pc += (A >= pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JEQ|USBPF_K:
-                       pc += (A == pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JSET|USBPF_K:
-                       pc += (A & pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGT|USBPF_X:
-                       pc += (A > X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGE|USBPF_X:
-                       pc += (A >= X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JEQ|USBPF_X:
-                       pc += (A == X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JSET|USBPF_X:
-                       pc += (A & X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_ALU|USBPF_ADD|USBPF_X:
-                       A += X;
-                       continue;
-
-               case USBPF_ALU|USBPF_SUB|USBPF_X:
-                       A -= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_MUL|USBPF_X:
-                       A *= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_DIV|USBPF_X:
-                       if (X == 0)
-                               return (0);
-                       A /= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_AND|USBPF_X:
-                       A &= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_OR|USBPF_X:
-                       A |= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_LSH|USBPF_X:
-                       A <<= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_RSH|USBPF_X:
-                       A >>= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_ADD|USBPF_K:
-                       A += pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_SUB|USBPF_K:
-                       A -= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_MUL|USBPF_K:
-                       A *= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_DIV|USBPF_K:
-                       A /= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_AND|USBPF_K:
-                       A &= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_OR|USBPF_K:
-                       A |= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_LSH|USBPF_K:
-                       A <<= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_RSH|USBPF_K:
-                       A >>= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_NEG:
-                       A = -A;
-                       continue;
-
-               case USBPF_MISC|USBPF_TAX:
-                       X = A;
-                       continue;
-
-               case USBPF_MISC|USBPF_TXA:
-                       A = X;
-                       continue;
-               }
-       }
-}
-
-static void
-usbpf_free(struct usbpf_d *ud)
-{
-
-       switch (ud->ud_bufmode) {
-       case USBPF_BUFMODE_BUFFER:
-               return (usbpf_buffer_free(ud));
-       default:
-               panic("usbpf_buf_free");
-       }
-}
-
-/*
- * Notify the buffer model that a buffer has moved into the hold position.
- */
-static void
-usbpf_bufheld(struct usbpf_d *ud)
-{
-
-       USBPFD_LOCK_ASSERT(ud);
-}
-
-/*
- * Free buffers currently in use by a descriptor.
- * Called on close.
- */
-static void
-usbpf_freed(struct usbpf_d *ud)
-{
-
-       /*
-        * We don't need to lock out interrupts since this descriptor has
-        * been detached from its interface and it yet hasn't been marked
-        * free.
-        */
-       usbpf_free(ud);
-       if (ud->ud_rfilter != NULL)
-               free((caddr_t)ud->ud_rfilter, M_USBPF);
-       if (ud->ud_wfilter != NULL)
-               free((caddr_t)ud->ud_wfilter, M_USBPF);
-       mtx_destroy(&ud->ud_mtx);
-}
-
-/*
- * Close the descriptor by detaching it from its interface,
- * deallocating its buffers, and marking it free.
- */
-static void
-usbpf_dtor(void *data)
-{
-       struct usbpf_d *ud = data;
-
-       USBPFD_LOCK(ud);
-       if (ud->ud_state == USBPF_WAITING)
-               callout_stop(&ud->ud_callout);
-       ud->ud_state = USBPF_IDLE;
-       USBPFD_UNLOCK(ud);
-       funsetown(&ud->ud_sigio);
-       mtx_lock(&usbpf_mtx);
-       if (ud->ud_bif)
-               usbpf_detachd(ud);
-       mtx_unlock(&usbpf_mtx);
-       selwakeuppri(&ud->ud_sel, PRIUSB);
-       knlist_destroy(&ud->ud_sel.si_note);
-       callout_drain(&ud->ud_callout);
-       usbpf_freed(ud);
-       free(ud, M_USBPF);
-}
-
-/*
- * Open device.  Returns ENXIO for illegal minor device number,
- * EBUSY if file is open by another process.
- */
-/* ARGSUSED */
-static int
-usbpf_open(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
-       struct usbpf_d *ud;
-       int error;
-
-       ud = malloc(sizeof(*ud), M_USBPF, M_WAITOK | M_ZERO);
-       error = devfs_set_cdevpriv(ud, usbpf_dtor);
-       if (error != 0) {
-               free(ud, M_USBPF);
-               return (error);
-       }
-
-       usbpf_buffer_init(ud);
-       ud->ud_bufmode = USBPF_BUFMODE_BUFFER;
-       ud->ud_sig = SIGIO;
-       ud->ud_direction = USBPF_D_INOUT;
-       ud->ud_pid = td->td_proc->p_pid;
-       mtx_init(&ud->ud_mtx, devtoname(dev), "usbpf cdev lock", MTX_DEF);
-       callout_init_mtx(&ud->ud_callout, &ud->ud_mtx, 0);
-       knlist_init_mtx(&ud->ud_sel.si_note, &ud->ud_mtx);
-
-       return (0);
-}
-
-static int
-usbpf_uiomove(struct usbpf_d *ud, caddr_t buf, u_int len, struct uio *uio)
-{
-
-       if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER)
-               return (EOPNOTSUPP);
-       return (usbpf_buffer_uiomove(ud, buf, len, uio));
-}
-
-/*
- *  usbpf_read - read next chunk of packets from buffers
- */
-static int
-usbpf_read(struct cdev *dev, struct uio *uio, int ioflag)
-{
-       struct usbpf_d *ud;
-       int error;
-       int non_block;
-       int timed_out;
-
-       error = devfs_get_cdevpriv((void **)&ud);
-       if (error != 0)
-               return (error);
-
-       /*
-        * Restrict application to use a buffer the same size as
-        * as kernel buffers.
-        */
-       if (uio->uio_resid != ud->ud_bufsize)
-               return (EINVAL);
-
-       non_block = ((ioflag & O_NONBLOCK) != 0);
-
-       USBPFD_LOCK(ud);
-       ud->ud_pid = curthread->td_proc->p_pid;
-       if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER) {
-               USBPFD_UNLOCK(ud);
-               return (EOPNOTSUPP);
-       }
-       if (ud->ud_state == USBPF_WAITING)
-               callout_stop(&ud->ud_callout);
-       timed_out = (ud->ud_state == USBPF_TIMED_OUT);
-       ud->ud_state = USBPF_IDLE;
-       /*
-        * If the hold buffer is empty, then do a timed sleep, which
-        * ends when the timeout expires or when enough packets
-        * have arrived to fill the store buffer.
-        */
-       while (ud->ud_hbuf == NULL) {
-               if (ud->ud_slen != 0) {
-                       /*
-                        * A packet(s) either arrived since the previous
-                        * read or arrived while we were asleep.
-                        */
-                       if (ud->ud_immediate || non_block || timed_out) {
-                               /*
-                                * Rotate the buffers and return what's here
-                                * if we are in immediate mode, non-blocking
-                                * flag is set, or this descriptor timed out.
-                                */
-                               USBPF_ROTATE_BUFFERS(ud);
-                               break;
-                       }
-               }
-
-               /*
-                * No data is available, check to see if the usbpf device
-                * is still pointed at a real interface.  If not, return
-                * ENXIO so that the userland process knows to rebind
-                * it before using it again.
-                */
-               if (ud->ud_bif == NULL) {
-                       USBPFD_UNLOCK(ud);
-                       return (ENXIO);
-               }
-
-               if (non_block) {
-                       USBPFD_UNLOCK(ud);
-                       return (EWOULDBLOCK);
-               }
-               error = msleep(ud, &ud->ud_mtx, PRIUSB|PCATCH,
-                   "uff", ud->ud_rtout);
-               if (error == EINTR || error == ERESTART) {
-                       USBPFD_UNLOCK(ud);
-                       return (error);
-               }
-               if (error == EWOULDBLOCK) {
-                       /*
-                        * On a timeout, return what's in the buffer,
-                        * which may be nothing.  If there is something
-                        * in the store buffer, we can rotate the buffers.
-                        */
-                       if (ud->ud_hbuf)
-                               /*
-                                * We filled up the buffer in between
-                                * getting the timeout and arriving
-                                * here, so we don't need to rotate.
-                                */
-                               break;
-
-                       if (ud->ud_slen == 0) {
-                               USBPFD_UNLOCK(ud);
-                               return (0);
-                       }
-                       USBPF_ROTATE_BUFFERS(ud);
-                       break;
-               }
-       }
-       /*
-        * At this point, we know we have something in the hold slot.
-        */
-       USBPFD_UNLOCK(ud);
-
-       /*
-        * Move data from hold buffer into user space.
-        * We know the entire buffer is transferred since
-        * we checked above that the read buffer is usbpf_bufsize bytes.
-        *
-        * XXXRW: More synchronization needed here: what if a second thread
-        * issues a read on the same fd at the same time?  Don't want this
-        * getting invalidated.
-        */
-       error = usbpf_uiomove(ud, ud->ud_hbuf, ud->ud_hlen, uio);
-
-       USBPFD_LOCK(ud);
-       ud->ud_fbuf = ud->ud_hbuf;
-       ud->ud_hbuf = NULL;
-       ud->ud_hlen = 0;
-       usbpf_buf_reclaimed(ud);
-       USBPFD_UNLOCK(ud);
-
-       return (error);
-}
-
-static int
-usbpf_write(struct cdev *dev, struct uio *uio, int ioflag)
-{
-
-       /* NOT IMPLEMENTED */
-       return (ENOSYS);
-}
-
-static int
-usbpf_ioctl_sblen(struct usbpf_d *ud, u_int *i)
-{
-
-       if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER)
-               return (EOPNOTSUPP);
-       return (usbpf_buffer_ioctl_sblen(ud, i));
-}
-
-/*
- * Reset a descriptor by flushing its packet buffer and clearing the receive
- * and drop counts.  This is doable for kernel-only buffers, but with
- * zero-copy buffers, we can't write to (or rotate) buffers that are
- * currently owned by userspace.  It would be nice if we could encapsulate
- * this logic in the buffer code rather than here.
- */
-static void
-usbpf_reset_d(struct usbpf_d *ud)
-{

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to