Re: more about serial ports: do they even work?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I don't recall seeing a followup to this post.

To put Michael's second suggestion into patch form, the following fixes
the problem for me:

--- kvm-81.orig/qemu/qemu-char.c        2008-12-14 06:16:27.000000000 -0700
+++ kvm-81/qemu/qemu-char.c     2009-02-02 14:12:20.000000000 -0700
@@ -1078,20 +1078,21 @@
             if (sarg | TIOCM_DTR)
                 *targ |= CHR_TIOCM_DTR;
             if (sarg | TIOCM_RTS)
                 *targ |= CHR_TIOCM_RTS;
         }
         break;
     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;
     default:
         return -ENOTSUP;
     }

Is this approach palatable to folks?

david


Michael Tokarev wrote:
> Michael Tokarev ?????:
>> After some debugging and debugging, with a help
>> Hollis Blanchard on #kvm@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
>         {
>             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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux