With rtsx(4), I can trigger a panic in sdmmc_needs_discover() by inserting an SD card (actually, a microSD in an SD-card sized adapter) during boot (while the boot loader is loading the kernel).
I haven't copied the backtrace (no serial console) but what happens is that rtsx_intr() fires during rtsx_init() called from rtsx_attach(). The rtsx_init() function enables interrupts very early, and then goes on to init various things. The last thing it does is check the ISR to see if a card is already inserted, and if so it sets the RTSX_F_CARD_PRESENT flag in the softc. If rtsx_intr() runs concurrently, and before the RTSX_F_CARD_PRESENT flag has been set, it will check the ISR as well, see that a card is present, and run sdmmc_needs_discover(). However, we haven't yet attached the sdmmc subsystem at this point, so the kernel panics. Enabling interrupts after checking whether a card is inserted seems to fix this problem and doesn't seem to cause a regression. I've tested various things, booting with and without a card and inserting a card at various times during the boot process, and it now seems solid. I'm not really sure why I didn't catch this before. For some reason the problem does not happen if the card is inserted while powering on the machine, so perhaps the hardware doesn't fire an interrupt in that case and I've never tested inserting a card during boot before. Index: rtsx.c =================================================================== RCS file: /cvs/src/sys/dev/ic/rtsx.c,v retrieving revision 1.2 diff -u -p -r1.2 rtsx.c --- rtsx.c 7 Dec 2012 22:18:56 -0000 1.2 +++ rtsx.c 28 Mar 2013 13:46:07 -0000 @@ -215,10 +215,6 @@ rtsx_init(struct rtsx_softc *sc, int att { u_int32_t status; - /* Enable interrupts. */ - WRITE4(sc, RTSX_BIER, - RTSX_TRANS_OK_INT_EN | RTSX_TRANS_FAIL_INT_EN | RTSX_SD_INT_EN); - /* Enable interrupt write-clear (default is read-clear). */ RTSX_CLR(sc, RTSX_NFTS_TX_CTRL, RTSX_INT_READ_CLR); @@ -226,6 +222,14 @@ rtsx_init(struct rtsx_softc *sc, int att status = READ4(sc, RTSX_BIPR); WRITE4(sc, RTSX_BIPR, status); + /* Check for cards already inserted at attach time. */ + if (attaching && (status & RTSX_SD_EXIST)) + sc->flags |= RTSX_F_CARD_PRESENT; + + /* Enable interrupts. */ + WRITE4(sc, RTSX_BIER, + RTSX_TRANS_OK_INT_EN | RTSX_TRANS_FAIL_INT_EN | RTSX_SD_INT_EN); + /* Power on SSC clock. */ RTSX_CLR(sc, RTSX_FPDCTL, RTSX_SSC_POWER_DOWN); delay(200); @@ -267,10 +271,6 @@ rtsx_init(struct rtsx_softc *sc, int att /* Set up LED GPIO. */ RTSX_WRITE(sc, RTSX_CARD_GPIO, 0x03); RTSX_WRITE(sc, RTSX_CARD_GPIO_DIR, 0x03); - - /* Check for cards already inserted at attach time. */ - if (attaching && (status & RTSX_SD_EXIST)) - sc->flags |= RTSX_F_CARD_PRESENT; return (0); }