usb.c 14.5 KB
Newer Older
B
bellard 已提交
1 2 3 4
/*
 * QEMU USB emulation
 *
 * Copyright (c) 2005 Fabrice Bellard
5
 *
6 7
 * 2008 Generic packet handler rewrite by Max Krasnyansky
 *
B
bellard 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
P
pbrook 已提交
26 27
#include "qemu-common.h"
#include "usb.h"
G
Gerd Hoffmann 已提交
28
#include "iov.h"
B
bellard 已提交
29

30
void usb_attach(USBPort *port)
B
bellard 已提交
31
{
32 33 34 35
    USBDevice *dev = port->dev;

    assert(dev != NULL);
    assert(dev->attached);
G
Gerd Hoffmann 已提交
36
    assert(dev->state == USB_STATE_NOTATTACHED);
37 38 39 40 41 42 43 44 45
    port->ops->attach(port);
    usb_send_msg(dev, USB_MSG_ATTACH);
}

void usb_detach(USBPort *port)
{
    USBDevice *dev = port->dev;

    assert(dev != NULL);
G
Gerd Hoffmann 已提交
46
    assert(dev->state != USB_STATE_NOTATTACHED);
47 48
    port->ops->detach(port);
    usb_send_msg(dev, USB_MSG_DETACH);
B
bellard 已提交
49 50
}

G
Gerd Hoffmann 已提交
51 52 53 54 55 56 57 58 59 60
void usb_reset(USBPort *port)
{
    USBDevice *dev = port->dev;

    assert(dev != NULL);
    usb_detach(port);
    usb_attach(port);
    usb_send_msg(dev, USB_MSG_RESET);
}

61 62 63
void usb_wakeup(USBDevice *dev)
{
    if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
64
        dev->port->ops->wakeup(dev->port);
65 66 67
    }
}

B
bellard 已提交
68
/**********************/
69

B
bellard 已提交
70 71
/* generic USB device helpers (you are not forced to use them when
   writing your USB device driver, but they help handling the
72
   protocol)
B
bellard 已提交
73 74
*/

75 76 77 78
#define SETUP_STATE_IDLE  0
#define SETUP_STATE_SETUP 1
#define SETUP_STATE_DATA  2
#define SETUP_STATE_ACK   3
B
bellard 已提交
79

80 81 82 83 84
static int do_token_setup(USBDevice *s, USBPacket *p)
{
    int request, value, index;
    int ret = 0;

G
Gerd Hoffmann 已提交
85
    if (p->iov.size != 8) {
86
        return USB_RET_STALL;
G
Gerd Hoffmann 已提交
87 88 89
    }

    usb_packet_copy(p, s->setup_buf, p->iov.size);
90 91 92 93 94 95
    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
    s->setup_index = 0;

    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
96

97
    if (s->setup_buf[0] & USB_DIR_IN) {
98
        ret = s->info->handle_control(s, p, request, value, index,
99
                                      s->setup_len, s->data_buf);
100 101 102 103
        if (ret == USB_RET_ASYNC) {
             s->setup_state = SETUP_STATE_SETUP;
             return USB_RET_ASYNC;
        }
104 105 106 107 108 109 110
        if (ret < 0)
            return ret;

        if (ret < s->setup_len)
            s->setup_len = ret;
        s->setup_state = SETUP_STATE_DATA;
    } else {
H
Hans de Goede 已提交
111 112 113 114 115 116
        if (s->setup_len > sizeof(s->data_buf)) {
            fprintf(stderr,
                "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
                s->setup_len, sizeof(s->data_buf));
            return USB_RET_STALL;
        }
117 118 119 120 121 122 123 124 125 126
        if (s->setup_len == 0)
            s->setup_state = SETUP_STATE_ACK;
        else
            s->setup_state = SETUP_STATE_DATA;
    }

    return ret;
}

static int do_token_in(USBDevice *s, USBPacket *p)
B
bellard 已提交
127
{
128 129 130 131
    int request, value, index;
    int ret = 0;

    if (p->devep != 0)
132
        return s->info->handle_data(s, p);
133 134 135 136 137 138 139 140

    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
 
    switch(s->setup_state) {
    case SETUP_STATE_ACK:
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
141
            ret = s->info->handle_control(s, p, request, value, index,
142
                                          s->setup_len, s->data_buf);
143 144 145 146
            if (ret == USB_RET_ASYNC) {
                return USB_RET_ASYNC;
            }
            s->setup_state = SETUP_STATE_IDLE;
147 148 149 150 151 152 153 154 155 156 157
            if (ret > 0)
                return 0;
            return ret;
        }

        /* return 0 byte */
        return 0;

    case SETUP_STATE_DATA:
        if (s->setup_buf[0] & USB_DIR_IN) {
            int len = s->setup_len - s->setup_index;
G
Gerd Hoffmann 已提交
158 159 160 161
            if (len > p->iov.size) {
                len = p->iov.size;
            }
            usb_packet_copy(p, s->data_buf + s->setup_index, len);
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
            s->setup_index += len;
            if (s->setup_index >= s->setup_len)
                s->setup_state = SETUP_STATE_ACK;
            return len;
        }

        s->setup_state = SETUP_STATE_IDLE;
        return USB_RET_STALL;

    default:
        return USB_RET_STALL;
    }
}

static int do_token_out(USBDevice *s, USBPacket *p)
{
    if (p->devep != 0)
179
        return s->info->handle_data(s, p);
180 181 182 183 184 185 186 187 188 189 190 191 192 193

    switch(s->setup_state) {
    case SETUP_STATE_ACK:
        if (s->setup_buf[0] & USB_DIR_IN) {
            s->setup_state = SETUP_STATE_IDLE;
            /* transfer OK */
        } else {
            /* ignore additional output */
        }
        return 0;

    case SETUP_STATE_DATA:
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
            int len = s->setup_len - s->setup_index;
G
Gerd Hoffmann 已提交
194 195 196 197
            if (len > p->iov.size) {
                len = p->iov.size;
            }
            usb_packet_copy(p, s->data_buf + s->setup_index, len);
198 199 200 201 202 203 204 205 206 207 208 209 210
            s->setup_index += len;
            if (s->setup_index >= s->setup_len)
                s->setup_state = SETUP_STATE_ACK;
            return len;
        }

        s->setup_state = SETUP_STATE_IDLE;
        return USB_RET_STALL;

    default:
        return USB_RET_STALL;
    }
}
B
bellard 已提交
211

212 213 214 215 216 217 218 219
/*
 * Generic packet handler.
 * Called by the HC (host controller).
 *
 * Returns length of the transaction or one of the USB_RET_XXX codes.
 */
int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
{
P
pbrook 已提交
220
    switch(p->pid) {
B
bellard 已提交
221 222
    case USB_MSG_ATTACH:
        s->state = USB_STATE_ATTACHED;
G
Gerd Hoffmann 已提交
223 224 225
        if (s->info->handle_attach) {
            s->info->handle_attach(s);
        }
226 227
        return 0;

B
bellard 已提交
228 229
    case USB_MSG_DETACH:
        s->state = USB_STATE_NOTATTACHED;
230 231
        return 0;

B
bellard 已提交
232 233 234 235
    case USB_MSG_RESET:
        s->remote_wakeup = 0;
        s->addr = 0;
        s->state = USB_STATE_DEFAULT;
G
Gerd Hoffmann 已提交
236 237 238
        if (s->info->handle_reset) {
            s->info->handle_reset(s);
        }
239 240 241 242 243 244 245 246
        return 0;
    }

    /* Rest of the PIDs must match our address */
    if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
        return USB_RET_NODEV;

    switch (p->pid) {
B
bellard 已提交
247
    case USB_TOKEN_SETUP:
248 249
        return do_token_setup(s, p);

B
bellard 已提交
250
    case USB_TOKEN_IN:
251 252
        return do_token_in(s, p);

B
bellard 已提交
253
    case USB_TOKEN_OUT:
254 255
        return do_token_out(s, p);
 
B
bellard 已提交
256
    default:
257
        return USB_RET_STALL;
B
bellard 已提交
258 259 260
    }
}

261 262 263 264 265 266
/* ctrl complete function for devices which use usb_generic_handle_packet and
   may return USB_RET_ASYNC from their handle_control callback. Device code
   which does this *must* call this function instead of the normal
   usb_packet_complete to complete their async control packets. */
void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
{
G
Gerd Hoffmann 已提交
267
    if (p->result < 0) {
268 269 270 271 272
        s->setup_state = SETUP_STATE_IDLE;
    }

    switch (s->setup_state) {
    case SETUP_STATE_SETUP:
G
Gerd Hoffmann 已提交
273 274
        if (p->result < s->setup_len) {
            s->setup_len = p->result;
275 276
        }
        s->setup_state = SETUP_STATE_DATA;
G
Gerd Hoffmann 已提交
277
        p->result = 8;
278 279 280 281
        break;

    case SETUP_STATE_ACK:
        s->setup_state = SETUP_STATE_IDLE;
G
Gerd Hoffmann 已提交
282
        p->result = 0;
283 284 285 286 287 288 289 290
        break;

    default:
        break;
    }
    usb_packet_complete(s, p);
}

B
bellard 已提交
291 292 293 294 295 296 297 298
/* XXX: fix overflow */
int set_usb_string(uint8_t *buf, const char *str)
{
    int len, i;
    uint8_t *q;

    q = buf;
    len = strlen(str);
P
pbrook 已提交
299
    *q++ = 2 * len + 2;
B
bellard 已提交
300 301 302 303 304 305 306
    *q++ = 3;
    for(i = 0; i < len; i++) {
        *q++ = str[i];
        *q++ = 0;
    }
    return q - buf;
}
P
pbrook 已提交
307 308 309 310 311

/* Send an internal message to a USB device.  */
void usb_send_msg(USBDevice *dev, int msg)
{
    USBPacket p;
G
Gerd Hoffmann 已提交
312 313
    int ret;

P
pbrook 已提交
314 315
    memset(&p, 0, sizeof(p));
    p.pid = msg;
G
Gerd Hoffmann 已提交
316
    ret = usb_handle_packet(dev, &p);
317
    /* This _must_ be synchronous */
G
Gerd Hoffmann 已提交
318 319 320 321 322 323 324 325 326 327
    assert(ret != USB_RET_ASYNC);
}

/* Hand over a packet to a device for processing.  Return value
   USB_RET_ASYNC indicates the processing isn't finished yet, the
   driver will call usb_packet_complete() when done processing it. */
int usb_handle_packet(USBDevice *dev, USBPacket *p)
{
    int ret;

G
Gerd Hoffmann 已提交
328
    assert(p->owner == NULL);
G
Gerd Hoffmann 已提交
329
    ret = dev->info->handle_packet(dev, p);
G
Gerd Hoffmann 已提交
330 331
    if (ret == USB_RET_ASYNC) {
        if (p->owner == NULL) {
332
            p->owner = usb_ep_get(dev, p->pid, p->devep);
G
Gerd Hoffmann 已提交
333 334 335 336 337 338 339
        } else {
            /* We'll end up here when usb_handle_packet is called
             * recursively due to a hub being in the chain.  Nothing
             * to do.  Leave p->owner pointing to the device, not the
             * hub. */;
        }
    }
G
Gerd Hoffmann 已提交
340
    return ret;
341
}
G
Gerd Hoffmann 已提交
342 343 344 345 346 347 348 349 350

/* Notify the controller that an async packet is complete.  This should only
   be called for packets previously deferred by returning USB_RET_ASYNC from
   handle_packet. */
void usb_packet_complete(USBDevice *dev, USBPacket *p)
{
    /* Note: p->owner != dev is possible in case dev is a hub */
    assert(p->owner != NULL);
    p->owner = NULL;
G
Gerd Hoffmann 已提交
351
    dev->port->ops->complete(dev->port, p);
G
Gerd Hoffmann 已提交
352 353 354 355 356 357 358 359
}

/* Cancel an active packet.  The packed must have been deferred by
   returning USB_RET_ASYNC from handle_packet, and not yet
   completed.  */
void usb_cancel_packet(USBPacket * p)
{
    assert(p->owner != NULL);
360
    p->owner->dev->info->cancel_packet(p->owner->dev, p);
G
Gerd Hoffmann 已提交
361 362
    p->owner = NULL;
}
G
Gerd Hoffmann 已提交
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416


void usb_packet_init(USBPacket *p)
{
    qemu_iovec_init(&p->iov, 1);
}

void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep)
{
    p->pid = pid;
    p->devaddr = addr;
    p->devep = ep;
    p->result = 0;
    qemu_iovec_reset(&p->iov);
}

void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len)
{
    qemu_iovec_add(&p->iov, ptr, len);
}

void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
{
    assert(p->result >= 0);
    assert(p->result + bytes <= p->iov.size);
    switch (p->pid) {
    case USB_TOKEN_SETUP:
    case USB_TOKEN_OUT:
        iov_to_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
        break;
    case USB_TOKEN_IN:
        iov_from_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
        break;
    default:
        fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid);
        abort();
    }
    p->result += bytes;
}

void usb_packet_skip(USBPacket *p, size_t bytes)
{
    assert(p->result >= 0);
    assert(p->result + bytes <= p->iov.size);
    if (p->pid == USB_TOKEN_IN) {
        iov_clear(p->iov.iov, p->iov.niov, p->result, bytes);
    }
    p->result += bytes;
}

void usb_packet_cleanup(USBPacket *p)
{
    qemu_iovec_destroy(&p->iov);
}
G
Gerd Hoffmann 已提交
417 418 419 420 421

void usb_ep_init(USBDevice *dev)
{
    int ep;

422 423 424
    dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
    dev->ep_ctl.ifnum = 0;
    dev->ep_ctl.dev = dev;
G
Gerd Hoffmann 已提交
425 426 427
    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
        dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
        dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
G
Gerd Hoffmann 已提交
428 429
        dev->ep_in[ep].ifnum = 0;
        dev->ep_out[ep].ifnum = 0;
430 431
        dev->ep_in[ep].dev = dev;
        dev->ep_out[ep].dev = dev;
G
Gerd Hoffmann 已提交
432 433 434
    }
}

G
Gerd Hoffmann 已提交
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
void usb_ep_dump(USBDevice *dev)
{
    static const char *tname[] = {
        [USB_ENDPOINT_XFER_CONTROL] = "control",
        [USB_ENDPOINT_XFER_ISOC]    = "isoc",
        [USB_ENDPOINT_XFER_BULK]    = "bulk",
        [USB_ENDPOINT_XFER_INT]     = "int",
    };
    int ifnum, ep, first;

    fprintf(stderr, "Device \"%s\", config %d\n",
            dev->product_desc, dev->configuration);
    for (ifnum = 0; ifnum < 16; ifnum++) {
        first = 1;
        for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
            if (dev->ep_in[ep].type != USB_ENDPOINT_XFER_INVALID &&
                dev->ep_in[ep].ifnum == ifnum) {
                if (first) {
                    first = 0;
                    fprintf(stderr, "  Interface %d, alternative %d\n",
                            ifnum, dev->altsetting[ifnum]);
                }
457 458 459
                fprintf(stderr, "    Endpoint %d, IN, %s, %d max\n", ep,
                        tname[dev->ep_in[ep].type],
                        dev->ep_in[ep].max_packet_size);
G
Gerd Hoffmann 已提交
460 461 462 463 464 465 466 467
            }
            if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
                dev->ep_out[ep].ifnum == ifnum) {
                if (first) {
                    first = 0;
                    fprintf(stderr, "  Interface %d, alternative %d\n",
                            ifnum, dev->altsetting[ifnum]);
                }
468 469 470
                fprintf(stderr, "    Endpoint %d, OUT, %s, %d max\n", ep,
                        tname[dev->ep_out[ep].type],
                        dev->ep_out[ep].max_packet_size);
G
Gerd Hoffmann 已提交
471 472 473 474 475 476
            }
        }
    }
    fprintf(stderr, "--\n");
}

G
Gerd Hoffmann 已提交
477 478 479
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
{
    struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev->ep_in : dev->ep_out;
480 481 482
    if (ep == 0) {
        return &dev->ep_ctl;
    }
G
Gerd Hoffmann 已提交
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
    assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
    assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
    return eps + ep - 1;
}

uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep)
{
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    return uep->type;
}

void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type)
{
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    uep->type = type;
}
G
Gerd Hoffmann 已提交
499 500 501 502 503 504 505 506 507 508 509 510

uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep)
{
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    return uep->ifnum;
}

void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
{
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    uep->ifnum = ifnum;
}
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537

void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
                                uint16_t raw)
{
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    int size, microframes;

    size = raw & 0x7ff;
    switch ((raw >> 11) & 3) {
    case 1:
        microframes = 2;
        break;
    case 2:
        microframes = 3;
        break;
    default:
        microframes = 1;
        break;
    }
    uep->max_packet_size = size * microframes;
}

int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
{
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
    return uep->max_packet_size;
}