Changeset 7b715892 in mainline for uspace/drv/ohci/hc.c


Ignore:
Timestamp:
2011-04-09T16:00:33Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5410c04
Parents:
8efafda (diff), 8e8b84f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

File:
1 edited

Legend:

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

    r8efafda r7b715892  
    4747static void hc_gain_control(hc_t *instance);
    4848static void hc_init_hw(hc_t *instance);
     49static int hc_init_transfer_lists(hc_t *instance);
     50static int hc_init_memory(hc_t *instance);
    4951/*----------------------------------------------------------------------------*/
    5052int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
     
    5961            &instance->manager, hub_address, hub_fun->handle);
    6062
     63        endpoint_t *ep = malloc(sizeof(endpoint_t));
     64        assert(ep);
     65        int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH,
     66            USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64);
     67        assert(ret == EOK);
     68        ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0);
     69        assert(ret == EOK);
     70
    6171        char *match_str = NULL;
    62         int ret = asprintf(&match_str, "usb&class=hub");
    63         ret = (match_str == NULL) ? ret : EOK;
     72        ret = asprintf(&match_str, "usb&class=hub");
     73//      ret = (match_str == NULL) ? ret : EOK;
    6474        if (ret < 0) {
    65                 usb_log_error("Failed to create root hub match-id string.\n");
     75                usb_log_error(
     76                    "Failed(%d) to create root hub match-id string.\n", ret);
    6677                return ret;
    6778        }
     
    107118        rh_init(&instance->rh, dev, instance->registers);
    108119
     120        hc_init_memory(instance);
    109121        hc_init_hw(instance);
    110122
     
    117129        assert(instance);
    118130        assert(batch);
     131
     132        /* check for root hub communication */
    119133        if (batch->target.address == instance->rh.address) {
    120134                return rh_request(&instance->rh, batch);
    121135        }
    122         /* TODO: implement */
    123         return ENOTSUP;
     136
     137        transfer_list_add_batch(
     138            instance->transfers[batch->transfer_type], batch);
     139
     140        switch (batch->transfer_type) {
     141        case USB_TRANSFER_CONTROL:
     142                instance->registers->command_status |= CS_CLF;
     143                break;
     144        case USB_TRANSFER_BULK:
     145                instance->registers->command_status |= CS_BLF;
     146                break;
     147        default:
     148                break;
     149        }
     150        return EOK;
    124151}
    125152/*----------------------------------------------------------------------------*/
     
    134161        usb_log_info("OHCI interrupt: %x.\n", status);
    135162
    136         /* TODO: Check for further interrupt causes */
    137         /* TODO: implement */
     163        LIST_INITIALIZE(done);
     164        transfer_list_remove_finished(&instance->transfers_interrupt, &done);
     165        transfer_list_remove_finished(&instance->transfers_isochronous, &done);
     166        transfer_list_remove_finished(&instance->transfers_control, &done);
     167        transfer_list_remove_finished(&instance->transfers_bulk, &done);
     168
     169        while (!list_empty(&done)) {
     170                link_t *item = done.next;
     171                list_remove(item);
     172                usb_transfer_batch_t *batch =
     173                    list_get_instance(item, usb_transfer_batch_t, link);
     174                usb_transfer_batch_finish(batch);
     175        }
    138176}
    139177/*----------------------------------------------------------------------------*/
     
    197235        assert(instance);
    198236        const uint32_t fm_interval = instance->registers->fm_interval;
     237
     238        /* reset hc */
    199239        instance->registers->command_status = CS_HCR;
    200240        async_usleep(10);
     241
     242        /* restore fm_interval */
    201243        instance->registers->fm_interval = fm_interval;
    202244        assert((instance->registers->command_status & CS_HCR) == 0);
     245
    203246        /* hc is now in suspend state */
    204         /* TODO: init HCCA block */
    205         /* TODO: init queues */
    206         /* TODO: enable queues */
     247
     248        /* enable queues */
     249        instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
    207250        /* TODO: enable interrupts */
    208         /* TODO: set periodic start to 90% */
     251        /* set periodic start to 90% */
     252        instance->registers->periodic_start = (fm_interval / 10) * 9;
    209253
    210254        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
    211255        usb_log_info("OHCI HC up and running.\n");
     256}
     257/*----------------------------------------------------------------------------*/
     258int hc_init_transfer_lists(hc_t *instance)
     259{
     260        assert(instance);
     261
     262#define SETUP_TRANSFER_LIST(type, name) \
     263do { \
     264        int ret = transfer_list_init(&instance->type, name); \
     265        if (ret != EOK) { \
     266                usb_log_error("Failed(%d) to setup %s transfer list.\n", \
     267                    ret, name); \
     268                transfer_list_fini(&instance->transfers_isochronous); \
     269                transfer_list_fini(&instance->transfers_interrupt); \
     270                transfer_list_fini(&instance->transfers_control); \
     271                transfer_list_fini(&instance->transfers_bulk); \
     272        } \
     273} while (0)
     274
     275        SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS");
     276        SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT");
     277        SETUP_TRANSFER_LIST(transfers_control, "CONTROL");
     278        SETUP_TRANSFER_LIST(transfers_bulk, "BULK");
     279
     280        transfer_list_set_next(&instance->transfers_interrupt,
     281            &instance->transfers_isochronous);
     282
     283        /* Assign pointers to be used during scheduling */
     284        instance->transfers[USB_TRANSFER_INTERRUPT] =
     285          &instance->transfers_interrupt;
     286        instance->transfers[USB_TRANSFER_ISOCHRONOUS] =
     287          &instance->transfers_interrupt;
     288        instance->transfers[USB_TRANSFER_CONTROL] =
     289          &instance->transfers_control;
     290        instance->transfers[USB_TRANSFER_BULK] =
     291          &instance->transfers_bulk;
     292
     293        return EOK;
     294#undef CHECK_RET_CLEAR_RETURN
     295}
     296/*----------------------------------------------------------------------------*/
     297int hc_init_memory(hc_t *instance)
     298{
     299        assert(instance);
     300        /* init queues */
     301        hc_init_transfer_lists(instance);
     302
     303        /* init HCCA */
     304        instance->hcca = malloc32(sizeof(hcca_t));
     305        if (instance->hcca == NULL)
     306                return ENOMEM;
     307        bzero(instance->hcca, sizeof(hcca_t));
     308        instance->registers->hcca = addr_to_phys(instance->hcca);
     309
     310        /* use queues */
     311        instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
     312        instance->registers->control_head =
     313            instance->transfers_control.list_head_pa;
     314
     315        unsigned i = 0;
     316        for (; i < 32; ++i) {
     317                instance->hcca->int_ep[i] =
     318                    instance->transfers_interrupt.list_head_pa;
     319        }
     320
     321        return EOK;
    212322}
    213323/**
Note: See TracChangeset for help on using the changeset viewer.