Ignore:
File:
1 edited

Legend:

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

    r9c10e51 r549ff23  
    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
     
    224235                usb_transfer_batch_finish_error(request, NULL, 0, EINVAL);
    225236        }
    226         usb_transfer_batch_dispose(request);
     237        usb_transfer_batch_destroy(request);
    227238}
    228239/*----------------------------------------------------------------------------*/
     
    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_destroy(
     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);
     
    351363                mask |= 1;
    352364        }
    353         size_t port = 1;
    354         for (; port <= instance->port_count; ++port) {
     365        for (size_t port = 1; port <= instance->port_count; ++port) {
    355366                /* Write-clean bits are those that indicate change */
    356367                if (RHPS_CHANGE_WC_MASK
     
    373384 * @return error code
    374385 */
    375 int get_status(rh_t *instance, usb_transfer_batch_t *request)
     386int get_status(const rh_t *instance, usb_transfer_batch_t *request)
    376387{
    377388        assert(instance);
     
    419430 * @return Error code
    420431 */
    421 int get_descriptor(rh_t *instance, usb_transfer_batch_t *request)
     432int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request)
    422433{
    423434        assert(instance);
     
    497508 * @return error code
    498509 */
    499 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)
    500511{
    501512        assert(instance);
     
    536547 * @return error code
    537548 */
    538 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)
    539550{
    540551        assert(instance);
     
    593604 * @return error code
    594605 */
    595 int set_feature(rh_t *instance, usb_transfer_batch_t *request)
     606int set_feature(const rh_t *instance, usb_transfer_batch_t *request)
    596607{
    597608        assert(instance);
     
    629640 * @return error code
    630641 */
    631 int clear_feature(rh_t *instance, usb_transfer_batch_t *request)
     642int clear_feature(const rh_t *instance, usb_transfer_batch_t *request)
    632643{
    633644        assert(instance);
     
    636647        const usb_device_request_setup_packet_t *setup_request =
    637648            (usb_device_request_setup_packet_t *) request->setup_buffer;
     649
    638650        request->transfered_size = 0;
     651
    639652        switch (setup_request->request_type)
    640653        {
     
    648661                /*
    649662                 * Chapter 11.16.2 specifies that only C_HUB_LOCAL_POWER and
    650                  * C_HUB_OVER_CURRENT are supported. C_HUB_OVER_CURRENT is represented
    651                  * 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
    652666                 * as root hubs do not support local power status feature.
    653667                 * (OHCI pg. 127) */
     
    721735                    "additional data\n");
    722736                return clear_feature(instance, request);
     737
    723738        case USB_DEVREQ_SET_FEATURE:
    724739                usb_log_debug2("Processing request without "
Note: See TracChangeset for help on using the changeset viewer.