Ignore:
File:
1 edited

Legend:

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

    r76fbd9a rd57122c  
    5656static const irq_cmd_t ohci_irq_commands[] = {
    5757        { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ },
    58         { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = 0 /* filled later */ },
     58        { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS },
    5959        { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
    6060        { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ },
     
    6868static int interrupt_emulator(hc_t *instance);
    6969static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    70 
     70/*----------------------------------------------------------------------------*/
    7171/** Get number of PIO ranges used in IRQ code.
    7272 * @return Number of ranges.
     
    7676        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
    7777}
    78 
    79 
     78/*----------------------------------------------------------------------------*/
     79/*----------------------------------------------------------------------------*/
    8080/** Get number of commands used in IRQ code.
    8181 * @return Number of commands.
     
    8585        return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
    8686}
    87 
     87/*----------------------------------------------------------------------------*/
    8888/** Generate IRQ code.
    8989 * @param[out] ranges PIO ranges buffer.
     
    111111        ohci_regs_t *registers = (ohci_regs_t *) regs;
    112112        cmds[0].addr = (void *) &registers->interrupt_status;
    113         cmds[1].value = OHCI_USED_INTERRUPTS;
    114113        cmds[3].addr = (void *) &registers->interrupt_status;
    115114
    116115        return EOK;
    117116}
    118 
     117/*----------------------------------------------------------------------------*/
    119118/** Announce OHCI root hub to the DDF
    120119 *
     
    175174#undef CHECK_RET_RELEASE
    176175}
    177 
     176/*----------------------------------------------------------------------------*/
    178177/** Initialize OHCI hc driver structure
    179178 *
     
    228227        return EOK;
    229228}
    230 
     229/*----------------------------------------------------------------------------*/
    231230void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep)
    232231{
     
    242241        switch (ep->transfer_type) {
    243242        case USB_TRANSFER_CONTROL:
    244                 OHCI_CLR(instance->registers->control, C_CLE);
     243                instance->registers->control &= ~C_CLE;
    245244                endpoint_list_add_ep(list, ohci_ep);
    246                 OHCI_WR(instance->registers->control_current, 0);
    247                 OHCI_SET(instance->registers->control, C_CLE);
     245                instance->registers->control_current = 0;
     246                instance->registers->control |= C_CLE;
    248247                break;
    249248        case USB_TRANSFER_BULK:
    250                 OHCI_CLR(instance->registers->control, C_BLE);
     249                instance->registers->control &= ~C_BLE;
    251250                endpoint_list_add_ep(list, ohci_ep);
    252                 OHCI_WR(instance->registers->bulk_current, 0);
    253                 OHCI_SET(instance->registers->control, C_BLE);
     251                instance->registers->control |= C_BLE;
    254252                break;
    255253        case USB_TRANSFER_ISOCHRONOUS:
    256254        case USB_TRANSFER_INTERRUPT:
    257                 OHCI_CLR(instance->registers->control, C_PLE | C_IE);
     255                instance->registers->control &= (~C_PLE & ~C_IE);
    258256                endpoint_list_add_ep(list, ohci_ep);
    259                 OHCI_SET(instance->registers->control, C_PLE | C_IE);
    260                 break;
    261         }
    262 }
    263 
     257                instance->registers->control |= C_PLE | C_IE;
     258                break;
     259        }
     260}
     261/*----------------------------------------------------------------------------*/
    264262void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep)
    265263{
     
    275273        switch (ep->transfer_type) {
    276274        case USB_TRANSFER_CONTROL:
    277                 OHCI_CLR(instance->registers->control, C_CLE);
     275                instance->registers->control &= ~C_CLE;
    278276                endpoint_list_remove_ep(list, ohci_ep);
    279                 OHCI_WR(instance->registers->control_current, 0);
    280                 OHCI_SET(instance->registers->control, C_CLE);
     277                instance->registers->control_current = 0;
     278                instance->registers->control |= C_CLE;
    281279                break;
    282280        case USB_TRANSFER_BULK:
    283                 OHCI_CLR(instance->registers->control, C_BLE);
     281                instance->registers->control &= ~C_BLE;
    284282                endpoint_list_remove_ep(list, ohci_ep);
    285                 OHCI_WR(instance->registers->bulk_current, 0);
    286                 OHCI_SET(instance->registers->control, C_BLE);
     283                instance->registers->control |= C_BLE;
    287284                break;
    288285        case USB_TRANSFER_ISOCHRONOUS:
    289286        case USB_TRANSFER_INTERRUPT:
    290                 OHCI_CLR(instance->registers->control, C_PLE | C_IE);
     287                instance->registers->control &= (~C_PLE & ~C_IE);
    291288                endpoint_list_remove_ep(list, ohci_ep);
    292                 OHCI_SET(instance->registers->control, C_PLE | C_IE);
     289                instance->registers->control |= C_PLE | C_IE;
    293290                break;
    294291        default:
     
    296293        }
    297294}
    298 
     295/*----------------------------------------------------------------------------*/
    299296/** Add USB transfer to the schedule.
    300297 *
     
    311308        /* Check for root hub communication */
    312309        if (batch->ep->address == instance->rh.address) {
    313                 usb_log_debug("OHCI root hub request.\n");
    314310                rh_request(&instance->rh, batch);
    315311                return EOK;
     
    327323        {
    328324        case USB_TRANSFER_CONTROL:
    329                 OHCI_SET(instance->registers->command_status, CS_CLF);
     325                instance->registers->command_status |= CS_CLF;
    330326                break;
    331327        case USB_TRANSFER_BULK:
    332                 OHCI_SET(instance->registers->command_status, CS_BLF);
     328                instance->registers->command_status |= CS_BLF;
    333329                break;
    334330        default:
     
    338334        return EOK;
    339335}
    340 
     336/*----------------------------------------------------------------------------*/
    341337/** Interrupt handling routine
    342338 *
     
    346342void hc_interrupt(hc_t *instance, uint32_t status)
    347343{
    348         status = ohci_reg2host(status);
    349344        assert(instance);
    350345        if ((status & ~I_SF) == 0) /* ignore sof status */
     
    357352                fibril_mutex_lock(&instance->guard);
    358353                usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
    359                     OHCI_RD(instance->registers->hcca),
     354                    instance->registers->hcca,
    360355                    (void *) addr_to_phys(instance->hcca));
    361356                usb_log_debug2("Periodic current: %#" PRIx32 ".\n",
    362                     OHCI_RD(instance->registers->periodic_current));
     357                    instance->registers->periodic_current);
    363358
    364359                link_t *current = list_first(&instance->pending_batches);
     
    384379
    385380}
    386 
     381/*----------------------------------------------------------------------------*/
    387382/** Check status register regularly
    388383 *
     
    402397        return EOK;
    403398}
    404 
     399/*----------------------------------------------------------------------------*/
    405400/** Turn off any (BIOS)driver that might be in control of the device.
    406401 *
     
    415410
    416411        usb_log_debug("Requesting OHCI control.\n");
    417         if (OHCI_RD(instance->registers->revision) & R_LEGACY_FLAG) {
     412        if (instance->registers->revision & R_LEGACY_FLAG) {
    418413                /* Turn off legacy emulation, it should be enough to zero
    419414                 * the lowest bit, but it caused problems. Thus clear all
     
    424419                (uint32_t*)((char*)instance->registers + LEGACY_REGS_OFFSET);
    425420                usb_log_debug("OHCI legacy register %p: %x.\n",
    426                     ohci_emulation_reg, OHCI_RD(*ohci_emulation_reg));
     421                    ohci_emulation_reg, *ohci_emulation_reg);
    427422                /* Zero everything but A20State */
    428                 OHCI_CLR(*ohci_emulation_reg, ~0x100);
     423                *ohci_emulation_reg &= 0x100;
    429424                usb_log_debug(
    430425                    "OHCI legacy register (should be 0 or 0x100) %p: %x.\n",
    431                     ohci_emulation_reg, OHCI_RD(*ohci_emulation_reg));
     426                    ohci_emulation_reg, *ohci_emulation_reg);
    432427        }
    433428
    434429        /* Interrupt routing enabled => smm driver is active */
    435         if (OHCI_RD(instance->registers->control) & C_IR) {
     430        if (instance->registers->control & C_IR) {
    436431                usb_log_debug("SMM driver: request ownership change.\n");
    437                 OHCI_SET(instance->registers->command_status, CS_OCR);
     432                instance->registers->command_status |= CS_OCR;
    438433                /* Hope that SMM actually knows its stuff or we can hang here */
    439                 while (OHCI_RD(instance->registers->control & C_IR)) {
     434                while (instance->registers->control & C_IR) {
    440435                        async_usleep(1000);
    441436                }
     
    445440                return;
    446441        }
     442
    447443        const unsigned hc_status = C_HCFS_GET(instance->registers->control);
    448444        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
     
    453449                        return;
    454450                }
    455                 /* HC is suspended assert resume for 20ms */
     451                /* HC is suspended assert resume for 20ms, */
    456452                C_HCFS_SET(instance->registers->control, C_HCFS_RESUME);
    457453                async_usleep(20000);
     
    465461        async_usleep(50000);
    466462}
    467 
     463/*----------------------------------------------------------------------------*/
    468464/** OHCI hw initialization routine.
    469465 *
     
    477473
    478474        /* Save contents of fm_interval register */
    479         const uint32_t fm_interval = OHCI_RD(instance->registers->fm_interval);
     475        const uint32_t fm_interval = instance->registers->fm_interval;
    480476        usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval);
    481477
     
    483479        usb_log_debug2("HC reset.\n");
    484480        size_t time = 0;
    485         OHCI_WR(instance->registers->command_status, CS_HCR);
    486         while (OHCI_RD(instance->registers->command_status) & CS_HCR) {
     481        instance->registers->command_status = CS_HCR;
     482        while (instance->registers->command_status & CS_HCR) {
    487483                async_usleep(10);
    488484                time += 10;
     
    491487
    492488        /* Restore fm_interval */
    493         OHCI_WR(instance->registers->fm_interval, fm_interval);
    494         assert((OHCI_RD(instance->registers->command_status) & CS_HCR) == 0);
     489        instance->registers->fm_interval = fm_interval;
     490        assert((instance->registers->command_status & CS_HCR) == 0);
    495491
    496492        /* hc is now in suspend state */
    497493        usb_log_debug2("HC should be in suspend state(%x).\n",
    498             OHCI_RD(instance->registers->control));
     494            instance->registers->control);
    499495
    500496        /* Use HCCA */
    501         OHCI_WR(instance->registers->hcca, addr_to_phys(instance->hcca));
     497        instance->registers->hcca = addr_to_phys(instance->hcca);
    502498
    503499        /* Use queues */
    504         OHCI_WR(instance->registers->bulk_head,
    505             instance->lists[USB_TRANSFER_BULK].list_head_pa);
     500        instance->registers->bulk_head =
     501            instance->lists[USB_TRANSFER_BULK].list_head_pa;
    506502        usb_log_debug2("Bulk HEAD set to: %p (%#" PRIx32 ").\n",
    507503            instance->lists[USB_TRANSFER_BULK].list_head,
    508504            instance->lists[USB_TRANSFER_BULK].list_head_pa);
    509505
    510         OHCI_WR(instance->registers->control_head,
    511             instance->lists[USB_TRANSFER_CONTROL].list_head_pa);
     506        instance->registers->control_head =
     507            instance->lists[USB_TRANSFER_CONTROL].list_head_pa;
    512508        usb_log_debug2("Control HEAD set to: %p (%#" PRIx32 ").\n",
    513509            instance->lists[USB_TRANSFER_CONTROL].list_head,
     
    515511
    516512        /* Enable queues */
    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));
     513        instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
     514        usb_log_debug2("All queues enabled(%x).\n",
     515            instance->registers->control);
    520516
    521517        /* Enable interrupts */
    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);
     518        instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
     519        usb_log_debug2("Enabled interrupts: %x.\n",
     520            instance->registers->interrupt_enable);
     521        instance->registers->interrupt_enable = I_MI;
    526522
    527523        /* Set periodic start to 90% */
    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);
     524        uint32_t frame_length = ((fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK);
     525        instance->registers->periodic_start = (frame_length / 10) * 9;
    532526        usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n",
    533             OHCI_RD(instance->registers->periodic_start),
    534             OHCI_RD(instance->registers->periodic_start), frame_length);
     527            instance->registers->periodic_start,
     528            instance->registers->periodic_start, frame_length);
     529
    535530        C_HCFS_SET(instance->registers->control, C_HCFS_OPERATIONAL);
    536531        usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n",
    537             OHCI_RD(instance->registers->control));
    538 }
    539 
     532            instance->registers->control);
     533}
     534/*----------------------------------------------------------------------------*/
    540535/** Initialize schedule queues
    541536 *
     
    571566        return EOK;
    572567}
    573 
     568/*----------------------------------------------------------------------------*/
    574569/** Initialize memory structures used by the OHCI hcd.
    575570 *
     
    596591
    597592        for (unsigned i = 0; i < 32; ++i) {
    598                 OHCI_WR(instance->hcca->int_ep[i],
    599                     instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
     593                instance->hcca->int_ep[i] =
     594                    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa;
    600595        }
    601596        usb_log_debug2("Interrupt HEADs set to: %p (%#" PRIx32 ").\n",
Note: See TracChangeset for help on using the changeset viewer.