Revision abb8a139 hw/usb-serial.c
b/hw/usb-serial.c | ||
---|---|---|
47 | 47 |
|
48 | 48 |
/* SET_MDM_CTRL */ |
49 | 49 |
|
50 |
#define FTDI_MDM_CTRL 3 |
|
51 | 50 |
#define FTDI_DTR 1 |
51 |
#define FTDI_SET_DTR (FTDI_DTR << 8) |
|
52 | 52 |
#define FTDI_RTS 2 |
53 |
#define FTDI_SET_RTS (FTDI_RTS << 8) |
|
53 | 54 |
|
54 | 55 |
/* SET_FLOW_CTRL */ |
55 | 56 |
|
... | ... | |
99 | 100 |
uint8_t event_chr; |
100 | 101 |
uint8_t error_chr; |
101 | 102 |
uint8_t event_trigger; |
102 |
uint8_t lines; |
|
103 | 103 |
QEMUSerialSetParams params; |
104 | 104 |
int latency; /* ms */ |
105 | 105 |
CharDriverState *cs; |
... | ... | |
178 | 178 |
s->recv_ptr = 0; |
179 | 179 |
s->recv_used = 0; |
180 | 180 |
/* TODO: purge in char driver */ |
181 |
s->lines &= ~(FTDI_DTR|FTDI_RTS); |
|
182 | 181 |
} |
183 | 182 |
|
184 | 183 |
static void usb_serial_handle_reset(USBDevice *dev) |
... | ... | |
191 | 190 |
/* TODO: Reset char device, send BREAK? */ |
192 | 191 |
} |
193 | 192 |
|
193 |
static uint8_t usb_get_modem_lines(USBSerialState *s) |
|
194 |
{ |
|
195 |
int flags; |
|
196 |
uint8_t ret; |
|
197 |
|
|
198 |
if (qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) |
|
199 |
return FTDI_CTS|FTDI_DSR|FTDI_RLSD; |
|
200 |
|
|
201 |
ret = 0; |
|
202 |
if (flags & CHR_TIOCM_CTS) |
|
203 |
ret |= FTDI_CTS; |
|
204 |
if (flags & CHR_TIOCM_DSR) |
|
205 |
ret |= FTDI_DSR; |
|
206 |
if (flags & CHR_TIOCM_RI) |
|
207 |
ret |= FTDI_RI; |
|
208 |
if (flags & CHR_TIOCM_CAR) |
|
209 |
ret |= FTDI_RLSD; |
|
210 |
|
|
211 |
return ret; |
|
212 |
} |
|
213 |
|
|
194 | 214 |
static int usb_serial_handle_control(USBDevice *dev, int request, int value, |
195 | 215 |
int index, int length, uint8_t *data) |
196 | 216 |
{ |
... | ... | |
306 | 326 |
} |
307 | 327 |
break; |
308 | 328 |
case DeviceOutVendor | FTDI_SET_MDM_CTRL: |
309 |
s->lines = value & FTDI_MDM_CTRL; |
|
329 |
{ |
|
330 |
static int flags; |
|
331 |
qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); |
|
332 |
if (value & FTDI_SET_RTS) { |
|
333 |
if (value & FTDI_RTS) |
|
334 |
flags |= CHR_TIOCM_RTS; |
|
335 |
else |
|
336 |
flags &= ~CHR_TIOCM_RTS; |
|
337 |
} |
|
338 |
if (value & FTDI_SET_DTR) { |
|
339 |
if (value & FTDI_DTR) |
|
340 |
flags |= CHR_TIOCM_DTR; |
|
341 |
else |
|
342 |
flags &= ~CHR_TIOCM_DTR; |
|
343 |
} |
|
344 |
qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); |
|
310 | 345 |
break; |
346 |
} |
|
311 | 347 |
case DeviceOutVendor | FTDI_SET_FLOW_CTRL: |
312 | 348 |
/* TODO: ioctl */ |
313 | 349 |
break; |
... | ... | |
357 | 393 |
/* TODO: TX ON/OFF */ |
358 | 394 |
break; |
359 | 395 |
case DeviceInVendor | FTDI_GET_MDM_ST: |
360 |
/* TODO: return modem status */
|
|
361 |
data[0] = 0;
|
|
362 |
ret = 1;
|
|
396 |
data[0] = usb_get_modem_lines(s) | 1;
|
|
397 |
data[1] = 0;
|
|
398 |
ret = 2;
|
|
363 | 399 |
break; |
364 | 400 |
case DeviceOutVendor | FTDI_SET_EVENT_CHR: |
365 | 401 |
/* TODO: handle it */ |
... | ... | |
409 | 445 |
ret = USB_RET_NAK; |
410 | 446 |
break; |
411 | 447 |
} |
412 |
/* TODO: Report serial line status */
|
|
413 |
*data++ = 0;
|
|
448 |
*data++ = usb_get_modem_lines(s) | 1;
|
|
449 |
/* We do not have the uart details */
|
|
414 | 450 |
*data++ = 0; |
415 | 451 |
len -= 2; |
416 | 452 |
if (len > s->recv_used) |
Also available in: Unified diff