Changeset 293de44 in mainline for uspace/drv/ohci/hc.c


Ignore:
Timestamp:
2011-05-20T11:18:53Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c7c2443
Parents:
160b75e (diff), 7941bd6 (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

    r160b75e r293de44  
    5151static int hc_init_memory(hc_t *instance);
    5252/*----------------------------------------------------------------------------*/
     53/** Announce OHCI root hub to the DDF
     54 *
     55 * @param[in] instance OHCI driver intance
     56 * @param[in] hub_fun DDF fuction representing OHCI root hub
     57 * @return Error code
     58 */
    5359int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
    5460{
     
    5662        assert(hub_fun);
    5763
    58         int ret;
    59 
    60         usb_address_t hub_address =
     64        const usb_address_t hub_address =
    6165            device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
    6266        if (hub_address <= 0) {
    63                 usb_log_error("Failed to get OHCI root hub address.\n");
     67                usb_log_error("Failed(%d) to get OHCI root hub address.\n",
     68                    hub_address);
    6469                return hub_address;
    6570        }
     
    6873            &instance->manager, hub_address, hub_fun->handle);
    6974
    70         ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL,
     75#define CHECK_RET_RELEASE(ret, message...) \
     76if (ret != EOK) { \
     77        usb_log_error(message); \
     78        hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \
     79        usb_device_keeper_release(&instance->manager, hub_address); \
     80        return ret; \
     81} else (void)0
     82
     83        int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL,
    7184            USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0);
    72         if (ret != EOK) {
    73                 usb_log_error("Failed to add OHCI rh endpoint 0.\n");
    74                 usb_device_keeper_release(&instance->manager, hub_address);
    75                 return ret;
    76         }
     85        CHECK_RET_RELEASE(ret, "Failed(%d) to add OHCI rh endpoint 0.\n", ret);
    7786
    7887        char *match_str = NULL;
    7988        /* DDF needs heap allocated string */
    8089        ret = asprintf(&match_str, "usb&class=hub");
    81         if (ret < 0) {
    82                 usb_log_error(
    83                     "Failed(%d) to create root hub match-id string.\n", ret);
    84                 usb_device_keeper_release(&instance->manager, hub_address);
    85                 return ret;
    86         }
     90        ret = ret > 0 ? 0 : ret;
     91        CHECK_RET_RELEASE(ret, "Failed(%d) to create match-id string.\n", ret);
    8792
    8893        ret = ddf_fun_add_match_id(hub_fun, match_str, 100);
    89         if (ret != EOK) {
    90                 usb_log_error("Failed add root hub match-id.\n");
    91         }
     94        CHECK_RET_RELEASE(ret, "Failed(%d) add root hub match-id.\n", ret);
     95
    9296        ret = ddf_fun_bind(hub_fun);
    93         return ret;
    94 }
    95 /*----------------------------------------------------------------------------*/
     97        CHECK_RET_RELEASE(ret, "Failed(%d) to bind root hub function.\n", ret);
     98
     99        return EOK;
     100#undef CHECK_RET_RELEASE
     101}
     102/*----------------------------------------------------------------------------*/
     103/** Initialize OHCI hc driver structure
     104 *
     105 * @param[in] instance Memory place for the structure.
     106 * @param[in] regs Address of the memory mapped I/O registers.
     107 * @param[in] reg_size Size of the memory mapped area.
     108 * @param[in] interrupts True if w interrupts should be used
     109 * @return Error code
     110 */
    96111int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts)
    97112{
     
    121136#undef CHECK_RET_RETURN
    122137
    123 
    124 //      hc_init_hw(instance);
     138        fibril_mutex_initialize(&instance->guard);
    125139        hc_gain_control(instance);
    126         fibril_mutex_initialize(&instance->guard);
    127140
    128141        rh_init(&instance->rh, instance->registers);
     
    137150}
    138151/*----------------------------------------------------------------------------*/
     152/** Create end register endpoint structures
     153 *
     154 * @param[in] instance OHCI driver structure.
     155 * @param[in] address USB address of the device.
     156 * @param[in] endpoint USB endpoint number.
     157 * @param[in] speed Communication speeed of the device.
     158 * @param[in] type Endpoint's transfer type.
     159 * @param[in] direction Endpoint's direction.
     160 * @param[in] mps Maximum packet size the endpoint accepts.
     161 * @param[in] size Maximum allowed buffer size.
     162 * @param[in] interval Time between transfers(interrupt transfers only).
     163 * @return Error code
     164 */
    139165int hc_add_endpoint(
    140166    hc_t *instance, usb_address_t address, usb_endpoint_t endpoint,
     
    194220}
    195221/*----------------------------------------------------------------------------*/
     222/** Dequeue and delete endpoint structures
     223 *
     224 * @param[in] instance OHCI hc driver structure.
     225 * @param[in] address USB address of the device.
     226 * @param[in] endpoint USB endpoint number.
     227 * @param[in] direction Direction of the endpoint.
     228 * @return Error code
     229 */
    196230int hc_remove_endpoint(hc_t *instance, usb_address_t address,
    197231    usb_endpoint_t endpoint, usb_direction_t direction)
     
    244278}
    245279/*----------------------------------------------------------------------------*/
     280/** Get access to endpoint structures
     281 *
     282 * @param[in] instance OHCI hc driver structure.
     283 * @param[in] address USB address of the device.
     284 * @param[in] endpoint USB endpoint number.
     285 * @param[in] direction Direction of the endpoint.
     286 * @param[out] bw Reserved bandwidth.
     287 * @return Error code
     288 */
    246289endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,
    247290    usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw)
     
    255298}
    256299/*----------------------------------------------------------------------------*/
     300/** Add USB transfer to the schedule.
     301 *
     302 * @param[in] instance OHCI hc driver structure.
     303 * @param[in] batch Batch representing the transfer.
     304 * @return Error code.
     305 */
    257306int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
    258307{
     
    261310        assert(batch->ep);
    262311
    263         /* check for root hub communication */
     312        /* Check for root hub communication */
    264313        if (batch->ep->address == instance->rh.address) {
    265314                return rh_request(&instance->rh, batch);
     
    269318        list_append(&batch->link, &instance->pending_batches);
    270319        batch_commit(batch);
    271         switch (batch->ep->transfer_type) {
     320
     321        /* Control and bulk schedules need a kick to start working */
     322        switch (batch->ep->transfer_type)
     323        {
    272324        case USB_TRANSFER_CONTROL:
    273325                instance->registers->command_status |= CS_CLF;
     
    279331                break;
    280332        }
    281 
    282333        fibril_mutex_unlock(&instance->guard);
    283334        return EOK;
    284335}
    285336/*----------------------------------------------------------------------------*/
     337/** Interrupt handling routine
     338 *
     339 * @param[in] instance OHCI hc driver structure.
     340 * @param[in] status Value of the status register at the time of interrupt.
     341 */
    286342void hc_interrupt(hc_t *instance, uint32_t status)
    287343{
     
    292348        if (status & I_RHSC)
    293349                rh_interrupt(&instance->rh);
    294 
    295350
    296351        if (status & I_WDH) {
     
    316371                fibril_mutex_unlock(&instance->guard);
    317372        }
    318 }
    319 /*----------------------------------------------------------------------------*/
     373
     374        if (status & I_UE) {
     375                hc_start_hw(instance);
     376        }
     377
     378}
     379/*----------------------------------------------------------------------------*/
     380/** Check status register regularly
     381 *
     382 * @param[in] instance OHCI hc driver structure.
     383 * @return Error code
     384 */
    320385int interrupt_emulator(hc_t *instance)
    321386{
     
    326391                instance->registers->interrupt_status = status;
    327392                hc_interrupt(instance, status);
    328                 async_usleep(50000);
     393                async_usleep(10000);
    329394        }
    330395        return EOK;
    331396}
    332397/*----------------------------------------------------------------------------*/
     398/** Turn off any (BIOS)driver that might be in control of the device.
     399 *
     400 * @param[in] instance OHCI hc driver structure.
     401 */
    333402void hc_gain_control(hc_t *instance)
    334403{
     
    380449}
    381450/*----------------------------------------------------------------------------*/
     451/** OHCI hw initialization routine.
     452 *
     453 * @param[in] instance OHCI hc driver structure.
     454 */
    382455void hc_start_hw(hc_t *instance)
    383456{
     
    447520}
    448521/*----------------------------------------------------------------------------*/
     522/** Initialize schedule queues
     523 *
     524 * @param[in] instance OHCI hc driver structure
     525 * @return Error code
     526 */
    449527int hc_init_transfer_lists(hc_t *instance)
    450528{
    451529        assert(instance);
    452 
    453530#define SETUP_ENDPOINT_LIST(type) \
    454531do { \
     
    458535                usb_log_error("Failed(%d) to setup %s endpoint list.\n", \
    459536                    ret, name); \
    460                 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \
     537                endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]);\
    461538                endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \
    462539                endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \
    463540                endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \
     541                return ret; \
    464542        } \
    465543} while (0)
     
    476554}
    477555/*----------------------------------------------------------------------------*/
     556/** Initialize memory structures used by the OHCI hcd.
     557 *
     558 * @param[in] instance OHCI hc driver structure.
     559 * @return Error code.
     560 */
    478561int hc_init_memory(hc_t *instance)
    479562{
     
    502585        /* Init interrupt code */
    503586        instance->interrupt_code.cmds = instance->interrupt_commands;
     587        instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
    504588        {
    505589                /* Read status register */
     
    521605                instance->interrupt_commands[2].srcarg = 2;
    522606
    523                 /* Write clean status register */
     607                /* Write-clean status register */
    524608                instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
    525609                instance->interrupt_commands[3].srcarg = 1;
     
    529613                /* Accept interrupt */
    530614                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
    531 
    532                 instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
    533615        }
    534616
Note: See TracChangeset for help on using the changeset viewer.