Ignore:
File:
1 edited

Legend:

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

    r27205841 r391d55b  
    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");
    228241
    229         ret = usb_endpoint_manager_init(&instance->ep_manager,
    230             BANDWIDTH_AVAILABLE_USB11);
     242        ret =
     243            usb_endpoint_manager_init(&instance->ep_manager,
     244                BANDWIDTH_AVAILABLE_USB11);
    231245        assert(ret == EOK);
    232246
     
    247261{
    248262        assert(instance);
    249 #define SETUP_TRANSFER_LIST(type, name) \
    250 do { \
    251         int ret = transfer_list_init(&instance->transfers_##type, name); \
     263#define CHECK_RET_CLEAR_RETURN(ret, message...) \
    252264        if (ret != EOK) { \
    253                 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \
    254                     ret, name, str_error(ret)); \
     265                usb_log_error(message); \
    255266                transfer_list_fini(&instance->transfers_bulk_full); \
    256267                transfer_list_fini(&instance->transfers_control_full); \
     
    258269                transfer_list_fini(&instance->transfers_interrupt); \
    259270                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 */
     271        } else (void) 0
     272
     273        /* initialize TODO: check errors */
     274        int ret;
     275        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     276        CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
     277
     278        ret = transfer_list_init(
     279            &instance->transfers_control_full, "CONTROL_FULL");
     280        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
     281
     282        ret = transfer_list_init(
     283            &instance->transfers_control_slow, "CONTROL_SLOW");
     284        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
     285
     286        ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT");
     287        CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list.");
     288
    269289        transfer_list_set_next(&instance->transfers_control_full,
    270290                &instance->transfers_bulk_full);
     
    310330
    311331        transfer_list_t *list =
    312             instance->transfers[batch->ep->speed][batch->ep->transfer_type];
     332            instance->transfers[batch->speed][batch->transfer_type];
    313333        assert(list);
     334        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     335                usb_device_keeper_use_control(
     336                    &instance->manager, batch->target);
     337        }
    314338        transfer_list_add_batch(list, batch);
    315339
     
    331355        assert(instance);
    332356//      status |= 1; //Uncomment to work around qemu hang
     357        /* TODO: Resume interrupts are not supported */
    333358        /* Lower 2 bits are transaction error and transaction complete */
    334         if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     359        if (status & 0x3) {
    335360                LIST_INITIALIZE(done);
    336361                transfer_list_remove_finished(
     
    348373                        usb_transfer_batch_t *batch =
    349374                            list_get_instance(item, usb_transfer_batch_t, link);
    350                         usb_transfer_batch_finish(batch);
    351                 }
    352         }
    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)) {
     375                        switch (batch->transfer_type)
     376                        {
     377                        case USB_TRANSFER_CONTROL:
     378                                usb_device_keeper_release_control(
     379                                    &instance->manager, batch->target);
     380                                break;
     381                        case USB_TRANSFER_INTERRUPT:
     382                        case USB_TRANSFER_ISOCHRONOUS: {
     383/*
     384                                int ret = bandwidth_free(&instance->bandwidth,
     385                                    batch->target.address,
     386                                    batch->target.endpoint,
     387                                    batch->direction);
     388                                if (ret != EOK)
     389                                        usb_log_warning("Failed(%d) to free "
     390                                            "reserved bw: %s.\n", ret,
     391                                            str_error(ret));
     392*/
     393                                }
     394                        default:
     395                                break;
     396                        }
     397                        batch->next_step(batch);
     398                }
     399        }
     400        /* bits 4 and 5 indicate hc error */
     401        if (status & 0x18) {
    357402                usb_log_error("UHCI hardware failure!.\n");
    358403                ++instance->hw_failures;
     
    384429
    385430        while (1) {
    386                 /* Readd and clear status register */
     431                /* read and ack interrupts */
    387432                uint16_t status = pio_read_16(&instance->registers->usbsts);
    388                 pio_write_16(&instance->registers->usbsts, status);
     433                pio_write_16(&instance->registers->usbsts, 0x1f);
    389434                if (status != 0)
    390435                        usb_log_debug2("UHCI status: %x.\n", status);
    391436                hc_interrupt(instance, status);
    392                 async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
     437                async_usleep(UHCI_CLEANER_TIMEOUT);
    393438        }
    394439        return EOK;
     
    461506#undef QH
    462507}
     508/*----------------------------------------------------------------------------*/
     509/** Check transfers for USB validity
     510 *
     511 * @param[in] low_speed Transfer speed.
     512 * @param[in] transfer Transer type
     513 * @param[in] size Size of data packets
     514 * @return True if transaction is allowed by USB specs, false otherwise
     515 */
     516#if 0
     517bool usb_is_allowed(
     518    bool low_speed, usb_transfer_type_t transfer, size_t size)
     519{
     520        /* see USB specification chapter 5.5-5.8 for magic numbers used here */
     521        switch(transfer)
     522        {
     523        case USB_TRANSFER_ISOCHRONOUS:
     524                return (!low_speed && size < 1024);
     525        case USB_TRANSFER_INTERRUPT:
     526                return size <= (low_speed ? 8 : 64);
     527        case USB_TRANSFER_CONTROL: /* device specifies its own max size */
     528                return (size <= (low_speed ? 8 : 64));
     529        case USB_TRANSFER_BULK: /* device specifies its own max size */
     530                return (!low_speed && size <= 64);
     531        }
     532        return false;
     533}
     534#endif
    463535/**
    464536 * @}
Note: See TracChangeset for help on using the changeset viewer.