SCO Unix device driver code: help needed

SCO Unix device driver code: help needed

Post by Paul Na » Fri, 18 Jun 1993 21:53:45



I am busy porting a device driver that I wrote for Xenix to SCO's Unix.
Almost everything is done, _except_ the driver causes the kernel to
panic from time to time.  This is not a happy state of affairs.

The driver multiplexes a number of TTYs down a single aggregate serial
channel.  Because of the lack of speed of the channel, I have found it
necessary to make write() operations block until the output buffers are
flushed (otherwise I run out of clists).  This has introduced significant
problems into my driver (I think).  I have appended code fragments.

Each write() sets a flag for that tty, which is cleared by the poll handler
when it finds the output clist empty.  On entering, the write() tests the
flag, and sleeps until it is cleared.  After a few hours of high-speed
output (8 ttys doing "ls -lR /" down a single 9600 aggregate), the kernel
panics.  Using crash shows a traceback from the timer tick to my driver's
output routine, to "ttout", to "getc".

Has anyone got any ideas?  My news feed is a trifle erratic, so I would
prefer resonses by e-mail, but _any_ assistance would be welcomed.

Rudimentary code fragments follow:

write()
{
   /* disable interrupts (and poll()) while testing semaphore */
   ospl = spl7();
   while (ml->do_not_write) {
      sleep (&ml->do_not_write, TTIPRI);
   }
   splx (ospl);
   /* write, then set the semaphore to block */
   (*linesw[ty->t_line].l_write)(ty);
   ml->do_not_write = TRUE;

Quote:}

poll()
{
   /* check whether there's still data in the clist */
   if (!ty->t_tbuf.c_ptr || !ty->t_tbuf.c_count) {
      if (ty->t_tbuf.c_ptr) {
         ty->t_tbuf.c_ptr -= ty->t_tbuf.c_size;
      }
      /* try to fetch some more */
      if (!(CPRES & (*linesw[ty->t_line].l_output)(ty))) {
         /* nope, so unblock the write and wake it up */
         if (ml->do_not_write) {
            ml->do_not_write = FALSE;
            wakeup (&ml->do_not_write);
         }
         break;
      }
   }
   /* yup, so let's write it, and decrement the count */
   OUTPUT (*ty->t_tbuf.c_ptr);
   ty->t_tbuf.c_ptr++; ty->t_tbuf.c_count--;

Quote:}

There is obviously a whole bunch of other code, but this is the meat of
the driver's output stage.  If anyone wants _all_ the code, they can have
it, but they'll probably barf :-).  The above code works just great on
Xenix.  On Unix, it'll block and unblock repeatedly, and then finally
panic.  Before I added the blocking, it seemed to work fine, but would run
out of clists after a while, and complain bitterly.  I thought that this
was _not_ the best way to handle the slow line ;-).

        paul
--
 Paul Nash                    network grunt and bit-pusher extraordinaire

#! rnews 1602

Newsgroups: en.climate
Distribution: fidonet
Date: Tue, 15 Jun 93 23:

 
 
 

SCO Unix device driver code: help needed

Post by Paul Na » Mon, 28 Jun 1993 16:14:00


Some time ago, I called into the darkness, hoping for some help:

Quote:> Each write() sets a flag for that tty, which is cleared by the poll handler
> when it finds the output clist empty.  On entering, the write() tests the
> flag, and sleeps until it is cleared.  After a few hours of high-speed
> output (8 ttys doing "ls -lR /" down a single 9600 aggregate), the kernel
> panics.  Using crash shows a traceback from the timer tick to my driver's
> output routine, to "ttout", to "getc".

I got a couple of "good luck" messages, but no solid answers.  Anyway,
after a few days of playing with "crash" and a bunch of dumps, I think
that I have the answer.  The system has been up on both Xenix and Unix
for about three days now (hold thumbs :-)), so it looks like I got it
right in the end.  For your edification:

Most communications devices have interrupt handlers running at spl5.
Because of this, the line discipline routines bracket any clist
manipulation with spl5()/splx(), to stop the clists getting broken.
However, _my_ driver runs polled (the *&%^^&% hardware can't generate
interrupts).  Polls are run from the timer tick at spl7.  This enables
the poll to break into the read()/write() line discipline code and
knock the clists sideways.  Bracketing any routines that manipulate
clists with spl7()/splx() seems to fix the problem.

Does anyone know why this made SCO Unix panic, which Xenix seemed to
grind on?  Maybe Xenix runs xxpoll() routines at spl5?  Maybe it is
better at handling corrupted clists?  Maybe the line discipline code
already runs at spl7?  Maybe it doesn't have the memory protection and
error checking that Unix has?

Anyway, I hope that this little gem will help someone else somewhere who
is battling with a similar problem :-).
--
 Paul Nash                    network grunt and bit-pusher extraordinaire


 
 
 

SCO Unix device driver code: help needed

Post by Stuart Lyn » Tue, 29 Jun 1993 09:12:26



}Does anyone know why this made SCO Unix panic, which Xenix seemed to
}grind on?  Maybe Xenix runs xxpoll() routines at spl5?  Maybe it is

Yes, that's about the way it worked under Xenix. Don't know if they
changed it for Unix. But given the recent comments WRT serial I/O under
UNIX it's probably a safe bet that something has changed.

You might check out the most recent FAS. They presumably have solved
most of these problems for SCO UNIX.

--

uucp login:nuucp passwd:nuucp .................... ftp.wimsey.com:~ftp/ls-lR.Z
PD Software for SCO UNIX .................... ftp.wimsey.com:~ftp/pub/wimseypd
604-936-8649(voice)  604-937-7718(fax)   604-937-5311(pep)  604-937-7411(v32b)

 
 
 

SCO Unix device driver code: help needed

Post by Uwe Doeri » Wed, 30 Jun 1993 20:25:49



>Most communications devices have interrupt handlers running at spl5.
>Because of this, the line discipline routines bracket any clist
>manipulation with spl5()/splx(), to stop the clists getting broken.

How did you find this out? Have you disassembled the respective kernel
module or is this just a guess?

My understanding is that CLIST routines are protected with spltty().
This priority level lies between spl6() and spl7(). Did you look at
the SCO sio driver? In file /etc/conf/sdevice.d/sio in the fourth
column is the IPL value for this driver. An IPL of 7 corresponds to
spltty() (look at /usr/include/sys/ipl.h for a translation between
IPL and SPL values). Could you check this out?

If the sio interrupt routine runs at IPL7/spltty() this would mean
that the CLIST routines have to be protected by spltty() as well.
Otherwise SCO's own sio driver would corrupt the CLISTs.

I would for sure like to hear about any differences in this area
between SCO UNIX and other SVR3.2 UNIX flavours as this might have
consequences for the FAS serial driver I maintain. This driver
sometimes crashes SCO UNIX systems, and with some applications
(especially Taylor UUCP) under SCO 3.2.4 ports hang after character
output. I even consider dropping support for SCO UNIX in the next
FAS release if I or someone else can't find out why FAS breaks only
under SCO UNIX.

      Uwe

PS: There is no comp.unix.i386 newsgroup. It was removed long ago and
has been replaced by comp.unix.pc-clone.32bit. I've changed this in my
follow-up.
--

Berlin       |----------------------------------------------------------------
Germany      |  UUCP : ...!unido!fub!geminix.in-berlin.de!gemini

 
 
 

SCO Unix device driver code: help needed

Post by Paul Na » Thu, 01 Jul 1993 08:42:18


In the continuing saga ...

Quote:> Most communications devices have interrupt handlers running at spl5.
> Because of this, the line discipline routines bracket any clist
> manipulation with spl5()/splx(), to stop the clists getting broken.
> However, _my_ driver runs polled (the *&%^^&% hardware can't generate
> interrupts).  Polls are run from the timer tick at spl7.  This enables
> the poll to break into the read()/write() line discipline code and
> knock the clists sideways.  Bracketing any routines that manipulate
> clists with spl7()/splx() seems to fix the problem.

Except that it doesn't work :-(.  The machines (two Xenix, one Unix)
keep alive for up to 4 days, then *zappo*.  Anyway, it seems that the
xxpoll() routine has a parameter passed in, this being the current
spl setting of the cpu.  Thus:

        int xxpoll (spl)
        int spl;
        {
           if (spl >= 5) return 0;
           ... other code here ...
        }

_should_ do the trick.  I'll report back later.  Looks like SCO do a
spl5() in their line disciplines even if the CPU priority has been set
higher.  Anyone from SCO care to comment?
--
 Paul Nash                    network grunt and bit-pusher extraordinaire

 
 
 

SCO Unix device driver code: help needed

Post by Gert Doeri » Thu, 01 Jul 1993 23:53:20



>You might check out the most recent FAS. They presumably have solved
>most of these problems for SCO UNIX.

Uwe has not. His last comment on the system hangups with FAS 2.10 and SCO
ODT 2.0 was something along the line of "if nobody has an idea how to fix
this, I'll stop supporting SCO".

gert
--



 
 
 

SCO Unix device driver code: help needed

Post by Wm E. Davidsen » Sat, 03 Jul 1993 00:40:19



|
| >You might check out the most recent FAS. They presumably have solved
| >most of these problems for SCO UNIX.
|
| Uwe has not. His last comment on the system hangups with FAS 2.10 and SCO
| ODT 2.0 was something along the line of "if nobody has an idea how to fix
| this, I'll stop supporting SCO".

If someone could tell me how to generate the problem, I'd be glad to
take a look at it. Since part of the consulting we offer is SCO device
drivers, I can't think of a better way to do cheap advertising than to
fix the problem, assuming I can find it. It has to be a UNIX thing, I
haven't seen it on Xenix, and I've been beating the hell out of this
system since the day FAS210 was available.

If someone wants to tell me *by mail* it might be better, I don't read
this group every day.
--

    TMR Associates, +1 518-370-5654
    C programming, data gathering, porting to open systems, heterogeneous
    environments, computer comtrolled housing, custom software

 
 
 

1. Looking for help with Simple Device Driver for SCO Unix

I need help writing a device driver for SCO Unix.  All it needs to do
is write a character to and IO port address and read a character from
another address.   Is this difficult to do on UNIX?  On DOS using Borland C++
i would simply use the INP and OUTP functions.

Any assistance would be greatly appreciated.

Thanks!

2. can't installp -u a fileset in COMMIT-HOLD on AIX 4.3.2

3. Device driver code for unix

4. Strange "df -k" output for /tmpfs

5. HELP needed: Solaris PCI device driver, device not auto detected.

6. VI, Terminals and the backspace key

7. need help accessing device i/o memory from device driver

8. XF86Setup

9. SCO UNIX *double* device driver

10. SCSI device driver for SCO UNIX 3.2.2

11. Any SCO Unix device driver discussion forum/list out there?

12. SCO UNIX 3.2.4 device driver question

13. SCO Unix device driver