a problem we've seen around here is that parallels
and vmware fusion will hang after 9load prints
"entry: 0x$address".  our intel 5400 motherboard
also does this when no serial is connected.

it turns out that all three of these setups have
the same problem.  consdrain() loops until all
the output has been stuffed down the serial port.
however, in these setups the first character sent
to the serial port sets up->txbusy and consdrain loops
forever trying to output the next character.

my solution was to note the number of characters
drained between calls to uartdrain and break out
of the loop if no progress is made.  i also reduced
the amount of time allowed to push 1 character out
to 500ms.  even for 128baud, this ought to be enough.

i attached a diff since the 9load i'm using has drifted
a bit from the distributed version.

- erik

----

diffy fns.h 8250.c console.c
diff /n/dump/2008/0721/sys/src/boot/pc/fns.h fns.h
126c126
< void  uartdrain(void);
---
> int   uartdrain(void);
260a261,262
> int i8250txchars;
> 
273a276,277
>       if(i < 100)
>               i8250txchars++;
298c302
< void
---
> int
302a307
>       static int last;
305a311,314
>       /* very poor hack.  don't wait forever if we never tx anything */
>       if(i8250txchars == last)
>               return -1;
>       last = i8250txchars;
308c317
<       for(timeo = 0; timeo < 10000 && up->txbusy; timeo++)
---
>       for(timeo = 0; timeo < 500 && up->txbusy; timeo++)
diff /n/dump/2008/0721/sys/src/boot/pc/console.c console.c
64d63
< 
66c65,66
<               uartdrain();
---
>               if(uartdrain() == -1)
>                       break;


Reply via email to