From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BwXoQ-0005GI-Hk for qemu-devel@nongnu.org; Sun, 15 Aug 2004 23:05:30 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BwXoO-0005Fi-TK for qemu-devel@nongnu.org; Sun, 15 Aug 2004 23:05:29 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BwXoO-0005Fe-Ow for qemu-devel@nongnu.org; Sun, 15 Aug 2004 23:05:28 -0400 Received: from [64.142.19.5] (helo=b.mail.sonic.net) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1BwXkC-0008Ll-Gj for qemu-devel@nongnu.org; Sun, 15 Aug 2004 23:01:08 -0400 Received: from 192.168.0.102 (adsl-68-123-27-193.dsl.pltn13.pacbell.net [68.123.27.193]) (authenticated bits=0) by b.mail.sonic.net (8.12.11/8.12.11) with ESMTP id i7G316a3010783 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Sun, 15 Aug 2004 20:01:07 -0700 From: Nile Geisinger Date: Sun, 15 Aug 2004 19:52:43 +0000 MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Message-Id: <200408151952.43815.nile@dloo.com> Subject: [Qemu-devel] A different serial port question Reply-To: nile@dloo.com, qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hi everyone, I asked the following question earlier on the list, but was Warnocked :]. T= he=20 question was a little detailed, but that was to make it simple to answer.=20 It's probably an obvious solution to a reader here, so thanks in advance fo= r=20 any help. thanks, Nile =2D------------------------------------------------------------------------= =2D------------------- I want to send data from the host qemu program to a guest kernel and back. This has a number of benefits for everyone. One of the most obvious i= s=20 users can output to a log on the host system easily (guest to host). Another benefit is that the host can inform the guest if its shutting down so it can shut down as well (host to guest).=20 To accomplish this, I've created by own serial device and am trying to send= =20 data back and forth between guest and host operating systems. At the moment= ,=20 I have it working sending data from Linux to my serial device in qemu, but= =20 am only intermittently successful going the other way -- i.e., I'm having=20 difficulty getting all of the data I think I'm putting in the serial device read by the Linux OS.=20 I've tried very hard to simplify my approach. Although I could use one=20 dual-channel serial port, I'm intentionally using two (one for reading, one= =20 for writing) to narrow down on the problem.=20 I start by adding both serial devices as follows in pc.c: // Initialize serial port (ttyS1) serial_init(0x2f8, 3, 0); // Initialize serial port (ttyS2) serial_init(0x3e8, 11, 0); I also added code in serial_init to initialize the devices (Here's the code= =20 for ttyS1, though I don't think this is where the problem is): if =A0(irq =3D=3D 3) { =A0=A0=A0=A0=A0=A0=A0=A0 =A0/* Create the communication file. */ =A0=A0=A0=A0=A0=A0=A0=A0 =A0unlink("mycom.txt"); =A0=A0=A0=A0=A0=A0=A0=A0 =A0input_writeptr =3D fopen("mycom.txt", "w"); =A0=A0=A0=A0=A0=A0=A0=A0 =A0fclose(input_writeptr); =A0=A0=A0=A0=A0=A0=A0=A0 =A0/* Open up our communication file for non-block= ing reading */ =A0=A0=A0=A0=A0=A0=A0=A0 =A0input_readfd =3D open("mycom.txt", O_RDONLY | O= _NONBLOCK); =A0 =A0 =A0 =A0 =A0 input_layer =3D s; =A0 =A0 =A0 =A0 =A0 qemu_add_fd_read_handler(input_readfd, serial_can_recei= ve1,=20 serial_receive1, s); =A0=A0=A0=A0=A0=A0=A0=A0 =A0/* Open up our communication file for writing. = */ =A0=A0=A0=A0=A0=A0=A0=A0 =A0input_writefd =3D open("mycom.txt", O_WRONLY); =A0=A0=A0=A0=A0=A0=A0=A0 =A0s->out_fd =3D input_writefd ; } Linux correctly recognizes both of the serial ports on booting.=20 On the client side, the C code that sends information from the linux os=20 through port (ttyS2) to the qemu program works correctly and I've written=20 code in qemu that prints it out.=20 However, the code that sends information from the qemu program through ttyS= 1=20 to the Linux operating system has some bug I'm missing. Data gets dropped intermittently. I think I am making either one of two problems: sending=20 information in qemu wrong to that serial device or reading it wrong in the = C=20 code on the linux side. This may be based on the fact that I'm new to seria= l=20 port programming and qemu.=20 Here are the two places I've tried sending information from qemu: =2D> in the inner loop of vl.c as it cycles through devices and performs it= s=20 read and then calls fd_read I pass it the info I want to send. For example: =A0=A0=A0=A0=A0=A0=A0=A0// Don't touch regular devices =A0=A0=A0=A0=A0=A0=A0=A0if (ioh->opaque !=3D my_output_device) =A0=A0=A0=A0=A0=A0=A0=A0{ =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0n =3D read(ioh->fd, buf, io= h->max_size); =A0=A0=A0=A0=A0=A0=A0=A0} =A0=A0=A0=A0=A0=A0=A0=A0// This is our device: Directly set n and the input= buffer so that=20 fd_read=20 can =A0=A0=A0=A0=A0=A0=A0=A0// be passed them. =A0=A0=A0=A0=A0=A0=A0=A0else { =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0n =3D strlen(myinfo); =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0strcpy(buf, myinfo, n); =A0=A0=A0=A0=A0=A0=A0=A0} =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =2D> Alternatively, in serial_ioport_read when that specific device is call= ed=20 with case 0, I change the variable 'ret' to the character I want to send. F= or=20 example: =A0=A0=A0=A0=A0=A0=A0=A0if (s !=3D my_output_device) =A0=A0=A0=A0=A0=A0=A0=A0{ =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0ret =3D s->rbr; // Original= code =A0=A0=A0=A0=A0=A0=A0=A0} =A0=A0=A0=A0=A0=A0=A0=A0else =A0=A0=A0=A0=A0=A0=A0=A0{ =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0ret =3D get_character_to_se= nd(); =A0// Directly set the variable=20 'ret' =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0s->rbr =3D ret; =A0=A0=A0=A0=A0=A0=A0=A0} =A0=A0=A0=A0=A0=A0=A0=A0 Either way, the result is that data is dropped somewhere from where qemu is sending it here to the program on the linux client trying to read it. Th= e=20 linux C code will read a few continuous bytes of information, then skip 10= =20 bytes, read a few more and skip another random set of bytes. My code on the= =20 linux side also seems fairly standard: =A0=A0=A0=A0=A0=A0=A0=A0fd =3D open(argv[1], O_RDONLY); =A0=A0=A0=A0=A0=A0=A0=A0tcgetattr(fd, tp); =A0 =A0 =A0 =A0 tp.c_cflag =3D CS8|CLOCAL|baud|CREAD; =A0 =A0 =A0 =A0 tp.c_oflag =3D 0; =A0 =A0 =A0 =A0 tp.c_iflag =3D IGNCR|IGNPAR; =A0 =A0 =A0 =A0 tp.c_lflag =3D 0; =A0 =A0 =A0 =A0 cfsetospeed(&tp, baud); =A0 =A0 =A0 =A0 cfsetispeed(&tp, baud); =A0 =A0 =A0 =A0 if (tcsetattr(fd, TCSANOW, &tp) < 0) { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 perror("Couldn't set term attributes"); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 exit(-1); =A0=A0=A0=A0=A0=A0=A0=A0} =A0 =A0 =A0 =A0 n =3D read(fd, readBuffer, 6); I've also tried this with O_NONBLOCK (i.e., non-blocking read), but it has = the=20 same problem of reading a few continuous bytes, then skipping a segment.=20 Can anyone see my mistake or have any ideas to make it possible for the Lin= ux side to continually read all the data? thanks again, Nile