Changeset e50cd7f in mainline for uspace/drv/uhci-hcd/hc.c


Ignore:
Timestamp:
2011-04-17T19:17:55Z (14 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63517c2, cfbbe1d3
Parents:
ef354b6 (diff), 8595577b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

new report structure fixes

File:
1 edited

Legend:

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

    ref354b6 re50cd7f  
    6666static int hc_interrupt_emulator(void *arg);
    6767static int hc_debug_checker(void *arg);
    68 #if 0
    69 static bool usb_is_allowed(
    70     bool low_speed, usb_transfer_type_t transfer, size_t size);
    71 #endif
    7268/*----------------------------------------------------------------------------*/
    7369/** Initialize UHCI hcd driver structure
     
    8985        int ret;
    9086
    91 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
     87#define CHECK_RET_RETURN(ret, message...) \
    9288        if (ret != EOK) { \
    9389                usb_log_error(message); \
    94                 if (instance->ddf_instance) \
    95                         ddf_fun_destroy(instance->ddf_instance); \
    9690                return ret; \
    9791        } else (void) 0
     
    9993        instance->hw_interrupts = interrupts;
    10094        instance->hw_failures = 0;
    101 
    102         /* Setup UHCI function. */
    103         instance->ddf_instance = fun;
    10495
    10596        /* allow access to hc control registers */
    10697        regs_t *io;
    10798        ret = pio_enable(regs, reg_size, (void**)&io);
    108         CHECK_RET_DEST_FUN_RETURN(ret,
     99        CHECK_RET_RETURN(ret,
    109100            "Failed(%d) to gain access to registers at %p: %s.\n",
    110             ret, str_error(ret), io);
     101            ret, io, str_error(ret));
    111102        instance->registers = io;
    112103        usb_log_debug("Device registers at %p(%u) accessible.\n",
     
    114105
    115106        ret = hc_init_mem_structures(instance);
    116         CHECK_RET_DEST_FUN_RETURN(ret,
    117             "Failed to initialize UHCI memory structures.\n");
     107        CHECK_RET_RETURN(ret,
     108            "Failed(%d) to initialize UHCI memory structures: %s.\n",
     109            ret, str_error(ret));
    118110
    119111        hc_init_hw(instance);
    120112        if (!interrupts) {
    121                 instance->cleaner =
     113                instance->interrupt_emulator =
    122114                    fibril_create(hc_interrupt_emulator, instance);
    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);
     115                fibril_add_ready(instance->interrupt_emulator);
     116        }
     117        (void)hc_debug_checker;
    131118
    132119        return EOK;
     
    228215        /* Set all frames to point to the first queue head */
    229216        const uint32_t queue =
    230           instance->transfers_interrupt.queue_head_pa
    231           | LINK_POINTER_QUEUE_HEAD_FLAG;
     217            LINK_POINTER_QH(addr_to_phys(
     218                instance->transfers_interrupt.queue_head));
    232219
    233220        unsigned i = 0;
     
    236223        }
    237224
    238         /* Init device keeper*/
     225        /* Init device keeper */
    239226        usb_device_keeper_init(&instance->manager);
    240227        usb_log_debug("Initialized device manager.\n");
    241228
    242         ret =
    243             usb_endpoint_manager_init(&instance->ep_manager,
    244                 BANDWIDTH_AVAILABLE_USB11);
     229        ret = usb_endpoint_manager_init(&instance->ep_manager,
     230            BANDWIDTH_AVAILABLE_USB11);
    245231        assert(ret == EOK);
    246232
     
    261247{
    262248        assert(instance);
    263 #define CHECK_RET_CLEAR_RETURN(ret, message...) \
     249#define SETUP_TRANSFER_LIST(type, name) \
     250do { \
     251        int ret = transfer_list_init(&instance->transfers_##type, name); \
    264252        if (ret != EOK) { \
    265                 usb_log_error(message); \
     253                usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \
     254                    ret, name, str_error(ret)); \
    266255                transfer_list_fini(&instance->transfers_bulk_full); \
    267256                transfer_list_fini(&instance->transfers_control_full); \
     
    269258                transfer_list_fini(&instance->transfers_interrupt); \
    270259                return ret; \
    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 
     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 */
    289269        transfer_list_set_next(&instance->transfers_control_full,
    290270                &instance->transfers_bulk_full);
     
    330310
    331311        transfer_list_t *list =
    332             instance->transfers[batch->speed][batch->transfer_type];
     312            instance->transfers[batch->ep->speed][batch->ep->transfer_type];
    333313        assert(list);
    334         if (batch->transfer_type == USB_TRANSFER_CONTROL) {
    335                 usb_device_keeper_use_control(
    336                     &instance->manager, batch->target);
    337         }
    338314        transfer_list_add_batch(list, batch);
    339315
     
    355331        assert(instance);
    356332//      status |= 1; //Uncomment to work around qemu hang
    357         /* TODO: Resume interrupts are not supported */
    358333        /* Lower 2 bits are transaction error and transaction complete */
    359         if (status & 0x3) {
     334        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
    360335                LIST_INITIALIZE(done);
    361336                transfer_list_remove_finished(
     
    373348                        usb_transfer_batch_t *batch =
    374349                            list_get_instance(item, usb_transfer_batch_t, link);
    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) {
     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)) {
    402357                usb_log_error("UHCI hardware failure!.\n");
    403358                ++instance->hw_failures;
     
    429384
    430385        while (1) {
    431                 /* read and ack interrupts */
     386                /* Readd and clear status register */
    432387                uint16_t status = pio_read_16(&instance->registers->usbsts);
    433                 pio_write_16(&instance->registers->usbsts, 0x1f);
     388                pio_write_16(&instance->registers->usbsts, status);
    434389                if (status != 0)
    435390                        usb_log_debug2("UHCI status: %x.\n", status);
    436391                hc_interrupt(instance, status);
    437                 async_usleep(UHCI_CLEANER_TIMEOUT);
     392                async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
    438393        }
    439394        return EOK;
     
    506461#undef QH
    507462}
    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
    517 bool 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
    535463/**
    536464 * @}
Note: See TracChangeset for help on using the changeset viewer.