On ppc32 make tb_set_jmp_target1 behave like it does on a ppc64
[qemu/mini2440.git] / hw / usb-serial.c
blobb666c99be78664f31674b1b8901cceb7f6fd7410
1 /*
2 * FTDI FT232BM Device emulation
4 * Copyright (c) 2006 CodeSourcery.
5 * Copyright (c) 2008 Samuel Thibault <samuel.thibault@ens-lyon.org>
6 * Written by Paul Brook, reused for FTDI by Samuel Thibault
8 * This code is licenced under the LGPL.
9 */
11 #include "qemu-common.h"
12 #include "usb.h"
13 #include "qemu-char.h"
15 //#define DEBUG_Serial
17 #ifdef DEBUG_Serial
18 #define DPRINTF(fmt, args...) \
19 do { printf("usb-serial: " fmt , ##args); } while (0)
20 #else
21 #define DPRINTF(fmt, args...) do {} while(0)
22 #endif
24 #define RECV_BUF 384
25 #define SEND_BUF 128 // Not used for now
27 /* Commands */
28 #define FTDI_RESET 0
29 #define FTDI_SET_MDM_CTRL 1
30 #define FTDI_SET_FLOW_CTRL 2
31 #define FTDI_SET_BAUD 3
32 #define FTDI_SET_DATA 4
33 #define FTDI_GET_MDM_ST 5
34 #define FTDI_SET_EVENT_CHR 6
35 #define FTDI_SET_ERROR_CHR 7
36 #define FTDI_SET_LATENCY 9
37 #define FTDI_GET_LATENCY 10
39 #define DeviceOutVendor ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
40 #define DeviceInVendor ((USB_DIR_IN |USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
42 /* RESET */
44 #define FTDI_RESET_SIO 0
45 #define FTDI_RESET_RX 1
46 #define FTDI_RESET_TX 2
48 /* SET_MDM_CTRL */
50 #define FTDI_MDM_CTRL 3
51 #define FTDI_DTR 1
52 #define FTDI_RTS 2
54 /* SET_FLOW_CTRL */
56 #define FTDI_RTS_CTS_HS 1
57 #define FTDI_DTR_DSR_HS 2
58 #define FTDI_XON_XOFF_HS 4
60 /* SET_DATA */
62 #define FTDI_PARITY (0x7 << 8)
63 #define FTDI_ODD (0x1 << 8)
64 #define FTDI_EVEN (0x2 << 8)
65 #define FTDI_MARK (0x3 << 8)
66 #define FTDI_SPACE (0x4 << 8)
68 #define FTDI_STOP (0x3 << 11)
69 #define FTDI_STOP1 (0x0 << 11)
70 #define FTDI_STOP15 (0x1 << 11)
71 #define FTDI_STOP2 (0x2 << 11)
73 /* GET_MDM_ST */
74 /* TODO: should be sent every 40ms */
75 #define FTDI_CTS (1<<4) // CTS line status
76 #define FTDI_DSR (1<<5) // DSR line status
77 #define FTDI_RI (1<<6) // RI line status
78 #define FTDI_RLSD (1<<7) // Receive Line Signal Detect
80 /* Status */
82 #define FTDI_DR (1<<0) // Data Ready
83 #define FTDI_OE (1<<1) // Overrun Err
84 #define FTDI_PE (1<<2) // Parity Err
85 #define FTDI_FE (1<<3) // Framing Err
86 #define FTDI_BI (1<<4) // Break Interrupt
87 #define FTDI_THRE (1<<5) // Transmitter Holding Register
88 #define FTDI_TEMT (1<<6) // Transmitter Empty
89 #define FTDI_FIFO (1<<7) // Error in FIFO
91 typedef struct {
92 USBDevice dev;
93 uint16_t vendorid;
94 uint16_t productid;
95 uint8_t recv_buf[RECV_BUF];
96 uint8_t recv_ptr;
97 uint8_t recv_used;
98 uint8_t send_buf[SEND_BUF];
99 uint8_t event_chr;
100 uint8_t error_chr;
101 uint8_t event_trigger;
102 uint8_t lines;
103 QEMUSerialSetParams params;
104 int latency; /* ms */
105 CharDriverState *cs;
106 } USBSerialState;
108 static const uint8_t qemu_serial_dev_descriptor[] = {
109 0x12, /* u8 bLength; */
110 0x01, /* u8 bDescriptorType; Device */
111 0x00, 0x02, /* u16 bcdUSB; v2.0 */
113 0x00, /* u8 bDeviceClass; */
114 0x00, /* u8 bDeviceSubClass; */
115 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
116 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
118 /* Vendor and product id are arbitrary. */
119 0x03, 0x04, /* u16 idVendor; */
120 0x00, 0xFF, /* u16 idProduct; */
121 0x00, 0x04, /* u16 bcdDevice */
123 0x01, /* u8 iManufacturer; */
124 0x02, /* u8 iProduct; */
125 0x03, /* u8 iSerialNumber; */
126 0x01 /* u8 bNumConfigurations; */
129 static const uint8_t qemu_serial_config_descriptor[] = {
131 /* one configuration */
132 0x09, /* u8 bLength; */
133 0x02, /* u8 bDescriptorType; Configuration */
134 0x20, 0x00, /* u16 wTotalLength; */
135 0x01, /* u8 bNumInterfaces; (1) */
136 0x01, /* u8 bConfigurationValue; */
137 0x00, /* u8 iConfiguration; */
138 0x80, /* u8 bmAttributes;
139 Bit 7: must be set,
140 6: Self-powered,
141 5: Remote wakeup,
142 4..0: resvd */
143 100/2, /* u8 MaxPower; */
145 /* one interface */
146 0x09, /* u8 if_bLength; */
147 0x04, /* u8 if_bDescriptorType; Interface */
148 0x00, /* u8 if_bInterfaceNumber; */
149 0x00, /* u8 if_bAlternateSetting; */
150 0x02, /* u8 if_bNumEndpoints; */
151 0xff, /* u8 if_bInterfaceClass; Vendor Specific */
152 0xff, /* u8 if_bInterfaceSubClass; Vendor Specific */
153 0xff, /* u8 if_bInterfaceProtocol; Vendor Specific */
154 0x02, /* u8 if_iInterface; */
156 /* Bulk-In endpoint */
157 0x07, /* u8 ep_bLength; */
158 0x05, /* u8 ep_bDescriptorType; Endpoint */
159 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
160 0x02, /* u8 ep_bmAttributes; Bulk */
161 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
162 0x00, /* u8 ep_bInterval; */
164 /* Bulk-Out endpoint */
165 0x07, /* u8 ep_bLength; */
166 0x05, /* u8 ep_bDescriptorType; Endpoint */
167 0x02, /* u8 ep_bEndpointAddress; OUT Endpoint 2 */
168 0x02, /* u8 ep_bmAttributes; Bulk */
169 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
170 0x00 /* u8 ep_bInterval; */
173 static void usb_serial_reset(USBSerialState *s)
175 /* TODO: Set flow control to none */
176 s->event_chr = 0x0d;
177 s->event_trigger = 0;
178 s->recv_ptr = 0;
179 s->recv_used = 0;
180 /* TODO: purge in char driver */
181 s->lines &= ~(FTDI_DTR|FTDI_RTS);
184 static void usb_serial_handle_reset(USBDevice *dev)
186 USBSerialState *s = (USBSerialState *)dev;
188 DPRINTF("Reset\n");
190 usb_serial_reset(s);
191 /* TODO: Reset char device, send BREAK? */
194 static int usb_serial_handle_control(USBDevice *dev, int request, int value,
195 int index, int length, uint8_t *data)
197 USBSerialState *s = (USBSerialState *)dev;
198 int ret = 0;
200 //DPRINTF("got control %x, value %x\n",request, value);
201 switch (request) {
202 case DeviceRequest | USB_REQ_GET_STATUS:
203 data[0] = (0 << USB_DEVICE_SELF_POWERED) |
204 (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
205 data[1] = 0x00;
206 ret = 2;
207 break;
208 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
209 if (value == USB_DEVICE_REMOTE_WAKEUP) {
210 dev->remote_wakeup = 0;
211 } else {
212 goto fail;
214 ret = 0;
215 break;
216 case DeviceOutRequest | USB_REQ_SET_FEATURE:
217 if (value == USB_DEVICE_REMOTE_WAKEUP) {
218 dev->remote_wakeup = 1;
219 } else {
220 goto fail;
222 ret = 0;
223 break;
224 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
225 dev->addr = value;
226 ret = 0;
227 break;
228 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
229 switch(value >> 8) {
230 case USB_DT_DEVICE:
231 memcpy(data, qemu_serial_dev_descriptor,
232 sizeof(qemu_serial_dev_descriptor));
233 data[8] = s->vendorid & 0xff;
234 data[9] = ((s->vendorid) >> 8) & 0xff;
235 data[10] = s->productid & 0xff;
236 data[11] = ((s->productid) >> 8) & 0xff;
237 ret = sizeof(qemu_serial_dev_descriptor);
238 break;
239 case USB_DT_CONFIG:
240 memcpy(data, qemu_serial_config_descriptor,
241 sizeof(qemu_serial_config_descriptor));
242 ret = sizeof(qemu_serial_config_descriptor);
243 break;
244 case USB_DT_STRING:
245 switch(value & 0xff) {
246 case 0:
247 /* language ids */
248 data[0] = 4;
249 data[1] = 3;
250 data[2] = 0x09;
251 data[3] = 0x04;
252 ret = 4;
253 break;
254 case 1:
255 /* vendor description */
256 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
257 break;
258 case 2:
259 /* product description */
260 ret = set_usb_string(data, "QEMU USB SERIAL");
261 break;
262 case 3:
263 /* serial number */
264 ret = set_usb_string(data, "1");
265 break;
266 default:
267 goto fail;
269 break;
270 default:
271 goto fail;
273 break;
274 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
275 data[0] = 1;
276 ret = 1;
277 break;
278 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
279 ret = 0;
280 break;
281 case DeviceRequest | USB_REQ_GET_INTERFACE:
282 data[0] = 0;
283 ret = 1;
284 break;
285 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
286 ret = 0;
287 break;
288 case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
289 ret = 0;
290 break;
292 /* Class specific requests. */
293 case DeviceOutVendor | FTDI_RESET:
294 switch (value) {
295 case FTDI_RESET_SIO:
296 usb_serial_reset(s);
297 break;
298 case FTDI_RESET_RX:
299 s->recv_ptr = 0;
300 s->recv_used = 0;
301 /* TODO: purge from char device */
302 break;
303 case FTDI_RESET_TX:
304 /* TODO: purge from char device */
305 break;
307 break;
308 case DeviceOutVendor | FTDI_SET_MDM_CTRL:
309 s->lines = value & FTDI_MDM_CTRL;
310 break;
311 case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
312 /* TODO: ioctl */
313 break;
314 case DeviceOutVendor | FTDI_SET_BAUD: {
315 static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 };
316 int subdivisor8 = subdivisors8[((value & 0xc000) >> 14)
317 | ((index & 1) << 2)];
318 int divisor = value & 0x3fff;
320 /* chip special cases */
321 if (divisor == 1 && subdivisor8 == 0)
322 subdivisor8 = 4;
323 if (divisor == 0 && subdivisor8 == 0)
324 divisor = 1;
326 s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8);
327 qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
328 break;
330 case DeviceOutVendor | FTDI_SET_DATA:
331 switch (value & FTDI_PARITY) {
332 case 0:
333 s->params.parity = 'N';
334 break;
335 case FTDI_ODD:
336 s->params.parity = 'O';
337 break;
338 case FTDI_EVEN:
339 s->params.parity = 'E';
340 break;
341 default:
342 DPRINTF("unsupported parity %d\n", value & FTDI_PARITY);
343 goto fail;
345 switch (value & FTDI_STOP) {
346 case FTDI_STOP1:
347 s->params.stop_bits = 1;
348 break;
349 case FTDI_STOP2:
350 s->params.stop_bits = 2;
351 break;
352 default:
353 DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
354 goto fail;
356 qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
357 /* TODO: TX ON/OFF */
358 break;
359 case DeviceInVendor | FTDI_GET_MDM_ST:
360 /* TODO: return modem status */
361 data[0] = 0;
362 ret = 1;
363 break;
364 case DeviceOutVendor | FTDI_SET_EVENT_CHR:
365 /* TODO: handle it */
366 s->event_chr = value;
367 break;
368 case DeviceOutVendor | FTDI_SET_ERROR_CHR:
369 /* TODO: handle it */
370 s->error_chr = value;
371 break;
372 case DeviceOutVendor | FTDI_SET_LATENCY:
373 s->latency = value;
374 break;
375 case DeviceInVendor | FTDI_GET_LATENCY:
376 data[0] = s->latency;
377 ret = 1;
378 break;
379 default:
380 fail:
381 DPRINTF("got unsupported/bogus control %x, value %x\n", request, value);
382 ret = USB_RET_STALL;
383 break;
385 return ret;
388 static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
390 USBSerialState *s = (USBSerialState *)dev;
391 int ret = 0;
392 uint8_t devep = p->devep;
393 uint8_t *data = p->data;
394 int len = p->len;
395 int first_len;
397 switch (p->pid) {
398 case USB_TOKEN_OUT:
399 if (devep != 2)
400 goto fail;
401 qemu_chr_write(s->cs, data, len);
402 break;
404 case USB_TOKEN_IN:
405 if (devep != 1)
406 goto fail;
407 first_len = RECV_BUF - s->recv_ptr;
408 if (len <= 2) {
409 ret = USB_RET_NAK;
410 break;
412 /* TODO: Report serial line status */
413 *data++ = 0;
414 *data++ = 0;
415 len -= 2;
416 if (len > s->recv_used)
417 len = s->recv_used;
418 if (!len) {
419 ret = USB_RET_NAK;
420 break;
422 if (first_len > len)
423 first_len = len;
424 memcpy(data, s->recv_buf + s->recv_ptr, first_len);
425 if (len > first_len)
426 memcpy(data + first_len, s->recv_buf, len - first_len);
427 s->recv_used -= len;
428 s->recv_ptr = (s->recv_ptr + len) % RECV_BUF;
429 ret = len + 2;
430 break;
432 default:
433 DPRINTF("Bad token\n");
434 fail:
435 ret = USB_RET_STALL;
436 break;
439 return ret;
442 static void usb_serial_handle_destroy(USBDevice *dev)
444 USBSerialState *s = (USBSerialState *)dev;
446 qemu_chr_close(s->cs);
447 qemu_free(s);
450 int usb_serial_can_read(void *opaque)
452 USBSerialState *s = opaque;
453 return RECV_BUF - s->recv_used;
456 void usb_serial_read(void *opaque, const uint8_t *buf, int size)
458 USBSerialState *s = opaque;
459 int first_size = RECV_BUF - s->recv_ptr;
460 if (first_size > size)
461 first_size = size;
462 memcpy(s->recv_buf + s->recv_ptr + s->recv_used, buf, first_size);
463 if (size > first_size)
464 memcpy(s->recv_buf, buf + first_size, size - first_size);
465 s->recv_used += size;
468 void usb_serial_event(void *opaque, int event)
470 USBSerialState *s = opaque;
472 switch (event) {
473 case CHR_EVENT_BREAK:
474 /* TODO: Send Break to USB */
475 break;
476 case CHR_EVENT_FOCUS:
477 break;
478 case CHR_EVENT_RESET:
479 usb_serial_reset(s);
480 /* TODO: Reset USB port */
481 break;
485 USBDevice *usb_serial_init(const char *filename)
487 USBSerialState *s;
488 CharDriverState *cdrv;
489 unsigned short vendorid = 0x0403, productid = 0x6001;
491 while (*filename && *filename != ':') {
492 const char *p;
493 char *e;
494 if (strstart(filename, "vendorid=", &p)) {
495 vendorid = strtol(p, &e, 16);
496 if (e == p || (*e && *e != ',' && *e != ':')) {
497 printf("bogus vendor ID %s\n", p);
498 return NULL;
500 filename = e;
501 } else if (strstart(filename, "productid=", &p)) {
502 productid = strtol(p, &e, 16);
503 if (e == p || (*e && *e != ',' && *e != ':')) {
504 printf("bogus product ID %s\n", p);
505 return NULL;
507 filename = e;
508 } else {
509 printf("unrecognized serial USB option %s\n", filename);
510 return NULL;
512 while(*filename == ',')
513 filename++;
515 if (!*filename) {
516 printf("character device specification needed\n");
517 return NULL;
519 filename++;
520 s = qemu_mallocz(sizeof(USBSerialState));
521 if (!s)
522 return NULL;
524 cdrv = qemu_chr_open(filename);
525 if (!cdrv)
526 goto fail;
527 s->cs = cdrv;
528 qemu_chr_add_handlers(cdrv, usb_serial_can_read, usb_serial_read, usb_serial_event, s);
530 s->dev.speed = USB_SPEED_FULL;
531 s->dev.handle_packet = usb_generic_handle_packet;
533 s->dev.handle_reset = usb_serial_handle_reset;
534 s->dev.handle_control = usb_serial_handle_control;
535 s->dev.handle_data = usb_serial_handle_data;
536 s->dev.handle_destroy = usb_serial_handle_destroy;
538 s->vendorid = vendorid;
539 s->productid = productid;
541 snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Serial(%.16s)",
542 filename);
544 usb_serial_handle_reset((USBDevice *)s);
545 return (USBDevice *)s;
546 fail:
547 qemu_free(s);
548 return NULL;