Revision 4c15ba9c hw/milkymist-softusb.c

b/hw/milkymist-softusb.c
25 25
#include "sysbus.h"
26 26
#include "trace.h"
27 27
#include "console.h"
28
#include "usb.h"
28
#include "hid.h"
29 29
#include "qemu-error.h"
30 30

  
31 31
enum {
......
46 46

  
47 47
struct MilkymistSoftUsbState {
48 48
    SysBusDevice busdev;
49
    USBBus usbbus;
50
    USBPort usbport[2];
51
    USBDevice *usbdev;
49
    HIDState hid_kbd;
50
    HIDState hid_mouse;
52 51

  
53 52
    qemu_irq irq;
54 53

  
......
62 61
    uint32_t regs[R_MAX];
63 62

  
64 63
    /* mouse state */
65
    int mouse_dx;
66
    int mouse_dy;
67
    int mouse_dz;
68
    uint8_t mouse_buttons_state;
64
    uint8_t mouse_hid_buffer[4];
69 65

  
70 66
    /* keyboard state */
71
    uint8_t kbd_usb_buffer[8];
67
    uint8_t kbd_hid_buffer[8];
72 68
};
73 69
typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
74 70

  
......
177 173
static void softusb_mouse_changed(MilkymistSoftUsbState *s)
178 174
{
179 175
    uint8_t m;
180
    uint8_t buf[4];
181

  
182
    buf[0] = s->mouse_buttons_state;
183
    buf[1] = s->mouse_dx;
184
    buf[2] = s->mouse_dy;
185
    buf[3] = s->mouse_dz;
186 176

  
187 177
    softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
188 178
    trace_milkymist_softusb_mevt(m);
189
    softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, buf, 4);
179
    softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4);
190 180
    m = (m + 1) & 0xf;
191 181
    softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
192 182

  
......
200 190

  
201 191
    softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
202 192
    trace_milkymist_softusb_kevt(m);
203
    softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_usb_buffer, 8);
193
    softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8);
204 194
    m = (m + 1) & 0x7;
205 195
    softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
206 196

  
......
208 198
    qemu_irq_pulse(s->irq);
209 199
}
210 200

  
211
static void softusb_mouse_event(void *opaque,
212
       int dx, int dy, int dz, int buttons_state)
201
static void softusb_kbd_hid_datain(HIDState *hs)
213 202
{
214
    MilkymistSoftUsbState *s = opaque;
203
    MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd);
204
    int len;
215 205

  
216 206
    /* if device is in reset, do nothing */
217 207
    if (s->regs[R_CTRL] & CTRL_RESET) {
218 208
        return;
219 209
    }
220 210

  
221
    trace_milkymist_softusb_mouse_event(dx, dy, dz, buttons_state);
211
    len = hid_keyboard_poll(hs, s->kbd_hid_buffer, sizeof(s->kbd_hid_buffer));
222 212

  
223
    s->mouse_dx = dx;
224
    s->mouse_dy = dy;
225
    s->mouse_dz = dz;
226
    s->mouse_buttons_state = buttons_state;
227

  
228
    softusb_mouse_changed(s);
213
    if (len == 8) {
214
        softusb_kbd_changed(s);
215
    }
229 216
}
230 217

  
231
static void softusb_usbdev_datain(void *opaque)
218
static void softusb_mouse_hid_datain(HIDState *hs)
232 219
{
233
    MilkymistSoftUsbState *s = opaque;
234

  
235
    USBPacket p;
236

  
237
    usb_packet_init(&p);
238
    usb_packet_setup(&p, USB_TOKEN_IN, 0, 1);
239
    usb_packet_addbuf(&p, s->kbd_usb_buffer, sizeof(s->kbd_usb_buffer));
240
    s->usbdev->info->handle_data(s->usbdev, &p);
241
    usb_packet_cleanup(&p);
242

  
243
    softusb_kbd_changed(s);
244
}
220
    MilkymistSoftUsbState *s =
221
            container_of(hs, MilkymistSoftUsbState, hid_mouse);
222
    int len;
245 223

  
246
static void softusb_attach(USBPort *port)
247
{
248
}
224
    /* if device is in reset, do nothing */
225
    if (s->regs[R_CTRL] & CTRL_RESET) {
226
        return;
227
    }
249 228

  
250
static void softusb_detach(USBPort *port)
251
{
252
}
229
    len = hid_pointer_poll(hs, s->mouse_hid_buffer,
230
            sizeof(s->mouse_hid_buffer));
253 231

  
254
static void softusb_child_detach(USBPort *port, USBDevice *child)
255
{
232
    if (len == 4) {
233
        softusb_mouse_changed(s);
234
    }
256 235
}
257 236

  
258
static USBPortOps softusb_ops = {
259
    .attach = softusb_attach,
260
    .detach = softusb_detach,
261
    .child_detach = softusb_child_detach,
262
};
263

  
264
static USBBusOps softusb_bus_ops = {
265
};
266

  
267 237
static void milkymist_softusb_reset(DeviceState *d)
268 238
{
269 239
    MilkymistSoftUsbState *s =
......
273 243
    for (i = 0; i < R_MAX; i++) {
274 244
        s->regs[i] = 0;
275 245
    }
276
    s->mouse_dx = 0;
277
    s->mouse_dy = 0;
278
    s->mouse_dz = 0;
279
    s->mouse_buttons_state = 0;
280
    memset(s->kbd_usb_buffer, 0, sizeof(s->kbd_usb_buffer));
246
    memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer));
247
    memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer));
248

  
249
    hid_reset(&s->hid_kbd);
250
    hid_reset(&s->hid_mouse);
281 251

  
282 252
    /* defaults */
283 253
    s->regs[R_CTRL] = CTRL_RESET;
......
304 274
    cpu_register_physical_memory(s->dmem_base, s->dmem_size,
305 275
            dmem_ram | IO_MEM_RAM);
306 276

  
307
    qemu_add_mouse_event_handler(softusb_mouse_event, s, 0, "Milkymist Mouse");
308

  
309
    /* create our usb bus */
310
    usb_bus_new(&s->usbbus, &softusb_bus_ops, NULL);
311

  
312
    /* our two ports */
313
    /* FIXME: claim to support full speed devices. qemu mouse and keyboard
314
     * report themselves as full speed devices. */
315
    usb_register_port(&s->usbbus, &s->usbport[0], NULL, 0, &softusb_ops,
316
            USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
317
    usb_register_port(&s->usbbus, &s->usbport[1], NULL, 1, &softusb_ops,
318
            USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
319

  
320
    /* and finally create an usb keyboard */
321
    s->usbdev = usb_create_simple(&s->usbbus, "usb-kbd");
322
    usb_hid_datain_cb(s->usbdev, s, softusb_usbdev_datain);
323
    s->usbdev->info->handle_reset(s->usbdev);
277
    hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
278
    hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
324 279

  
325 280
    return 0;
326 281
}
......
332 287
    .minimum_version_id_old = 1,
333 288
    .fields      = (VMStateField[]) {
334 289
        VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX),
335
        VMSTATE_INT32(mouse_dx, MilkymistSoftUsbState),
336
        VMSTATE_INT32(mouse_dy, MilkymistSoftUsbState),
337
        VMSTATE_INT32(mouse_dz, MilkymistSoftUsbState),
338
        VMSTATE_UINT8(mouse_buttons_state, MilkymistSoftUsbState),
339
        VMSTATE_BUFFER(kbd_usb_buffer, MilkymistSoftUsbState),
290
        VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState),
291
        VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState),
292
        VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState),
293
        VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState),
340 294
        VMSTATE_END_OF_LIST()
341 295
    }
342 296
};

Also available in: Unified diff