4
* Copyright (c) 2005 Fabrice Bellard
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
#include "qemu-common.h"
27
void usb_attach(USBPort *port, USBDevice *dev)
29
port->attach(port, dev);
32
/**********************/
33
/* generic USB device helpers (you are not forced to use them when
34
writing your USB device driver, but they help handling the
38
#define SETUP_STATE_IDLE 0
39
#define SETUP_STATE_DATA 1
40
#define SETUP_STATE_ACK 2
42
int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
46
uint8_t *data = p->data;
50
s->state = USB_STATE_ATTACHED;
53
s->state = USB_STATE_NOTATTACHED;
58
s->state = USB_STATE_DEFAULT;
62
if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
66
memcpy(s->setup_buf, data, 8);
67
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
69
if (s->setup_buf[0] & USB_DIR_IN) {
70
ret = s->handle_control(s,
71
(s->setup_buf[0] << 8) | s->setup_buf[1],
72
(s->setup_buf[3] << 8) | s->setup_buf[2],
73
(s->setup_buf[5] << 8) | s->setup_buf[4],
78
if (ret < s->setup_len)
80
s->setup_state = SETUP_STATE_DATA;
82
if (s->setup_len == 0)
83
s->setup_state = SETUP_STATE_ACK;
85
s->setup_state = SETUP_STATE_DATA;
89
if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
93
switch(s->setup_state) {
95
if (!(s->setup_buf[0] & USB_DIR_IN)) {
96
s->setup_state = SETUP_STATE_IDLE;
97
ret = s->handle_control(s,
98
(s->setup_buf[0] << 8) | s->setup_buf[1],
99
(s->setup_buf[3] << 8) | s->setup_buf[2],
100
(s->setup_buf[5] << 8) | s->setup_buf[4],
109
case SETUP_STATE_DATA:
110
if (s->setup_buf[0] & USB_DIR_IN) {
111
l = s->setup_len - s->setup_index;
114
memcpy(data, s->data_buf + s->setup_index, l);
116
if (s->setup_index >= s->setup_len)
117
s->setup_state = SETUP_STATE_ACK;
120
s->setup_state = SETUP_STATE_IDLE;
129
ret = s->handle_data(s, p);
134
if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
135
return USB_RET_NODEV;
138
switch(s->setup_state) {
139
case SETUP_STATE_ACK:
140
if (s->setup_buf[0] & USB_DIR_IN) {
141
s->setup_state = SETUP_STATE_IDLE;
144
/* ignore additional output */
147
case SETUP_STATE_DATA:
148
if (!(s->setup_buf[0] & USB_DIR_IN)) {
149
l = s->setup_len - s->setup_index;
152
memcpy(s->data_buf + s->setup_index, data, l);
154
if (s->setup_index >= s->setup_len)
155
s->setup_state = SETUP_STATE_ACK;
158
s->setup_state = SETUP_STATE_IDLE;
167
ret = s->handle_data(s, p);
179
/* XXX: fix overflow */
180
int set_usb_string(uint8_t *buf, const char *str)
189
for(i = 0; i < len; i++) {
196
/* Send an internal message to a USB device. */
197
void usb_send_msg(USBDevice *dev, int msg)
200
memset(&p, 0, sizeof(p));
202
dev->handle_packet(dev, &p);