Michael Tokarev ?????:
> After some debugging and debugging, with a help
> Hollis Blanchard on #...@freenode, I discovered
> that kvm (or, rather, qemu) does not work correctly
> with serial ports, at least on linux. One problem
> report has already here, author Cc'd -- see e.g.
> http://marc.info/?l=kvm&m=122995568009533&w=2 .
>
> Here's what's going on.
>
> When opening a host's port, kvm resets the status
> lines, doing this:
>
> ioctl(13, TIOCMGET, [TIOCM_DTR|TIOCM_RTS|TIOCM_CTS|TIOCM_DSR|0x4000])
> ioctl(13, TIOCMSET, [TIOCM_DTR|TIOCM_RTS])
>
> which results in the following set
>
> ioctl(13, TIOCMGET, [TIOCM_DTR|TIOCM_RTS|TIOCM_CTS|TIOCM_DSR])
Here's the possible solution (NotAPAtch(tm)):
In kvm-xx/qemu/qemu-char.c:
case CHR_IOCTL_SERIAL_SET_TIOCM:
{
int sarg = *(int *)arg;
int targ = 0; <==== change this 0 to 0x4000
if (sarg | CHR_TIOCM_DTR)
targ |= TIOCM_DTR;
if (sarg | CHR_TIOCM_RTS)
targ |= TIOCM_RTS;
ioctl(s->fd_in, TIOCMSET, &targ);
}
break;
This is obviously a hack, esp. since this bit is not
always present even on linux (after reading 8250.c
driver).
Real fix will be, I guess, to read the full set
first, and combine it with DTR|RTS received from
guest, something like this:
case CHR_IOCTL_SERIAL_SET_TIOCM:
{
int sarg = *(int *)arg;
int targ = 0;
ioctl(s->fd_in, TIOCMGET, &targ);
if (!(sarg | CHR_TIOCM_DTR))
targ &= ~TIOCM_DTR;
if (!(sarg | CHR_TIOCM_RTS))
targ ~= ~TIOCM_RTS;
ioctl(s->fd_in, TIOCMSET, &targ);
}
break;
I.e., to always keep all the other bits, but
allow changing DTR and RTS.
Again, I don't know how it's linux-specific, but
it seems the solution above should work on other
platforms just fine.
/mjt
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html