Changeset df6ded8 in mainline for uspace/drv/bus/usb/ehci/ehci_rh.c


Ignore:
Timestamp:
2018-02-28T16:37:50Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1b20da0
Parents:
f5e5f73 (diff), b2dca8de (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.
git-author:
Jakub Jermar <jakub@…> (2018-02-28 16:06:42)
git-committer:
Jakub Jermar <jakub@…> (2018-02-28 16:37:50)
Message:

Merge github.com:helenos-xhci-team/helenos

This commit merges support for USB 3 and generally refactors, fixes,
extends and cleans up the existing USB framework.

Notable additions and features:

  • new host controller driver has been implemented to control various xHC models (among others, NEC Renesas uPD720200)
  • isochronous data transfer mode
  • support for explicit USB device removal
  • USB tablet driver
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/ehci_rh.c

    rf5e5f73 rdf6ded8  
    11/*
    22 * Copyright (c) 2013 Jan Vesely
     3 * Copyright (c) 2018 Ondrej Hlavaty
    34 * All rights reserved.
    45 *
     
    100101 */
    101102errno_t ehci_rh_init(ehci_rh_t *instance, ehci_caps_regs_t *caps, ehci_regs_t *regs,
    102     const char *name)
     103    fibril_mutex_t *guard, const char *name)
    103104{
    104105        assert(instance);
     
    107108            (EHCI_RD(caps->hcsparams) >> EHCI_CAPS_HCS_N_PORTS_SHIFT) &
    108109            EHCI_CAPS_HCS_N_PORTS_MASK;
    109         usb_log_debug2("RH(%p): hcsparams: %x.\n", instance,
     110        usb_log_debug2("RH(%p): hcsparams: %x.", instance,
    110111            EHCI_RD(caps->hcsparams));
    111         usb_log_info("RH(%p): Found %u ports.\n", instance,
     112        usb_log_info("RH(%p): Found %u ports.", instance,
    112113            instance->port_count);
    113114
     
    127128
    128129        ehci_rh_hub_desc_init(instance, EHCI_RD(caps->hcsparams));
    129         instance->unfinished_interrupt_transfer = NULL;
     130        instance->guard = guard;
     131        instance->status_change_endpoint = NULL;
    130132
    131133        return virthub_base_init(&instance->base, name, &ops, instance,
     
    144146        assert(instance);
    145147        assert(batch);
    146         const usb_target_t target = {{
    147                 .address = batch->ep->address,
    148                 .endpoint = batch->ep->endpoint,
    149         }};
    150         batch->error = virthub_base_request(&instance->base, target,
    151             usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
    152             batch->buffer, batch->buffer_size, &batch->transfered_size);
     148        batch->error = virthub_base_request(&instance->base, batch->target,
     149            batch->dir, (void*) batch->setup.buffer,
     150            batch->dma_buffer.virt, batch->size,
     151            &batch->transferred_size);
    153152        if (batch->error == ENAK) {
    154153                usb_log_debug("RH(%p): BATCH(%p) adding as unfinished",
    155154                    instance, batch);
    156                 /* This is safe because only status change interrupt transfers
    157                  * return NAK. The assertion holds true because the batch
    158                  * existence prevents communication with that ep */
    159                 assert(instance->unfinished_interrupt_transfer == NULL);
    160                 instance->unfinished_interrupt_transfer = batch;
     155
     156                /* Lock the HC guard */
     157                fibril_mutex_lock(instance->guard);
     158                const int err = endpoint_activate_locked(batch->ep, batch);
     159                if (err) {
     160                        fibril_mutex_unlock(batch->ep->guard);
     161                        return err;
     162                }
     163
     164                /*
     165                 * Asserting that the HC do not run two instances of the status
     166                 * change endpoint - shall be true.
     167                 */
     168                assert(!instance->status_change_endpoint);
     169
     170                endpoint_add_ref(batch->ep);
     171                instance->status_change_endpoint = batch->ep;
     172                fibril_mutex_unlock(instance->guard);
    161173        } else {
    162                 usb_transfer_batch_finish(batch, NULL);
    163                 usb_transfer_batch_destroy(batch);
    164174                usb_log_debug("RH(%p): BATCH(%p) virtual request complete: %s",
    165175                    instance, batch, str_error(batch->error));
     176                usb_transfer_batch_finish(batch);
    166177        }
    167178        return EOK;
     
    177188errno_t ehci_rh_interrupt(ehci_rh_t *instance)
    178189{
    179         //TODO atomic swap needed
    180         usb_transfer_batch_t *batch = instance->unfinished_interrupt_transfer;
    181         instance->unfinished_interrupt_transfer = NULL;
    182         usb_log_debug2("RH(%p): Interrupt. Processing batch: %p",
    183             instance, batch);
     190        fibril_mutex_lock(instance->guard);
     191        endpoint_t *ep = instance->status_change_endpoint;
     192        if (!ep) {
     193                fibril_mutex_unlock(instance->guard);
     194                return EOK;
     195        }
     196
     197        usb_transfer_batch_t * const batch = ep->active_batch;
     198        endpoint_deactivate_locked(ep);
     199        instance->status_change_endpoint = NULL;
     200        fibril_mutex_unlock(instance->guard);
     201
     202        endpoint_del_ref(ep);
     203
    184204        if (batch) {
    185                 const usb_target_t target = {{
    186                         .address = batch->ep->address,
    187                         .endpoint = batch->ep->endpoint,
    188                 }};
    189                 batch->error = virthub_base_request(&instance->base, target,
    190                     usb_transfer_batch_direction(batch),
    191                     (void*)batch->setup_buffer,
    192                     batch->buffer, batch->buffer_size, &batch->transfered_size);
    193                 usb_transfer_batch_finish(batch, NULL);
    194                 usb_transfer_batch_destroy(batch);
     205                usb_log_debug2("RH(%p): Interrupt. Processing batch: %p",
     206                    instance, batch);
     207                batch->error = virthub_base_request(&instance->base, batch->target,
     208                    batch->dir, (void*) batch->setup.buffer,
     209                    batch->dma_buffer.virt, batch->size,
     210                    &batch->transferred_size);
     211                usb_transfer_batch_finish(batch);
    195212        }
    196213        return EOK;
     
    258275
    259276#define BIT_VAL(val, bit)   ((val & bit) ? 1 : 0)
    260 #define EHCI2USB(val, bit, feat)   (BIT_VAL(val, bit) << feat)
     277#define EHCI2USB(val, bit, mask)   (BIT_VAL(val, bit) ? mask : 0)
    261278
    262279/** Port status request handler.
     
    280297        const uint32_t reg = EHCI_RD(hub->registers->portsc[port]);
    281298        const uint32_t status = uint32_host2usb(
    282             EHCI2USB(reg, USB_PORTSC_CONNECT_FLAG, USB_HUB_FEATURE_PORT_CONNECTION) |
    283             EHCI2USB(reg, USB_PORTSC_ENABLED_FLAG, USB_HUB_FEATURE_PORT_ENABLE) |
    284             EHCI2USB(reg, USB_PORTSC_SUSPEND_FLAG, USB_HUB_FEATURE_PORT_SUSPEND) |
    285             EHCI2USB(reg, USB_PORTSC_OC_ACTIVE_FLAG, USB_HUB_FEATURE_PORT_OVER_CURRENT) |
    286             EHCI2USB(reg, USB_PORTSC_PORT_RESET_FLAG, USB_HUB_FEATURE_PORT_RESET) |
    287             EHCI2USB(reg, USB_PORTSC_PORT_POWER_FLAG, USB_HUB_FEATURE_PORT_POWER) |
     299            EHCI2USB(reg, USB_PORTSC_CONNECT_FLAG, USB_HUB_PORT_STATUS_CONNECTION) |
     300            EHCI2USB(reg, USB_PORTSC_ENABLED_FLAG, USB_HUB_PORT_STATUS_ENABLE) |
     301            EHCI2USB(reg, USB_PORTSC_SUSPEND_FLAG, USB2_HUB_PORT_STATUS_SUSPEND) |
     302            EHCI2USB(reg, USB_PORTSC_OC_ACTIVE_FLAG, USB_HUB_PORT_STATUS_OC) |
     303            EHCI2USB(reg, USB_PORTSC_PORT_RESET_FLAG, USB_HUB_PORT_STATUS_RESET) |
     304            EHCI2USB(reg, USB_PORTSC_PORT_POWER_FLAG, USB2_HUB_PORT_STATUS_POWER) |
    288305            (((reg & USB_PORTSC_LINE_STATUS_MASK) == USB_PORTSC_LINE_STATUS_K) ?
    289                 (1 << USB_HUB_FEATURE_PORT_LOW_SPEED) : 0) |
    290             ((reg & USB_PORTSC_PORT_OWNER_FLAG) ? 0 : (1 << USB_HUB_FEATURE_PORT_HIGH_SPEED)) |
    291             EHCI2USB(reg, USB_PORTSC_PORT_TEST_MASK, 11) |
    292             EHCI2USB(reg, USB_PORTSC_INDICATOR_MASK, 12) |
    293             EHCI2USB(reg, USB_PORTSC_CONNECT_CH_FLAG, USB_HUB_FEATURE_C_PORT_CONNECTION) |
    294             EHCI2USB(reg, USB_PORTSC_EN_CHANGE_FLAG, USB_HUB_FEATURE_C_PORT_ENABLE) |
    295             (hub->resume_flag[port] ? (1 << USB_HUB_FEATURE_C_PORT_SUSPEND) : 0) |
    296             EHCI2USB(reg, USB_PORTSC_OC_CHANGE_FLAG, USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |
    297             (hub->reset_flag[port] ? (1 << USB_HUB_FEATURE_C_PORT_RESET): 0)
     306                (USB2_HUB_PORT_STATUS_LOW_SPEED) : 0) |
     307            ((reg & USB_PORTSC_PORT_OWNER_FLAG) ? 0 : USB2_HUB_PORT_STATUS_HIGH_SPEED) |
     308            EHCI2USB(reg, USB_PORTSC_PORT_TEST_MASK, USB2_HUB_PORT_STATUS_TEST) |
     309            EHCI2USB(reg, USB_PORTSC_INDICATOR_MASK, USB2_HUB_PORT_STATUS_INDICATOR) |
     310            EHCI2USB(reg, USB_PORTSC_CONNECT_CH_FLAG, USB_HUB_PORT_STATUS_C_CONNECTION) |
     311            EHCI2USB(reg, USB_PORTSC_EN_CHANGE_FLAG, USB2_HUB_PORT_STATUS_C_ENABLE) |
     312            (hub->resume_flag[port] ? USB2_HUB_PORT_STATUS_C_SUSPEND : 0) |
     313            EHCI2USB(reg, USB_PORTSC_OC_CHANGE_FLAG, USB_HUB_PORT_STATUS_C_OC) |
     314            (hub->reset_flag[port] ? USB_HUB_PORT_STATUS_C_RESET: 0)
    298315        );
    299316        /* Note feature numbers for test and indicator feature do not
     
    396413                return EOK;
    397414
    398         case USB_HUB_FEATURE_PORT_ENABLE:         /*1*/
     415        case USB2_HUB_FEATURE_PORT_ENABLE:         /*1*/
    399416                usb_log_debug2("RH(%p-%u): Clear port enable.", hub, port);
    400417                EHCI_CLR(hub->registers->portsc[port],
     
    402419                return EOK;
    403420
    404         case USB_HUB_FEATURE_PORT_SUSPEND:        /*2*/
     421        case USB2_HUB_FEATURE_PORT_SUSPEND:        /*2*/
    405422                usb_log_debug2("RH(%p-%u): Clear port suspend.", hub, port);
    406423                /* If not in suspend it's noop */
     
    420437                    USB_PORTSC_CONNECT_CH_FLAG);
    421438                return EOK;
    422         case USB_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
     439        case USB2_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
    423440                usb_log_debug2("RH(%p-%u): Clear port enable change.",
    424441                    hub, port);
     
    432449                    USB_PORTSC_OC_CHANGE_FLAG);
    433450                return EOK;
    434         case USB_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
     451        case USB2_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
    435452                usb_log_debug2("RH(%p-%u): Clear port suspend change.",
    436453                    hub, port);
     
    467484        const unsigned feature = uint16_usb2host(setup_packet->value);
    468485        switch (feature) {
    469         case USB_HUB_FEATURE_PORT_ENABLE:  /*1*/
     486        case USB2_HUB_FEATURE_PORT_ENABLE:  /*1*/
    470487                usb_log_debug2("RH(%p-%u): Set port enable.", hub, port);
    471488                EHCI_SET(hub->registers->portsc[port],
    472489                    USB_PORTSC_ENABLED_FLAG);
    473490                return EOK;
    474         case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/
     491        case USB2_HUB_FEATURE_PORT_SUSPEND: /*2*/
    475492                usb_log_debug2("RH(%p-%u): Set port suspend.", hub, port);
    476493                EHCI_SET(hub->registers->portsc[port],
Note: See TracChangeset for help on using the changeset viewer.