Changeset 224174f in mainline for uspace/drv/bus/usb/ohci/hc.c


Ignore:
Timestamp:
2013-07-11T13:16:57Z (11 years ago)
Author:
Manuele Conti <conti.ma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2b3e8840, b2c96093
Parents:
990ab7d (diff), 3a67d63 (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 mainline changes

File:
1 edited

Legend:

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

    r990ab7d r224174f  
    3535
    3636#include <errno.h>
     37#include <stdbool.h>
    3738#include <str_error.h>
    3839#include <adt/list.h>
     
    8384};
    8485
     86enum {
     87        /** Number of PIO ranges used in IRQ code */
     88        hc_irq_pio_range_count =
     89            sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t),
     90
     91        /** Number of commands used in IRQ code */
     92        hc_irq_cmd_count =
     93            sizeof(ohci_irq_commands) / sizeof(irq_cmd_t)
     94};
     95
    8596static void hc_gain_control(hc_t *instance);
    8697static void hc_start(hc_t *instance);
     
    89100static int interrupt_emulator(hc_t *instance);
    90101static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    91 
    92 /** Get number of PIO ranges used in IRQ code.
    93  * @return Number of ranges.
    94  */
    95 size_t hc_irq_pio_range_count(void)
    96 {
    97         return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
    98 }
    99 
    100 /** Get number of commands used in IRQ code.
    101  * @return Number of commands.
    102  */
    103 size_t hc_irq_cmd_count(void)
    104 {
    105         return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
    106 }
    107102
    108103/** Generate IRQ code.
     
    137132}
    138133
     134/** Register interrupt handler.
     135 *
     136 * @param[in] device Host controller DDF device
     137 * @param[in] reg_base Register range base
     138 * @param[in] reg_size Register range size
     139 * @param[in] irq Interrupt number
     140 * @paran[in] handler Interrupt handler
     141 *
     142 * @return EOK on success or negative error code
     143 */
     144int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size,
     145    int irq, interrupt_handler_t handler)
     146{
     147        int rc;
     148
     149        irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
     150        irq_cmd_t irq_cmds[hc_irq_cmd_count];
     151
     152        irq_code_t irq_code = {
     153                .rangecount = hc_irq_pio_range_count,
     154                .ranges = irq_ranges,
     155                .cmdcount = hc_irq_cmd_count,
     156                .cmds = irq_cmds
     157        };
     158
     159        rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     160            sizeof(irq_cmds), reg_base, reg_size);
     161        if (rc != EOK) {
     162                usb_log_error("Failed to generate IRQ code: %s.\n",
     163                    str_error(rc));
     164                return rc;
     165        }
     166
     167        /* Register handler to avoid interrupt lockup */
     168        rc = register_interrupt_handler(device, irq, handler, &irq_code);
     169        if (rc != EOK) {
     170                usb_log_error("Failed to register interrupt handler: %s.\n",
     171                    str_error(rc));
     172                return rc;
     173        }
     174
     175        return EOK;
     176}
     177
    139178/** Announce OHCI root hub to the DDF
    140179 *
     
    145184int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
    146185{
     186        bool addr_reqd = false;
     187        bool ep_added = false;
     188        bool fun_bound = false;
     189        int rc;
     190
    147191        assert(instance);
    148192        assert(hub_fun);
     
    150194        /* Try to get address 1 for root hub. */
    151195        instance->rh.address = 1;
    152         int ret = usb_device_manager_request_address(
     196        rc = usb_device_manager_request_address(
    153197            &instance->generic.dev_manager, &instance->rh.address, false,
    154198            USB_SPEED_FULL);
    155         if (ret != EOK) {
     199        if (rc != EOK) {
    156200                usb_log_error("Failed to get OHCI root hub address: %s\n",
    157                     str_error(ret));
    158                 return ret;
    159         }
    160 
    161 #define CHECK_RET_UNREG_RETURN(ret, message...) \
    162 if (ret != EOK) { \
    163         usb_log_error(message); \
    164         usb_endpoint_manager_remove_ep( \
    165             &instance->generic.ep_manager, instance->rh.address, 0, \
    166             USB_DIRECTION_BOTH, NULL, NULL); \
    167         usb_device_manager_release_address( \
    168             &instance->generic.dev_manager, instance->rh.address); \
    169         return ret; \
    170 } else (void)0
    171 
    172         ret = usb_endpoint_manager_add_ep(
     201                    str_error(rc));
     202                goto error;
     203        }
     204
     205        addr_reqd = true;
     206
     207        rc = usb_endpoint_manager_add_ep(
    173208            &instance->generic.ep_manager, instance->rh.address, 0,
    174209            USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
    175210            0, NULL, NULL);
    176         CHECK_RET_UNREG_RETURN(ret,
    177             "Failed to register root hub control endpoint: %s.\n",
    178             str_error(ret));
    179 
    180         ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
    181         CHECK_RET_UNREG_RETURN(ret,
    182             "Failed to add root hub match-id: %s.\n", str_error(ret));
    183 
    184         ret = ddf_fun_bind(hub_fun);
    185         CHECK_RET_UNREG_RETURN(ret,
    186             "Failed to bind root hub function: %s.\n", str_error(ret));
    187 
    188         ret = usb_device_manager_bind_address(&instance->generic.dev_manager,
     211        if (rc != EOK) {
     212                usb_log_error("Failed to register root hub control endpoint: %s.\n",
     213                    str_error(rc));
     214                goto error;
     215        }
     216
     217        ep_added = true;
     218
     219        rc = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
     220        if (rc != EOK) {
     221                usb_log_error("Failed to add root hub match-id: %s.\n",
     222                    str_error(rc));
     223                goto error;
     224        }
     225
     226        rc = ddf_fun_bind(hub_fun);
     227        if (rc != EOK) {
     228                usb_log_error("Failed to bind root hub function: %s.\n",
     229                    str_error(rc));
     230                goto error;
     231        }
     232
     233        fun_bound = true;
     234
     235        rc = usb_device_manager_bind_address(&instance->generic.dev_manager,
    189236            instance->rh.address, ddf_fun_get_handle(hub_fun));
    190         if (ret != EOK)
     237        if (rc != EOK) {
    191238                usb_log_warning("Failed to bind root hub address: %s.\n",
    192                     str_error(ret));
    193 
    194         return EOK;
    195 #undef CHECK_RET_RELEASE
     239                    str_error(rc));
     240        }
     241
     242        return EOK;
     243error:
     244        if (fun_bound)
     245                ddf_fun_unbind(hub_fun);
     246        if (ep_added) {
     247                usb_endpoint_manager_remove_ep(
     248                    &instance->generic.ep_manager, instance->rh.address, 0,
     249                    USB_DIRECTION_BOTH, NULL, NULL);
     250        }
     251        if (addr_reqd) {
     252                usb_device_manager_release_address(
     253                    &instance->generic.dev_manager, instance->rh.address);
     254        }
     255        return rc;
    196256}
    197257
     
    208268        assert(instance);
    209269
    210 #define CHECK_RET_RETURN(ret, message...) \
    211 if (ret != EOK) { \
    212         usb_log_error(message); \
    213         return ret; \
    214 } else (void)0
    215 
    216         int ret =
     270        int rc =
    217271            pio_enable((void*)regs, reg_size, (void**)&instance->registers);
    218         CHECK_RET_RETURN(ret,
    219             "Failed to gain access to device registers: %s.\n", str_error(ret));
     272        if (rc != EOK) {
     273                usb_log_error("Failed to gain access to device registers: %s.\n",
     274                    str_error(rc));
     275                return rc;
     276        }
    220277
    221278        list_initialize(&instance->pending_batches);
     
    228285        instance->generic.ep_remove_hook = ohci_endpoint_fini;
    229286
    230         ret = hc_init_memory(instance);
    231         CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n",
    232             str_error(ret));
    233 #undef CHECK_RET_RETURN
     287        rc = hc_init_memory(instance);
     288        if (rc != EOK) {
     289                usb_log_error("Failed to create OHCI memory structures: %s.\n",
     290                    str_error(rc));
     291                return rc;
     292        }
    234293
    235294        fibril_mutex_initialize(&instance->guard);
Note: See TracChangeset for help on using the changeset viewer.