Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 478e243 in mainline


Ignore:
Timestamp:
2014-01-22T00:00:18Z (8 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
64c96b9
Parents:
bdddc9d
Message:

ehci: Initialize and start the HC

Location:
uspace/drv/bus/usb/ehci
Files:
3 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}
  • uspace/drv/bus/usb/ehci/hc.h

    rbdddc9d r478e243  
    5050#include "ehci_regs.h"
    5151#include "ehci_rh.h"
     52#include "hw_struct/link_pointer.h"
    5253//#include "endpoint_list.h"
    5354
     
    5859        /** Memory mapped I/O registers area */
    5960        ehci_regs_t *registers;
     61
     62        /** Iso transfer list */
     63        link_pointer_t *periodic_list_base;
    6064
    6165        /** Transfer schedules */
  • uspace/drv/bus/usb/ehci/utils/malloc32.h

    rbdddc9d r478e243  
    3636
    3737#include <as.h>
     38#include <ddi.h>
    3839#include <errno.h>
    3940#include <stdlib.h>
     
    4445 * buffers do not have to be aligned.
    4546 */
    46 #define EHCI_ALIGN 32
     47#define EHCI_ALIGN   32
     48
     49#define EHCI_REQUIRED_PAGE_SIZE   4096
    4750
    4851/** Get physical address translation
     
    7679static inline void free32(void *addr)
    7780        { free(addr); }
     81
     82/** Create 4KB page mapping
     83 *
     84 * @return Address of the mapped page, NULL on failure.
     85 */
     86static inline void *get_page(void)
     87{
     88        uintptr_t phys;
     89        void *address;
     90
     91        const int ret = dmamem_map_anonymous(EHCI_REQUIRED_PAGE_SIZE,
     92            DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
     93            &address);
     94
     95        return ((ret == EOK) ? address : NULL);
     96}
     97
     98static inline void return_page(void *page)
     99{
     100        dmamem_unmap_anonymous(page);
     101}
    78102#endif
    79103/**
Note: See TracChangeset for help on using the changeset viewer.