Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 308a5d5 in mainline


Ignore:
Timestamp:
2011-04-24T15:38:10Z (9 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
master
Children:
94c0dcbd
Parents:
9b78020 (diff), 564a2b3 (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:

Changes from development

Location:
uspace/drv
Files:
7 edited

Legend:

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

    r9b78020 r308a5d5  
    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);
    219220        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
    220221        return EOK;
     
    471472        size_t * buffer_size) {
    472473        int bit_count = instance->port_count + 1;
    473         (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1);
    474 
    475         (*buffer) = malloc(*buffer_size);
     474        (*buffer_size) = (bit_count+7 / 8);
     475
     476        (*buffer) = instance->interrupt_buffer;//malloc(*buffer_size);
    476477        uint8_t * bitmap = (uint8_t*) (*buffer);
    477478        uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16))
  • uspace/drv/ohci/root_hub.h

    r9b78020 r308a5d5  
    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;
    5864} rh_t;
    5965
  • uspace/drv/uhci-hcd/hc.c

    r9b78020 r308a5d5  
    4444#include "hc.h"
    4545
    46 static 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 /*----------------------------------------------------------------------------*/
     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
    6252static int hc_init_transfer_lists(hc_t *instance);
    6353static int hc_init_mem_structures(hc_t *instance);
     
    151141                /* Enable all interrupts, but resume interrupt */
    152142                pio_write_16(&instance->registers->usbintr,
    153                     UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     143                    UHCI_INTR_ALLOW_INTERRUPTS);
    154144        }
    155145
     
    177167{
    178168        assert(instance);
    179 #define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \
     169#define CHECK_RET_RETURN(ret, message...) \
    180170        if (ret != EOK) { \
    181171                usb_log_error(message); \
    182                 if (instance->interrupt_code.cmds != NULL) \
    183                         free(instance->interrupt_code.cmds); \
    184172                return ret; \
    185173        } else (void) 0
    186174
    187175        /* Init interrupt code */
    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 
     176        instance->interrupt_code.cmds = instance->interrupt_commands;
    193177        {
    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);
     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;
    202206        }
    203207
    204208        /* Init transfer lists */
    205         ret = hc_init_transfer_lists(instance);
    206         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");
     209        int ret = hc_init_transfer_lists(instance);
     210        CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n");
    207211        usb_log_debug("Initialized transfer lists.\n");
    208212
     
    210214        instance->frame_list = get_page();
    211215        ret = instance ? EOK : ENOMEM;
    212         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
     216        CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
    213217        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    214218
    215219        /* Set all frames to point to the first queue head */
    216         const uint32_t queue =
    217             LINK_POINTER_QH(addr_to_phys(
    218                 instance->transfers_interrupt.queue_head));
     220        const uint32_t queue = LINK_POINTER_QH(
     221                addr_to_phys(instance->transfers_interrupt.queue_head));
    219222
    220223        unsigned i = 0;
     
    229232        ret = usb_endpoint_manager_init(&instance->ep_manager,
    230233            BANDWIDTH_AVAILABLE_USB11);
    231         assert(ret == EOK);
    232 
    233         return EOK;
    234 #undef CHECK_RET_DEST_CMDS_RETURN
     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
    235239}
    236240/*----------------------------------------------------------------------------*/
     
    277281#ifdef FSBR
    278282        transfer_list_set_next(&instance->transfers_bulk_full,
    279                 &instance->transfers_control_full);
     283            &instance->transfers_control_full);
    280284#endif
    281285
     
    330334{
    331335        assert(instance);
    332         status |= 1; //Uncomment to work around qemu hang
    333336        /* Lower 2 bits are transaction error and transaction complete */
    334337        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     
    352355        }
    353356        /* Resume interrupts are not supported */
     357        if (status & UHCI_STATUS_RESUME) {
     358                usb_log_error("Resume interrupt!\n");
     359        }
    354360
    355361        /* Bits 4 and 5 indicate hc error */
     
    380386{
    381387        usb_log_debug("Started interrupt emulator.\n");
    382         hc_t *instance = (hc_t*)arg;
     388        hc_t *instance = arg;
    383389        assert(instance);
    384390
    385391        while (1) {
    386                 /* Readd and clear status register */
     392                /* Read and clear status register */
    387393                uint16_t status = pio_read_16(&instance->registers->usbsts);
    388394                pio_write_16(&instance->registers->usbsts, status);
    389395                if (status != 0)
    390396                        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;
    391401                hc_interrupt(instance, status);
    392402                async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
     
    402412int hc_debug_checker(void *arg)
    403413{
    404         hc_t *instance = (hc_t*)arg;
     414        hc_t *instance = arg;
    405415        assert(instance);
    406416
  • uspace/drv/uhci-hcd/hc.h

    r9b78020 r308a5d5  
    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)
    7173
    7274        /** Interrupt enabled registers */
     
    9193#define UHCI_DEBUGER_TIMEOUT 5000000
    9294#define UHCI_ALLOWED_HW_FAIL 5
     95#define UHCI_NEEDED_IRQ_COMMANDS 5
    9396
    9497/* Main HC driver structure */
     
    119122        /** Code to be executed in kernel interrupt handler */
    120123        irq_code_t interrupt_code;
     124
     125        /** Commands that form interrupt code */
     126        irq_cmd_t interrupt_commands[UHCI_NEEDED_IRQ_COMMANDS];
    121127
    122128        /** Fibril periodically checking status register*/
  • uspace/drv/uhci-hcd/pci.c

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

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

    r9b78020 r308a5d5  
    105105        }
    106106
    107         //usb_pipe_start_session(hub_info->control_pipe);
    108107        //set hub configuration
    109108        opResult = usb_hub_set_configuration(hub_info);
     
    122121                return opResult;
    123122        }
    124         //usb_pipe_end_session(hub_info->control_pipe);
    125 
    126123
    127124        usb_log_debug("Creating 'hub' function in DDF.\n");
     
    176173leave:
    177174        /* FIXME: proper interval. */
    178         async_usleep(1000 * 1000 * 10);
     175        async_usleep(1000 * 250);
    179176
    180177        return true;
     
    218215        // get hub descriptor
    219216        usb_log_debug("creating serialized descriptor\n");
    220         //void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    221217        uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
    222218        usb_hub_descriptor_t * descriptor;
     
    253249            sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
    254250        size_t port;
    255         for (port = 0; port < hub_info->port_count + 1; port++) {
     251        for (port = 0; port < hub_info->port_count + 1; ++port) {
    256252                usb_hub_port_init(&hub_info->ports[port]);
    257253        }
    258254        if(is_power_switched){
    259255                usb_log_debug("is_power_switched\n");
    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                                 }
     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));
    269264                        }
    270                 }else{
     265                }
     266                if(!has_individual_port_powering){
    271267                        usb_log_debug("!has_individual_port_powering\n");
    272268                        opResult = usb_hub_set_feature(hub_info->control_pipe,
     
    281277        }
    282278        usb_log_debug2("freeing data\n");
    283         //free(serialized_descriptor);
    284         //free(descriptor->devices_removable);
    285279        free(descriptor);
    286280        return EOK;
     
    415409    usb_hub_status_t status) {
    416410        int opResult;
    417         if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
     411        if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
    418412                //restart power on hub
    419413                opResult = usb_hub_set_feature(hub_info->control_pipe,
     
    425419        } else {//power reestablished on hub- restart ports
    426420                size_t port;
    427                 for (port = 0; port < hub_info->port_count; ++port) {
     421                for (port = 1; port <= hub_info->port_count; ++port) {
    428422                        opResult = usb_hub_set_port_feature(
    429423                            hub_info->control_pipe,
     
    434428                        }
    435429                }
     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                }
    436437        }
    437438        return opResult;
Note: See TracChangeset for help on using the changeset viewer.