|
|
1.1 root 1: /*
2: * QEMU USB emulation
3: *
4: * Copyright (c) 2005 Fabrice Bellard
1.1.1.4 root 5: *
1.1.1.5 root 6: * 2008 Generic packet handler rewrite by Max Krasnyansky
7: *
1.1 root 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: */
1.1.1.4 root 26: #include "qemu-common.h"
27: #include "usb.h"
1.1 root 28:
29: void usb_attach(USBPort *port, USBDevice *dev)
30: {
31: port->attach(port, dev);
32: }
33:
34: /**********************/
1.1.1.5 root 35:
1.1 root 36: /* generic USB device helpers (you are not forced to use them when
37: writing your USB device driver, but they help handling the
1.1.1.4 root 38: protocol)
1.1 root 39: */
40:
41: #define SETUP_STATE_IDLE 0
42: #define SETUP_STATE_DATA 1
43: #define SETUP_STATE_ACK 2
44:
1.1.1.5 root 45: static int do_token_setup(USBDevice *s, USBPacket *p)
46: {
47: int request, value, index;
48: int ret = 0;
49:
50: if (p->len != 8)
51: return USB_RET_STALL;
52:
53: memcpy(s->setup_buf, p->data, 8);
54: s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
55: s->setup_index = 0;
56:
57: request = (s->setup_buf[0] << 8) | s->setup_buf[1];
58: value = (s->setup_buf[3] << 8) | s->setup_buf[2];
59: index = (s->setup_buf[5] << 8) | s->setup_buf[4];
60:
61: if (s->setup_buf[0] & USB_DIR_IN) {
1.1.1.6 ! root 62: ret = s->info->handle_control(s, request, value, index,
! 63: s->setup_len, s->data_buf);
1.1.1.5 root 64: if (ret < 0)
65: return ret;
66:
67: if (ret < s->setup_len)
68: s->setup_len = ret;
69: s->setup_state = SETUP_STATE_DATA;
70: } else {
71: if (s->setup_len == 0)
72: s->setup_state = SETUP_STATE_ACK;
73: else
74: s->setup_state = SETUP_STATE_DATA;
75: }
76:
77: return ret;
78: }
79:
80: static int do_token_in(USBDevice *s, USBPacket *p)
81: {
82: int request, value, index;
83: int ret = 0;
84:
85: if (p->devep != 0)
1.1.1.6 ! root 86: return s->info->handle_data(s, p);
1.1.1.5 root 87:
88: request = (s->setup_buf[0] << 8) | s->setup_buf[1];
89: value = (s->setup_buf[3] << 8) | s->setup_buf[2];
90: index = (s->setup_buf[5] << 8) | s->setup_buf[4];
91:
92: switch(s->setup_state) {
93: case SETUP_STATE_ACK:
94: if (!(s->setup_buf[0] & USB_DIR_IN)) {
95: s->setup_state = SETUP_STATE_IDLE;
1.1.1.6 ! root 96: ret = s->info->handle_control(s, request, value, index,
! 97: s->setup_len, s->data_buf);
1.1.1.5 root 98: if (ret > 0)
99: return 0;
100: return ret;
101: }
102:
103: /* return 0 byte */
104: return 0;
105:
106: case SETUP_STATE_DATA:
107: if (s->setup_buf[0] & USB_DIR_IN) {
108: int len = s->setup_len - s->setup_index;
109: if (len > p->len)
110: len = p->len;
111: memcpy(p->data, s->data_buf + s->setup_index, len);
112: s->setup_index += len;
113: if (s->setup_index >= s->setup_len)
114: s->setup_state = SETUP_STATE_ACK;
115: return len;
116: }
117:
118: s->setup_state = SETUP_STATE_IDLE;
119: return USB_RET_STALL;
120:
121: default:
122: return USB_RET_STALL;
123: }
124: }
125:
126: static int do_token_out(USBDevice *s, USBPacket *p)
1.1 root 127: {
1.1.1.5 root 128: if (p->devep != 0)
1.1.1.6 ! root 129: return s->info->handle_data(s, p);
1.1.1.5 root 130:
131: switch(s->setup_state) {
132: case SETUP_STATE_ACK:
133: if (s->setup_buf[0] & USB_DIR_IN) {
134: s->setup_state = SETUP_STATE_IDLE;
135: /* transfer OK */
136: } else {
137: /* ignore additional output */
138: }
139: return 0;
1.1 root 140:
1.1.1.5 root 141: case SETUP_STATE_DATA:
142: if (!(s->setup_buf[0] & USB_DIR_IN)) {
143: int len = s->setup_len - s->setup_index;
144: if (len > p->len)
145: len = p->len;
146: memcpy(s->data_buf + s->setup_index, p->data, len);
147: s->setup_index += len;
148: if (s->setup_index >= s->setup_len)
149: s->setup_state = SETUP_STATE_ACK;
150: return len;
151: }
152:
153: s->setup_state = SETUP_STATE_IDLE;
154: return USB_RET_STALL;
155:
156: default:
157: return USB_RET_STALL;
158: }
159: }
160:
161: /*
162: * Generic packet handler.
163: * Called by the HC (host controller).
164: *
165: * Returns length of the transaction or one of the USB_RET_XXX codes.
166: */
167: int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
168: {
1.1.1.3 root 169: switch(p->pid) {
1.1 root 170: case USB_MSG_ATTACH:
171: s->state = USB_STATE_ATTACHED;
1.1.1.5 root 172: return 0;
173:
1.1 root 174: case USB_MSG_DETACH:
175: s->state = USB_STATE_NOTATTACHED;
1.1.1.5 root 176: return 0;
177:
1.1 root 178: case USB_MSG_RESET:
179: s->remote_wakeup = 0;
180: s->addr = 0;
181: s->state = USB_STATE_DEFAULT;
1.1.1.6 ! root 182: s->info->handle_reset(s);
1.1.1.5 root 183: return 0;
184: }
185:
186: /* Rest of the PIDs must match our address */
187: if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
188: return USB_RET_NODEV;
189:
190: switch (p->pid) {
1.1 root 191: case USB_TOKEN_SETUP:
1.1.1.5 root 192: return do_token_setup(s, p);
193:
1.1 root 194: case USB_TOKEN_IN:
1.1.1.5 root 195: return do_token_in(s, p);
196:
1.1 root 197: case USB_TOKEN_OUT:
1.1.1.5 root 198: return do_token_out(s, p);
199:
1.1 root 200: default:
1.1.1.5 root 201: return USB_RET_STALL;
1.1 root 202: }
203: }
204:
205: /* XXX: fix overflow */
206: int set_usb_string(uint8_t *buf, const char *str)
207: {
208: int len, i;
209: uint8_t *q;
210:
211: q = buf;
212: len = strlen(str);
1.1.1.2 root 213: *q++ = 2 * len + 2;
1.1 root 214: *q++ = 3;
215: for(i = 0; i < len; i++) {
216: *q++ = str[i];
217: *q++ = 0;
218: }
219: return q - buf;
220: }
1.1.1.3 root 221:
222: /* Send an internal message to a USB device. */
223: void usb_send_msg(USBDevice *dev, int msg)
224: {
225: USBPacket p;
226: memset(&p, 0, sizeof(p));
227: p.pid = msg;
1.1.1.6 ! root 228: dev->info->handle_packet(dev, &p);
1.1.1.3 root 229:
1.1.1.5 root 230: /* This _must_ be synchronous */
231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.