svn commit: r223486 - in head: sys/dev/sound/usb sys/dev/usb sys/dev/usb/input sys/dev/usb/net sys/dev/usb/serial sys/dev/usb/storage sys/dev/usb/wlan sys/netgraph/bluetooth/drivers/ubt sys/netgrap...

Hans Petter Selasky hselasky at FreeBSD.org
Fri Jun 24 02:30:03 UTC 2011


Author: hselasky
Date: Fri Jun 24 02:30:02 2011
New Revision: 223486
URL: http://svn.freebsd.org/changeset/base/223486

Log:
  - Move all USB device ID arrays into so-called sections,
    sorted according to the mode which they support:
  	host, device or dual mode
  - Add generic tool to extract these data:
  	tools/bus_autoconf
  
  Discussed with:	imp
  Suggested by:	Robert Millan <rmh at debian.org>
  PR:		misc/157903
  MFC after:	14 days

Added:
  head/tools/tools/bus_autoconf/
  head/tools/tools/bus_autoconf/Makefile   (contents, props changed)
  head/tools/tools/bus_autoconf/bus_autoconf.c   (contents, props changed)
  head/tools/tools/bus_autoconf/bus_autoconf.h   (contents, props changed)
  head/tools/tools/bus_autoconf/bus_autoconf.sh   (contents, props changed)
Modified:
  head/sys/dev/sound/usb/uaudio.c
  head/sys/dev/usb/input/atp.c
  head/sys/dev/usb/input/uhid.c
  head/sys/dev/usb/net/if_aue.c
  head/sys/dev/usb/net/if_axe.c
  head/sys/dev/usb/net/if_cdce.c
  head/sys/dev/usb/net/if_cue.c
  head/sys/dev/usb/net/if_ipheth.c
  head/sys/dev/usb/net/if_kue.c
  head/sys/dev/usb/net/if_mos.c
  head/sys/dev/usb/net/if_rue.c
  head/sys/dev/usb/net/if_udav.c
  head/sys/dev/usb/net/uhso.c
  head/sys/dev/usb/serial/u3g.c
  head/sys/dev/usb/serial/uark.c
  head/sys/dev/usb/serial/ubsa.c
  head/sys/dev/usb/serial/uchcom.c
  head/sys/dev/usb/serial/ucycom.c
  head/sys/dev/usb/serial/uftdi.c
  head/sys/dev/usb/serial/ugensa.c
  head/sys/dev/usb/serial/uipaq.c
  head/sys/dev/usb/serial/ulpt.c
  head/sys/dev/usb/serial/umcs.c
  head/sys/dev/usb/serial/umct.c
  head/sys/dev/usb/serial/umodem.c
  head/sys/dev/usb/serial/umoscom.c
  head/sys/dev/usb/serial/uplcom.c
  head/sys/dev/usb/serial/uslcom.c
  head/sys/dev/usb/serial/uvisor.c
  head/sys/dev/usb/serial/uvscom.c
  head/sys/dev/usb/storage/umass.c
  head/sys/dev/usb/usbdi.h
  head/sys/dev/usb/wlan/if_rum.c
  head/sys/dev/usb/wlan/if_run.c
  head/sys/dev/usb/wlan/if_uath.c
  head/sys/dev/usb/wlan/if_upgt.c
  head/sys/dev/usb/wlan/if_ural.c
  head/sys/dev/usb/wlan/if_urtw.c
  head/sys/dev/usb/wlan/if_zyd.c
  head/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
  head/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c

Modified: head/sys/dev/sound/usb/uaudio.c
==============================================================================
--- head/sys/dev/sound/usb/uaudio.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/sound/usb/uaudio.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -531,6 +531,15 @@ static driver_t uaudio_driver = {
 	.size = sizeof(struct uaudio_softc),
 };
 
+static const STRUCT_USB_HOST_ID __used uaudio_devs[] = {
+	/* Generic USB audio class match */
+	{USB_IFACE_CLASS(UICLASS_AUDIO),
+	 USB_IFACE_SUBCLASS(UISUBCLASS_AUDIOCONTROL),},
+	/* Generic USB MIDI class match */
+	{USB_IFACE_CLASS(UICLASS_AUDIO),
+	 USB_IFACE_SUBCLASS(UISUBCLASS_MIDISTREAM),},
+};
+
 static int
 uaudio_probe(device_t dev)
 {

Modified: head/sys/dev/usb/input/atp.c
==============================================================================
--- head/sys/dev/usb/input/atp.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/input/atp.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -240,7 +240,7 @@ struct atp_dev_params {
 	},
 };
 
-static const struct usb_device_id atp_devs[] = {
+static const STRUCT_USB_HOST_ID atp_devs[] = {
 	/* Core Duo MacBook & MacBook Pro */
 	{ USB_VPI(USB_VENDOR_APPLE, 0x0217, ATP_DEV_PARAMS_0) },
 	{ USB_VPI(USB_VENDOR_APPLE, 0x0218, ATP_DEV_PARAMS_0) },

Modified: head/sys/dev/usb/input/uhid.c
==============================================================================
--- head/sys/dev/usb/input/uhid.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/input/uhid.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -607,29 +607,33 @@ uhid_ioctl(struct usb_fifo *fifo, u_long
 	return (error);
 }
 
+static const STRUCT_USB_HOST_ID uhid_devs[] = {
+	/* generic HID class */
+	{USB_IFACE_CLASS(UICLASS_HID),},
+	/* the Xbox 360 gamepad doesn't use the HID class */
+	{USB_IFACE_CLASS(UICLASS_VENDOR),
+	 USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER),
+	 USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD),},
+};
+
 static int
 uhid_probe(device_t dev)
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	int error;
 
 	DPRINTFN(11, "\n");
 
-	if (uaa->usb_mode != USB_MODE_HOST) {
+	if (uaa->usb_mode != USB_MODE_HOST)
 		return (ENXIO);
-	}
-	if (uaa->info.bInterfaceClass != UICLASS_HID) {
 
-		/* the Xbox 360 gamepad doesn't use the HID class */
+	error = usbd_lookup_id_by_uaa(uhid_devs, sizeof(uhid_devs), uaa);
+	if (error)
+		return (error);
 
-		if ((uaa->info.bInterfaceClass != UICLASS_VENDOR) ||
-		    (uaa->info.bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER) ||
-		    (uaa->info.bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)) {
-			return (ENXIO);
-		}
-	}
-	if (usb_test_quirk(uaa, UQ_HID_IGNORE)) {
+	if (usb_test_quirk(uaa, UQ_HID_IGNORE))
 		return (ENXIO);
-	}
+
 	return (BUS_PROBE_GENERIC);
 }
 

Modified: head/sys/dev/usb/net/if_aue.c
==============================================================================
--- head/sys/dev/usb/net/if_aue.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_aue.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -110,7 +110,7 @@ SYSCTL_INT(_hw_usb_aue, OID_AUTO, debug,
 /*
  * Various supported device vendors/products.
  */
-static const struct usb_device_id aue_devs[] = {
+static const STRUCT_USB_HOST_ID aue_devs[] = {
 #define	AUE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
     AUE_DEV(3COM, 3C460B, AUE_FLAG_PII),
     AUE_DEV(ABOCOM, DSB650TX_PNA, 0),

Modified: head/sys/dev/usb/net/if_axe.c
==============================================================================
--- head/sys/dev/usb/net/if_axe.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_axe.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -133,7 +133,7 @@ SYSCTL_INT(_hw_usb_axe, OID_AUTO, debug,
 /*
  * Various supported device vendors/products.
  */
-static const struct usb_device_id axe_devs[] = {
+static const STRUCT_USB_HOST_ID axe_devs[] = {
 #define	AXE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
 	AXE_DEV(ABOCOM, UF200, 0),
 	AXE_DEV(ACERCM, EP1427X2, 0),

Modified: head/sys/dev/usb/net/if_cdce.c
==============================================================================
--- head/sys/dev/usb/net/if_cdce.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_cdce.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -263,7 +263,7 @@ static const struct usb_ether_methods cd
 	.ue_setpromisc = cdce_setpromisc,
 };
 
-static const struct usb_device_id cdce_devs[] = {
+static const STRUCT_USB_HOST_ID cdce_host_devs[] = {
 	{USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)},
@@ -277,7 +277,9 @@ static const struct usb_device_id cdce_d
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
+};
 
+static const STRUCT_USB_DUAL_ID cdce_dual_devs[] = {
 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_NETWORK_CONTROL_MODEL, 0)},
@@ -472,8 +474,12 @@ static int
 cdce_probe(device_t dev)
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	int error;
 
-	return (usbd_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa));
+	error = usbd_lookup_id_by_uaa(cdce_host_devs, sizeof(cdce_host_devs), uaa);
+	if (error)
+		error = usbd_lookup_id_by_uaa(cdce_dual_devs, sizeof(cdce_dual_devs), uaa);
+	return (error);
 }
 
 static void

Modified: head/sys/dev/usb/net/if_cue.c
==============================================================================
--- head/sys/dev/usb/net/if_cue.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_cue.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$");
 
 /* Belkin F5U111 adapter covered by NETMATE entry */
 
-static const struct usb_device_id cue_devs[] = {
+static const STRUCT_USB_HOST_ID cue_devs[] = {
 #define	CUE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
 	CUE_DEV(CATC, NETMATE),
 	CUE_DEV(CATC, NETMATE2),

Modified: head/sys/dev/usb/net/if_ipheth.c
==============================================================================
--- head/sys/dev/usb/net/if_ipheth.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_ipheth.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -148,7 +148,7 @@ static const struct usb_ether_methods ip
     USB_IFACE_CLASS(c), USB_IFACE_SUBCLASS(sc), \
     USB_IFACE_PROTOCOL(pt)
 
-static const struct usb_device_id ipheth_devs[] = {
+static const STRUCT_USB_HOST_ID ipheth_devs[] = {
 	{IPHETH_ID(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
 	    IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
 	    IPHETH_USBINTF_PROTO)},

Modified: head/sys/dev/usb/net/if_kue.c
==============================================================================
--- head/sys/dev/usb/net/if_kue.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_kue.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -100,7 +100,7 @@ __FBSDID("$FreeBSD$");
 /*
  * Various supported device vendors/products.
  */
-static const struct usb_device_id kue_devs[] = {
+static const STRUCT_USB_HOST_ID kue_devs[] = {
 #define	KUE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
 	KUE_DEV(3COM, 3C19250),
 	KUE_DEV(3COM, 3C460),

Modified: head/sys/dev/usb/net/if_mos.c
==============================================================================
--- head/sys/dev/usb/net/if_mos.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_mos.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -146,7 +146,7 @@ SYSCTL_INT(_hw_usb_mos, OID_AUTO, debug,
 
 
 /* Various supported device vendors/products. */
-static const struct usb_device_id mos_devs[] = {
+static const STRUCT_USB_HOST_ID mos_devs[] = {
 	{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730, MCS7730)},
 	{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830, MCS7830)},
 	{USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030, MCS7830)},

Modified: head/sys/dev/usb/net/if_rue.c
==============================================================================
--- head/sys/dev/usb/net/if_rue.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_rue.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -108,7 +108,7 @@ SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug,
  * Various supported device vendors/products.
  */
 
-static const struct usb_device_id rue_devs[] = {
+static const STRUCT_USB_HOST_ID rue_devs[] = {
 	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, 0)},
 	{USB_VPI(USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100, 0)},
 	{USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01, 0)},

Modified: head/sys/dev/usb/net/if_udav.c
==============================================================================
--- head/sys/dev/usb/net/if_udav.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/if_udav.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -199,7 +199,7 @@ SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug
 #define	UDAV_CLRBIT(sc, reg, x)	\
 	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
 
-static const struct usb_device_id udav_devs[] = {
+static const STRUCT_USB_HOST_ID udav_devs[] = {
 	/* ShanTou DM9601 USB NIC */
 	{USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
 	/* ShanTou ST268 USB NIC */

Modified: head/sys/dev/usb/net/uhso.c
==============================================================================
--- head/sys/dev/usb/net/uhso.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/net/uhso.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -247,7 +247,7 @@ static char *uhso_port_type_sysctl[] = {
 /* ifnet device unit allocations */
 static struct unrhdr *uhso_ifnet_unit = NULL;
 
-static const struct usb_device_id uhso_devs[] = {
+static const STRUCT_USB_HOST_ID uhso_devs[] = {
 #define	UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
 	/* Option GlobeSurfer iCON 7.2 */
 	UHSO_DEV(OPTION, GSICON72, UHSO_STATIC_IFACE),

Modified: head/sys/dev/usb/serial/u3g.c
==============================================================================
--- head/sys/dev/usb/serial/u3g.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/u3g.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -182,7 +182,7 @@ MODULE_DEPEND(u3g, ucom, 1, 1, 1);
 MODULE_DEPEND(u3g, usb, 1, 1, 1);
 MODULE_VERSION(u3g, 1);
 
-static const struct usb_device_id u3g_devs[] = {
+static const STRUCT_USB_HOST_ID u3g_devs[] = {
 #define	U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
 	U3G_DEV(ACERP, H10, 0),
 	U3G_DEV(AIRPLUS, MCD650, 0),

Modified: head/sys/dev/usb/serial/uark.c
==============================================================================
--- head/sys/dev/usb/serial/uark.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uark.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -170,7 +170,7 @@ MODULE_DEPEND(uark, ucom, 1, 1, 1);
 MODULE_DEPEND(uark, usb, 1, 1, 1);
 MODULE_VERSION(uark, 1);
 
-static const struct usb_device_id uark_devs[] = {
+static const STRUCT_USB_HOST_ID uark_devs[] = {
 	{USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)},
 };
 

Modified: head/sys/dev/usb/serial/ubsa.c
==============================================================================
--- head/sys/dev/usb/serial/ubsa.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/ubsa.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -239,7 +239,7 @@ static const struct ucom_callback ubsa_c
 	.ucom_poll = &ubsa_poll,
 };
 
-static const struct usb_device_id ubsa_devs[] = {
+static const STRUCT_USB_HOST_ID ubsa_devs[] = {
 	/* AnyData ADU-500A */
 	{USB_VPI(USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A, 0)},
 	/* AnyData ADU-E100A/H */

Modified: head/sys/dev/usb/serial/uchcom.c
==============================================================================
--- head/sys/dev/usb/serial/uchcom.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uchcom.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -204,7 +204,7 @@ static const struct uchcom_divider_recor
 
 #define	NUM_DIVIDERS	(sizeof (dividers) / sizeof (dividers[0]))
 
-static const struct usb_device_id uchcom_devs[] = {
+static const STRUCT_USB_HOST_ID uchcom_devs[] = {
 	{USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)},
 	{USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)},
 };

Modified: head/sys/dev/usb/serial/ucycom.c
==============================================================================
--- head/sys/dev/usb/serial/ucycom.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/ucycom.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -180,7 +180,7 @@ MODULE_VERSION(ucycom, 1);
 /*
  * Supported devices
  */
-static const struct usb_device_id ucycom_devs[] = {
+static const STRUCT_USB_HOST_ID ucycom_devs[] = {
 	{USB_VPI(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, MODEL_CY7C64013)},
 };
 

Modified: head/sys/dev/usb/serial/uftdi.c
==============================================================================
--- head/sys/dev/usb/serial/uftdi.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uftdi.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -206,7 +206,7 @@ MODULE_DEPEND(uftdi, ucom, 1, 1, 1);
 MODULE_DEPEND(uftdi, usb, 1, 1, 1);
 MODULE_VERSION(uftdi, 1);
 
-static struct usb_device_id uftdi_devs[] = {
+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),

Modified: head/sys/dev/usb/serial/ugensa.c
==============================================================================
--- head/sys/dev/usb/serial/ugensa.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/ugensa.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -154,7 +154,7 @@ MODULE_DEPEND(ugensa, ucom, 1, 1, 1);
 MODULE_DEPEND(ugensa, usb, 1, 1, 1);
 MODULE_VERSION(ugensa, 1);
 
-static const struct usb_device_id ugensa_devs[] = {
+static const STRUCT_USB_HOST_ID ugensa_devs[] = {
 	{USB_VPI(USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220, 0)},
 	{USB_VPI(USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CDMA_MODEM1, 0)},
 	{USB_VPI(USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_CDMA_MSM_K, 0)},

Modified: head/sys/dev/usb/serial/uipaq.c
==============================================================================
--- head/sys/dev/usb/serial/uipaq.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uipaq.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -153,7 +153,7 @@ static const struct ucom_callback uipaq_
  * support the same hardware. Numeric values are used where no usbdevs
  * entries exist.
  */
-static const struct usb_device_id uipaq_devs[] = {
+static const STRUCT_USB_HOST_ID uipaq_devs[] = {
 	/* Socket USB Sync */
 	{USB_VPI(0x0104, 0x00be, 0)},
 	/* USB Sync 0301 */

Modified: head/sys/dev/usb/serial/ulpt.c
==============================================================================
--- head/sys/dev/usb/serial/ulpt.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/ulpt.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -483,24 +483,39 @@ ulpt_ioctl(struct usb_fifo *fifo, u_long
 	return (ENODEV);
 }
 
+static const STRUCT_USB_HOST_ID ulpt_devs[] = {
+	/* Uni-directional USB printer */
+	{USB_IFACE_CLASS(UICLASS_PRINTER),
+	 USB_IFACE_SUBCLASS(UISUBCLASS_PRINTER),
+	 USB_IFACE_PROTOCOL(UIPROTO_PRINTER_UNI)},
+
+	/* Bi-directional USB printer */
+	{USB_IFACE_CLASS(UICLASS_PRINTER),
+	 USB_IFACE_SUBCLASS(UISUBCLASS_PRINTER),
+	 USB_IFACE_PROTOCOL(UIPROTO_PRINTER_BI)},
+
+	/* 1284 USB printer */
+	{USB_IFACE_CLASS(UICLASS_PRINTER),
+	 USB_IFACE_SUBCLASS(UISUBCLASS_PRINTER),
+	 USB_IFACE_PROTOCOL(UIPROTO_PRINTER_1284)},
+};
+
 static int
 ulpt_probe(device_t dev)
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	int error;
 
 	DPRINTFN(11, "\n");
 
-	if (uaa->usb_mode != USB_MODE_HOST) {
+	if (uaa->usb_mode != USB_MODE_HOST)
 		return (ENXIO);
-	}
-	if ((uaa->info.bInterfaceClass == UICLASS_PRINTER) &&
-	    (uaa->info.bInterfaceSubClass == UISUBCLASS_PRINTER) &&
-	    ((uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_UNI) ||
-	    (uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_BI) ||
-	    (uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_1284))) {
-		return (0);
-	}
-	return (ENXIO);
+
+	error = usbd_lookup_id_by_uaa(ulpt_devs, sizeof(ulpt_devs), uaa);
+	if (error)
+		return (error);
+
+	return (BUS_PROBE_GENERIC);
 }
 
 static int

Modified: head/sys/dev/usb/serial/umcs.c
==============================================================================
--- head/sys/dev/usb/serial/umcs.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/umcs.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -253,7 +253,7 @@ static struct ucom_callback umcs7840_cal
 	.ucom_poll = &umcs7840_poll,
 };
 
-static const struct usb_device_id umcs7840_devs[] = {
+static const STRUCT_USB_HOST_ID umcs7840_devs[] = {
 	{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7820, 0)},
 	{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7840, 0)},
 };

Modified: head/sys/dev/usb/serial/umct.c
==============================================================================
--- head/sys/dev/usb/serial/umct.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/umct.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -192,7 +192,7 @@ static const struct ucom_callback umct_c
 	.ucom_poll = &umct_poll,
 };
 
-static const struct usb_device_id umct_devs[] = {
+static const STRUCT_USB_HOST_ID umct_devs[] = {
 	{USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0)},
 	{USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, 0)},
 	{USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, 0)},

Modified: head/sys/dev/usb/serial/umodem.c
==============================================================================
--- head/sys/dev/usb/serial/umodem.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/umodem.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -123,7 +123,7 @@ SYSCTL_INT(_hw_usb_umodem, OID_AUTO, deb
     &umodem_debug, 0, "Debug level");
 #endif
 
-static const struct usb_device_id umodem_devs[] = {
+static const STRUCT_USB_HOST_ID umodem_devs[] = {
 	/* Generic Modem class match */
 	{USB_IFACE_CLASS(UICLASS_CDC),
 		USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),

Modified: head/sys/dev/usb/serial/umoscom.c
==============================================================================
--- head/sys/dev/usb/serial/umoscom.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/umoscom.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -280,7 +280,7 @@ MODULE_DEPEND(umoscom, ucom, 1, 1, 1);
 MODULE_DEPEND(umoscom, usb, 1, 1, 1);
 MODULE_VERSION(umoscom, 1);
 
-static const struct usb_device_id umoscom_devs[] = {
+static const STRUCT_USB_HOST_ID umoscom_devs[] = {
 	{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, 0)}
 };
 

Modified: head/sys/dev/usb/serial/uplcom.c
==============================================================================
--- head/sys/dev/usb/serial/uplcom.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uplcom.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -247,7 +247,7 @@ static struct ucom_callback uplcom_callb
 #define	UPLCOM_DEV(v,p)				\
   { USB_VENDOR(USB_VENDOR_##v), USB_PRODUCT(USB_PRODUCT_##v##_##p) }
 
-static const struct usb_device_id uplcom_devs[] = {
+static const STRUCT_USB_HOST_ID uplcom_devs[] = {
 	UPLCOM_DEV(ACERP, S81),			/* BenQ S81 phone */
 	UPLCOM_DEV(ADLINK, ND6530),		/* ADLINK ND-6530 USB-Serial */
 	UPLCOM_DEV(ALCATEL, OT535),		/* Alcatel One Touch 535/735 */

Modified: head/sys/dev/usb/serial/uslcom.c
==============================================================================
--- head/sys/dev/usb/serial/uslcom.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uslcom.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -173,7 +173,7 @@ static struct ucom_callback uslcom_callb
 	.ucom_poll = &uslcom_poll,
 };
 
-static const struct usb_device_id uslcom_devs[] = {
+static const STRUCT_USB_HOST_ID uslcom_devs[] = {
 #define	USLCOM_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
     USLCOM_DEV(BALTECH, CARDREADER),
     USLCOM_DEV(CLIPSAL, 5500PCU),

Modified: head/sys/dev/usb/serial/uvisor.c
==============================================================================
--- head/sys/dev/usb/serial/uvisor.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uvisor.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -253,7 +253,7 @@ MODULE_DEPEND(uvisor, ucom, 1, 1, 1);
 MODULE_DEPEND(uvisor, usb, 1, 1, 1);
 MODULE_VERSION(uvisor, 1);
 
-static const struct usb_device_id uvisor_devs[] = {
+static const STRUCT_USB_HOST_ID uvisor_devs[] = {
 #define	UVISOR_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
 	UVISOR_DEV(ACEECA, MEZ1000, UVISOR_FLAG_PALM4),
 	UVISOR_DEV(ALPHASMART, DANA_SYNC, UVISOR_FLAG_PALM4),

Modified: head/sys/dev/usb/serial/uvscom.c
==============================================================================
--- head/sys/dev/usb/serial/uvscom.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/serial/uvscom.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -233,7 +233,7 @@ static const struct ucom_callback uvscom
 	.ucom_poll = &uvscom_poll,
 };
 
-static const struct usb_device_id uvscom_devs[] = {
+static const STRUCT_USB_HOST_ID uvscom_devs[] = {
 	/* SUNTAC U-Cable type A4 */
 	{USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4, 0)},
 	/* SUNTAC U-Cable type D2 */

Modified: head/sys/dev/usb/storage/umass.c
==============================================================================
--- head/sys/dev/usb/storage/umass.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/storage/umass.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -721,6 +721,11 @@ MODULE_VERSION(umass, 1);
  * USB device probe/attach/detach
  */
 
+static const STRUCT_USB_HOST_ID __used umass_devs[] = {
+	/* generic mass storage class */
+	{USB_IFACE_CLASS(UICLASS_MASS),},
+};
+
 static uint16_t
 umass_get_proto(struct usb_interface *iface)
 {

Modified: head/sys/dev/usb/usbdi.h
==============================================================================
--- head/sys/dev/usb/usbdi.h	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/usbdi.h	Fri Jun 24 02:30:02 2011	(r223486)
@@ -228,6 +228,18 @@ struct usb_config {
 };
 
 /*
+ * Use these macro when defining USB device ID arrays if you want to
+ * have your driver module automatically loaded in host, device or
+ * both modes respectivly:
+ */
+#define	STRUCT_USB_HOST_ID \
+    struct usb_device_id __section("usb_host_id")
+#define	STRUCT_USB_DEVICE_ID \
+    struct usb_device_id __section("usb_device_id")
+#define	STRUCT_USB_DUAL_ID \
+    struct usb_device_id __section("usb_dual_id")
+
+/*
  * The following structure is used when looking up an USB driver for
  * an USB device. It is inspired by the Linux structure called
  * "usb_device_id".

Modified: head/sys/dev/usb/wlan/if_rum.c
==============================================================================
--- head/sys/dev/usb/wlan/if_rum.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_rum.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -85,7 +85,7 @@ SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug,
     "Debug level");
 #endif
 
-static const struct usb_device_id rum_devs[] = {
+static const STRUCT_USB_HOST_ID rum_devs[] = {
 #define	RUM_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
     RUM_DEV(ABOCOM, HWU54DM),
     RUM_DEV(ABOCOM, RT2573_2),

Modified: head/sys/dev/usb/wlan/if_run.c
==============================================================================
--- head/sys/dev/usb/wlan/if_run.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_run.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -96,7 +96,7 @@ SYSCTL_INT(_hw_usb_run, OID_AUTO, debug,
  */
 #define RUN_CMDQ_GET(c)	(atomic_fetchadd_32((c), 1) & RUN_CMDQ_MASQ)
 
-static const struct usb_device_id run_devs[] = {
+static const STRUCT_USB_HOST_ID run_devs[] = {
 #define RUN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
     RUN_DEV(ABOCOM,		RT2770),
     RUN_DEV(ABOCOM,		RT2870),

Modified: head/sys/dev/usb/wlan/if_uath.c
==============================================================================
--- head/sys/dev/usb/wlan/if_uath.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_uath.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -167,7 +167,7 @@ enum {
 	  (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)))
 
 /* recognized device vendors/products */
-static const struct usb_device_id uath_devs[] = {
+static const STRUCT_USB_HOST_ID uath_devs[] = {
 #define	UATH_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
 	UATH_DEV(ACCTON,		SMCWUSBG),
 	UATH_DEV(ACCTON,		SMCWUSBTG2),

Modified: head/sys/dev/usb/wlan/if_upgt.c
==============================================================================
--- head/sys/dev/usb/wlan/if_upgt.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_upgt.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -170,7 +170,7 @@ static int	upgt_tx_start(struct upgt_sof
 
 static const char *upgt_fwname = "upgt-gw3887";
 
-static const struct usb_device_id upgt_devs_2[] = {
+static const STRUCT_USB_HOST_ID upgt_devs[] = {
 #define	UPGT_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
 	/* version 2 devices */
 	UPGT_DEV(ACCTON,	PRISM_GT),
@@ -236,7 +236,7 @@ upgt_match(device_t dev)
 	if (uaa->info.bIfaceIndex != UPGT_IFACE_INDEX)
 		return (ENXIO);
 
-	return (usbd_lookup_id_by_uaa(upgt_devs_2, sizeof(upgt_devs_2), uaa));
+	return (usbd_lookup_id_by_uaa(upgt_devs, sizeof(upgt_devs), uaa));
 }
 
 static int

Modified: head/sys/dev/usb/wlan/if_ural.c
==============================================================================
--- head/sys/dev/usb/wlan/if_ural.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_ural.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -91,7 +91,7 @@ SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug
 	 ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0)
 
 /* various supported device vendors/products */
-static const struct usb_device_id ural_devs[] = {
+static const STRUCT_USB_HOST_ID ural_devs[] = {
 #define	URAL_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
 	URAL_DEV(ASUS, WL167G),
 	URAL_DEV(ASUS, RT2570),

Modified: head/sys/dev/usb/wlan/if_urtw.c
==============================================================================
--- head/sys/dev/usb/wlan/if_urtw.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_urtw.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -102,7 +102,7 @@ TUNABLE_INT("hw.usb.urtw.preamble_mode",
 	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
 #define	URTW_REV_RTL8187B	0
 #define	URTW_REV_RTL8187L	1
-static const struct usb_device_id urtw_devs[] = {
+static const STRUCT_USB_HOST_ID urtw_devs[] = {
 	URTW_DEV_B(NETGEAR, WG111V3),
 	URTW_DEV_B(REALTEK, RTL8187B_0),
 	URTW_DEV_B(REALTEK, RTL8187B_1),

Modified: head/sys/dev/usb/wlan/if_zyd.c
==============================================================================
--- head/sys/dev/usb/wlan/if_zyd.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/dev/usb/wlan/if_zyd.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -200,7 +200,7 @@ static const struct zyd_phy_pair zyd_def
 	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, ZYD_ZD1211) }
 #define	ZYD_ZD1211B_DEV(v,p)	\
 	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, ZYD_ZD1211B) }
-static const struct usb_device_id zyd_devs[] = {
+static const STRUCT_USB_HOST_ID zyd_devs[] = {
 	/* ZYD_ZD1211 */
 	ZYD_ZD1211_DEV(3COM2, 3CRUSB10075),
 	ZYD_ZD1211_DEV(ABOCOM, WL54),

Modified: head/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
==============================================================================
--- head/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -382,14 +382,14 @@ static const struct usb_config		ubt_conf
  * where VENDOR_ID and PRODUCT_ID are hex numbers.
  */
 
-static const struct usb_device_id ubt_ignore_devs[] = 
+static const STRUCT_USB_HOST_ID ubt_ignore_devs[] = 
 {
 	/* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */
 	{ USB_VPI(USB_VENDOR_AVM, 0x2200, 0) },
 };
 
 /* List of supported bluetooth devices */
-static const struct usb_device_id ubt_devs[] =
+static const STRUCT_USB_HOST_ID ubt_devs[] =
 {
 	/* Generic Bluetooth class devices */
 	{ USB_IFACE_CLASS(UDCLASS_WIRELESS),

Modified: head/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c
==============================================================================
--- head/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c	Thu Jun 23 22:21:28 2011	(r223485)
+++ head/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -180,7 +180,7 @@ MODULE_DEPEND(ubtbcmfw, usb, 1, 1, 1);
 static int
 ubtbcmfw_probe(device_t dev)
 {
-	const struct usb_device_id	devs[] = {
+	static const STRUCT_USB_HOST_ID devs[] = {
 	/* Broadcom BCM2033 devices only */
 	{ USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) },
 	};

Added: head/tools/tools/bus_autoconf/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/bus_autoconf/Makefile	Fri Jun 24 02:30:02 2011	(r223486)
@@ -0,0 +1,43 @@
+# $FreeBSD$
+#
+# Copyright (c) 2011 Hans Petter Selasky. 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.
+#
+
+#
+# Example on how to use:
+#
+# make clean all install
+#
+# ./bus_autoconf.sh /boot/kernel/*.ko | less
+#
+
+PROG=	bus_autoconf
+MAN=
+BINDIR?= /usr/local/bin
+
+SRCS=	bus_autoconf.c
+
+WARNS=	6
+
+.include <bsd.prog.mk>

Added: head/tools/tools/bus_autoconf/bus_autoconf.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/bus_autoconf/bus_autoconf.c	Fri Jun 24 02:30:02 2011	(r223486)
@@ -0,0 +1,321 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. 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.
+ */
+
+/*
+ * Disclaimer: This utility and format is subject to change and not a
+ * comitted interface.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include <err.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "bus_autoconf.h"
+
+static char *type;
+static char *file_name;
+static char *module;
+static const char *mode;
+
+static int
+usb_compare(const void *_a, const void *_b)
+{
+	const struct usb_device_id *a = _a;
+	const struct usb_device_id *b = _b;
+
+	if (a->idVendor > b->idVendor)
+		return (1);
+	if (a->idVendor < b->idVendor)
+		return (-1);
+	if (a->idProduct > b->idProduct)
+		return (1);
+	if (a->idProduct < b->idProduct)
+		return (-1);
+	if (a->bDeviceClass > b->bDeviceClass)
+		return (1);
+	if (a->bDeviceClass < b->bDeviceClass)
+		return (-1);
+	if (a->bDeviceSubClass > b->bDeviceSubClass)
+		return (1);
+	if (a->bDeviceSubClass < b->bDeviceSubClass)
+		return (-1);
+	if (a->bDeviceProtocol > b->bDeviceProtocol)
+		return (1);
+	if (a->bDeviceProtocol < b->bDeviceProtocol)
+		return (-1);
+	if (a->bInterfaceClass > b->bInterfaceClass)
+		return (1);
+	if (a->bInterfaceClass < b->bInterfaceClass)
+		return (-1);
+	if (a->bInterfaceSubClass > b->bInterfaceSubClass)
+		return (1);
+	if (a->bInterfaceSubClass < b->bInterfaceSubClass)
+		return (-1);
+	if (a->bInterfaceProtocol > b->bInterfaceProtocol)
+		return (1);
+	if (a->bInterfaceProtocol < b->bInterfaceProtocol)
+		return (-1);
+
+	return (0);
+}
+
+static void
+usb_sort(struct usb_device_id *id, uint32_t nid)
+{
+	qsort(id, nid, sizeof(*id), &usb_compare);
+}
+
+struct usb_info {
+	uint8_t	is_iface;
+	uint8_t	is_any;
+	uint8_t	is_vp;
+	uint8_t	is_dev;
+};
+
+static void
+usb_dump_sub(struct usb_device_id *id, struct usb_info *pinfo)
+{
+#if USB_HAVE_COMPAT_LINUX
+	if (id->match_flags & USB_DEVICE_ID_MATCH_VENDOR)
+		id->match_flag_vendor = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT)
+		id->match_flag_product = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO)
+		id->match_flag_dev_lo = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI)
+		id->match_flag_dev_hi = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS)
+		id->match_flag_dev_class = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS)
+		id->match_flag_dev_subclass = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
+		id->match_flag_dev_protocol = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS)
+		id->match_flag_int_class = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS)
+		id->match_flag_int_subclass = 1;
+	if (id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL)
+		id->match_flag_int_protocol = 1;
+#endif
+
+	pinfo->is_iface = id->match_flag_int_class |
+	    id->match_flag_int_protocol |
+	    id->match_flag_int_subclass;
+
+	pinfo->is_dev = id->match_flag_dev_class |
+	    id->match_flag_dev_subclass;
+
+	pinfo->is_vp = id->match_flag_vendor |
+	    id->match_flag_product;
+
+	pinfo->is_any = pinfo->is_vp + pinfo->is_dev + pinfo->is_iface;
+}
+
+static uint32_t
+usb_dump(struct usb_device_id *id, uint32_t nid)
+{
+	uint32_t n = 1;
+	struct usb_info info;
+
+	usb_dump_sub(id, &info);
+
+	if (info.is_iface) {
+		printf("nomatch 10 {\n"
+		    "	match \"system\" \"USB\";\n"
+		    "	match \"subsystem\" \"INTERFACE\";\n"
+		    "	match \"mode\" \"%s\";\n", mode);
+	} else if (info.is_any) {
+		printf("nomatch 10 {\n"
+		    "	match \"system\" \"USB\";\n"
+		    "	match \"subsystem\" \"DEVICE\";\n"
+		    "	match \"mode\" \"%s\";\n", mode);
+	} else {
+		return (n);
+	}
+
+	if (id->match_flag_vendor) {
+		printf("	match \"vendor\" \"0x%04x\";\n",
+		    id->idVendor);
+	}
+	if (id->match_flag_product) {
+		uint32_t x;
+
+		if (info.is_any == 1 && info.is_vp == 1) {
+			/* try to join similar entries */
+			while (n < nid) {
+				usb_dump_sub(id + n, &info);
+
+				if (info.is_any != 1 || info.is_vp != 1)
+					break;
+				if (id[n].idVendor != id[0].idVendor)
+					break;
+				n++;
+			}
+			/* restore infos */
+			usb_dump_sub(id, &info);
+		}
+		if (n == 1) {
+			printf("	match \"product\" \"0x%04x\";\n",
+			    id->idProduct);
+		} else {
+			printf("	match \"product\" \"(");
+
+			for (x = 0; x != n; x++) {
+				printf("0x%04x%s", id[x].idProduct,
+				    (x == (n - 1)) ? "" : "|");
+			}
+
+			printf(")\";\n");
+		}
+	}
+	if (id->match_flag_dev_class) {
+		printf("	match \"devclass\" \"0x%02x\";\n",
+		    id->bDeviceClass);
+	}
+	if (id->match_flag_dev_subclass) {
+		printf("	match \"devsubclass\" \"0x%02x\";\n",
+		    id->bDeviceSubClass);
+	}
+	if (id->match_flag_int_class) {
+		printf("	match \"intclass\" \"0x%02x\";\n",
+		    id->bInterfaceClass);
+	}
+	if (id->match_flag_int_subclass) {
+		printf("	match \"intsubclass\" \"0x%02x\";\n",
+		    id->bInterfaceSubClass);
+	}
+	if (id->match_flag_int_protocol) {
+		printf("	match \"intprotocol\" \"0x%02x\";\n",
+		    id->bInterfaceProtocol);
+	}
+	printf("	action \"kldload %s\";\n"
+	    "};\n\n", module);
+
+	return (n);
+}
+
+static void
+usb_parse_and_dump(int f, off_t size)
+{
+	struct usb_device_id *id;
+	uint32_t nid;
+	uint32_t x;
+
+	if (size % sizeof(struct usb_device_id)) {
+		errx(EX_NOINPUT, "Size is not divisible by %d",
+		    (int)sizeof(struct usb_device_id));
+	}
+	lseek(f, 0, SEEK_SET);
+
+	id = malloc(size);
+	if (id == NULL) {
+		errx(EX_SOFTWARE, "Out of memory");
+	}
+	if (read(f, id, size) != size) {
+		err(EX_NOINPUT, "Cannot read all data");
+	}
+	nid = size / sizeof(*id);
+
+	usb_sort(id, nid);
+
+	for (x = 0; x != nid;)
+		x += usb_dump(id + x, nid - x);
+
+	free(id);
+}
+
+static void
+usage(void)
+{
+	fprintf(stderr,
+	    "bus_autoconf - devd config file generator\n"
+	    "	-i <input_binary>\n"
+	    "	-m <module_name>\n"
+	    "	-t <structure_type>\n"
+	    "	-h show usage\n"
+	);
+	exit(EX_USAGE);
+}
+
+int
+main(int argc, char **argv)
+{
+	const char *params = "i:m:ht:";
+	int c;
+	int f;
+	off_t off;
+
+	while ((c = getopt(argc, argv, params)) != -1) {
+		switch (c) {
+		case 'i':
+			file_name = optarg;
+			break;
+		case 't':
+			type = optarg;
+			break;
+		case 'm':
+			module = optarg;
+			break;
+		default:
+			usage();
+			break;
+		}
+	}
+
+	if (type == NULL || module == NULL || file_name == NULL)
+		usage();
+
+	f = open(file_name, O_RDONLY);
+	if (f < 0)
+		err(EX_NOINPUT, "Cannot open file '%s'", file_name);
+
+	off = lseek(f, 0, SEEK_END);
+	if (off <= 0)
+		err(EX_NOINPUT, "Cannot seek to end of file");
+
+	if (strcmp(type, "usb_host") == 0) {
+		mode = "host";
+		usb_parse_and_dump(f, off);
+	} else if (strcmp(type, "usb_device") == 0) {
+		mode = "device";
+		usb_parse_and_dump(f, off);
+	} else if (strcmp(type, "usb_dual") == 0) {
+		mode = "(host|device)";
+		usb_parse_and_dump(f, off);
+	} else {
+		err(EX_USAGE, "Unsupported structure type: %s", type);
+	}
+
+	close(f);
+
+	return (0);
+}

Added: head/tools/tools/bus_autoconf/bus_autoconf.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/bus_autoconf/bus_autoconf.h	Fri Jun 24 02:30:02 2011	(r223486)
@@ -0,0 +1,83 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. 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.
+ */
+
+#ifndef _BUS_AUTOCONF_H_
+#define	_BUS_AUTOCONF_H_
+
+/* Make sure we get the have compat linux definition. */
+#include <dev/usb/usb.h>
+
+struct usb_device_id {
+
+	/* Hook for driver specific information */
+	unsigned long driver_info;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list