cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

core.c (23801B)


      1/*
      2 * QEMU USB emulation
      3 *
      4 * Copyright (c) 2005 Fabrice Bellard
      5 *
      6 * 2008 Generic packet handler rewrite by Max Krasnyansky
      7 *
      8 * Permission is hereby granted, free of charge, to any person obtaining a copy
      9 * of this software and associated documentation files (the "Software"), to deal
     10 * in the Software without restriction, including without limitation the rights
     11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     12 * copies of the Software, and to permit persons to whom the Software is
     13 * furnished to do so, subject to the following conditions:
     14 *
     15 * The above copyright notice and this permission notice shall be included in
     16 * all copies or substantial portions of the Software.
     17 *
     18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     24 * THE SOFTWARE.
     25 */
     26#include "qemu/osdep.h"
     27#include "hw/usb.h"
     28#include "qemu/iov.h"
     29#include "trace.h"
     30
     31void usb_pick_speed(USBPort *port)
     32{
     33    static const int speeds[] = {
     34        USB_SPEED_SUPER,
     35        USB_SPEED_HIGH,
     36        USB_SPEED_FULL,
     37        USB_SPEED_LOW,
     38    };
     39    USBDevice *udev = port->dev;
     40    int i;
     41
     42    for (i = 0; i < ARRAY_SIZE(speeds); i++) {
     43        if ((udev->speedmask & (1 << speeds[i])) &&
     44            (port->speedmask & (1 << speeds[i]))) {
     45            udev->speed = speeds[i];
     46            return;
     47        }
     48    }
     49}
     50
     51void usb_attach(USBPort *port)
     52{
     53    USBDevice *dev = port->dev;
     54
     55    assert(dev != NULL);
     56    assert(dev->attached);
     57    assert(dev->state == USB_STATE_NOTATTACHED);
     58    usb_pick_speed(port);
     59    port->ops->attach(port);
     60    dev->state = USB_STATE_ATTACHED;
     61    usb_device_handle_attach(dev);
     62}
     63
     64void usb_detach(USBPort *port)
     65{
     66    USBDevice *dev = port->dev;
     67
     68    assert(dev != NULL);
     69    assert(dev->state != USB_STATE_NOTATTACHED);
     70    port->ops->detach(port);
     71    dev->state = USB_STATE_NOTATTACHED;
     72}
     73
     74void usb_port_reset(USBPort *port)
     75{
     76    USBDevice *dev = port->dev;
     77
     78    assert(dev != NULL);
     79    usb_detach(port);
     80    usb_attach(port);
     81    usb_device_reset(dev);
     82}
     83
     84void usb_device_reset(USBDevice *dev)
     85{
     86    if (dev == NULL || !dev->attached) {
     87        return;
     88    }
     89    usb_device_handle_reset(dev);
     90    dev->remote_wakeup = 0;
     91    dev->addr = 0;
     92    dev->state = USB_STATE_DEFAULT;
     93}
     94
     95void usb_wakeup(USBEndpoint *ep, unsigned int stream)
     96{
     97    USBDevice *dev = ep->dev;
     98    USBBus *bus = usb_bus_from_device(dev);
     99
    100    if (!phase_check(PHASE_MACHINE_READY)) {
    101        /*
    102         * This is machine init cold plug.  No need to wakeup anyone,
    103         * all devices will be reset anyway.  And trying to wakeup can
    104         * cause problems due to hitting uninitialized devices.
    105         */
    106        return;
    107    }
    108    if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
    109        dev->port->ops->wakeup(dev->port);
    110    }
    111    if (bus->ops->wakeup_endpoint) {
    112        bus->ops->wakeup_endpoint(bus, ep, stream);
    113    }
    114}
    115
    116/**********************/
    117
    118/* generic USB device helpers (you are not forced to use them when
    119   writing your USB device driver, but they help handling the
    120   protocol)
    121*/
    122
    123#define SETUP_STATE_IDLE  0
    124#define SETUP_STATE_SETUP 1
    125#define SETUP_STATE_DATA  2
    126#define SETUP_STATE_ACK   3
    127#define SETUP_STATE_PARAM 4
    128
    129static void do_token_setup(USBDevice *s, USBPacket *p)
    130{
    131    int request, value, index;
    132    unsigned int setup_len;
    133
    134    if (p->iov.size != 8) {
    135        p->status = USB_RET_STALL;
    136        return;
    137    }
    138
    139    usb_packet_copy(p, s->setup_buf, p->iov.size);
    140    s->setup_index = 0;
    141    p->actual_length = 0;
    142    setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
    143    if (setup_len > sizeof(s->data_buf)) {
    144        fprintf(stderr,
    145                "usb_generic_handle_packet: ctrl buffer too small (%u > %zu)\n",
    146                setup_len, sizeof(s->data_buf));
    147        p->status = USB_RET_STALL;
    148        return;
    149    }
    150    s->setup_len = setup_len;
    151
    152    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
    153    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
    154    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
    155
    156    if (s->setup_buf[0] & USB_DIR_IN) {
    157        usb_pcap_ctrl(p, true);
    158        usb_device_handle_control(s, p, request, value, index,
    159                                  s->setup_len, s->data_buf);
    160        if (p->status == USB_RET_ASYNC) {
    161            s->setup_state = SETUP_STATE_SETUP;
    162        }
    163        if (p->status != USB_RET_SUCCESS) {
    164            return;
    165        }
    166
    167        if (p->actual_length < s->setup_len) {
    168            s->setup_len = p->actual_length;
    169        }
    170        s->setup_state = SETUP_STATE_DATA;
    171    } else {
    172        if (s->setup_len == 0)
    173            s->setup_state = SETUP_STATE_ACK;
    174        else
    175            s->setup_state = SETUP_STATE_DATA;
    176    }
    177
    178    p->actual_length = 8;
    179}
    180
    181static void do_token_in(USBDevice *s, USBPacket *p)
    182{
    183    int request, value, index;
    184
    185    assert(p->ep->nr == 0);
    186
    187    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
    188    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
    189    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
    190
    191    switch(s->setup_state) {
    192    case SETUP_STATE_ACK:
    193        if (!(s->setup_buf[0] & USB_DIR_IN)) {
    194            usb_pcap_ctrl(p, true);
    195            usb_device_handle_control(s, p, request, value, index,
    196                                      s->setup_len, s->data_buf);
    197            if (p->status == USB_RET_ASYNC) {
    198                return;
    199            }
    200            s->setup_state = SETUP_STATE_IDLE;
    201            p->actual_length = 0;
    202            usb_pcap_ctrl(p, false);
    203        }
    204        break;
    205
    206    case SETUP_STATE_DATA:
    207        if (s->setup_buf[0] & USB_DIR_IN) {
    208            int len = s->setup_len - s->setup_index;
    209            if (len > p->iov.size) {
    210                len = p->iov.size;
    211            }
    212            usb_packet_copy(p, s->data_buf + s->setup_index, len);
    213            s->setup_index += len;
    214            if (s->setup_index >= s->setup_len) {
    215                s->setup_state = SETUP_STATE_ACK;
    216            }
    217            return;
    218        }
    219        s->setup_state = SETUP_STATE_IDLE;
    220        p->status = USB_RET_STALL;
    221        usb_pcap_ctrl(p, false);
    222        break;
    223
    224    default:
    225        p->status = USB_RET_STALL;
    226    }
    227}
    228
    229static void do_token_out(USBDevice *s, USBPacket *p)
    230{
    231    assert(p->ep->nr == 0);
    232
    233    switch(s->setup_state) {
    234    case SETUP_STATE_ACK:
    235        if (s->setup_buf[0] & USB_DIR_IN) {
    236            s->setup_state = SETUP_STATE_IDLE;
    237            usb_pcap_ctrl(p, false);
    238            /* transfer OK */
    239        } else {
    240            /* ignore additional output */
    241        }
    242        break;
    243
    244    case SETUP_STATE_DATA:
    245        if (!(s->setup_buf[0] & USB_DIR_IN)) {
    246            int len = s->setup_len - s->setup_index;
    247            if (len > p->iov.size) {
    248                len = p->iov.size;
    249            }
    250            usb_packet_copy(p, s->data_buf + s->setup_index, len);
    251            s->setup_index += len;
    252            if (s->setup_index >= s->setup_len) {
    253                s->setup_state = SETUP_STATE_ACK;
    254            }
    255            return;
    256        }
    257        s->setup_state = SETUP_STATE_IDLE;
    258        p->status = USB_RET_STALL;
    259        usb_pcap_ctrl(p, false);
    260        break;
    261
    262    default:
    263        p->status = USB_RET_STALL;
    264    }
    265}
    266
    267static void do_parameter(USBDevice *s, USBPacket *p)
    268{
    269    int i, request, value, index;
    270    unsigned int setup_len;
    271
    272    for (i = 0; i < 8; i++) {
    273        s->setup_buf[i] = p->parameter >> (i*8);
    274    }
    275
    276    s->setup_state = SETUP_STATE_PARAM;
    277    s->setup_index = 0;
    278
    279    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
    280    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
    281    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
    282
    283    setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
    284    if (setup_len > sizeof(s->data_buf)) {
    285        fprintf(stderr,
    286                "usb_generic_handle_packet: ctrl buffer too small (%u > %zu)\n",
    287                setup_len, sizeof(s->data_buf));
    288        p->status = USB_RET_STALL;
    289        return;
    290    }
    291    s->setup_len = setup_len;
    292
    293    if (p->pid == USB_TOKEN_OUT) {
    294        usb_packet_copy(p, s->data_buf, s->setup_len);
    295    }
    296
    297    usb_pcap_ctrl(p, true);
    298    usb_device_handle_control(s, p, request, value, index,
    299                              s->setup_len, s->data_buf);
    300    if (p->status == USB_RET_ASYNC) {
    301        return;
    302    }
    303
    304    if (p->actual_length < s->setup_len) {
    305        s->setup_len = p->actual_length;
    306    }
    307    if (p->pid == USB_TOKEN_IN) {
    308        p->actual_length = 0;
    309        usb_packet_copy(p, s->data_buf, s->setup_len);
    310    }
    311    usb_pcap_ctrl(p, false);
    312}
    313
    314/* ctrl complete function for devices which use usb_generic_handle_packet and
    315   may return USB_RET_ASYNC from their handle_control callback. Device code
    316   which does this *must* call this function instead of the normal
    317   usb_packet_complete to complete their async control packets. */
    318void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
    319{
    320    if (p->status < 0) {
    321        s->setup_state = SETUP_STATE_IDLE;
    322        usb_pcap_ctrl(p, false);
    323    }
    324
    325    switch (s->setup_state) {
    326    case SETUP_STATE_SETUP:
    327        if (p->actual_length < s->setup_len) {
    328            s->setup_len = p->actual_length;
    329        }
    330        s->setup_state = SETUP_STATE_DATA;
    331        p->actual_length = 8;
    332        break;
    333
    334    case SETUP_STATE_ACK:
    335        s->setup_state = SETUP_STATE_IDLE;
    336        p->actual_length = 0;
    337        usb_pcap_ctrl(p, false);
    338        break;
    339
    340    case SETUP_STATE_PARAM:
    341        if (p->actual_length < s->setup_len) {
    342            s->setup_len = p->actual_length;
    343        }
    344        if (p->pid == USB_TOKEN_IN) {
    345            p->actual_length = 0;
    346            usb_packet_copy(p, s->data_buf, s->setup_len);
    347        }
    348        break;
    349
    350    default:
    351        break;
    352    }
    353    usb_packet_complete(s, p);
    354}
    355
    356USBDevice *usb_find_device(USBPort *port, uint8_t addr)
    357{
    358    USBDevice *dev = port->dev;
    359
    360    if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT) {
    361        return NULL;
    362    }
    363    if (dev->addr == addr) {
    364        return dev;
    365    }
    366    return usb_device_find_device(dev, addr);
    367}
    368
    369static void usb_process_one(USBPacket *p)
    370{
    371    USBDevice *dev = p->ep->dev;
    372    bool nak;
    373
    374    /*
    375     * Handlers expect status to be initialized to USB_RET_SUCCESS, but it
    376     * can be USB_RET_NAK here from a previous usb_process_one() call,
    377     * or USB_RET_ASYNC from going through usb_queue_one().
    378     */
    379    nak = (p->status == USB_RET_NAK);
    380    p->status = USB_RET_SUCCESS;
    381
    382    if (p->ep->nr == 0) {
    383        /* control pipe */
    384        if (p->parameter) {
    385            do_parameter(dev, p);
    386            return;
    387        }
    388        switch (p->pid) {
    389        case USB_TOKEN_SETUP:
    390            do_token_setup(dev, p);
    391            break;
    392        case USB_TOKEN_IN:
    393            do_token_in(dev, p);
    394            break;
    395        case USB_TOKEN_OUT:
    396            do_token_out(dev, p);
    397            break;
    398        default:
    399            p->status = USB_RET_STALL;
    400        }
    401    } else {
    402        /* data pipe */
    403        if (!nak) {
    404            usb_pcap_data(p, true);
    405        }
    406        usb_device_handle_data(dev, p);
    407    }
    408}
    409
    410static void usb_queue_one(USBPacket *p)
    411{
    412    usb_packet_set_state(p, USB_PACKET_QUEUED);
    413    QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
    414    p->status = USB_RET_ASYNC;
    415}
    416
    417/* Hand over a packet to a device for processing.  p->status ==
    418   USB_RET_ASYNC indicates the processing isn't finished yet, the
    419   driver will call usb_packet_complete() when done processing it. */
    420void usb_handle_packet(USBDevice *dev, USBPacket *p)
    421{
    422    if (dev == NULL) {
    423        p->status = USB_RET_NODEV;
    424        return;
    425    }
    426    assert(dev == p->ep->dev);
    427    assert(dev->state == USB_STATE_DEFAULT);
    428    usb_packet_check_state(p, USB_PACKET_SETUP);
    429    assert(p->ep != NULL);
    430
    431    /* Submitting a new packet clears halt */
    432    if (p->ep->halted) {
    433        assert(QTAILQ_EMPTY(&p->ep->queue));
    434        p->ep->halted = false;
    435    }
    436
    437    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
    438        usb_process_one(p);
    439        if (p->status == USB_RET_ASYNC) {
    440            /* hcd drivers cannot handle async for isoc */
    441            assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
    442            /* using async for interrupt packets breaks migration */
    443            assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
    444                   (dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
    445            usb_packet_set_state(p, USB_PACKET_ASYNC);
    446            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
    447        } else if (p->status == USB_RET_ADD_TO_QUEUE) {
    448            usb_queue_one(p);
    449        } else {
    450            /*
    451             * When pipelining is enabled usb-devices must always return async,
    452             * otherwise packets can complete out of order!
    453             */
    454            assert(p->stream || !p->ep->pipeline ||
    455                   QTAILQ_EMPTY(&p->ep->queue));
    456            if (p->status != USB_RET_NAK) {
    457                usb_pcap_data(p, false);
    458                usb_packet_set_state(p, USB_PACKET_COMPLETE);
    459            }
    460        }
    461    } else {
    462        usb_queue_one(p);
    463    }
    464}
    465
    466void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
    467{
    468    USBEndpoint *ep = p->ep;
    469
    470    assert(p->stream || QTAILQ_FIRST(&ep->queue) == p);
    471    assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK);
    472
    473    if (p->status != USB_RET_SUCCESS ||
    474            (p->short_not_ok && (p->actual_length < p->iov.size))) {
    475        ep->halted = true;
    476    }
    477    usb_pcap_data(p, false);
    478    usb_packet_set_state(p, USB_PACKET_COMPLETE);
    479    QTAILQ_REMOVE(&ep->queue, p, queue);
    480    dev->port->ops->complete(dev->port, p);
    481}
    482
    483/* Notify the controller that an async packet is complete.  This should only
    484   be called for packets previously deferred by returning USB_RET_ASYNC from
    485   handle_packet. */
    486void usb_packet_complete(USBDevice *dev, USBPacket *p)
    487{
    488    USBEndpoint *ep = p->ep;
    489
    490    usb_packet_check_state(p, USB_PACKET_ASYNC);
    491    usb_packet_complete_one(dev, p);
    492
    493    while (!QTAILQ_EMPTY(&ep->queue)) {
    494        p = QTAILQ_FIRST(&ep->queue);
    495        if (ep->halted) {
    496            /* Empty the queue on a halt */
    497            p->status = USB_RET_REMOVE_FROM_QUEUE;
    498            dev->port->ops->complete(dev->port, p);
    499            continue;
    500        }
    501        if (p->state == USB_PACKET_ASYNC) {
    502            break;
    503        }
    504        usb_packet_check_state(p, USB_PACKET_QUEUED);
    505        usb_process_one(p);
    506        if (p->status == USB_RET_ASYNC) {
    507            usb_packet_set_state(p, USB_PACKET_ASYNC);
    508            break;
    509        }
    510        usb_packet_complete_one(ep->dev, p);
    511    }
    512}
    513
    514/* Cancel an active packet.  The packed must have been deferred by
    515   returning USB_RET_ASYNC from handle_packet, and not yet
    516   completed.  */
    517void usb_cancel_packet(USBPacket * p)
    518{
    519    bool callback = (p->state == USB_PACKET_ASYNC);
    520    assert(usb_packet_is_inflight(p));
    521    usb_packet_set_state(p, USB_PACKET_CANCELED);
    522    QTAILQ_REMOVE(&p->ep->queue, p, queue);
    523    if (callback) {
    524        usb_device_cancel_packet(p->ep->dev, p);
    525    }
    526}
    527
    528
    529void usb_packet_init(USBPacket *p)
    530{
    531    qemu_iovec_init(&p->iov, 1);
    532}
    533
    534static const char *usb_packet_state_name(USBPacketState state)
    535{
    536    static const char *name[] = {
    537        [USB_PACKET_UNDEFINED] = "undef",
    538        [USB_PACKET_SETUP]     = "setup",
    539        [USB_PACKET_QUEUED]    = "queued",
    540        [USB_PACKET_ASYNC]     = "async",
    541        [USB_PACKET_COMPLETE]  = "complete",
    542        [USB_PACKET_CANCELED]  = "canceled",
    543    };
    544    if (state < ARRAY_SIZE(name)) {
    545        return name[state];
    546    }
    547    return "INVALID";
    548}
    549
    550void usb_packet_check_state(USBPacket *p, USBPacketState expected)
    551{
    552    USBDevice *dev;
    553    USBBus *bus;
    554
    555    if (p->state == expected) {
    556        return;
    557    }
    558    dev = p->ep->dev;
    559    bus = usb_bus_from_device(dev);
    560    trace_usb_packet_state_fault(bus->busnr, dev->port->path, p->ep->nr, p,
    561                                 usb_packet_state_name(p->state),
    562                                 usb_packet_state_name(expected));
    563    assert(!"usb packet state check failed");
    564}
    565
    566void usb_packet_set_state(USBPacket *p, USBPacketState state)
    567{
    568    if (p->ep) {
    569        USBDevice *dev = p->ep->dev;
    570        USBBus *bus = usb_bus_from_device(dev);
    571        trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr, p,
    572                                      usb_packet_state_name(p->state),
    573                                      usb_packet_state_name(state));
    574    } else {
    575        trace_usb_packet_state_change(-1, "", -1, p,
    576                                      usb_packet_state_name(p->state),
    577                                      usb_packet_state_name(state));
    578    }
    579    p->state = state;
    580}
    581
    582void usb_packet_setup(USBPacket *p, int pid,
    583                      USBEndpoint *ep, unsigned int stream,
    584                      uint64_t id, bool short_not_ok, bool int_req)
    585{
    586    assert(!usb_packet_is_inflight(p));
    587    assert(p->iov.iov != NULL);
    588    p->id = id;
    589    p->pid = pid;
    590    p->ep = ep;
    591    p->stream = stream;
    592    p->status = USB_RET_SUCCESS;
    593    p->actual_length = 0;
    594    p->parameter = 0;
    595    p->short_not_ok = short_not_ok;
    596    p->int_req = int_req;
    597    p->combined = NULL;
    598    qemu_iovec_reset(&p->iov);
    599    usb_packet_set_state(p, USB_PACKET_SETUP);
    600}
    601
    602void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len)
    603{
    604    qemu_iovec_add(&p->iov, ptr, len);
    605}
    606
    607void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
    608{
    609    QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
    610
    611    assert(p->actual_length >= 0);
    612    assert(p->actual_length + bytes <= iov->size);
    613    switch (p->pid) {
    614    case USB_TOKEN_SETUP:
    615    case USB_TOKEN_OUT:
    616        iov_to_buf(iov->iov, iov->niov, p->actual_length, ptr, bytes);
    617        break;
    618    case USB_TOKEN_IN:
    619        iov_from_buf(iov->iov, iov->niov, p->actual_length, ptr, bytes);
    620        break;
    621    default:
    622        fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid);
    623        abort();
    624    }
    625    p->actual_length += bytes;
    626}
    627
    628void usb_packet_skip(USBPacket *p, size_t bytes)
    629{
    630    QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
    631
    632    assert(p->actual_length >= 0);
    633    assert(p->actual_length + bytes <= iov->size);
    634    if (p->pid == USB_TOKEN_IN) {
    635        iov_memset(iov->iov, iov->niov, p->actual_length, 0, bytes);
    636    }
    637    p->actual_length += bytes;
    638}
    639
    640size_t usb_packet_size(USBPacket *p)
    641{
    642    return p->combined ? p->combined->iov.size : p->iov.size;
    643}
    644
    645void usb_packet_cleanup(USBPacket *p)
    646{
    647    assert(!usb_packet_is_inflight(p));
    648    qemu_iovec_destroy(&p->iov);
    649}
    650
    651void usb_ep_reset(USBDevice *dev)
    652{
    653    int ep;
    654
    655    dev->ep_ctl.nr = 0;
    656    dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
    657    dev->ep_ctl.ifnum = 0;
    658    dev->ep_ctl.max_packet_size = 64;
    659    dev->ep_ctl.max_streams = 0;
    660    dev->ep_ctl.dev = dev;
    661    dev->ep_ctl.pipeline = false;
    662    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
    663        dev->ep_in[ep].nr = ep + 1;
    664        dev->ep_out[ep].nr = ep + 1;
    665        dev->ep_in[ep].pid = USB_TOKEN_IN;
    666        dev->ep_out[ep].pid = USB_TOKEN_OUT;
    667        dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
    668        dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
    669        dev->ep_in[ep].ifnum = USB_INTERFACE_INVALID;
    670        dev->ep_out[ep].ifnum = USB_INTERFACE_INVALID;
    671        dev->ep_in[ep].max_packet_size = 0;
    672        dev->ep_out[ep].max_packet_size = 0;
    673        dev->ep_in[ep].max_streams = 0;
    674        dev->ep_out[ep].max_streams = 0;
    675        dev->ep_in[ep].dev = dev;
    676        dev->ep_out[ep].dev = dev;
    677        dev->ep_in[ep].pipeline = false;
    678        dev->ep_out[ep].pipeline = false;
    679    }
    680}
    681
    682void usb_ep_init(USBDevice *dev)
    683{
    684    int ep;
    685
    686    usb_ep_reset(dev);
    687    QTAILQ_INIT(&dev->ep_ctl.queue);
    688    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
    689        QTAILQ_INIT(&dev->ep_in[ep].queue);
    690        QTAILQ_INIT(&dev->ep_out[ep].queue);
    691    }
    692}
    693
    694void usb_ep_dump(USBDevice *dev)
    695{
    696    static const char *tname[] = {
    697        [USB_ENDPOINT_XFER_CONTROL] = "control",
    698        [USB_ENDPOINT_XFER_ISOC]    = "isoc",
    699        [USB_ENDPOINT_XFER_BULK]    = "bulk",
    700        [USB_ENDPOINT_XFER_INT]     = "int",
    701    };
    702    int ifnum, ep, first;
    703
    704    fprintf(stderr, "Device \"%s\", config %d\n",
    705            dev->product_desc, dev->configuration);
    706    for (ifnum = 0; ifnum < 16; ifnum++) {
    707        first = 1;
    708        for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
    709            if (dev->ep_in[ep].type != USB_ENDPOINT_XFER_INVALID &&
    710                dev->ep_in[ep].ifnum == ifnum) {
    711                if (first) {
    712                    first = 0;
    713                    fprintf(stderr, "  Interface %d, alternative %d\n",
    714                            ifnum, dev->altsetting[ifnum]);
    715                }
    716                fprintf(stderr, "    Endpoint %d, IN, %s, %d max\n", ep,
    717                        tname[dev->ep_in[ep].type],
    718                        dev->ep_in[ep].max_packet_size);
    719            }
    720            if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
    721                dev->ep_out[ep].ifnum == ifnum) {
    722                if (first) {
    723                    first = 0;
    724                    fprintf(stderr, "  Interface %d, alternative %d\n",
    725                            ifnum, dev->altsetting[ifnum]);
    726                }
    727                fprintf(stderr, "    Endpoint %d, OUT, %s, %d max\n", ep,
    728                        tname[dev->ep_out[ep].type],
    729                        dev->ep_out[ep].max_packet_size);
    730            }
    731        }
    732    }
    733    fprintf(stderr, "--\n");
    734}
    735
    736struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
    737{
    738    struct USBEndpoint *eps;
    739
    740    assert(dev != NULL);
    741    if (ep == 0) {
    742        return &dev->ep_ctl;
    743    }
    744    assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
    745    assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
    746    eps = (pid == USB_TOKEN_IN) ? dev->ep_in : dev->ep_out;
    747    return eps + ep - 1;
    748}
    749
    750uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep)
    751{
    752    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    753    return uep->type;
    754}
    755
    756void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type)
    757{
    758    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    759    uep->type = type;
    760}
    761
    762void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
    763{
    764    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    765    uep->ifnum = ifnum;
    766}
    767
    768void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
    769                                uint16_t raw)
    770{
    771    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    772    int size, microframes;
    773
    774    size = raw & 0x7ff;
    775    switch ((raw >> 11) & 3) {
    776    case 1:
    777        microframes = 2;
    778        break;
    779    case 2:
    780        microframes = 3;
    781        break;
    782    default:
    783        microframes = 1;
    784        break;
    785    }
    786    uep->max_packet_size = size * microframes;
    787}
    788
    789void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw)
    790{
    791    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    792    int MaxStreams;
    793
    794    MaxStreams = raw & 0x1f;
    795    if (MaxStreams) {
    796        uep->max_streams = 1 << MaxStreams;
    797    } else {
    798        uep->max_streams = 0;
    799    }
    800}
    801
    802void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted)
    803{
    804    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    805    uep->halted = halted;
    806}
    807
    808USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
    809                                    uint64_t id)
    810{
    811    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    812    USBPacket *p;
    813
    814    QTAILQ_FOREACH(p, &uep->queue, queue) {
    815        if (p->id == id) {
    816            return p;
    817        }
    818    }
    819
    820    return NULL;
    821}