dev/ic/com.c, callouts and cv_wait

Brad Spencer <[email protected]>
Newsgroups gmane.os.netbsd.devel.kernel
Message-ID <[email protected]>
Hello...

I was wondering if anyone can enlighten me about something I am seeing.

I am working on a driver for the SC16IS7xx family of UART bridges.
These are I2C or SPI devices that provide a 16550 or there abouts
register set that is behind a I2C or SPI bus.  I.E. you can use them to
add more real UARTs to a RPI, via the I2C or SPI bus, for example.

I am reusing the dev/ic/com.c existing code, switching out the cr_read,
cr_write and cr_write_multi functions to calls that speak to the I2C
bus.

This all appears to work as expected:

[   1.0000040] iic0 at bsciic0: I2C bus
[   1.0000040] sc16is7xx0 at iic0 addr 0x48
[   1.0000040] sc16is7xx0: NXP SC16IS750/SC16IS760
[   1.0000040] com1 at sc16is7xx0 channel 0: ns16550a, 16-byte FIFO

The "ns16550a, 16-byte FIFO" came from dev/ic/com.c after it poked the
chip registers so I suspect that those calls to the I2C bus are working
as expected at least for reads.

I am using polling mode with dev/ic/com.c which simulates hardware
interrupts using a callout to com_intr_poll.  When the callout runs and
tries to access the I2C bus I get this panic:

[   2.1213299] panic: kernel diagnostic assertion "(l->l_pflag & LP_INTR) == 0 |
| panicstr != NULL" failed: file "../../../../kern/kern_condvar.c", line 133
[   2.1213299] cpu0: Begin traceback...
[   2.1213299] 0xba581d94: netbsd:db_panic+0x14
[   2.1213299] 0xba581db4: netbsd:vpanic+0x114
[   2.1213299] 0xba581dcc: netbsd:kern_assert+0x40
[   2.1213299] 0xba581e04: netbsd:cv_wait+0x1b0
[   2.1213299] 0xba581e34: netbsd:bsciic_exec+0xb4
[   2.1213299] 0xba581e6c: netbsd:sc16is7xxi2c_read_register_direct+0x74
[   2.1213299] 0xba581e8c: netbsd:sc16is7xx_i2c_com_read_1+0x38
[   2.1213299] 0xba581ecc: netbsd:comintr+0x6c
[   2.1213299] 0xba581ee4: netbsd:com_intr_poll+0x14
[   2.1213299] 0xba581f34: netbsd:callout_softclock+0xe0
[   2.1213299] 0xba581fac: netbsd:softint_dispatch+0x128
[   2.1213299] Bad frame pointer: 0x80cddf54
[   2.1213299] cpu0: End traceback...

That was on a RPI, but the same sort of thing happens with umcpmio(4)
too on a amd64 VM.  In that case it is a cv_wait_sig that panics in the
USB stack.

dev/ic/com.c was adjusted some to allow higher level code to ask that
dev/ic/com.c mutex to run as an adaptive lock instead of IPL_HIGH, its
callouts were declared MPSAFE (ignoring for a moment that they might not
be) and the softint that is used to call comsoft was declared MPSAFE
(also ignoring for a second that it might not be).  These last two
adjustments were mostly to keep the code from using the global kernel
lock.  Its probably incorrect, but I am mostly just trying to get
through attach at this point.

I read the man page for callout a number of times and it does not appear
to hint one way or the other if callout(9) are allowed to cv_wait, but
it seems like they are not.

I have used cv_wait from kernel threads before, but I have never
attempted to do use them from a callout (I don't think).  Did I miss
something, or is this case not allowed??


BTW - as a brief aside if dev/ic/com.c runs with its mutex at IPL_HIGH
and tries to use the I2C bus it doesn't make it past the iic_acquire_bus
as that can sleep and you get the "trying to sleep with a spin lock"
panic.





-- 
Brad Spencer - [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.