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