|
|
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: {
1.1.1.7 ! root 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: }
1.1 root 57: }
58:
59: /**********************/
1.1.1.5 root 60:
1.1 root 61: /* generic USB device helpers (you are not forced to use them when
62: writing your USB device driver, but they help handling the
1.1.1.4 root 63: protocol)
1.1 root 64: */
65:
66: #define SETUP_STATE_IDLE 0
67: #define SETUP_STATE_DATA 1
68: #define SETUP_STATE_ACK 2
69:
1.1.1.5 root 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) {
1.1.1.6 root 87: ret = s->info->handle_control(s, request, value, index,
88: s->setup_len, s->data_buf);
1.1.1.5 root 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 == 0)
97: s->setup_state = SETUP_STATE_ACK;
98: else
99: s->setup_state = SETUP_STATE_DATA;
100: }
101:
102: return ret;
103: }
104:
105: static int do_token_in(USBDevice *s, USBPacket *p)
106: {
107: int request, value, index;
108: int ret = 0;
109:
110: if (p->devep != 0)
1.1.1.6 root 111: return s->info->handle_data(s, p);
1.1.1.5 root 112:
113: request = (s->setup_buf[0] << 8) | s->setup_buf[1];
114: value = (s->setup_buf[3] << 8) | s->setup_buf[2];
115: index = (s->setup_buf[5] << 8) | s->setup_buf[4];
116:
117: switch(s->setup_state) {
118: case SETUP_STATE_ACK:
119: if (!(s->setup_buf[0] & USB_DIR_IN)) {
120: s->setup_state = SETUP_STATE_IDLE;
1.1.1.6 root 121: ret = s->info->handle_control(s, request, value, index,
122: s->setup_len, s->data_buf);
1.1.1.5 root 123: if (ret > 0)
124: return 0;
125: return ret;
126: }
127:
128: /* return 0 byte */
129: return 0;
130:
131: case SETUP_STATE_DATA:
132: if (s->setup_buf[0] & USB_DIR_IN) {
133: int len = s->setup_len - s->setup_index;
134: if (len > p->len)
135: len = p->len;
136: memcpy(p->data, s->data_buf + s->setup_index, len);
137: s->setup_index += len;
138: if (s->setup_index >= s->setup_len)
139: s->setup_state = SETUP_STATE_ACK;
140: return len;
141: }
142:
143: s->setup_state = SETUP_STATE_IDLE;
144: return USB_RET_STALL;
145:
146: default:
147: return USB_RET_STALL;
148: }
149: }
150:
151: static int do_token_out(USBDevice *s, USBPacket *p)
1.1 root 152: {
1.1.1.5 root 153: if (p->devep != 0)
1.1.1.6 root 154: return s->info->handle_data(s, p);
1.1.1.5 root 155:
156: switch(s->setup_state) {
157: case SETUP_STATE_ACK:
158: if (s->setup_buf[0] & USB_DIR_IN) {
159: s->setup_state = SETUP_STATE_IDLE;
160: /* transfer OK */
161: } else {
162: /* ignore additional output */
163: }
164: return 0;
1.1 root 165:
1.1.1.5 root 166: case SETUP_STATE_DATA:
167: if (!(s->setup_buf[0] & USB_DIR_IN)) {
168: int len = s->setup_len - s->setup_index;
169: if (len > p->len)
170: len = p->len;
171: memcpy(s->data_buf + s->setup_index, p->data, len);
172: s->setup_index += len;
173: if (s->setup_index >= s->setup_len)
174: s->setup_state = SETUP_STATE_ACK;
175: return len;
176: }
177:
178: s->setup_state = SETUP_STATE_IDLE;
179: return USB_RET_STALL;
180:
181: default:
182: return USB_RET_STALL;
183: }
184: }
185:
186: /*
187: * Generic packet handler.
188: * Called by the HC (host controller).
189: *
190: * Returns length of the transaction or one of the USB_RET_XXX codes.
191: */
192: int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
193: {
1.1.1.3 root 194: switch(p->pid) {
1.1 root 195: case USB_MSG_ATTACH:
196: s->state = USB_STATE_ATTACHED;
1.1.1.7 ! root 197: if (s->info->handle_attach) {
! 198: s->info->handle_attach(s);
! 199: }
1.1.1.5 root 200: return 0;
201:
1.1 root 202: case USB_MSG_DETACH:
203: s->state = USB_STATE_NOTATTACHED;
1.1.1.5 root 204: return 0;
205:
1.1 root 206: case USB_MSG_RESET:
207: s->remote_wakeup = 0;
208: s->addr = 0;
209: s->state = USB_STATE_DEFAULT;
1.1.1.7 ! root 210: if (s->info->handle_reset) {
! 211: s->info->handle_reset(s);
! 212: }
1.1.1.5 root 213: return 0;
214: }
215:
216: /* Rest of the PIDs must match our address */
217: if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
218: return USB_RET_NODEV;
219:
220: switch (p->pid) {
1.1 root 221: case USB_TOKEN_SETUP:
1.1.1.5 root 222: return do_token_setup(s, p);
223:
1.1 root 224: case USB_TOKEN_IN:
1.1.1.5 root 225: return do_token_in(s, p);
226:
1.1 root 227: case USB_TOKEN_OUT:
1.1.1.5 root 228: return do_token_out(s, p);
229:
1.1 root 230: default:
1.1.1.5 root 231: return USB_RET_STALL;
1.1 root 232: }
233: }
234:
235: /* XXX: fix overflow */
236: int set_usb_string(uint8_t *buf, const char *str)
237: {
238: int len, i;
239: uint8_t *q;
240:
241: q = buf;
242: len = strlen(str);
1.1.1.2 root 243: *q++ = 2 * len + 2;
1.1 root 244: *q++ = 3;
245: for(i = 0; i < len; i++) {
246: *q++ = str[i];
247: *q++ = 0;
248: }
249: return q - buf;
250: }
1.1.1.3 root 251:
252: /* Send an internal message to a USB device. */
253: void usb_send_msg(USBDevice *dev, int msg)
254: {
255: USBPacket p;
256: memset(&p, 0, sizeof(p));
257: p.pid = msg;
1.1.1.6 root 258: dev->info->handle_packet(dev, &p);
1.1.1.3 root 259:
1.1.1.5 root 260: /* This _must_ be synchronous */
261: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.