changeset 505:a9b404e9938e

Lazy update
author Aleksandr Rybalko <ray@ddteam.net>
date Wed, 25 Jul 2012 17:09:47 +0300
parents 8f13631d24de
children ee87e0535ac7
files head/sys/dev/usb/controller/ehci.c head/sys/dev/usb/controller/ehci_fsl.c head/sys/dev/usb/controller/ehci_pci.c head/sys/dev/usb/controller/ohci_pci.c head/sys/dev/usb/controller/xhci.c head/sys/dev/usb/controller/xhci_pci.c head/sys/dev/usb/controller/xhcireg.h head/sys/dev/usb/input/uhid.c head/sys/dev/usb/input/ums.c head/sys/dev/usb/net/if_rue.c head/sys/dev/usb/net/if_udav.c head/sys/dev/usb/net/if_udavreg.h head/sys/dev/usb/quirk/usb_quirk.c head/sys/dev/usb/serial/u3g.c head/sys/dev/usb/serial/uftdi.c head/sys/dev/usb/serial/uftdi_reg.h head/sys/dev/usb/usb_controller.h head/sys/dev/usb/usb_device.c head/sys/dev/usb/usb_generic.c head/sys/dev/usb/usb_hid.c head/sys/dev/usb/usb_hub.c head/sys/dev/usb/usb_hub.h head/sys/dev/usb/usb_pf.c head/sys/dev/usb/usb_transfer.c head/sys/dev/usb/usbdevs head/sys/dev/usb/wlan/if_rum.c head/sys/dev/usb/wlan/if_run.c head/sys/dev/usb/wlan/if_ural.c
diffstat 28 files changed, 1168 insertions(+), 387 deletions(-) [+]
line wrap: on
line diff
--- a/head/sys/dev/usb/controller/ehci.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/controller/ehci.c	Wed Jul 25 17:09:47 2012 +0300
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci.c 234961 2012-05-03 16:06:22Z hselasky $");
 
 #include <sys/stdint.h>
 #include <sys/stddef.h>
@@ -2398,9 +2398,9 @@
 	    EHCI_SITD_SET_HUBA(xfer->xroot->udev->hs_hub_addr) |
 	    EHCI_SITD_SET_PORT(xfer->xroot->udev->hs_port_no);
 
-	if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) {
+	if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN)
 		sitd_portaddr |= EHCI_SITD_SET_DIR_IN;
-	}
+
 	sitd_portaddr = htohc32(sc, sitd_portaddr);
 
 	/* initialize all TD's */
@@ -2436,9 +2436,6 @@
 {
 	struct usb_page_search buf_res;
 	ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-	struct usb_fs_isoc_schedule *fss_start;
-	struct usb_fs_isoc_schedule *fss_end;
-	struct usb_fs_isoc_schedule *fss;
 	ehci_sitd_t *td;
 	ehci_sitd_t *td_last = NULL;
 	ehci_sitd_t **pp_last;
@@ -2450,7 +2447,6 @@
 	uint16_t tlen;
 	uint8_t sa;
 	uint8_t sb;
-	uint8_t error;
 
 #ifdef USB_DEBUG
 	uint8_t once = 1;
@@ -2495,9 +2491,8 @@
 	 * pre-compute when the isochronous transfer will be finished:
 	 */
 	xfer->isoc_time_complete =
-	    usbd_fs_isoc_schedule_isoc_time_expand
-	    (xfer->xroot->udev, &fss_start, &fss_end, nframes) + buf_offset +
-	    xfer->nframes;
+	    usb_isoc_time_expand(&sc->sc_bus, nframes) +
+	    buf_offset + xfer->nframes;
 
 	/* get the real number of frames */
 
@@ -2520,19 +2515,14 @@
 
 	xfer->qh_pos = xfer->endpoint->isoc_next;
 
-	fss = fss_start + (xfer->qh_pos % USB_ISOC_TIME_MAX);
-
 	while (nframes--) {
 		if (td == NULL) {
 			panic("%s:%d: out of TD's\n",
 			    __FUNCTION__, __LINE__);
 		}
-		if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
+		if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT])
 			pp_last = &sc->sc_isoc_fs_p_last[0];
-		}
-		if (fss >= fss_end) {
-			fss = fss_start;
-		}
+
 		/* reuse sitd_portaddr and sitd_back from last transfer */
 
 		if (*plen > xfer->max_frame_size) {
@@ -2547,17 +2537,19 @@
 #endif
 			*plen = xfer->max_frame_size;
 		}
-		/*
-		 * We currently don't care if the ISOCHRONOUS schedule is
-		 * full!
-		 */
-		error = usbd_fs_isoc_schedule_alloc(fss, &sa, *plen);
-		if (error) {
+
+		/* allocate a slot */
+
+		sa = usbd_fs_isoc_schedule_alloc_slot(xfer,
+		    xfer->isoc_time_complete - nframes - 1);
+
+		if (sa == 255) {
 			/*
-			 * The FULL speed schedule is FULL! Set length
-			 * to zero.
+			 * Schedule is FULL, set length to zero:
 			 */
+
 			*plen = 0;
+			sa = USB_FS_ISOC_UFRAME_MAX - 1;
 		}
 		if (*plen) {
 			/*
@@ -2637,7 +2629,6 @@
 		pp_last++;
 
 		plen++;
-		fss++;
 		td_last = td;
 		td = td->obj_next;
 	}
@@ -2647,11 +2638,29 @@
 	/* update isoc_next */
 	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) &
 	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
+
+	/*
+	 * We don't allow cancelling of the SPLIT transaction USB FULL
+	 * speed transfer, because it disturbs the bandwidth
+	 * computation algorithm.
+	 */
+	xfer->flags_int.can_cancel_immed = 0;
 }
 
 static void
 ehci_device_isoc_fs_start(struct usb_xfer *xfer)
 {
+	/*
+	 * We don't allow cancelling of the SPLIT transaction USB FULL
+	 * speed transfer, because it disturbs the bandwidth
+	 * computation algorithm.
+	 */
+	xfer->flags_int.can_cancel_immed = 0;
+
+	/* set a default timeout */
+	if (xfer->timeout == 0)
+		xfer->timeout = 500; /* ms */
+
 	/* put transfer on interrupt queue */
 	ehci_transfer_intr_enqueue(xfer);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/usb/controller/ehci_fsl.c	Wed Jul 25 17:09:47 2012 +0300
@@ -0,0 +1,423 @@
+/*-
+ * Copyright (c) 2010-2012 Semihalf
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci_fsl.c 236120 2012-05-26 21:05:11Z raj $");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/queue.h>
+#include <sys/lock.h>
+#include <sys/lockmgr.h>
+#include <sys/condvar.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+#include <machine/bus.h>
+#include <machine/clock.h>
+#include <machine/resource.h>
+
+#include <powerpc/include/tlb.h>
+
+#include "opt_platform.h"
+
+/*
+ * Register the driver
+ */
+/* Forward declarations */
+static int	fsl_ehci_attach(device_t self);
+static int	fsl_ehci_detach(device_t self);
+static int	fsl_ehci_probe(device_t self);
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, fsl_ehci_probe),
+	DEVMETHOD(device_attach, fsl_ehci_attach),
+	DEVMETHOD(device_detach, fsl_ehci_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+	{ 0, 0 }
+};
+
+/* kobj_class definition */
+static driver_t ehci_driver = {
+	"ehci",
+	ehci_methods,
+	sizeof(struct ehci_softc)
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);
+
+/*
+ * Private defines
+ */
+#define FSL_EHCI_REG_OFF	0x100
+#define FSL_EHCI_REG_SIZE	0x300
+
+/*
+ * Internal interface registers' offsets.
+ * Offsets from 0x000 ehci dev space, big-endian access.
+ */
+enum internal_reg {
+	SNOOP1		= 0x400,
+	SNOOP2		= 0x404,
+	AGE_CNT_THRESH	= 0x408,
+	SI_CTRL		= 0x410,
+	CONTROL		= 0x500
+};
+
+/* CONTROL register bit flags */
+enum control_flags {
+	USB_EN		= 0x00000004,
+	UTMI_PHY_EN	= 0x00000200,
+	ULPI_INT_EN	= 0x00000001
+};
+
+/* SI_CTRL register bit flags */
+enum si_ctrl_flags {
+	FETCH_32	= 1,
+	FETCH_64	= 0
+};
+
+#define SNOOP_RANGE_2GB	0x1E
+
+/*
+ * Operational registers' offsets.
+ * Offsets from USBCMD register, little-endian access.
+ */
+enum special_op_reg {
+	USBMODE		= 0x0A8,
+	PORTSC		= 0x084,
+	ULPI_VIEWPORT	= 0x70
+};
+
+/* USBMODE register bit flags */
+enum usbmode_flags {
+	HOST_MODE	= 0x3,
+	DEVICE_MODE	= 0x2
+};
+
+#define	PORT_POWER_MASK	0x00001000
+
+/*
+ * Private methods
+ */
+
+static void
+set_to_host_mode(ehci_softc_t *sc)
+{
+	int tmp;
+
+	tmp = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, USBMODE);
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, USBMODE, tmp | HOST_MODE);
+}
+
+static void
+enable_usb(device_t dev, bus_space_tag_t iot, bus_space_handle_t ioh)
+{
+	int tmp;
+	phandle_t node;
+	char *phy_type;
+
+	phy_type = NULL;
+	tmp = bus_space_read_4(iot, ioh, CONTROL) | USB_EN;
+
+	node = ofw_bus_get_node(dev);
+	if ((node != 0) &&
+	    (OF_getprop_alloc(node, "phy_type", 1, (void **)&phy_type) > 0)) {
+		if (strncasecmp(phy_type, "utmi", strlen("utmi")) == 0)
+			tmp |= UTMI_PHY_EN;
+		free(phy_type, M_OFWPROP);
+	}
+	bus_space_write_4(iot, ioh, CONTROL, tmp);
+}
+
+static void
+set_32b_prefetch(bus_space_tag_t iot, bus_space_handle_t ioh)
+{
+
+	bus_space_write_4(iot, ioh, SI_CTRL, FETCH_32);
+}
+
+static void
+set_snooping(bus_space_tag_t iot, bus_space_handle_t ioh)
+{
+
+	bus_space_write_4(iot, ioh, SNOOP1, SNOOP_RANGE_2GB);
+	bus_space_write_4(iot, ioh, SNOOP2, 0x80000000 | SNOOP_RANGE_2GB);
+}
+
+static void
+clear_port_power(ehci_softc_t *sc)
+{
+	int tmp;
+
+	tmp = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, PORTSC);
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, PORTSC, tmp & ~PORT_POWER_MASK);
+}
+
+/*
+ * Public methods
+ */
+static int
+fsl_ehci_probe(device_t dev)
+{
+
+	if (((ofw_bus_is_compatible(dev, "fsl-usb2-dr")) == 0) &&
+	    ((ofw_bus_is_compatible(dev, "fsl-usb2-mph")) == 0))
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale integrated EHCI controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+fsl_ehci_attach(device_t self)
+{
+	ehci_softc_t *sc;
+	int rid;
+	int err;
+	bus_space_handle_t ioh;
+	bus_space_tag_t iot;
+
+	sc = device_get_softc(self);
+	rid = 0;
+
+	sc->sc_bus.parent = self;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+
+	if (usb_bus_mem_alloc_all(&sc->sc_bus,
+	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc))
+		return (ENOMEM);
+
+	/* Allocate io resource for EHCI */
+	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_io_res == NULL) {
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (ENXIO);
+	}
+	iot = rman_get_bustag(sc->sc_io_res);
+
+	/*
+	 * Set handle to USB related registers subregion used by generic
+	 * EHCI driver
+	 */
+	ioh = rman_get_bushandle(sc->sc_io_res);
+
+	err = bus_space_subregion(iot, ioh, FSL_EHCI_REG_OFF, FSL_EHCI_REG_SIZE,
+	    &sc->sc_io_hdl);
+	if (err != 0) {
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (ENXIO);
+	}
+
+	/* Set little-endian tag for use by the generic EHCI driver */
+	sc->sc_io_tag = &bs_le_tag;
+
+	/* Allocate irq */
+	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (ENXIO);
+	}
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO,
+	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(self, "Could not setup irq, %d\n", err);
+		sc->sc_intr_hdl = NULL;
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (ENXIO);
+	}
+
+	/* Add USB device */
+	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(self, "Could not add USB device\n");
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (ENOMEM);
+	}
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+	sc->sc_id_vendor = 0x1234;
+	strlcpy(sc->sc_vendor, "Freescale", sizeof(sc->sc_vendor));
+
+	/* Enable USB */
+	err = ehci_reset(sc);
+	if (err) {
+		device_printf(self, "Could not reset the controller\n");
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (ENXIO);
+	}
+
+	enable_usb(self, iot, ioh);
+	set_snooping(iot, ioh);
+	set_to_host_mode(sc);
+	set_32b_prefetch(iot, ioh);
+
+	/*
+	 * If usb subsystem is enabled in U-Boot, port power has to be turned
+	 * off to allow proper discovery of devices during boot up.
+	 */
+	clear_port_power(sc);
+
+	/* Set flags */
+	sc->sc_flags |= EHCI_SCFLG_DONTRESET | EHCI_SCFLG_NORESTERM;
+
+	err = ehci_init(sc);
+	if (!err) {
+		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	}
+
+	if (err) {
+		device_printf(self, "USB init failed err=%d\n", err);
+		err = fsl_ehci_detach(self);
+		if (err) {
+			device_printf(self,
+			    "Detach of the driver failed with error %d\n",
+			    err);
+		}
+		return (EIO);
+	}
+
+	return (0);
+}
+
+static int
+fsl_ehci_detach(device_t self)
+{
+
+	int err;
+	ehci_softc_t *sc;
+
+	sc = device_get_softc(self);
+	/*
+	 * only call ehci_detach() after ehci_init()
+	 */
+	if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
+		ehci_detach(sc);
+		sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+	}
+
+	/* Disable interrupts that might have been switched on in ehci_init */
+	if (sc->sc_io_tag && sc->sc_io_hdl)
+		bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, EHCI_USBINTR, 0);
+
+	if (sc->sc_irq_res && sc->sc_intr_hdl) {
+		err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
+		if (err) {
+			device_printf(self, "Could not tear down irq, %d\n",
+			    err);
+			return (err);
+		}
+		sc->sc_intr_hdl = NULL;
+	}
+
+	if (sc->sc_bus.bdev) {
+		device_delete_child(self, sc->sc_bus.bdev);
+		sc->sc_bus.bdev = NULL;
+	}
+
+	/* During module unload there are lots of children leftover */
+	device_delete_children(self);
+
+	if (sc->sc_irq_res) {
+		bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		sc->sc_irq_res = NULL;
+	}
+
+	if (sc->sc_io_res) {
+		bus_release_resource(self, SYS_RES_MEMORY, 0, sc->sc_io_res);
+		sc->sc_io_res = NULL;
+		sc->sc_io_tag = 0;
+		sc->sc_io_hdl = 0;
+	}
+
+	return (0);
+}
+
--- a/head/sys/dev/usb/controller/ehci_pci.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/controller/ehci_pci.c	Wed Jul 25 17:09:47 2012 +0300
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci_pci.c 228483 2011-12-14 00:28:54Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci_pci.c 238015 2012-07-02 19:35:56Z mav $");
 
 /*
  * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
@@ -104,9 +104,6 @@
 	uint32_t device_id = pci_get_devid(self);
 
 	switch (device_id) {
-	case 0x268c8086:
-		return ("Intel 63XXESB USB 2.0 controller");
-
 	case 0x523910b9:
 		return "ALi M5239 USB 2.0 controller";
 
@@ -120,7 +117,13 @@
 		return "ATI SB200 USB 2.0 controller";
 	case 0x43731002:
 		return "ATI SB400 USB 2.0 controller";
+	case 0x43961002:
+		return ("AMD SB7x0/SB8x0/SB9x0 USB 2.0 controller");
 
+	case 0x1e268086:
+		return ("Intel Panther Point USB 2.0 controller");
+	case 0x1e2d8086:
+		return ("Intel Panther Point USB 2.0 controller");
 	case 0x25ad8086:
 		return "Intel 6300ESB USB 2.0 controller";
 	case 0x24cd8086:
@@ -129,9 +132,10 @@
 		return "Intel 82801EB/R (ICH5) USB 2.0 controller";
 	case 0x265c8086:
 		return "Intel 82801FB (ICH6) USB 2.0 controller";
+	case 0x268c8086:
+		return ("Intel 63XXESB USB 2.0 controller");
 	case 0x27cc8086:
 		return "Intel 82801GB/R (ICH7) USB 2.0 controller";
-
 	case 0x28368086:
 		return "Intel 82801H (ICH8) USB 2.0 controller USB2-A";
 	case 0x283a8086:
@@ -243,6 +247,7 @@
 		val = pci_read_config(self, 0x4b, 1);
 		if (val & 0x20)
 			return;
+		val |= 0x20;
 		pci_write_config(self, 0x4b, val, 1);
 		device_printf(self, "VIA-quirk applied\n");
 	}
--- a/head/sys/dev/usb/controller/ohci_pci.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/controller/ohci_pci.c	Wed Jul 25 17:09:47 2012 +0300
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ohci_pci.c 228483 2011-12-14 00:28:54Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ohci_pci.c 238015 2012-07-02 19:35:56Z mav $");
 
 /*
  * USB Open Host Controller driver.
@@ -132,6 +132,10 @@
 		return "ATI SB400 USB Controller";
 	case 0x43751002:
 		return "ATI SB400 USB Controller";
+	case 0x43971002:
+		return ("AMD SB7x0/SB8x0/SB9x0 USB controller");
+	case 0x43991002:
+		return ("AMD SB7x0/SB8x0/SB9x0 USB controller");
 
 	case 0x06701095:
 		return ("CMD Tech 670 (USB0670) USB controller");
--- a/head/sys/dev/usb/controller/xhci.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/controller/xhci.c	Wed Jul 25 17:09:47 2012 +0300
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/controller/xhci.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/xhci.c 234803 2012-04-29 17:12:33Z hselasky $");
 
 #include <sys/stdint.h>
 #include <sys/stddef.h>
@@ -115,6 +115,7 @@
 	uint8_t			tbc;
 	uint8_t			tlbpc;
 	uint8_t			step_td;
+	uint8_t			do_isoc_sync;
 };
 
 static void	xhci_do_poll(struct usb_bus *);
@@ -1657,11 +1658,15 @@
 			td->td_trb[x].dwTrb2 = htole32(dword);
 
 			dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT |
-			  XHCI_TRB_3_TYPE_SET(temp->trb_type) | 
-			  XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8) | 
+			  XHCI_TRB_3_TYPE_SET(temp->trb_type) |
+			  (temp->do_isoc_sync ?
+			   XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8) :
+			   XHCI_TRB_3_ISO_SIA_BIT) |
 			  XHCI_TRB_3_TBC_SET(temp->tbc) |
 			  XHCI_TRB_3_TLBPC_SET(temp->tlbpc);
 
+			temp->do_isoc_sync = 0;
+
 			if (temp->direction == UE_DIR_IN) {
 				dword |= XHCI_TRB_3_DIR_IN;
 
@@ -1764,6 +1769,7 @@
 	uint32_t y;
 	uint8_t mult;
 
+	temp.do_isoc_sync = 0;
 	temp.step_td = 0;
 	temp.tbc = 0;
 	temp.tlbpc = 0;
@@ -1841,6 +1847,8 @@
 			 */
 			xfer->endpoint->isoc_next = XHCI_MFINDEX_GET(x + (3 * 8));
 			xfer->endpoint->is_synced = 1;
+			temp.do_isoc_sync = 1;
+
 			DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
 		}
 
@@ -1931,7 +1939,10 @@
 
 			uint8_t tdpc;
 
-			/* isochronous transfers don't have short packet termination */
+			/*
+			 * Isochronous transfers don't have short
+			 * packet termination:
+			 */
 
 			temp.shortpkt = 1;
 
@@ -2271,12 +2282,29 @@
 	switch (udev->speed) {
 	case USB_SPEED_LOW:
 		temp |= XHCI_SCTX_0_SPEED_SET(2);
+		if (udev->parent_hs_hub != NULL &&
+		    udev->parent_hs_hub->ddesc.bDeviceProtocol ==
+		    UDPROTO_HSHUBMTT) {
+			DPRINTF("Device inherits MTT\n");
+			temp |= XHCI_SCTX_0_MTT_SET(1);
+		}
 		break;
 	case USB_SPEED_HIGH:
 		temp |= XHCI_SCTX_0_SPEED_SET(3);
+		if (sc->sc_hw.devs[index].nports != 0 &&
+		    udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) {
+			DPRINTF("HUB supports MTT\n");
+			temp |= XHCI_SCTX_0_MTT_SET(1);
+		}
 		break;
 	case USB_SPEED_FULL:
 		temp |= XHCI_SCTX_0_SPEED_SET(1);
+		if (udev->parent_hs_hub != NULL &&
+		    udev->parent_hs_hub->ddesc.bDeviceProtocol ==
+		    UDPROTO_HSHUBMTT) {
+			DPRINTF("Device inherits MTT\n");
+			temp |= XHCI_SCTX_0_MTT_SET(1);
+		}
 		break;
 	default:
 		temp |= XHCI_SCTX_0_SPEED_SET(4);
@@ -2287,15 +2315,8 @@
 	    (udev->speed == USB_SPEED_SUPER ||
 	    udev->speed == USB_SPEED_HIGH);
 
-	if (is_hub) {
+	if (is_hub)
 		temp |= XHCI_SCTX_0_HUB_SET(1);
-#if 0
-		if (udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) {
-			DPRINTF("HUB supports MTT\n");
-			temp |= XHCI_SCTX_0_MTT_SET(1);
-		}
-#endif
-	}
 
 	xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx0, temp);
 
@@ -2327,8 +2348,10 @@
 
 	temp = XHCI_SCTX_2_IRQ_TARGET_SET(0);
 
-	if (is_hub)
-		temp |= XHCI_SCTX_2_TT_THINK_TIME_SET(sc->sc_hw.devs[index].tt);
+	if (is_hub) {
+		temp |= XHCI_SCTX_2_TT_THINK_TIME_SET(
+		    sc->sc_hw.devs[index].tt);
+	}
 
 	hubdev = udev->parent_hs_hub;
 
--- a/head/sys/dev/usb/controller/xhci_pci.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/controller/xhci_pci.c	Wed Jul 25 17:09:47 2012 +0300
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/controller/xhci_pci.c 228483 2011-12-14 00:28:54Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/xhci_pci.c 238551 2012-07-17 14:03:04Z mav $");
 
 #include <sys/stdint.h>
 #include <sys/stddef.h>
@@ -93,6 +93,21 @@
 static const char *
 xhci_pci_match(device_t self)
 {
+	uint32_t device_id = pci_get_devid(self);
+
+	switch (device_id) {
+	case 0x01941033:
+		return ("NEC uPD720200 USB 3.0 controller");
+
+	case 0x1e318086:
+		return ("Intel Panther Point USB 3.0 controller");
+	case 0x8c318086:
+		return ("Intel Lynx Point USB 3.0 controller");
+
+	default:
+		break;
+	}
+
 	if ((pci_get_class(self) == PCIC_SERIALBUS)
 	    && (pci_get_subclass(self) == PCIS_SERIALBUS_USB)
 	    && (pci_get_progif(self) == PCIP_SERIALBUS_USB_XHCI)) {
@@ -232,6 +247,7 @@
 xhci_pci_take_controller(device_t self)
 {
 	struct xhci_softc *sc = device_get_softc(self);
+	uint32_t device_id = pci_get_devid(self);
 	uint32_t cparams;
 	uint32_t eecp;
 	uint32_t eec;
@@ -272,5 +288,13 @@
 			usb_pause_mtx(NULL, hz / 100);	/* wait 10ms */
 		}
 	}
+
+	/* On Intel chipsets reroute ports from EHCI to XHCI controller. */
+	if (device_id == 0x1e318086 /* Panther Point */ ||
+	    device_id == 0x8c318086 /* Lynx Point */) {
+		pci_write_config(self, PCI_XHCI_INTEL_USB3_PSSEN, 0xffffffff, 4);
+		pci_write_config(self, PCI_XHCI_INTEL_XUSB2PR, 0xffffffff, 4);
+	}
+
 	return (0);
 }
--- a/head/sys/dev/usb/controller/xhcireg.h	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/controller/xhcireg.h	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/controller/xhcireg.h 228493 2011-12-14 08:44:16Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/controller/xhcireg.h 238551 2012-07-17 14:03:04Z mav $ */
 
 /*-
  * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
@@ -34,6 +34,9 @@
 #define	PCI_USB_REV_3_0		0x30	/* USB 3.0 */
 #define	PCI_XHCI_FLADJ		0x61	/* RW frame length adjust */
 
+#define	PCI_XHCI_INTEL_XUSB2PR	0xD0	/* Intel USB2 Port Routing */
+#define	PCI_XHCI_INTEL_USB3_PSSEN 0xD8	/* Intel USB3 Port SuperSpeed Enable */
+
 /* XHCI capability registers */
 #define	XHCI_CAPLENGTH		0x00	/* RO capability */
 #define	XHCI_RESERVED		0x01	/* Reserved */
--- a/head/sys/dev/usb/input/uhid.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/input/uhid.c	Wed Jul 25 17:09:47 2012 +0300
@@ -5,7 +5,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/input/uhid.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/input/uhid.c 235569 2012-05-17 22:04:17Z mav $");
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -87,6 +87,7 @@
 #define	UHID_FRAME_NUM 	  50		/* bytes, frame number */
 
 enum {
+	UHID_INTR_DT_WR,
 	UHID_INTR_DT_RD,
 	UHID_CTRL_DT_WR,
 	UHID_CTRL_DT_RD,
@@ -128,7 +129,8 @@
 static device_attach_t uhid_attach;
 static device_detach_t uhid_detach;
 
-static usb_callback_t uhid_intr_callback;
+static usb_callback_t uhid_intr_write_callback;
+static usb_callback_t uhid_intr_read_callback;
 static usb_callback_t uhid_write_callback;
 static usb_callback_t uhid_read_callback;
 
@@ -152,7 +154,36 @@
 };
 
 static void
-uhid_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+uhid_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhid_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_page_cache *pc;
+	int actlen;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+	case USB_ST_SETUP:
+tr_setup:
+		pc = usbd_xfer_get_frame(xfer, 0);
+		if (usb_fifo_get_data(sc->sc_fifo.fp[USB_FIFO_TX], pc,
+		    0, usbd_xfer_max_len(xfer), &actlen, 0)) {
+			usbd_xfer_set_frame_len(xfer, 0, actlen);
+			usbd_transfer_submit(xfer);
+		}
+		return;
+
+	default:			/* Error */
+		if (error != USB_ERR_CANCELLED) {
+			/* try to clear stall first */
+			usbd_xfer_set_stall(xfer);
+			goto tr_setup;
+		}
+		return;
+	}
+}
+
+static void
+uhid_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
 {
 	struct uhid_softc *sc = usbd_xfer_softc(xfer);
 	struct usb_page_cache *pc;
@@ -327,13 +358,22 @@
 
 static const struct usb_config uhid_config[UHID_N_TRANSFER] = {
 
+	[UHID_INTR_DT_WR] = {
+		.type = UE_INTERRUPT,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.flags = {.pipe_bof = 1,.no_pipe_ok = 1, },
+		.bufsize = UHID_BSIZE,
+		.callback = &uhid_intr_write_callback,
+	},
+
 	[UHID_INTR_DT_RD] = {
 		.type = UE_INTERRUPT,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
 		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
 		.bufsize = UHID_BSIZE,
-		.callback = &uhid_intr_callback,
+		.callback = &uhid_intr_read_callback,
 	},
 
 	[UHID_CTRL_DT_WR] = {
@@ -381,7 +421,12 @@
 {
 	struct uhid_softc *sc = usb_fifo_softc(fifo);
 
-	usbd_transfer_start(sc->sc_xfer[UHID_CTRL_DT_WR]);
+	if ((sc->sc_flags & UHID_FLAG_IMMED) ||
+	    sc->sc_xfer[UHID_INTR_DT_WR] == NULL) {
+		usbd_transfer_start(sc->sc_xfer[UHID_CTRL_DT_WR]);
+	} else {
+		usbd_transfer_start(sc->sc_xfer[UHID_INTR_DT_WR]);
+	}
 }
 
 static void
@@ -390,6 +435,7 @@
 	struct uhid_softc *sc = usb_fifo_softc(fifo);
 
 	usbd_transfer_stop(sc->sc_xfer[UHID_CTRL_DT_WR]);
+	usbd_transfer_stop(sc->sc_xfer[UHID_INTR_DT_WR]);
 }
 
 static int
--- a/head/sys/dev/usb/input/ums.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/input/ums.c	Wed Jul 25 17:09:47 2012 +0300
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/input/ums.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/input/ums.c 235451 2012-05-14 17:00:32Z hselasky $");
 
 /*
  * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
@@ -134,6 +134,7 @@
 	struct usb_xfer *sc_xfer[UMS_N_TRANSFER];
 
 	int sc_pollrate;
+	int sc_fflags;
 
 	uint8_t	sc_buttons;
 	uint8_t	sc_iid;
@@ -677,32 +678,13 @@
 	DPRINTF("size=%d, id=%d\n", isize, sc->sc_iid);
 #endif
 
-	if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
-		sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
-	else
-		sc->sc_hw.buttons = sc->sc_buttons;
-
-	sc->sc_hw.iftype = MOUSE_IF_USB;
-	sc->sc_hw.type = MOUSE_MOUSE;
-	sc->sc_hw.model = MOUSE_MODEL_GENERIC;
-	sc->sc_hw.hwid = 0;
-
-	sc->sc_mode.protocol = MOUSE_PROTO_MSC;
-	sc->sc_mode.rate = -1;
-	sc->sc_mode.resolution = MOUSE_RES_UNKNOWN;
-	sc->sc_mode.accelfactor = 0;
-	sc->sc_mode.level = 0;
-	sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
-	sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
-	sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
-
 	err = usb_fifo_attach(uaa->device, sc, &sc->sc_mtx,
 	    &ums_fifo_methods, &sc->sc_fifo,
 	    device_get_unit(dev), -1, uaa->info.bIfaceIndex,
   	    UID_ROOT, GID_OPERATOR, 0644);
-	if (err) {
+	if (err)
 		goto detach;
-	}
+
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
 	    OID_AUTO, "parseinfo", CTLTYPE_STRING|CTLFLAG_RD,
@@ -825,7 +807,7 @@
 static void
 ums_reset_buf(struct ums_softc *sc)
 {
-	/* reset read queue */
+	/* reset read queue, must be called locked */
 	usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]);
 }
 
@@ -836,7 +818,33 @@
 
 	DPRINTFN(2, "\n");
 
-	if (fflags & FREAD) {
+	/* check for duplicate open, should not happen */
+	if (sc->sc_fflags & fflags)
+		return (EBUSY);
+
+	/* check for first open */
+	if (sc->sc_fflags == 0) {
+
+		/* reset all USB mouse parameters */
+
+		if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
+			sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
+		else
+			sc->sc_hw.buttons = sc->sc_buttons;
+
+		sc->sc_hw.iftype = MOUSE_IF_USB;
+		sc->sc_hw.type = MOUSE_MOUSE;
+		sc->sc_hw.model = MOUSE_MODEL_GENERIC;
+		sc->sc_hw.hwid = 0;
+
+		sc->sc_mode.protocol = MOUSE_PROTO_MSC;
+		sc->sc_mode.rate = -1;
+		sc->sc_mode.resolution = MOUSE_RES_UNKNOWN;
+		sc->sc_mode.accelfactor = 0;
+		sc->sc_mode.level = 0;
+		sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
+		sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
+		sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
 
 		/* reset status */
 
@@ -847,21 +855,31 @@
 		sc->sc_status.dy = 0;
 		sc->sc_status.dz = 0;
 		/* sc->sc_status.dt = 0; */
+	}
 
+	if (fflags & FREAD) {
+		/* allocate RX buffer */
 		if (usb_fifo_alloc_buffer(fifo,
 		    UMS_BUF_SIZE, UMS_IFQ_MAXLEN)) {
 			return (ENOMEM);
 		}
 	}
+
+	sc->sc_fflags |= fflags & (FREAD | FWRITE);
 	return (0);
 }
 
 static void
 ums_close(struct usb_fifo *fifo, int fflags)
 {
-	if (fflags & FREAD) {
+	struct ums_softc *sc = usb_fifo_softc(fifo);
+
+	DPRINTFN(2, "\n");
+
+	if (fflags & FREAD)
 		usb_fifo_free_buffer(fifo);
-	}
+
+	sc->sc_fflags &= ~(fflags & (FREAD | FWRITE));
 }
 
 static int
@@ -891,7 +909,7 @@
 			/* don't change the current setting */
 		} else if ((mode.level < 0) || (mode.level > 1)) {
 			error = EINVAL;
-			goto done;
+			break;
 		} else {
 			sc->sc_mode.level = mode.level;
 		}
@@ -928,7 +946,7 @@
 	case MOUSE_SETLEVEL:
 		if (*(int *)addr < 0 || *(int *)addr > 1) {
 			error = EINVAL;
-			goto done;
+			break;
 		}
 		sc->sc_mode.level = *(int *)addr;
 
@@ -975,9 +993,9 @@
 		}
 	default:
 		error = ENOTTY;
+		break;
 	}
 
-done:
 	mtx_unlock(&sc->sc_mtx);
 	return (error);
 }
--- a/head/sys/dev/usb/net/if_rue.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/net/if_rue.c	Wed Jul 25 17:09:47 2012 +0300
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_rue.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_rue.c 235255 2012-05-11 02:40:40Z marius $");
 
 /*
  * RealTek RTL8150 USB to fast ethernet controller driver.
@@ -202,8 +202,9 @@
 
 static devclass_t rue_devclass;
 
-DRIVER_MODULE(rue, uhub, rue_driver, rue_devclass, NULL, 0);
-DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, 0, 0);
+DRIVER_MODULE_ORDERED(rue, uhub, rue_driver, rue_devclass, NULL, NULL,
+    SI_ORDER_ANY);
+DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, NULL, NULL);
 MODULE_DEPEND(rue, uether, 1, 1, 1);
 MODULE_DEPEND(rue, usb, 1, 1, 1);
 MODULE_DEPEND(rue, ether, 1, 1, 1);
--- a/head/sys/dev/usb/net/if_udav.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/net/if_udav.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,6 +1,6 @@
 /*	$NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $	*/
 /*	$nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $	*/
-/*	$FreeBSD: head/sys/dev/usb/net/if_udav.c 233774 2012-04-02 10:50:42Z hselasky $	*/
+/*	$FreeBSD: head/sys/dev/usb/net/if_udav.c 238466 2012-07-15 05:49:02Z rpaulo $	*/
 /*-
  * Copyright (c) 2003
  *     Shingo WATANABE <[email protected]>.  All rights reserved.
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_udav.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_udav.c 238466 2012-07-15 05:49:02Z rpaulo $");
 
 #include <sys/stdint.h>
 #include <sys/stddef.h>
@@ -169,7 +169,7 @@
 MODULE_DEPEND(udav, miibus, 1, 1, 1);
 MODULE_VERSION(udav, 1);
 
-static const struct usb_ether_methods udav_ue_methods = {
+static struct usb_ether_methods udav_ue_methods = {
 	.ue_attach_post = udav_attach_post,
 	.ue_start = udav_start,
 	.ue_init = udav_init,
@@ -206,7 +206,8 @@
 	{USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, 0)},
 	/* Kontron AG USB Ethernet */
 	{USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_DM9601, 0)},
-	{USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082, 0)},
+	{USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082,
+	    UDAV_FLAG_NO_PHY)},
 };
 
 static void
@@ -259,6 +260,16 @@
 		goto detach;
 	}
 
+	/*
+	 * The JP1082 has an unusable PHY and provides no link information.
+	 */
+	if (sc->sc_flags & UDAV_FLAG_NO_PHY) {
+		udav_ue_methods.ue_tick = NULL;
+		udav_ue_methods.ue_mii_upd = NULL;
+		udav_ue_methods.ue_mii_sts = NULL;
+		sc->sc_flags |= UDAV_FLAG_LINK;
+	}
+
 	ue->ue_sc = sc;
 	ue->ue_dev = dev;
 	ue->ue_udev = uaa->device;
@@ -712,7 +723,8 @@
 	UDAV_LOCK_ASSERT(sc, MA_OWNED);
 
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-	sc->sc_flags &= ~UDAV_FLAG_LINK;
+	if (!(sc->sc_flags & UDAV_FLAG_NO_PHY))
+		sc->sc_flags &= ~UDAV_FLAG_LINK;
 
 	/*
 	 * stop all the transfers, if not already stopped:
--- a/head/sys/dev/usb/net/if_udavreg.h	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/net/if_udavreg.h	Wed Jul 25 17:09:47 2012 +0300
@@ -1,6 +1,6 @@
 /*	$NetBSD: if_udavreg.h,v 1.2 2003/09/04 15:17:39 tsutsui Exp $	*/
 /*	$nabe: if_udavreg.h,v 1.2 2003/08/21 16:26:40 nabe Exp $	*/
-/*	$FreeBSD$	*/
+/*	$FreeBSD: head/sys/dev/usb/net/if_udavreg.h 238466 2012-07-15 05:49:02Z rpaulo $	*/
 /*-
  * Copyright (c) 2003
  *     Shingo WATANABE <[email protected]>.  All rights reserved.
@@ -159,6 +159,7 @@
 	int			sc_flags;
 #define	UDAV_FLAG_LINK		0x0001
 #define	UDAV_FLAG_EXT_PHY	0x0040
+#define	UDAV_FLAG_NO_PHY	0x0080
 };
 
 #define	UDAV_LOCK(_sc)			mtx_lock(&(_sc)->sc_mtx)
--- a/head/sys/dev/usb/quirk/usb_quirk.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/quirk/usb_quirk.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/quirk/usb_quirk.c 230238 2012-01-16 22:26:25Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/quirk/usb_quirk.c 238718 2012-07-23 15:14:28Z emaste $ */
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
@@ -123,6 +123,7 @@
 	USB_QUIRK(METAGEEK2, WISPYDBX, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE),
 	USB_QUIRK(TENX, UAUDIO0, 0x0101, 0x0101, UQ_AUDIO_SWAP_LR),
 	/* MS keyboards do weird things */
+	USB_QUIRK(MICROSOFT, NATURAL4000, 0x0000, 0xFFFF, UQ_KBD_BOOTPROTO),
 	USB_QUIRK(MICROSOFT, WLINTELLIMOUSE, 0x0000, 0xffff, UQ_MS_LEADING_BYTE),
 	/* umodem(4) device quirks */
 	USB_QUIRK(METRICOM, RICOCHET_GS, 0x100, 0x100, UQ_ASSUME_CM_OVER_DATA),
@@ -442,11 +443,13 @@
 	USB_QUIRK(ANYDATA, ADU_500A, 0x0000, 0xffff,
 	    UQ_QUALCOMM_MSM6800_DTR_RTS),
 	USB_QUIRK(HUAWEI, MOBILE, 0x0000, 0xffff, UQ_QUALCOMM_MSM6800_DTR_RTS),
-	USB_QUIRK(HUAWEI, EC306_INIT, 0x0000, 0xffff, UQ_MSC_EJECT_HUAWEISCSI),
 	USB_QUIRK(CHIPSBANK, USBMEMSTICK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(CHIPSBANK, USBMEMSTICK1, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(NEWLINK, USB2IDEBRIDGE, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 
+	USB_QUIRK(TOSHIBA, TRANSMEMORY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(VIALABS, USB30SATABRIDGE, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+
 	/* Non-standard USB MIDI devices */
 	USB_QUIRK(ROLAND, UM1, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 	USB_QUIRK(ROLAND, SC8850, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
@@ -464,7 +467,13 @@
 	USB_QUIRK(ROLAND, SD20, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 	USB_QUIRK(ROLAND, SD80, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 	USB_QUIRK(ROLAND, UA700, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
+	USB_QUIRK(EGO, M4U, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
+	USB_QUIRK(LOGILINK, U2M, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
 	USB_QUIRK(MEDELI, DD305, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI, UQ_MATCH_VENDOR_ONLY),
+	USB_QUIRK(REDOCTANE, GHMIDI, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
+	USB_QUIRK(TEXTECH, U2M_1, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
+	USB_QUIRK(TEXTECH, U2M_2, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
+	USB_QUIRK(WCH2, U2M, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
 
 	/*
 	 * Quirks for manufacturers which USB devices does not respond
--- a/head/sys/dev/usb/serial/u3g.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/serial/u3g.c	Wed Jul 25 17:09:47 2012 +0300
@@ -16,7 +16,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/usb/serial/u3g.c 232684 2012-03-08 07:22:41Z hselasky $
+ * $FreeBSD: head/sys/dev/usb/serial/u3g.c 238717 2012-07-23 14:22:45Z rea $
  */
 
 /*
@@ -294,15 +294,18 @@
 	U3G_DEV(HUAWEI, E143F, U3GINIT_HUAWEI),
 	U3G_DEV(HUAWEI, E173, 0),
 	U3G_DEV(HUAWEI, E173_INIT, U3GINIT_HUAWEISCSI),
+	U3G_DEV(HUAWEI, E3131, 0),
+	U3G_DEV(HUAWEI, E3131_INIT, U3GINIT_HUAWEISCSI),
 	U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI),
 	U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
 	U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E392, U3GINIT_HUAWEISCSI),
 	U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
 	U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI),
 	U3G_DEV(HUAWEI, E1820, U3GINIT_HUAWEISCSI),
 	U3G_DEV(HUAWEI, K3765, U3GINIT_HUAWEI),
-	U3G_DEV(HUAWEI, EC306_INIT, U3GINIT_HUAWEISCSI),
 	U3G_DEV(HUAWEI, K3765_INIT, U3GINIT_HUAWEISCSI),
+	U3G_DEV(HUAWEI, ETS2055, U3GINIT_HUAWEI),
 	U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
 	U3G_DEV(KYOCERA2, KPC680, 0),
 	U3G_DEV(LONGCHEER, WM66, U3GINIT_HUAWEI),
@@ -368,7 +371,10 @@
 	U3G_DEV(QISDA, H21_2, 0),
 	U3G_DEV(QUALCOMM2, AC8700, 0),
 	U3G_DEV(QUALCOMM2, MF330, 0),
+	U3G_DEV(QUALCOMM2, SIM5218, 0),
 	U3G_DEV(QUALCOMM2, VW110L, U3GINIT_SCSIEJECT),
+	U3G_DEV(QUALCOMM2, GOBI2000_QDL, 0),
+	U3G_DEV(QUALCOMM2, GOBI2000, 0),
 	U3G_DEV(QUALCOMMINC, AC2726, 0),
 	U3G_DEV(QUALCOMMINC, AC8700, 0),
 	U3G_DEV(QUALCOMMINC, AC8710, 0),
--- a/head/sys/dev/usb/serial/uftdi.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/serial/uftdi.c	Wed Jul 25 17:09:47 2012 +0300
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uftdi.c 230242 2012-01-16 23:14:23Z stas $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uftdi.c 237236 2012-06-18 19:18:31Z marius $");
 
 /*
  * NOTE: all function names beginning like "uftdi_cfg_" can only
@@ -38,7 +38,7 @@
  */
 
 /*
- * FTDI FT8U100AX serial adapter driver
+ * FTDI FT2232x, FT8U100AX and FT8U232AM serial adapter driver
  */
 
 #include <sys/stdint.h>
@@ -81,7 +81,7 @@
 #endif
 
 #define	UFTDI_CONFIG_INDEX	0
-#define	UFTDI_IFACE_INDEX	0
+#define	UFTDI_IFACE_INDEX_JTAG	0
 
 #define	UFTDI_OBUFSIZE 64		/* bytes, cannot be increased due to
 					 * do size encoding */
@@ -102,10 +102,10 @@
 	struct mtx sc_mtx;
 
 	uint32_t sc_unit;
-	enum uftdi_type sc_type;
 
 	uint16_t sc_last_lcr;
 
+	uint8_t sc_type;
 	uint8_t	sc_iface_index;
 	uint8_t	sc_hdrlen;
 	uint8_t	sc_msr;
@@ -190,7 +190,7 @@
 	DEVMETHOD(device_attach, uftdi_attach),
 	DEVMETHOD(device_detach, uftdi_detach),
 
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t uftdi_devclass;
@@ -201,59 +201,61 @@
 	.size = sizeof(struct uftdi_softc),
 };
 
-DRIVER_MODULE(uftdi, uhub, uftdi_driver, uftdi_devclass, NULL, 0);
+DRIVER_MODULE(uftdi, uhub, uftdi_driver, uftdi_devclass, NULL, NULL);
 MODULE_DEPEND(uftdi, ucom, 1, 1, 1);
 MODULE_DEPEND(uftdi, usb, 1, 1, 1);
 MODULE_VERSION(uftdi, 1);
 
-static STRUCT_USB_HOST_ID uftdi_devs[] = {
-#define	UFTDI_DEV(v,p,t) \
-  { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, UFTDI_TYPE_##t) }
-	UFTDI_DEV(ATMEL, STK541, 8U232AM),
-	UFTDI_DEV(DRESDENELEKTRONIK, SENSORTERMINALBOARD, 8U232AM),
-	UFTDI_DEV(DRESDENELEKTRONIK, WIRELESSHANDHELDTERMINAL, 8U232AM),
-	UFTDI_DEV(FALCOM, TWIST, 8U232AM),
-	UFTDI_DEV(FTDI, GAMMASCOUT, 8U232AM),
-	UFTDI_DEV(FTDI, SERIAL_8U100AX, SIO),
-	UFTDI_DEV(FTDI, SERIAL_2232C, 8U232AM),
-	UFTDI_DEV(FTDI, SERIAL_2232D, 8U232AM),
-	UFTDI_DEV(FTDI, BEAGLEBONE, 8U232AM),
-	UFTDI_DEV(FTDI, SERIAL_4232H, 8U232AM),
-	UFTDI_DEV(FTDI, SERIAL_8U232AM, 8U232AM),
-	UFTDI_DEV(FTDI, SERIAL_8U232AM4, 8U232AM),
-	UFTDI_DEV(FTDI, SERIAL_BEAGLEBONE, 8U232AM),
-	UFTDI_DEV(FTDI, SEMC_DSS20, 8U232AM),
-	UFTDI_DEV(FTDI, CFA_631, 8U232AM),
-	UFTDI_DEV(FTDI, CFA_632, 8U232AM),
-	UFTDI_DEV(FTDI, CFA_633, 8U232AM),
-	UFTDI_DEV(FTDI, CFA_634, 8U232AM),
-	UFTDI_DEV(FTDI, CFA_635, 8U232AM),
-	UFTDI_DEV(FTDI, USB_UIRT, 8U232AM),
-	UFTDI_DEV(FTDI, USBSERIAL, 8U232AM),
-	UFTDI_DEV(FTDI, KBS, 8U232AM),
-	UFTDI_DEV(FTDI, MX2_3, 8U232AM),
-	UFTDI_DEV(FTDI, MX4_5, 8U232AM),
-	UFTDI_DEV(FTDI, LK202, 8U232AM),
-	UFTDI_DEV(FTDI, LK204, 8U232AM),
-	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13M, 8U232AM),
-	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13S, 8U232AM),
-	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13U, 8U232AM),
-	UFTDI_DEV(FTDI, EISCOU, 8U232AM),
-	UFTDI_DEV(FTDI, UOPTBR, 8U232AM),
-	UFTDI_DEV(FTDI, EMCU2D, 8U232AM),
-	UFTDI_DEV(FTDI, PCMSFU, 8U232AM),
-	UFTDI_DEV(FTDI, EMCU2H, 8U232AM),
-	UFTDI_DEV(FTDI, MAXSTREAM, 8U232AM),
-	UFTDI_DEV(FTDI, CTI_USB_NANO_485, 8U232AM),
-	UFTDI_DEV(FTDI, CTI_USB_MINI_485, 8U232AM),
-	UFTDI_DEV(SIIG2, US2308, 8U232AM),
-	UFTDI_DEV(INTREPIDCS, VALUECAN, 8U232AM),
-	UFTDI_DEV(INTREPIDCS, NEOVI, 8U232AM),
-	UFTDI_DEV(BBELECTRONICS, USOTL4, 8U232AM),
-	UFTDI_DEV(MATRIXORBITAL, MOUA, 8U232AM),
-	UFTDI_DEV(MARVELL, SHEEVAPLUG, 8U232AM),
-	UFTDI_DEV(MELCO, PCOPRS1, 8U232AM),
-	UFTDI_DEV(RATOC, REXUSB60F, 8U232AM),
+static const STRUCT_USB_HOST_ID uftdi_devs[] = {
+#define	UFTDI_DEV(v, p, i) \
+  { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+	UFTDI_DEV(ATMEL, STK541, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(BBELECTRONICS, USOTL4, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(DRESDENELEKTRONIK, SENSORTERMINALBOARD,
+	    UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(DRESDENELEKTRONIK, WIRELESSHANDHELDTERMINAL,
+	    UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FALCOM, TWIST, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, BEAGLEBONE, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CFA_631, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CFA_632, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CFA_633, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CFA_634, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CFA_635, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CTI_USB_MINI_485, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, CTI_USB_NANO_485, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, EISCOU, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, EMCU2D, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, EMCU2H, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, GAMMASCOUT, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, KBS, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, LK202, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, LK204, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, MAXSTREAM, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, MX2_3, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, MX4_5, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, PCMSFU, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, SEMC_DSS20, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_2232C, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_2232D, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_4232H, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_8U100AX, UFTDI_TYPE_SIO),
+	UFTDI_DEV(FTDI, SERIAL_8U232AM, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_8U232AM4, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13M, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13S, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13U, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, TURTELIZER2, UFTDI_TYPE_8U232AM | UFTDI_FLAG_JTAG),
+	UFTDI_DEV(FTDI, UOPTBR, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, USBSERIAL, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(FTDI, USB_UIRT, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(INTREPIDCS, NEOVI, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(INTREPIDCS, VALUECAN, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(MARVELL, SHEEVAPLUG, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(MATRIXORBITAL, MOUA, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(MELCO, PCOPRS1, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(RATOC, REXUSB60F, UFTDI_TYPE_8U232AM),
+	UFTDI_DEV(SIIG2, US2308, UFTDI_TYPE_8U232AM)
 #undef UFTDI_DEV
 };
 
@@ -261,6 +263,7 @@
 uftdi_probe(device_t dev)
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	const struct usb_device_id *id;
 
 	if (uaa->usb_mode != USB_MODE_HOST) {
 		return (ENXIO);
@@ -268,9 +271,24 @@
 	if (uaa->info.bConfigIndex != UFTDI_CONFIG_INDEX) {
 		return (ENXIO);
 	}
-	/* attach to all present interfaces */
 
-	return (usbd_lookup_id_by_uaa(uftdi_devs, sizeof(uftdi_devs), uaa));
+	/*
+	 * Attach to all present interfaces unless this is a JTAG one, which
+	 * we leave for userland.
+	 */
+	id = usbd_lookup_id_by_info(uftdi_devs, sizeof(uftdi_devs),
+	    &uaa->info);
+	if (id == NULL)
+		return (ENXIO);
+	if ((id->driver_info & UFTDI_FLAG_JTAG) != 0 &&
+	    uaa->info.bIfaceIndex == UFTDI_IFACE_INDEX_JTAG) {
+		printf("%s: skipping JTAG interface at %u.%u\n",
+		    device_get_name(dev), usbd_get_bus_index(uaa->device),
+		    usbd_get_device_index(uaa->device));
+		return (ENXIO);
+	}
+	uaa->driver_info = id->driver_info;
+	return (BUS_PROBE_SPECIFIC);
 }
 
 static int
@@ -293,7 +311,7 @@
 	DPRINTF("\n");
 
 	sc->sc_iface_index = uaa->info.bIfaceIndex;
-	sc->sc_type = USB_GET_DRIVER_INFO(uaa);
+	sc->sc_type = USB_GET_DRIVER_INFO(uaa) & UFTDI_TYPE_MASK;
 
 	switch (sc->sc_type) {
 	case UFTDI_TYPE_SIO:
@@ -562,6 +580,7 @@
 uftdi_set_parm_soft(struct termios *t,
     struct uftdi_param_config *cfg, uint8_t type)
 {
+
 	memset(cfg, 0, sizeof(*cfg));
 
 	switch (type) {
@@ -824,5 +843,6 @@
 uftdi_poll(struct ucom_softc *ucom)
 {
 	struct uftdi_softc *sc = ucom->sc_parent;
+
 	usbd_transfer_poll(sc->sc_xfer, UFTDI_N_TRANSFER);
 }
--- a/head/sys/dev/usb/serial/uftdi_reg.h	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/serial/uftdi_reg.h	Wed Jul 25 17:09:47 2012 +0300
@@ -1,5 +1,5 @@
 /*	$NetBSD: uftdireg.h,v 1.6 2002/07/11 21:14:28 augustss Exp $ */
-/*	$FreeBSD$	*/
+/*	$FreeBSD: head/sys/dev/usb/serial/uftdi_reg.h 237236 2012-06-18 19:18:31Z marius $	*/
 
 /*
  * Definitions for the FTDI USB Single Port Serial Converter -
@@ -35,10 +35,12 @@
 #define	FTDI_PIT_SIOB		2	/* SIOB */
 #define	FTDI_PIT_PARALLEL	3	/* Parallel */
 
-enum uftdi_type {
-	UFTDI_TYPE_SIO,
-	UFTDI_TYPE_8U232AM
-};
+/* Values for driver_info */
+#define	UFTDI_TYPE_MASK		0x000000ff
+#define	UFTDI_TYPE_SIO		0x00000001
+#define	UFTDI_TYPE_8U232AM	0x00000002
+#define	UFTDI_FLAG_MASK		0x0000ff00
+#define	UFTDI_FLAG_JTAG		0x00000100
 
 /*
  * BmRequestType:  0100 0000B
@@ -63,14 +65,12 @@
  *    baud and data format not reset
  *
  * The Purge RX and TX buffer commands affect nothing except the buffers
- *
  */
 /* FTDI_SIO_RESET */
 #define	FTDI_SIO_RESET_SIO 0
 #define	FTDI_SIO_RESET_PURGE_RX 1
 #define	FTDI_SIO_RESET_PURGE_TX 2
 
-
 /*
  * BmRequestType:  0100 0000B
  * bRequest:       FTDI_SIO_SET_BAUDRATE
@@ -135,7 +135,6 @@
 #define	FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
 #define	FTDI_SIO_SET_BREAK (0x1 << 14)
 
-
 /*
  * BmRequestType:   0100 0000B
  * bRequest:        FTDI_SIO_MODEM_CTRL
@@ -172,7 +171,6 @@
 #define	FTDI_SIO_SET_RTS_HIGH (2 | ( FTDI_SIO_SET_RTS_MASK << 8))
 #define	FTDI_SIO_SET_RTS_LOW (0 | ( FTDI_SIO_SET_RTS_MASK << 8))
 
-
 /*
  *   BmRequestType:  0100 0000b
  *   bRequest:       FTDI_SIO_SET_FLOW_CTRL
@@ -203,7 +201,6 @@
 #define	FTDI_SIO_DTR_DSR_HS 0x2
 #define	FTDI_SIO_XON_XOFF_HS 0x4
 
-
 /*
  *  BmRequestType:   0100 0000b
  *  bRequest:        FTDI_SIO_SET_EVENT_CHAR
@@ -227,8 +224,6 @@
  * which is what normally happens.
  */
 
-
-
 /*
  *  BmRequestType:  0100 0000b
  *  bRequest:       FTDI_SIO_SET_ERROR_CHAR
@@ -243,14 +238,11 @@
  *           0 = disabled
  *           1 = enabled
  *  B9..15 Reserved
- *
- *
  * FTDI_SIO_SET_ERROR_CHAR
  * Set the parity error replacement character for the specified communications
  * port.
  */
 
-
 /*
  *   BmRequestType:   1100 0000b
  *   bRequest:        FTDI_SIO_GET_MODEM_STATUS
@@ -282,10 +274,7 @@
 #define	FTDI_SIO_RI_MASK  0x40
 #define	FTDI_SIO_RLSD_MASK 0x80
 
-
-
 /*
- *
  * DATA FORMAT
  *
  * IN Endpoint
@@ -317,8 +306,6 @@
  * B5	Transmitter Holding Register (THRE)
  * B6	Transmitter Empty (TEMT)
  * B7	Error in RCVR FIFO
- *
- *
  * OUT Endpoint
  *
  * This device reserves the first bytes of data on this endpoint contain the
@@ -330,7 +317,6 @@
  * Offset	Description
  * B0..1	Port
  * B2..7	Length of message - (not including Byte 0)
- *
  */
 #define	FTDI_PORT_MASK 0x0f
 #define	FTDI_MSR_MASK 0xf0
--- a/head/sys/dev/usb/usb_controller.h	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_controller.h	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_controller.h 228483 2011-12-14 00:28:54Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_controller.h 234803 2012-04-29 17:12:33Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -231,7 +231,8 @@
 uint8_t	usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb);
 void	usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb);
 uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr);
-uint16_t usbd_fs_isoc_schedule_isoc_time_expand(struct usb_device *udev, struct usb_fs_isoc_schedule **pp_start, struct usb_fs_isoc_schedule **pp_end, uint16_t isoc_time);
-uint8_t	usbd_fs_isoc_schedule_alloc(struct usb_fs_isoc_schedule *fss, uint8_t *pstart, uint16_t len);
+#if USB_HAVE_TT_SUPPORT
+uint8_t	usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time);
+#endif
 
 #endif					/* _USB_CONTROLLER_H_ */
--- a/head/sys/dev/usb/usb_device.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_device.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_device.c 233774 2012-04-02 10:50:42Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_device.c 236407 2012-06-01 16:30:54Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -750,10 +750,13 @@
 		if (do_init) {
 			/* setup the USB interface structure */
 			iface->idesc = id;
-			/* default setting */
-			iface->parent_iface_index = USB_IFACE_INDEX_ANY;
 			/* set alternate index */
 			iface->alt_index = alt_index;
+			/* set default interface parent */
+			if (iface_index == USB_IFACE_INDEX_ANY) {
+				iface->parent_iface_index =
+				    USB_IFACE_INDEX_ANY;
+			}
 		}
 
 		DPRINTFN(5, "found idesc nendpt=%d\n", id->bNumEndpoints);
@@ -1229,10 +1232,13 @@
 {
 	struct usb_interface *iface;
 
+	if (udev == NULL) {
+		/* nothing to do */
+		return;
+	}
 	iface = usbd_get_iface(udev, iface_index);
-	if (iface) {
+	if (iface != NULL)
 		iface->parent_iface_index = parent_index;
-	}
 }
 
 static void
--- a/head/sys/dev/usb/usb_generic.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_generic.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_generic.c 227461 2011-11-12 08:16:45Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_generic.c 236407 2012-06-01 16:30:54Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -2166,7 +2166,16 @@
 			break;
 		}
 
+		/*
+		 * Detach the currently attached driver.
+		 */
 		usb_detach_device(f->udev, n, 0);
+
+		/*
+		 * Set parent to self, this should keep attach away
+		 * until the next set configuration event.
+		 */
+		usbd_set_parent_iface(f->udev, n, n);
 		break;
 
 	case USB_SET_POWER_MODE:
--- a/head/sys/dev/usb/usb_hid.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_hid.c	Wed Jul 25 17:09:47 2012 +0300
@@ -2,7 +2,7 @@
 
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/usb_hid.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/usb_hid.c 235510 2012-05-16 17:51:56Z mav $");
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -425,7 +425,7 @@
 				s->loc_size = dval & mask;
 				break;
 			case 8:
-				hid_switch_rid(s, c, dval);
+				hid_switch_rid(s, c, dval & mask);
 				break;
 			case 9:
 				/* mask because value is unsigned */
--- a/head/sys/dev/usb/usb_hub.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_hub.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_hub.c 233774 2012-04-02 10:50:42Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_hub.c 234803 2012-04-29 17:12:33Z hselasky $ */
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
@@ -109,6 +109,7 @@
 #define	UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
 #define	UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
 #define	UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
+#define	UHUB_IS_MULTI_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBMTT)
 #define	UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB)
 
 /* prototypes for type checking: */
@@ -948,6 +949,16 @@
 		    "bus powered HUB. HUB ignored\n");
 		goto error;
 	}
+
+	if (UHUB_IS_MULTI_TT(sc)) {
+		err = usbd_set_alt_interface_index(udev, 0, 1);
+		if (err) {
+			device_printf(dev, "MTT could not be enabled\n");
+			goto error;
+		}
+		device_printf(dev, "MTT enabled\n");
+	}
+
 	/* get HUB descriptor */
 
 	DPRINTFN(2, "Getting HUB descriptor\n");
@@ -1057,10 +1068,6 @@
 	}
 	udev->hub = hub;
 
-#if USB_HAVE_TT_SUPPORT
-	/* init FULL-speed ISOCHRONOUS schedule */
-	usbd_fs_isoc_schedule_init_all(hub->fs_isoc_schedule);
-#endif
 	/* initialize HUB structure */
 	hub->hubsoftc = sc;
 	hub->explore = &uhub_explore;
@@ -1656,42 +1663,6 @@
 }
 
 /*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_init_sub
- *
- * This function initialises an USB FULL speed isochronous schedule
- * entry.
- *------------------------------------------------------------------------*/
-#if USB_HAVE_TT_SUPPORT
-static void
-usbd_fs_isoc_schedule_init_sub(struct usb_fs_isoc_schedule *fss)
-{
-	fss->total_bytes = (USB_FS_ISOC_UFRAME_MAX *
-	    USB_FS_BYTES_PER_HS_UFRAME);
-	fss->frame_bytes = (USB_FS_BYTES_PER_HS_UFRAME);
-	fss->frame_slot = 0;
-}
-#endif
-
-/*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_init_all
- *
- * This function will reset the complete USB FULL speed isochronous
- * bandwidth schedule.
- *------------------------------------------------------------------------*/
-#if USB_HAVE_TT_SUPPORT
-void
-usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss)
-{
-	struct usb_fs_isoc_schedule *fss_end = fss + USB_ISOC_TIME_MAX;
-
-	while (fss != fss_end) {
-		usbd_fs_isoc_schedule_init_sub(fss);
-		fss++;
-	}
-}
-#endif
-
-/*------------------------------------------------------------------------*
  *	usb_isoc_time_expand
  *
  * This function will expand the time counter from 7-bit to 16-bit.
@@ -1723,114 +1694,130 @@
 }
 
 /*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_isoc_time_expand
+ *	usbd_fs_isoc_schedule_alloc_slot
  *
- * This function does multiple things. First of all it will expand the
- * passed isochronous time, which is the return value. Then it will
- * store where the current FULL speed isochronous schedule is
- * positioned in time and where the end is. See "pp_start" and
- * "pp_end" arguments.
+ * This function will allocate bandwidth for an isochronous FULL speed
+ * transaction in the FULL speed schedule.
  *
  * Returns:
- *   Expanded version of "isoc_time".
- *
- * NOTE: This function depends on being called regularly with
- * intervals less than "USB_ISOC_TIME_MAX".
- *------------------------------------------------------------------------*/
-#if USB_HAVE_TT_SUPPORT
-uint16_t
-usbd_fs_isoc_schedule_isoc_time_expand(struct usb_device *udev,
-    struct usb_fs_isoc_schedule **pp_start,
-    struct usb_fs_isoc_schedule **pp_end,
-    uint16_t isoc_time)
-{
-	struct usb_fs_isoc_schedule *fss_end;
-	struct usb_fs_isoc_schedule *fss_a;
-	struct usb_fs_isoc_schedule *fss_b;
-	struct usb_hub *hs_hub;
-
-	isoc_time = usb_isoc_time_expand(udev->bus, isoc_time);
-
-	hs_hub = udev->parent_hs_hub->hub;
-
-	if (hs_hub != NULL) {
-
-		fss_a = hs_hub->fs_isoc_schedule +
-		    (hs_hub->isoc_last_time % USB_ISOC_TIME_MAX);
-
-		hs_hub->isoc_last_time = isoc_time;
-
-		fss_b = hs_hub->fs_isoc_schedule +
-		    (isoc_time % USB_ISOC_TIME_MAX);
-
-		fss_end = hs_hub->fs_isoc_schedule + USB_ISOC_TIME_MAX;
-
-		*pp_start = hs_hub->fs_isoc_schedule;
-		*pp_end = fss_end;
-
-		while (fss_a != fss_b) {
-			if (fss_a == fss_end) {
-				fss_a = hs_hub->fs_isoc_schedule;
-				continue;
-			}
-			usbd_fs_isoc_schedule_init_sub(fss_a);
-			fss_a++;
-		}
-
-	} else {
-
-		*pp_start = NULL;
-		*pp_end = NULL;
-	}
-	return (isoc_time);
-}
-#endif
-
-/*------------------------------------------------------------------------*
- *	usbd_fs_isoc_schedule_alloc
- *
- * This function will allocate bandwidth for an isochronous FULL speed
- * transaction in the FULL speed schedule. The microframe slot where
- * the transaction should be started is stored in the byte pointed to
- * by "pstart". The "len" argument specifies the length of the
- * transaction in bytes.
- *
- * Returns:
- *    0: Success
+ *    <8: Success
  * Else: Error
  *------------------------------------------------------------------------*/
 #if USB_HAVE_TT_SUPPORT
 uint8_t
-usbd_fs_isoc_schedule_alloc(struct usb_fs_isoc_schedule *fss,
-    uint8_t *pstart, uint16_t len)
+usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time)
 {
-	uint8_t slot = fss->frame_slot;
+	struct usb_xfer *xfer;
+	struct usb_xfer *pipe_xfer;
+	struct usb_bus *bus;
+	usb_frlength_t len;
+	usb_frlength_t data_len;
+	uint16_t delta;
+	uint16_t slot;
+	uint8_t retval;
 
-	/* Compute overhead and bit-stuffing */
+	data_len = 0;
+	slot = 0;
+
+	bus = isoc_xfer->xroot->bus;
+
+	TAILQ_FOREACH(xfer, &bus->intr_q.head, wait_entry) {
 
-	len += 8;
+		/* skip self, if any */
 
-	len *= 7;
-	len /= 6;
+		if (xfer == isoc_xfer)
+			continue;
+
+		/* check if this USB transfer is going through the same TT */
 
-	if (len > fss->total_bytes) {
-		*pstart = 0;		/* set some dummy value */
-		return (1);		/* error */
-	}
-	if (len > 0) {
+		if (xfer->xroot->udev->parent_hs_hub !=
+		    isoc_xfer->xroot->udev->parent_hs_hub) {
+			continue;
+		}
+		if ((isoc_xfer->xroot->udev->parent_hs_hub->
+		    ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) &&
+		    (xfer->xroot->udev->hs_port_no !=
+		    isoc_xfer->xroot->udev->hs_port_no)) {
+			continue;
+		}
+		if (xfer->endpoint->methods != isoc_xfer->endpoint->methods)
+			continue;
 
-		fss->total_bytes -= len;
+		/* check if isoc_time is part of this transfer */
+
+		delta = xfer->isoc_time_complete - isoc_time;
+		if (delta > 0 && delta <= xfer->nframes) {
+			delta = xfer->nframes - delta;
 
-		while (len >= fss->frame_bytes) {
-			len -= fss->frame_bytes;
-			fss->frame_bytes = USB_FS_BYTES_PER_HS_UFRAME;
-			fss->frame_slot++;
+			len = xfer->frlengths[delta];
+			len += 8;
+			len *= 7;
+			len /= 6;
+
+			data_len += len;
 		}
 
-		fss->frame_bytes -= len;
+		/* check double buffered transfers */
+
+		TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q.head,
+		    wait_entry) {
+
+			/* skip self, if any */
+
+			if (pipe_xfer == isoc_xfer)
+				continue;
+
+			/* check if isoc_time is part of this transfer */
+
+			delta = pipe_xfer->isoc_time_complete - isoc_time;
+			if (delta > 0 && delta <= pipe_xfer->nframes) {
+				delta = pipe_xfer->nframes - delta;
+
+				len = pipe_xfer->frlengths[delta];
+				len += 8;
+				len *= 7;
+				len /= 6;
+
+				data_len += len;
+			}
+		}
+	}
+
+	while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
+		data_len -= USB_FS_BYTES_PER_HS_UFRAME;
+		slot++;
 	}
-	*pstart = slot;
-	return (0);			/* success */
+
+	/* check for overflow */
+
+	if (slot >= USB_FS_ISOC_UFRAME_MAX)
+		return (255);
+
+	retval = slot;
+
+	delta = isoc_xfer->isoc_time_complete - isoc_time;
+	if (delta > 0 && delta <= isoc_xfer->nframes) {
+		delta = isoc_xfer->nframes - delta;
+
+		len = isoc_xfer->frlengths[delta];
+		len += 8;
+		len *= 7;
+		len /= 6;
+
+		data_len += len;
+	}
+
+	while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
+		data_len -= USB_FS_BYTES_PER_HS_UFRAME;
+		slot++;
+	}
+
+	/* check for overflow */
+
+	if (slot >= USB_FS_ISOC_UFRAME_MAX)
+		return (255);
+
+	return (retval);
 }
 #endif
 
--- a/head/sys/dev/usb/usb_hub.h	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_hub.h	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD$ */
+/* $FreeBSD: head/sys/dev/usb/usb_hub.h 234803 2012-04-29 17:12:33Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -38,22 +38,9 @@
 };
 
 /*
- * The following structure defines how many bytes are
- * left in an 1ms USB time slot.
- */
-struct usb_fs_isoc_schedule {
-	uint16_t total_bytes;
-	uint8_t	frame_bytes;
-	uint8_t	frame_slot;
-};
-
-/*
  * The following structure defines an USB HUB.
  */
 struct usb_hub {
-#if USB_HAVE_TT_SUPPORT
-	struct usb_fs_isoc_schedule fs_isoc_schedule[USB_ISOC_TIME_MAX];
-#endif
 	struct usb_device *hubudev;	/* the HUB device */
 	usb_error_t (*explore) (struct usb_device *hub);
 	void   *hubsoftc;
@@ -68,7 +55,6 @@
 
 void	usb_hs_bandwidth_alloc(struct usb_xfer *xfer);
 void	usb_hs_bandwidth_free(struct usb_xfer *xfer);
-void	usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss);
 void	usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up,
 	    struct usb_device *udev, uint8_t device_index);
 struct usb_device *usb_bus_port_get_device(struct usb_bus *bus,
--- a/head/sys/dev/usb/usb_pf.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_pf.c	Wed Jul 25 17:09:47 2012 +0300
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/usb_pf.c 220301 2011-04-03 20:03:45Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/usb_pf.c 238361 2012-07-11 02:57:32Z hrs $");
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/bus.h>
@@ -44,8 +44,10 @@
 #include <sys/sockio.h>
 #include <net/if.h>
 #include <net/if_types.h>
+#include <net/if_clone.h>
 #include <net/bpf.h>
 #include <sys/sysctl.h>
+#include <net/route.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -58,35 +60,146 @@
 #include <dev/usb/usb_pf.h>
 #include <dev/usb/usb_transfer.h>
 
-static int usb_no_pf;
+#define	USBUSNAME	"usbus"
+
+static void usbpf_init(void);
+static void usbpf_uninit(void);
+static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
+static int usbpf_clone_match(struct if_clone *, const char *);
+static int usbpf_clone_create(struct if_clone *, char *, size_t, caddr_t);
+static int usbpf_clone_destroy(struct if_clone *, struct ifnet *);
+static struct usb_bus *usbpf_ifname2ubus(const char *);
+static uint32_t usbpf_aggregate_xferflags(struct usb_xfer_flags *);
+static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *);
+static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t);
+static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int);
+
+static struct if_clone usbpf_cloner = IFC_CLONE_INITIALIZER(
+    USBUSNAME, NULL, IF_MAXUNIT,
+    NULL, usbpf_clone_match, usbpf_clone_create, usbpf_clone_destroy);
+
+SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL);
+SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
+
+static void
+usbpf_init(void)
+{
+
+	if_clone_attach(&usbpf_cloner);
+}
 
-SYSCTL_INT(_hw_usb, OID_AUTO, no_pf, CTLFLAG_RW,
-    &usb_no_pf, 0, "Set to disable USB packet filtering");
+static void
+usbpf_uninit(void)
+{
+	int devlcnt;
+	device_t *devlp;
+	devclass_t dc;
+	struct usb_bus *ubus;
+	int error;
+	int i;
+	
+	if_clone_detach(&usbpf_cloner);
 
-TUNABLE_INT("hw.usb.no_pf", &usb_no_pf);
+	dc = devclass_find(USBUSNAME);
+	if (dc == NULL)
+		return;
+	error = devclass_get_devices(dc, &devlp, &devlcnt);
+	if (error)
+		return;
+	for (i = 0; i < devlcnt; i++) {
+		ubus = device_get_softc(devlp[i]);
+		if (ubus != NULL && ubus->ifp != NULL)
+			usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
+	}
+}
+
+static int
+usbpf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	
+	/* No configuration allowed. */
+	return (EINVAL);
+}
 
-void
-usbpf_attach(struct usb_bus *ubus)
+static struct usb_bus *
+usbpf_ifname2ubus(const char *ifname)
 {
-	struct ifnet *ifp;
+	device_t dev;
+	devclass_t dc;
+	int unit;
+	int error;
+
+	if (strncmp(ifname, USBUSNAME, sizeof(USBUSNAME) - 1) != 0)
+		return (NULL);
+	error = ifc_name2unit(ifname, &unit);
+	if (error || unit < 0)
+		return (NULL);
+	dc = devclass_find(USBUSNAME);
+	if (dc == NULL)
+		return (NULL);
+	dev = devclass_get_device(dc, unit);
+	if (dev == NULL)
+		return (NULL);
+
+	return (device_get_softc(dev));
+}
+
+static int
+usbpf_clone_match(struct if_clone *ifc, const char *name)
+{
+	struct usb_bus *ubus;
 
-	if (usb_no_pf != 0) {
-		ubus->ifp = NULL;
-		return;
+	ubus = usbpf_ifname2ubus(name);
+	if (ubus == NULL)
+		return (0);
+	if (ubus->ifp != NULL)
+		return (0);
+
+	return (1);
+}
+
+static int
+usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+{
+	int error;
+	int unit;
+	struct ifnet *ifp;
+	struct usb_bus *ubus;
+
+	error = ifc_name2unit(name, &unit);
+	if (error)
+		return (error);
+ 	if (unit < 0)
+		return (EINVAL);
+
+	ubus = usbpf_ifname2ubus(name);
+	if (ubus == NULL)
+		return (1);
+	if (ubus->ifp != NULL)
+		return (1);
+
+	error = ifc_alloc_unit(ifc, &unit);
+	if (error) {
+		ifc_free_unit(ifc, unit);
+		device_printf(ubus->parent, "usbpf: Could not allocate "
+		    "instance\n");
+		return (error);
 	}
-
 	ifp = ubus->ifp = if_alloc(IFT_USB);
 	if (ifp == NULL) {
+		ifc_free_unit(ifc, unit);
 		device_printf(ubus->parent, "usbpf: Could not allocate "
 		    "instance\n");
-		return;
+		return (ENOSPC);
 	}
-
-	if_initname(ifp, "usbus", device_get_unit(ubus->bdev));
-	ifp->if_flags = IFF_CANTCONFIG;
+	strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
+	ifp->if_softc = ubus;
+	ifp->if_dname = ifc->ifc_name;
+	ifp->if_dunit = unit;
+	ifp->if_ioctl = usbpf_ioctl;
 	if_attach(ifp);
-	if_up(ifp);
-
+	ifp->if_flags |= IFF_UP;
+	rt_ifmsg(ifp);
 	/*
 	 * XXX According to the specification of DLT_USB, it indicates
 	 * packets beginning with USB setup header. But not sure all
@@ -94,6 +207,31 @@
 	 */
 	bpfattach(ifp, DLT_USB, USBPF_HDR_LEN);
 
+	return (0);
+}
+
+static int
+usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+{
+	struct usb_bus *ubus;
+	int unit;
+
+	ubus = ifp->if_softc;
+	unit = ifp->if_dunit;
+
+	ubus->ifp = NULL;
+	bpfdetach(ifp);
+	if_detach(ifp);
+	if_free(ifp);
+	ifc_free_unit(ifc, unit);
+	
+	return (0);
+}
+
+void
+usbpf_attach(struct usb_bus *ubus)
+{
+
 	if (bootverbose)
 		device_printf(ubus->parent, "usbpf: Attached\n");
 }
@@ -101,15 +239,11 @@
 void
 usbpf_detach(struct usb_bus *ubus)
 {
-	struct ifnet *ifp = ubus->ifp;
 
-	if (ifp != NULL) {
-		bpfdetach(ifp);
-		if_down(ifp);
-		if_detach(ifp);
-		if_free(ifp);
-	}
-	ubus->ifp = NULL;
+	if (ubus->ifp != NULL)
+		usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
+	if (bootverbose)
+		device_printf(ubus->parent, "usbpf: Detached\n");
 }
 
 static uint32_t
@@ -259,8 +393,6 @@
 	bus = xfer->xroot->bus;
 
 	/* sanity checks */
-	if (usb_no_pf != 0)
-		return;
 	if (bus->ifp == NULL)
 		return;
 	if (!bpf_peers_present(bus->ifp->if_bpf))
--- a/head/sys/dev/usb/usb_transfer.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usb_transfer.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_transfer.c 233774 2012-04-02 10:50:42Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_transfer.c 236070 2012-05-26 08:33:53Z marius $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -217,12 +217,12 @@
 	 * Try multi-allocation chunks to reduce the number of DMA
 	 * allocations, hence DMA allocations are slow.
 	 */
-	if (size >= PAGE_SIZE) {
+	if (size >= USB_PAGE_SIZE) {
 		n_dma_pc = count;
 		n_obj = 1;
 	} else {
 		/* compute number of objects per page */
-		n_obj = (PAGE_SIZE / size);
+		n_obj = (USB_PAGE_SIZE / size);
 		/*
 		 * Compute number of DMA chunks, rounded up
 		 * to nearest one:
@@ -1681,11 +1681,12 @@
 
 	DPRINTF("enter\n");
 
+	/* the transfer can now be cancelled */
+	xfer->flags_int.can_cancel_immed = 1;
+
 	/* enter the transfer */
 	(ep->methods->enter) (xfer);
 
-	xfer->flags_int.can_cancel_immed = 1;
-
 	/* check for transfer error */
 	if (xfer->error) {
 		/* some error has happened */
@@ -2418,13 +2419,15 @@
 #if USB_HAVE_PF
 	usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT);
 #endif
+
+	/* the transfer can now be cancelled */
+	xfer->flags_int.can_cancel_immed = 1;
+
 	/* start USB transfer, if no error */
 	if (xfer->error == 0)
 		(ep->methods->start) (xfer);
 
-	xfer->flags_int.can_cancel_immed = 1;
-
-	/* check for error */
+	/* check for transfer error */
 	if (xfer->error) {
 		/* some error has happened */
 		usbd_transfer_done(xfer, 0);
@@ -2599,13 +2602,14 @@
 #if USB_HAVE_PF
 	usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT);
 #endif
+	/* the transfer can now be cancelled */
+	xfer->flags_int.can_cancel_immed = 1;
+
 	/* start USB transfer, if no error */
 	if (xfer->error == 0)
 		(ep->methods->start) (xfer);
 
-	xfer->flags_int.can_cancel_immed = 1;
-
-	/* check for error */
+	/* check for transfer error */
 	if (xfer->error) {
 		/* some error has happened */
 		usbd_transfer_done(xfer, 0);
--- a/head/sys/dev/usb/usbdevs	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/usbdevs	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-$FreeBSD: head/sys/dev/usb/usbdevs 232684 2012-03-08 07:22:41Z hselasky $
+$FreeBSD: head/sys/dev/usb/usbdevs 238717 2012-07-23 14:22:45Z rea $
 /* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
 
 /*-
@@ -487,6 +487,7 @@
 vendor GREENHOUSE	0x0a6b	GREENHOUSE
 vendor MEDELI		0x0a67	Medeli
 vendor GEOCAST		0x0a79	Geocast Network Systems
+vendor EGO		0x0a92	EGO systems
 vendor IDQUANTIQUE	0x0aba	id Quantique
 vendor ZYDAS		0x0ace	Zydas Technology Corporation
 vendor NEODIO		0x0aec	Neodio
@@ -559,6 +560,7 @@
 vendor MOTOROLA4	0x100d	Motorola
 vendor AIRPLUS		0x1011  Airplus
 vendor DESKNOTE		0x1019	Desknote
+vendor NEC3		0x1033	NEC
 vendor GIGABYTE		0x1044	GIGABYTE
 vendor WESTERN		0x1058	Western Digital
 vendor MOTOROLA		0x1063	Motorola
@@ -611,6 +613,7 @@
 vendor EMTEC		0x13fe	Emtec
 vendor NOVATEL		0x1410	Novatel Wireless
 vendor MERLIN		0x1416	Merlin
+vendor REDOCTANE	0x1430	RedOctane
 vendor WISTRONNEWEB	0x1435	Wistron NeWeb
 vendor RADIOSHACK	0x1453	Radio Shack
 vendor HUAWEI3COM	0x1472	Huawei-3Com
@@ -633,6 +636,7 @@
 vendor SPARKLAN		0x15a9	SparkLAN
 vendor SOUNDGRAPH 	0x15c2	Soundgraph, Inc.
 vendor AMIT2		0x15c5	AMIT
+vendor TEXTECH		0x15ca	Textech International Ltd.
 vendor SOHOWARE		0x15e8	SOHOware
 vendor UMAX		0x1606	UMAX Data Systems
 vendor INSIDEOUT	0x1608	Inside Out Networks
@@ -687,6 +691,7 @@
 vendor ENCORE		0x203d	Encore
 vendor PARA		0x20b8	PARA Industrial
 vendor SIMTEC		0x20df	Simtec Electronics
+vendor VIALABS		0x2109	VIA Labs
 vendor ERICSSON		0x2282	Ericsson
 vendor MOTOROLA2	0x22b8	Motorola
 vendor TRIPPLITE	0x2478	Tripp-Lite
@@ -723,6 +728,7 @@
 vendor 3COM3		0xa727	3Com
 vendor DATAAPEX		0xdaae	DataApex
 vendor HP2		0xf003	Hewlett Packard
+vendor LOGILINK		0xfc08	LogiLink
 vendor USRP		0xfffe	GNU Radio USRP
 
 /*
@@ -1473,6 +1479,10 @@
 product EGALAX TPANEL2		0x0002	Touch Panel
 product EGALAX2 TPANEL		0x0001	Touch Panel
 
+/* EGO Products */
+product EGO DUMMY		0x0000	Dummy Product
+product EGO M4U			0x1020	ESI M4U
+
 /* Eicon Networks */
 product EICON DIVA852		0x4905	Diva 852 ISDN TA
 
@@ -1605,9 +1615,9 @@
 product FTDI SERIAL_8U232AM4	0x6004	8U232AM Serial
 product FTDI SERIAL_2232C	0x6010	FT2232C Dual port Serial
 product FTDI SERIAL_2232D	0x9e90	FT2232D Dual port Serial
-product FTDI BEAGLEBONE		0xA6D0  BeagleBone
 product FTDI SERIAL_4232H	0x6011	FT4232H Quad port Serial
-product FTDI SERIAL_BEAGLEBONE	0xa6d0	BeagleBone FTDI Serial
+product FTDI BEAGLEBONE		0xa6d0	BeagleBone
+product FTDI TURTELIZER2	0xbdc8	egnite Turtelizer 2 JTAG/RS232 Adapter
 /* Gude Analog- und Digitalsysteme products also uses FTDI's id: */
 product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi
 product FTDI TACTRIX_OPENPORT_13S 0xcc49 OpenPort 1.3 Subaru
@@ -1885,8 +1895,11 @@
 product HUAWEI E1752		0x1446	3G modem
 product HUAWEI K3765		0x1465	3G modem
 product HUAWEI E1820		0x14ac	E1820 HSPA+ USB Slider
-product HUAWEI EC306_INIT	0x1505	EC306 Initial
+product HUAWEI E3131_INIT	0x14fe	3G modem initial
+product HUAWEI E392		0x1505	LTE modem
+product HUAWEI E3131		0x1506	3G modem
 product HUAWEI K3765_INIT	0x1520	K3765 Initial
+product HUAWEI ETS2055		0x1803	CDMA modem
 product HUAWEI E173		0x1c05	3G modem
 product HUAWEI E173_INIT	0x1c0b	3G modem initial
 
@@ -1918,6 +1931,7 @@
 product INTEL EASYPC_CAMERA	0x0110	Easy PC Camera
 product INTEL TESTBOARD		0x9890	82930 test board
 product INTEL2 IRMH        	0x0020	Integrated Rate Matching Hub
+product INTEL2 IRMH2        	0x0024	Integrated Rate Matching Hub
 
 /* Intersil products */
 product INTERSIL PRISM_GT	0x1000	PrismGT USB 2.0 WLAN
@@ -2092,6 +2106,10 @@
 product LINKSYS4 RT3070		0x0078	RT3070
 product LINKSYS4 WUSB600NV2	0x0079	WUSB600N v2
 
+/* Logilink products */
+product LOGILINK DUMMY		0x0000	Dummy product
+product LOGILINK U2M		0x0101	LogiLink USB MIDI Cable
+
 /* Logitech products */
 product LOGITECH M2452		0x0203	M2452 keyboard
 product LOGITECH M4848		0x0301	M4848 mouse
@@ -2126,6 +2144,7 @@
 product LOGITEC RT2870_2	0x0163	RT2870
 product LOGITEC RT2870_3	0x0164	RT2870
 product LOGITEC LANW300NU2	0x0166  LAN-W300N/U2
+product LOGITEC LANW150NU2	0x0168  LAN-W150N/U2
 
 /* Longcheer Holdings, Ltd. products */
 product LONGCHEER WM66		0x6061	Longcheer WM66 HSDPA
@@ -2191,7 +2210,8 @@
 product MELCO RT2870_2		0x0150	RT2870
 product MELCO WLIUCGN		0x015d	WLI-UC-GN
 product MELCO WLIUCG301N	0x016f	WLI-UC-G301N
-product MELCO WLIUCGNM		0x01a2  WLI-UC-GNM
+product MELCO WLIUCGNM		0x01a2	WLI-UC-GNM
+product MELCO WLIUCGNM2		0x01ee	WLI-UC-GNM2
 
 /* Merlin products */
 product MERLIN V620             0x1110  Merlin V620
@@ -2605,6 +2625,7 @@
 product PLANEX2 GWUSMM		0xed02	GW-USMM
 product PLANEX2 RT2870		0xed06	RT2870
 product PLANEX2 GWUSMICRON	0xed14	GW-USMicroN
+product PLANEX2 GWUSVALUEEZ	0xed17	GW-USValue-EZ
 product PLANEX3 GWUS54GZ	0xab10	GW-US54GZ
 product PLANEX3 GU1000T		0xab11	GU-1000T
 product PLANEX3 GWUS54MINI	0xab13	GW-US54Mini
@@ -2686,6 +2707,9 @@
 product QUALCOMM2 CDMA_MSM	0x3196	CDMA Technologies MSM modem
 product QUALCOMM2 AC8700	0x6000	AC8700
 product QUALCOMM2 VW110L	0x1000	Vertex Wireless 110L modem
+product QUALCOMM2 SIM5218	0x9000	SIM5218
+product QUALCOMM2 GOBI2000_QDL	0x9204	Qualcomm Gobi 2000 QDL
+product QUALCOMM2 GOBI2000	0x9205	Qualcomm Gobi 2000 modem
 product QUALCOMMINC CDMA_MSM	0x0001	CDMA Technologies MSM modem
 product QUALCOMMINC E0002	0x0002	3G modem
 product QUALCOMMINC E0003	0x0003	3G modem
@@ -2815,6 +2839,10 @@
 product REALTEK RTL8187B_1	0x8197	RTL8187B Wireless Adapter
 product REALTEK RTL8187B_2	0x8198	RTL8187B Wireless Adapter
 
+/* RedOctane products */
+product REDOCTANE DUMMY		0x0000	Dummy product
+product REDOCTANE GHMIDI	0x474b	GH MIDI INTERFACE
+
 /* Renesas products */
 product RENESAS RX610		0x0053	RX610 RX-Stick
 
@@ -3251,6 +3279,11 @@
 /* Teclast products */
 product TECLAST TLC300		0x3203	USB Media Player
 
+/* TexTech products */
+product TEXTECH DUMMY		0x0000	Dummy product
+product TEXTECH U2M_1		0x0101	Textech USB MIDI cable
+product TEXTECH U2M_2		0x1806	Textech USB MIDI cable
+
 /* Supra products */
 product DIAMOND2 SUPRAEXPRESS56K 0x07da	Supra Express 56K modem
 product DIAMOND2 SUPRA2890	0x0b4a	SupraMax 2890 56K Modem
@@ -3328,6 +3361,7 @@
 product TOSHIBA RT3070		0x0a07	RT3070
 product TOSHIBA G450		0x0d45	G450 modem
 product TOSHIBA HSDPA		0x1302	G450 modem
+product TOSHIBA TRANSMEMORY	0x6545	USB ThumbDrive
 
 /* Trek Technology products */
 product TREK THUMBDRIVE		0x1111	ThumbDrive
@@ -3384,6 +3418,9 @@
 /* VIA Technologies products */
 product VIA USB2IDEBRIDGE	0x6204	USB 2.0 IDE Bridge
 
+/* VIA Labs */
+product VIALABS USB30SATABRIDGE	0x0700	USB 3.0 SATA Bridge
+
 /* Vaisala products */
 product VAISALA CABLE		0x0200	USB Interface cable
 
@@ -3427,7 +3464,9 @@
 
 /* WCH products */
 product WCH CH341SER		0x5523	CH341/CH340 USB-Serial Bridge
+product WCH2 DUMMY		0x0000	Dummy product
 product WCH2 CH341SER		0x7523	CH341/CH340 USB-Serial Bridge
+product WCH2 U2M		0X752d	CH345 USB2.0-MIDI
 
 /* Western Digital products */
 product WESTERN COMBO		0x0200	Firewire USB Combo
--- a/head/sys/dev/usb/wlan/if_rum.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/wlan/if_rum.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/*	$FreeBSD: head/sys/dev/usb/wlan/if_rum.c 233774 2012-04-02 10:50:42Z hselasky $	*/
+/*	$FreeBSD: head/sys/dev/usb/wlan/if_rum.c 236439 2012-06-02 09:10:51Z hselasky $	*/
 
 /*-
  * Copyright (c) 2005-2007 Damien Bergamini <[email protected]>
@@ -19,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rum.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rum.c 236439 2012-06-02 09:10:51Z hselasky $");
 
 /*-
  * Ralink Technology RT2501USB/RT2601USB chipset driver
@@ -726,6 +726,12 @@
 		ni = ieee80211_ref_node(vap->iv_bss);
 
 		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
+			if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) {
+				RUM_UNLOCK(sc);
+				IEEE80211_LOCK(ic);
+				ieee80211_free_node(ni);
+				return (-1);
+			}
 			rum_update_slot(ic->ic_ifp);
 			rum_enable_mrr(sc);
 			rum_set_txpreamble(sc);
@@ -2135,11 +2141,12 @@
 
 	if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC)
 		return;
+	if (ic->ic_bsschan == IEEE80211_CHAN_ANYC)
+		return;
 
 	m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo);
-	if (m0 == NULL) {
+	if (m0 == NULL)
 		return;
-	}
 
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
 	rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
--- a/head/sys/dev/usb/wlan/if_run.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/wlan/if_run.c	Wed Jul 25 17:09:47 2012 +0300
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_run.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_run.c 238274 2012-07-09 06:34:15Z hrs $");
 
 /*-
  * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver.
@@ -209,6 +209,7 @@
     RUN_DEV(LOGITEC,		RT2870_2),
     RUN_DEV(LOGITEC,		RT2870_3),
     RUN_DEV(LOGITEC,		LANW300NU2),
+    RUN_DEV(LOGITEC,		LANW150NU2),
     RUN_DEV(MELCO,		RT2870_1),
     RUN_DEV(MELCO,		RT2870_2),
     RUN_DEV(MELCO,		WLIUCAG300N),
@@ -216,6 +217,7 @@
     RUN_DEV(MELCO,		WLIUCG301N),
     RUN_DEV(MELCO,		WLIUCGN),
     RUN_DEV(MELCO,		WLIUCGNM),
+    RUN_DEV(MELCO,		WLIUCGNM2),
     RUN_DEV(MOTOROLA4,		RT2770),
     RUN_DEV(MOTOROLA4,		RT3070),
     RUN_DEV(MSI,		RT3070_1),
@@ -1830,6 +1832,11 @@
 		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
 			struct ieee80211_node *ni;
 
+			if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) {
+				RUN_UNLOCK(sc);
+				IEEE80211_LOCK(ic);
+				return (-1);
+			}
 			run_updateslot(ic->ic_ifp);
 			run_enable_mrr(sc);
 			run_set_txpreamble(sc);
@@ -2523,8 +2530,8 @@
 		struct run_rx_radiotap_header *tap = &sc->sc_rxtap;
 
 		tap->wr_flags = 0;
-		tap->wr_chan_freq = htole16(ic->ic_bsschan->ic_freq);
-		tap->wr_chan_flags = htole16(ic->ic_bsschan->ic_flags);
+		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
 		tap->wr_antsignal = rssi;
 		tap->wr_antenna = ant;
 		tap->wr_dbm_antsignal = run_rssi2dbm(sc, rssi, ant);
@@ -2778,8 +2785,8 @@
 
 			tap->wt_flags = 0;
 			tap->wt_rate = rt2860_rates[data->ridx].rate;
-			tap->wt_chan_freq = htole16(vap->iv_bss->ni_chan->ic_freq);
-			tap->wt_chan_flags = htole16(vap->iv_bss->ni_chan->ic_flags);
+			tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+			tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
 			tap->wt_hwqueue = index;
 			if (le16toh(txwi->phy) & RT2860_PHY_SHPRE)
 				tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
@@ -3967,6 +3974,8 @@
 
 	if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC)
 		return;
+	if (ic->ic_bsschan == IEEE80211_CHAN_ANYC)
+		return;
 
 	/*
 	 * No need to call ieee80211_beacon_update(), run_update_beacon()
--- a/head/sys/dev/usb/wlan/if_ural.c	Wed Jul 25 17:07:47 2012 +0300
+++ b/head/sys/dev/usb/wlan/if_ural.c	Wed Jul 25 17:09:47 2012 +0300
@@ -1,4 +1,4 @@
-/*	$FreeBSD: head/sys/dev/usb/wlan/if_ural.c 233774 2012-04-02 10:50:42Z hselasky $	*/
+/*	$FreeBSD: head/sys/dev/usb/wlan/if_ural.c 236439 2012-06-02 09:10:51Z hselasky $	*/
 
 /*-
  * Copyright (c) 2005, 2006
@@ -21,7 +21,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_ural.c 233774 2012-04-02 10:50:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_ural.c 236439 2012-06-02 09:10:51Z hselasky $");
 
 /*-
  * Ralink Technology RT2500USB chipset driver
@@ -713,6 +713,12 @@
 		ni = ieee80211_ref_node(vap->iv_bss);
 
 		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
+			if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) {
+				RAL_UNLOCK(sc);
+				IEEE80211_LOCK(ic);
+				ieee80211_free_node(ni);
+				return (-1);
+			}
 			ural_update_slot(ic->ic_ifp);
 			ural_set_txpreamble(sc);
 			ural_set_basicrates(sc, ic->ic_bsschan);
@@ -1054,7 +1060,12 @@
 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 		m_freem(m0);
 		ieee80211_free_node(ni);
-		return EIO;
+		return (EIO);
+	}
+	if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) {
+		m_freem(m0);
+		ieee80211_free_node(ni);
+		return (ENXIO);
 	}
 	data = STAILQ_FIRST(&sc->tx_free);
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);