tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
xhci patch 20150606
Hello,
Here are xhci patches of some fixes, comments, and
adding functions.
---
nh-usb_subr-ss.diff
+ Use macro to check speed.
Forgotten in privious patch.
nh-xhcireg-maxintr.diff
+ Fix num of Max Interrupters to 11 bits width.
nh-uhub-wrc.diff
+ Simplify treatment of WRC condition and add comments.
nh-usb-kernhist.diff
+ Add missing KERNHIST_LINK_STATIC(usbhist).
nh-bos.diff
+ Read Binary Object Store descriptor and store to ud_bdesc.
nh-usbdi_util.diff
+ Add usbd_set_port_u[12]_timeout().
nh-ssp.diff
+ Add usbd_get_port_status_ext().
+ Add some definitions for super speed plus.
+ Update comments.
--
t-hash
--- usb_subr.c.0 2015-05-29 00:35:08.000000000 +0900
+++ usb_subr.c.1 2015-05-29 00:30:56.000000000 +0900
@@ -1428,10 +1428,11 @@ usbd_fill_deviceinfo(struct usbd_device
else if (s & UPS_SUSPEND)
err = USB_PORT_SUSPENDED;
/*
- * UPS_PORT_POWER_SS is available only
- * if SS, otherwise it means UPS_LOW_SPEED.
+ * Note: UPS_PORT_POWER_SS is available only
+ * on 3.x, and UPS_PORT_POWER is available
+ * only on 2.0 or 1.1.
*/
- else if (dev->ud_speed == USB_SPEED_SUPER &&
+ else if (USB_IS_SS(dev->ud_speed) &&
(s & UPS_PORT_POWER_SS))
err = USB_PORT_POWERED;
else if (s & UPS_PORT_POWER)
--- src/sys/dev/usb/xhcireg.h.orig 2015-04-07 01:29:02.000000000 +0900
+++ src/sys/dev/usb/xhcireg.h 2015-06-02 11:28:19.000000000 +0900
@@ -51,7 +51,7 @@
#define XHCI_HCIVERSION_1_0 0x0100 /* xHCI version 1.0 */
#define XHCI_HCSPARAMS1 0x04 /* RO structual parameters 1 */
#define XHCI_HCS1_MAXSLOTS(x) ((x) & 0xFF)
-#define XHCI_HCS1_MAXINTRS(x) (((x) >> 8) & 0x3FF)
+#define XHCI_HCS1_MAXINTRS(x) (((x) >> 8) & 0x7FF)
#define XHCI_HCS1_MAXPORTS(x) (((x) >> 24) & 0xFF)
#define XHCI_HCSPARAMS2 0x08 /* RO structual parameters 2 */
#define XHCI_HCS2_IST(x) ((x) & 0xF)
--- src/sys/dev/usb/uhub.c.orig 2015-05-28 15:54:12.000000000 +0900
+++ src/sys/dev/usb/uhub.c 2015-06-03 11:57:34.000000000 +0900
@@ -586,11 +586,17 @@ uhub_explore(struct usbd_device *dev)
port);
}
}
- int is_wrc = 0;
- if (change & UPS_C_PORT_RESET)
+ if (change & UPS_C_PORT_RESET) {
usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
+ }
if (change & UPS_C_BH_PORT_RESET) {
- is_wrc = 1;
+ /*
+ * some xHCs set WarmResetChange instead of CSC
+ * when port is reset.
+ */
+ if ((status & UPS_CURRENT_CONNECT_STATUS) != 0) {
+ change |= UPS_C_CONNECT_STATUS;
+ }
usbd_clear_port_feature(dev, port,
UHF_C_BH_PORT_RESET);
}
@@ -603,9 +609,7 @@ uhub_explore(struct usbd_device *dev)
/* XXX handle overcurrent and resume events! */
- /* xHCI sets WRC instead of CSC when port is reset */
- if (!reconnect && !(change & UPS_C_CONNECT_STATUS) &&
- !(is_wrc && (status & UPS_CURRENT_CONNECT_STATUS))) {
+ if (!reconnect && !(change & UPS_C_CONNECT_STATUS)) {
/* No status change, just do recursive explore. */
if (up->up_dev != NULL && up->up_dev->ud_hub != NULL)
up->up_dev->ud_hub->uh_explore(up->up_dev);
--- src/sys/dev/usb/usb.c.orig 2015-05-29 02:06:38.000000000 +0900
+++ src/sys/dev/usb/usb.c 2015-05-31 15:45:07.000000000 +0900
@@ -276,6 +276,8 @@ usb_once_init(void)
struct usb_taskq *taskq;
int i;
+ KERNHIST_LINK_STATIC(usbhist);
+
selinit(&usb_selevent);
mutex_init(&usb_event_lock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&usb_event_cv, "usbrea");
--- src/sys/dev/usb/usb_subr.c.orig 2015-05-29 00:30:56.000000000 +0900
+++ src/sys/dev/usb/usb_subr.c 2015-05-29 00:29:27.000000000 +0900
@@ -529,6 +529,7 @@ usbd_status
usbd_set_config_index(struct usbd_device *dev, int index, int msg)
{
usb_config_descriptor_t cd, *cdp;
+ usb_bos_descriptor_t bd, *bdp = NULL;
usbd_status err;
int i, ifcidx, nifc, len, selfpowered, power;
@@ -552,8 +553,12 @@ usbd_set_config_index(struct usbd_device
usbd_free_iface_data(dev, ifcidx);
kmem_free(dev->ud_ifaces, nifc * sizeof(struct usbd_interface));
kmem_free(dev->ud_cdesc, UGETW(dev->ud_cdesc->wTotalLength));
+ if (dev->ud_bdesc != NULL)
+ kmem_free(dev->ud_bdesc,
+ UGETW(dev->ud_bdesc->wTotalLength));
dev->ud_ifaces = NULL;
dev->ud_cdesc = NULL;
+ dev->ud_bdesc = NULL;
dev->ud_config = USB_UNCONFIG_NO;
}
@@ -596,6 +601,41 @@ usbd_set_config_index(struct usbd_device
goto bad;
}
+ if (USB_IS_SS(dev->ud_speed)) {
+ int blen;
+
+ /* get short bos desc */
+ err = usbd_get_bos_desc(dev, index, &bd);
+ if (err) {
+ DPRINTF("get_bos_desc=%d", err, 0, 0, 0);
+ goto bad;
+ }
+ blen = UGETW(bd.wTotalLength);
+ bdp = kmem_alloc(blen, KM_SLEEP);
+ if (bdp == NULL) {
+ err = USBD_NOMEM;
+ goto bad;
+ }
+
+ /* Get the full desc */
+ for (i = 0; i < 3; i++) {
+ err = usbd_get_desc(dev, UDESC_BOS, index, blen, bdp);
+ if (!err)
+ break;
+ usbd_delay_ms(dev, 200);
+ }
+ if (err) {
+ DPRINTF("get_bos_desc=%d", err, 0, 0, 0);
+ goto bad;
+ }
+ if (bdp->bDescriptorType != UDESC_BOS) {
+ DPRINTF("bad desc %d", bdp->bDescriptorType, 0, 0, 0);
+ err = USBD_INVAL;
+ goto bad;
+ }
+ }
+ dev->ud_bdesc = bdp;
+
/*
* Figure out if the device is self or bus powered.
*/
@@ -687,6 +727,10 @@ usbd_set_config_index(struct usbd_device
bad:
kmem_free(cdp, len);
+ if (bdp != NULL) {
+ kmem_free(bdp, UGETW(bdp->wTotalLength));
+ dev->ud_bdesc = NULL;
+ }
return err;
}
@@ -1532,6 +1576,8 @@ usb_free_device(struct usbd_device *dev)
}
if (dev->ud_cdesc != NULL)
kmem_free(dev->ud_cdesc, UGETW(dev->ud_cdesc->wTotalLength));
+ if (dev->ud_bdesc != NULL)
+ kmem_free(dev->ud_bdesc, UGETW(dev->ud_bdesc->wTotalLength));
if (dev->ud_subdevlen > 0) {
kmem_free(dev->ud_subdevs,
dev->ud_subdevlen * sizeof(device_t));
--- src/sys/dev/usb/usbdivar.h.orig 2015-03-27 15:05:02.000000000 +0900
+++ src/sys/dev/usb/usbdivar.h 2015-05-28 10:16:46.000000000 +0900
@@ -195,6 +195,7 @@ struct usbd_device {
struct usbd_interface *ud_ifaces; /* array of all interfaces */
usb_device_descriptor_t ud_ddesc; /* device descriptor */
usb_config_descriptor_t *ud_cdesc; /* full config descr */
+ usb_bos_descriptor_t *ud_bdesc; /* full BOS descr */
const struct usbd_quirks *ud_quirks;/* device quirks, always set */
struct usbd_hub *ud_hub; /* only if this is a hub */
int ud_subdevlen; /* array length of following */
--- src/sys/dev/usb/usbdi_util.c.orig 2015-04-07 01:29:02.000000000 +0900
+++ src/sys/dev/usb/usbdi_util.c 2015-06-02 11:36:48.000000000 +0900
@@ -243,6 +243,32 @@ usbd_set_port_feature(struct usbd_device
}
usbd_status
+usbd_set_port_u1_timeout(struct usbd_device *dev, int port, int timeout)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_WRITE_CLASS_OTHER;
+ req.bRequest = UR_SET_FEATURE;
+ USETW(req.wValue, UHF_PORT_U1_TIMEOUT);
+ USETW2(req.wIndex, timeout, port);
+ USETW(req.wLength, 0);
+ return usbd_do_request(dev, &req, 0);
+}
+
+usbd_status
+usbd_set_port_u2_timeout(struct usbd_device *dev, int port, int timeout)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_WRITE_CLASS_OTHER;
+ req.bRequest = UR_SET_FEATURE;
+ USETW(req.wValue, UHF_PORT_U2_TIMEOUT);
+ USETW2(req.wIndex, timeout, port);
+ USETW(req.wLength, 0);
+ return usbd_do_request(dev, &req, 0);
+}
+
+usbd_status
usbd_get_protocol(struct usbd_interface *iface, uint8_t *report)
{
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
--- src/sys/dev/usb/usbdi_util.h.orig 2015-04-07 01:29:02.000000000 +0900
+++ src/sys/dev/usb/usbdi_util.h 2015-06-02 11:34:43.000000000 +0900
@@ -52,6 +52,8 @@ usbd_status usbd_set_hub_feature(struct
usbd_status usbd_clear_hub_feature(struct usbd_device *, int);
usbd_status usbd_set_port_feature(struct usbd_device *, int, int);
usbd_status usbd_clear_port_feature(struct usbd_device *, int, int);
+usbd_status usbd_set_port_u1_timeout(struct usbd_device *, int, int);
+usbd_status usbd_set_port_u2_timeout(struct usbd_device *, int, int);
usbd_status usbd_get_device_status(struct usbd_device *, usb_status_t *);
usbd_status usbd_get_hub_status(struct usbd_device *, usb_hub_status_t *);
usbd_status usbd_get_protocol(struct usbd_interface *, uint8_t *);
--- src/sys/dev/usb/usbdi_util.c.orig 2015-04-07 01:29:02.000000000 +0900
+++ src/sys/dev/usb/usbdi_util.c 2015-06-02 11:36:48.000000000 +0900
@@ -190,6 +190,21 @@ usbd_get_port_status(struct usbd_device
return usbd_do_request(dev, &req, ps);
}
+/* USB 3.1 10.16.2.6, 10.16.2.6.3 */
+usbd_status
+usbd_get_port_status_ext(struct usbd_device *dev, int port,
+ usb_port_status_ext_t *pse)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_READ_CLASS_OTHER;
+ req.bRequest = UR_GET_STATUS;
+ USETW2(req.wValue, 0, UR_PST_EXT_PORT_STATUS);
+ USETW(req.wIndex, port);
+ USETW(req.wLength, sizeof *pse);
+ return (usbd_do_request(dev, &req, pse));
+}
+
usbd_status
usbd_clear_hub_feature(struct usbd_device *dev, int sel)
{
--- src/sys/dev/usb/usbdi_util.h.orig 2015-06-02 11:34:43.000000000 +0900
+++ src/sys/dev/usb/usbdi_util.h 2015-06-06 11:17:21.000000000 +0900
@@ -48,6 +48,8 @@ usbd_status usbd_get_device_desc(struct
usbd_status usbd_set_address(struct usbd_device *, int);
usbd_status usbd_get_port_status(struct usbd_device *,
int, usb_port_status_t *);
+usbd_status usbd_get_port_status_ext(struct usbd_device *,
+ int, usb_port_status_ext_t *);
usbd_status usbd_set_hub_feature(struct usbd_device *, int);
usbd_status usbd_clear_hub_feature(struct usbd_device *, int);
usbd_status usbd_set_port_feature(struct usbd_device *, int, int);
--- src/sys/dev/usb/usb.h.orig 2015-05-28 15:54:12.000000000 +0900
+++ src/sys/dev/usb/usb.h 2015-06-02 11:38:22.000000000 +0900
@@ -395,15 +395,25 @@ typedef struct {
} UPACKED usb_devcap_platform_descriptor_t;
#define USB_DEVCAP_PLATFORM_DESCRIPTOR_SIZE 20
+/* usb 3.1 ch 9.6.2.4 */
typedef struct {
uByte bLength;
uByte bDescriptorType;
uByte bDevCapabilityType;
uByte bReserved;
uDWord bmAttributes;
+#define XHCI_DEVCAP_SSP_SSAC(x) __SHIFTOUT(x, __BITS(4,0))
+#define XHCI_DEVCAP_SSP_SSIC(x) __SHIFTOUT(x, __BITS(8,5))
uWord wFunctionalitySupport;
+#define XHCI_DEVCAP_SSP_SSID(x) __SHIFTOUT(x, __BITS(3,0))
+#define XHCI_DEVCAP_SSP_MIN_RXLANE_COUNT(x) __SHIFTOUT(x, __BITS(11,8))
+#define XHCI_DEVCAP_SSP_MIN_TXLANE_COUNT(x) __SHIFTOUT(x, __BITS(15,12))
uWord wReserved;
uDWord bmSublinkSpeedAttr[0];
+#define XHCI_DEVCAP_SSP_LSE(x) __SHIFTOUT(x, __BITS(5,4))
+#define XHCI_DEVCAP_SSP_ST(x) __SHIFTOUT(x, __BITS(7,6))
+#define XHCI_DEVCAP_SSP_LP(x) __SHIFTOUT(x, __BITS(15,14))
+#define XHCI_DEVCAP_SSP_LSM(x) __SHIFTOUT(x, __BITS(31,16))
} UPACKED usb_devcap_ssp_descriptor_t;
#define USB_DEVCAP_SSP_DESCRIPTOR_SIZE 12 /* variable length */
@@ -424,6 +434,10 @@ typedef struct {
#define UR_STOP_TT 0x0b
#define UR_SET_HUB_DEPTH 0x0c
#define UR_GET_PORT_ERR_COUNT 0x0d
+/* Port Status Type for GET_STATUS, USB 3.1 10.16.2.6 and Table 10-12 */
+#define UR_PST_PORT_STATUS 0
+#define UR_PST_PD_STATUS 1
+#define UR_PST_EXT_PORT_STATUS 2
/*
* Hub features from USB 2.0 spec, table 11-17 and updated by the
@@ -597,6 +611,14 @@ typedef struct {
#define UPS_C_PORT_CONFIG_ERROR 0x0080
} UPACKED usb_port_status_t;
+/* 10.16.2.6 */
+/* Valid when port status type is UR_PST_EXT_PORT_STATUS. */
+typedef struct {
+ uWord wPortStatus;
+ uWord wPortChange;
+ uDWord dwExtPortStatus;
+} UPACKED usb_port_status_ext_t;
+
/* Device class codes */
#define UDCLASS_IN_INTERFACE 0x00
#define UDCLASS_COMM 0x02
@@ -854,7 +876,8 @@ struct usb_device_info {
#define USB_SPEED_FULL 2
#define USB_SPEED_HIGH 3
#define USB_SPEED_SUPER 4
-#define USB_IS_SS(X) ((X) == USB_SPEED_SUPER)
+#define USB_SPEED_SUPER_PLUS 5
+#define USB_IS_SS(X) ((X) == USB_SPEED_SUPER || (X) == USB_SPEED_SUPER_PLUS)
int udi_power; /* power consumption in mA, 0 if selfpowered */
int udi_nports;
char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
--- src/sys/dev/usb/xhci.c.orig 2015-05-28 16:07:49.000000000 +0900
+++ src/sys/dev/usb/xhci.c 2015-06-06 14:01:46.000000000 +0900
@@ -1005,11 +1006,14 @@ xhci_intr1(struct xhci_softc * const sc)
* port_status speed
* definition: UPS_*_SPEED in usb.h
* They are used in usb_port_status_t and valid only for USB 2.0.
- * Speed value is 0 for Super Speed or more.
+ * Speed value is always 0 for Super Speed or more, and dwExtPortStatus
+ * of usb_port_status_ext_t indicates port speed.
* Note that some 3.0 values overlap with 2.0 values.
* (e.g. 0x200 means UPS_POER_POWER_SS in SS and
* means UPS_LOW_SPEED in HS.)
- * port status sent from hub also uses these values.
+ * port status returned from hub also uses these values.
+ * On NetBSD UPS_OTHER_SPEED indicates port speed is super speed
+ * or more.
* xspeed:
* definition: Protocol Speed ID (PSI) (xHCI 1.1 7.2.1)
* They are used in only slot context and PORTSC reg of xhci.
Home |
Main Index |
Thread Index |
Old Index