Ignore:
File:
1 edited

Legend:

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

    r8b54fe6 rd57122c  
    4747    (I_SO | I_WDH | I_UE | I_RHSC)
    4848
    49 static const irq_cmd_t ohci_irq_commands[] =
    50 {
    51         { .cmd = CMD_MEM_READ_32, .dstarg = 1, .addr = NULL /*filled later*/ },
     49static const irq_pio_range_t ohci_pio_ranges[] = {
     50        {
     51                .base = 0,      /* filled later */
     52                .size = sizeof(ohci_regs_t)
     53        }
     54};
     55
     56static const irq_cmd_t ohci_irq_commands[] = {
     57        { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ },
    5258        { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS },
    5359        { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
    54         { .cmd = CMD_MEM_WRITE_A_32, .srcarg = 1, .addr = NULL /*filled later*/ },
     60        { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ },
    5561        { .cmd = CMD_ACCEPT },
    5662};
     
    6369static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    6470/*----------------------------------------------------------------------------*/
     71/** Get number of PIO ranges used in IRQ code.
     72 * @return Number of ranges.
     73 */
     74size_t hc_irq_pio_range_count(void)
     75{
     76        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
     77}
     78/*----------------------------------------------------------------------------*/
     79/*----------------------------------------------------------------------------*/
    6580/** Get number of commands used in IRQ code.
    6681 * @return Number of commands.
     
    7186}
    7287/*----------------------------------------------------------------------------*/
    73 /** Generate IRQ code commands.
    74  * @param[out] cmds Place to store the commands.
    75  * @param[in] cmd_size Size of the place (bytes).
     88/** Generate IRQ code.
     89 * @param[out] ranges PIO ranges buffer.
     90 * @param[in] ranges_size Size of the ranges buffer (bytes).
     91 * @param[out] cmds Commands buffer.
     92 * @param[in] cmds_size Size of the commands buffer (bytes).
    7693 * @param[in] regs Physical address of device's registers.
    7794 * @param[in] reg_size Size of the register area (bytes).
     
    7996 * @return Error code.
    8097 */
    81 int hc_get_irq_commands(
    82     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size)
    83 {
    84         if (cmd_size < sizeof(ohci_irq_commands)
    85             || reg_size < sizeof(ohci_regs_t))
     98int
     99hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
     100    size_t cmds_size, uintptr_t regs, size_t reg_size)
     101{
     102        if ((ranges_size < sizeof(ohci_pio_ranges)) ||
     103            (cmds_size < sizeof(ohci_irq_commands)) ||
     104            (reg_size < sizeof(ohci_regs_t)))
    86105                return EOVERFLOW;
    87106
    88         /* Create register mapping to use in IRQ handler.
    89          * This mapping should be present in kernel only.
    90          * Remove it from here when kernel knows how to create mappings
    91          * and accepts physical addresses in IRQ code.
    92          * TODO: remove */
    93         ohci_regs_t *registers;
    94         const int ret = pio_enable((void*)regs, reg_size, (void**)&registers);
    95         if (ret != EOK)
    96                 return ret;
    97 
    98         /* Some bogus access to force create mapping. DO NOT remove,
    99          * unless whole virtual addresses in irq is replaced
    100          * NOTE: Compiler won't remove this as ohci_regs_t members
    101          * are declared volatile.
    102          *
    103          * Introducing CMD_MEM set of IRQ code commands broke
    104          * assumption that IRQ code does not cause page faults.
    105          * If this happens during idling (THREAD == NULL)
    106          * it causes kernel panic.
    107          */
    108         registers->revision;
     107        memcpy(ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges));
     108        ranges[0].base = regs;
    109109
    110110        memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands));
    111 
    112         void *address = (void*)&registers->interrupt_status;
    113         cmds[0].addr = address;
    114         cmds[3].addr = address;
     111        ohci_regs_t *registers = (ohci_regs_t *) regs;
     112        cmds[0].addr = (void *) &registers->interrupt_status;
     113        cmds[3].addr = (void *) &registers->interrupt_status;
     114
    115115        return EOK;
    116116}
     
    127127        assert(hub_fun);
    128128
    129         const usb_address_t hub_address =
    130             usb_device_manager_get_free_address(
    131                 &instance->generic.dev_manager, USB_SPEED_FULL);
    132         if (hub_address <= 0) {
     129        /* Try to get address 1 for root hub. */
     130        instance->rh.address = 1;
     131        int ret = usb_device_manager_request_address(
     132            &instance->generic.dev_manager, &instance->rh.address, false,
     133            USB_SPEED_FULL);
     134        if (ret != EOK) {
    133135                usb_log_error("Failed to get OHCI root hub address: %s\n",
    134                     str_error(hub_address));
    135                 return hub_address;
    136         }
    137         instance->rh.address = hub_address;
    138         usb_device_manager_bind(
    139             &instance->generic.dev_manager, hub_address, hub_fun->handle);
     136                    str_error(ret));
     137                return ret;
     138        }
    140139
    141140#define CHECK_RET_UNREG_RETURN(ret, message...) \
    142141if (ret != EOK) { \
    143142        usb_log_error(message); \
    144         usb_endpoint_manager_unregister_ep( \
    145             &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\
    146         usb_device_manager_release( \
    147             &instance->generic.dev_manager, hub_address); \
     143        usb_endpoint_manager_remove_ep( \
     144            &instance->generic.ep_manager, instance->rh.address, 0, \
     145            USB_DIRECTION_BOTH, NULL, NULL); \
     146        usb_device_manager_release_address( \
     147            &instance->generic.dev_manager, instance->rh.address); \
    148148        return ret; \
    149149} else (void)0
    150         int ret = usb_endpoint_manager_add_ep(
    151             &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH,
    152             USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0);
     150
     151        ret = usb_endpoint_manager_add_ep(
     152            &instance->generic.ep_manager, instance->rh.address, 0,
     153            USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
     154            0, NULL, NULL);
    153155        CHECK_RET_UNREG_RETURN(ret,
    154156            "Failed to register root hub control endpoint: %s.\n",
     
    162164        CHECK_RET_UNREG_RETURN(ret,
    163165            "Failed to bind root hub function: %s.\n", str_error(ret));
     166
     167        ret = usb_device_manager_bind_address(&instance->generic.dev_manager,
     168            instance->rh.address, hub_fun->handle);
     169        if (ret != EOK)
     170                usb_log_warning("Failed to bind root hub address: %s.\n",
     171                    str_error(ret));
    164172
    165173        return EOK;
     
    192200        list_initialize(&instance->pending_batches);
    193201
    194         ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,
    195             bandwidth_count_usb11);
    196         CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n",
    197             str_error(ret));
     202        hcd_init(&instance->generic, USB_SPEED_FULL,
     203            BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    198204        instance->generic.private_data = instance;
    199205        instance->generic.schedule = hc_schedule;
    200206        instance->generic.ep_add_hook = ohci_endpoint_init;
     207        instance->generic.ep_remove_hook = ohci_endpoint_fini;
    201208
    202209        ret = hc_init_memory(instance);
     
    221228}
    222229/*----------------------------------------------------------------------------*/
    223 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep)
    224 {
     230void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep)
     231{
     232        assert(instance);
     233        assert(ep);
     234
    225235        endpoint_list_t *list = &instance->lists[ep->transfer_type];
    226236        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
     237        assert(list);
     238        assert(ohci_ep);
     239
    227240        /* Enqueue ep */
    228241        switch (ep->transfer_type) {
     
    247260}
    248261/*----------------------------------------------------------------------------*/
    249 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep)
    250 {
     262void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep)
     263{
     264        assert(instance);
     265        assert(ep);
     266
    251267        /* Dequeue ep */
    252268        endpoint_list_t *list = &instance->lists[ep->transfer_type];
    253269        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
     270
     271        assert(list);
     272        assert(ohci_ep);
    254273        switch (ep->transfer_type) {
    255274        case USB_TRANSFER_CONTROL:
     
    565584
    566585        /*Init HCCA */
    567         instance->hcca = malloc32(sizeof(hcca_t));
     586        instance->hcca = hcca_get();
    568587        if (instance->hcca == NULL)
    569588                return ENOMEM;
     
    571590        usb_log_debug2("OHCI HCCA initialized at %p.\n", instance->hcca);
    572591
    573         unsigned i = 0;
    574         for (; i < 32; ++i) {
     592        for (unsigned i = 0; i < 32; ++i) {
    575593                instance->hcca->int_ep[i] =
    576594                    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa;
Note: See TracChangeset for help on using the changeset viewer.