Changes in / [308a5d5:9b78020] in mainline


Ignore:
Location:
uspace/drv
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/root_hub.c

    r308a5d5 r9b78020  
    217217        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
    218218        instance->unfinished_interrupt_transfer = NULL;
    219         instance->interrupt_buffer = malloc((instance->port_count + 8)/8);
    220219        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
    221220        return EOK;
     
    472471        size_t * buffer_size) {
    473472        int bit_count = instance->port_count + 1;
    474         (*buffer_size) = (bit_count+7 / 8);
    475 
    476         (*buffer) = instance->interrupt_buffer;//malloc(*buffer_size);
     473        (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1);
     474
     475        (*buffer) = malloc(*buffer_size);
    477476        uint8_t * bitmap = (uint8_t*) (*buffer);
    478477        uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16))
  • uspace/drv/ohci/root_hub.h

    r308a5d5 r9b78020  
    5656        /** interrupt transfer waiting for an actual interrupt to occur */
    5757        usb_transfer_batch_t * unfinished_interrupt_transfer;
    58         /** pre-allocated interrupt mask
    59          *
    60          * This is allocated when initializing instance, so that memory
    61          * allocation is not needed when processing request.
    62          */
    63         uint8_t * interrupt_buffer;
    6458} rh_t;
    6559
  • uspace/drv/uhci-hcd/hc.c

    r308a5d5 r9b78020  
    4444#include "hc.h"
    4545
    46 #define UHCI_INTR_ALLOW_INTERRUPTS \
    47     (UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET)
    48 #define UHCI_STATUS_USED_INTERRUPTS \
    49     (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
    50 
    51 
     46static irq_cmd_t uhci_cmds[] = {
     47        {
     48                .cmd = CMD_PIO_READ_16,
     49                .addr = NULL, /* patched for every instance */
     50                .dstarg = 1
     51        },
     52        {
     53                .cmd = CMD_PIO_WRITE_16,
     54                .addr = NULL, /* pathed for every instance */
     55                .value = 0x1f
     56        },
     57        {
     58                .cmd = CMD_ACCEPT
     59        }
     60};
     61/*----------------------------------------------------------------------------*/
    5262static int hc_init_transfer_lists(hc_t *instance);
    5363static int hc_init_mem_structures(hc_t *instance);
     
    141151                /* Enable all interrupts, but resume interrupt */
    142152                pio_write_16(&instance->registers->usbintr,
    143                     UHCI_INTR_ALLOW_INTERRUPTS);
     153                    UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
    144154        }
    145155
     
    167177{
    168178        assert(instance);
    169 #define CHECK_RET_RETURN(ret, message...) \
     179#define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \
    170180        if (ret != EOK) { \
    171181                usb_log_error(message); \
     182                if (instance->interrupt_code.cmds != NULL) \
     183                        free(instance->interrupt_code.cmds); \
    172184                return ret; \
    173185        } else (void) 0
    174186
    175187        /* Init interrupt code */
    176         instance->interrupt_code.cmds = instance->interrupt_commands;
     188        instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds));
     189        int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK;
     190        CHECK_RET_DEST_CMDS_RETURN(ret,
     191            "Failed to allocate interrupt cmds space.\n");
     192
    177193        {
    178                 /* Read status register */
    179                 instance->interrupt_commands[0].cmd = CMD_PIO_READ_16;
    180                 instance->interrupt_commands[0].dstarg = 1;
    181                 instance->interrupt_commands[0].addr =
    182                     &instance->registers->usbsts;
    183 
    184                 /* Test whether we are the interrupt cause */
    185                 instance->interrupt_commands[1].cmd = CMD_BTEST;
    186                 instance->interrupt_commands[1].value =
    187                     UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS;
    188                 instance->interrupt_commands[1].srcarg = 1;
    189                 instance->interrupt_commands[1].dstarg = 2;
    190 
    191                 /* Predicate cleaning and accepting */
    192                 instance->interrupt_commands[2].cmd = CMD_PREDICATE;
    193                 instance->interrupt_commands[2].value = 2;
    194                 instance->interrupt_commands[2].srcarg = 2;
    195 
    196                 /* Write clean status register */
    197                 instance->interrupt_commands[3].cmd = CMD_PIO_WRITE_A_16;
    198                 instance->interrupt_commands[3].srcarg = 1;
    199                 instance->interrupt_commands[3].addr =
    200                     &instance->registers->usbsts;
    201 
    202                 /* Accept interrupt */
    203                 instance->interrupt_commands[4].cmd = CMD_ACCEPT;
    204 
    205                 instance->interrupt_code.cmdcount = UHCI_NEEDED_IRQ_COMMANDS;
     194                irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds;
     195                memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
     196                interrupt_commands[0].addr =
     197                    (void*)&instance->registers->usbsts;
     198                interrupt_commands[1].addr =
     199                    (void*)&instance->registers->usbsts;
     200                instance->interrupt_code.cmdcount =
     201                    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
    206202        }
    207203
    208204        /* Init transfer lists */
    209         int ret = hc_init_transfer_lists(instance);
    210         CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n");
     205        ret = hc_init_transfer_lists(instance);
     206        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");
    211207        usb_log_debug("Initialized transfer lists.\n");
    212208
     
    214210        instance->frame_list = get_page();
    215211        ret = instance ? EOK : ENOMEM;
    216         CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
     212        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
    217213        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    218214
    219215        /* Set all frames to point to the first queue head */
    220         const uint32_t queue = LINK_POINTER_QH(
    221                 addr_to_phys(instance->transfers_interrupt.queue_head));
     216        const uint32_t queue =
     217            LINK_POINTER_QH(addr_to_phys(
     218                instance->transfers_interrupt.queue_head));
    222219
    223220        unsigned i = 0;
     
    232229        ret = usb_endpoint_manager_init(&instance->ep_manager,
    233230            BANDWIDTH_AVAILABLE_USB11);
    234         CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
    235             str_error(ret));
    236 
    237         return EOK;
    238 #undef CHECK_RET_RETURN
     231        assert(ret == EOK);
     232
     233        return EOK;
     234#undef CHECK_RET_DEST_CMDS_RETURN
    239235}
    240236/*----------------------------------------------------------------------------*/
     
    281277#ifdef FSBR
    282278        transfer_list_set_next(&instance->transfers_bulk_full,
    283             &instance->transfers_control_full);
     279                &instance->transfers_control_full);
    284280#endif
    285281
     
    334330{
    335331        assert(instance);
     332        status |= 1; //Uncomment to work around qemu hang
    336333        /* Lower 2 bits are transaction error and transaction complete */
    337334        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     
    355352        }
    356353        /* Resume interrupts are not supported */
    357         if (status & UHCI_STATUS_RESUME) {
    358                 usb_log_error("Resume interrupt!\n");
    359         }
    360354
    361355        /* Bits 4 and 5 indicate hc error */
     
    386380{
    387381        usb_log_debug("Started interrupt emulator.\n");
    388         hc_t *instance = arg;
     382        hc_t *instance = (hc_t*)arg;
    389383        assert(instance);
    390384
    391385        while (1) {
    392                 /* Read and clear status register */
     386                /* Readd and clear status register */
    393387                uint16_t status = pio_read_16(&instance->registers->usbsts);
    394388                pio_write_16(&instance->registers->usbsts, status);
    395389                if (status != 0)
    396390                        usb_log_debug2("UHCI status: %x.\n", status);
    397 // Qemu fails to report stalled communication
    398 // see https://bugs.launchpad.net/qemu/+bug/757654
    399 // This is a simple workaround to force queue processing every time
    400         //      status |= 1;
    401391                hc_interrupt(instance, status);
    402392                async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
     
    412402int hc_debug_checker(void *arg)
    413403{
    414         hc_t *instance = arg;
     404        hc_t *instance = (hc_t*)arg;
    415405        assert(instance);
    416406
  • uspace/drv/uhci-hcd/hc.h

    r308a5d5 r9b78020  
    6969#define UHCI_STATUS_ERROR_INTERRUPT (1 << 1)
    7070#define UHCI_STATUS_INTERRUPT (1 << 0)
    71 #define UHCI_STATUS_NM_INTERRUPTS \
    72     (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)
    7371
    7472        /** Interrupt enabled registers */
     
    9391#define UHCI_DEBUGER_TIMEOUT 5000000
    9492#define UHCI_ALLOWED_HW_FAIL 5
    95 #define UHCI_NEEDED_IRQ_COMMANDS 5
    9693
    9794/* Main HC driver structure */
     
    122119        /** Code to be executed in kernel interrupt handler */
    123120        irq_code_t interrupt_code;
    124 
    125         /** Commands that form interrupt code */
    126         irq_cmd_t interrupt_commands[UHCI_NEEDED_IRQ_COMMANDS];
    127121
    128122        /** Fibril periodically checking status register*/
  • uspace/drv/uhci-hcd/pci.c

    r308a5d5 r9b78020  
    146146         * write all WC bits in USB legacy register */
    147147        sysarg_t address = 0xc0;
    148         sysarg_t value = 0xaf00;
     148        sysarg_t value = 0x8f00;
    149149
    150150        int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
  • uspace/drv/uhci-hcd/uhci-hcd.ma

    r308a5d5 r9b78020  
    202010 pci/ven=8086&dev=2938
    212110 pci/ven=8086&dev=2939
    22 
    23 10 pci/ven=8086&dev=24c2
    24 10 pci/ven=8086&dev=24c4
    25 10 pci/ven=8086&dev=24c7
  • uspace/drv/usbhub/usbhub.c

    r308a5d5 r9b78020  
    105105        }
    106106
     107        //usb_pipe_start_session(hub_info->control_pipe);
    107108        //set hub configuration
    108109        opResult = usb_hub_set_configuration(hub_info);
     
    121122                return opResult;
    122123        }
     124        //usb_pipe_end_session(hub_info->control_pipe);
     125
    123126
    124127        usb_log_debug("Creating 'hub' function in DDF.\n");
     
    173176leave:
    174177        /* FIXME: proper interval. */
    175         async_usleep(1000 * 250);
     178        async_usleep(1000 * 1000 * 10);
    176179
    177180        return true;
     
    215218        // get hub descriptor
    216219        usb_log_debug("creating serialized descriptor\n");
     220        //void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    217221        uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
    218222        usb_hub_descriptor_t * descriptor;
     
    249253            sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
    250254        size_t port;
    251         for (port = 0; port < hub_info->port_count + 1; ++port) {
     255        for (port = 0; port < hub_info->port_count + 1; port++) {
    252256                usb_hub_port_init(&hub_info->ports[port]);
    253257        }
    254258        if(is_power_switched){
    255259                usb_log_debug("is_power_switched\n");
    256                
    257                 for (port = 1; port <= hub_info->port_count; ++port) {
    258                         usb_log_debug("powering port %d\n",port);
    259                         opResult = usb_hub_set_port_feature(hub_info->control_pipe,
    260                             port, USB_HUB_FEATURE_PORT_POWER);
    261                         if (opResult != EOK) {
    262                                 usb_log_error("cannot power on port %zu: %s.\n",
    263                                     port, str_error(opResult));
     260                if(has_individual_port_powering){
     261                        usb_log_debug("has_individual_port_powering\n");
     262                        for (port = 0; port < hub_info->port_count; port++) {
     263                                opResult = usb_hub_set_port_feature(hub_info->control_pipe,
     264                                    port+1, USB_HUB_FEATURE_PORT_POWER);
     265                                if (opResult != EOK) {
     266                                        usb_log_error("cannot power on port %zu: %s.\n",
     267                                            port+1, str_error(opResult));
     268                                }
    264269                        }
    265                 }
    266                 if(!has_individual_port_powering){
     270                }else{
    267271                        usb_log_debug("!has_individual_port_powering\n");
    268272                        opResult = usb_hub_set_feature(hub_info->control_pipe,
     
    277281        }
    278282        usb_log_debug2("freeing data\n");
     283        //free(serialized_descriptor);
     284        //free(descriptor->devices_removable);
    279285        free(descriptor);
    280286        return EOK;
     
    409415    usb_hub_status_t status) {
    410416        int opResult;
    411         if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
     417        if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
    412418                //restart power on hub
    413419                opResult = usb_hub_set_feature(hub_info->control_pipe,
     
    419425        } else {//power reestablished on hub- restart ports
    420426                size_t port;
    421                 for (port = 1; port <= hub_info->port_count; ++port) {
     427                for (port = 0; port < hub_info->port_count; ++port) {
    422428                        opResult = usb_hub_set_port_feature(
    423429                            hub_info->control_pipe,
     
    428434                        }
    429435                }
    430                 opResult = usb_hub_clear_feature(hub_info->control_pipe,
    431                     USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
    432                 if (opResult != EOK) {
    433                         usb_log_error("cannnot clear hub power change flag: "
    434                             "%d\n",
    435                             opResult);
    436                 }
    437436        }
    438437        return opResult;
Note: See TracChangeset for help on using the changeset viewer.