Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a75f9cbc in mainline


Ignore:
Timestamp:
2018-01-12T18:49:16Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
e7e99bf
Parents:
129e6f1
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-12 18:49:04)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-12 18:49:16)
Message:

xhci: try to identify custom speeds

Location:
uspace/drv/bus/usb/xhci
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/debug.c

    r129e6f1 ra75f9cbc  
    313313                        ports_from = XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF);
    314314                        ports_to = ports_from + XHCI_REG_RD(ec, XHCI_EC_SP_CP_COUNT) - 1;
    315                         usb_log_debug("\tProtocol %.4s%u.%u, ports %u-%u", name.str,
     315                        unsigned psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC);
     316
     317                        usb_log_debug("\tProtocol %.4s%u.%u, ports %u-%u, %u protocol speeds", name.str,
    316318                            XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR),
    317319                            XHCI_REG_RD(ec, XHCI_EC_SP_MINOR),
    318                             ports_from, ports_to);
    319 
    320                         unsigned psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC);
     320                            ports_from, ports_to, psic);
     321
    321322                        for (unsigned i = 0; i < psic; i++)
    322323                                xhci_dump_psi(xhci_extcap_psi(ec, i));
  • uspace/drv/bus/usb/xhci/hc.c

    r129e6f1 ra75f9cbc  
    5959        .tx_bps = PSI_TO_BPS(psie, psim) \
    6060}
    61 static const xhci_port_speed_t ps_default_full  = PORT_SPEED(FULL, 2, 2, 12);
    62 static const xhci_port_speed_t ps_default_low   = PORT_SPEED(LOW, 2, 1, 1500);
    63 static const xhci_port_speed_t ps_default_high  = PORT_SPEED(HIGH, 2, 2, 480);
    64 static const xhci_port_speed_t ps_default_super = PORT_SPEED(SUPER, 3, 3, 5);
     61
     62static const xhci_port_speed_t default_psiv_to_port_speed [] = {
     63        [1] = PORT_SPEED(FULL, 2, 2, 12),
     64        [2] = PORT_SPEED(LOW, 2, 1, 1500),
     65        [3] = PORT_SPEED(HIGH, 2, 2, 480),
     66        [4] = PORT_SPEED(SUPER, 3, 3, 5),
     67};
     68
     69static const unsigned usb_speed_to_psiv [] = {
     70        [USB_SPEED_FULL] = 1,
     71        [USB_SPEED_LOW] = 2,
     72        [USB_SPEED_HIGH] = 3,
     73        [USB_SPEED_SUPER] = 4,
     74};
    6575
    6676/**
     
    105115
    106116                                if (major == 2) {
    107                                         speeds[1] = ps_default_full;
    108                                         speeds[2] = ps_default_low;
    109                                         speeds[3] = ps_default_high;
    110 
    111                                         hc->speed_to_psiv[USB_SPEED_FULL] = 1;
    112                                         hc->speed_to_psiv[USB_SPEED_LOW] = 2;
    113                                         hc->speed_to_psiv[USB_SPEED_HIGH] = 3;
     117                                        speeds[1] = default_psiv_to_port_speed[1];
     118                                        speeds[2] = default_psiv_to_port_speed[2];
     119                                        speeds[3] = default_psiv_to_port_speed[3];
    114120                                } else if (major == 3) {
    115                                         speeds[4] = ps_default_super;
    116                                         hc->speed_to_psiv[USB_SPEED_SUPER] = 4;
     121                                        speeds[4] = default_psiv_to_port_speed[4];
    117122                                } else {
    118123                                        return EINVAL;
     
    127132                                        unsigned psie = XHCI_REG_RD(psi, XHCI_PSI_PSIE);
    128133                                        unsigned psim = XHCI_REG_RD(psi, XHCI_PSI_PSIM);
    129 
     134                                        uint64_t bps = PSI_TO_BPS(psie, psim);
     135
     136                                        /*
     137                                         * Speed is not implied, but using one of default PSIV. This is
     138                                         * not clearly stated in xHCI spec. There is a clear intention
     139                                         * to allow xHCI to specify its own speed parameters, but
     140                                         * throughout the document, they used fixed values for e.g.
     141                                         * High-speed (3), without stating the controller shall have
     142                                         * implied default speeds - and for instance Intel controllers
     143                                         * do not. So let's check if the values match and if so, accept
     144                                         * the implied USB speed too.
     145                                         *
     146                                         * The main reason we need this is the usb_speed to have
     147                                         * mapping also for devices connected to hubs.
     148                                         */
     149                                        if (psiv < ARRAY_SIZE(default_psiv_to_port_speed)
     150                                           && default_psiv_to_port_speed[psiv].major == major
     151                                           && default_psiv_to_port_speed[psiv].minor == minor
     152                                           && default_psiv_to_port_speed[psiv].rx_bps == bps
     153                                           && default_psiv_to_port_speed[psiv].tx_bps == bps) {
     154                                                speeds[psiv] = default_psiv_to_port_speed[psiv];
     155                                                usb_log_debug2("Assumed default %s speed of USB %u.", usb_str_speed(speeds[psiv].usb_speed), major);
     156                                                continue;
     157                                        }
     158
     159                                        // Custom speed
    130160                                        speeds[psiv].major = major;
    131161                                        speeds[psiv].minor = minor;
    132162                                        str_ncpy(speeds[psiv].name, 4, name.str, 4);
    133163                                        speeds[psiv].usb_speed = USB_SPEED_MAX;
    134 
    135                                         uint64_t bps = PSI_TO_BPS(psie, psim);
    136164
    137165                                        if (sim == XHCI_PSI_PLT_SYMM || sim == XHCI_PSI_PLT_RX)
     
    684712        /* Although we have the precise PSIV value on devices of tier 1,
    685713         * we have to rely on reverse mapping on others. */
    686         if (!hc->speed_to_psiv[dev->base.speed]) {
    687                 usb_log_error("Device reported an USB speed that cannot be mapped to HC port speed.");
     714        if (!usb_speed_to_psiv[dev->base.speed]) {
     715                usb_log_error("Device reported an USB speed (%s) that cannot be mapped to HC port speed.", usb_str_speed(dev->base.speed));
    688716                return EINVAL;
    689717        }
     
    707735        XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1);
    708736        XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, dev->route_str);
    709         XHCI_SLOT_SPEED_SET(ictx->slot_ctx, hc->speed_to_psiv[dev->base.speed]);
     737        XHCI_SLOT_SPEED_SET(ictx->slot_ctx, usb_speed_to_psiv[dev->base.speed]);
    710738
    711739        /* In a very specific case, we have to set also these. But before that,
  • uspace/drv/bus/usb/xhci/hc.h

    r129e6f1 ra75f9cbc  
    9292        /** Port speed mapping */
    9393        xhci_port_speed_t speeds [16];
    94         uint8_t speed_to_psiv [USB_SPEED_MAX];
    9594} xhci_hc_t;
    9695
Note: See TracChangeset for help on using the changeset viewer.