Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Aug 2003 12:50:44 -0400
From:      Don Bowman <don@sandvine.com>
To:        Don Bowman <don@sandvine.com>, "'freebsd-hackers@freebsd.org'" <freebsd-hackers@freebsd.org>
Subject:   RE: hang in sio driver when interrupt occurs while in siocnputc()
Message-ID:  <FE045D4D9F7AED4CBFF1B3B813C8533702742202@mail.sandvine.com>

next in thread | raw e-mail | index | archive | help
> From: Don Bowman 
> 
> I find that if the kernel is in the middle of a printf,
> is using a serial console, and a key is pressed, that i
> may end up stuck in the siointr. I added a counter to
> siointr1() so that if it receives more than 100 characters
> in a single interrupt it panics. What I find happens is
> that the chip (a winbond w83627HF in this case, 16550 compat)
> claims to have more characters to read (the fifo is not empty),
> but no interrupt is pending. The siointr1() loops forever on
> this, reading the com_data register.
> 
> I created a simple kernel module that, on command from a sysctl,
> outputs many characters in a callout. When this is going, I hit
> enter a few times, and my panic occurs.
> 
> Debugger(c03093aa) at Debugger+0x35
> panic(c0330173,ce098000,3f8,ff807e60,8) at panic+0xb8
> siointr1(ce098000,c0382788,3f8,ff807e44,c02c1e40) at siointr1+0x146
> siointr(ce098000) at siointr+0x17
> Xfastintr4(ff807e60,3f8,1c200,45,0) at Xfastintr4+0x20
> siocnputc(c0362c44,45) at siocnputc+0x4d
> cnputc(45,1,63,0,ff807f40) at cnputc+0x4c
> putchar(45,ff807f60) at putchar+0x9d
> kvprintf(ce3bd75c,c01cb490,ff807f60,a,ff807f7c) at kvprintf+0x38e
> printf(ce3bd75c,45,0,ce3bd670,ff807fa8) at printf+0x44
> so_timeout(0,40000000,ffffffff,0,ffffffff) at so_timeout+0x3b
> softclock(0,ff800018,c02e0010,ce090010,ffffffff) at softclock+0xfe
> doreti_swi(0,ff808000,0,0,f323a000) at doreti_swi+0xf
> idle_loop() at idle_loop+0x44
> 
> siocnputc() just takes spltty(), which doesn't prevent
> the interrupt from happening.
> 
> this doesn't seem right, do you think that the siocn* routines
> should take COM_LOCK()?
> 
> This is on RELENG_4. The system is SMP.
> 
> 

Further, it appears the intent of siocnopen() is to disable
interrupts on the particular uart, since its overwriting
other registers:

        sp->ier = inb(iobase + com_ier);
        outb(iobase + com_ier, 0);      /* spltty() doesn't stop siointr()
*/

but i'm nonetheless getting an interrupt.

@ the offset I'm at in siocnputc 
siocnputc+0x48: call    siocnopen
siocnputc+0x4d: pushl   %ebx
i'm in the process of calling siocnopen(), so it hasn't got to that
interrupt
disable code yet.

--don



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FE045D4D9F7AED4CBFF1B3B813C8533702742202>