1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-22 11:17:19 +00:00

Merge from NetBSD.

o usb_subr.c, add delta 1.119:

  Move usb_get_string() and make it public.

o usbdi.c, bring on par with 1.106, this includes:

  - Make an iterator abstraction for looping through all descriptors.

  - Whine about not being able to figure out default language if we are debugging.

  - Move usb_get_string() and make it public.

o usbdi.h, bring on par with 1.64, this includes:

  - Make an iterator abstraction for looping through all descriptors.

  - Move usb_get_string() and make it public.

o usbdi_util.c, bring on par with 1.42, this includes:

  - Add usbd_get_protocol().

  - Use NULL instead of 0.

  - Fix (mostly harmless) typo.

  - Move utility routine from uirda.c to usbdi_util.c.

o usbdi_util.h, bring on par with 1.31, this includes:

  - Add usbd_get_protocol().

  - Move utility routine from uirda.c to usbdi_util.c.

MFC after:	3 days
This commit is contained in:
Maxim Sobolev 2005-03-01 08:01:22 +00:00
parent 8c8cb52737
commit 21a69c81c0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=142883
5 changed files with 150 additions and 56 deletions

View File

@ -7,6 +7,7 @@
* $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 $
* $NetBSD: usb_subr.c,v 1.119 2004/10/23 13:26:33 augustss Exp $
*/
#include <sys/cdefs.h>
@ -90,7 +91,6 @@ extern int usbdebug;
Static usbd_status usbd_set_config(usbd_device_handle, int);
Static void usbd_devinfo_vp(usbd_device_handle, char *, char *, int);
Static char *usbd_get_string(usbd_device_handle, int, char *);
Static int usbd_getnewaddr(usbd_bus_handle bus);
#if defined(__NetBSD__)
Static int usbd_print(void *aux, const char *pnp);
@ -196,51 +196,6 @@ usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
return (USBD_NORMAL_COMPLETION);
}
char *
usbd_get_string(usbd_device_handle dev, int si, char *buf)
{
int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
usb_string_descriptor_t us;
char *s;
int i, n;
u_int16_t c;
usbd_status err;
int size;
if (si == 0)
return (0);
if (dev->quirks->uq_flags & UQ_NO_STRINGS)
return (0);
if (dev->langid == USBD_NOLANG) {
/* Set up default language */
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, &size);
if (err)
return (0);
s = buf;
n = size / 2 - 1;
for (i = 0; i < n; i++) {
c = UGETW(us.bString[i]);
/* Convert from Unicode, handle buggy strings. */
if ((c & 0xff00) == 0)
*s++ = c;
else if ((c & 0x00ff) == 0 && swap)
*s++ = c >> 8;
else
*s++ = '?';
}
*s++ = 0;
return (buf);
}
Static void
usbd_trim_spaces(char *p)
{
@ -272,9 +227,15 @@ usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev)
}
if (usedev) {
vendor = usbd_get_string(dev, udd->iManufacturer, v);
if (usbd_get_string(dev, udd->iManufacturer, v))
vendor = NULL;
else
vendor = v;
usbd_trim_spaces(vendor);
product = usbd_get_string(dev, udd->iProduct, p);
if (usbd_get_string(dev, udd->iProduct, p))
product = NULL;
else
product = p;
usbd_trim_spaces(product);
if (vendor && !*vendor)
vendor = NULL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $ */
/* $NetBSD: usbdi.c,v 1.106 2004/10/24 12:52:40 augustss Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/kernel.h>
#include <sys/device.h>
#elif defined(__FreeBSD__)
#include <sys/module.h>
@ -62,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/usb_quirks.h>
#if defined(__FreeBSD__)
#include "usb_if.h"
@ -1154,6 +1156,86 @@ usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
return (NULL);
}
void
usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
{
const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
iter->cur = (const uByte *)cd;
iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
}
const usb_descriptor_t *
usb_desc_iter_next(usbd_desc_iter_t *iter)
{
const usb_descriptor_t *desc;
if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
if (iter->cur != iter->end)
printf("usb_desc_iter_next: bad descriptor\n");
return NULL;
}
desc = (const usb_descriptor_t *)iter->cur;
if (desc->bLength == 0) {
printf("usb_desc_iter_next: descriptor length = 0\n");
return NULL;
}
iter->cur += desc->bLength;
if (iter->cur > iter->end) {
printf("usb_desc_iter_next: descriptor length too large\n");
return NULL;
}
return desc;
}
usbd_status
usbd_get_string(usbd_device_handle dev, int si, char *buf)
{
int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
usb_string_descriptor_t us;
char *s;
int i, n;
u_int16_t c;
usbd_status err;
int size;
buf[0] = '\0';
if (si == 0)
return (USBD_INVAL);
if (dev->quirks->uq_flags & UQ_NO_STRINGS)
return (USBD_STALLED);
if (dev->langid == USBD_NOLANG) {
/* Set up default language */
err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
&size);
if (err || size < 4) {
DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n"));
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, &size);
if (err)
return (err);
s = buf;
n = size / 2 - 1;
for (i = 0; i < n; i++) {
c = UGETW(us.bString[i]);
/* Convert from Unicode, handle buggy strings. */
if ((c & 0xff00) == 0)
*s++ = c;
else if ((c & 0x00ff) == 0 && swap)
*s++ = c >> 8;
else
*s++ = '?';
}
*s++ = 0;
return (USBD_NORMAL_COMPLETION);
}
#if defined(__FreeBSD__)
int
usbd_driver_load(module_t mod, int what, void *arg)

View File

@ -170,6 +170,16 @@ usbd_status usbd_reload_device_desc(usbd_device_handle);
int usbd_ratecheck(struct timeval *last);
usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf);
/* An iterator for descriptors. */
typedef struct {
const uByte *cur;
const uByte *end;
} usbd_desc_iter_t;
void usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter);
const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *iter);
/*
* The usb_task structs form a queue of things to run in the USB event
* thread. Normally this is just device discovery when a connect/disconnect

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi_util.c,v 1.36 2001/11/13 06:24:57 lukem Exp $ */
/* $NetBSD: usbdi_util.c,v 1.42 2004/12/03 08:53:40 augustss Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -222,6 +222,25 @@ usbd_set_port_feature(usbd_device_handle dev, int port, int sel)
return (usbd_do_request(dev, &req, 0));
}
usbd_status
usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report)
{
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n",
iface, id->bInterfaceNumber));
if (id == NULL)
return (USBD_IOERROR);
usbd_interface2device_handle(iface, &dev);
req.bmRequestType = UT_READ_CLASS_INTERFACE;
req.bRequest = UR_GET_PROTOCOL;
USETW(req.wValue, 0);
USETW(req.wIndex, id->bInterfaceNumber);
USETW(req.wLength, 1);
return (usbd_do_request(dev, &req, report));
}
usbd_status
usbd_set_protocol(usbd_interface_handle iface, int report)
@ -291,8 +310,8 @@ usbd_get_report(usbd_interface_handle iface, int type, int id, void *data,
usbd_device_handle dev;
usb_device_request_t req;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
if (id == 0)
DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
if (ifd == NULL)
return (USBD_IOERROR);
usbd_interface2device_handle(iface, &dev);
req.bmRequestType = UT_READ_CLASS_INTERFACE;
@ -346,7 +365,7 @@ usbd_get_hid_descriptor(usbd_interface_handle ifc)
char *p, *end;
if (idesc == NULL)
return (0);
return (NULL);
usbd_interface2device_handle(ifc, &dev);
cdesc = usbd_get_config_descriptor(dev);
@ -360,7 +379,7 @@ usbd_get_hid_descriptor(usbd_interface_handle ifc)
if (hd->bDescriptorType == UDESC_INTERFACE)
break;
}
return (0);
return (NULL);
}
usbd_status
@ -432,7 +451,7 @@ usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
splx(s);
return (err);
}
error = tsleep(xfer, PZERO | PCATCH, lbl, 0);
error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
splx(s);
if (error) {
DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
@ -506,3 +525,20 @@ usb_detach_wakeup(device_ptr_t dv)
DPRINTF(("usb_detach_wakeup: for %s\n", USBDEVPTRNAME(dv)));
wakeup(dv);
}
const usb_descriptor_t *
usb_find_desc(usbd_device_handle dev, int type, int subtype)
{
usbd_desc_iter_t iter;
const usb_descriptor_t *desc;
usb_desc_iter_init(dev, &iter);
for (;;) {
desc = usb_desc_iter_next(&iter);
if (!desc || (desc->bDescriptorType == type &&
(subtype == USBD_SUBTYPE_ANY ||
subtype == desc->bDescriptorSubtype)))
break;
}
return desc;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi_util.h,v 1.29 2004/06/23 02:30:52 mycroft Exp $ */
/* $NetBSD: usbdi_util.h,v 1.31 2004/12/03 08:53:40 augustss Exp $ */
/* $FreeBSD$ */
/*-
@ -54,6 +54,7 @@ usbd_status usbd_set_port_feature(usbd_device_handle dev, int, int);
usbd_status usbd_clear_port_feature(usbd_device_handle, int, int);
usbd_status usbd_get_device_status(usbd_device_handle, usb_status_t *);
usbd_status usbd_get_hub_status(usbd_device_handle, usb_hub_status_t *);
usbd_status usbd_get_protocol(usbd_interface_handle dev, u_int8_t *report);
usbd_status usbd_set_protocol(usbd_interface_handle dev, int report);
usbd_status usbd_get_report_descriptor(usbd_device_handle dev, int ifcno,
int size, void *d);
@ -88,3 +89,7 @@ usbd_status usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
void usb_detach_wait(device_ptr_t);
void usb_detach_wakeup(device_ptr_t);
const usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type,
int subtype);
#define USBD_SUBTYPE_ANY (~0)