Statistics
| Branch: | Revision:

root / hw / usb-hid.c @ 8109b9b6

History | View | Annotate | Download (27.7 kB)

1 59ae540c bellard
/*
2 59ae540c bellard
 * QEMU USB HID devices
3 5fafdf24 ths
 *
4 59ae540c bellard
 * Copyright (c) 2005 Fabrice Bellard
5 47b2d338 balrog
 * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
6 5fafdf24 ths
 *
7 59ae540c bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 59ae540c bellard
 * of this software and associated documentation files (the "Software"), to deal
9 59ae540c bellard
 * in the Software without restriction, including without limitation the rights
10 59ae540c bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 59ae540c bellard
 * copies of the Software, and to permit persons to whom the Software is
12 59ae540c bellard
 * furnished to do so, subject to the following conditions:
13 59ae540c bellard
 *
14 59ae540c bellard
 * The above copyright notice and this permission notice shall be included in
15 59ae540c bellard
 * all copies or substantial portions of the Software.
16 59ae540c bellard
 *
17 59ae540c bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 59ae540c bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 59ae540c bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 59ae540c bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 59ae540c bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 59ae540c bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 59ae540c bellard
 * THE SOFTWARE.
24 59ae540c bellard
 */
25 87ecb68b pbrook
#include "hw.h"
26 87ecb68b pbrook
#include "console.h"
27 87ecb68b pbrook
#include "usb.h"
28 59ae540c bellard
29 59ae540c bellard
/* HID interface requests */
30 59ae540c bellard
#define GET_REPORT   0xa101
31 59ae540c bellard
#define GET_IDLE     0xa102
32 59ae540c bellard
#define GET_PROTOCOL 0xa103
33 47b2d338 balrog
#define SET_REPORT   0x2109
34 59ae540c bellard
#define SET_IDLE     0x210a
35 59ae540c bellard
#define SET_PROTOCOL 0x210b
36 59ae540c bellard
37 47b2d338 balrog
/* HID descriptor types */
38 47b2d338 balrog
#define USB_DT_HID    0x21
39 47b2d338 balrog
#define USB_DT_REPORT 0x22
40 47b2d338 balrog
#define USB_DT_PHY    0x23
41 47b2d338 balrog
42 47b2d338 balrog
#define USB_MOUSE     1
43 47b2d338 balrog
#define USB_TABLET    2
44 47b2d338 balrog
#define USB_KEYBOARD  3
45 09b26c5e bellard
46 59ae540c bellard
typedef struct USBMouseState {
47 59ae540c bellard
    int dx, dy, dz, buttons_state;
48 09b26c5e bellard
    int x, y;
49 09b26c5e bellard
    int mouse_grabbed;
50 455204eb ths
    QEMUPutMouseEntry *eh_entry;
51 59ae540c bellard
} USBMouseState;
52 59ae540c bellard
53 47b2d338 balrog
typedef struct USBKeyboardState {
54 47b2d338 balrog
    uint16_t modifiers;
55 47b2d338 balrog
    uint8_t leds;
56 47b2d338 balrog
    uint8_t key[16];
57 47b2d338 balrog
    int keys;
58 47b2d338 balrog
} USBKeyboardState;
59 47b2d338 balrog
60 47b2d338 balrog
typedef struct USBHIDState {
61 47b2d338 balrog
    USBDevice dev;
62 47b2d338 balrog
    union {
63 47b2d338 balrog
        USBMouseState ptr;
64 47b2d338 balrog
        USBKeyboardState kbd;
65 47b2d338 balrog
    };
66 47b2d338 balrog
    int kind;
67 47b2d338 balrog
    int protocol;
68 47b2d338 balrog
    int idle;
69 117b3ae6 pbrook
    int changed;
70 47b2d338 balrog
} USBHIDState;
71 47b2d338 balrog
72 59ae540c bellard
/* mostly the same values as the Bochs USB Mouse device */
73 59ae540c bellard
static const uint8_t qemu_mouse_dev_descriptor[] = {
74 59ae540c bellard
        0x12,       /*  u8 bLength; */
75 59ae540c bellard
        0x01,       /*  u8 bDescriptorType; Device */
76 e126cf13 ths
        0x00, 0x01, /*  u16 bcdUSB; v1.0 */
77 59ae540c bellard
78 59ae540c bellard
        0x00,            /*  u8  bDeviceClass; */
79 59ae540c bellard
        0x00,            /*  u8  bDeviceSubClass; */
80 59ae540c bellard
        0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
81 59ae540c bellard
        0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
82 59ae540c bellard
83 59ae540c bellard
        0x27, 0x06, /*  u16 idVendor; */
84 59ae540c bellard
         0x01, 0x00, /*  u16 idProduct; */
85 59ae540c bellard
        0x00, 0x00, /*  u16 bcdDevice */
86 59ae540c bellard
87 59ae540c bellard
        0x03,       /*  u8  iManufacturer; */
88 59ae540c bellard
        0x02,       /*  u8  iProduct; */
89 59ae540c bellard
        0x01,       /*  u8  iSerialNumber; */
90 59ae540c bellard
        0x01        /*  u8  bNumConfigurations; */
91 59ae540c bellard
};
92 59ae540c bellard
93 59ae540c bellard
static const uint8_t qemu_mouse_config_descriptor[] = {
94 59ae540c bellard
        /* one configuration */
95 59ae540c bellard
        0x09,       /*  u8  bLength; */
96 59ae540c bellard
        0x02,       /*  u8  bDescriptorType; Configuration */
97 59ae540c bellard
        0x22, 0x00, /*  u16 wTotalLength; */
98 59ae540c bellard
        0x01,       /*  u8  bNumInterfaces; (1) */
99 59ae540c bellard
        0x01,       /*  u8  bConfigurationValue; */
100 59ae540c bellard
        0x04,       /*  u8  iConfiguration; */
101 5fafdf24 ths
        0xa0,       /*  u8  bmAttributes;
102 59ae540c bellard
                                 Bit 7: must be set,
103 59ae540c bellard
                                     6: Self-powered,
104 59ae540c bellard
                                     5: Remote wakeup,
105 59ae540c bellard
                                     4..0: resvd */
106 59ae540c bellard
        50,         /*  u8  MaxPower; */
107 3b46e624 ths
108 59ae540c bellard
        /* USB 1.1:
109 59ae540c bellard
         * USB 2.0, single TT organization (mandatory):
110 59ae540c bellard
         *        one interface, protocol 0
111 59ae540c bellard
         *
112 59ae540c bellard
         * USB 2.0, multiple TT organization (optional):
113 59ae540c bellard
         *        two interfaces, protocols 1 (like single TT)
114 59ae540c bellard
         *        and 2 (multiple TT mode) ... config is
115 59ae540c bellard
         *        sometimes settable
116 59ae540c bellard
         *        NOT IMPLEMENTED
117 59ae540c bellard
         */
118 59ae540c bellard
119 59ae540c bellard
        /* one interface */
120 59ae540c bellard
        0x09,       /*  u8  if_bLength; */
121 59ae540c bellard
        0x04,       /*  u8  if_bDescriptorType; Interface */
122 59ae540c bellard
        0x00,       /*  u8  if_bInterfaceNumber; */
123 59ae540c bellard
        0x00,       /*  u8  if_bAlternateSetting; */
124 59ae540c bellard
        0x01,       /*  u8  if_bNumEndpoints; */
125 59ae540c bellard
        0x03,       /*  u8  if_bInterfaceClass; */
126 59ae540c bellard
        0x01,       /*  u8  if_bInterfaceSubClass; */
127 59ae540c bellard
        0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
128 47b2d338 balrog
        0x07,       /*  u8  if_iInterface; */
129 3b46e624 ths
130 09b26c5e bellard
        /* HID descriptor */
131 09b26c5e bellard
        0x09,        /*  u8  bLength; */
132 09b26c5e bellard
        0x21,        /*  u8 bDescriptorType; */
133 09b26c5e bellard
        0x01, 0x00,  /*  u16 HID_class */
134 09b26c5e bellard
        0x00,        /*  u8 country_code */
135 09b26c5e bellard
        0x01,        /*  u8 num_descriptors */
136 09b26c5e bellard
        0x22,        /*  u8 type; Report */
137 c21c583a balrog
        52, 0,       /*  u16 len */
138 09b26c5e bellard
139 59ae540c bellard
        /* one endpoint (status change endpoint) */
140 59ae540c bellard
        0x07,       /*  u8  ep_bLength; */
141 59ae540c bellard
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
142 59ae540c bellard
        0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
143 59ae540c bellard
         0x03,       /*  u8  ep_bmAttributes; Interrupt */
144 c21c583a balrog
         0x04, 0x00, /*  u16 ep_wMaxPacketSize; */
145 59ae540c bellard
        0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
146 09b26c5e bellard
};
147 09b26c5e bellard
148 09b26c5e bellard
static const uint8_t qemu_tablet_config_descriptor[] = {
149 09b26c5e bellard
        /* one configuration */
150 09b26c5e bellard
        0x09,       /*  u8  bLength; */
151 09b26c5e bellard
        0x02,       /*  u8  bDescriptorType; Configuration */
152 09b26c5e bellard
        0x22, 0x00, /*  u16 wTotalLength; */
153 09b26c5e bellard
        0x01,       /*  u8  bNumInterfaces; (1) */
154 09b26c5e bellard
        0x01,       /*  u8  bConfigurationValue; */
155 47b2d338 balrog
        0x05,       /*  u8  iConfiguration; */
156 5fafdf24 ths
        0xa0,       /*  u8  bmAttributes;
157 09b26c5e bellard
                                 Bit 7: must be set,
158 09b26c5e bellard
                                     6: Self-powered,
159 09b26c5e bellard
                                     5: Remote wakeup,
160 09b26c5e bellard
                                     4..0: resvd */
161 09b26c5e bellard
        50,         /*  u8  MaxPower; */
162 3b46e624 ths
163 09b26c5e bellard
        /* USB 1.1:
164 09b26c5e bellard
         * USB 2.0, single TT organization (mandatory):
165 09b26c5e bellard
         *        one interface, protocol 0
166 09b26c5e bellard
         *
167 09b26c5e bellard
         * USB 2.0, multiple TT organization (optional):
168 09b26c5e bellard
         *        two interfaces, protocols 1 (like single TT)
169 09b26c5e bellard
         *        and 2 (multiple TT mode) ... config is
170 09b26c5e bellard
         *        sometimes settable
171 09b26c5e bellard
         *        NOT IMPLEMENTED
172 09b26c5e bellard
         */
173 09b26c5e bellard
174 09b26c5e bellard
        /* one interface */
175 09b26c5e bellard
        0x09,       /*  u8  if_bLength; */
176 09b26c5e bellard
        0x04,       /*  u8  if_bDescriptorType; Interface */
177 09b26c5e bellard
        0x00,       /*  u8  if_bInterfaceNumber; */
178 09b26c5e bellard
        0x00,       /*  u8  if_bAlternateSetting; */
179 09b26c5e bellard
        0x01,       /*  u8  if_bNumEndpoints; */
180 09b26c5e bellard
        0x03,       /*  u8  if_bInterfaceClass; */
181 09b26c5e bellard
        0x01,       /*  u8  if_bInterfaceSubClass; */
182 09b26c5e bellard
        0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
183 47b2d338 balrog
        0x07,       /*  u8  if_iInterface; */
184 59ae540c bellard
185 59ae540c bellard
        /* HID descriptor */
186 59ae540c bellard
        0x09,        /*  u8  bLength; */
187 59ae540c bellard
        0x21,        /*  u8 bDescriptorType; */
188 59ae540c bellard
        0x01, 0x00,  /*  u16 HID_class */
189 59ae540c bellard
        0x00,        /*  u8 country_code */
190 59ae540c bellard
        0x01,        /*  u8 num_descriptors */
191 59ae540c bellard
        0x22,        /*  u8 type; Report */
192 09b26c5e bellard
        74, 0,       /*  u16 len */
193 09b26c5e bellard
194 09b26c5e bellard
        /* one endpoint (status change endpoint) */
195 09b26c5e bellard
        0x07,       /*  u8  ep_bLength; */
196 09b26c5e bellard
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
197 09b26c5e bellard
        0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
198 09b26c5e bellard
         0x03,       /*  u8  ep_bmAttributes; Interrupt */
199 09b26c5e bellard
         0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
200 f2f1ac82 bellard
        0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
201 59ae540c bellard
};
202 59ae540c bellard
203 47b2d338 balrog
static const uint8_t qemu_keyboard_config_descriptor[] = {
204 47b2d338 balrog
    /* one configuration */
205 47b2d338 balrog
    0x09,                /*  u8  bLength; */
206 47b2d338 balrog
    USB_DT_CONFIG,        /*  u8  bDescriptorType; Configuration */
207 47b2d338 balrog
    0x22, 0x00,                /*  u16 wTotalLength; */
208 47b2d338 balrog
    0x01,                /*  u8  bNumInterfaces; (1) */
209 47b2d338 balrog
    0x01,                /*  u8  bConfigurationValue; */
210 47b2d338 balrog
    0x06,                /*  u8  iConfiguration; */
211 5fafdf24 ths
    0xa0,                /*  u8  bmAttributes;
212 47b2d338 balrog
                                Bit 7: must be set,
213 47b2d338 balrog
                                    6: Self-powered,
214 47b2d338 balrog
                                    5: Remote wakeup,
215 47b2d338 balrog
                                    4..0: resvd */
216 47b2d338 balrog
    0x32,                /*  u8  MaxPower; */
217 47b2d338 balrog
218 47b2d338 balrog
    /* USB 1.1:
219 47b2d338 balrog
     * USB 2.0, single TT organization (mandatory):
220 47b2d338 balrog
     *        one interface, protocol 0
221 47b2d338 balrog
     *
222 47b2d338 balrog
     * USB 2.0, multiple TT organization (optional):
223 47b2d338 balrog
     *        two interfaces, protocols 1 (like single TT)
224 47b2d338 balrog
     *        and 2 (multiple TT mode) ... config is
225 47b2d338 balrog
     *        sometimes settable
226 47b2d338 balrog
     *        NOT IMPLEMENTED
227 47b2d338 balrog
     */
228 47b2d338 balrog
229 47b2d338 balrog
    /* one interface */
230 47b2d338 balrog
    0x09,                /*  u8  if_bLength; */
231 47b2d338 balrog
    USB_DT_INTERFACE,        /*  u8  if_bDescriptorType; Interface */
232 47b2d338 balrog
    0x00,                /*  u8  if_bInterfaceNumber; */
233 47b2d338 balrog
    0x00,                /*  u8  if_bAlternateSetting; */
234 47b2d338 balrog
    0x01,                /*  u8  if_bNumEndpoints; */
235 47b2d338 balrog
    0x03,                /*  u8  if_bInterfaceClass; HID */
236 47b2d338 balrog
    0x01,                /*  u8  if_bInterfaceSubClass; Boot */
237 47b2d338 balrog
    0x01,                /*  u8  if_bInterfaceProtocol; Keyboard */
238 47b2d338 balrog
    0x07,                /*  u8  if_iInterface; */
239 47b2d338 balrog
240 47b2d338 balrog
    /* HID descriptor */
241 47b2d338 balrog
    0x09,                /*  u8  bLength; */
242 47b2d338 balrog
    USB_DT_HID,                /*  u8  bDescriptorType; */
243 47b2d338 balrog
    0x11, 0x01,                /*  u16 HID_class */
244 47b2d338 balrog
    0x00,                /*  u8  country_code */
245 47b2d338 balrog
    0x01,                /*  u8  num_descriptors */
246 47b2d338 balrog
    USB_DT_REPORT,        /*  u8  type; Report */
247 47b2d338 balrog
    0x3f, 0x00,                /*  u16 len */
248 47b2d338 balrog
249 47b2d338 balrog
    /* one endpoint (status change endpoint) */
250 47b2d338 balrog
    0x07,                /*  u8  ep_bLength; */
251 47b2d338 balrog
    USB_DT_ENDPOINT,        /*  u8  ep_bDescriptorType; Endpoint */
252 47b2d338 balrog
    USB_DIR_IN | 0x01,        /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
253 47b2d338 balrog
    0x03,                /*  u8  ep_bmAttributes; Interrupt */
254 47b2d338 balrog
    0x08, 0x00,                /*  u16 ep_wMaxPacketSize; */
255 47b2d338 balrog
    0x0a,                /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
256 47b2d338 balrog
};
257 47b2d338 balrog
258 59ae540c bellard
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
259 976f8eef balrog
    0x05, 0x01,                /* Usage Page (Generic Desktop) */
260 976f8eef balrog
    0x09, 0x02,                /* Usage (Mouse) */
261 976f8eef balrog
    0xa1, 0x01,                /* Collection (Application) */
262 976f8eef balrog
    0x09, 0x01,                /*   Usage (Pointer) */
263 976f8eef balrog
    0xa1, 0x00,                /*   Collection (Physical) */
264 976f8eef balrog
    0x05, 0x09,                /*     Usage Page (Button) */
265 976f8eef balrog
    0x19, 0x01,                /*     Usage Minimum (1) */
266 976f8eef balrog
    0x29, 0x03,                /*     Usage Maximum (3) */
267 976f8eef balrog
    0x15, 0x00,                /*     Logical Minimum (0) */
268 976f8eef balrog
    0x25, 0x01,                /*     Logical Maximum (1) */
269 976f8eef balrog
    0x95, 0x03,                /*     Report Count (3) */
270 976f8eef balrog
    0x75, 0x01,                /*     Report Size (1) */
271 976f8eef balrog
    0x81, 0x02,                /*     Input (Data, Variable, Absolute) */
272 976f8eef balrog
    0x95, 0x01,                /*     Report Count (1) */
273 976f8eef balrog
    0x75, 0x05,                /*     Report Size (5) */
274 976f8eef balrog
    0x81, 0x01,                /*     Input (Constant) */
275 976f8eef balrog
    0x05, 0x01,                /*     Usage Page (Generic Desktop) */
276 976f8eef balrog
    0x09, 0x30,                /*     Usage (X) */
277 976f8eef balrog
    0x09, 0x31,                /*     Usage (Y) */
278 976f8eef balrog
    0x09, 0x38,                /*     Usage (Wheel) */
279 976f8eef balrog
    0x15, 0x81,                /*     Logical Minimum (-0x7f) */
280 976f8eef balrog
    0x25, 0x7f,                /*     Logical Maximum (0x7f) */
281 976f8eef balrog
    0x75, 0x08,                /*     Report Size (8) */
282 976f8eef balrog
    0x95, 0x03,                /*     Report Count (3) */
283 976f8eef balrog
    0x81, 0x06,                /*     Input (Data, Variable, Relative) */
284 976f8eef balrog
    0xc0,                /*   End Collection */
285 976f8eef balrog
    0xc0,                /* End Collection */
286 59ae540c bellard
};
287 59ae540c bellard
288 09b26c5e bellard
static const uint8_t qemu_tablet_hid_report_descriptor[] = {
289 976f8eef balrog
    0x05, 0x01,                /* Usage Page (Generic Desktop) */
290 976f8eef balrog
    0x09, 0x01,                /* Usage (Pointer) */
291 976f8eef balrog
    0xa1, 0x01,                /* Collection (Application) */
292 976f8eef balrog
    0x09, 0x01,                /*   Usage (Pointer) */
293 976f8eef balrog
    0xa1, 0x00,                /*   Collection (Physical) */
294 976f8eef balrog
    0x05, 0x09,                /*     Usage Page (Button) */
295 976f8eef balrog
    0x19, 0x01,                /*     Usage Minimum (1) */
296 976f8eef balrog
    0x29, 0x03,                /*     Usage Maximum (3) */
297 976f8eef balrog
    0x15, 0x00,                /*     Logical Minimum (0) */
298 976f8eef balrog
    0x25, 0x01,                /*     Logical Maximum (1) */
299 976f8eef balrog
    0x95, 0x03,                /*     Report Count (3) */
300 976f8eef balrog
    0x75, 0x01,                /*     Report Size (1) */
301 976f8eef balrog
    0x81, 0x02,                /*     Input (Data, Variable, Absolute) */
302 976f8eef balrog
    0x95, 0x01,                /*     Report Count (1) */
303 976f8eef balrog
    0x75, 0x05,                /*     Report Size (5) */
304 976f8eef balrog
    0x81, 0x01,                /*     Input (Constant) */
305 976f8eef balrog
    0x05, 0x01,                /*     Usage Page (Generic Desktop) */
306 976f8eef balrog
    0x09, 0x30,                /*     Usage (X) */
307 976f8eef balrog
    0x09, 0x31,                /*     Usage (Y) */
308 976f8eef balrog
    0x15, 0x00,                /*     Logical Minimum (0) */
309 de5c2d0a balrog
    0x26, 0xff, 0x7f,        /*     Logical Maximum (0x7fff) */
310 976f8eef balrog
    0x35, 0x00,                /*     Physical Minimum (0) */
311 de5c2d0a balrog
    0x46, 0xff, 0x7f,        /*     Physical Maximum (0x7fff) */
312 976f8eef balrog
    0x75, 0x10,                /*     Report Size (16) */
313 976f8eef balrog
    0x95, 0x02,                /*     Report Count (2) */
314 976f8eef balrog
    0x81, 0x02,                /*     Input (Data, Variable, Absolute) */
315 976f8eef balrog
    0x05, 0x01,                /*     Usage Page (Generic Desktop) */
316 976f8eef balrog
    0x09, 0x38,                /*     Usage (Wheel) */
317 976f8eef balrog
    0x15, 0x81,                /*     Logical Minimum (-0x7f) */
318 976f8eef balrog
    0x25, 0x7f,                /*     Logical Maximum (0x7f) */
319 976f8eef balrog
    0x35, 0x00,                /*     Physical Minimum (same as logical) */
320 976f8eef balrog
    0x45, 0x00,                /*     Physical Maximum (same as logical) */
321 976f8eef balrog
    0x75, 0x08,                /*     Report Size (8) */
322 976f8eef balrog
    0x95, 0x01,                /*     Report Count (1) */
323 976f8eef balrog
    0x81, 0x06,                /*     Input (Data, Variable, Relative) */
324 976f8eef balrog
    0xc0,                /*   End Collection */
325 976f8eef balrog
    0xc0,                /* End Collection */
326 09b26c5e bellard
};
327 09b26c5e bellard
328 47b2d338 balrog
static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
329 47b2d338 balrog
    0x05, 0x01,                /* Usage Page (Generic Desktop) */
330 47b2d338 balrog
    0x09, 0x06,                /* Usage (Keyboard) */
331 47b2d338 balrog
    0xa1, 0x01,                /* Collection (Application) */
332 47b2d338 balrog
    0x75, 0x01,                /*   Report Size (1) */
333 47b2d338 balrog
    0x95, 0x08,                /*   Report Count (8) */
334 47b2d338 balrog
    0x05, 0x07,                /*   Usage Page (Key Codes) */
335 47b2d338 balrog
    0x19, 0xe0,                /*   Usage Minimum (224) */
336 47b2d338 balrog
    0x29, 0xe7,                /*   Usage Maximum (231) */
337 47b2d338 balrog
    0x15, 0x00,                /*   Logical Minimum (0) */
338 47b2d338 balrog
    0x25, 0x01,                /*   Logical Maximum (1) */
339 47b2d338 balrog
    0x81, 0x02,                /*   Input (Data, Variable, Absolute) */
340 47b2d338 balrog
    0x95, 0x01,                /*   Report Count (1) */
341 47b2d338 balrog
    0x75, 0x08,                /*   Report Size (8) */
342 47b2d338 balrog
    0x81, 0x01,                /*   Input (Constant) */
343 47b2d338 balrog
    0x95, 0x05,                /*   Report Count (5) */
344 47b2d338 balrog
    0x75, 0x01,                /*   Report Size (1) */
345 47b2d338 balrog
    0x05, 0x08,                /*   Usage Page (LEDs) */
346 47b2d338 balrog
    0x19, 0x01,                /*   Usage Minimum (1) */
347 47b2d338 balrog
    0x29, 0x05,                /*   Usage Maximum (5) */
348 47b2d338 balrog
    0x91, 0x02,                /*   Output (Data, Variable, Absolute) */
349 47b2d338 balrog
    0x95, 0x01,                /*   Report Count (1) */
350 47b2d338 balrog
    0x75, 0x03,                /*   Report Size (3) */
351 47b2d338 balrog
    0x91, 0x01,                /*   Output (Constant) */
352 47b2d338 balrog
    0x95, 0x06,                /*   Report Count (6) */
353 47b2d338 balrog
    0x75, 0x08,                /*   Report Size (8) */
354 47b2d338 balrog
    0x15, 0x00,                /*   Logical Minimum (0) */
355 47b2d338 balrog
    0x25, 0xff,                /*   Logical Maximum (255) */
356 47b2d338 balrog
    0x05, 0x07,                /*   Usage Page (Key Codes) */
357 47b2d338 balrog
    0x19, 0x00,                /*   Usage Minimum (0) */
358 47b2d338 balrog
    0x29, 0xff,                /*   Usage Maximum (255) */
359 47b2d338 balrog
    0x81, 0x00,                /*   Input (Data, Array) */
360 47b2d338 balrog
    0xc0,                /* End Collection */
361 47b2d338 balrog
};
362 47b2d338 balrog
363 47b2d338 balrog
#define USB_HID_USAGE_ERROR_ROLLOVER        0x01
364 47b2d338 balrog
#define USB_HID_USAGE_POSTFAIL                0x02
365 47b2d338 balrog
#define USB_HID_USAGE_ERROR_UNDEFINED        0x03
366 47b2d338 balrog
367 47b2d338 balrog
/* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
368 47b2d338 balrog
 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
369 47b2d338 balrog
static const uint8_t usb_hid_usage_keys[0x100] = {
370 47b2d338 balrog
    0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
371 47b2d338 balrog
    0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
372 47b2d338 balrog
    0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
373 47b2d338 balrog
    0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
374 47b2d338 balrog
    0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
375 47b2d338 balrog
    0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
376 47b2d338 balrog
    0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
377 47b2d338 balrog
    0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
378 47b2d338 balrog
    0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
379 47b2d338 balrog
    0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
380 47b2d338 balrog
    0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
381 47b2d338 balrog
    0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
382 47b2d338 balrog
    0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
383 47b2d338 balrog
    0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
384 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
386 47b2d338 balrog
387 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
391 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
394 47b2d338 balrog
    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
396 47b2d338 balrog
    0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
397 47b2d338 balrog
    0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
398 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 47b2d338 balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 47b2d338 balrog
};
404 47b2d338 balrog
405 59ae540c bellard
static void usb_mouse_event(void *opaque,
406 59ae540c bellard
                            int dx1, int dy1, int dz1, int buttons_state)
407 59ae540c bellard
{
408 117b3ae6 pbrook
    USBHIDState *hs = opaque;
409 117b3ae6 pbrook
    USBMouseState *s = &hs->ptr;
410 59ae540c bellard
411 59ae540c bellard
    s->dx += dx1;
412 59ae540c bellard
    s->dy += dy1;
413 59ae540c bellard
    s->dz += dz1;
414 59ae540c bellard
    s->buttons_state = buttons_state;
415 117b3ae6 pbrook
    hs->changed = 1;
416 59ae540c bellard
}
417 59ae540c bellard
418 09b26c5e bellard
static void usb_tablet_event(void *opaque,
419 09b26c5e bellard
                             int x, int y, int dz, int buttons_state)
420 09b26c5e bellard
{
421 117b3ae6 pbrook
    USBHIDState *hs = opaque;
422 117b3ae6 pbrook
    USBMouseState *s = &hs->ptr;
423 09b26c5e bellard
424 09b26c5e bellard
    s->x = x;
425 09b26c5e bellard
    s->y = y;
426 09b26c5e bellard
    s->dz += dz;
427 09b26c5e bellard
    s->buttons_state = buttons_state;
428 117b3ae6 pbrook
    hs->changed = 1;
429 09b26c5e bellard
}
430 09b26c5e bellard
431 47b2d338 balrog
static void usb_keyboard_event(void *opaque, int keycode)
432 47b2d338 balrog
{
433 117b3ae6 pbrook
    USBHIDState *hs = opaque;
434 117b3ae6 pbrook
    USBKeyboardState *s = &hs->kbd;
435 47b2d338 balrog
    uint8_t hid_code, key;
436 47b2d338 balrog
    int i;
437 47b2d338 balrog
438 47b2d338 balrog
    key = keycode & 0x7f;
439 47b2d338 balrog
    hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
440 47b2d338 balrog
    s->modifiers &= ~(1 << 8);
441 47b2d338 balrog
442 117b3ae6 pbrook
    hs->changed = 1;
443 117b3ae6 pbrook
444 47b2d338 balrog
    switch (hid_code) {
445 47b2d338 balrog
    case 0x00:
446 47b2d338 balrog
        return;
447 47b2d338 balrog
448 47b2d338 balrog
    case 0xe0:
449 47b2d338 balrog
        if (s->modifiers & (1 << 9)) {
450 47b2d338 balrog
            s->modifiers ^= 3 << 8;
451 47b2d338 balrog
            return;
452 47b2d338 balrog
        }
453 47b2d338 balrog
    case 0xe1 ... 0xe7:
454 47b2d338 balrog
        if (keycode & (1 << 7)) {
455 47b2d338 balrog
            s->modifiers &= ~(1 << (hid_code & 0x0f));
456 47b2d338 balrog
            return;
457 47b2d338 balrog
        }
458 47b2d338 balrog
    case 0xe8 ... 0xef:
459 47b2d338 balrog
        s->modifiers |= 1 << (hid_code & 0x0f);
460 47b2d338 balrog
        return;
461 47b2d338 balrog
    }
462 47b2d338 balrog
463 47b2d338 balrog
    if (keycode & (1 << 7)) {
464 47b2d338 balrog
        for (i = s->keys - 1; i >= 0; i --)
465 47b2d338 balrog
            if (s->key[i] == hid_code) {
466 47b2d338 balrog
                s->key[i] = s->key[-- s->keys];
467 47b2d338 balrog
                s->key[s->keys] = 0x00;
468 47b2d338 balrog
                return;
469 47b2d338 balrog
            }
470 47b2d338 balrog
    } else {
471 47b2d338 balrog
        for (i = s->keys - 1; i >= 0; i --)
472 47b2d338 balrog
            if (s->key[i] == hid_code)
473 47b2d338 balrog
                return;
474 47b2d338 balrog
        if (s->keys < sizeof(s->key))
475 47b2d338 balrog
            s->key[s->keys ++] = hid_code;
476 47b2d338 balrog
    }
477 47b2d338 balrog
}
478 47b2d338 balrog
479 59ae540c bellard
static inline int int_clamp(int val, int vmin, int vmax)
480 59ae540c bellard
{
481 59ae540c bellard
    if (val < vmin)
482 59ae540c bellard
        return vmin;
483 59ae540c bellard
    else if (val > vmax)
484 59ae540c bellard
        return vmax;
485 59ae540c bellard
    else
486 59ae540c bellard
        return val;
487 59ae540c bellard
}
488 59ae540c bellard
489 117b3ae6 pbrook
static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
490 59ae540c bellard
{
491 59ae540c bellard
    int dx, dy, dz, b, l;
492 117b3ae6 pbrook
    USBMouseState *s = &hs->ptr;
493 59ae540c bellard
494 09b26c5e bellard
    if (!s->mouse_grabbed) {
495 117b3ae6 pbrook
        s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
496 455204eb ths
                                                  0, "QEMU USB Mouse");
497 09b26c5e bellard
        s->mouse_grabbed = 1;
498 09b26c5e bellard
    }
499 3b46e624 ths
500 976f8eef balrog
    dx = int_clamp(s->dx, -127, 127);
501 976f8eef balrog
    dy = int_clamp(s->dy, -127, 127);
502 976f8eef balrog
    dz = int_clamp(s->dz, -127, 127);
503 59ae540c bellard
504 59ae540c bellard
    s->dx -= dx;
505 59ae540c bellard
    s->dy -= dy;
506 59ae540c bellard
    s->dz -= dz;
507 3b46e624 ths
508 976f8eef balrog
    /* Appears we have to invert the wheel direction */
509 976f8eef balrog
    dz = 0 - dz;
510 976f8eef balrog
511 59ae540c bellard
    b = 0;
512 59ae540c bellard
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
513 59ae540c bellard
        b |= 0x01;
514 59ae540c bellard
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
515 59ae540c bellard
        b |= 0x02;
516 59ae540c bellard
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
517 59ae540c bellard
        b |= 0x04;
518 3b46e624 ths
519 c21c583a balrog
    l = 0;
520 c21c583a balrog
    if (len > l)
521 c21c583a balrog
        buf[l ++] = b;
522 c21c583a balrog
    if (len > l)
523 c21c583a balrog
        buf[l ++] = dx;
524 c21c583a balrog
    if (len > l)
525 c21c583a balrog
        buf[l ++] = dy;
526 c21c583a balrog
    if (len > l)
527 c21c583a balrog
        buf[l ++] = dz;
528 59ae540c bellard
    return l;
529 59ae540c bellard
}
530 59ae540c bellard
531 117b3ae6 pbrook
static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
532 09b26c5e bellard
{
533 09b26c5e bellard
    int dz, b, l;
534 117b3ae6 pbrook
    USBMouseState *s = &hs->ptr;
535 09b26c5e bellard
536 09b26c5e bellard
    if (!s->mouse_grabbed) {
537 117b3ae6 pbrook
        s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
538 455204eb ths
                                                  1, "QEMU USB Tablet");
539 09b26c5e bellard
        s->mouse_grabbed = 1;
540 09b26c5e bellard
    }
541 3b46e624 ths
542 976f8eef balrog
    dz = int_clamp(s->dz, -127, 127);
543 09b26c5e bellard
    s->dz -= dz;
544 09b26c5e bellard
545 09b26c5e bellard
    /* Appears we have to invert the wheel direction */
546 09b26c5e bellard
    dz = 0 - dz;
547 09b26c5e bellard
    b = 0;
548 09b26c5e bellard
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
549 09b26c5e bellard
        b |= 0x01;
550 09b26c5e bellard
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
551 09b26c5e bellard
        b |= 0x02;
552 09b26c5e bellard
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
553 09b26c5e bellard
        b |= 0x04;
554 09b26c5e bellard
555 09b26c5e bellard
    buf[0] = b;
556 09b26c5e bellard
    buf[1] = s->x & 0xff;
557 09b26c5e bellard
    buf[2] = s->x >> 8;
558 09b26c5e bellard
    buf[3] = s->y & 0xff;
559 09b26c5e bellard
    buf[4] = s->y >> 8;
560 09b26c5e bellard
    buf[5] = dz;
561 09b26c5e bellard
    l = 6;
562 09b26c5e bellard
563 09b26c5e bellard
    return l;
564 09b26c5e bellard
}
565 09b26c5e bellard
566 47b2d338 balrog
static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
567 47b2d338 balrog
{
568 47b2d338 balrog
    if (len < 2)
569 47b2d338 balrog
        return 0;
570 47b2d338 balrog
571 47b2d338 balrog
    buf[0] = s->modifiers & 0xff;
572 47b2d338 balrog
    buf[1] = 0;
573 47b2d338 balrog
    if (s->keys > 6)
574 47b2d338 balrog
        memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
575 47b2d338 balrog
    else
576 47b2d338 balrog
        memcpy(buf + 2, s->key, MIN(8, len) - 2);
577 47b2d338 balrog
578 47b2d338 balrog
    return MIN(8, len);
579 47b2d338 balrog
}
580 47b2d338 balrog
581 47b2d338 balrog
static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
582 47b2d338 balrog
{
583 47b2d338 balrog
    if (len > 0) {
584 47b2d338 balrog
        /* 0x01: Num Lock LED
585 47b2d338 balrog
         * 0x02: Caps Lock LED
586 47b2d338 balrog
         * 0x04: Scroll Lock LED
587 47b2d338 balrog
         * 0x08: Compose LED
588 47b2d338 balrog
         * 0x10: Kana LED */
589 47b2d338 balrog
        s->leds = buf[0];
590 47b2d338 balrog
    }
591 47b2d338 balrog
    return 0;
592 47b2d338 balrog
}
593 47b2d338 balrog
594 059809e4 bellard
static void usb_mouse_handle_reset(USBDevice *dev)
595 59ae540c bellard
{
596 47b2d338 balrog
    USBHIDState *s = (USBHIDState *)dev;
597 47b2d338 balrog
598 47b2d338 balrog
    s->ptr.dx = 0;
599 47b2d338 balrog
    s->ptr.dy = 0;
600 47b2d338 balrog
    s->ptr.dz = 0;
601 47b2d338 balrog
    s->ptr.x = 0;
602 47b2d338 balrog
    s->ptr.y = 0;
603 47b2d338 balrog
    s->ptr.buttons_state = 0;
604 47b2d338 balrog
    s->protocol = 1;
605 47b2d338 balrog
}
606 47b2d338 balrog
607 47b2d338 balrog
static void usb_keyboard_handle_reset(USBDevice *dev)
608 47b2d338 balrog
{
609 47b2d338 balrog
    USBHIDState *s = (USBHIDState *)dev;
610 47b2d338 balrog
611 926acf8f balrog
    qemu_add_kbd_event_handler(usb_keyboard_event, s);
612 47b2d338 balrog
    s->protocol = 1;
613 59ae540c bellard
}
614 59ae540c bellard
615 47b2d338 balrog
static int usb_hid_handle_control(USBDevice *dev, int request, int value,
616 59ae540c bellard
                                  int index, int length, uint8_t *data)
617 59ae540c bellard
{
618 47b2d338 balrog
    USBHIDState *s = (USBHIDState *)dev;
619 09b26c5e bellard
    int ret = 0;
620 59ae540c bellard
621 59ae540c bellard
    switch(request) {
622 59ae540c bellard
    case DeviceRequest | USB_REQ_GET_STATUS:
623 59ae540c bellard
        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
624 59ae540c bellard
            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
625 59ae540c bellard
        data[1] = 0x00;
626 59ae540c bellard
        ret = 2;
627 59ae540c bellard
        break;
628 59ae540c bellard
    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
629 59ae540c bellard
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
630 59ae540c bellard
            dev->remote_wakeup = 0;
631 59ae540c bellard
        } else {
632 59ae540c bellard
            goto fail;
633 59ae540c bellard
        }
634 59ae540c bellard
        ret = 0;
635 59ae540c bellard
        break;
636 59ae540c bellard
    case DeviceOutRequest | USB_REQ_SET_FEATURE:
637 59ae540c bellard
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
638 59ae540c bellard
            dev->remote_wakeup = 1;
639 59ae540c bellard
        } else {
640 59ae540c bellard
            goto fail;
641 59ae540c bellard
        }
642 59ae540c bellard
        ret = 0;
643 59ae540c bellard
        break;
644 59ae540c bellard
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
645 59ae540c bellard
        dev->addr = value;
646 59ae540c bellard
        ret = 0;
647 59ae540c bellard
        break;
648 59ae540c bellard
    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
649 59ae540c bellard
        switch(value >> 8) {
650 59ae540c bellard
        case USB_DT_DEVICE:
651 5fafdf24 ths
            memcpy(data, qemu_mouse_dev_descriptor,
652 59ae540c bellard
                   sizeof(qemu_mouse_dev_descriptor));
653 59ae540c bellard
            ret = sizeof(qemu_mouse_dev_descriptor);
654 59ae540c bellard
            break;
655 59ae540c bellard
        case USB_DT_CONFIG:
656 09b26c5e bellard
            if (s->kind == USB_MOUSE) {
657 5fafdf24 ths
                memcpy(data, qemu_mouse_config_descriptor,
658 09b26c5e bellard
                       sizeof(qemu_mouse_config_descriptor));
659 09b26c5e bellard
                ret = sizeof(qemu_mouse_config_descriptor);
660 09b26c5e bellard
            } else if (s->kind == USB_TABLET) {
661 5fafdf24 ths
                memcpy(data, qemu_tablet_config_descriptor,
662 09b26c5e bellard
                       sizeof(qemu_tablet_config_descriptor));
663 09b26c5e bellard
                ret = sizeof(qemu_tablet_config_descriptor);
664 47b2d338 balrog
            } else if (s->kind == USB_KEYBOARD) {
665 5fafdf24 ths
                memcpy(data, qemu_keyboard_config_descriptor,
666 47b2d338 balrog
                       sizeof(qemu_keyboard_config_descriptor));
667 47b2d338 balrog
                ret = sizeof(qemu_keyboard_config_descriptor);
668 47b2d338 balrog
            }
669 59ae540c bellard
            break;
670 59ae540c bellard
        case USB_DT_STRING:
671 59ae540c bellard
            switch(value & 0xff) {
672 59ae540c bellard
            case 0:
673 59ae540c bellard
                /* language ids */
674 59ae540c bellard
                data[0] = 4;
675 59ae540c bellard
                data[1] = 3;
676 59ae540c bellard
                data[2] = 0x09;
677 59ae540c bellard
                data[3] = 0x04;
678 59ae540c bellard
                ret = 4;
679 59ae540c bellard
                break;
680 59ae540c bellard
            case 1:
681 59ae540c bellard
                /* serial number */
682 59ae540c bellard
                ret = set_usb_string(data, "1");
683 59ae540c bellard
                break;
684 59ae540c bellard
            case 2:
685 59ae540c bellard
                /* product description */
686 47b2d338 balrog
                ret = set_usb_string(data, s->dev.devname);
687 59ae540c bellard
                break;
688 59ae540c bellard
            case 3:
689 59ae540c bellard
                /* vendor description */
690 59ae540c bellard
                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
691 59ae540c bellard
                break;
692 59ae540c bellard
            case 4:
693 59ae540c bellard
                ret = set_usb_string(data, "HID Mouse");
694 59ae540c bellard
                break;
695 59ae540c bellard
            case 5:
696 47b2d338 balrog
                ret = set_usb_string(data, "HID Tablet");
697 47b2d338 balrog
                break;
698 47b2d338 balrog
            case 6:
699 47b2d338 balrog
                ret = set_usb_string(data, "HID Keyboard");
700 47b2d338 balrog
                break;
701 47b2d338 balrog
            case 7:
702 59ae540c bellard
                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
703 59ae540c bellard
                break;
704 59ae540c bellard
            default:
705 59ae540c bellard
                goto fail;
706 59ae540c bellard
            }
707 59ae540c bellard
            break;
708 59ae540c bellard
        default:
709 59ae540c bellard
            goto fail;
710 59ae540c bellard
        }
711 59ae540c bellard
        break;
712 59ae540c bellard
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
713 59ae540c bellard
        data[0] = 1;
714 59ae540c bellard
        ret = 1;
715 59ae540c bellard
        break;
716 59ae540c bellard
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
717 59ae540c bellard
        ret = 0;
718 59ae540c bellard
        break;
719 59ae540c bellard
    case DeviceRequest | USB_REQ_GET_INTERFACE:
720 59ae540c bellard
        data[0] = 0;
721 59ae540c bellard
        ret = 1;
722 59ae540c bellard
        break;
723 59ae540c bellard
    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
724 59ae540c bellard
        ret = 0;
725 59ae540c bellard
        break;
726 59ae540c bellard
        /* hid specific requests */
727 59ae540c bellard
    case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
728 59ae540c bellard
        switch(value >> 8) {
729 59ae540c bellard
        case 0x22:
730 09b26c5e bellard
            if (s->kind == USB_MOUSE) {
731 5fafdf24 ths
                memcpy(data, qemu_mouse_hid_report_descriptor,
732 09b26c5e bellard
                       sizeof(qemu_mouse_hid_report_descriptor));
733 09b26c5e bellard
                ret = sizeof(qemu_mouse_hid_report_descriptor);
734 09b26c5e bellard
            } else if (s->kind == USB_TABLET) {
735 5fafdf24 ths
                memcpy(data, qemu_tablet_hid_report_descriptor,
736 09b26c5e bellard
                       sizeof(qemu_tablet_hid_report_descriptor));
737 09b26c5e bellard
                ret = sizeof(qemu_tablet_hid_report_descriptor);
738 47b2d338 balrog
            } else if (s->kind == USB_KEYBOARD) {
739 5fafdf24 ths
                memcpy(data, qemu_keyboard_hid_report_descriptor,
740 47b2d338 balrog
                       sizeof(qemu_keyboard_hid_report_descriptor));
741 47b2d338 balrog
                ret = sizeof(qemu_keyboard_hid_report_descriptor);
742 47b2d338 balrog
            }
743 47b2d338 balrog
            break;
744 59ae540c bellard
        default:
745 59ae540c bellard
            goto fail;
746 59ae540c bellard
        }
747 59ae540c bellard
        break;
748 59ae540c bellard
    case GET_REPORT:
749 09b26c5e bellard
        if (s->kind == USB_MOUSE)
750 117b3ae6 pbrook
            ret = usb_mouse_poll(s, data, length);
751 09b26c5e bellard
        else if (s->kind == USB_TABLET)
752 117b3ae6 pbrook
            ret = usb_tablet_poll(s, data, length);
753 47b2d338 balrog
        else if (s->kind == USB_KEYBOARD)
754 47b2d338 balrog
            ret = usb_keyboard_poll(&s->kbd, data, length);
755 47b2d338 balrog
        break;
756 47b2d338 balrog
    case SET_REPORT:
757 47b2d338 balrog
        if (s->kind == USB_KEYBOARD)
758 47b2d338 balrog
            ret = usb_keyboard_write(&s->kbd, data, length);
759 47b2d338 balrog
        else
760 47b2d338 balrog
            goto fail;
761 47b2d338 balrog
        break;
762 47b2d338 balrog
    case GET_PROTOCOL:
763 47b2d338 balrog
        if (s->kind != USB_KEYBOARD)
764 47b2d338 balrog
            goto fail;
765 47b2d338 balrog
        ret = 1;
766 47b2d338 balrog
        data[0] = s->protocol;
767 47b2d338 balrog
        break;
768 47b2d338 balrog
    case SET_PROTOCOL:
769 47b2d338 balrog
        if (s->kind != USB_KEYBOARD)
770 47b2d338 balrog
            goto fail;
771 47b2d338 balrog
        ret = 0;
772 47b2d338 balrog
        s->protocol = value;
773 47b2d338 balrog
        break;
774 47b2d338 balrog
    case GET_IDLE:
775 47b2d338 balrog
        ret = 1;
776 47b2d338 balrog
        data[0] = s->idle;
777 59ae540c bellard
        break;
778 59ae540c bellard
    case SET_IDLE:
779 47b2d338 balrog
        s->idle = value;
780 59ae540c bellard
        ret = 0;
781 59ae540c bellard
        break;
782 59ae540c bellard
    default:
783 59ae540c bellard
    fail:
784 59ae540c bellard
        ret = USB_RET_STALL;
785 59ae540c bellard
        break;
786 59ae540c bellard
    }
787 59ae540c bellard
    return ret;
788 59ae540c bellard
}
789 59ae540c bellard
790 47b2d338 balrog
static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
791 59ae540c bellard
{
792 47b2d338 balrog
    USBHIDState *s = (USBHIDState *)dev;
793 09b26c5e bellard
    int ret = 0;
794 59ae540c bellard
795 4d611c9a pbrook
    switch(p->pid) {
796 59ae540c bellard
    case USB_TOKEN_IN:
797 4d611c9a pbrook
        if (p->devep == 1) {
798 117b3ae6 pbrook
            /* TODO: Implement finite idle delays.  */
799 117b3ae6 pbrook
            if (!(s->changed || s->idle))
800 117b3ae6 pbrook
                return USB_RET_NAK;
801 117b3ae6 pbrook
            s->changed = 0;
802 47b2d338 balrog
            if (s->kind == USB_MOUSE)
803 117b3ae6 pbrook
                ret = usb_mouse_poll(s, p->data, p->len);
804 47b2d338 balrog
            else if (s->kind == USB_TABLET)
805 117b3ae6 pbrook
                ret = usb_tablet_poll(s, p->data, p->len);
806 47b2d338 balrog
            else if (s->kind == USB_KEYBOARD)
807 47b2d338 balrog
                ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
808 59ae540c bellard
        } else {
809 59ae540c bellard
            goto fail;
810 59ae540c bellard
        }
811 59ae540c bellard
        break;
812 59ae540c bellard
    case USB_TOKEN_OUT:
813 59ae540c bellard
    default:
814 59ae540c bellard
    fail:
815 59ae540c bellard
        ret = USB_RET_STALL;
816 59ae540c bellard
        break;
817 59ae540c bellard
    }
818 59ae540c bellard
    return ret;
819 59ae540c bellard
}
820 59ae540c bellard
821 47b2d338 balrog
static void usb_hid_handle_destroy(USBDevice *dev)
822 059809e4 bellard
{
823 47b2d338 balrog
    USBHIDState *s = (USBHIDState *)dev;
824 059809e4 bellard
825 47b2d338 balrog
    if (s->kind != USB_KEYBOARD)
826 47b2d338 balrog
        qemu_remove_mouse_event_handler(s->ptr.eh_entry);
827 47b2d338 balrog
    /* TODO: else */
828 059809e4 bellard
    qemu_free(s);
829 059809e4 bellard
}
830 059809e4 bellard
831 09b26c5e bellard
USBDevice *usb_tablet_init(void)
832 09b26c5e bellard
{
833 47b2d338 balrog
    USBHIDState *s;
834 09b26c5e bellard
835 47b2d338 balrog
    s = qemu_mallocz(sizeof(USBHIDState));
836 09b26c5e bellard
    if (!s)
837 09b26c5e bellard
        return NULL;
838 09b26c5e bellard
    s->dev.speed = USB_SPEED_FULL;
839 09b26c5e bellard
    s->dev.handle_packet = usb_generic_handle_packet;
840 09b26c5e bellard
841 09b26c5e bellard
    s->dev.handle_reset = usb_mouse_handle_reset;
842 47b2d338 balrog
    s->dev.handle_control = usb_hid_handle_control;
843 47b2d338 balrog
    s->dev.handle_data = usb_hid_handle_data;
844 47b2d338 balrog
    s->dev.handle_destroy = usb_hid_handle_destroy;
845 09b26c5e bellard
    s->kind = USB_TABLET;
846 117b3ae6 pbrook
    /* Force poll routine to be run and grab input the first time.  */
847 117b3ae6 pbrook
    s->changed = 1;
848 09b26c5e bellard
849 1f6e24e7 bellard
    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
850 1f6e24e7 bellard
851 09b26c5e bellard
    return (USBDevice *)s;
852 09b26c5e bellard
}
853 09b26c5e bellard
854 59ae540c bellard
USBDevice *usb_mouse_init(void)
855 59ae540c bellard
{
856 47b2d338 balrog
    USBHIDState *s;
857 59ae540c bellard
858 47b2d338 balrog
    s = qemu_mallocz(sizeof(USBHIDState));
859 59ae540c bellard
    if (!s)
860 59ae540c bellard
        return NULL;
861 59ae540c bellard
    s->dev.speed = USB_SPEED_FULL;
862 59ae540c bellard
    s->dev.handle_packet = usb_generic_handle_packet;
863 59ae540c bellard
864 59ae540c bellard
    s->dev.handle_reset = usb_mouse_handle_reset;
865 47b2d338 balrog
    s->dev.handle_control = usb_hid_handle_control;
866 47b2d338 balrog
    s->dev.handle_data = usb_hid_handle_data;
867 47b2d338 balrog
    s->dev.handle_destroy = usb_hid_handle_destroy;
868 09b26c5e bellard
    s->kind = USB_MOUSE;
869 117b3ae6 pbrook
    /* Force poll routine to be run and grab input the first time.  */
870 117b3ae6 pbrook
    s->changed = 1;
871 59ae540c bellard
872 1f6e24e7 bellard
    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
873 1f6e24e7 bellard
874 59ae540c bellard
    return (USBDevice *)s;
875 59ae540c bellard
}
876 47b2d338 balrog
877 47b2d338 balrog
USBDevice *usb_keyboard_init(void)
878 47b2d338 balrog
{
879 47b2d338 balrog
    USBHIDState *s;
880 47b2d338 balrog
881 47b2d338 balrog
    s = qemu_mallocz(sizeof(USBHIDState));
882 47b2d338 balrog
    if (!s)
883 47b2d338 balrog
        return NULL;
884 47b2d338 balrog
    s->dev.speed = USB_SPEED_FULL;
885 47b2d338 balrog
    s->dev.handle_packet = usb_generic_handle_packet;
886 47b2d338 balrog
887 47b2d338 balrog
    s->dev.handle_reset = usb_keyboard_handle_reset;
888 47b2d338 balrog
    s->dev.handle_control = usb_hid_handle_control;
889 47b2d338 balrog
    s->dev.handle_data = usb_hid_handle_data;
890 47b2d338 balrog
    s->dev.handle_destroy = usb_hid_handle_destroy;
891 47b2d338 balrog
    s->kind = USB_KEYBOARD;
892 47b2d338 balrog
893 47b2d338 balrog
    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
894 47b2d338 balrog
895 47b2d338 balrog
    return (USBDevice *) s;
896 47b2d338 balrog
}