Commit abb8a13918ecc1e8160aa78582de9d5224ea70df

Authored by aurel32
1 parent f88e4b91

usb-serial: add support for modem lines

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4998 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 45 additions and 9 deletions
hw/usb-serial.c
@@ -47,9 +47,10 @@ do { printf(&quot;usb-serial: &quot; fmt , ##args); } while (0) @@ -47,9 +47,10 @@ do { printf(&quot;usb-serial: &quot; fmt , ##args); } while (0)
47 47
48 /* SET_MDM_CTRL */ 48 /* SET_MDM_CTRL */
49 49
50 -#define FTDI_MDM_CTRL 3  
51 #define FTDI_DTR 1 50 #define FTDI_DTR 1
  51 +#define FTDI_SET_DTR (FTDI_DTR << 8)
52 #define FTDI_RTS 2 52 #define FTDI_RTS 2
  53 +#define FTDI_SET_RTS (FTDI_RTS << 8)
53 54
54 /* SET_FLOW_CTRL */ 55 /* SET_FLOW_CTRL */
55 56
@@ -99,7 +100,6 @@ typedef struct { @@ -99,7 +100,6 @@ typedef struct {
99 uint8_t event_chr; 100 uint8_t event_chr;
100 uint8_t error_chr; 101 uint8_t error_chr;
101 uint8_t event_trigger; 102 uint8_t event_trigger;
102 - uint8_t lines;  
103 QEMUSerialSetParams params; 103 QEMUSerialSetParams params;
104 int latency; /* ms */ 104 int latency; /* ms */
105 CharDriverState *cs; 105 CharDriverState *cs;
@@ -178,7 +178,6 @@ static void usb_serial_reset(USBSerialState *s) @@ -178,7 +178,6 @@ static void usb_serial_reset(USBSerialState *s)
178 s->recv_ptr = 0; 178 s->recv_ptr = 0;
179 s->recv_used = 0; 179 s->recv_used = 0;
180 /* TODO: purge in char driver */ 180 /* TODO: purge in char driver */
181 - s->lines &= ~(FTDI_DTR|FTDI_RTS);  
182 } 181 }
183 182
184 static void usb_serial_handle_reset(USBDevice *dev) 183 static void usb_serial_handle_reset(USBDevice *dev)
@@ -191,6 +190,27 @@ static void usb_serial_handle_reset(USBDevice *dev) @@ -191,6 +190,27 @@ static void usb_serial_handle_reset(USBDevice *dev)
191 /* TODO: Reset char device, send BREAK? */ 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 static int usb_serial_handle_control(USBDevice *dev, int request, int value, 214 static int usb_serial_handle_control(USBDevice *dev, int request, int value,
195 int index, int length, uint8_t *data) 215 int index, int length, uint8_t *data)
196 { 216 {
@@ -306,8 +326,24 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, @@ -306,8 +326,24 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value,
306 } 326 }
307 break; 327 break;
308 case DeviceOutVendor | FTDI_SET_MDM_CTRL: 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 break; 345 break;
  346 + }
311 case DeviceOutVendor | FTDI_SET_FLOW_CTRL: 347 case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
312 /* TODO: ioctl */ 348 /* TODO: ioctl */
313 break; 349 break;
@@ -357,9 +393,9 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, @@ -357,9 +393,9 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value,
357 /* TODO: TX ON/OFF */ 393 /* TODO: TX ON/OFF */
358 break; 394 break;
359 case DeviceInVendor | FTDI_GET_MDM_ST: 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 break; 399 break;
364 case DeviceOutVendor | FTDI_SET_EVENT_CHR: 400 case DeviceOutVendor | FTDI_SET_EVENT_CHR:
365 /* TODO: handle it */ 401 /* TODO: handle it */
@@ -409,8 +445,8 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) @@ -409,8 +445,8 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
409 ret = USB_RET_NAK; 445 ret = USB_RET_NAK;
410 break; 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 *data++ = 0; 450 *data++ = 0;
415 len -= 2; 451 len -= 2;
416 if (len > s->recv_used) 452 if (len > s->recv_used)