Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/hc.c

    r27205841 r4c28d17  
    6666static int hc_interrupt_emulator(void *arg);
    6767static int hc_debug_checker(void *arg);
     68#if 0
     69static bool usb_is_allowed(
     70    bool low_speed, usb_transfer_type_t transfer, size_t size);
     71#endif
    6872/*----------------------------------------------------------------------------*/
    6973/** Initialize UHCI hcd driver structure
     
    8589        int ret;
    8690
    87 #define CHECK_RET_RETURN(ret, message...) \
     91#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    8892        if (ret != EOK) { \
    8993                usb_log_error(message); \
     94                if (instance->ddf_instance) \
     95                        ddf_fun_destroy(instance->ddf_instance); \
    9096                return ret; \
    9197        } else (void) 0
     
    9399        instance->hw_interrupts = interrupts;
    94100        instance->hw_failures = 0;
     101
     102        /* Setup UHCI function. */
     103        instance->ddf_instance = fun;
    95104
    96105        /* allow access to hc control registers */
    97106        regs_t *io;
    98107        ret = pio_enable(regs, reg_size, (void**)&io);
    99         CHECK_RET_RETURN(ret,
     108        CHECK_RET_DEST_FUN_RETURN(ret,
    100109            "Failed(%d) to gain access to registers at %p: %s.\n",
    101             ret, io, str_error(ret));
     110            ret, str_error(ret), io);
    102111        instance->registers = io;
    103112        usb_log_debug("Device registers at %p(%u) accessible.\n",
     
    105114
    106115        ret = hc_init_mem_structures(instance);
    107         CHECK_RET_RETURN(ret,
    108             "Failed(%d) to initialize UHCI memory structures: %s.\n",
    109             ret, str_error(ret));
     116        CHECK_RET_DEST_FUN_RETURN(ret,
     117            "Failed to initialize UHCI memory structures.\n");
    110118
    111119        hc_init_hw(instance);
    112120        if (!interrupts) {
    113                 instance->interrupt_emulator =
     121                instance->cleaner =
    114122                    fibril_create(hc_interrupt_emulator, instance);
    115                 fibril_add_ready(instance->interrupt_emulator);
    116         }
    117         (void)hc_debug_checker;
     123                fibril_add_ready(instance->cleaner);
     124        } else {
     125                /* TODO: enable interrupts here */
     126        }
     127
     128        instance->debug_checker =
     129            fibril_create(hc_debug_checker, instance);
     130//      fibril_add_ready(instance->debug_checker);
    118131
    119132        return EOK;
     
    215228        /* Set all frames to point to the first queue head */
    216229        const uint32_t queue =
    217             LINK_POINTER_QH(addr_to_phys(
    218                 instance->transfers_interrupt.queue_head));
     230          instance->transfers_interrupt.queue_head_pa
     231          | LINK_POINTER_QUEUE_HEAD_FLAG;
    219232
    220233        unsigned i = 0;
     
    223236        }
    224237
    225         /* Init device keeper */
     238        /* Init device keeper*/
    226239        usb_device_keeper_init(&instance->manager);
    227240        usb_log_debug("Initialized device manager.\n");
     
    247260{
    248261        assert(instance);
    249 #define SETUP_TRANSFER_LIST(type, name) \
    250 do { \
    251         int ret = transfer_list_init(&instance->transfers_##type, name); \
     262#define CHECK_RET_CLEAR_RETURN(ret, message...) \
    252263        if (ret != EOK) { \
    253                 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \
    254                     ret, name, str_error(ret)); \
     264                usb_log_error(message); \
    255265                transfer_list_fini(&instance->transfers_bulk_full); \
    256266                transfer_list_fini(&instance->transfers_control_full); \
     
    258268                transfer_list_fini(&instance->transfers_interrupt); \
    259269                return ret; \
    260         } \
    261 } while (0)
    262 
    263         SETUP_TRANSFER_LIST(bulk_full, "BULK FULL");
    264         SETUP_TRANSFER_LIST(control_full, "CONTROL FULL");
    265         SETUP_TRANSFER_LIST(control_slow, "CONTROL LOW");
    266         SETUP_TRANSFER_LIST(interrupt, "INTERRUPT");
    267 #undef SETUP_TRANSFER_LIST
    268         /* Connect lists into one schedule */
     270        } else (void) 0
     271
     272        /* initialize TODO: check errors */
     273        int ret;
     274        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     275        CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
     276
     277        ret = transfer_list_init(
     278            &instance->transfers_control_full, "CONTROL_FULL");
     279        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
     280
     281        ret = transfer_list_init(
     282            &instance->transfers_control_slow, "CONTROL_SLOW");
     283        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
     284
     285        ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT");
     286        CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list.");
     287
    269288        transfer_list_set_next(&instance->transfers_control_full,
    270289                &instance->transfers_bulk_full);
     
    310329
    311330        transfer_list_t *list =
    312             instance->transfers[batch->ep->speed][batch->ep->transfer_type];
     331            instance->transfers[batch->speed][batch->transfer_type];
    313332        assert(list);
    314333        transfer_list_add_batch(list, batch);
     
    331350        assert(instance);
    332351//      status |= 1; //Uncomment to work around qemu hang
     352        /* TODO: Resume interrupts are not supported */
    333353        /* Lower 2 bits are transaction error and transaction complete */
    334         if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     354        if (status & 0x3) {
    335355                LIST_INITIALIZE(done);
    336356                transfer_list_remove_finished(
     
    351371                }
    352372        }
    353         /* Resume interrupts are not supported */
    354 
    355         /* Bits 4 and 5 indicate hc error */
    356         if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
     373        /* bits 4 and 5 indicate hc error */
     374        if (status & 0x18) {
    357375                usb_log_error("UHCI hardware failure!.\n");
    358376                ++instance->hw_failures;
     
    384402
    385403        while (1) {
    386                 /* Readd and clear status register */
     404                /* read and ack interrupts */
    387405                uint16_t status = pio_read_16(&instance->registers->usbsts);
    388                 pio_write_16(&instance->registers->usbsts, status);
     406                pio_write_16(&instance->registers->usbsts, 0x1f);
    389407                if (status != 0)
    390408                        usb_log_debug2("UHCI status: %x.\n", status);
    391409                hc_interrupt(instance, status);
    392                 async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
     410                async_usleep(UHCI_CLEANER_TIMEOUT);
    393411        }
    394412        return EOK;
     
    461479#undef QH
    462480}
     481/*----------------------------------------------------------------------------*/
     482/** Check transfers for USB validity
     483 *
     484 * @param[in] low_speed Transfer speed.
     485 * @param[in] transfer Transer type
     486 * @param[in] size Size of data packets
     487 * @return True if transaction is allowed by USB specs, false otherwise
     488 */
     489#if 0
     490bool usb_is_allowed(
     491    bool low_speed, usb_transfer_type_t transfer, size_t size)
     492{
     493        /* see USB specification chapter 5.5-5.8 for magic numbers used here */
     494        switch(transfer)
     495        {
     496        case USB_TRANSFER_ISOCHRONOUS:
     497                return (!low_speed && size < 1024);
     498        case USB_TRANSFER_INTERRUPT:
     499                return size <= (low_speed ? 8 : 64);
     500        case USB_TRANSFER_CONTROL: /* device specifies its own max size */
     501                return (size <= (low_speed ? 8 : 64));
     502        case USB_TRANSFER_BULK: /* device specifies its own max size */
     503                return (!low_speed && size <= 64);
     504        }
     505        return false;
     506}
     507#endif
    463508/**
    464509 * @}
Note: See TracChangeset for help on using the changeset viewer.