MFNetBSD.
uhid.c (1.61), author: jdolecek add support for USB_GET_DEVICEINFO and USB_GET_STRING_DESC ioctls, with same meaning as for ugen(4) usbdi_util.h (1.29), usb_quirks.c (1.50), uhid.c (1.62), ugen.c (1.68), usb_subr.c (1.114) author: mycroft Yes, some devices return incorrect lengths in their string descriptors. Rather than losing, do what Windows does: just request the maximum size, and allow a shorter response. Obsoletes the need for UQ_NO_STRINGS, and therefore these "quirks" are removed. usb_subr.c (1.116), author: mycroft In the "seemed like a good idea until I found the fatal flaw" department... Attempting to read a maximum-size string descriptor causes my kue device to go completely apeshit. So, go back to the original method, but allow the device to return a shorter string than it claimed. Obtained from: NetBSD
This commit is contained in:
parent
9561f9f36e
commit
5bebcf6d1c
@ -4,6 +4,7 @@
|
||||
* $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $
|
||||
* $NetBSD: ugen.c,v 1.64 2003/06/28 14:21:46 darrenr Exp $
|
||||
* $NetBSD: ugen.c,v 1.65 2003/06/29 22:30:56 fvdl Exp $
|
||||
* $NetBSD: ugen.c,v 1.68 2004/06/23 02:30:52 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -1311,13 +1312,15 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
|
||||
free(cdesc, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
case USB_GET_STRING_DESC:
|
||||
case USB_GET_STRING_DESC: {
|
||||
int len;
|
||||
si = (struct usb_string_desc *)addr;
|
||||
err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
|
||||
si->usd_language_id, &si->usd_desc);
|
||||
si->usd_language_id, &si->usd_desc, &len);
|
||||
if (err)
|
||||
return (EINVAL);
|
||||
break;
|
||||
}
|
||||
case USB_DO_REQUEST:
|
||||
{
|
||||
struct usb_ctl_request *ur = (void *)addr;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
/* Also already merged from NetBSD:
|
||||
* $NetBSD: uhid.c,v 1.54 2002/09/23 05:51:21 simonb Exp $
|
||||
* $NetBSD: uhid.c,v 1.61 2004/05/08 11:41:19 jdolecek Exp $
|
||||
* $NetBSD: uhid.c,v 1.62 2004/06/23 02:30:52 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -703,6 +705,22 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr, int flag,
|
||||
*(int *)addr = 0; /* XXX: we only support reportid 0? */
|
||||
break;
|
||||
|
||||
case USB_GET_DEVICEINFO:
|
||||
usbd_fill_deviceinfo(sc->sc_hdev.sc_parent->sc_udev,
|
||||
(struct usb_device_info *)addr, 1);
|
||||
break;
|
||||
|
||||
case USB_GET_STRING_DESC:
|
||||
{
|
||||
struct usb_string_desc *si = (struct usb_string_desc *)addr;
|
||||
err = usbd_get_string_desc(sc->sc_hdev.sc_parent->sc_udev,
|
||||
si->usd_string_index,
|
||||
si->usd_language_id, &si->usd_desc, &size);
|
||||
if (err)
|
||||
return (EINVAL);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usb_quirks.c,v 1.42 2003/01/02 04:19:00 imp Exp $ */
|
||||
/* $NetBSD: usb_quirks.c,v 1.50 2004/06/23 02:30:52 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -63,10 +63,6 @@ Static const struct usbd_quirk_entry {
|
||||
{ USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, 0x100, { UQ_NO_SET_PROTO}},
|
||||
{ USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
|
||||
0x094, { UQ_SWAP_UNICODE}},
|
||||
{ USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, 0x100, { UQ_NO_STRINGS }},
|
||||
{ USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, 0x002, { UQ_NO_STRINGS }},
|
||||
{ USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0x101, { UQ_NO_STRINGS }},
|
||||
{ USB_VENDOR_WACOM, USB_PRODUCT_WACOM_CT0405U, 0x101, { UQ_NO_STRINGS }},
|
||||
{ USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_BAD_ADC }},
|
||||
{ USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_AU_NO_XU }},
|
||||
{ USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, { UQ_BAD_ADC }},
|
||||
@ -76,16 +72,13 @@ Static const struct usbd_quirk_entry {
|
||||
{ USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, { UQ_BUS_POWERED }},
|
||||
{ USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0x102, { UQ_BUS_POWERED }},
|
||||
{ USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
|
||||
0x100, { UQ_ASSUME_CM_OVER_DATA | UQ_NO_STRINGS }},
|
||||
0x100, { UQ_ASSUME_CM_OVER_DATA }},
|
||||
{ USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900,
|
||||
0x000, { UQ_ASSUME_CM_OVER_DATA | UQ_NO_STRINGS }},
|
||||
0x000, { UQ_ASSUME_CM_OVER_DATA }},
|
||||
{ USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, { UQ_POWER_CLAIM }},
|
||||
{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U,
|
||||
0x000, { UQ_NO_STRINGS }},
|
||||
{ USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }},
|
||||
{ USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE,
|
||||
0x100, { UQ_AU_INP_ASYNC }},
|
||||
{ USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010, 0x100, { UQ_NO_STRINGS }},
|
||||
/* XXX These should have a revision number, but I don't know what they are. */
|
||||
{ USB_VENDOR_HP, USB_PRODUCT_HP_895C, ANY, { UQ_BROKEN_BIDIR }},
|
||||
{ USB_VENDOR_HP, USB_PRODUCT_HP_880C, ANY, { UQ_BROKEN_BIDIR }},
|
||||
@ -102,7 +95,6 @@ Static const struct usbd_quirk_entry {
|
||||
ANY, { UQ_ASSUME_CM_OVER_DATA }},
|
||||
{ USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTW65I,
|
||||
ANY, { UQ_ASSUME_CM_OVER_DATA }},
|
||||
{ USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMRPAD, ANY, { UQ_NO_STRINGS }},
|
||||
{ USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_CDMA_MSM,
|
||||
ANY, { UQ_ASSUME_CM_OVER_DATA }},
|
||||
{ USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS64LX,
|
||||
|
@ -4,6 +4,9 @@
|
||||
* $NetBSD: usb_subr.c,v 1.102 2003/01/01 16:21:50 augustss Exp $
|
||||
* $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $
|
||||
* $NetBSD: usb_subr.c,v 1.111 2004/03/15 10:35:04 augustss Exp $
|
||||
* $NetBSD: usb_subr.c,v 1.114 2004/06/23 02:30:52 mycroft Exp $
|
||||
* $NetBSD: usb_subr.c,v 1.115 2004/06/23 05:23:19 mycroft Exp $
|
||||
* $NetBSD: usb_subr.c,v 1.116 2004/06/23 06:27:54 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -157,7 +160,7 @@ usbd_errstr(usbd_status err)
|
||||
|
||||
usbd_status
|
||||
usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
|
||||
usb_string_descriptor_t *sdesc)
|
||||
usb_string_descriptor_t *sdesc, int *sizep)
|
||||
{
|
||||
usb_device_request_t req;
|
||||
usbd_status err;
|
||||
@ -173,11 +176,22 @@ usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
if (actlen < 1)
|
||||
if (actlen < 2)
|
||||
return (USBD_SHORT_XFER);
|
||||
|
||||
USETW(req.wLength, sdesc->bLength); /* the whole string */
|
||||
return (usbd_do_request(dev, &req, sdesc));
|
||||
err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
|
||||
&actlen, USBD_DEFAULT_TIMEOUT);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
if (actlen != sdesc->bLength) {
|
||||
DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
|
||||
sdesc->bLength, actlen));
|
||||
}
|
||||
|
||||
*sizep = actlen;
|
||||
return (USBD_NORMAL_COMPLETION);
|
||||
}
|
||||
|
||||
char *
|
||||
@ -189,6 +203,7 @@ usbd_get_string(usbd_device_handle dev, int si, char *buf)
|
||||
int i, n;
|
||||
u_int16_t c;
|
||||
usbd_status err;
|
||||
int size;
|
||||
|
||||
if (si == 0)
|
||||
return (0);
|
||||
@ -196,19 +211,20 @@ usbd_get_string(usbd_device_handle dev, int si, char *buf)
|
||||
return (0);
|
||||
if (dev->langid == USBD_NOLANG) {
|
||||
/* Set up default language */
|
||||
err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
|
||||
if (err || us.bLength < 4) {
|
||||
err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
|
||||
&size);
|
||||
if (err || size < 4) {
|
||||
dev->langid = 0; /* Well, just pick something then */
|
||||
} else {
|
||||
/* Pick the first language as the default. */
|
||||
dev->langid = UGETW(us.bString[0]);
|
||||
}
|
||||
}
|
||||
err = usbd_get_string_desc(dev, si, dev->langid, &us);
|
||||
err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
|
||||
if (err)
|
||||
return (0);
|
||||
s = buf;
|
||||
n = us.bLength / 2 - 1;
|
||||
n = size / 2 - 1;
|
||||
for (i = 0; i < n; i++) {
|
||||
c = UGETW(us.bString[i]);
|
||||
/* Convert from Unicode, handle buggy strings. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usbdi_util.h,v 1.23 2001/10/26 17:58:22 augustss Exp $ */
|
||||
/* $NetBSD: usbdi_util.h,v 1.29 2004/06/23 02:30:52 mycroft Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -69,7 +69,8 @@ usbd_status usbd_read_report_desc(usbd_interface_handle ifc, void **descp,
|
||||
int *sizep, usb_malloc_type mem);
|
||||
usbd_status usbd_get_config(usbd_device_handle dev, u_int8_t *conf);
|
||||
usbd_status usbd_get_string_desc(usbd_device_handle dev, int sindex,
|
||||
int langid, usb_string_descriptor_t *sdesc);
|
||||
int langid,usb_string_descriptor_t *sdesc,
|
||||
int *sizep);
|
||||
void usbd_delay_ms(usbd_device_handle, u_int);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user