? 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 {