Changeset bfc5c9dd in mainline for uspace/drv/bus/usb/ohci/hc.c


Ignore:
Timestamp:
2012-02-23T20:42:30Z (12 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.

File:
1 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/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.