Ignore:
File:
1 edited

Legend:

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

    r7de1988c r772a172  
    8585static int hc_init_mem_structures(hc_t *instance);
    8686static int hc_init_transfer_lists(hc_t *instance);
    87 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    8887
    8988static int hc_interrupt_emulator(void *arg);
    9089static int hc_debug_checker(void *arg);
    9190
    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 };
    10191
    10292/** Generate IRQ code.
    103  * @param[out] ranges PIO ranges buffer.
    104  * @param[in] ranges_size Size of the ranges buffer (bytes).
    105  * @param[out] cmds Commands buffer.
    106  * @param[in] cmds_size Size of the commands buffer (bytes).
     93 * @param[out] code IRQ code structure.
    10794 * @param[in] regs Device's register range.
    10895 *
    10996 * @return Error code.
    11097 */
    111 int
    112 hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
    113     size_t cmds_size, addr_range_t *regs)
    114 {
    115         if ((ranges_size < sizeof(uhci_irq_pio_ranges)) ||
    116             (cmds_size < sizeof(uhci_irq_commands)) ||
    117             (RNGSZ(*regs) < sizeof(uhci_regs_t)))
     98int hc_gen_irq_code(irq_code_t *code, addr_range_t *regs)
     99{
     100        assert(code);
     101
     102        if (RNGSZ(*regs) < sizeof(uhci_regs_t))
    118103                return EOVERFLOW;
    119104
    120         memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
    121         ranges[0].base = RNGABS(*regs);
    122 
    123         memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
     105        code->ranges = malloc(sizeof(uhci_irq_pio_ranges));
     106        if (code->ranges == NULL)
     107                return ENOMEM;
     108
     109        code->cmds = malloc(sizeof(uhci_irq_commands));
     110        if (code->cmds == NULL) {
     111                free(code->ranges);
     112                return ENOMEM;
     113        }
     114
     115        code->rangecount = ARRAY_SIZE(uhci_irq_pio_ranges);
     116        code->cmdcount = ARRAY_SIZE(uhci_irq_commands);
     117
     118        memcpy(code->ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
     119        code->ranges[0].base = RNGABS(*regs);
     120
     121        memcpy(code->cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
    124122        uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(*regs);
    125         cmds[0].addr = &registers->usbsts;
    126         cmds[3].addr = &registers->usbsts;
    127 
    128         return EOK;
    129 }
    130 
    131 /** Register interrupt handler.
    132  *
    133  * @param[in] device Host controller DDF device
    134  * @param[in] regs Register range
    135  * @param[in] irq Interrupt number
    136  * @paran[in] handler Interrupt handler
    137  *
    138  * @return EOK on success or negative error code
    139  */
    140 int hc_register_irq_handler(ddf_dev_t *device, addr_range_t *regs, int irq,
    141     interrupt_handler_t handler)
    142 {
    143         int rc;
    144         irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
    145         irq_cmd_t irq_cmds[hc_irq_cmd_count];
    146         rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    147             sizeof(irq_cmds), regs);
    148         if (rc != EOK) {
    149                 usb_log_error("Failed to generate IRQ commands: %s.\n",
    150                     str_error(rc));
    151                 return rc;
    152         }
    153 
    154         irq_code_t irq_code = {
    155                 .rangecount = hc_irq_pio_range_count,
    156                 .ranges = irq_ranges,
    157                 .cmdcount = hc_irq_cmd_count,
    158                 .cmds = irq_cmds
    159         };
    160 
    161         /* Register handler to avoid interrupt lockup */
    162         rc = register_interrupt_handler(device, irq, handler, &irq_code);
    163         if (rc != EOK) {
    164                 usb_log_error("Failed to register interrupt handler: %s.\n",
    165                     str_error(rc));
    166                 return rc;
    167         }
     123        code->cmds[0].addr = (void*)&registers->usbsts;
     124        code->cmds[3].addr = (void*)&registers->usbsts;
    168125
    169126        return EOK;
     
    240197int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts)
    241198{
     199        assert(instance);
     200        assert(regs);
    242201        assert(regs->size >= sizeof(uhci_regs_t));
    243         int rc;
    244202
    245203        instance->hw_interrupts = interrupts;
     
    248206        /* allow access to hc control registers */
    249207        uhci_regs_t *io;
    250         rc = pio_enable_range(regs, (void **) &io);
    251         if (rc != EOK) {
     208        int ret = pio_enable_range(regs, (void **) &io);
     209        if (ret != EOK) {
    252210                usb_log_error("Failed to gain access to registers at %p: %s.\n",
    253                     io, str_error(rc));
    254                 return rc;
    255         }
    256 
     211                    io, str_error(ret));
     212                return ret;
     213        }
    257214        instance->registers = io;
     215
    258216        usb_log_debug(
    259217            "Device registers at %p (%zuB) accessible.\n", io, regs->size);
    260218
    261         rc = hc_init_mem_structures(instance);
    262         if (rc != EOK) {
    263                 usb_log_error("Failed to initialize UHCI memory structures: %s.\n",
    264                     str_error(rc));
    265                 return rc;
    266         }
    267 
    268         hcd_init(&instance->generic, USB_SPEED_FULL,
    269             BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    270 
    271         instance->generic.private_data = instance;
    272         instance->generic.schedule = hc_schedule;
    273         instance->generic.ep_add_hook = NULL;
     219        ret = hc_init_mem_structures(instance);
     220        if (ret != EOK) {
     221                usb_log_error("Failed to init UHCI memory structures: %s.\n",
     222                    str_error(ret));
     223                // TODO: we should disable pio here
     224                return ret;
     225        }
    274226
    275227        hc_init_hw(instance);
     
    280232        }
    281233        (void)hc_debug_checker;
     234
     235        uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
    282236
    283237        return EOK;
     
    440394{
    441395        assert(hcd);
    442         hc_t *instance = hcd->private_data;
     396        hc_t *instance = hcd->driver.data;
    443397        assert(instance);
    444398        assert(batch);
     399
     400        if (batch->ep->address == uhci_rh_get_address(&instance->rh))
     401                return uhci_rh_schedule(&instance->rh, batch);
     402
    445403        uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch);
    446404        if (!uhci_batch) {
Note: See TracChangeset for help on using the changeset viewer.