diff options
| author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2020-12-15 12:05:07 +0000 |
|---|---|---|
| committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2020-12-15 12:05:07 +0000 |
| commit | b8b3f4fdc31fb21b54f5f3104e318e1c342cb2d9 (patch) | |
| tree | 1f5c014aeb2abb8fcb9e40518cbfe85b257e92fd /sys/dev/usb | |
| parent | 6da5df470099fc55f20b03ef364af730e7be4ffe (diff) | |
Notes
Diffstat (limited to 'sys/dev/usb')
| -rw-r--r-- | sys/dev/usb/usb_device.c | 6 | ||||
| -rw-r--r-- | sys/dev/usb/usb_request.c | 15 | ||||
| -rw-r--r-- | sys/dev/usb/usbdi.h | 4 |
3 files changed, 21 insertions, 4 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 3499516c91e6c..cc679611a832b 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -2,7 +2,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2008-2020 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 @@ -905,6 +905,10 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd) /* update current number of endpoints */ ep_curr = ep_max; } + /* update number of alternate settings, if any */ + if (iface_index == USB_IFACE_INDEX_ANY) + iface->num_altsetting = ips.iface_index_alt + 1; + /* check for init */ if (do_init) { /* setup the USB interface structure */ diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index 36c6a28124c59..a1781f3589a44 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -4,7 +4,7 @@ * * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. * Copyright (c) 1998 Lennart Augustsson. All rights reserved. - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2008-2020 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 @@ -1436,6 +1436,7 @@ usbd_req_set_alt_interface_no(struct usb_device *udev, struct mtx *mtx, { struct usb_interface *iface = usbd_get_iface(udev, iface_index); struct usb_device_request req; + usb_error_t err; if ((iface == NULL) || (iface->idesc == NULL)) return (USB_ERR_INVAL); @@ -1447,7 +1448,17 @@ usbd_req_set_alt_interface_no(struct usb_device *udev, struct mtx *mtx, req.wIndex[0] = iface->idesc->bInterfaceNumber; req.wIndex[1] = 0; USETW(req.wLength, 0); - return (usbd_do_request(udev, mtx, &req, 0)); + err = usbd_do_request(udev, mtx, &req, 0); + if (err == USB_ERR_STALLED && iface->num_altsetting == 1) { + /* + * The USB specification chapter 9.4.10 says that USB + * devices having only one alternate setting are + * allowed to STALL this request. Ignore this failure. + */ + err = 0; + DPRINTF("Setting default alternate number failed. (ignored)\n"); + } + return (err); } /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index a8ba5408f5c4d..1b3b4af5f7170 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -174,6 +174,9 @@ struct usb_endpoint { struct usb_interface { struct usb_interface_descriptor *idesc; device_t subdev; + /* Total number of alternate settings, from 1 to 256 */ + uint16_t num_altsetting; + /* Current alternate interface index, from 0 to 255 */ uint8_t alt_index; uint8_t parent_iface_index; @@ -183,7 +186,6 @@ struct usb_interface { struct usb_device *linux_udev; void *bsd_priv_sc; /* device specific information */ char *pnpinfo; /* additional PnP-info for this interface */ - uint8_t num_altsetting; /* number of alternate settings */ uint8_t bsd_iface_index; }; |
