Ignore:
File:
1 edited

Legend:

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

    rf83666c r6340a6ff  
    3535
    3636#include <errno.h>
    37 #include <stdbool.h>
    3837#include <str_error.h>
    3938#include <adt/list.h>
     
    4241#include <usb/debug.h>
    4342#include <usb/usb.h>
    44 #include <usb/ddfiface.h>
    4543
    4644#include "hc.h"
     
    8482};
    8583
    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 
    9684static void hc_gain_control(hc_t *instance);
    9785static void hc_start(hc_t *instance);
     
    9987static int hc_init_memory(hc_t *instance);
    10088static int interrupt_emulator(hc_t *instance);
    101 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
     89
     90/** Get number of PIO ranges used in IRQ code.
     91 * @return Number of ranges.
     92 */
     93size_t hc_irq_pio_range_count(void)
     94{
     95        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
     96}
     97
     98/** Get number of commands used in IRQ code.
     99 * @return Number of commands.
     100 */
     101size_t hc_irq_cmd_count(void)
     102{
     103        return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
     104}
    102105
    103106/** Generate IRQ code.
     
    132135}
    133136
    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 
    178 /** Announce OHCI root hub to the DDF
    179  *
    180  * @param[in] instance OHCI driver intance
    181  * @param[in] hub_fun DDF fuction representing OHCI root hub
    182  * @return Error code
    183  */
    184 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
    185 {
    186         bool addr_reqd = false;
    187         bool ep_added = false;
    188         bool fun_bound = false;
    189         int rc;
    190 
    191         assert(instance);
    192         assert(hub_fun);
    193 
    194         /* Try to get address 1 for root hub. */
    195         instance->rh.address = 1;
    196         rc = usb_device_manager_request_address(
    197             &instance->generic.dev_manager, &instance->rh.address, false,
    198             USB_SPEED_FULL);
    199         if (rc != EOK) {
    200                 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(
    208             &instance->generic.ep_manager, instance->rh.address, 0,
    209             USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
    210             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,
    236             instance->rh.address, ddf_fun_get_handle(hub_fun));
    237         if (rc != EOK) {
    238                 usb_log_warning("Failed to bind root hub address: %s.\n",
    239                     str_error(rc));
    240         }
    241 
    242         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;
    256 }
    257 
    258137/** Initialize OHCI hc driver structure
    259138 *
     
    268147        assert(instance);
    269148
    270         int rc =
     149        int ret =
    271150            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;
     151        if (ret != EOK) {
     152                usb_log_error("Failed to enable access to device regss: %s.\n",
     153                    str_error(ret));
     154                return ret;
    276155        }
    277156
    278157        list_initialize(&instance->pending_batches);
    279 
    280         hcd_init(&instance->generic, USB_SPEED_FULL,
    281             BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    282         instance->generic.private_data = instance;
    283         instance->generic.schedule = hc_schedule;
    284         instance->generic.ep_add_hook = ohci_endpoint_init;
    285         instance->generic.ep_remove_hook = ohci_endpoint_fini;
    286 
    287         rc = hc_init_memory(instance);
    288         if (rc != EOK) {
     158        fibril_mutex_initialize(&instance->guard);
     159
     160        ret = hc_init_memory(instance);
     161        if (ret != EOK) {
    289162                usb_log_error("Failed to create OHCI memory structures: %s.\n",
    290                     str_error(rc));
    291                 return rc;
    292         }
    293 
    294         fibril_mutex_initialize(&instance->guard);
     163                    str_error(ret));
     164                return ret;
     165        }
    295166
    296167        hc_gain_control(instance);
     
    302173        }
    303174
    304         rh_init(&instance->rh, instance->registers);
     175        ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
    305176        hc_start(instance);
    306177
     
    389260
    390261        /* Check for root hub communication */
    391         if (batch->ep->address == instance->rh.address) {
     262        if (batch->ep->address == ohci_rh_get_address(&instance->rh)) {
    392263                usb_log_debug("OHCI root hub request.\n");
    393                 rh_request(&instance->rh, batch);
    394                 return EOK;
     264                return ohci_rh_schedule(&instance->rh, batch);
    395265        }
    396266        ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch);
     
    431301        usb_log_debug2("OHCI(%p) interrupt: %x.\n", instance, status);
    432302        if (status & I_RHSC)
    433                 rh_interrupt(&instance->rh);
     303                ohci_rh_interrupt(&instance->rh);
    434304
    435305        if (status & I_WDH) {
     
    629499do { \
    630500        const char *name = usb_str_transfer_type(type); \
    631         int ret = endpoint_list_init(&instance->lists[type], name); \
     501        const int ret = endpoint_list_init(&instance->lists[type], name); \
    632502        if (ret != EOK) { \
    633503                usb_log_error("Failed to setup %s endpoint list: %s.\n", \
Note: See TracChangeset for help on using the changeset viewer.