Changeset 916991b in mainline for uspace/drv/bus/usb/xhci/rh.c


Ignore:
Timestamp:
2017-10-05T16:13:55Z (7 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4930b15
Parents:
9876e34
Message:

Implemented SetStatusFeature request.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/rh.c

    r9876e34 r916991b  
    4545#include "rh.h"
    4646
     47#define USB_MAP_VALUE(a, b) [USB_HUB_FEATURE_##a] = b
     48#define USB_MAP_XHCI(a, b) USB_MAP_VALUE(a, XHCI_REG_MASK(XHCI_PORT_##b))
     49
    4750enum {
    4851        HUB_STATUS_CHANGE_PIPE = 1,
     
    389392        xhci_port_regs_t* regs = &hub->hc->op_regs->portrs[setup_packet->index - 1];
    390393
    391 #define USB_MAP_XHCI(a, b) [USB_HUB_FEATURE_##a] = XHCI_REG_MASK(XHCI_PORT_##b)
    392 
    393394        const usb_hub_class_feature_t feature = uint16_usb2host(setup_packet->value);
    394395        static const ioport32_t masks[] = {
     
    396397                USB_MAP_XHCI(C_PORT_ENABLE, PEC),
    397398                USB_MAP_XHCI(C_PORT_OVER_CURRENT, OCC),
    398                 USB_MAP_XHCI(C_PORT_RESET, PRC)
     399                USB_MAP_XHCI(C_PORT_RESET, PRC),
     400                USB_MAP_XHCI(PORT_ENABLE, PED),
     401                USB_MAP_XHCI(PORT_RESET, PR),
     402                USB_MAP_XHCI(PORT_POWER, PP)
    399403        };
    400404
    401 #undef USB_MAP_XHCI
     405        static const bool is_change[] = {
     406                USB_MAP_VALUE(C_PORT_CONNECTION, true),
     407                USB_MAP_VALUE(C_PORT_ENABLE, true),
     408                USB_MAP_VALUE(C_PORT_OVER_CURRENT, true),
     409                USB_MAP_VALUE(C_PORT_RESET, true),
     410                USB_MAP_VALUE(PORT_ENABLE, false),
     411                USB_MAP_VALUE(PORT_RESET, false),
     412                USB_MAP_VALUE(PORT_POWER, false)
     413        };
    402414
    403415        usb_log_debug2("RH: ClearPortFeature(%hu) = %d.", setup_packet->index,
    404416                feature);
    405417
    406         /* Clear the register by writing 1. */
    407         XHCI_REG_WR_FIELD(&regs->portsc, masks[feature], 32);
     418        if (is_change[feature]) {
     419                /* Clear the register by writing 1. */
     420                XHCI_REG_SET_FIELD(&regs->portsc, masks[feature], 32);
     421        } else {
     422                /* Clear the register by writing 0. */
     423                XHCI_REG_CLR_FIELD(&regs->portsc, masks[feature], 32);
     424        }
    408425
    409426        return EOK;
     
    422439    uint8_t *data, size_t *act_size)
    423440{
    424         /* TODO: Implement me! */
    425         usb_log_debug2("Called req_set_port_feature().");
     441        xhci_rh_t *hub = virthub_get_data(device);
     442        assert(hub);
     443
     444        if (!setup_packet->index || setup_packet->index > hub->max_ports) {
     445                return ESTALL;
     446        }
     447
     448        /* The index is 1-based. */
     449        xhci_port_regs_t* regs = &hub->hc->op_regs->portrs[setup_packet->index - 1];
     450
     451        const usb_hub_class_feature_t feature = uint16_usb2host(setup_packet->value);
     452        static const ioport32_t masks[] = {
     453                USB_MAP_XHCI(PORT_ENABLE, PED),
     454                USB_MAP_XHCI(PORT_RESET, PR),
     455                USB_MAP_XHCI(PORT_POWER, PP)
     456        };
     457
     458        usb_log_debug2("RH: SetPortFeature(%hu) = %d.", setup_packet->index,
     459                feature);
     460
     461        /* Set the feature in the PIO register. */
     462        XHCI_REG_SET_FIELD(&regs->portsc, masks[feature], 32);
     463
    426464        return EOK;
    427465}
Note: See TracChangeset for help on using the changeset viewer.