Changeset cffa14e6 in mainline for uspace/drv/bus/usb/ohci


Ignore:
Timestamp:
2013-07-24T17:27:56Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
db71e2a
Parents:
c442f63
Message:

revert usb hc macro changes

Location:
uspace/drv/bus/usb/ohci
Files:
3 edited

Legend:

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

    rc442f63 rcffa14e6  
    3535
    3636#include <errno.h>
    37 #include <stdbool.h>
    3837#include <str_error.h>
    3938#include <adt/list.h>
     
    8483};
    8584
    86 enum {
    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 
    9685static void hc_gain_control(hc_t *instance);
    9786static void hc_start(hc_t *instance);
     
    10089static int interrupt_emulator(hc_t *instance);
    10190static 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 */
     95size_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 */
     103size_t hc_irq_cmd_count(void)
     104{
     105        return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
     106}
    102107
    103108/** Generate IRQ code.
     
    132137}
    133138
    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  */
    144 int 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 
    178139/** Announce OHCI root hub to the DDF
    179140 *
     
    184145int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
    185146{
    186         bool addr_reqd = false;
    187         bool ep_added = false;
    188         bool fun_bound = false;
    189         int rc;
    190 
    191147        assert(instance);
    192148        assert(hub_fun);
     
    194150        /* Try to get address 1 for root hub. */
    195151        instance->rh.address = 1;
    196         rc = usb_device_manager_request_address(
     152        int ret = usb_device_manager_request_address(
    197153            &instance->generic.dev_manager, &instance->rh.address, false,
    198154            USB_SPEED_FULL);
    199         if (rc != EOK) {
     155        if (ret != EOK) {
    200156                usb_log_error("Failed to get OHCI root hub address: %s\n",
    201                     str_error(rc));
    202                 goto error;
    203         }
    204 
    205         addr_reqd = true;
    206 
    207         rc = usb_endpoint_manager_add_ep(
     157                    str_error(ret));
     158                return ret;
     159        }
     160
     161#define CHECK_RET_UNREG_RETURN(ret, message...) \
     162if (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(
    208173            &instance->generic.ep_manager, instance->rh.address, 0,
    209174            USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
    210175            0, NULL, NULL);
    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,
     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,
    236189            instance->rh.address, ddf_fun_get_handle(hub_fun));
    237         if (rc != EOK) {
     190        if (ret != EOK)
    238191                usb_log_warning("Failed to bind root hub address: %s.\n",
    239                     str_error(rc));
    240         }
     192                    str_error(ret));
    241193
    242194        return EOK;
    243 error:
    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;
     195#undef CHECK_RET_RELEASE
    256196}
    257197
     
    268208        assert(instance);
    269209
    270         int rc =
     210#define CHECK_RET_RETURN(ret, message...) \
     211if (ret != EOK) { \
     212        usb_log_error(message); \
     213        return ret; \
     214} else (void)0
     215
     216        int ret =
    271217            pio_enable((void*)regs, reg_size, (void**)&instance->registers);
    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         }
     218        CHECK_RET_RETURN(ret,
     219            "Failed to gain access to device registers: %s.\n", str_error(ret));
    277220
    278221        list_initialize(&instance->pending_batches);
     
    285228        instance->generic.ep_remove_hook = ohci_endpoint_fini;
    286229
    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         }
     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
    293234
    294235        fibril_mutex_initialize(&instance->guard);
  • uspace/drv/bus/usb/ohci/hc.h

    rc442f63 rcffa14e6  
    3535#define DRV_OHCI_HC_H
    3636
    37 #include <ddf/interrupt.h>
    3837#include <fibril.h>
    3938#include <fibril_synch.h>
     
    7574} hc_t;
    7675
     76size_t hc_irq_pio_range_count(void);
     77size_t hc_irq_cmd_count(void);
    7778int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
    7879    size_t);
    79 int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t);
    8080int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    8181int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
  • uspace/drv/bus/usb/ohci/ohci.c

    rc442f63 rcffa14e6  
    143143int device_setup_ohci(ddf_dev_t *device)
    144144{
    145         bool ih_registered = false;
    146         bool hc_inited = false;
    147         int rc;
    148 
    149145        if (device == NULL)
    150146                return EBADMEM;
     
    156152        }
    157153
     154#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     155if (ret != EOK) { \
     156        if (instance->hc_fun) { \
     157                ddf_fun_destroy(instance->hc_fun); \
     158        } \
     159        if (instance->rh_fun) { \
     160                ddf_fun_destroy(instance->rh_fun); \
     161        } \
     162        usb_log_error(message); \
     163        return ret; \
     164} else (void)0
     165
    158166        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    159         if (instance->hc_fun == NULL) {
    160                 usb_log_error("Failed to create OHCI HC function: %s.\n",
    161                     str_error(ENOMEM));
    162                 rc = ENOMEM;
    163                 goto error;
    164         }
    165 
     167        int ret = instance->hc_fun ? EOK : ENOMEM;
     168        CHECK_RET_DEST_FREE_RETURN(ret,
     169            "Failed to create OHCI HC function: %s.\n", str_error(ret));
    166170        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    167171        ddf_fun_data_implant(instance->hc_fun, &instance->hc);
    168172
    169173        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    170         if (instance->rh_fun == NULL) {
    171                 usb_log_error("Failed to create OHCI RH function: %s.\n",
    172                     str_error(ENOMEM));
    173                 rc = ENOMEM;
    174                 goto error;
    175         }
    176 
     174        ret = instance->rh_fun ? EOK : ENOMEM;
     175        CHECK_RET_DEST_FREE_RETURN(ret,
     176            "Failed to create OHCI RH function: %s.\n", str_error(ret));
    177177        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    178178
     
    181181        int irq = 0;
    182182
    183         rc = get_my_registers(device, &reg_base, &reg_size, &irq);
    184         if (rc != EOK) {
    185                 usb_log_error("Failed to get register memory addresses "
    186                     "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
    187                     str_error(rc));
    188                 goto error;
    189         }
    190 
     183        ret = get_my_registers(device, &reg_base, &reg_size, &irq);
     184        CHECK_RET_DEST_FREE_RETURN(ret,
     185            "Failed to get register memory addresses for %" PRIun ": %s.\n",
     186            ddf_dev_get_handle(device), str_error(ret));
    191187        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    192188            (void *) reg_base, reg_size, irq);
    193189
    194         rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler);
    195         if (rc != EOK) {
    196                 usb_log_error("Failed to register interrupt handler: %s.\n",
    197                     str_error(rc));
    198                 goto error;
    199         }
    200 
    201         ih_registered = true;
     190        const size_t ranges_count = hc_irq_pio_range_count();
     191        const size_t cmds_count = hc_irq_cmd_count();
     192        irq_pio_range_t irq_ranges[ranges_count];
     193        irq_cmd_t irq_cmds[cmds_count];
     194        irq_code_t irq_code = {
     195                .rangecount = ranges_count,
     196                .ranges = irq_ranges,
     197                .cmdcount = cmds_count,
     198                .cmds = irq_cmds
     199        };
     200
     201        ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     202            sizeof(irq_cmds), reg_base, reg_size);
     203        CHECK_RET_DEST_FREE_RETURN(ret,
     204            "Failed to generate IRQ code: %s.\n", str_error(ret));
     205
     206
     207        /* Register handler to avoid interrupt lockup */
     208        ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
     209        CHECK_RET_DEST_FREE_RETURN(ret,
     210            "Failed to register interrupt handler: %s.\n", str_error(ret));
    202211
    203212        /* Try to enable interrupts */
    204213        bool interrupts = false;
    205         rc = enable_interrupts(device);
    206         if (rc != EOK) {
     214        ret = enable_interrupts(device);
     215        if (ret != EOK) {
    207216                usb_log_warning("Failed to enable interrupts: %s."
    208                     " Falling back to polling\n", str_error(rc));
     217                    " Falling back to polling\n", str_error(ret));
    209218                /* We don't need that handler */
    210219                unregister_interrupt_handler(device, irq);
    211                 ih_registered = false;
    212220        } else {
    213221                usb_log_debug("Hw interrupts enabled.\n");
     
    215223        }
    216224
    217         rc = hc_init(&instance->hc, reg_base, reg_size, interrupts);
    218         if (rc != EOK) {
    219                 usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
    220                 goto error;
    221         }
    222 
    223         hc_inited = true;
    224 
    225         rc = ddf_fun_bind(instance->hc_fun);
    226         if (rc != EOK) {
    227                 usb_log_error("Failed to bind OHCI device function: %s.\n",
    228                     str_error(rc));
    229                 goto error;
    230         }
    231 
    232         rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    233         if (rc != EOK) {
    234                 usb_log_error("Failed to add OHCI to HC category: %s.\n",
    235                     str_error(rc));
    236                 goto error;
    237         }
    238 
    239         rc = hc_register_hub(&instance->hc, instance->rh_fun);
    240         if (rc != EOK) {
    241                 usb_log_error("Failed to register OHCI root hub: %s.\n",
    242                     str_error(rc));
    243                 goto error;
    244         }
    245 
    246         return EOK;
    247 
    248 error:
    249         if (hc_inited)
    250                 hc_fini(&instance->hc);
    251         if (ih_registered)
    252                 unregister_interrupt_handler(device, irq);
    253         if (instance->hc_fun != NULL)
    254                 ddf_fun_destroy(instance->hc_fun);
    255         if (instance->rh_fun != NULL)
    256                 ddf_fun_destroy(instance->rh_fun);
    257         return rc;
     225        ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
     226        CHECK_RET_DEST_FREE_RETURN(ret,
     227            "Failed to init ohci_hcd: %s.\n", str_error(ret));
     228
     229#define CHECK_RET_FINI_RETURN(ret, message...) \
     230if (ret != EOK) { \
     231        hc_fini(&instance->hc); \
     232        unregister_interrupt_handler(device, irq); \
     233        CHECK_RET_DEST_FREE_RETURN(ret, message); \
     234} else (void)0
     235
     236
     237        ret = ddf_fun_bind(instance->hc_fun);
     238        CHECK_RET_FINI_RETURN(ret,
     239            "Failed to bind OHCI device function: %s.\n", str_error(ret));
     240
     241        ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     242        CHECK_RET_FINI_RETURN(ret,
     243            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
     244
     245        ret = hc_register_hub(&instance->hc, instance->rh_fun);
     246        CHECK_RET_FINI_RETURN(ret,
     247            "Failed to register OHCI root hub: %s.\n", str_error(ret));
     248        return ret;
     249
     250#undef CHECK_RET_FINI_RETURN
    258251}
    259252/**
Note: See TracChangeset for help on using the changeset viewer.