Changeset cffa14e6 in mainline


Ignore:
Timestamp:
2013-07-24T17:27:56Z (11 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
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/main.c

    rc442f63 rcffa14e6  
    3333 * Main routines of EHCI driver.
    3434 */
    35 
    3635#include <ddf/driver.h>
    3736#include <ddf/interrupt.h>
    3837#include <device/hw_res.h>
    3938#include <errno.h>
    40 #include <stdbool.h>
    4139#include <str_error.h>
    4240
     
    7270static int ehci_dev_add(ddf_dev_t *device)
    7371{
    74         ddf_fun_t *hc_fun = NULL;
    75         bool fun_bound = false;
    76 
    7772        assert(device);
     73#define CHECK_RET_RETURN(ret, message...) \
     74if (ret != EOK) { \
     75        usb_log_error(message); \
     76        return ret; \
     77}
    7878
    7979        uintptr_t reg_base = 0;
     
    8181        int irq = 0;
    8282
    83         int rc = get_my_registers(device, &reg_base, &reg_size, &irq);
    84         if (rc != EOK) {
    85                 usb_log_error("Failed to get memory addresses for %" PRIun
    86                     ": %s.\n", ddf_dev_get_handle(device), str_error(rc));
    87                 goto error;
    88         }
    89 
     83        int ret = get_my_registers(device, &reg_base, &reg_size, &irq);
     84        CHECK_RET_RETURN(ret,
     85            "Failed to get memory addresses for %" PRIun ": %s.\n",
     86            ddf_dev_get_handle(device), str_error(ret));
    9087        usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
    9188            reg_base, reg_size, irq);
    9289
    93         rc = disable_legacy(device, reg_base, reg_size);
    94         if (rc != EOK) {
    95                 usb_log_error("Failed to disable legacy USB: %s.\n",
    96                     str_error(rc));
    97                 goto error;
    98         }
     90        ret = disable_legacy(device, reg_base, reg_size);
     91        CHECK_RET_RETURN(ret,
     92            "Failed to disable legacy USB: %s.\n", str_error(ret));
    9993
    100         hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
     94        ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
    10195        if (hc_fun == NULL) {
    10296                usb_log_error("Failed to create EHCI function.\n");
    103                 rc = ENOMEM;
    104                 goto error;
     97                return ENOMEM;
    10598        }
    106 
    10799        hcd_t *ehci_hc = ddf_fun_data_alloc(hc_fun, sizeof(hcd_t));
    108100        if (ehci_hc == NULL) {
    109101                usb_log_error("Failed to alloc generic HC driver.\n");
    110                 rc = ENOMEM;
    111                 goto error;
     102                return ENOMEM;
    112103        }
    113 
    114104        /* High Speed, no bandwidth */
    115105        hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL);
    116106        ddf_fun_set_ops(hc_fun,  &hc_ops);
    117107
    118         rc = ddf_fun_bind(hc_fun);
    119         if (rc != EOK) {
    120                 usb_log_error("Failed to bind EHCI function: %s.\n",
    121                     str_error(rc));
    122                 goto error;
    123         }
    124 
    125         fun_bound = true;
    126 
    127         rc = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
    128         if (rc != EOK) {
    129                 usb_log_error("Failed to add EHCI to HC class: %s.\n",
    130                     str_error(rc));
    131                 goto error;
    132         }
     108        ret = ddf_fun_bind(hc_fun);
     109        CHECK_RET_RETURN(ret,
     110            "Failed to bind EHCI function: %s.\n",
     111            str_error(ret));
     112        ret = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
     113        CHECK_RET_RETURN(ret,
     114            "Failed to add EHCI to HC class: %s.\n",
     115            str_error(ret));
    133116
    134117        usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
     
    136119
    137120        return EOK;
    138 error:
    139         if (fun_bound)
    140                 ddf_fun_unbind(hc_fun);
    141         if (hc_fun != NULL)
    142                 ddf_fun_destroy(hc_fun);
    143         return rc;
     121#undef CHECK_RET_RETURN
    144122}
    145123
  • uspace/drv/bus/usb/ehci/res.c

    rc442f63 rcffa14e6  
    145145                return ENOMEM;
    146146
     147#define CHECK_RET_HANGUP_RETURN(ret, message...) \
     148        if (ret != EOK) { \
     149                usb_log_error(message); \
     150                async_hangup(parent_sess); \
     151                return ret; \
     152        } else (void)0
     153
    147154        /* Read the first EEC. i.e. Legacy Support register */
    148155        uint32_t usblegsup;
    149         int rc = pci_config_space_read_32(parent_sess,
     156        int ret = pci_config_space_read_32(parent_sess,
    150157            eecp + USBLEGSUP_OFFSET, &usblegsup);
    151         if (rc != EOK) {
    152                 usb_log_error("Failed to read USBLEGSUP: %s.\n",
    153                     str_error(rc));
    154                 goto error;
    155         }
    156 
     158        CHECK_RET_HANGUP_RETURN(ret,
     159            "Failed to read USBLEGSUP: %s.\n", str_error(ret));
    157160        usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
    158161
     
    160163         * byte. (OS Control semaphore)*/
    161164        usb_log_debug("Requesting OS control.\n");
    162         rc = pci_config_space_write_8(parent_sess,
     165        ret = pci_config_space_write_8(parent_sess,
    163166            eecp + USBLEGSUP_OFFSET + 3, 1);
    164         if (rc != EOK) {
    165                 usb_log_error("Failed to request OS EHCI control: %s.\n",
    166                     str_error(rc));
    167                 goto error;
    168         }
     167        CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n",
     168            str_error(ret));
    169169
    170170        size_t wait = 0;
    171171        /* Wait for BIOS to release control. */
    172         rc = pci_config_space_read_32(
     172        ret = pci_config_space_read_32(
    173173            parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup);
    174         if (rc != EOK) {
    175                 usb_log_error("Failed reading PCI config space: %s.\n",
    176                     str_error(rc));
    177                 goto error;
    178         }
    179 
    180174        while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
    181175                async_usleep(WAIT_STEP);
    182                 rc = pci_config_space_read_32(parent_sess,
     176                ret = pci_config_space_read_32(parent_sess,
    183177                    eecp + USBLEGSUP_OFFSET, &usblegsup);
    184                 if (rc != EOK) {
    185                         usb_log_error("Failed reading PCI config space: %s.\n",
    186                             str_error(rc));
    187                         goto error;
    188                 }
    189178                wait += WAIT_STEP;
    190179        }
     
    199188        usb_log_warning( "BIOS failed to release control after "
    200189            "%zu usecs, force it.\n", wait);
    201         rc = pci_config_space_write_32(parent_sess,
     190        ret = pci_config_space_write_32(parent_sess,
    202191            eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL);
    203         if (rc != EOK) {
    204                 usb_log_error("Failed to force OS control: "
    205                     "%s.\n", str_error(rc));
    206                 goto error;
    207         }
    208 
     192        CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: "
     193            "%s.\n", str_error(ret));
    209194        /*
    210195         * Check capability type here, value of 01h identifies the capability
     
    216201                /* Read the second EEC Legacy Support and Control register */
    217202                uint32_t usblegctlsts;
    218                 rc = pci_config_space_read_32(parent_sess,
     203                ret = pci_config_space_read_32(parent_sess,
    219204                    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
    220                 if (rc != EOK) {
    221                         usb_log_error("Failed to get USBLEGCTLSTS: %s.\n",
    222                             str_error(rc));
    223                         goto error;
    224                 }
    225 
     205                CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n",
     206                    str_error(ret));
    226207                usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts);
    227208                /*
     
    230211                 * interfering. NOTE: Three upper bits are WC
    231212                 */
    232                 rc = pci_config_space_write_32(parent_sess,
     213                ret = pci_config_space_write_32(parent_sess,
    233214                    eecp + USBLEGCTLSTS_OFFSET, 0xe0000000);
    234                 if (rc != EOK) {
    235                         usb_log_error("Failed(%d) zero USBLEGCTLSTS.\n", rc);
    236                         goto error;
    237                 }
    238 
     215                CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
    239216                udelay(10);
    240                 rc = pci_config_space_read_32(parent_sess,
     217                ret = pci_config_space_read_32(parent_sess,
    241218                    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
    242                 if (rc != EOK) {
    243                         usb_log_error("Failed to get USBLEGCTLSTS 2: %s.\n",
    244                             str_error(rc));
    245                         goto error;
    246                 }
    247 
     219                CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n",
     220                    str_error(ret));
    248221                usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
    249222                    usblegctlsts);
     
    251224
    252225        /* Read again Legacy Support register */
    253         rc = pci_config_space_read_32(parent_sess,
     226        ret = pci_config_space_read_32(parent_sess,
    254227            eecp + USBLEGSUP_OFFSET, &usblegsup);
    255         if (rc != EOK) {
    256                 usb_log_error("Failed to read USBLEGSUP: %s.\n",
    257                     str_error(rc));
    258                 goto error;
    259         }
    260 
     228        CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n",
     229            str_error(ret));
    261230        usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
    262231        async_hangup(parent_sess);
    263232        return EOK;
    264 error:
    265         async_hangup(parent_sess);
    266         return rc;
     233#undef CHECK_RET_HANGUP_RETURN
    267234}
    268235
     
    272239        usb_log_debug("Disabling EHCI legacy support.\n");
    273240
     241#define CHECK_RET_RETURN(ret, message...) \
     242        if (ret != EOK) { \
     243                usb_log_error(message); \
     244                return ret; \
     245        } else (void)0
     246
    274247        /* Map EHCI registers */
    275248        void *regs = NULL;
    276         int rc = pio_enable((void*)reg_base, reg_size, &regs);
    277         if (rc != EOK) {
    278                 usb_log_error("Failed to map registers %p: %s.\n",
    279                     (void *) reg_base, str_error(rc));
    280                 return rc;
    281         }
     249        int ret = pio_enable((void*)reg_base, reg_size, &regs);
     250        CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n",
     251            (void *) reg_base, str_error(ret));
    282252
    283253        usb_log_debug2("Registers mapped at: %p.\n", regs);
     
    293263        usb_log_debug("Value of EECP: %x.\n", eecp);
    294264
    295         rc = disable_extended_caps(device, eecp);
    296         if (rc != EOK) {
    297                 usb_log_error("Failed to disable extended capabilities: %s.\n",
    298                     str_error(rc));
    299                 return rc;
    300         }
     265        ret = disable_extended_caps(device, eecp);
     266        CHECK_RET_RETURN(ret, "Failed to disable extended capabilities: %s.\n",
     267            str_error(ret));
     268
     269#undef CHECK_RET_RETURN
    301270
    302271        /*
     
    337306            usbcmd, *usbcmd, usbsts, *usbsts, usbint, *usbint, usbconf,*usbconf);
    338307
    339         return rc;
     308        return ret;
    340309}
    341310
  • 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/**
  • uspace/drv/bus/usb/uhci/hc.c

    rc442f63 rcffa14e6  
    9090static int hc_debug_checker(void *arg);
    9191
    92 enum {
    93         /** Number of PIO ranges used in IRQ code */
    94         hc_irq_pio_range_count =
    95             sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t),
    96 
    97         /* Number of commands used in IRQ code */
    98         hc_irq_cmd_count =
    99             sizeof(uhci_irq_commands) / sizeof(irq_cmd_t)
    100 };
     92
     93/** Get number of PIO ranges used in IRQ code.
     94 * @return Number of ranges.
     95 */
     96size_t hc_irq_pio_range_count(void)
     97{
     98        return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t);
     99}
     100
     101/** Get number of commands used in IRQ code.
     102 * @return Number of commands.
     103 */
     104size_t hc_irq_cmd_count(void)
     105{
     106        return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t);
     107}
    101108
    102109/** Generate IRQ code.
     
    126133        cmds[0].addr = &registers->usbsts;
    127134        cmds[3].addr = &registers->usbsts;
    128 
    129         return EOK;
    130 }
    131 
    132 /** Register interrupt handler.
    133  *
    134  * @param[in] device Host controller DDF device
    135  * @param[in] reg_base Register range base
    136  * @param[in] reg_size Register range size
    137  * @param[in] irq Interrupt number
    138  * @paran[in] handler Interrupt handler
    139  *
    140  * @return EOK on success or negative error code
    141  */
    142 int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size,
    143     int irq, interrupt_handler_t handler)
    144 {
    145         int rc;
    146         irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
    147         irq_cmd_t irq_cmds[hc_irq_cmd_count];
    148         rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    149             sizeof(irq_cmds), reg_base, reg_size);
    150         if (rc != EOK) {
    151                 usb_log_error("Failed to generate IRQ commands: %s.\n",
    152                     str_error(rc));
    153                 return rc;
    154         }
    155 
    156         irq_code_t irq_code = {
    157                 .rangecount = hc_irq_pio_range_count,
    158                 .ranges = irq_ranges,
    159                 .cmdcount = hc_irq_cmd_count,
    160                 .cmds = irq_cmds
    161         };
    162 
    163         /* Register handler to avoid interrupt lockup */
    164         rc = register_interrupt_handler(device, irq, handler, &irq_code);
    165         if (rc != EOK) {
    166                 usb_log_error("Failed to register interrupt handler: %s.\n",
    167                     str_error(rc));
    168                 return rc;
    169         }
    170135
    171136        return EOK;
     
    244209{
    245210        assert(reg_size >= sizeof(uhci_regs_t));
    246         int rc;
     211        int ret;
     212
     213#define CHECK_RET_RETURN(ret, message...) \
     214        if (ret != EOK) { \
     215                usb_log_error(message); \
     216                return ret; \
     217        } else (void) 0
    247218
    248219        instance->hw_interrupts = interrupts;
     
    251222        /* allow access to hc control registers */
    252223        uhci_regs_t *io;
    253         rc = pio_enable(regs, reg_size, (void **)&io);
    254         if (rc != EOK) {
    255                 usb_log_error("Failed to gain access to registers at %p: %s.\n",
    256                     io, str_error(rc));
    257                 return rc;
    258         }
    259 
     224        ret = pio_enable(regs, reg_size, (void **)&io);
     225        CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n",
     226            io, str_error(ret));
    260227        instance->registers = io;
    261228        usb_log_debug(
    262229            "Device registers at %p (%zuB) accessible.\n", io, reg_size);
    263230
    264         rc = hc_init_mem_structures(instance);
    265         if (rc != EOK) {
    266                 usb_log_error("Failed to initialize UHCI memory structures: %s.\n",
    267                     str_error(rc));
    268                 return rc;
    269         }
     231        ret = hc_init_mem_structures(instance);
     232        CHECK_RET_RETURN(ret,
     233            "Failed to initialize UHCI memory structures: %s.\n",
     234            str_error(ret));
     235
     236#undef CHECK_RET_RETURN
    270237
    271238        hcd_init(&instance->generic, USB_SPEED_FULL,
     
    430397
    431398        return EOK;
     399#undef CHECK_RET_CLEAR_RETURN
    432400}
    433401
  • uspace/drv/bus/usb/uhci/hc.h

    rc442f63 rcffa14e6  
    3636#define DRV_UHCI_HC_H
    3737
    38 #include <ddf/interrupt.h>
    3938#include <fibril.h>
    4039#include <usb/host/hcd.h>
     
    120119} hc_t;
    121120
    122 int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t);
     121size_t hc_irq_pio_range_count(void);
     122size_t hc_irq_cmd_count(void);
    123123int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
    124124    size_t);
  • uspace/drv/bus/usb/uhci/uhci.c

    rc442f63 rcffa14e6  
    3838
    3939#include <errno.h>
    40 #include <stdbool.h>
    4140#include <str_error.h>
    4241#include <ddf/interrupt.h>
     
    150149int device_setup_uhci(ddf_dev_t *device)
    151150{
    152         bool ih_registered = false;
    153         bool hc_inited = false;
    154         bool fun_bound = false;
    155         int rc;
    156 
    157151        if (!device)
    158152                return EBADMEM;
     
    164158        }
    165159
     160#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     161if (ret != EOK) { \
     162        if (instance->hc_fun) \
     163                ddf_fun_destroy(instance->hc_fun); \
     164        if (instance->rh_fun) {\
     165                ddf_fun_destroy(instance->rh_fun); \
     166        } \
     167        usb_log_error(message); \
     168        return ret; \
     169} else (void)0
     170
     171        instance->rh_fun = NULL;
    166172        instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc");
    167         if (instance->hc_fun == NULL) {
    168                 usb_log_error("Failed to create UHCI HC function.\n");
    169                 rc = ENOMEM;
    170                 goto error;
    171         }
    172 
     173        int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
     174        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
    173175        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    174176        ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic);
    175177
    176178        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
    177         if (instance->rh_fun == NULL) {
    178                 usb_log_error("Failed to create UHCI RH function.\n");
    179                 rc = ENOMEM;
    180                 goto error;
    181         }
    182 
     179        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
     180        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
    183181        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    184182        ddf_fun_data_implant(instance->rh_fun, &instance->rh);
     
    188186        int irq = 0;
    189187
    190         rc = get_my_registers(device, &reg_base, &reg_size, &irq);
    191         if (rc != EOK) {
    192                 usb_log_error("Failed to get I/O addresses for %" PRIun ": %s.\n",
    193                     ddf_dev_get_handle(device), str_error(rc));
    194                 goto error;
    195         }
     188        ret = get_my_registers(device, &reg_base, &reg_size, &irq);
     189        CHECK_RET_DEST_FREE_RETURN(ret,
     190            "Failed to get I/O addresses for %" PRIun ": %s.\n",
     191            ddf_dev_get_handle(device), str_error(ret));
    196192        usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
    197193            (void *) reg_base, reg_size, irq);
    198194
    199         rc = disable_legacy(device);
    200         if (rc != EOK) {
    201                 usb_log_error("Failed to disable legacy USB: %s.\n",
    202                     str_error(rc));
    203                 goto error;
    204         }
    205 
    206         rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler);
    207         if (rc != EOK) {
    208                 usb_log_error("Failed to register interrupt handler: %s.\n",
    209                     str_error(rc));
    210                 goto error;
    211         }
    212 
    213         ih_registered = true;
     195        ret = disable_legacy(device);
     196        CHECK_RET_DEST_FREE_RETURN(ret,
     197            "Failed to disable legacy USB: %s.\n", str_error(ret));
     198
     199        const size_t ranges_count = hc_irq_pio_range_count();
     200        const size_t cmds_count = hc_irq_cmd_count();
     201        irq_pio_range_t irq_ranges[ranges_count];
     202        irq_cmd_t irq_cmds[cmds_count];
     203        ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     204            sizeof(irq_cmds), reg_base, reg_size);
     205        CHECK_RET_DEST_FREE_RETURN(ret,
     206            "Failed to generate IRQ commands: %s.\n", str_error(ret));
     207
     208        irq_code_t irq_code = {
     209                .rangecount = ranges_count,
     210                .ranges = irq_ranges,
     211                .cmdcount = cmds_count,
     212                .cmds = irq_cmds
     213        };
     214
     215        /* Register handler to avoid interrupt lockup */
     216        ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
     217        CHECK_RET_DEST_FREE_RETURN(ret,
     218            "Failed to register interrupt handler: %s.\n", str_error(ret));
    214219
    215220        bool interrupts = false;
    216         rc = enable_interrupts(device);
    217         if (rc != EOK) {
     221        ret = enable_interrupts(device);
     222        if (ret != EOK) {
    218223                usb_log_warning("Failed to enable interrupts: %s."
    219                     " Falling back to polling.\n", str_error(rc));
     224                    " Falling back to polling.\n", str_error(ret));
    220225        } else {
    221226                usb_log_debug("Hw interrupts enabled.\n");
     
    223228        }
    224229
    225         rc = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
    226         if (rc != EOK) {
    227                 usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc));
    228                 goto error;
    229         }
    230 
    231         hc_inited = true;
    232 
    233         rc = ddf_fun_bind(instance->hc_fun);
    234         if (rc != EOK) {
    235                 usb_log_error("Failed to bind UHCI device function: %s.\n",
    236                     str_error(rc));
    237                 goto error;
    238         }
    239 
    240         fun_bound = true;
    241 
    242         rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    243         if (rc != EOK) {
    244                 usb_log_error("Failed to add UHCI to HC class: %s.\n",
    245                     str_error(rc));
    246                 goto error;
    247         }
    248 
    249         rc = rh_init(&instance->rh, instance->rh_fun,
     230        ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
     231        CHECK_RET_DEST_FREE_RETURN(ret,
     232            "Failed to init uhci_hcd: %s.\n", str_error(ret));
     233
     234#define CHECK_RET_FINI_RETURN(ret, message...) \
     235if (ret != EOK) { \
     236        hc_fini(&instance->hc); \
     237        CHECK_RET_DEST_FREE_RETURN(ret, message); \
     238        return ret; \
     239} else (void)0
     240
     241        ret = ddf_fun_bind(instance->hc_fun);
     242        CHECK_RET_FINI_RETURN(ret, "Failed to bind UHCI device function: %s.\n",
     243            str_error(ret));
     244
     245        ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     246        CHECK_RET_FINI_RETURN(ret,
     247            "Failed to add UHCI to HC class: %s.\n", str_error(ret));
     248
     249        ret = rh_init(&instance->rh, instance->rh_fun,
    250250            (uintptr_t)instance->hc.registers + 0x10, 4);
    251         if (rc != EOK) {
    252                 usb_log_error("Failed to setup UHCI root hub: %s.\n",
    253                     str_error(rc));
    254                 goto error;
    255         }
    256 
    257         rc = ddf_fun_bind(instance->rh_fun);
    258         if (rc != EOK) {
    259                 usb_log_error("Failed to register UHCI root hub: %s.\n",
    260                     str_error(rc));
    261                 goto error;
    262         }
     251        CHECK_RET_FINI_RETURN(ret,
     252            "Failed to setup UHCI root hub: %s.\n", str_error(ret));
     253
     254        ret = ddf_fun_bind(instance->rh_fun);
     255        CHECK_RET_FINI_RETURN(ret,
     256            "Failed to register UHCI root hub: %s.\n", str_error(ret));
    263257
    264258        return EOK;
    265 
    266 error:
    267         if (fun_bound)
    268                 ddf_fun_unbind(instance->hc_fun);
    269         if (hc_inited)
    270                 hc_fini(&instance->hc);
    271         if (ih_registered)
    272                 unregister_interrupt_handler(device, irq);
    273         if (instance->hc_fun != NULL)
    274                 ddf_fun_destroy(instance->hc_fun);
    275         if (instance->rh_fun != NULL) {
    276                 ddf_fun_destroy(instance->rh_fun);
    277         }
    278         return rc;
     259#undef CHECK_RET_FINI_RETURN
    279260}
    280261/**
  • uspace/drv/bus/usb/uhcirh/main.c

    rc442f63 rcffa14e6  
    9393        size_t io_size = 0;
    9494        uhci_root_hub_t *rh = NULL;
    95         int rc;
     95        int ret = EOK;
    9696
    97         rc = hc_get_my_registers(device, &io_regs, &io_size);
    98         if (rc != EOK) {
    99                 usb_log_error( "Failed to get registers from HC: %s.\n",
    100                     str_error(rc));
    101                 return rc;
    102         }
     97#define CHECK_RET_FREE_RH_RETURN(ret, message...) \
     98if (ret != EOK) { \
     99        usb_log_error(message); \
     100        return ret; \
     101} else (void)0
    103102
     103        ret = hc_get_my_registers(device, &io_regs, &io_size);
     104        CHECK_RET_FREE_RH_RETURN(ret,
     105            "Failed to get registers from HC: %s.\n", str_error(ret));
    104106        usb_log_debug("I/O regs at %p (size %zuB).\n",
    105107            (void *) io_regs, io_size);
    106108
    107109        rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t));
    108         if (rh == NULL) {
    109                 usb_log_error("Failed to allocate rh driver instance.\n");
    110                 return ENOMEM;
    111         }
     110        ret = (rh == NULL) ? ENOMEM : EOK;
     111        CHECK_RET_FREE_RH_RETURN(ret,
     112            "Failed to allocate rh driver instance.\n");
    112113
    113         rc = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
    114         if (rc != EOK) {
    115                 usb_log_error("Failed(%d) to initialize rh driver instance: "
    116                     "%s.\n", rc, str_error(rc));
    117                 return rc;
    118         }
     114        ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
     115        CHECK_RET_FREE_RH_RETURN(ret,
     116            "Failed(%d) to initialize rh driver instance: %s.\n",
     117            ret, str_error(ret));
    119118
    120119        usb_log_info("Controlling root hub '%s' (%" PRIun ").\n",
    121120            ddf_dev_get_name(device), ddf_dev_get_handle(device));
    122 
    123121        return EOK;
    124122}
  • uspace/drv/bus/usb/uhcirh/port.c

    rc442f63 rcffa14e6  
    150150{
    151151        uhci_port_t *instance = port;
    152         int rc;
    153152        assert(instance);
    154153
    155154        unsigned allowed_failures = MAX_ERROR_COUNT;
     155#define CHECK_RET_FAIL(ret, msg...) \
     156        if (ret != EOK) { \
     157                usb_log_error(msg); \
     158                if (!(allowed_failures-- > 0)) { \
     159                        usb_log_fatal( \
     160                           "Maximum number of failures reached, " \
     161                           "bailing out.\n"); \
     162                        return ret; \
     163                } \
     164                continue; \
     165        } else (void)0
    156166
    157167        while (1) {
     
    172182                    instance->id_string, port_status);
    173183
    174                 rc = usb_hc_connection_open(&instance->hc_connection);
    175                 if (rc != EOK) {
    176                         usb_log_error("%s: Failed to connect to HC %s.\n",
    177                             instance->id_string, str_error(rc));
    178                         if (!(allowed_failures-- > 0))
    179                                 goto fatal_error;
    180                         continue;
    181                 }
     184                int ret = usb_hc_connection_open(&instance->hc_connection);
     185                CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n",
     186                    instance->id_string, str_error(ret));
    182187
    183188                /* Remove any old device */
     
    199204                }
    200205
    201                 rc = usb_hc_connection_close(&instance->hc_connection);
    202                 if (rc != EOK) {
    203                         usb_log_error("%s: Failed to disconnect from HC %s.\n",
    204                             instance->id_string, str_error(rc));
    205                         if (!(allowed_failures-- > 0))
    206                                 goto fatal_error;
    207                         continue;
    208                 }
    209         }
    210 
    211         return EOK;
    212 
    213 fatal_error:
    214         usb_log_fatal("Maximum number of failures reached, bailing out.\n");
    215         return rc;
     206                ret = usb_hc_connection_close(&instance->hc_connection);
     207                CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n",
     208                    instance->id_string, str_error(ret));
     209        }
     210        return EOK;
    216211}
    217212
Note: See TracChangeset for help on using the changeset viewer.