? usb.diff
? ic/cvs.core
? pci/if_sip.log
Index: usb/ugen.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ugen.c,v
retrieving revision 1.85
diff -u -p -r1.85 ugen.c
--- usb/ugen.c	3 Sep 2006 07:14:47 -0000	1.85
+++ usb/ugen.c	28 Nov 2006 22:32:38 -0000
@@ -47,6 +47,7 @@
 __KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.85 2006/09/03 07:14:47 christos Exp $");
 
 #include "opt_ugen_bulk_ra_wb.h"
+#include "opt_compat_netbsd.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1804,6 +1805,13 @@ ugen_do_ioctl(struct ugen_softc *sc, int
 		usbd_fill_deviceinfo(sc->sc_udev,
 				     (struct usb_device_info *)addr, 1);
 		break;
+#ifdef COMPAT_30
+	case USB_GET_DEVICEINFO_OLD:
+		usbd_fill_deviceinfo_old(sc->sc_udev,
+					 (struct usb_device_info_old *)addr, 1);
+
+		break;
+#endif
 	default:
 		return (EINVAL);
 	}
Index: usb/uhid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uhid.c,v
retrieving revision 1.70
diff -u -p -r1.70 uhid.c
--- usb/uhid.c	3 Sep 2006 21:09:46 -0000	1.70
+++ usb/uhid.c	28 Nov 2006 22:32:38 -0000
@@ -44,6 +44,8 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.70 2006/09/03 21:09:46 christos Exp $");
 
+#include "opt_compat_netbsd.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -532,9 +534,15 @@ uhid_do_ioctl(struct uhid_softc *sc, u_l
 
 	case USB_GET_DEVICEINFO:
 		usbd_fill_deviceinfo(sc->sc_hdev.sc_parent->sc_udev,
-				     (struct usb_device_info *)addr, 1);
+			             (struct usb_device_info *)addr, 1);
 		break;
+#ifdef COMPAT_30
+	case USB_GET_DEVICEINFO_OLD:
+		usbd_fill_deviceinfo_old(sc->sc_hdev.sc_parent->sc_udev,
+					 (struct usb_device_info_old *)addr, 1);
 
+		break;
+#endif
         case USB_GET_STRING_DESC:
 	    {
                 struct usb_string_desc *si = (struct usb_string_desc *)addr;
Index: usb/usb.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb.c,v
retrieving revision 1.88
diff -u -p -r1.88 usb.c
--- usb/usb.c	3 Sep 2006 21:33:10 -0000	1.88
+++ usb/usb.c	28 Nov 2006 22:32:38 -0000
@@ -46,6 +46,8 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.88 2006/09/03 21:33:10 christos Exp $");
 
+#include "opt_compat_netbsd.h"
+
 #include "ohci.h"
 #include "uhci.h"
 
@@ -142,6 +144,10 @@ Static void usb_add_event(int, struct us
 
 Static int usb_get_next_event(struct usb_event *);
 
+#ifdef COMPAT_30
+Static void usb_copy_old_devinfo(struct usb_device_info_old *, const struct usb_device_info *);
+#endif
+
 Static const char *usbrev_str[] = USBREV_STR;
 
 USB_DECLARE_DRIVER(usb);
@@ -408,14 +414,32 @@ usbopen(dev_t dev, int flag, int mode, s
 int
 usbread(dev_t dev, struct uio *uio, int flag)
 {
-	struct usb_event *ue = usb_alloc_event();
-	int s, error, n;
+	struct usb_event *ue;
+#ifdef COMPAT_30
+	struct usb_event_old *ueo;
+#endif
+	int s, error, n, useold;
 
 	if (minor(dev) != USB_DEV_MINOR)
 		return (ENXIO);
 
-	if (uio->uio_resid != sizeof(struct usb_event))
+	useold = 0;
+	/* XXXGCC */
+	ueo = NULL;
+	switch (uio->uio_resid) {
+#ifdef COMPAT_30
+	case sizeof(struct usb_event_old):
+		ueo = malloc(sizeof(struct usb_event_old), M_USBDEV,
+			     M_WAITOK|M_ZERO);
+		useold = 1;
+		/* FALLTHRU */
+#endif
+	case sizeof(struct usb_event):
+		ue = usb_alloc_event();
+		break;
+	default:
 		return (EINVAL);
+	}
 
 	error = 0;
 	s = splusb();
@@ -432,9 +456,44 @@ usbread(dev_t dev, struct uio *uio, int 
 			break;
 	}
 	splx(s);
-	if (!error)
-		error = uiomove((void *)ue, uio->uio_resid, uio);
+	if (!error) {
+#ifdef COMPAT_30
+		if (useold) { /* copy fields to old struct */
+			ueo->ue_type = ue->ue_type;
+			memcpy(&ueo->ue_time, &ue->ue_time,
+			      sizeof(struct timespec));
+			switch (ue->ue_type) {
+				case USB_EVENT_DEVICE_ATTACH:
+				case USB_EVENT_DEVICE_DETACH:
+					usb_copy_old_devinfo(&ueo->u.ue_device, &ue->u.ue_device);
+					break;
+
+				case USB_EVENT_CTRLR_ATTACH:
+				case USB_EVENT_CTRLR_DETACH:
+					ueo->u.ue_ctrlr.ue_bus=ue->u.ue_ctrlr.ue_bus;
+					break;
+
+				case USB_EVENT_DRIVER_ATTACH:
+				case USB_EVENT_DRIVER_DETACH:
+					ueo->u.ue_driver.ue_cookie=ue->u.ue_driver.ue_cookie;
+					memcpy(ueo->u.ue_driver.ue_devname,
+					       ue->u.ue_driver.ue_devname,  
+					       sizeof(ue->u.ue_driver.ue_devname));
+					break;
+				default:
+					;
+			}
+
+			error = uiomove((void *)ueo, uio->uio_resid, uio);
+		} else
+#endif
+			error = uiomove((void *)ue, uio->uio_resid, uio);
+	}
 	usb_free_event(ue);
+#ifdef COMPAT_30
+	if (useold)
+		free(ueo, M_USBDEV);
+#endif
 
 	return (error);
 }
@@ -554,17 +613,32 @@ usbioctl(dev_t devt, u_long cmd, caddr_t
 	}
 
 	case USB_DEVICEINFO:
+#ifdef COMPAT_30
+	case USB_DEVICEINFO_OLD:
+#endif
 	{
 		struct usb_device_info *di = (void *)data;
-		int addr = di->udi_addr;
+#ifdef COMPAT_30
+		struct usb_device_info_old *dio = (void *)data;
+#endif
+		int addr;
 		usbd_device_handle dev;
 
+		if (cmd == USB_DEVICEINFO)
+			addr=di->udi_addr;
+		else
+			addr=dio->udi_addr;
 		if (addr < 1 || addr >= USB_MAX_DEVICES)
 			return (EINVAL);
 		dev = sc->sc_bus->devices[addr];
 		if (dev == NULL)
 			return (ENXIO);
-		usbd_fill_deviceinfo(dev, di, 1);
+		if (cmd == USB_DEVICEINFO)
+			usbd_fill_deviceinfo(dev, di, 1);
+#ifdef COMPAT_30
+		else
+			usbd_fill_deviceinfo_old(dev, dio, 1);
+#endif
 		break;
 	}
 
@@ -860,3 +934,62 @@ usb_detach(device_ptr_t self, int flags)
 
 	return (0);
 }
+
+#ifdef COMPAT_30
+Static void
+usb_copy_old_devinfo(struct usb_device_info_old *uo,
+		     const struct usb_device_info *ue)
+{
+	const unsigned char *p;
+	unsigned char *q;
+	int i, n;
+
+	uo->udi_bus = ue->udi_bus;
+	uo->udi_addr = ue->udi_addr;       
+	uo->udi_cookie = ue->udi_cookie;
+	for (i = 0, p = (const unsigned char *)ue->udi_product,
+	     q = (unsigned char *)uo->udi_product;
+	     *p && i < USB_MAX_STRING_LEN - 1; p++) {
+		if (*p < 0x80)
+			q[i++] = *p;
+		else {
+			q[i++] = '?';
+			if ((*p & 0xe0) == 0xe0)
+				p++;
+			p++;
+		}
+	}
+	q[i] = 0;
+
+	for (i = 0, p = ue->udi_vendor, q = uo->udi_vendor;
+	     *p && i < USB_MAX_STRING_LEN - 1; p++) {
+		if (* p < 0x80)
+			q[i++] = *p;
+		else {
+			q[i++] = '?';
+			p++;
+			if ((*p & 0xe0) == 0xe0)
+				p++;
+		}
+	}
+	q[i] = 0;
+
+	memcpy(uo->udi_release, ue->udi_release, sizeof(uo->udi_release));
+
+	uo->udi_productNo = ue->udi_productNo;
+	uo->udi_vendorNo = ue->udi_vendorNo;
+	uo->udi_releaseNo = ue->udi_releaseNo;
+	uo->udi_class = ue->udi_class;
+	uo->udi_subclass = ue->udi_subclass;
+	uo->udi_protocol = ue->udi_protocol;
+	uo->udi_config = ue->udi_config;
+	uo->udi_speed = ue->udi_speed;
+	uo->udi_power = ue->udi_power;    
+	uo->udi_nports = ue->udi_nports;
+
+	for (n=0; n<USB_MAX_DEVNAMES; n++)
+		memcpy(uo->udi_devnames[n],
+		       ue->udi_devnames[n], USB_MAX_DEVNAMELEN);
+	memcpy(uo->udi_ports, ue->udi_ports, sizeof(uo->udi_ports));
+}
+#endif
Index: usb/usb.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb.h,v
retrieving revision 1.74
diff -u -p -r1.74 usb.h
--- usb/usb.h	24 Jul 2006 14:24:50 -0000	1.74
+++ usb/usb.h	28 Nov 2006 22:32:38 -0000
@@ -621,6 +621,28 @@ struct usb_device_info {
 #define USB_PORT_DISABLED 0xfc
 };
 
+/* <=3.0 had this layout of the structure */
+struct usb_device_info_old {
+        u_int8_t        udi_bus;
+        u_int8_t        udi_addr;       /* device address */
+        usb_event_cookie_t udi_cookie;
+        char            udi_product[USB_MAX_STRING_LEN];
+        char            udi_vendor[USB_MAX_STRING_LEN];
+        char            udi_release[8];
+        u_int16_t       udi_productNo;
+        u_int16_t       udi_vendorNo;
+        u_int16_t       udi_releaseNo;
+        u_int8_t        udi_class;
+        u_int8_t        udi_subclass;
+        u_int8_t        udi_protocol;
+        u_int8_t        udi_config;
+        u_int8_t        udi_speed;
+        int             udi_power;      /* power consumption in mA, 0 if selfpowered */
+        int             udi_nports;
+        char            udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
+        u_int8_t        udi_ports[16];/* hub only: addresses of devices on ports */
+};
+
 struct usb_ctl_report {
 	int	ucr_report;
 	u_char	ucr_data[1024];	/* filled data size will vary */
@@ -659,11 +681,29 @@ struct usb_event {
 	} u;
 };
 
+/* old <=3.0 compat event */
+struct usb_event_old {
+	int                     ue_type;
+	struct timespec         ue_time;
+	union {
+		struct {
+			int                     ue_bus;
+		} ue_ctrlr;
+		struct usb_device_info_old          ue_device;
+		struct {
+			usb_event_cookie_t      ue_cookie;
+			char                    ue_devname[16];
+		} ue_driver;
+	} u;
+};
+
+
 /* USB controller */
 #define USB_REQUEST		_IOWR('U', 1, struct usb_ctl_request)
 #define USB_SETDEBUG		_IOW ('U', 2, int)
 #define USB_DISCOVER		_IO  ('U', 3)
 #define USB_DEVICEINFO		_IOWR('U', 4, struct usb_device_info)
+#define USB_DEVICEINFO_OLD	_IOWR('U', 4, struct usb_device_info_old)
 #define USB_DEVICESTATS		_IOR ('U', 5, struct usb_device_stats)
 
 /* Generic HID device */
@@ -687,6 +727,7 @@ struct usb_event {
 #define USB_GET_STRING_DESC	_IOWR('U', 110, struct usb_string_desc)
 #define USB_DO_REQUEST		_IOWR('U', 111, struct usb_ctl_request)
 #define USB_GET_DEVICEINFO	_IOR ('U', 112, struct usb_device_info)
+#define USB_GET_DEVICEINFO_OLD	_IOR ('U', 112, struct usb_device_info_old)
 #define USB_SET_SHORT_XFER	_IOW ('U', 113, int)
 #define USB_SET_TIMEOUT		_IOW ('U', 114, int)
 #define USB_SET_BULK_RA		_IOW ('U', 115, int)
Index: usb/usb_subr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.135
diff -u -p -r1.135 usb_subr.c
--- usb/usb_subr.c	11 Jun 2006 16:00:08 -0000	1.135
+++ usb/usb_subr.c	28 Nov 2006 22:32:39 -0000
@@ -83,8 +83,9 @@ extern int usbdebug;
 Static usbd_status usbd_set_config(usbd_device_handle, int);
 Static void usbd_devinfo(usbd_device_handle, int, char *, size_t);
 Static void usbd_devinfo_vp(usbd_device_handle dev,
-			    char v[USB_MAX_ENCODED_STRING_LEN],
-			    char p[USB_MAX_ENCODED_STRING_LEN], int usedev);
+			    char *v,
+			    char *p, int usedev,
+			    int useencoded );
 Static int usbd_getnewaddr(usbd_bus_handle bus);
 #if defined(__NetBSD__)
 Static int usbd_print(void *, const char *);
@@ -208,8 +209,8 @@ usbd_trim_spaces(char *p)
 }
 
 Static void
-usbd_devinfo_vp(usbd_device_handle dev, char v[USB_MAX_ENCODED_STRING_LEN],
-		char p[USB_MAX_ENCODED_STRING_LEN], int usedev)
+usbd_devinfo_vp(usbd_device_handle dev, char *v,
+		char *p, int usedev, int useencoded)
 {
 	usb_device_descriptor_t *udd = &dev->ddesc;
 #ifdef USBVERBOSE
@@ -221,10 +222,10 @@ usbd_devinfo_vp(usbd_device_handle dev, 
 		return;
 
 	if (usedev) {
-		if (usbd_get_string(dev, udd->iManufacturer, v) ==
+		if (usbd_get_string0(dev, udd->iManufacturer, v, useencoded) ==
 		    USBD_NORMAL_COMPLETION)
 			usbd_trim_spaces(v);
-		if (usbd_get_string(dev, udd->iProduct, p) ==
+		if (usbd_get_string0(dev, udd->iProduct, p, useencoded) ==
 		    USBD_NORMAL_COMPLETION)
 			usbd_trim_spaces(p);
 	}
@@ -273,7 +274,7 @@ usbd_devinfo(usbd_device_handle dev, int
 
 	ep = cp + l;
 
-	usbd_devinfo_vp(dev, vendor, product, 1);
+	usbd_devinfo_vp(dev, vendor, product, 1, 1);
 	cp += snprintf(cp, ep - cp, "%s %s", vendor, product);
 	if (showclass)
 		cp += snprintf(cp, ep - cp, ", class %d/%d",
@@ -1254,7 +1255,7 @@ usbd_fill_deviceinfo(usbd_device_handle 
 	di->udi_bus = USBDEVUNIT(dev->bus->bdev);
 	di->udi_addr = dev->address;
 	di->udi_cookie = dev->cookie;
-	usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
+	usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev, 1);
 	usbd_printBCD(di->udi_release, sizeof(di->udi_release),
 	    UGETW(dev->ddesc.bcdDevice));
 	di->udi_serial[0] = 0;
@@ -1310,6 +1311,71 @@ usbd_fill_deviceinfo(usbd_device_handle 
 		di->udi_nports = 0;
 }
 
+#ifdef COMPAT_30
+void
+usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di,
+                         int usedev)
+{
+	struct usbd_port *p;
+	int i, err, s;
+
+	di->udi_bus = USBDEVUNIT(dev->bus->bdev);
+	di->udi_addr = dev->address;
+	di->udi_cookie = dev->cookie;
+	usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev, 0);
+	usbd_printBCD(di->udi_release, sizeof(di->udi_release),
+	    UGETW(dev->ddesc.bcdDevice));
+	di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
+	di->udi_productNo = UGETW(dev->ddesc.idProduct);
+	di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
+	di->udi_class = dev->ddesc.bDeviceClass;
+	di->udi_subclass = dev->ddesc.bDeviceSubClass;
+	di->udi_protocol = dev->ddesc.bDeviceProtocol;
+	di->udi_config = dev->config;
+	di->udi_power = dev->self_powered ? 0 : dev->power;
+	di->udi_speed = dev->speed;
+
+	if (dev->subdevs != NULL) {
+		for (i = 0; dev->subdevs[i] &&
+			     i < USB_MAX_DEVNAMES; i++) {
+			strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]),
+				USB_MAX_DEVNAMELEN);
+			di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
+		}
+	} else {
+		i = 0;
+	}
+	for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
+		di->udi_devnames[i][0] = 0;		 /* empty */
+
+	if (dev->hub) {
+		for (i = 0;
+		     i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
+			     i < dev->hub->hubdesc.bNbrPorts;
+		     i++) {
+			p = &dev->hub->ports[i];
+			if (p->device)
+				err = p->device->address;
+			else {
+				s = UGETW(p->status.wPortStatus);
+				if (s & UPS_PORT_ENABLED)
+					err = USB_PORT_ENABLED;
+				else if (s & UPS_SUSPEND)
+					err = USB_PORT_SUSPENDED;
+				else if (s & UPS_PORT_POWER)
+					err = USB_PORT_POWERED;
+				else
+					err = USB_PORT_DISABLED;
+			}
+			di->udi_ports[i] = err;
+		}
+		di->udi_nports = dev->hub->hubdesc.bNbrPorts;
+	} else
+		di->udi_nports = 0;
+}
+#endif
+
+
 void
 usb_free_device(usbd_device_handle dev)
 {
Index: usb/usbdi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdi.c,v
retrieving revision 1.110
diff -u -p -r1.110 usbdi.c
--- usb/usbdi.c	24 Dec 2005 20:27:52 -0000	1.110
+++ usb/usbdi.c	28 Nov 2006 22:32:39 -0000
@@ -41,6 +41,8 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.110 2005/12/24 20:27:52 perry Exp $");
 
+#include "opt_compat_netbsd.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #if defined(__NetBSD__) || defined(__OpenBSD__)
@@ -1178,10 +1180,16 @@ usb_desc_iter_next(usbd_desc_iter_t *ite
 usbd_status
 usbd_get_string(usbd_device_handle dev, int si, char *buf)
 {
+	return usbd_get_string0(dev, si, buf, 1);
+}
+
+usbd_status
+usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode)
+{
 	int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
 	usb_string_descriptor_t us;
 	char *s;
-	int i, n;
+	int i, j, n;
 	u_int16_t c;
 	usbd_status err;
 	int size;
@@ -1208,23 +1216,36 @@ usbd_get_string(usbd_device_handle dev, 
 		return (err);
 	s = buf;
 	n = size / 2 - 1;
-	for (i = 0; i < n; i++) {
-		c = UGETW(us.bString[i]);
-		if (swap)
-			c = (c >> 8) | (c << 8);
-		/* Encode (16-bit) Unicode as UTF8. */
-		if (c < 0x0080) {
-			*s++ = c;
-		} else if (c < 0x0800) {
-			*s++ = 0xc0 | (c >> 6);
-			*s++ = 0x80 | (c & 0x3f);
-		} else {
-			*s++ = 0xe0 | (c >> 12);
-			*s++ = 0x80 | ((c >> 6) & 0x3f);
-			*s++ = 0x80 | (c & 0x3f);
+	if (unicode) {
+		for (i = 0; i < n; i++) {
+			c = UGETW(us.bString[i]);
+			if (swap)
+				c = (c >> 8) | (c << 8);
+			if (c < 0x0080) {
+				*s++ = c;
+			} else if (c < 0x0800) {
+				*s++ = 0xc0 | (c >> 6);
+				*s++ = 0x80 | (c & 0x3f);
+			} else {
+				*s++ = 0xe0 | (c >> 12);
+				*s++ = 0x80 | ((c >> 6) & 0x3f);
+				*s++ = 0x80 | (c & 0x3f);
+			}
 		}
+		*s++ = 0;
 	}
-	*s++ = 0;
+#ifdef COMPAT_30
+	else {
+		for (i = j = 0; i < n && j < USB_MAX_STRING_LEN - 1; i++) {
+			c = UGETW(us.bString[i]);
+			if (swap)
+				c = (c >> 8) | (c << 8);
+			/* Encode (16-bit) Unicode as UTF8. */
+			s[j++] = (c < 0x80) ? c : '?';
+		}
+		s[j] = 0;
+	}
+#endif
 	return (USBD_NORMAL_COMPLETION);
 }
 
Index: usb/usbdi.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdi.h,v
retrieving revision 1.69
diff -u -p -r1.69 usbdi.h
--- usb/usbdi.h	28 Nov 2005 13:14:48 -0000	1.69
+++ usb/usbdi.h	28 Nov 2006 22:32:39 -0000
@@ -150,6 +150,7 @@ usbd_status usbd_set_interface(usbd_inte
 int usbd_get_no_alts(usb_config_descriptor_t *, int);
 usbd_status  usbd_get_interface(usbd_interface_handle, u_int8_t *);
 void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int);
+void usbd_fill_deviceinfo_old(usbd_device_handle, struct usb_device_info_old *, int);
 int usbd_get_interface_altindex(usbd_interface_handle);
 
 usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *,
@@ -177,6 +178,7 @@ usbd_status usbd_reload_device_desc(usbd
 int usbd_ratecheck(struct timeval *);
 
 usbd_status usbd_get_string(usbd_device_handle, int, char *);
+usbd_status usbd_get_string0(usbd_device_handle, int, char *, int);
 
 /* An iterator for descriptors. */
 typedef struct {
