Changeset 0e7380f in mainline


Ignore:
Timestamp:
2018-01-13T00:18:28Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
94e9c29
Parents:
fb154e13
Message:

xhci: wait for conditions to hold in a systematic way

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

Legend:

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

    rfb154e13 r0e7380f  
    387387                return EOK;
    388388
    389         /* TODO: Test this with USB3-aware BIOS */
     389        if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_CNR), 0))
     390                return ETIMEOUT;
     391
    390392        usb_log_debug2("LEGSUP: bios: %x, os: %x", hc->legsup->sem_bios, hc->legsup->sem_os);
    391         XHCI_REG_WR(hc->legsup, XHCI_LEGSUP_SEM_OS, 1);
     393        XHCI_REG_SET(hc->legsup, XHCI_LEGSUP_SEM_OS, 1);
    392394        for (int i = 0; i <= (XHCI_LEGSUP_BIOS_TIMEOUT_US / XHCI_LEGSUP_POLLING_DELAY_1MS); i++) {
    393395                usb_log_debug2("LEGSUP: elapsed: %i ms, bios: %x, os: %x", i,
     
    395397                        XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_OS));
    396398                if (XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_BIOS) == 0) {
    397                         assert(XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_OS) == 1);
    398                         return EOK;
     399                        return XHCI_REG_RD(hc->legsup, XHCI_LEGSUP_SEM_OS) == 1 ? EOK : EIO;
    399400                }
    400401                async_usleep(XHCI_LEGSUP_POLLING_DELAY_1MS);
     
    410411static int hc_reset(xhci_hc_t *hc)
    411412{
     413        if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_CNR), 0))
     414                return ETIMEOUT;
     415
    412416        /* Stop the HC: set R/S to 0 */
    413417        XHCI_REG_CLR(hc->op_regs, XHCI_OP_RS, 1);
    414418
    415         /* Wait 16 ms until the HC is halted */
    416         async_usleep(16000);
    417         assert(XHCI_REG_RD(hc->op_regs, XHCI_OP_HCH));
     419        /* Wait until the HC is halted - it shall take at most 16 ms */
     420        if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_HCH), XHCI_REG_MASK(XHCI_OP_HCH)))
     421                return ETIMEOUT;
    418422
    419423        /* Reset */
     
    421425
    422426        /* Wait until the reset is complete */
    423         while (XHCI_REG_RD(hc->op_regs, XHCI_OP_HCRST))
    424                 async_usleep(1000);
     427        if (xhci_reg_wait(&hc->op_regs->usbcmd, XHCI_REG_MASK(XHCI_OP_HCRST), 0))
     428                return ETIMEOUT;
    425429
    426430        return EOK;
     
    437441                return err;
    438442
    439         // FIXME: Waiting forever.
    440         while (XHCI_REG_RD(hc->op_regs, XHCI_OP_CNR))
    441                 async_usleep(1000);
     443        if (xhci_reg_wait(&hc->op_regs->usbsts, XHCI_REG_MASK(XHCI_OP_CNR), 0))
     444                return ETIMEOUT;
    442445
    443446        uint64_t dcbaaptr = hc->dcbaa_dma.phys;
  • uspace/drv/bus/usb/xhci/hw_struct/common.h

    rfb154e13 r0e7380f  
    4242#include <assert.h>
    4343#include <bitops.h>
     44#include <byteorder.h>
    4445#include <ddi.h>
    45 #include <byteorder.h>
     46#include <errno.h>
    4647
    4748#define host2xhci(size, val) host2uint##size##_t_le((val))
     
    8889}
    8990
     91static inline int xhci_reg_wait(xhci_dword_t *reg, uint32_t mask, uint32_t expected)
     92{
     93        mask = host2xhci(32, mask);
     94        expected = host2xhci(32, expected);
     95
     96        unsigned retries = 100;
     97        uint32_t value = *reg & mask;
     98
     99        for (; retries > 0 && value != expected; --retries) {
     100                async_usleep(10000);
     101                value = *reg & mask;
     102        }
     103
     104        return value == expected ? EOK : ETIMEOUT;
     105}
     106
    90107#endif
    91108
Note: See TracChangeset for help on using the changeset viewer.