Changeset 478e243 in mainline for uspace/drv/bus/usb/ehci/hc.c


Ignore:
Timestamp:
2014-01-22T00:00:18Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
64c96b9
Parents:
bdddc9d
Message:

ehci: Initialize and start the HC

File:
1 edited

Legend:

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

    rbdddc9d r478e243  
    8989};
    9090
    91 static void hc_gain_control(hc_t *instance);
    9291static void hc_start(hc_t *instance);
    9392static int hc_init_memory(hc_t *instance);
     
    185184        }
    186185
    187         hc_gain_control(instance);
    188 
    189186        ehci_rh_init(
    190187            &instance->rh, instance->caps, instance->registers, "ehci rh");
     
    262259}
    263260
    264 /** Turn off any (BIOS)driver that might be in control of the device.
    265  *
    266  * This function implements routines described in chapter 5.1.1.3 of the EHCI
    267  * specification (page 40, pdf page 54).
     261/** EHCI hw initialization routine.
    268262 *
    269263 * @param[in] instance EHCI hc driver structure.
    270264 */
    271 void hc_gain_control(hc_t *instance)
    272 {
    273         assert(instance);
    274 }
    275 
    276 /** EHCI hw initialization routine.
    277  *
    278  * @param[in] instance EHCI hc driver structure.
    279  */
    280265void hc_start(hc_t *instance)
    281266{
    282267        assert(instance);
     268        /* Turn of the HC if it's running, Reseting a running device is
     269         * undefined */
     270        if (!(EHCI_RD(instance->registers->usbsts) & USB_STS_HC_HALTED_FLAG)) {
     271                /* disable all interrupts */
     272                EHCI_WR(instance->registers->usbintr, 0);
     273                /* ack all interrupts */
     274                EHCI_WR(instance->registers->usbsts, 0x3f);
     275                /* Stop HC hw */
     276                EHCI_WR(instance->registers->usbcmd, 0);
     277                /* Wait until hc is halted */
     278                while ((EHCI_RD(instance->registers->usbsts) & USB_STS_HC_HALTED_FLAG) == 0) {
     279                        async_usleep(1);
     280                }
     281                usb_log_info("EHCI turned off.\n");
     282        } else {
     283                usb_log_info("EHCI was not running.\n");
     284        }
     285
     286        /* Hw initialization sequence, see page 53 (pdf 63) */
     287        EHCI_SET(instance->registers->usbcmd, USB_CMD_HC_RESET_FLAG);
     288        while (EHCI_RD(instance->registers->usbcmd) & USB_CMD_HC_RESET_FLAG) {
     289                async_usleep(1);
     290        }
     291        /* Enable interrupts */
     292        EHCI_WR(instance->registers->usbintr, USB_INTR_PORT_CHANGE_FLAG | USB_INTR_IRQ_FLAG);
     293        /* Use lower 4G segment */
     294        EHCI_WR(instance->registers->ctrldssegment, 0);
     295        /* Set periodic list */
     296        assert(instance->periodic_list_base);
     297        const uintptr_t phys_base =
     298            addr_to_phys((void*)instance->periodic_list_base);
     299        assert((phys_base & USB_PERIODIC_LIST_BASE_MASK) == phys_base);
     300        EHCI_WR(instance->registers->periodiclistbase, phys_base);
     301
     302        /* start hc and get all ports */
     303        EHCI_SET(instance->registers->usbcmd, USB_CMD_RUN_FLAG);
     304        EHCI_SET(instance->registers->configflag, USB_CONFIG_FLAG_FLAG);
     305#if 0
    283306        /*
    284307         * TURN OFF EHCI FOR NOW
    285308         */
    286 
    287309        usb_log_debug("USBCMD value: %x.\n",
    288310            EHCI_RD(instance->registers->usbcmd));
     
    301323                usb_log_info("EHCI was not running.\n");
    302324        }
     325#endif
    303326        usb_log_debug("Registers: \n"
    304327            "\t USBCMD(%p): %x(0x00080000 = at least 1ms between interrupts)\n"
     
    319342int hc_init_memory(hc_t *instance)
    320343{
     344        assert(instance);
     345
     346        /* Take 1024 periodic list heads, we ignore low mem options */
     347        instance->periodic_list_base = get_page();
     348        if (!instance->periodic_list_base)
     349                return ENOMEM;
     350        for (unsigned i = 0;
     351            i < PAGE_SIZE/sizeof(instance->periodic_list_base[0]); ++i)
     352        {
     353                /* Disable everything for now */
     354                instance->periodic_list_base[i] = LINK_POINTER_TERM;
     355        }
    321356        return EOK;
    322357}
Note: See TracChangeset for help on using the changeset viewer.