Changeset bfc5c9dd in mainline


Ignore:
Timestamp:
2012-02-23T20:42:30Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
815b244a
Parents:
ffcc5776
Message:

ohci: Use more generic approach to access registers(and convert endian).

Make hc initialization work by design, not by accident. (Fixes random hang on startup).
Queues still disabled.

Location:
uspace/drv/bus/usb/ohci
Files:
4 edited

Legend:

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

    rffcc5776 rbfc5c9dd  
    242242        switch (ep->transfer_type) {
    243243        case USB_TRANSFER_CONTROL:
    244                 instance->registers->control &= ~C_CLE;
     244                OHCI_CLR(instance->registers->control, C_CLE);
    245245                endpoint_list_add_ep(list, ohci_ep);
    246                 instance->registers->control_current = 0;
    247                 instance->registers->control |= C_CLE;
     246                OHCI_WR(instance->registers->control_current, 0);
     247                OHCI_SET(instance->registers->control, C_CLE);
    248248                break;
    249249        case USB_TRANSFER_BULK:
    250                 instance->registers->control &= ~C_BLE;
     250                OHCI_CLR(instance->registers->control, C_BLE);
    251251                endpoint_list_add_ep(list, ohci_ep);
    252                 instance->registers->control |= C_BLE;
     252                OHCI_WR(instance->registers->bulk_current, 0);
     253                OHCI_SET(instance->registers->control, C_BLE);
    253254                break;
    254255        case USB_TRANSFER_ISOCHRONOUS:
    255256        case USB_TRANSFER_INTERRUPT:
    256                 instance->registers->control &= (~C_PLE & ~C_IE);
     257                OHCI_CLR(instance->registers->control, C_PLE | C_IE);
    257258                endpoint_list_add_ep(list, ohci_ep);
    258                 instance->registers->control |= C_PLE | C_IE;
     259                OHCI_SET(instance->registers->control, C_PLE | C_IE);
    259260                break;
    260261        }
     
    274275        switch (ep->transfer_type) {
    275276        case USB_TRANSFER_CONTROL:
    276                 instance->registers->control &= ~C_CLE;
     277                OHCI_CLR(instance->registers->control, C_CLE);
    277278                endpoint_list_remove_ep(list, ohci_ep);
    278                 instance->registers->control_current = 0;
    279                 instance->registers->control |= C_CLE;
     279                OHCI_WR(instance->registers->control_current, 0);
     280                OHCI_SET(instance->registers->control, C_CLE);
    280281                break;
    281282        case USB_TRANSFER_BULK:
    282                 instance->registers->control &= ~C_BLE;
     283                OHCI_CLR(instance->registers->control, C_BLE);
    283284                endpoint_list_remove_ep(list, ohci_ep);
    284                 instance->registers->control |= C_BLE;
     285                OHCI_WR(instance->registers->bulk_current, 0);
     286                OHCI_SET(instance->registers->control, C_BLE);
    285287                break;
    286288        case USB_TRANSFER_ISOCHRONOUS:
    287289        case USB_TRANSFER_INTERRUPT:
    288                 instance->registers->control &= (~C_PLE & ~C_IE);
     290                OHCI_CLR(instance->registers->control, C_PLE | C_IE);
    289291                endpoint_list_remove_ep(list, ohci_ep);
    290                 instance->registers->control |= C_PLE | C_IE;
     292                OHCI_SET(instance->registers->control, C_PLE | C_IE);
    291293                break;
    292294        default:
     
    325327        {
    326328        case USB_TRANSFER_CONTROL:
    327                 instance->registers->command_status |= CS_CLF;
     329                OHCI_SET(instance->registers->command_status, CS_CLF);
    328330                break;
    329331        case USB_TRANSFER_BULK:
    330                 instance->registers->command_status |= CS_BLF;
     332                OHCI_SET(instance->registers->command_status, CS_BLF);
    331333                break;
    332334        default:
     
    344346void hc_interrupt(hc_t *instance, uint32_t status)
    345347{
     348        status = ohci_reg2host(status);
    346349        assert(instance);
    347350        if ((status & ~I_SF) == 0) /* ignore sof status */
     
    354357                fibril_mutex_lock(&instance->guard);
    355358                usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
    356                     instance->registers->hcca,
     359                    OHCI_RD(instance->registers->hcca),
    357360                    (void *) addr_to_phys(instance->hcca));
    358361                usb_log_debug2("Periodic current: %#" PRIx32 ".\n",
    359                     instance->registers->periodic_current);
     362                    OHCI_RD(instance->registers->periodic_current));
    360363
    361364                link_t *current = list_first(&instance->pending_batches);
     
    412415
    413416        usb_log_debug("Requesting OHCI control.\n");
    414         if (instance->registers->revision & R_LEGACY_FLAG) {
     417        if (OHCI_RD(instance->registers->revision) & R_LEGACY_FLAG) {
    415418                /* Turn off legacy emulation, it should be enough to zero
    416419                 * the lowest bit, but it caused problems. Thus clear all
     
    421424                (uint32_t*)((char*)instance->registers + LEGACY_REGS_OFFSET);
    422425                usb_log_debug("OHCI legacy register %p: %x.\n",
    423                     ohci_emulation_reg, *ohci_emulation_reg);
     426                    ohci_emulation_reg, OHCI_RD(*ohci_emulation_reg));
    424427                /* Zero everything but A20State */
    425                 *ohci_emulation_reg &= 0x100;
     428                OHCI_CLR(*ohci_emulation_reg, ~0x100);
    426429                usb_log_debug(
    427430                    "OHCI legacy register (should be 0 or 0x100) %p: %x.\n",
    428                     ohci_emulation_reg, *ohci_emulation_reg);
     431                    ohci_emulation_reg, OHCI_RD(*ohci_emulation_reg));
    429432        }
    430433
    431434        /* Interrupt routing enabled => smm driver is active */
    432         if (instance->registers->control & C_IR) {
     435        if (OHCI_RD(instance->registers->control) & C_IR) {
    433436                usb_log_debug("SMM driver: request ownership change.\n");
    434                 instance->registers->command_status |= CS_OCR;
     437                OHCI_SET(instance->registers->command_status, CS_OCR);
    435438                /* Hope that SMM actually knows its stuff or we can hang here */
    436                 while (instance->registers->control & C_IR) {
     439                while (OHCI_RD(instance->registers->control & C_IR)) {
    437440                        async_usleep(1000);
    438441                }
     
    442445                return;
    443446        }
    444 
    445447        const unsigned hc_status = C_HCFS_GET(instance->registers->control);
    446448        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
     
    451453                        return;
    452454                }
    453                 /* HC is suspended assert resume for 20ms, */
     455                /* HC is suspended assert resume for 20ms */
    454456                C_HCFS_SET(instance->registers->control, C_HCFS_RESUME);
    455457                async_usleep(20000);
     
    475477
    476478        /* Save contents of fm_interval register */
    477         const uint32_t fm_interval = instance->registers->fm_interval;
     479        const uint32_t fm_interval = OHCI_RD(instance->registers->fm_interval);
    478480        usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval);
    479481
     
    481483        usb_log_debug2("HC reset.\n");
    482484        size_t time = 0;
    483         instance->registers->command_status = CS_HCR;
    484         while (instance->registers->command_status & CS_HCR) {
     485        OHCI_WR(instance->registers->command_status, CS_HCR);
     486        while (OHCI_RD(instance->registers->command_status) & CS_HCR) {
    485487                async_usleep(10);
    486488                time += 10;
     
    489491
    490492        /* Restore fm_interval */
    491         instance->registers->fm_interval = fm_interval;
    492         assert((instance->registers->command_status & CS_HCR) == 0);
     493        OHCI_WR(instance->registers->fm_interval, fm_interval);
     494        assert((OHCI_RD(instance->registers->command_status) & CS_HCR) == 0);
    493495
    494496        /* hc is now in suspend state */
    495497        usb_log_debug2("HC should be in suspend state(%x).\n",
    496             instance->registers->control);
     498            OHCI_RD(instance->registers->control));
    497499
    498500        /* Use HCCA */
    499         instance->registers->hcca = addr_to_phys(instance->hcca);
     501        OHCI_WR(instance->registers->hcca, addr_to_phys(instance->hcca));
    500502
    501503        /* Use queues */
    502         instance->registers->bulk_head =
    503             instance->lists[USB_TRANSFER_BULK].list_head_pa;
     504        OHCI_WR(instance->registers->bulk_head,
     505            instance->lists[USB_TRANSFER_BULK].list_head_pa);
    504506        usb_log_debug2("Bulk HEAD set to: %p (%#" PRIx32 ").\n",
    505507            instance->lists[USB_TRANSFER_BULK].list_head,
    506508            instance->lists[USB_TRANSFER_BULK].list_head_pa);
    507509
    508         instance->registers->control_head =
    509             instance->lists[USB_TRANSFER_CONTROL].list_head_pa;
     510        OHCI_WR(instance->registers->control_head,
     511            instance->lists[USB_TRANSFER_CONTROL].list_head_pa);
    510512        usb_log_debug2("Control HEAD set to: %p (%#" PRIx32 ").\n",
    511513            instance->lists[USB_TRANSFER_CONTROL].list_head,
     
    513515
    514516        /* Enable queues */
    515 //      instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
    516 //      usb_log_debug2("All queues enabled(%x).\n",
    517 //          instance->registers->control);
     517//      OHCI_SET(instance->registers->control, (C_PLE | C_IE | C_CLE | C_BLE));
     518//      usb_log_debug("Queues enabled(%x).\n",
     519//          OHCI_RD(instance->registers->control));
    518520
    519521        /* Enable interrupts */
    520         instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
    521         usb_log_debug2("Enabled interrupts: %x.\n",
    522             instance->registers->interrupt_enable);
    523         instance->registers->interrupt_enable = I_MI;
     522        OHCI_WR(instance->registers->interrupt_enable, OHCI_USED_INTERRUPTS);
     523        usb_log_debug("Enabled interrupts: %x.\n",
     524            OHCI_RD(instance->registers->interrupt_enable));
     525        OHCI_WR(instance->registers->interrupt_enable, I_MI);
    524526
    525527        /* Set periodic start to 90% */
    526         const uint32_t frame_length = FMI_FL_GET(fm_interval);
    527         PS_SET(instance->registers->periodic_start, (frame_length / 10) * 9);
     528        const uint32_t frame_length =
     529            (fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK;
     530        OHCI_WR(instance->registers->periodic_start,
     531            ((frame_length / 10) * 9) & PS_MASK << PS_SHIFT);
    528532        usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n",
    529             PS_GET(instance->registers->periodic_start),
    530             PS_GET(instance->registers->periodic_start), frame_length);
    531 
     533            OHCI_RD(instance->registers->periodic_start),
     534            OHCI_RD(instance->registers->periodic_start), frame_length);
    532535        C_HCFS_SET(instance->registers->control, C_HCFS_OPERATIONAL);
    533536        usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n",
    534             instance->registers->control);
     537            OHCI_RD(instance->registers->control));
    535538}
    536539/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/ohci/main.c

    rffcc5776 rbfc5c9dd  
    8383int main(int argc, char *argv[])
    8484{
    85         sleep(5);
    8685        usb_log_enable(USB_LOG_LEVEL_DEBUG2, NAME);
    8786        return ddf_driver_main(&ohci_driver);
  • uspace/drv/bus/usb/ohci/ohci_regs.h

    rffcc5776 rbfc5c9dd  
    4242#define ohci_reg2host(value) uint32_t_le2host(value)
    4343
     44#define OHCI_WR(reg, val) reg = host2uint32_t_le(val)
     45#define OHCI_RD(reg) uint32_t_le2host(reg)
     46#define OHCI_SET(reg, val) reg |= host2uint32_t_le(val)
     47#define OHCI_CLR(reg, val) reg &= host2uint32_t_le(val)
     48
     49
    4450#define LEGACY_REGS_OFFSET 0x100
    4551
     
    4753typedef struct ohci_regs {
    4854        const ioport32_t revision;
    49 #define R_REVISION_(reg) (ohci_reg2host(reg) & 0x3f)
    50 #define R_LEGACY_FLAG   host2ohci_reg(0x80)
     55#define R_REVISION_MASK (0x3f)
     56#define R_LEGACY_FLAG   (0x80)
    5157
    5258        ioport32_t control;
     
    5662#define C_CBSR_1_3  (0x2)
    5763#define C_CBSR_1_4  (0x3)
    58 #define C_CBSR_GET(reg) (ohci_reg2host(reg) & 0x3)
    59 #define C_CBSR_SET(reg, value) \
    60 do { \
    61     reg = (reg & host2ohci_reg(~0x3) | host2ohci_reg(value & 0x3)) \
    62 } while (0)
    63 
    64 #define C_PLE host2ohci_reg(1 << 2)   /* Periodic list enable */
    65 #define C_IE  host2ohci_reg(1 << 3)   /* Isochronous enable */
    66 #define C_CLE host2ohci_reg(1 << 4)   /* Control list enable */
    67 #define C_BLE host2ohci_reg(1 << 5)   /* Bulk list enable */
     64#define C_CBSR_MASK (0x3)
     65#define C_CBSR_SHIFT 0
     66
     67#define C_PLE (1 << 2)   /* Periodic list enable */
     68#define C_IE  (1 << 3)   /* Isochronous enable */
     69#define C_CLE (1 << 4)   /* Control list enable */
     70#define C_BLE (1 << 5)   /* Bulk list enable */
    6871
    6972/* Host controller functional state */
     
    7275#define C_HCFS_OPERATIONAL (0x2)
    7376#define C_HCFS_SUSPEND     (0x3)
    74 #define C_HCFS_GET(reg) ((ohci_reg2host(reg) >> 6) & 0x3)
     77#define C_HCFS_GET(reg) ((OHCI_RD(reg) >> 6) & 0x3)
    7578#define C_HCFS_SET(reg, value) \
    7679do { \
    77     reg = (reg & host2ohci_reg(~(0x3 << 6))) \
    78         | host2ohci_reg((value & 0x3) << 6); \
     80        uint32_t r = OHCI_RD(reg); \
     81        r &= ~(0x3 << 6); \
     82        r |= (value & 0x3) << 6; \
     83        OHCI_WR(reg, r); \
    7984} while (0)
    8085
    81 #define C_IR  host2ohci_reg(1 << 8)  /* Interrupt routing, make sure it's 0 */
    82 #define C_RWC host2ohci_reg(1 << 9)  /* Remote wakeup connected, host specific */
    83 #define C_RWE host2ohci_reg(1 << 10)  /* Remote wakeup enable */
     86#define C_IR  (1 << 8)  /* Interrupt routing, make sure it's 0 */
     87#define C_RWC (1 << 9)  /* Remote wakeup connected, host specific */
     88#define C_RWE (1 << 10)  /* Remote wakeup enable */
    8489
    8590        ioport32_t command_status;
    86 #define CS_HCR host2ohci_reg(1 << 0)   /* Host controller reset */
    87 #define CS_CLF host2ohci_reg(1 << 1)   /* Control list filled */
    88 #define CS_BLF host2ohci_reg(1 << 2)   /* Bulk list filled */
    89 #define CS_OCR host2ohci_reg(1 << 3)   /* Ownership change request */
     91#define CS_HCR (1 << 0)   /* Host controller reset */
     92#define CS_CLF (1 << 1)   /* Control list filled */
     93#define CS_BLF (1 << 2)   /* Bulk list filled */
     94#define CS_OCR (1 << 3)   /* Ownership change request */
    9095#if 0
    9196#define CS_SOC_MASK (0x3) /* Scheduling overrun count */
     
    100105        ioport32_t interrupt_enable;
    101106        ioport32_t interrupt_disable;
    102 #define I_SO   host2ohci_reg(1 << 0)   /* Scheduling overrun */
    103 #define I_WDH  host2ohci_reg(1 << 1)   /* Done head write-back */
    104 #define I_SF   host2ohci_reg(1 << 2)   /* Start of frame */
    105 #define I_RD   host2ohci_reg(1 << 3)   /* Resume detect */
    106 #define I_UE   host2ohci_reg(1 << 4)   /* Unrecoverable error */
    107 #define I_FNO  host2ohci_reg(1 << 5)   /* Frame number overflow */
    108 #define I_RHSC host2ohci_reg(1 << 6)   /* Root hub status change */
    109 #define I_OC   host2ohci_reg(1 << 30)  /* Ownership change */
    110 #define I_MI   host2ohci_reg(1 << 31)  /* Master interrupt (any/all) */
     107#define I_SO   (1 << 0)   /* Scheduling overrun */
     108#define I_WDH  (1 << 1)   /* Done head write-back */
     109#define I_SF   (1 << 2)   /* Start of frame */
     110#define I_RD   (1 << 3)   /* Resume detect */
     111#define I_UE   (1 << 4)   /* Unrecoverable error */
     112#define I_FNO  (1 << 5)   /* Frame number overflow */
     113#define I_RHSC (1 << 6)   /* Root hub status change */
     114#define I_OC   (1 << 30)  /* Ownership change */
     115#define I_MI   (1 << 31)  /* Master interrupt (any/all) */
    111116
    112117        /** HCCA pointer (see hw_struct hcca.h) */
     
    134139        /** Frame time and max packet size for all transfers */
    135140        ioport32_t fm_interval;
    136 #define FMI_FL_GET(reg) (ohci_reg2host(reg) & 0x3fff)
    137 #if 0   
    138141#define FMI_FI_MASK (0x3fff) /* Frame interval in bit times (should be 11999)*/
    139142#define FMI_FI_SHIFT (0)
     
    141144#define FMI_FSMPS_SHIFT (16)
    142145#define FMI_TOGGLE_FLAG (1 << 31)
    143 #endif
    144146
    145147        /** Bit times remaining in current frame */
    146148        const ioport32_t fm_remaining;
    147 #define FMR_R_GET(reg) (ohci_reg2host(reg) & 0x3fff)
    148 #if 0   
    149149#define FMR_FR_MASK FMI_FI_MASK
    150150#define FMR_FR_SHIFT FMI_FI_SHIFT
    151151#define FMR_TOGGLE_FLAG FMI_TOGGLE_FLAG
    152 #endif
     152
    153153        /** Frame number */
    154154        const ioport32_t fm_number;
    155 #if 0
    156155#define FMN_NUMBER_MASK (0xffff)
    157 #endif
     156
    158157        /** Remaining bit time in frame to start periodic transfers */
    159158        ioport32_t periodic_start;
    160 #define PS_GET(reg) (ohci_reg2host(reg) & 0x3fff)
    161 #define PS_SET(reg, value) \
    162 do { \
    163         reg = (reg & host2ohci_reg(~0x3fff)) | host2ohci_reg(value & 0x3fff); \
    164 } while (0)
     159#define PS_MASK 0x3fff
     160#define PS_SHIFT 0
    165161
    166162        /** Threshold for starting LS transaction */
    167163        ioport32_t ls_threshold;
    168 //#define LST_LST_MASK (0x7fff)
     164#define LST_LST_MASK (0x7fff)
    169165
    170166        /** The first root hub control register */
    171167        ioport32_t rh_desc_a;
    172168/** Number of downstream ports, max 15 */
    173 #define RHDA_NDS(reg) (ohci_reg2host(reg) & 0xff)
     169#define RHDA_NDS_MASK  (0xff)
    174170/** Power switching mode: 0-global, 1-per port*/
    175 #define RHDA_PSM_FLAG  host2ohci_reg(1 << 8)
     171#define RHDA_PSM_FLAG  (1 << 8)
    176172/** No power switch: 1-power on, 0-use PSM*/
    177 #define RHDA_NPS_FLAG  host2ohci_reg(1 << 9)
     173#define RHDA_NPS_FLAG  (1 << 9)
    178174/** 1-Compound device, must be 0 */
    179 #define RHDA_DT_FLAG   host2ohci_reg(1 << 10)
     175#define RHDA_DT_FLAG   (1 << 10)
    180176/** Over-current mode: 0-global, 1-per port */
    181 #define RHDA_OCPM_FLAG host2ohci_reg(1 << 11)
     177#define RHDA_OCPM_FLAG (1 << 11)
    182178/** OC control: 0-use OCPM, 1-OC off */
    183 #define RHDA_NOCP_FLAG host2ohci_reg(1 << 12)
     179#define RHDA_NOCP_FLAG (1 << 12)
    184180/** Power on to power good time */
    185 #define RHDA_POTPGT(reg) (ohci_reg2host(reg) >> 24)
     181#define RHDA_POTPGT_SHIFT   24
    186182
    187183        /** The other root hub control register */
    188184        ioport32_t rh_desc_b;
    189185/** Device removable mask */
    190 #define RHDB_DR_READ(reg) (ohci_reg2host(reg) & 0xffff)
    191 #define RHDB_DR_WRITE(val) host2ohci_reg(val & 0xffff)
     186#define RHDB_DR_SHIFT   0
     187#define RHDB_DR_MASK    0xffff
    192188/** Power control mask */
    193 #define RHDB_PCC_READ(reg) (ohci_reg2host(reg) >> 16)
    194 #define RHDB_PCC_WRITE(val) host2ohci_reg(val << 16)
    195 /* Port device removable status */
    196 #define RHDB_DR_FLAG(port) \
    197     host2ohci_reg(((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)
    198 /* Port power control status: 1-per port power control, 0-global power switch */
    199 #define RHDB_PPC_FLAG(port) \
    200     host2ohci_reg(((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)
     189#define RHDB_PCC_MASK (0xffff)
     190#define RHDB_PCC_SHIFT 16
    201191
    202192        /** Root hub status register */
     
    207197 *        specified in PPCM(RHDB), or all ports,
    208198 *        if power is set globally */
    209 #define RHS_LPS_FLAG  host2ohci_reg(1 <<  0)
     199#define RHS_LPS_FLAG  (1 <<  0)
    210200#define RHS_CLEAR_GLOBAL_POWER RHS_LPS_FLAG /* synonym for the above */
    211201/** Over-current indicator, if per-port: 0 */
    212 #define RHS_OCI_FLAG  host2ohci_reg(1 <<  1)
     202#define RHS_OCI_FLAG  (1 <<  1)
    213203
    214204/* read: 0-connect status change does not wake HC
    215205 *       1-connect status change wakes HC
    216206 * write: 1-set DRWE, 0-no effect */
    217 #define RHS_DRWE_FLAG host2ohci_reg(1 << 15)
     207#define RHS_DRWE_FLAG (1 << 15)
    218208#define RHS_SET_DRWE RHS_DRWE_FLAG
    219209/* read: 0,
     
    222212 *        specified in PPCM(RHDB), or all ports,
    223213 *        if power is set globally */
    224 #define RHS_LPSC_FLAG host2ohci_reg(1 << 16)
     214#define RHS_LPSC_FLAG (1 << 16)
    225215#define RHS_SET_GLOBAL_POWER RHS_LPSC_FLAG /* synonym for the above */
    226216/** Over-current change indicator*/
    227 #define RHS_OCIC_FLAG host2ohci_reg(1 << 17)
    228 #define RHS_CLEAR_DRWE host2ohci_reg(1 << 31)
     217#define RHS_OCIC_FLAG (1 << 17)
     218#define RHS_CLEAR_DRWE (1 << 31)
    229219
    230220        /** Root hub per port status */
    231221        ioport32_t rh_port_status[];
    232 #define RHPS_CCS_FLAG host2ohci_reg(1 << 0) /* r: current connect status,
     222#define RHPS_CCS_FLAG (1 << 0) /* r: current connect status,
    233223                                               * w: 1-clear port enable, 0-N/S*/
    234224#define RHPS_CLEAR_PORT_ENABLE RHPS_CCS_FLAG
    235 #define RHPS_PES_FLAG host2ohci_reg(1 << 1) /* r: port enable status
     225#define RHPS_PES_FLAG (1 << 1) /* r: port enable status
    236226                                              * w: 1-set port enable, 0-N/S */
    237227#define RHPS_SET_PORT_ENABLE RHPS_PES_FLAG
    238 #define RHPS_PSS_FLAG host2ohci_reg(1 << 2) /* r: port suspend status
     228#define RHPS_PSS_FLAG (1 << 2) /* r: port suspend status
    239229                                               * w: 1-set port suspend, 0-N/S */
    240230#define RHPS_SET_PORT_SUSPEND RHPS_PSS_FLAG
    241 #define RHPS_POCI_FLAG host2ohci_reg(1 << 3) /* r: port over-current
     231#define RHPS_POCI_FLAG (1 << 3) /* r: port over-current
    242232                                                * (if reports are per-port
    243233                                                * w: 1-clear port suspend
     
    245235                                                *    0-nothing */
    246236#define RHPS_CLEAR_PORT_SUSPEND RHPS_POCI_FLAG
    247 #define RHPS_PRS_FLAG host2ohci_reg(1 << 4) /* r: port reset status
     237#define RHPS_PRS_FLAG (1 << 4) /* r: port reset status
    248238                                               * w: 1-set port reset, 0-N/S */
    249239#define RHPS_SET_PORT_RESET RHPS_PRS_FLAG
    250 #define RHPS_PPS_FLAG host2ohci_reg(1 << 8) /* r: port power status
     240#define RHPS_PPS_FLAG (1 << 8) /* r: port power status
    251241                                              * w: 1-set port power, 0-N/S */
    252242#define RHPS_SET_PORT_POWER RHPS_PPS_FLAG
    253 #define RHPS_LSDA_FLAG host2ohci_reg(1 << 9) /* r: low speed device attached
     243#define RHPS_LSDA_FLAG (1 << 9) /* r: low speed device attached
    254244                                                * w: 1-clear port power, 0-N/S*/
    255245#define RHPS_CLEAR_PORT_POWER RHPS_LSDA_FLAG
    256 #define RHPS_CSC_FLAG  host2ohci_reg(1 << 16) /* connect status change WC */
    257 #define RHPS_PESC_FLAG host2ohci_reg(1 << 17) /* port enable status change WC */
    258 #define RHPS_PSSC_FLAG host2ohci_reg(1 << 18) /* port suspend status change WC */
    259 #define RHPS_OCIC_FLAG host2ohci_reg(1 << 19) /* port over-current change WC */
    260 #define RHPS_PRSC_FLAG host2ohci_reg(1 << 20) /* port reset status change WC */
    261 #define RHPS_CHANGE_WC_MASK host2ohci_reg(0x1f0000)
    262 /** OHCI designers were kind enough to make bits correspond to feature # */
    263 #define RHPS_FEATURE_BIT(feature) host2ohci_reg(1 << feature)
     246#define RHPS_CSC_FLAG  (1 << 16) /* connect status change WC */
     247#define RHPS_PESC_FLAG (1 << 17) /* port enable status change WC */
     248#define RHPS_PSSC_FLAG (1 << 18) /* port suspend status change WC */
     249#define RHPS_OCIC_FLAG (1 << 19) /* port over-current change WC */
     250#define RHPS_PRSC_FLAG (1 << 20) /* port reset status change WC */
     251#define RHPS_CHANGE_WC_MASK (0x1f0000)
    264252} __attribute__((packed)) ohci_regs_t;
    265253#endif
  • uspace/drv/bus/usb/ohci/root_hub.c

    rffcc5776 rbfc5c9dd  
    154154
    155155        instance->registers = regs;
    156         instance->port_count = RHDA_NDS(instance->registers->rh_desc_a);
    157         usb_log_debug("rh_desc_a: %x.\n", instance->registers->rh_desc_a);
     156        instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK;
     157        usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a));
    158158        if (instance->port_count > 15) {
    159159                usb_log_warning("OHCI specification does not allow more than 15"
     
    167167
    168168#if defined OHCI_POWER_SWITCH_no
     169        usb_log_debug("OHCI rh: Set power mode to no power switching.\n");
    169170        /* Set port power mode to no power-switching. (always on) */
    170         instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
     171        OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG);
    171172
    172173        /* Set to no over-current reporting */
    173         instance->registers->rh_desc_a |= RHDA_NOCP_FLAG;
     174        OHCI_SET(regs->rh_desc_a, RHDA_NOCP_FLAG);
    174175
    175176#elif defined OHCI_POWER_SWITCH_ganged
    176         /* Set port power mode to no ganged power-switching. */
    177         instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
    178         instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG;
    179         instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     177        usb_log_debug("OHCI rh: Set power mode to ganged power switching.\n");
     178        /* Set port power mode to ganged power-switching. */
     179        OHCI_CLEAR(regs->rh_desc_a, RHDA_NPS_FLAG);
     180        OHCI_CLEAR(regs->rh_desc_a, RHDA_PSM_FLAG);
     181
     182        /* Turn off power (hub driver will turn this back on)*/
     183        OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);
    180184
    181185        /* Set to global over-current */
    182         instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
    183         instance->registers->rh_desc_a &= ~RHDA_OCPM_FLAG;
     186        OHCI_CLEAR(regs->rh_desc_a, RHDA_NOCP_FLAG);
     187        OHCI_CLEAR(regs->rh_desc_a, RHDA_OCPM_FLAG);
    184188#else
    185         /* Set port power mode to no per port power-switching. */
    186         instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
    187         instance->registers->rh_desc_a |= RHDA_PSM_FLAG;
     189        usb_log_debug("OHCI rh: Set power mode to per-port power switching.\n");
     190        /* Set port power mode to per port power-switching. */
     191        OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
     192        OHCI_SET(regs->rh_desc_a, RHDA_PSM_FLAG);
    188193
    189194        /* Control all ports by global switch and turn them off */
    190         instance->registers->rh_desc_b &= ~RHDB_PCC_WRITE(~0);
    191         instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     195        OHCI_CLR(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
     196        OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);
    192197
    193198        /* Return control to per port state */
    194         instance->registers->rh_desc_b |= RHDB_PCC_WRITE(~0);
     199        OHCI_SET(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
    195200
    196201        /* Set per port over-current */
    197         instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
    198         instance->registers->rh_desc_a |= RHDA_OCPM_FLAG;
     202        OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG);
     203        OHCI_SET(regs->rh_desc_a, RHDA_OCPM_FLAG);
    199204#endif
    200205
     
    285290        instance->hub_descriptor_size = size;
    286291
    287         const uint32_t hub_desc = instance->registers->rh_desc_a;
    288         const uint32_t port_desc = instance->registers->rh_desc_b;
     292        const uint32_t hub_desc = OHCI_RD(instance->registers->rh_desc_a);
     293        const uint32_t port_desc = OHCI_RD(instance->registers->rh_desc_b);
    289294
    290295        /* bDescLength */
     
    308313        instance->descriptors.hub[4] = 0;
    309314        /* bPwrOn2PwrGood */
    310         instance->descriptors.hub[5] = RHDA_POTPGT(hub_desc);
     315        instance->descriptors.hub[5] = hub_desc >> RHDA_POTPGT_SHIFT;
    311316        /* bHubContrCurrent, root hubs don't need no power. */
    312317        instance->descriptors.hub[6] = 0;
    313318
    314319        /* Device Removable and some legacy 1.0 stuff*/
    315         instance->descriptors.hub[7] = RHDB_DR_READ(port_desc) & 0xff;
     320        instance->descriptors.hub[7] = (port_desc >> RHDB_DR_SHIFT) & 0xff;
    316321        instance->descriptors.hub[8] = 0xff;
    317322        if (instance->interrupt_mask_size == 2) {
    318                 instance->descriptors.hub[8] = RHDB_DR_READ(port_desc) >> 8;
     323                instance->descriptors.hub[8] =
     324                    (port_desc >> RHDB_DR_SHIFT) >> 8;
    319325                instance->descriptors.hub[9]  = 0xff;
    320326                instance->descriptors.hub[10] = 0xff;
     
    364370
    365371        /* Only local power source change and over-current change can happen */
    366         if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
     372        if (OHCI_RD(instance->registers->rh_status)
     373            & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
    367374                mask |= 1;
    368375        }
    369376        for (size_t port = 1; port <= instance->port_count; ++port) {
    370377                /* Write-clean bits are those that indicate change */
    371                 if (RHPS_CHANGE_WC_MASK
    372                     & instance->registers->rh_port_status[port - 1]) {
    373 
     378                if (OHCI_RD(instance->registers->rh_port_status[port - 1])
     379                    & RHPS_CHANGE_WC_MASK) {
    374380                        mask |= (1 << port);
    375381                }
     
    396402        usb_device_request_setup_packet_t *request_packet =
    397403            (usb_device_request_setup_packet_t*)request->setup_buffer;
     404
     405        const uint16_t index = uint16_usb2host(request_packet->index);
    398406
    399407        switch (request_packet->request_type)
     
    406414                        TRANSFER_END(request, EOVERFLOW);
    407415                } else {
    408                         uint32_t data = instance->registers->rh_status &
    409                             (RHS_LPS_FLAG | RHS_LPSC_FLAG
    410                                 | RHS_OCI_FLAG | RHS_OCIC_FLAG);
     416                        const uint32_t data =
     417                            OHCI_RD(instance->registers->rh_status) &
     418                                (RHS_LPS_FLAG | RHS_LPSC_FLAG
     419                                    | RHS_OCI_FLAG | RHS_OCIC_FLAG);
    411420                        TRANSFER_END_DATA(request, &data, sizeof(data));
    412421                }
     
    420429                        TRANSFER_END(request, EOVERFLOW);
    421430                } else {
    422                         unsigned port = request_packet->index;
     431                        const unsigned port = index;
    423432                        if (port < 1 || port > instance->port_count)
    424433                                TRANSFER_END(request, EINVAL);
    425 
    426                         uint32_t data =
    427                             instance->registers->rh_port_status[port - 1];
     434                        /* Register format matches the format of port status
     435                         * field */
     436                        const uint32_t data = uint32_usb2host(OHCI_RD(
     437                            instance->registers->rh_port_status[port - 1]));
    428438                        TRANSFER_END_DATA(request, &data, sizeof(data));
    429439                }
     
    441451        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE):
    442452                /* Hubs are allowed to have only one interface */
    443                 if (request_packet->index != 0)
     453                if (index != 0)
    444454                        TRANSFER_END(request, EINVAL);
    445455                /* Fall through, as the answer will be the same: 0x0000 */
    446456        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT):
    447457                /* Endpoint 0 (default control) and 1 (interrupt) */
    448                 if (request_packet->index >= 2)
     458                if (index >= 2)
    449459                        TRANSFER_END(request, EINVAL);
    450460
     
    455465                } else {
    456466                        /* Endpoints are OK. (We don't halt) */
    457                         uint16_t data = 0;
     467                        const uint16_t data = 0;
    458468                        TRANSFER_END_DATA(request, &data, sizeof(data));
    459469                }
     
    556566        switch (feature)
    557567        {
    558         case USB_HUB_FEATURE_PORT_POWER:   //8
    559                 /* No power switching */
    560                 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG)
    561                         return EOK;
    562                 /* Ganged power switching */
    563                 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) {
    564                         instance->registers->rh_status = RHS_SET_GLOBAL_POWER;
    565                         return EOK;
     568        case USB_HUB_FEATURE_PORT_POWER:   /*8*/
     569                {
     570                        const uint32_t rhda =
     571                            OHCI_RD(instance->registers->rh_desc_a);
     572                        /* No power switching */
     573                        if (rhda & RHDA_NPS_FLAG)
     574                                return EOK;
     575                        /* Ganged power switching, one port powers all */
     576                        if (!(rhda & RHDA_PSM_FLAG)) {
     577                                OHCI_WR(instance->registers->rh_status,
     578                                    RHS_SET_GLOBAL_POWER);
     579                                return EOK;
     580                        }
    566581                }
    567         case USB_HUB_FEATURE_PORT_ENABLE:  //1
    568         case USB_HUB_FEATURE_PORT_SUSPEND: //2
    569         case USB_HUB_FEATURE_PORT_RESET:   //4
    570                 usb_log_debug2(
    571                     "Setting port ENABLE, SUSPEND or RESET on port %zu.\n",
    572                     port);
    573                 instance->registers->rh_port_status[port - 1] =
    574                     RHPS_FEATURE_BIT(feature);
     582                        /* Fall through */
     583        case USB_HUB_FEATURE_PORT_ENABLE:  /*1*/
     584        case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/
     585        case USB_HUB_FEATURE_PORT_RESET:   /*4*/
     586                usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET "
     587                    "on port %zu.\n", port);
     588                OHCI_WR(instance->registers->rh_port_status[port - 1],
     589                    1 << feature);
    575590                return EOK;
    576591        default:
     
    598613        switch (feature)
    599614        {
    600         case USB_HUB_FEATURE_PORT_POWER:          //8
    601                 /* No power switching */
    602                 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG)
    603                         return ENOTSUP;
    604                 /* Ganged power switching */
    605                 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) {
    606                         instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     615        case USB_HUB_FEATURE_PORT_POWER:          /*8*/
     616                {
     617                        const uint32_t rhda =
     618                            OHCI_RD(instance->registers->rh_desc_a);
     619                        /* No power switching */
     620                        if (rhda & RHDA_NPS_FLAG)
     621                                return ENOTSUP;
     622                        /* Ganged power switching, one port powers all */
     623                        if (!(rhda & RHDA_PSM_FLAG)) {
     624                                OHCI_WR(instance->registers->rh_status,
     625                                    RHS_CLEAR_GLOBAL_POWER);
     626                                return EOK;
     627                        }
     628                        OHCI_WR(instance->registers->rh_port_status[port - 1],
     629                            RHPS_CLEAR_PORT_POWER);
    607630                        return EOK;
    608631                }
    609                 instance->registers->rh_port_status[port - 1] =
    610                         RHPS_CLEAR_PORT_POWER;
     632
     633        case USB_HUB_FEATURE_PORT_ENABLE:         /*1*/
     634                OHCI_WR(instance->registers->rh_port_status[port - 1],
     635                    RHPS_CLEAR_PORT_ENABLE);
    611636                return EOK;
    612637
    613         case USB_HUB_FEATURE_PORT_ENABLE:         //1
    614                 instance->registers->rh_port_status[port - 1] =
    615                         RHPS_CLEAR_PORT_ENABLE;
     638        case USB_HUB_FEATURE_PORT_SUSPEND:        /*2*/
     639                OHCI_WR(instance->registers->rh_port_status[port - 1],
     640                    RHPS_CLEAR_PORT_SUSPEND);
    616641                return EOK;
    617642
    618         case USB_HUB_FEATURE_PORT_SUSPEND:        //2
    619                 instance->registers->rh_port_status[port - 1] =
    620                         RHPS_CLEAR_PORT_SUSPEND;
    621                 return EOK;
    622 
    623         case USB_HUB_FEATURE_C_PORT_CONNECTION:   //16
    624         case USB_HUB_FEATURE_C_PORT_ENABLE:       //17
    625         case USB_HUB_FEATURE_C_PORT_SUSPEND:      //18
    626         case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: //19
    627         case USB_HUB_FEATURE_C_PORT_RESET:        //20
     643        case USB_HUB_FEATURE_C_PORT_CONNECTION:   /*16*/
     644        case USB_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
     645        case USB_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
     646        case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/
     647        case USB_HUB_FEATURE_C_PORT_RESET:        /*20*/
    628648                usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, "
    629                     "C_SUSPEND or C_RESET on port %zu.\n",
    630                     port);
    631                 instance->registers->rh_port_status[port - 1] =
    632                     RHPS_FEATURE_BIT(feature);
     649                    "C_SUSPEND, C_OC or C_RESET on port %zu.\n", port);
     650                /* Bit offsets correspond to the feature number */
     651                OHCI_WR(instance->registers->rh_port_status[port - 1],
     652                    1 << feature);
    633653                return EOK;
    634654
     
    658678        case USB_HUB_REQ_TYPE_SET_PORT_FEATURE:
    659679                usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    660                 int ret = set_feature_port(instance,
     680                const int ret = set_feature_port(instance,
    661681                    setup_request->value, setup_request->index);
    662682                TRANSFER_END(request, ret);
     
    697717        case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE:
    698718                usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n");
    699                 int ret = clear_feature_port(instance,
     719                const int ret = clear_feature_port(instance,
    700720                    setup_request->value, setup_request->index);
    701721                TRANSFER_END(request, ret);
     
    710730                 * as root hubs do not support local power status feature.
    711731                 * (OHCI pg. 127) */
    712                 if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) {
    713                         instance->registers->rh_status = RHS_OCIC_FLAG;
     732                if (uint16_usb2host(setup_request->value)
     733                    == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) {
     734                        OHCI_WR(instance->registers->rh_status, RHS_OCIC_FLAG);
    714735                        TRANSFER_END(request, EOK);
    715736                }
     
    775796                if (request->buffer_size == 0)
    776797                        TRANSFER_END(request, EOVERFLOW);
    777                 uint8_t config = 1;
     798                const uint8_t config = 1;
    778799                TRANSFER_END_DATA(request, &config, sizeof(config));
    779800
     
    794815                        TRANSFER_END(request, EINVAL);
    795816
    796                 instance->address = setup_request->value;
     817                instance->address = uint16_usb2host(setup_request->value);
    797818                TRANSFER_END(request, EOK);
    798819
Note: See TracChangeset for help on using the changeset viewer.