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]
