8250: Customized base baudrate
[qemu] / hw / usb.c
1 /*
2  * QEMU USB emulation
3  *
4  * Copyright (c) 2005 Fabrice Bellard
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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
22  * THE SOFTWARE.
23  */
24 #include "qemu-common.h"
25 #include "usb.h"
26
27 void usb_attach(USBPort *port, USBDevice *dev)
28 {
29     port->attach(port, dev);
30 }
31
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
35    protocol)
36 */
37
38 #define SETUP_STATE_IDLE 0
39 #define SETUP_STATE_DATA 1
40 #define SETUP_STATE_ACK  2
41
42 int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
43 {
44     int l, ret = 0;
45     int len = p->len;
46     uint8_t *data = p->data;
47
48     switch(p->pid) {
49     case USB_MSG_ATTACH:
50         s->state = USB_STATE_ATTACHED;
51         break;
52     case USB_MSG_DETACH:
53         s->state = USB_STATE_NOTATTACHED;
54         break;
55     case USB_MSG_RESET:
56         s->remote_wakeup = 0;
57         s->addr = 0;
58         s->state = USB_STATE_DEFAULT;
59         s->handle_reset(s);
60         break;
61     case USB_TOKEN_SETUP:
62         if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
63             return USB_RET_NODEV;
64         if (len != 8)
65             goto fail;
66         memcpy(s->setup_buf, data, 8);
67         s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
68         s->setup_index = 0;
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],
74                                     s->setup_len,
75                                     s->data_buf);
76             if (ret < 0)
77                 return ret;
78             if (ret < s->setup_len)
79                 s->setup_len = ret;
80             s->setup_state = SETUP_STATE_DATA;
81         } else {
82             if (s->setup_len == 0)
83                 s->setup_state = SETUP_STATE_ACK;
84             else
85                 s->setup_state = SETUP_STATE_DATA;
86         }
87         break;
88     case USB_TOKEN_IN:
89         if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
90             return USB_RET_NODEV;
91         switch(p->devep) {
92         case 0:
93             switch(s->setup_state) {
94             case SETUP_STATE_ACK:
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],
101                                       s->setup_len,
102                                       s->data_buf);
103                     if (ret > 0)
104                         ret = 0;
105                 } else {
106                     /* return 0 byte */
107                 }
108                 break;
109             case SETUP_STATE_DATA:
110                 if (s->setup_buf[0] & USB_DIR_IN) {
111                     l = s->setup_len - s->setup_index;
112                     if (l > len)
113                         l = len;
114                     memcpy(data, s->data_buf + s->setup_index, l);
115                     s->setup_index += l;
116                     if (s->setup_index >= s->setup_len)
117                         s->setup_state = SETUP_STATE_ACK;
118                     ret = l;
119                 } else {
120                     s->setup_state = SETUP_STATE_IDLE;
121                     goto fail;
122                 }
123                 break;
124             default:
125                 goto fail;
126             }
127             break;
128         default:
129             ret = s->handle_data(s, p);
130             break;
131         }
132         break;
133     case USB_TOKEN_OUT:
134         if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
135             return USB_RET_NODEV;
136         switch(p->devep) {
137         case 0:
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;
142                     /* transfer OK */
143                 } else {
144                     /* ignore additional output */
145                 }
146                 break;
147             case SETUP_STATE_DATA:
148                 if (!(s->setup_buf[0] & USB_DIR_IN)) {
149                     l = s->setup_len - s->setup_index;
150                     if (l > len)
151                         l = len;
152                     memcpy(s->data_buf + s->setup_index, data, l);
153                     s->setup_index += l;
154                     if (s->setup_index >= s->setup_len)
155                         s->setup_state = SETUP_STATE_ACK;
156                     ret = l;
157                 } else {
158                     s->setup_state = SETUP_STATE_IDLE;
159                     goto fail;
160                 }
161                 break;
162             default:
163                 goto fail;
164             }
165             break;
166         default:
167             ret = s->handle_data(s, p);
168             break;
169         }
170         break;
171     default:
172     fail:
173         ret = USB_RET_STALL;
174         break;
175     }
176     return ret;
177 }
178
179 /* XXX: fix overflow */
180 int set_usb_string(uint8_t *buf, const char *str)
181 {
182     int len, i;
183     uint8_t *q;
184
185     q = buf;
186     len = strlen(str);
187     *q++ = 2 * len + 2;
188     *q++ = 3;
189     for(i = 0; i < len; i++) {
190         *q++ = str[i];
191         *q++ = 0;
192     }
193     return q - buf;
194 }
195
196 /* Send an internal message to a USB device.  */
197 void usb_send_msg(USBDevice *dev, int msg)
198 {
199     USBPacket p;
200     memset(&p, 0, sizeof(p));
201     p.pid = msg;
202     dev->handle_packet(dev, &p);
203 }
204