Changeset df6ded8 in mainline for uspace/drv/bus/usb/ohci/ohci_rh.c


Ignore:
Timestamp:
2018-02-28T16:37:50Z (7 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/ohci/ohci_rh.c

    rf5e5f73 rdf6ded8  
    11/*
    22 * Copyright (c) 2013 Jan Vesely
     3 * Copyright (c) 2018 Ondrej Hlavaty
    34 * All rights reserved.
    45 *
     
    109110 * initializes internal virtual hub.
    110111 */
    111 errno_t ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs, const char *name)
     112errno_t ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs,
     113    fibril_mutex_t *guard, const char *name)
    112114{
    113115        assert(instance);
    114116        instance->registers = regs;
    115117        instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK;
    116         usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a));
     118        usb_log_debug2("rh_desc_a: %x.", OHCI_RD(regs->rh_desc_a));
    117119        if (instance->port_count > OHCI_MAX_PORTS) {
    118120                usb_log_warning("OHCI specification does not allow %d ports. "
    119                     "Max %d ports will be used.\n", instance->port_count,
     121                    "Max %d ports will be used.", instance->port_count,
    120122                    OHCI_MAX_PORTS);
    121123                instance->port_count = OHCI_MAX_PORTS;
    122124        }
    123         usb_log_info("%s: Found %u ports.\n", name, instance->port_count);
     125        usb_log_info("%s: Found %u ports.", name, instance->port_count);
    124126
    125127#if defined OHCI_POWER_SWITCH_no
    126         usb_log_info("%s: Set power mode to no power switching.\n", name);
     128        usb_log_info("%s: Set power mode to no power switching.", name);
    127129        /* Set port power mode to no power-switching. (always on) */
    128130        OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG);
     
    132134
    133135#elif defined OHCI_POWER_SWITCH_ganged
    134         usb_log_info("%s: Set power mode to ganged power switching.\n", name);
     136        usb_log_info("%s: Set power mode to ganged power switching.", name);
    135137        /* Set port power mode to ganged power-switching. */
    136138        OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
     
    144146        OHCI_CLR(regs->rh_desc_a, RHDA_OCPM_FLAG);
    145147#else
    146         usb_log_info("%s: Set power mode to per-port power switching.\n", name);
     148        usb_log_info("%s: Set power mode to per-port power switching.", name);
    147149        /* Set port power mode to per port power-switching. */
    148150        OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
     
    162164
    163165        ohci_rh_hub_desc_init(instance);
    164         instance->unfinished_interrupt_transfer = NULL;
     166        instance->status_change_endpoint = NULL;
     167        instance->guard = guard;
    165168        return virthub_base_init(&instance->base, name, &ops, instance,
    166169            NULL, &instance->hub_descriptor.header, HUB_STATUS_CHANGE_PIPE);
     
    178181        assert(instance);
    179182        assert(batch);
    180         const usb_target_t target = {{
    181                 .address = batch->ep->address,
    182                 .endpoint = batch->ep->endpoint,
    183         }};
    184         batch->error = virthub_base_request(&instance->base, target,
    185             usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
    186             batch->buffer, batch->buffer_size, &batch->transfered_size);
     183        batch->error = virthub_base_request(&instance->base, batch->target,
     184            batch->dir, &batch->setup.packet,
     185            batch->dma_buffer.virt, batch->size, &batch->transferred_size);
    187186        if (batch->error == ENAK) {
    188                 /* This is safe because only status change interrupt transfers
    189                  * return NAK. The assertion holds true because the batch
    190                  * existence prevents communication with that ep */
    191                 assert(instance->unfinished_interrupt_transfer == NULL);
    192                 instance->unfinished_interrupt_transfer = batch;
     187                /* Lock the HC guard */
     188                fibril_mutex_lock(instance->guard);
     189                const int err = endpoint_activate_locked(batch->ep, batch);
     190                if (err) {
     191                        fibril_mutex_unlock(batch->ep->guard);
     192                        return err;
     193                }
     194
     195                /*
     196                 * Asserting that the HC do not run two instances of the status
     197                 * change endpoint - shall be true.
     198                 */
     199                assert(!instance->status_change_endpoint);
     200
     201                endpoint_add_ref(batch->ep);
     202                instance->status_change_endpoint = batch->ep;
     203                fibril_mutex_unlock(instance->guard);
    193204        } else {
    194                 usb_transfer_batch_finish(batch, NULL);
    195                 usb_transfer_batch_destroy(batch);
     205                usb_transfer_batch_finish(batch);
    196206        }
    197207        return EOK;
     
    207217errno_t ohci_rh_interrupt(ohci_rh_t *instance)
    208218{
    209         //TODO atomic swap needed
    210         usb_transfer_batch_t *batch = instance->unfinished_interrupt_transfer;
    211         instance->unfinished_interrupt_transfer = NULL;
     219        fibril_mutex_lock(instance->guard);
     220        endpoint_t *ep = instance->status_change_endpoint;
     221        if (!ep) {
     222                fibril_mutex_unlock(instance->guard);
     223                return EOK;
     224        }
     225
     226        usb_transfer_batch_t * const batch = ep->active_batch;
     227        endpoint_deactivate_locked(ep);
     228        instance->status_change_endpoint = NULL;
     229        fibril_mutex_unlock(instance->guard);
     230
     231        endpoint_del_ref(ep);
     232
    212233        if (batch) {
    213                 const usb_target_t target = {{
    214                         .address = batch->ep->address,
    215                         .endpoint = batch->ep->endpoint,
    216                 }};
    217                 batch->error = virthub_base_request(&instance->base, target,
    218                     usb_transfer_batch_direction(batch),
    219                     (void*)batch->setup_buffer,
    220                     batch->buffer, batch->buffer_size, &batch->transfered_size);
    221                 usb_transfer_batch_finish(batch, NULL);
    222                 usb_transfer_batch_destroy(batch);
     234                batch->error = virthub_base_request(&instance->base, batch->target,
     235                    batch->dir, &batch->setup.packet,
     236                    batch->dma_buffer.virt, batch->size, &batch->transferred_size);
     237                usb_transfer_batch_finish(batch);
    223238        }
    224239        return EOK;
     
    351366                }
    352367
    353         case USB_HUB_FEATURE_PORT_ENABLE:         /*1*/
     368        case USB2_HUB_FEATURE_PORT_ENABLE:         /*1*/
    354369                OHCI_WR(hub->registers->rh_port_status[port],
    355370                    RHPS_CLEAR_PORT_ENABLE);
    356371                return EOK;
    357372
    358         case USB_HUB_FEATURE_PORT_SUSPEND:        /*2*/
     373        case USB2_HUB_FEATURE_PORT_SUSPEND:        /*2*/
    359374                OHCI_WR(hub->registers->rh_port_status[port],
    360375                    RHPS_CLEAR_PORT_SUSPEND);
     
    362377
    363378        case USB_HUB_FEATURE_C_PORT_CONNECTION:   /*16*/
    364         case USB_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
    365         case USB_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
     379        case USB2_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
     380        case USB2_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
    366381        case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/
    367382        case USB_HUB_FEATURE_C_PORT_RESET:        /*20*/
    368383                usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, "
    369                     "C_SUSPEND, C_OC or C_RESET on port %u.\n", port);
     384                    "C_SUSPEND, C_OC or C_RESET on port %u.", port);
    370385                /* Bit offsets correspond to the feature number */
    371386                OHCI_WR(hub->registers->rh_port_status[port],
     
    412427                /* Fall through, for per port power */
    413428                /* Fallthrough */
    414         case USB_HUB_FEATURE_PORT_ENABLE:  /*1*/
    415         case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/
     429        case USB2_HUB_FEATURE_PORT_ENABLE:  /*1*/
     430        case USB2_HUB_FEATURE_PORT_SUSPEND: /*2*/
    416431        case USB_HUB_FEATURE_PORT_RESET:   /*4*/
    417432                usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET "
    418                     "on port %u.\n", port);
     433                    "on port %u.", port);
    419434                /* Bit offsets correspond to the feature number */
    420435                OHCI_WR(hub->registers->rh_port_status[port], 1 << feature);
     
    462477        }
    463478
    464         usb_log_debug2("OHCI root hub interrupt mask: %hx.\n", mask);
     479        usb_log_debug2("OHCI root hub interrupt mask: %hx.", mask);
    465480
    466481        if (mask == 0)
Note: See TracChangeset for help on using the changeset viewer.