Changeset 98fb010 in mainline for uspace/drv/bus/usb/ohci/root_hub.c


Ignore:
Timestamp:
2011-10-16T19:33:47Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1f131fb9
Parents:
721d4b6e (diff), f8dfb40 (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:

Merge OHCI related changes and improvements.

Rework some routines and use asserts to verify that the device follows OHCI specs.
Add explanatory comments.

File:
1 edited

Legend:

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

    r721d4b6e r98fb010  
    3535#include <errno.h>
    3636#include <str_error.h>
     37#include <fibril_synch.h>
    3738
    3839#include <usb/debug.h>
     40#include <usb/dev/request.h>
     41#include <usb/classes/hub.h>
    3942
    4043#include "root_hub.h"
     
    4346#include <usb/dev/driver.h>
    4447#include "ohci_regs.h"
    45 
    46 #include <usb/dev/request.h>
    47 #include <usb/classes/hub.h>
    4848
    4949/**
     
    108108static void create_serialized_hub_descriptor(rh_t *instance);
    109109static void rh_init_descriptors(rh_t *instance);
    110 static uint16_t create_interrupt_mask(rh_t *instance);
    111 static int get_status(rh_t *instance, usb_transfer_batch_t *request);
    112 static int get_descriptor(rh_t *instance, usb_transfer_batch_t *request);
    113 static int set_feature(rh_t *instance, usb_transfer_batch_t *request);
    114 static int clear_feature(rh_t *instance, usb_transfer_batch_t *request);
    115 static int set_feature_port(rh_t *instance, uint16_t feature, uint16_t port);
    116 static int clear_feature_port(rh_t *instance, uint16_t feature, uint16_t port);
     110static uint16_t create_interrupt_mask(const rh_t *instance);
     111static int get_status(const rh_t *instance, usb_transfer_batch_t *request);
     112static int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request);
     113static int set_feature(const rh_t *instance, usb_transfer_batch_t *request);
     114static int clear_feature(const rh_t *instance, usb_transfer_batch_t *request);
     115static int set_feature_port(
     116    const rh_t *instance, uint16_t feature, uint16_t port);
     117static int clear_feature_port(
     118    const rh_t *instance, uint16_t feature, uint16_t port);
    117119static int control_request(rh_t *instance, usb_transfer_batch_t *request);
    118120static inline void interrupt_request(
     
    153155        instance->unfinished_interrupt_transfer = NULL;
    154156
    155 #ifdef OHCI_POWER_SWITCH_no
     157#if defined OHCI_POWER_SWITCH_no
    156158        /* Set port power mode to no power-switching. (always on) */
    157159        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
     160
    158161        /* Set to no over-current reporting */
    159162        instance->registers->rh_desc_a |= RHDA_NOCP_FLAG;
     163
    160164#elif defined OHCI_POWER_SWITCH_ganged
    161165        /* Set port power mode to no ganged power-switching. */
     
    163167        instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG;
    164168        instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     169
    165170        /* Set to global over-current */
    166171        instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
     
    174179        instance->registers->rh_desc_b &= (RHDB_PCC_MASK << RHDB_PCC_SHIFT);
    175180        instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     181
    176182        /* Return control to per port state */
    177183        instance->registers->rh_desc_b |=
    178184                ((1 << (instance->port_count + 1)) - 1) << RHDB_PCC_SHIFT;
     185
    179186        /* Set per port over-current */
    180187        instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
     
    182189#endif
    183190
     191        fibril_mutex_initialize(&instance->guard);
    184192        rh_init_descriptors(instance);
    185193
     
    209217        case USB_TRANSFER_INTERRUPT:
    210218                usb_log_debug("Root hub got INTERRUPT packet\n");
     219                fibril_mutex_lock(&instance->guard);
     220                assert(instance->unfinished_interrupt_transfer == NULL);
    211221                const uint16_t mask = create_interrupt_mask(instance);
    212222                if (mask == 0) {
    213223                        usb_log_debug("No changes..\n");
    214                         assert(instance->unfinished_interrupt_transfer == NULL);
    215224                        instance->unfinished_interrupt_transfer = request;
     225                        fibril_mutex_unlock(&instance->guard);
    216226                        return;
    217227                }
    218228                usb_log_debug("Processing changes...\n");
    219229                interrupt_request(request, mask, instance->interrupt_mask_size);
     230                fibril_mutex_unlock(&instance->guard);
    220231                break;
    221232
     
    237248        assert(instance);
    238249
    239         if (!instance->unfinished_interrupt_transfer)
    240                 return;
    241 
    242         usb_log_debug("Finalizing interrupt transfer\n");
    243         const uint16_t mask = create_interrupt_mask(instance);
    244         interrupt_request(instance->unfinished_interrupt_transfer,
    245             mask, instance->interrupt_mask_size);
    246         usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer);
    247 
    248         instance->unfinished_interrupt_transfer = NULL;
     250        fibril_mutex_lock(&instance->guard);
     251        if (instance->unfinished_interrupt_transfer) {
     252                usb_log_debug("Finalizing interrupt transfer\n");
     253                const uint16_t mask = create_interrupt_mask(instance);
     254                interrupt_request(instance->unfinished_interrupt_transfer,
     255                    mask, instance->interrupt_mask_size);
     256                usb_transfer_batch_dispose(
     257                    instance->unfinished_interrupt_transfer);
     258                instance->unfinished_interrupt_transfer = NULL;
     259        }
     260        fibril_mutex_unlock(&instance->guard);
    249261}
    250262/*----------------------------------------------------------------------------*/
     
    342354 * @return Mask of changes.
    343355 */
    344 uint16_t create_interrupt_mask(rh_t *instance)
     356uint16_t create_interrupt_mask(const rh_t *instance)
    345357{
    346358        assert(instance);
     
    372384 * @return error code
    373385 */
    374 int get_status(rh_t *instance, usb_transfer_batch_t *request)
     386int get_status(const rh_t *instance, usb_transfer_batch_t *request)
    375387{
    376388        assert(instance);
     
    418430 * @return Error code
    419431 */
    420 int get_descriptor(rh_t *instance, usb_transfer_batch_t *request)
     432int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request)
    421433{
    422434        assert(instance);
     
    496508 * @return error code
    497509 */
    498 int set_feature_port(rh_t *instance, uint16_t feature, uint16_t port)
     510int set_feature_port(const rh_t *instance, uint16_t feature, uint16_t port)
    499511{
    500512        assert(instance);
     
    535547 * @return error code
    536548 */
    537 int clear_feature_port(rh_t *instance, uint16_t feature, uint16_t port)
     549int clear_feature_port(const rh_t *instance, uint16_t feature, uint16_t port)
    538550{
    539551        assert(instance);
     
    592604 * @return error code
    593605 */
    594 int set_feature(rh_t *instance, usb_transfer_batch_t *request)
     606int set_feature(const rh_t *instance, usb_transfer_batch_t *request)
    595607{
    596608        assert(instance);
     
    628640 * @return error code
    629641 */
    630 int clear_feature(rh_t *instance, usb_transfer_batch_t *request)
     642int clear_feature(const rh_t *instance, usb_transfer_batch_t *request)
    631643{
    632644        assert(instance);
     
    635647        const usb_device_request_setup_packet_t *setup_request =
    636648            (usb_device_request_setup_packet_t *) request->setup_buffer;
     649
    637650        request->transfered_size = 0;
     651
    638652        switch (setup_request->request_type)
    639653        {
     
    647661                /*
    648662                 * Chapter 11.16.2 specifies that only C_HUB_LOCAL_POWER and
    649                  * C_HUB_OVER_CURRENT are supported. C_HUB_OVER_CURRENT is represented
    650                  * by OHCI RHS_OCIC_FLAG. C_HUB_LOCAL_POWER is not supported
     663                 * C_HUB_OVER_CURRENT are supported.
     664                 * C_HUB_OVER_CURRENT is represented by OHCI RHS_OCIC_FLAG.
     665                 * C_HUB_LOCAL_POWER is not supported
    651666                 * as root hubs do not support local power status feature.
    652667                 * (OHCI pg. 127) */
     
    720735                    "additional data\n");
    721736                return clear_feature(instance, request);
     737
    722738        case USB_DEVREQ_SET_FEATURE:
    723739                usb_log_debug2("Processing request without "
Note: See TracChangeset for help on using the changeset viewer.