Statistics
| Branch: | Revision:

root / hw / usb.c @ 8656954a

History | View | Annotate | Download (7.1 kB)

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-common.h"
27
#include "usb.h"
28

    
29
void usb_attach(USBPort *port, USBDevice *dev)
30
{
31
    if (dev != NULL) {
32
        /* attach */
33
        if (port->dev) {
34
            usb_attach(port, NULL);
35
        }
36
        dev->port = port;
37
        port->dev = dev;
38
        port->ops->attach(port);
39
        usb_send_msg(dev, USB_MSG_ATTACH);
40
    } else {
41
        /* detach */
42
        dev = port->dev;
43
        port->ops->detach(port);
44
        if (dev) {
45
            usb_send_msg(dev, USB_MSG_DETACH);
46
            dev->port = NULL;
47
            port->dev = NULL;
48
        }
49
    }
50
}
51

    
52
void usb_wakeup(USBDevice *dev)
53
{
54
    if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
55
        dev->port->ops->wakeup(dev);
56
    }
57
}
58

    
59
/**********************/
60

    
61
/* generic USB device helpers (you are not forced to use them when
62
   writing your USB device driver, but they help handling the
63
   protocol)
64
*/
65

    
66
#define SETUP_STATE_IDLE 0
67
#define SETUP_STATE_DATA 1
68
#define SETUP_STATE_ACK  2
69

    
70
static int do_token_setup(USBDevice *s, USBPacket *p)
71
{
72
    int request, value, index;
73
    int ret = 0;
74

    
75
    if (p->len != 8)
76
        return USB_RET_STALL;
77
 
78
    memcpy(s->setup_buf, p->data, 8);
79
    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
80
    s->setup_index = 0;
81

    
82
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
83
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
84
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
85
 
86
    if (s->setup_buf[0] & USB_DIR_IN) {
87
        ret = s->info->handle_control(s, request, value, index, 
88
                                      s->setup_len, s->data_buf);
89
        if (ret < 0)
90
            return ret;
91

    
92
        if (ret < s->setup_len)
93
            s->setup_len = ret;
94
        s->setup_state = SETUP_STATE_DATA;
95
    } else {
96
        if (s->setup_len > sizeof(s->data_buf)) {
97
            fprintf(stderr,
98
                "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
99
                s->setup_len, sizeof(s->data_buf));
100
            return USB_RET_STALL;
101
        }
102
        if (s->setup_len == 0)
103
            s->setup_state = SETUP_STATE_ACK;
104
        else
105
            s->setup_state = SETUP_STATE_DATA;
106
    }
107

    
108
    return ret;
109
}
110

    
111
static int do_token_in(USBDevice *s, USBPacket *p)
112
{
113
    int request, value, index;
114
    int ret = 0;
115

    
116
    if (p->devep != 0)
117
        return s->info->handle_data(s, p);
118

    
119
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
120
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
121
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
122
 
123
    switch(s->setup_state) {
124
    case SETUP_STATE_ACK:
125
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
126
            s->setup_state = SETUP_STATE_IDLE;
127
            ret = s->info->handle_control(s, request, value, index,
128
                                          s->setup_len, s->data_buf);
129
            if (ret > 0)
130
                return 0;
131
            return ret;
132
        }
133

    
134
        /* return 0 byte */
135
        return 0;
136

    
137
    case SETUP_STATE_DATA:
138
        if (s->setup_buf[0] & USB_DIR_IN) {
139
            int len = s->setup_len - s->setup_index;
140
            if (len > p->len)
141
                len = p->len;
142
            memcpy(p->data, s->data_buf + s->setup_index, len);
143
            s->setup_index += len;
144
            if (s->setup_index >= s->setup_len)
145
                s->setup_state = SETUP_STATE_ACK;
146
            return len;
147
        }
148

    
149
        s->setup_state = SETUP_STATE_IDLE;
150
        return USB_RET_STALL;
151

    
152
    default:
153
        return USB_RET_STALL;
154
    }
155
}
156

    
157
static int do_token_out(USBDevice *s, USBPacket *p)
158
{
159
    if (p->devep != 0)
160
        return s->info->handle_data(s, p);
161

    
162
    switch(s->setup_state) {
163
    case SETUP_STATE_ACK:
164
        if (s->setup_buf[0] & USB_DIR_IN) {
165
            s->setup_state = SETUP_STATE_IDLE;
166
            /* transfer OK */
167
        } else {
168
            /* ignore additional output */
169
        }
170
        return 0;
171

    
172
    case SETUP_STATE_DATA:
173
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
174
            int len = s->setup_len - s->setup_index;
175
            if (len > p->len)
176
                len = p->len;
177
            memcpy(s->data_buf + s->setup_index, p->data, len);
178
            s->setup_index += len;
179
            if (s->setup_index >= s->setup_len)
180
                s->setup_state = SETUP_STATE_ACK;
181
            return len;
182
        }
183

    
184
        s->setup_state = SETUP_STATE_IDLE;
185
        return USB_RET_STALL;
186

    
187
    default:
188
        return USB_RET_STALL;
189
    }
190
}
191

    
192
/*
193
 * Generic packet handler.
194
 * Called by the HC (host controller).
195
 *
196
 * Returns length of the transaction or one of the USB_RET_XXX codes.
197
 */
198
int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
199
{
200
    switch(p->pid) {
201
    case USB_MSG_ATTACH:
202
        s->state = USB_STATE_ATTACHED;
203
        if (s->info->handle_attach) {
204
            s->info->handle_attach(s);
205
        }
206
        return 0;
207

    
208
    case USB_MSG_DETACH:
209
        s->state = USB_STATE_NOTATTACHED;
210
        return 0;
211

    
212
    case USB_MSG_RESET:
213
        s->remote_wakeup = 0;
214
        s->addr = 0;
215
        s->state = USB_STATE_DEFAULT;
216
        if (s->info->handle_reset) {
217
            s->info->handle_reset(s);
218
        }
219
        return 0;
220
    }
221

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

    
226
    switch (p->pid) {
227
    case USB_TOKEN_SETUP:
228
        return do_token_setup(s, p);
229

    
230
    case USB_TOKEN_IN:
231
        return do_token_in(s, p);
232

    
233
    case USB_TOKEN_OUT:
234
        return do_token_out(s, p);
235
 
236
    default:
237
        return USB_RET_STALL;
238
    }
239
}
240

    
241
/* XXX: fix overflow */
242
int set_usb_string(uint8_t *buf, const char *str)
243
{
244
    int len, i;
245
    uint8_t *q;
246

    
247
    q = buf;
248
    len = strlen(str);
249
    *q++ = 2 * len + 2;
250
    *q++ = 3;
251
    for(i = 0; i < len; i++) {
252
        *q++ = str[i];
253
        *q++ = 0;
254
    }
255
    return q - buf;
256
}
257

    
258
/* Send an internal message to a USB device.  */
259
void usb_send_msg(USBDevice *dev, int msg)
260
{
261
    USBPacket p;
262
    memset(&p, 0, sizeof(p));
263
    p.pid = msg;
264
    dev->info->handle_packet(dev, &p);
265

    
266
    /* This _must_ be synchronous */
267
}