Date: Fri, 20 Jun 2008 23:57:08 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Arthur Hartwig <arthur.hartwig@nokia.com> Cc: freebsd-bugs@FreeBSD.org, freebsd-gnats-submit@FreeBSD.org Subject: Re: kern/124777: USB cua dvices don't revert to tty devices when they are closed Message-ID: <20080620231121.K63907@delplex.bde.org> In-Reply-To: <200806200647.m5K6lwa4042472@www.freebsd.org> References: <200806200647.m5K6lwa4042472@www.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 20 Jun 2008, Arthur Hartwig wrote: >> Description: > Once a USB serial device is opened as a cua device it continues to behave as a cua device even after being closed. cua devices allow only one open, tty devices allow multiple concurrent opens. Thus if a USB serial adapter is opened as /dev/cuaU0 (for example to set some modem parameters) closed and then opened as /dev/ttyU0 to allow login through the USB serial port adapter, then after login the 'more' command specifying a large enough file (more than a screen full) stalls when the controlling terminal is opened because the kernel thinks the controlling terminal is still a cua device and it has already been opened. Where is the bug that keeps generating long lines like the above in PRs? >> Fix: > For now I have added the two lines: > > tp->t_actout = FALSE; > wakeup(&tp->t_actout); > > to ucomclose() in sys/dev/usb/ucom.c to mimic what is done with other serial port hardware but I think the better solution is to add these two lines to tty_close() in sys/kern/tty.c and remove them from close functions in the serial port drivers. Yes, handling of the callin and callout devices should have been completely moved to generic code. But beware of bugs doing this. Code cannot simply be moved, since it might need to run in a particular order. At least the sio and cy were broken by changing the order of the siosettimeout() call. This results in (at least) the timeout not being set up on the first call and never being torn down after the second call. After 2 calls, the timeout is always active and always gives panics on module unload. The working non-generic open code was essentially: MI_stuff_part_1(); MD_stuff_part_1(); MI_stuff_part_2(); MD_stuff_part_2(); ... MI_stuff_part_5(); /* perhaps up to 10 sections */ MD_stuff_part_5(); and not all of the reorderings to reduce this to a single MD call are valid. The above t_actout code is just before the broken siosettimout() call in sio, but moving it seems to be OK. The working code was: % s = spltty(); % ttyld_close(tp, flag); % com->hotchar = ttyldoptim(tp); % comhardclose(com); % ttyclose(tp); % siosettimeout(); % splx(s); The t_actout code was in comhardclose() and has only been renamed. It was at the end together with a TSA_CARR_ON() wakeup which should also be moved (to the MI code just before the ttyclose() call). The siosettimeout() call was also moved into comhardclose(), but that completely broke it. It must be after the ttyclose() call. Other bugs in this area include almost null documentation of the callin and callout devices in ucom(4). Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080620231121.K63907>