hub alternate interface wip
Change-Id: Ib35bcbe76e7bbf444ba9260d3def60e38317c68d
diff --git a/system/dev/usb/dwc2/dwc2.c b/system/dev/usb/dwc2/dwc2.c
index 3c095bf..db8c4b9 100644
--- a/system/dev/usb/dwc2/dwc2.c
+++ b/system/dev/usb/dwc2/dwc2.c
@@ -603,7 +603,7 @@
return ZX_OK;
}
-zx_status_t dwc_config_hub(void* ctx, uint32_t device_id, usb_speed_t speed,
+zx_status_t dwc_config_hub(void* ctx, uint32_t device_id, usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor) {
// Not sure if DWC controller has to take any specific action here.
return ZX_OK;
diff --git a/system/dev/usb/usb-bus/usb-bus.c b/system/dev/usb/usb-bus/usb-bus.c
index 6ecc772..87b5277 100644
--- a/system/dev/usb/usb-bus/usb-bus.c
+++ b/system/dev/usb/usb-bus/usb-bus.c
@@ -59,13 +59,13 @@
};
static zx_status_t bus_configure_hub(void* ctx, zx_device_t* hub_device, usb_speed_t speed,
- usb_hub_descriptor_t* descriptor) {
+ bool multi_tt, usb_hub_descriptor_t* descriptor) {
usb_bus_t* bus = ctx;
uint32_t hub_id;
if (usb_interface_get_device_id(hub_device, &hub_id) != ZX_OK) {
return ZX_ERR_INTERNAL;
}
- return usb_hci_configure_hub(&bus->hci, hub_id, speed, descriptor);
+ return usb_hci_configure_hub(&bus->hci, hub_id, speed, multi_tt, descriptor);
}
static zx_status_t bus_device_added(void* ctx, zx_device_t* hub_device, int port, usb_speed_t speed) {
diff --git a/system/dev/usb/usb-bus/usb-device.c b/system/dev/usb/usb-bus/usb-device.c
index 7235ff6..1b6b750 100644
--- a/system/dev/usb/usb-bus/usb-device.c
+++ b/system/dev/usb/usb-bus/usb-device.c
@@ -39,11 +39,13 @@
zx_status_t usb_device_set_interface(usb_device_t* device, uint8_t interface_id,
uint8_t alt_setting) {
+printf("usb_device_set_interface 1\n");
mtx_lock(&device->interface_mutex);
usb_interface_t* intf;
list_for_every_entry(&device->children, intf, usb_interface_t, node) {
if (usb_interface_contains_interface(intf, interface_id)) {
mtx_unlock(&device->interface_mutex);
+printf("usb_device_set_interface 4\n");
return usb_interface_set_alt_setting(intf, interface_id, alt_setting);
}
}
diff --git a/system/dev/usb/usb-bus/usb-interface.c b/system/dev/usb/usb-bus/usb-interface.c
index e9860cd..d5e33ff 100644
--- a/system/dev/usb/usb-bus/usb-interface.c
+++ b/system/dev/usb/usb-bus/usb-interface.c
@@ -164,6 +164,8 @@
bool interface_endpoints[USB_MAX_EPS] = {};
zx_status_t status = ZX_OK;
+printf("usb_interface_configure_endpoints 1\n");
+
// iterate through our descriptors to find which endpoints should be active
usb_descriptor_header_t* header = intf->descriptor;
usb_descriptor_header_t* end = (usb_descriptor_header_t*)((void*)header + intf->descriptor_length);
@@ -171,6 +173,7 @@
bool enable_endpoints = false;
while (header < end) {
+printf("top of loop\n");
if (header->bDescriptorType == USB_DT_INTERFACE) {
usb_interface_descriptor_t* intf_desc = (usb_interface_descriptor_t*)header;
cur_interface = intf_desc->bInterfaceNumber;
@@ -186,14 +189,18 @@
header = NEXT_DESCRIPTOR(header);
}
+printf("usb_interface_configure_endpoints 2\n");
+
// update to new set of endpoints
// FIXME - how do we recover if we fail half way through processing the endpoints?
for (size_t i = 0; i < countof(new_endpoints); i++) {
+printf("for loop %zu\n", i);
if (interface_endpoints[i]) {
usb_endpoint_descriptor_t* old_ep = intf->active_endpoints[i];
usb_endpoint_descriptor_t* new_ep = new_endpoints[i];
if (old_ep != new_ep) {
if (old_ep) {
+printf("enable false\n");
zx_status_t ret = usb_interface_enable_endpoint(intf, old_ep, NULL, false);
if (ret != ZX_OK) status = ret;
}
@@ -205,6 +212,7 @@
&& next->bDescriptorType == USB_DT_SS_EP_COMPANION) {
ss_comp_desc = (usb_ss_ep_comp_descriptor_t *)next;
}
+printf("enable true\n");
zx_status_t ret = usb_interface_enable_endpoint(intf, new_ep, ss_comp_desc, true);
if (ret != ZX_OK) status = ret;
}
@@ -212,6 +220,7 @@
}
}
}
+printf("usb_interface_configure_endpoints 99\n");
return status;
}
@@ -321,6 +330,13 @@
return intf->device_id;
}
+static zx_status_t usb_interface_get_device_descriptor(void* ctx,
+ usb_device_descriptor_t* out_desc) {
+ usb_interface_t* intf = ctx;
+ memcpy(out_desc, &intf->device->device_desc, sizeof(intf->device->device_desc));
+ return ZX_OK;
+}
+
static zx_status_t usb_interface_get_descriptor_list(void* ctx, void** out_descriptors,
size_t* out_length) {
usb_interface_t* intf = ctx;
@@ -634,9 +650,11 @@
zx_status_t usb_interface_set_alt_setting(usb_interface_t* intf, uint8_t interface_id,
uint8_t alt_setting) {
+printf("usb_interface_set_alt_setting 1\n");
zx_status_t status = usb_interface_configure_endpoints(intf, interface_id, alt_setting);
if (status != ZX_OK) return status;
+printf("usb_interface_set_alt_setting 2\n");
return usb_device_control(intf->device,
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE,
USB_REQ_SET_INTERFACE, alt_setting, interface_id, NULL, 0);
diff --git a/system/dev/usb/usb-hub/usb-hub.c b/system/dev/usb/usb-hub/usb-hub.c
index fcaff7b..33bae73 100644
--- a/system/dev/usb/usb-hub/usb-hub.c
+++ b/system/dev/usb/usb-hub/usb-hub.c
@@ -304,7 +304,31 @@
goto fail;
}
- result = usb_bus_configure_hub(&hub->bus, hub->usb_device, hub->hub_speed, &desc);
+ bool multi_tt = false;
+ if (hub->hub_speed == USB_SPEED_HIGH) {
+printf("USB_SPEED_HIGH\n");
+ usb_device_descriptor_t device_desc;
+ size_t out_length;
+ zx_status_t status = usb_get_descriptor(&hub->usb, USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ USB_DT_DEVICE, 0, &device_desc, sizeof(device_desc),
+ ZX_TIME_INFINITE, &out_length);
+printf("status %d out_length %zu bDeviceProtocol %u\n", status, out_length, device_desc.bDeviceProtocol);
+
+
+
+ if (status == ZX_OK && out_length == sizeof(device_desc) &&
+ device_desc.bDeviceProtocol == USB_HUB_MULTI_TT) {
+printf("call usb_set_interface\n");
+ status = usb_set_interface(&hub->usb, 0, 1);
+printf("set interface got %d\n", status);
+ if (status == ZX_OK) {
+printf("multi_TT\n");
+ multi_tt = true;
+ }
+ }
+ }
+
+ result = usb_bus_configure_hub(&hub->bus, hub->usb_device, hub->hub_speed, multi_tt, &desc);
if (result < 0) {
zxlogf(ERROR, "configure_hub failed: %d\n", result);
goto fail;
diff --git a/system/dev/usb/usb-virtual-bus/usb-virtual-host.c b/system/dev/usb/usb-virtual-bus/usb-virtual-host.c
index d484a20..3b32287 100644
--- a/system/dev/usb/usb-virtual-bus/usb-virtual-host.c
+++ b/system/dev/usb/usb-virtual-bus/usb-virtual-host.c
@@ -70,7 +70,7 @@
return 0;
}
-zx_status_t virt_host_config_hub(void* ctx, uint32_t device_id, usb_speed_t speed,
+zx_status_t virt_host_config_hub(void* ctx, uint32_t device_id, usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor) {
return ZX_OK;
}
diff --git a/system/dev/usb/xhci/usb-xhci.c b/system/dev/usb/xhci/usb-xhci.c
index 8181ca4..485c7d6 100644
--- a/system/dev/usb/xhci/usb-xhci.c
+++ b/system/dev/usb/xhci/usb-xhci.c
@@ -87,10 +87,10 @@
return xhci_get_current_frame(xhci);
}
-static zx_status_t xhci_config_hub(void* ctx, uint32_t device_id, usb_speed_t speed,
+static zx_status_t xhci_config_hub(void* ctx, uint32_t device_id, usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor) {
xhci_t* xhci = ctx;
- return xhci_configure_hub(xhci, device_id, speed, descriptor);
+ return xhci_configure_hub(xhci, device_id, speed, multi_tt, descriptor);
}
static zx_status_t xhci_hub_device_added(void* ctx, uint32_t hub_address, int port,
diff --git a/system/dev/usb/xhci/xhci-device-manager.c b/system/dev/usb/xhci/xhci-device-manager.c
index 924e2af..7957f13 100644
--- a/system/dev/usb/xhci/xhci-device-manager.c
+++ b/system/dev/usb/xhci/xhci-device-manager.c
@@ -131,12 +131,12 @@
io_buffer_cache_op(&slot->buffer, ZX_VMO_OP_CACHE_INVALIDATE, 0,
sizeof(xhci_slot_context_t));
#endif
- mtt = XHCI_GET_BITS32(&slot->sc->sc0, SLOT_CTX_MTT_START, SLOT_CTX_MTT_BITS);
+ mtt = XHCI_READ32(&slot->sc->sc0) & SLOT_CTX_MTT;
tt_hub_slot_id = hub_address;
tt_port_number = port;
}
}
- XHCI_SET_BITS32(&sc->sc0, SLOT_CTX_MTT_START, SLOT_CTX_MTT_BITS, mtt);
+ XHCI_SET32(&sc->sc0, SLOT_CTX_MTT, mtt);
XHCI_SET_BITS32(&sc->sc2, SLOT_CTX_TT_HUB_SLOT_ID_START, SLOT_CTX_TT_HUB_SLOT_ID_BITS,
tt_hub_slot_id);
XHCI_SET_BITS32(&sc->sc2, SLOT_CTX_TT_PORT_NUM_START, SLOT_CTX_TT_PORT_NUM_BITS,
@@ -677,7 +677,7 @@
return status;
}
-zx_status_t xhci_configure_hub(xhci_t* xhci, uint32_t slot_id, usb_speed_t speed,
+zx_status_t xhci_configure_hub(xhci_t* xhci, uint32_t slot_id, usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor) {
zxlogf(TRACE, "xhci_configure_hub slot_id: %d speed: %d\n", slot_id, speed);
if (xhci_is_root_hub(xhci, slot_id)) {
@@ -704,7 +704,12 @@
#if XHCI_USE_CACHE_OPS
io_buffer_cache_op(&slot->buffer, ZX_VMO_OP_CACHE_INVALIDATE, 0, sizeof(xhci_slot_context_t));
#endif
- XHCI_WRITE32(&sc->sc0, XHCI_READ32(&slot->sc->sc0) | SLOT_CTX_HUB);
+ uint32_t sc0 = XHCI_READ32(&slot->sc->sc1);
+ sc0 |= SLOT_CTX_HUB;
+ if (multi_tt) {
+ sc0 |= SLOT_CTX_MTT;
+ }
+ XHCI_WRITE32(&sc->sc0, sc0);
XHCI_WRITE32(&sc->sc1, XHCI_READ32(&slot->sc->sc1));
XHCI_WRITE32(&sc->sc2, XHCI_READ32(&slot->sc->sc2));
diff --git a/system/dev/usb/xhci/xhci-device-manager.h b/system/dev/usb/xhci/xhci-device-manager.h
index e7a191b..7102a9b 100644
--- a/system/dev/usb/xhci/xhci-device-manager.h
+++ b/system/dev/usb/xhci/xhci-device-manager.h
@@ -18,5 +18,5 @@
zx_status_t xhci_queue_start_root_hubs(xhci_t* xhci);
zx_status_t xhci_enable_endpoint(xhci_t* xhci, uint32_t slot_id, usb_endpoint_descriptor_t* ep_desc,
usb_ss_ep_comp_descriptor_t* ss_comp_desc, bool enable);
-zx_status_t xhci_configure_hub(xhci_t* xhci, uint32_t slot_id, usb_speed_t speed,
+zx_status_t xhci_configure_hub(xhci_t* xhci, uint32_t slot_id, usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor);
diff --git a/system/dev/usb/xhci/xhci-hw.h b/system/dev/usb/xhci/xhci-hw.h
index 59f9ae6..dccf9ef 100644
--- a/system/dev/usb/xhci/xhci-hw.h
+++ b/system/dev/usb/xhci/xhci-hw.h
@@ -470,8 +470,7 @@
#define SLOT_CTX_ROUTE_STRING_BITS 20
#define SLOT_CTX_SPEED_START 20
#define SLOT_CTX_SPEED_BITS 4
-#define SLOT_CTX_MTT_START 25
-#define SLOT_CTX_MTT_BITS 1
+#define SLOT_CTX_MTT (1 << 25)
#define SLOT_CTX_HUB (1 << 26)
#define SLOT_CTX_CONTEXT_ENTRIES_START 27
#define SLOT_CTX_CONTEXT_ENTRIES_BITS 5
diff --git a/system/public/zircon/hw/usb-hub.h b/system/public/zircon/hw/usb-hub.h
index 2a8b395..c524d48 100644
--- a/system/public/zircon/hw/usb-hub.h
+++ b/system/public/zircon/hw/usb-hub.h
@@ -12,6 +12,12 @@
#define USB_RECIP_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
#define USB_RECIP_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+// Hub device protocols
+#define USB_HUB_NO_TT 0
+#define USB_HUB_SINGLE_TT 1
+#define USB_HUB_MULTI_TT 2
+#define USB_HUB_SUPERSPEED 3
+
// Hub requests
#define USB_HUB_SET_DEPTH 12
diff --git a/system/ulib/ddk/include/ddk/protocol/usb-bus.h b/system/ulib/ddk/include/ddk/protocol/usb-bus.h
index 52291e9..658fdee 100644
--- a/system/ulib/ddk/include/ddk/protocol/usb-bus.h
+++ b/system/ulib/ddk/include/ddk/protocol/usb-bus.h
@@ -16,7 +16,7 @@
typedef struct usb_bus_protocol_ops {
// Hub support
zx_status_t (*configure_hub)(void* ctx, zx_device_t* hub_device, usb_speed_t speed,
- usb_hub_descriptor_t* descriptor);
+ bool multi_tt, usb_hub_descriptor_t* descriptor);
zx_status_t (*hub_device_added)(void* ctx, zx_device_t* hub_device, int port,
usb_speed_t speed);
zx_status_t (*hub_device_removed)(void* ctx, zx_device_t* hub_device, int port);
@@ -28,9 +28,9 @@
} usb_bus_protocol_t;
static inline zx_status_t usb_bus_configure_hub(usb_bus_protocol_t* bus, zx_device_t* hub_device,
- usb_speed_t speed,
+ usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor) {
- return bus->ops->configure_hub(bus->ctx, hub_device, speed, descriptor);
+ return bus->ops->configure_hub(bus->ctx, hub_device, speed, multi_tt, descriptor);
}
static inline zx_status_t usb_bus_hub_device_added(usb_bus_protocol_t* bus, zx_device_t* hub_device,
diff --git a/system/ulib/ddk/include/ddk/protocol/usb-hci.h b/system/ulib/ddk/include/ddk/protocol/usb-hci.h
index 9b3745d..31469a3 100644
--- a/system/ulib/ddk/include/ddk/protocol/usb-hci.h
+++ b/system/ulib/ddk/include/ddk/protocol/usb-hci.h
@@ -29,7 +29,7 @@
uint64_t (*get_current_frame)(void* ctx);
// Hub support
- zx_status_t (*configure_hub)(void* ctx, uint32_t device_id, usb_speed_t speed,
+ zx_status_t (*configure_hub)(void* ctx, uint32_t device_id, usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor);
zx_status_t (*hub_device_added)(void* ctx, uint32_t device_id, int port, usb_speed_t speed);
zx_status_t (*hub_device_removed)(void* ctx, uint32_t device_id, int port);
@@ -69,9 +69,9 @@
}
static inline zx_status_t usb_hci_configure_hub(usb_hci_protocol_t* hci, uint32_t device_id,
- usb_speed_t speed,
+ usb_speed_t speed, bool multi_tt,
usb_hub_descriptor_t* descriptor) {
- return hci->ops->configure_hub(hci->ctx, device_id, speed, descriptor);
+ return hci->ops->configure_hub(hci->ctx, device_id, speed, multi_tt, descriptor);
}
static inline zx_status_t usb_hci_hub_device_added(usb_hci_protocol_t* hci, uint32_t device_id,
diff --git a/system/ulib/ddk/include/ddk/protocol/usb.h b/system/ulib/ddk/include/ddk/protocol/usb.h
index 80f80af..e3fcdb0 100644
--- a/system/ulib/ddk/include/ddk/protocol/usb.h
+++ b/system/ulib/ddk/include/ddk/protocol/usb.h
@@ -24,6 +24,7 @@
zx_status_t (*reset_endpoint)(void* ctx, uint8_t ep_address);
size_t (*get_max_transfer_size)(void* ctx, uint8_t ep_address);
uint32_t (*get_device_id)(void* ctx);
+ zx_status_t (*get_device_descriptor)(void* ctx, usb_device_descriptor_t* out_desc);
zx_status_t (*get_descriptor_list)(void* ctx, void** out_descriptors, size_t* out_length);
zx_status_t (*get_additional_descriptor_list)(void* ctx, void** out_descriptors,
size_t* out_length);
@@ -104,6 +105,11 @@
return usb->ops->get_device_id(usb->ctx);
}
+static inline zx_status_t usb_get_device_descriptor(usb_protocol_t* usb,
+ usb_device_descriptor_t* out_desc) {
+ return usb->ops->get_device_descriptor(usb->ctx, out_desc);
+}
+
// returns the USB descriptors for the USB device or interface
// the returned value is de-allocated with free()
static inline zx_status_t usb_get_descriptor_list(usb_protocol_t* usb, void** out_descriptors,