aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/drivers/usb/xhci_devconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/drivers/usb/xhci_devconf.c')
-rw-r--r--payloads/libpayload/drivers/usb/xhci_devconf.c82
1 files changed, 35 insertions, 47 deletions
diff --git a/payloads/libpayload/drivers/usb/xhci_devconf.c b/payloads/libpayload/drivers/usb/xhci_devconf.c
index 2b1de3bf9e..5699499f26 100644
--- a/payloads/libpayload/drivers/usb/xhci_devconf.c
+++ b/payloads/libpayload/drivers/usb/xhci_devconf.c
@@ -75,27 +75,6 @@ xhci_get_tt(xhci_t *const xhci, const usb_speed speed,
return *tt != 0;
}
-static long
-xhci_get_mps0(usbdev_t *const dev, const int speed)
-{
- u8 buf[8];
- dev_req_t dr = {
- .bmRequestType = gen_bmRequestType(
- device_to_host, standard_type, dev_recp),
- .data_dir = device_to_host,
- .bRequest = GET_DESCRIPTOR,
- .wValue = (1 << 8),
- .wIndex = 0,
- .wLength = 8,
- };
- if (dev->controller->control(dev, IN, sizeof(dr), &dr, 8, buf)) {
- xhci_debug("Failed to read MPS0\n");
- return COMMUNICATION_ERROR;
- } else {
- return usb_decode_mps0(speed, buf[7]);
- }
-}
-
static inputctx_t *
xhci_make_inputctx(const size_t ctxsize)
{
@@ -120,14 +99,14 @@ xhci_make_inputctx(const size_t ctxsize)
return ic;
}
-int
+usbdev_t *
xhci_set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr)
{
xhci_t *const xhci = XHCI_INST(controller);
const size_t ctxsize = CTXSIZE(xhci);
devinfo_t *di = NULL;
-
- int i, ret = -1;
+ usbdev_t *dev = NULL;
+ int i;
inputctx_t *const ic = xhci_make_inputctx(ctxsize);
transfer_ring_t *const tr = malloc(sizeof(*tr));
@@ -193,33 +172,46 @@ xhci_set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr)
}
mdelay(SET_ADDRESS_MDELAY);
- init_device_entry(controller, slot_id);
- controller->devices[slot_id]->address = slot_id;
+ dev = init_device_entry(controller, slot_id);
+ if (!dev)
+ goto _disable_return;
+
+ dev->address = slot_id;
+ dev->hub = hubaddr;
+ dev->port = hubport;
+ dev->speed = speed;
+ dev->endpoints[0].dev = dev;
+ dev->endpoints[0].endpoint = 0;
+ dev->endpoints[0].toggle = 0;
+ dev->endpoints[0].direction = SETUP;
+ dev->endpoints[0].type = CONTROL;
- const long mps0 = xhci_get_mps0(
- controller->devices[slot_id], speed);
- if (mps0 < 0) {
+ u8 buf[8];
+ if (get_descriptor(dev, gen_bmRequestType(device_to_host, standard_type,
+ dev_recp), DT_DEV, 0, buf, sizeof(buf)) != sizeof(buf)) {
+ usb_debug("first get_descriptor(DT_DEV) failed\n");
goto _disable_return;
- } else if (mps0 != 8) {
+ }
+
+ dev->endpoints[0].maxpacketsize = usb_decode_mps0(speed, buf[7]);
+ if (dev->endpoints[0].maxpacketsize != 8) {
memset((void *)ic->dev.ep0, 0x00, ctxsize);
*ic->add = (1 << 1); /* EP0 Context */
- EC_SET(MPS, ic->dev.ep0, mps0);
+ EC_SET(MPS, ic->dev.ep0, dev->endpoints[0].maxpacketsize);
cc = xhci_cmd_evaluate_context(xhci, slot_id, ic);
if (cc != CC_SUCCESS) {
xhci_debug("Context evaluation failed: %d\n", cc);
goto _disable_return;
- } else {
- xhci_debug("Set MPS0 to %dB\n", mps0);
}
}
- ret = slot_id;
goto _free_ic_return;
_disable_return:
xhci_cmd_disable_slot(xhci, slot_id);
xhci->dcbaa[slot_id] = 0;
usb_detach_device(controller, slot_id);
+ dev = NULL;
_free_return:
if (tr)
free((void *)tr->ring);
@@ -231,30 +223,27 @@ _free_ic_return:
if (ic)
free(ic->raw);
free(ic);
- return ret;
+ return dev;
}
static int
xhci_finish_hub_config(usbdev_t *const dev, inputctx_t *const ic)
{
- hub_descriptor_t *const descriptor = (hub_descriptor_t *)
- get_descriptor(
- dev,
- gen_bmRequestType(device_to_host, class_type, dev_recp),
- 0x29, 0, 0);
- if (!descriptor) {
+ hub_descriptor_t desc;
+
+ if (get_descriptor(dev, gen_bmRequestType(device_to_host, class_type,
+ dev_recp), 0x29, 0, &desc, sizeof(desc)) != sizeof(desc)) {
xhci_debug("Failed to fetch hub descriptor\n");
return COMMUNICATION_ERROR;
}
SC_SET(HUB, ic->dev.slot, 1);
SC_SET(MTT, ic->dev.slot, 0); /* No support for Multi-TT */
- SC_SET(NPORTS, ic->dev.slot, descriptor->bNbrPorts);
+ SC_SET(NPORTS, ic->dev.slot, desc.bNbrPorts);
if (dev->speed == HIGH_SPEED)
SC_SET(TTT, ic->dev.slot,
- (descriptor->wHubCharacteristics >> 5) & 0x0003);
+ (desc.wHubCharacteristics >> 5) & 0x0003);
- free(descriptor);
return 0;
}
@@ -349,7 +338,7 @@ xhci_finish_device_config(usbdev_t *const dev)
ic->dev.slot->f2 = di->ctx.slot->f2;
ic->dev.slot->f3 = di->ctx.slot->f3;
- if (((device_descriptor_t *)dev->descriptor)->bDeviceClass == 0x09) {
+ if (dev->descriptor->bDeviceClass == 0x09 && dev->speed < SUPER_SPEED) {
ret = xhci_finish_hub_config(dev, ic);
if (ret)
goto _free_return;
@@ -363,8 +352,7 @@ xhci_finish_device_config(usbdev_t *const dev)
xhci_dump_inputctx(ic);
- const int config_id = ((configuration_descriptor_t *)
- dev->configuration)->bConfigurationValue;
+ const int config_id = dev->configuration->bConfigurationValue;
xhci_debug("config_id: %d\n", config_id);
const int cc =
xhci_cmd_configure_endpoint(xhci, dev->address, config_id, ic);