linux/drivers/usb/gadget/udc/aspeed-vhub/hub.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget
   4 *
   5 * hub.c - virtual hub handling
   6 *
   7 * Copyright 2017 IBM Corporation
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <linux/delay.h>
  14#include <linux/ioport.h>
  15#include <linux/slab.h>
  16#include <linux/errno.h>
  17#include <linux/list.h>
  18#include <linux/interrupt.h>
  19#include <linux/proc_fs.h>
  20#include <linux/prefetch.h>
  21#include <linux/clk.h>
  22#include <linux/usb/gadget.h>
  23#include <linux/of.h>
  24#include <linux/of_gpio.h>
  25#include <linux/regmap.h>
  26#include <linux/dma-mapping.h>
  27#include <linux/bcd.h>
  28#include <linux/version.h>
  29#include <linux/usb.h>
  30#include <linux/usb/hcd.h>
  31
  32#include "vhub.h"
  33
  34/* usb 2.0 hub device descriptor
  35 *
  36 * A few things we may want to improve here:
  37 *
  38 *    - We may need to indicate TT support
  39 *    - We may need a device qualifier descriptor
  40 *      as devices can pretend to be usb1 or 2
  41 *    - Make vid/did overridable
  42 *    - make it look like usb1 if usb1 mode forced
  43 */
  44#define KERNEL_REL      bin2bcd(LINUX_VERSION_MAJOR)
  45#define KERNEL_VER      bin2bcd(LINUX_VERSION_PATCHLEVEL)
  46
  47enum {
  48        AST_VHUB_STR_INDEX_MAX = 4,
  49        AST_VHUB_STR_MANUF = 3,
  50        AST_VHUB_STR_PRODUCT = 2,
  51        AST_VHUB_STR_SERIAL = 1,
  52};
  53
  54static const struct usb_device_descriptor ast_vhub_dev_desc = {
  55        .bLength                = USB_DT_DEVICE_SIZE,
  56        .bDescriptorType        = USB_DT_DEVICE,
  57        .bcdUSB                 = cpu_to_le16(0x0200),
  58        .bDeviceClass           = USB_CLASS_HUB,
  59        .bDeviceSubClass        = 0,
  60        .bDeviceProtocol        = 1,
  61        .bMaxPacketSize0        = 64,
  62        .idVendor               = cpu_to_le16(0x1d6b),
  63        .idProduct              = cpu_to_le16(0x0107),
  64        .bcdDevice              = cpu_to_le16(0x0100),
  65        .iManufacturer          = AST_VHUB_STR_MANUF,
  66        .iProduct               = AST_VHUB_STR_PRODUCT,
  67        .iSerialNumber          = AST_VHUB_STR_SERIAL,
  68        .bNumConfigurations     = 1,
  69};
  70
  71/*
  72 * Configuration descriptor: same comments as above
  73 * regarding handling USB1 mode.
  74 */
  75
  76/*
  77 * We don't use sizeof() as Linux definition of
  78 * struct usb_endpoint_descriptor contains 2
  79 * extra bytes
  80 */
  81#define AST_VHUB_CONF_DESC_SIZE (USB_DT_CONFIG_SIZE + \
  82                                 USB_DT_INTERFACE_SIZE + \
  83                                 USB_DT_ENDPOINT_SIZE)
  84
  85static const struct ast_vhub_full_cdesc ast_vhub_conf_desc = {
  86        .cfg = {
  87                .bLength                = USB_DT_CONFIG_SIZE,
  88                .bDescriptorType        = USB_DT_CONFIG,
  89                .wTotalLength           = cpu_to_le16(AST_VHUB_CONF_DESC_SIZE),
  90                .bNumInterfaces         = 1,
  91                .bConfigurationValue    = 1,
  92                .iConfiguration         = 0,
  93                .bmAttributes           = USB_CONFIG_ATT_ONE |
  94                                          USB_CONFIG_ATT_SELFPOWER |
  95                                          USB_CONFIG_ATT_WAKEUP,
  96                .bMaxPower              = 0,
  97        },
  98        .intf = {
  99                .bLength                = USB_DT_INTERFACE_SIZE,
 100                .bDescriptorType        = USB_DT_INTERFACE,
 101                .bInterfaceNumber       = 0,
 102                .bAlternateSetting      = 0,
 103                .bNumEndpoints          = 1,
 104                .bInterfaceClass        = USB_CLASS_HUB,
 105                .bInterfaceSubClass     = 0,
 106                .bInterfaceProtocol     = 0,
 107                .iInterface             = 0,
 108        },
 109        .ep = {
 110                .bLength                = USB_DT_ENDPOINT_SIZE,
 111                .bDescriptorType        = USB_DT_ENDPOINT,
 112                .bEndpointAddress       = 0x81,
 113                .bmAttributes           = USB_ENDPOINT_XFER_INT,
 114                .wMaxPacketSize         = cpu_to_le16(1),
 115                .bInterval              = 0x0c,
 116        },
 117};
 118
 119#define AST_VHUB_HUB_DESC_SIZE  (USB_DT_HUB_NONVAR_SIZE + 2)
 120
 121static const struct usb_hub_descriptor ast_vhub_hub_desc = {
 122        .bDescLength                    = AST_VHUB_HUB_DESC_SIZE,
 123        .bDescriptorType                = USB_DT_HUB,
 124        .bNbrPorts                      = AST_VHUB_NUM_PORTS,
 125        .wHubCharacteristics            = cpu_to_le16(HUB_CHAR_NO_LPSM),
 126        .bPwrOn2PwrGood                 = 10,
 127        .bHubContrCurrent               = 0,
 128        .u.hs.DeviceRemovable[0]        = 0,
 129        .u.hs.DeviceRemovable[1]        = 0xff,
 130};
 131
 132/*
 133 * These strings converted to UTF-16 must be smaller than
 134 * our EP0 buffer.
 135 */
 136static const struct usb_string ast_vhub_str_array[] = {
 137        {
 138                .id = AST_VHUB_STR_SERIAL,
 139                .s = "00000000"
 140        },
 141        {
 142                .id = AST_VHUB_STR_PRODUCT,
 143                .s = "USB Virtual Hub"
 144        },
 145        {
 146                .id = AST_VHUB_STR_MANUF,
 147                .s = "Aspeed"
 148        },
 149        { }
 150};
 151
 152static const struct usb_gadget_strings ast_vhub_strings = {
 153        .language = 0x0409,
 154        .strings = (struct usb_string *)ast_vhub_str_array
 155};
 156
 157static int ast_vhub_hub_dev_status(struct ast_vhub_ep *ep,
 158                                   u16 wIndex, u16 wValue)
 159{
 160        u8 st0;
 161
 162        EPDBG(ep, "GET_STATUS(dev)\n");
 163
 164        /*
 165         * Mark it as self-powered, I doubt the BMC is powered off
 166         * the USB bus ...
 167         */
 168        st0 = 1 << USB_DEVICE_SELF_POWERED;
 169
 170        /*
 171         * Need to double check how remote wakeup actually works
 172         * on that chip and what triggers it.
 173         */
 174        if (ep->vhub->wakeup_en)
 175                st0 |= 1 << USB_DEVICE_REMOTE_WAKEUP;
 176
 177        return ast_vhub_simple_reply(ep, st0, 0);
 178}
 179
 180static int ast_vhub_hub_ep_status(struct ast_vhub_ep *ep,
 181                                  u16 wIndex, u16 wValue)
 182{
 183        int ep_num;
 184        u8 st0 = 0;
 185
 186        ep_num = wIndex & USB_ENDPOINT_NUMBER_MASK;
 187        EPDBG(ep, "GET_STATUS(ep%d)\n", ep_num);
 188
 189        /* On the hub we have only EP 0 and 1 */
 190        if (ep_num == 1) {
 191                if (ep->vhub->ep1_stalled)
 192                        st0 |= 1 << USB_ENDPOINT_HALT;
 193        } else if (ep_num != 0)
 194                return std_req_stall;
 195
 196        return ast_vhub_simple_reply(ep, st0, 0);
 197}
 198
 199static int ast_vhub_hub_dev_feature(struct ast_vhub_ep *ep,
 200                                    u16 wIndex, u16 wValue,
 201                                    bool is_set)
 202{
 203        EPDBG(ep, "%s_FEATURE(dev val=%02x)\n",
 204              is_set ? "SET" : "CLEAR", wValue);
 205
 206        if (wValue != USB_DEVICE_REMOTE_WAKEUP)
 207                return std_req_stall;
 208
 209        ep->vhub->wakeup_en = is_set;
 210        EPDBG(ep, "Hub remote wakeup %s\n",
 211              is_set ? "enabled" : "disabled");
 212
 213        return std_req_complete;
 214}
 215
 216static int ast_vhub_hub_ep_feature(struct ast_vhub_ep *ep,
 217                                   u16 wIndex, u16 wValue,
 218                                   bool is_set)
 219{
 220        int ep_num;
 221        u32 reg;
 222
 223        ep_num = wIndex & USB_ENDPOINT_NUMBER_MASK;
 224        EPDBG(ep, "%s_FEATURE(ep%d val=%02x)\n",
 225              is_set ? "SET" : "CLEAR", ep_num, wValue);
 226
 227        if (ep_num > 1)
 228                return std_req_stall;
 229        if (wValue != USB_ENDPOINT_HALT)
 230                return std_req_stall;
 231        if (ep_num == 0)
 232                return std_req_complete;
 233
 234        EPDBG(ep, "%s stall on EP 1\n",
 235              is_set ? "setting" : "clearing");
 236
 237        ep->vhub->ep1_stalled = is_set;
 238        reg = readl(ep->vhub->regs + AST_VHUB_EP1_CTRL);
 239        if (is_set) {
 240                reg |= VHUB_EP1_CTRL_STALL;
 241        } else {
 242                reg &= ~VHUB_EP1_CTRL_STALL;
 243                reg |= VHUB_EP1_CTRL_RESET_TOGGLE;
 244        }
 245        writel(reg, ep->vhub->regs + AST_VHUB_EP1_CTRL);
 246
 247        return std_req_complete;
 248}
 249
 250static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
 251                             u8 desc_type, u16 len)
 252{
 253        size_t dsize;
 254        struct ast_vhub *vhub = ep->vhub;
 255
 256        EPDBG(ep, "GET_DESCRIPTOR(type:%d)\n", desc_type);
 257
 258        /*
 259         * Copy first to EP buffer and send from there, so
 260         * we can do some in-place patching if needed. We know
 261         * the EP buffer is big enough but ensure that doesn't
 262         * change. We do that now rather than later after we
 263         * have checked sizes etc... to avoid a gcc bug where
 264         * it thinks len is constant and barfs about read
 265         * overflows in memcpy.
 266         */
 267        switch(desc_type) {
 268        case USB_DT_DEVICE:
 269                dsize = USB_DT_DEVICE_SIZE;
 270                memcpy(ep->buf, &vhub->vhub_dev_desc, dsize);
 271                BUILD_BUG_ON(dsize > sizeof(vhub->vhub_dev_desc));
 272                BUILD_BUG_ON(USB_DT_DEVICE_SIZE >= AST_VHUB_EP0_MAX_PACKET);
 273                break;
 274        case USB_DT_CONFIG:
 275                dsize = AST_VHUB_CONF_DESC_SIZE;
 276                memcpy(ep->buf, &vhub->vhub_conf_desc, dsize);
 277                BUILD_BUG_ON(dsize > sizeof(vhub->vhub_conf_desc));
 278                BUILD_BUG_ON(AST_VHUB_CONF_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
 279                break;
 280        case USB_DT_HUB:
 281                dsize = AST_VHUB_HUB_DESC_SIZE;
 282                memcpy(ep->buf, &vhub->vhub_hub_desc, dsize);
 283                BUILD_BUG_ON(dsize > sizeof(vhub->vhub_hub_desc));
 284                BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
 285                break;
 286        default:
 287                return std_req_stall;
 288        }
 289
 290        /* Crop requested length */
 291        if (len > dsize)
 292                len = dsize;
 293
 294        /* Shoot it from the EP buffer */
 295        return ast_vhub_reply(ep, NULL, len);
 296}
 297
 298static struct usb_gadget_strings*
 299ast_vhub_str_of_container(struct usb_gadget_string_container *container)
 300{
 301        return (struct usb_gadget_strings *)container->stash;
 302}
 303
 304static int ast_vhub_collect_languages(struct ast_vhub *vhub, void *buf,
 305                                      size_t size)
 306{
 307        int rc, hdr_len, nlangs, max_langs;
 308        struct usb_gadget_strings *lang_str;
 309        struct usb_gadget_string_container *container;
 310        struct usb_string_descriptor *sdesc = buf;
 311
 312        nlangs = 0;
 313        hdr_len = sizeof(struct usb_descriptor_header);
 314        max_langs = (size - hdr_len) / sizeof(sdesc->wData[0]);
 315        list_for_each_entry(container, &vhub->vhub_str_desc, list) {
 316                if (nlangs >= max_langs)
 317                        break;
 318
 319                lang_str = ast_vhub_str_of_container(container);
 320                sdesc->wData[nlangs++] = cpu_to_le16(lang_str->language);
 321        }
 322
 323        rc = hdr_len + nlangs * sizeof(sdesc->wData[0]);
 324        sdesc->bLength = rc;
 325        sdesc->bDescriptorType = USB_DT_STRING;
 326
 327        return rc;
 328}
 329
 330static struct usb_gadget_strings *ast_vhub_lookup_string(struct ast_vhub *vhub,
 331                                                         u16 lang_id)
 332{
 333        struct usb_gadget_strings *lang_str;
 334        struct usb_gadget_string_container *container;
 335
 336        list_for_each_entry(container, &vhub->vhub_str_desc, list) {
 337                lang_str = ast_vhub_str_of_container(container);
 338                if (lang_str->language == lang_id)
 339                        return lang_str;
 340        }
 341
 342        return NULL;
 343}
 344
 345static int ast_vhub_rep_string(struct ast_vhub_ep *ep,
 346                               u8 string_id, u16 lang_id,
 347                               u16 len)
 348{
 349        int rc;
 350        u8 buf[256];
 351        struct ast_vhub *vhub = ep->vhub;
 352        struct usb_gadget_strings *lang_str;
 353
 354        if (string_id == 0) {
 355                rc = ast_vhub_collect_languages(vhub, buf, sizeof(buf));
 356        } else {
 357                lang_str = ast_vhub_lookup_string(vhub, lang_id);
 358                if (!lang_str)
 359                        return std_req_stall;
 360
 361                rc = usb_gadget_get_string(lang_str, string_id, buf);
 362        }
 363
 364        if (rc < 0 || rc >= AST_VHUB_EP0_MAX_PACKET)
 365                return std_req_stall;
 366
 367        /* Shoot it from the EP buffer */
 368        memcpy(ep->buf, buf, rc);
 369        return ast_vhub_reply(ep, NULL, min_t(u16, rc, len));
 370}
 371
 372enum std_req_rc ast_vhub_std_hub_request(struct ast_vhub_ep *ep,
 373                                         struct usb_ctrlrequest *crq)
 374{
 375        struct ast_vhub *vhub = ep->vhub;
 376        u16 wValue, wIndex, wLength;
 377
 378        wValue = le16_to_cpu(crq->wValue);
 379        wIndex = le16_to_cpu(crq->wIndex);
 380        wLength = le16_to_cpu(crq->wLength);
 381
 382        /* First packet, grab speed */
 383        if (vhub->speed == USB_SPEED_UNKNOWN) {
 384                u32 ustat = readl(vhub->regs + AST_VHUB_USBSTS);
 385                if (ustat & VHUB_USBSTS_HISPEED)
 386                        vhub->speed = USB_SPEED_HIGH;
 387                else
 388                        vhub->speed = USB_SPEED_FULL;
 389                UDCDBG(vhub, "USB status=%08x speed=%s\n", ustat,
 390                       vhub->speed == USB_SPEED_HIGH ? "high" : "full");
 391        }
 392
 393        switch ((crq->bRequestType << 8) | crq->bRequest) {
 394                /* SET_ADDRESS */
 395        case DeviceOutRequest | USB_REQ_SET_ADDRESS:
 396                EPDBG(ep, "SET_ADDRESS: Got address %x\n", wValue);
 397                writel(wValue, vhub->regs + AST_VHUB_CONF);
 398                return std_req_complete;
 399
 400                /* GET_STATUS */
 401        case DeviceRequest | USB_REQ_GET_STATUS:
 402                return ast_vhub_hub_dev_status(ep, wIndex, wValue);
 403        case InterfaceRequest | USB_REQ_GET_STATUS:
 404                return ast_vhub_simple_reply(ep, 0, 0);
 405        case EndpointRequest | USB_REQ_GET_STATUS:
 406                return ast_vhub_hub_ep_status(ep, wIndex, wValue);
 407
 408                /* SET/CLEAR_FEATURE */
 409        case DeviceOutRequest | USB_REQ_SET_FEATURE:
 410                return ast_vhub_hub_dev_feature(ep, wIndex, wValue, true);
 411        case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
 412                return ast_vhub_hub_dev_feature(ep, wIndex, wValue, false);
 413        case EndpointOutRequest | USB_REQ_SET_FEATURE:
 414                return ast_vhub_hub_ep_feature(ep, wIndex, wValue, true);
 415        case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
 416                return ast_vhub_hub_ep_feature(ep, wIndex, wValue, false);
 417
 418                /* GET/SET_CONFIGURATION */
 419        case DeviceRequest | USB_REQ_GET_CONFIGURATION:
 420                return ast_vhub_simple_reply(ep, 1);
 421        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
 422                if (wValue != 1)
 423                        return std_req_stall;
 424                return std_req_complete;
 425
 426                /* GET_DESCRIPTOR */
 427        case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
 428                switch (wValue >> 8) {
 429                case USB_DT_DEVICE:
 430                case USB_DT_CONFIG:
 431                        return ast_vhub_rep_desc(ep, wValue >> 8,
 432                                                 wLength);
 433                case USB_DT_STRING:
 434                        return ast_vhub_rep_string(ep, wValue & 0xff,
 435                                                   wIndex, wLength);
 436                }
 437                return std_req_stall;
 438
 439                /* GET/SET_INTERFACE */
 440        case DeviceRequest | USB_REQ_GET_INTERFACE:
 441                return ast_vhub_simple_reply(ep, 0);
 442        case DeviceOutRequest | USB_REQ_SET_INTERFACE:
 443                if (wValue != 0 || wIndex != 0)
 444                        return std_req_stall;
 445                return std_req_complete;
 446        }
 447        return std_req_stall;
 448}
 449
 450static void ast_vhub_update_hub_ep1(struct ast_vhub *vhub,
 451                                    unsigned int port)
 452{
 453        /* Update HW EP1 response */
 454        u32 reg = readl(vhub->regs + AST_VHUB_EP1_STS_CHG);
 455        u32 pmask = (1 << (port + 1));
 456        if (vhub->ports[port].change)
 457                reg |= pmask;
 458        else
 459                reg &= ~pmask;
 460        writel(reg, vhub->regs + AST_VHUB_EP1_STS_CHG);
 461}
 462
 463static void ast_vhub_change_port_stat(struct ast_vhub *vhub,
 464                                      unsigned int port,
 465                                      u16 clr_flags,
 466                                      u16 set_flags,
 467                                      bool set_c)
 468{
 469        struct ast_vhub_port *p = &vhub->ports[port];
 470        u16 prev;
 471
 472        /* Update port status */
 473        prev = p->status;
 474        p->status = (prev & ~clr_flags) | set_flags;
 475        DDBG(&p->dev, "port %d status %04x -> %04x (C=%d)\n",
 476             port + 1, prev, p->status, set_c);
 477
 478        /* Update change bits if needed */
 479        if (set_c) {
 480                u16 chg = p->status ^ prev;
 481
 482                /* Only these are relevant for change */
 483                chg &= USB_PORT_STAT_C_CONNECTION |
 484                       USB_PORT_STAT_C_ENABLE |
 485                       USB_PORT_STAT_C_SUSPEND |
 486                       USB_PORT_STAT_C_OVERCURRENT |
 487                       USB_PORT_STAT_C_RESET |
 488                       USB_PORT_STAT_C_L1;
 489
 490                /*
 491                 * We only set USB_PORT_STAT_C_ENABLE if we are disabling
 492                 * the port as per USB spec, otherwise MacOS gets upset
 493                 */
 494                if (p->status & USB_PORT_STAT_ENABLE)
 495                        chg &= ~USB_PORT_STAT_C_ENABLE;
 496
 497                p->change = chg;
 498                ast_vhub_update_hub_ep1(vhub, port);
 499        }
 500}
 501
 502static void ast_vhub_send_host_wakeup(struct ast_vhub *vhub)
 503{
 504        u32 reg = readl(vhub->regs + AST_VHUB_CTRL);
 505        UDCDBG(vhub, "Waking up host !\n");
 506        reg |= VHUB_CTRL_MANUAL_REMOTE_WAKEUP;
 507        writel(reg, vhub->regs + AST_VHUB_CTRL);
 508}
 509
 510void ast_vhub_device_connect(struct ast_vhub *vhub,
 511                             unsigned int port, bool on)
 512{
 513        if (on)
 514                ast_vhub_change_port_stat(vhub, port, 0,
 515                                          USB_PORT_STAT_CONNECTION, true);
 516        else
 517                ast_vhub_change_port_stat(vhub, port,
 518                                          USB_PORT_STAT_CONNECTION |
 519                                          USB_PORT_STAT_ENABLE,
 520                                          0, true);
 521
 522        /*
 523         * If the hub is set to wakup the host on connection events
 524         * then send a wakeup.
 525         */
 526        if (vhub->wakeup_en)
 527                ast_vhub_send_host_wakeup(vhub);
 528}
 529
 530static void ast_vhub_wake_work(struct work_struct *work)
 531{
 532        struct ast_vhub *vhub = container_of(work,
 533                                             struct ast_vhub,
 534                                             wake_work);
 535        unsigned long flags;
 536        unsigned int i;
 537
 538        /*
 539         * Wake all sleeping ports. If a port is suspended by
 540         * the host suspend (without explicit state suspend),
 541         * we let the normal host wake path deal with it later.
 542         */
 543        spin_lock_irqsave(&vhub->lock, flags);
 544        for (i = 0; i < vhub->max_ports; i++) {
 545                struct ast_vhub_port *p = &vhub->ports[i];
 546
 547                if (!(p->status & USB_PORT_STAT_SUSPEND))
 548                        continue;
 549                ast_vhub_change_port_stat(vhub, i,
 550                                          USB_PORT_STAT_SUSPEND,
 551                                          0, true);
 552                ast_vhub_dev_resume(&p->dev);
 553        }
 554        ast_vhub_send_host_wakeup(vhub);
 555        spin_unlock_irqrestore(&vhub->lock, flags);
 556}
 557
 558void ast_vhub_hub_wake_all(struct ast_vhub *vhub)
 559{
 560        /*
 561         * A device is trying to wake the world, because this
 562         * can recurse into the device, we break the call chain
 563         * using a work queue
 564         */
 565        schedule_work(&vhub->wake_work);
 566}
 567
 568static void ast_vhub_port_reset(struct ast_vhub *vhub, u8 port)
 569{
 570        struct ast_vhub_port *p = &vhub->ports[port];
 571        u16 set, clr, speed;
 572
 573        /* First mark disabled */
 574        ast_vhub_change_port_stat(vhub, port,
 575                                  USB_PORT_STAT_ENABLE |
 576                                  USB_PORT_STAT_SUSPEND,
 577                                  USB_PORT_STAT_RESET,
 578                                  false);
 579
 580        if (!p->dev.driver)
 581                return;
 582
 583        /*
 584         * This will either "start" the port or reset the
 585         * device if already started...
 586         */
 587        ast_vhub_dev_reset(&p->dev);
 588
 589        /* Grab the right speed */
 590        speed = p->dev.driver->max_speed;
 591        if (speed == USB_SPEED_UNKNOWN || speed > vhub->speed)
 592                speed = vhub->speed;
 593
 594        switch (speed) {
 595        case USB_SPEED_LOW:
 596                set = USB_PORT_STAT_LOW_SPEED;
 597                clr = USB_PORT_STAT_HIGH_SPEED;
 598                break;
 599        case USB_SPEED_FULL:
 600                set = 0;
 601                clr = USB_PORT_STAT_LOW_SPEED |
 602                        USB_PORT_STAT_HIGH_SPEED;
 603                break;
 604        case USB_SPEED_HIGH:
 605                set = USB_PORT_STAT_HIGH_SPEED;
 606                clr = USB_PORT_STAT_LOW_SPEED;
 607                break;
 608        default:
 609                UDCDBG(vhub, "Unsupported speed %d when"
 610                       " connecting device\n",
 611                       speed);
 612                return;
 613        }
 614        clr |= USB_PORT_STAT_RESET;
 615        set |= USB_PORT_STAT_ENABLE;
 616
 617        /* This should ideally be delayed ... */
 618        ast_vhub_change_port_stat(vhub, port, clr, set, true);
 619}
 620
 621static enum std_req_rc ast_vhub_set_port_feature(struct ast_vhub_ep *ep,
 622                                                 u8 port, u16 feat)
 623{
 624        struct ast_vhub *vhub = ep->vhub;
 625        struct ast_vhub_port *p;
 626
 627        if (port == 0 || port > vhub->max_ports)
 628                return std_req_stall;
 629        port--;
 630        p = &vhub->ports[port];
 631
 632        switch(feat) {
 633        case USB_PORT_FEAT_SUSPEND:
 634                if (!(p->status & USB_PORT_STAT_ENABLE))
 635                        return std_req_complete;
 636                ast_vhub_change_port_stat(vhub, port,
 637                                          0, USB_PORT_STAT_SUSPEND,
 638                                          false);
 639                ast_vhub_dev_suspend(&p->dev);
 640                return std_req_complete;
 641        case USB_PORT_FEAT_RESET:
 642                EPDBG(ep, "Port reset !\n");
 643                ast_vhub_port_reset(vhub, port);
 644                return std_req_complete;
 645        case USB_PORT_FEAT_POWER:
 646                /*
 647                 * On Power-on, we mark the connected flag changed,
 648                 * if there's a connected device, some hosts will
 649                 * otherwise fail to detect it.
 650                 */
 651                if (p->status & USB_PORT_STAT_CONNECTION) {
 652                        p->change |= USB_PORT_STAT_C_CONNECTION;
 653                        ast_vhub_update_hub_ep1(vhub, port);
 654                }
 655                return std_req_complete;
 656        case USB_PORT_FEAT_TEST:
 657        case USB_PORT_FEAT_INDICATOR:
 658                /* We don't do anything with these */
 659                return std_req_complete;
 660        }
 661        return std_req_stall;
 662}
 663
 664static enum std_req_rc ast_vhub_clr_port_feature(struct ast_vhub_ep *ep,
 665                                                 u8 port, u16 feat)
 666{
 667        struct ast_vhub *vhub = ep->vhub;
 668        struct ast_vhub_port *p;
 669
 670        if (port == 0 || port > vhub->max_ports)
 671                return std_req_stall;
 672        port--;
 673        p = &vhub->ports[port];
 674
 675        switch(feat) {
 676        case USB_PORT_FEAT_ENABLE:
 677                ast_vhub_change_port_stat(vhub, port,
 678                                          USB_PORT_STAT_ENABLE |
 679                                          USB_PORT_STAT_SUSPEND, 0,
 680                                          false);
 681                ast_vhub_dev_suspend(&p->dev);
 682                return std_req_complete;
 683        case USB_PORT_FEAT_SUSPEND:
 684                if (!(p->status & USB_PORT_STAT_SUSPEND))
 685                        return std_req_complete;
 686                ast_vhub_change_port_stat(vhub, port,
 687                                          USB_PORT_STAT_SUSPEND, 0,
 688                                          false);
 689                ast_vhub_dev_resume(&p->dev);
 690                return std_req_complete;
 691        case USB_PORT_FEAT_POWER:
 692                /* We don't do power control */
 693                return std_req_complete;
 694        case USB_PORT_FEAT_INDICATOR:
 695                /* We don't have indicators */
 696                return std_req_complete;
 697        case USB_PORT_FEAT_C_CONNECTION:
 698        case USB_PORT_FEAT_C_ENABLE:
 699        case USB_PORT_FEAT_C_SUSPEND:
 700        case USB_PORT_FEAT_C_OVER_CURRENT:
 701        case USB_PORT_FEAT_C_RESET:
 702                /* Clear state-change feature */
 703                p->change &= ~(1u << (feat - 16));
 704                ast_vhub_update_hub_ep1(vhub, port);
 705                return std_req_complete;
 706        }
 707        return std_req_stall;
 708}
 709
 710static enum std_req_rc ast_vhub_get_port_stat(struct ast_vhub_ep *ep,
 711                                              u8 port)
 712{
 713        struct ast_vhub *vhub = ep->vhub;
 714        u16 stat, chg;
 715
 716        if (port == 0 || port > vhub->max_ports)
 717                return std_req_stall;
 718        port--;
 719
 720        stat = vhub->ports[port].status;
 721        chg = vhub->ports[port].change;
 722
 723        /* We always have power */
 724        stat |= USB_PORT_STAT_POWER;
 725
 726        EPDBG(ep, " port status=%04x change=%04x\n", stat, chg);
 727
 728        return ast_vhub_simple_reply(ep,
 729                                     stat & 0xff,
 730                                     stat >> 8,
 731                                     chg & 0xff,
 732                                     chg >> 8);
 733}
 734
 735enum std_req_rc ast_vhub_class_hub_request(struct ast_vhub_ep *ep,
 736                                           struct usb_ctrlrequest *crq)
 737{
 738        u16 wValue, wIndex, wLength;
 739
 740        wValue = le16_to_cpu(crq->wValue);
 741        wIndex = le16_to_cpu(crq->wIndex);
 742        wLength = le16_to_cpu(crq->wLength);
 743
 744        switch ((crq->bRequestType << 8) | crq->bRequest) {
 745        case GetHubStatus:
 746                EPDBG(ep, "GetHubStatus\n");
 747                return ast_vhub_simple_reply(ep, 0, 0, 0, 0);
 748        case GetPortStatus:
 749                EPDBG(ep, "GetPortStatus(%d)\n", wIndex & 0xff);
 750                return ast_vhub_get_port_stat(ep, wIndex & 0xf);
 751        case GetHubDescriptor:
 752                if (wValue != (USB_DT_HUB << 8))
 753                        return std_req_stall;
 754                EPDBG(ep, "GetHubDescriptor(%d)\n", wIndex & 0xff);
 755                return ast_vhub_rep_desc(ep, USB_DT_HUB, wLength);
 756        case SetHubFeature:
 757        case ClearHubFeature:
 758                EPDBG(ep, "Get/SetHubFeature(%d)\n", wValue);
 759                /* No feature, just complete the requests */
 760                if (wValue == C_HUB_LOCAL_POWER ||
 761                    wValue == C_HUB_OVER_CURRENT)
 762                        return std_req_complete;
 763                return std_req_stall;
 764        case SetPortFeature:
 765                EPDBG(ep, "SetPortFeature(%d,%d)\n", wIndex & 0xf, wValue);
 766                return ast_vhub_set_port_feature(ep, wIndex & 0xf, wValue);
 767        case ClearPortFeature:
 768                EPDBG(ep, "ClearPortFeature(%d,%d)\n", wIndex & 0xf, wValue);
 769                return ast_vhub_clr_port_feature(ep, wIndex & 0xf, wValue);
 770        case ClearTTBuffer:
 771        case ResetTT:
 772        case StopTT:
 773                return std_req_complete;
 774        case GetTTState:
 775                return ast_vhub_simple_reply(ep, 0, 0, 0, 0);
 776        default:
 777                EPDBG(ep, "Unknown class request\n");
 778        }
 779        return std_req_stall;
 780}
 781
 782void ast_vhub_hub_suspend(struct ast_vhub *vhub)
 783{
 784        unsigned int i;
 785
 786        UDCDBG(vhub, "USB bus suspend\n");
 787
 788        if (vhub->suspended)
 789                return;
 790
 791        vhub->suspended = true;
 792
 793        /*
 794         * Forward to unsuspended ports without changing
 795         * their connection status.
 796         */
 797        for (i = 0; i < vhub->max_ports; i++) {
 798                struct ast_vhub_port *p = &vhub->ports[i];
 799
 800                if (!(p->status & USB_PORT_STAT_SUSPEND))
 801                        ast_vhub_dev_suspend(&p->dev);
 802        }
 803}
 804
 805void ast_vhub_hub_resume(struct ast_vhub *vhub)
 806{
 807        unsigned int i;
 808
 809        UDCDBG(vhub, "USB bus resume\n");
 810
 811        if (!vhub->suspended)
 812                return;
 813
 814        vhub->suspended = false;
 815
 816        /*
 817         * Forward to unsuspended ports without changing
 818         * their connection status.
 819         */
 820        for (i = 0; i < vhub->max_ports; i++) {
 821                struct ast_vhub_port *p = &vhub->ports[i];
 822
 823                if (!(p->status & USB_PORT_STAT_SUSPEND))
 824                        ast_vhub_dev_resume(&p->dev);
 825        }
 826}
 827
 828void ast_vhub_hub_reset(struct ast_vhub *vhub)
 829{
 830        unsigned int i;
 831
 832        UDCDBG(vhub, "USB bus reset\n");
 833
 834        /*
 835         * Is the speed known ? If not we don't care, we aren't
 836         * initialized yet and ports haven't been enabled.
 837         */
 838        if (vhub->speed == USB_SPEED_UNKNOWN)
 839                return;
 840
 841        /* We aren't suspended anymore obviously */
 842        vhub->suspended = false;
 843
 844        /* No speed set */
 845        vhub->speed = USB_SPEED_UNKNOWN;
 846
 847        /* Wakeup not enabled anymore */
 848        vhub->wakeup_en = false;
 849
 850        /*
 851         * Clear all port status, disable gadgets and "suspend"
 852         * them. They will be woken up by a port reset.
 853         */
 854        for (i = 0; i < vhub->max_ports; i++) {
 855                struct ast_vhub_port *p = &vhub->ports[i];
 856
 857                /* Only keep the connected flag */
 858                p->status &= USB_PORT_STAT_CONNECTION;
 859                p->change = 0;
 860
 861                /* Suspend the gadget if any */
 862                ast_vhub_dev_suspend(&p->dev);
 863        }
 864
 865        /* Cleanup HW */
 866        writel(0, vhub->regs + AST_VHUB_CONF);
 867        writel(0, vhub->regs + AST_VHUB_EP0_CTRL);
 868        writel(VHUB_EP1_CTRL_RESET_TOGGLE |
 869               VHUB_EP1_CTRL_ENABLE,
 870               vhub->regs + AST_VHUB_EP1_CTRL);
 871        writel(0, vhub->regs + AST_VHUB_EP1_STS_CHG);
 872}
 873
 874static void ast_vhub_of_parse_dev_desc(struct ast_vhub *vhub,
 875                                       const struct device_node *vhub_np)
 876{
 877        u16 id;
 878        u32 data;
 879
 880        if (!of_property_read_u32(vhub_np, "vhub-vendor-id", &data)) {
 881                id = (u16)data;
 882                vhub->vhub_dev_desc.idVendor = cpu_to_le16(id);
 883        }
 884        if (!of_property_read_u32(vhub_np, "vhub-product-id", &data)) {
 885                id = (u16)data;
 886                vhub->vhub_dev_desc.idProduct = cpu_to_le16(id);
 887        }
 888        if (!of_property_read_u32(vhub_np, "vhub-device-revision", &data)) {
 889                id = (u16)data;
 890                vhub->vhub_dev_desc.bcdDevice = cpu_to_le16(id);
 891        }
 892}
 893
 894static void ast_vhub_fixup_usb1_dev_desc(struct ast_vhub *vhub)
 895{
 896        vhub->vhub_dev_desc.bcdUSB = cpu_to_le16(0x0100);
 897        vhub->vhub_dev_desc.bDeviceProtocol = 0;
 898}
 899
 900static struct usb_gadget_string_container*
 901ast_vhub_str_container_alloc(struct ast_vhub *vhub)
 902{
 903        unsigned int size;
 904        struct usb_string *str_array;
 905        struct usb_gadget_strings *lang_str;
 906        struct usb_gadget_string_container *container;
 907
 908        size = sizeof(*container);
 909        size += sizeof(struct usb_gadget_strings);
 910        size += sizeof(struct usb_string) * AST_VHUB_STR_INDEX_MAX;
 911        container = devm_kzalloc(&vhub->pdev->dev, size, GFP_KERNEL);
 912        if (!container)
 913                return ERR_PTR(-ENOMEM);
 914
 915        lang_str = ast_vhub_str_of_container(container);
 916        str_array = (struct usb_string *)(lang_str + 1);
 917        lang_str->strings = str_array;
 918        return container;
 919}
 920
 921static void ast_vhub_str_deep_copy(struct usb_gadget_strings *dest,
 922                                   const struct usb_gadget_strings *src)
 923{
 924        struct usb_string *src_array = src->strings;
 925        struct usb_string *dest_array = dest->strings;
 926
 927        dest->language = src->language;
 928        if (src_array && dest_array) {
 929                do {
 930                        *dest_array = *src_array;
 931                        dest_array++;
 932                        src_array++;
 933                } while (src_array->s);
 934        }
 935}
 936
 937static int ast_vhub_str_alloc_add(struct ast_vhub *vhub,
 938                                  const struct usb_gadget_strings *src_str)
 939{
 940        struct usb_gadget_strings *dest_str;
 941        struct usb_gadget_string_container *container;
 942
 943        container = ast_vhub_str_container_alloc(vhub);
 944        if (IS_ERR(container))
 945                return PTR_ERR(container);
 946
 947        dest_str = ast_vhub_str_of_container(container);
 948        ast_vhub_str_deep_copy(dest_str, src_str);
 949        list_add_tail(&container->list, &vhub->vhub_str_desc);
 950
 951        return 0;
 952}
 953
 954static const struct {
 955        const char *name;
 956        u8 id;
 957} str_id_map[] = {
 958        {"manufacturer",        AST_VHUB_STR_MANUF},
 959        {"product",             AST_VHUB_STR_PRODUCT},
 960        {"serial-number",       AST_VHUB_STR_SERIAL},
 961        {},
 962};
 963
 964static int ast_vhub_of_parse_str_desc(struct ast_vhub *vhub,
 965                                      const struct device_node *desc_np)
 966{
 967        u32 langid;
 968        int ret = 0;
 969        int i, offset;
 970        const char *str;
 971        struct device_node *child;
 972        struct usb_string str_array[AST_VHUB_STR_INDEX_MAX];
 973        struct usb_gadget_strings lang_str = {
 974                .strings = (struct usb_string *)str_array,
 975        };
 976
 977        for_each_child_of_node(desc_np, child) {
 978                if (of_property_read_u32(child, "reg", &langid))
 979                        continue; /* no language identifier specified */
 980
 981                if (!usb_validate_langid(langid))
 982                        continue; /* invalid language identifier */
 983
 984                lang_str.language = langid;
 985                for (i = offset = 0; str_id_map[i].name; i++) {
 986                        str = of_get_property(child, str_id_map[i].name, NULL);
 987                        if (str) {
 988                                str_array[offset].s = str;
 989                                str_array[offset].id = str_id_map[i].id;
 990                                offset++;
 991                        }
 992                }
 993                str_array[offset].id = 0;
 994                str_array[offset].s = NULL;
 995
 996                ret = ast_vhub_str_alloc_add(vhub, &lang_str);
 997                if (ret) {
 998                        of_node_put(child);
 999                        break;
1000                }
1001        }
1002
1003        return ret;
1004}
1005
1006static int ast_vhub_init_desc(struct ast_vhub *vhub)
1007{
1008        int ret;
1009        struct device_node *desc_np;
1010        const struct device_node *vhub_np = vhub->pdev->dev.of_node;
1011
1012        /* Initialize vhub Device Descriptor. */
1013        memcpy(&vhub->vhub_dev_desc, &ast_vhub_dev_desc,
1014                sizeof(vhub->vhub_dev_desc));
1015        ast_vhub_of_parse_dev_desc(vhub, vhub_np);
1016        if (vhub->force_usb1)
1017                ast_vhub_fixup_usb1_dev_desc(vhub);
1018
1019        /* Initialize vhub Configuration Descriptor. */
1020        memcpy(&vhub->vhub_conf_desc, &ast_vhub_conf_desc,
1021                sizeof(vhub->vhub_conf_desc));
1022
1023        /* Initialize vhub Hub Descriptor. */
1024        memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
1025                sizeof(vhub->vhub_hub_desc));
1026        vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports;
1027
1028        /* Initialize vhub String Descriptors. */
1029        INIT_LIST_HEAD(&vhub->vhub_str_desc);
1030        desc_np = of_get_child_by_name(vhub_np, "vhub-strings");
1031        if (desc_np)
1032                ret = ast_vhub_of_parse_str_desc(vhub, desc_np);
1033        else
1034                ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings);
1035
1036        return ret;
1037}
1038
1039int ast_vhub_init_hub(struct ast_vhub *vhub)
1040{
1041        vhub->speed = USB_SPEED_UNKNOWN;
1042        INIT_WORK(&vhub->wake_work, ast_vhub_wake_work);
1043
1044        return ast_vhub_init_desc(vhub);
1045}
1046