kern/128037: System hang on shutdown with PCMCIA-CF adapter inserted
Arthur Hartwig
arthur.hartwig at nokia.com
Mon Oct 13 01:40:01 UTC 2008
>Number: 128037
>Category: kern
>Synopsis: System hang on shutdown with PCMCIA-CF adapter inserted
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Oct 13 01:40:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Arthur Hartwig
>Release: 6.3
>Organization:
Nokia
>Environment:
>Description:
System has a TI PCI1520 Cardbus PCI bridge. If a PCMCIA to Compact Flash adapter is inserted in the Cardbus slot and the system is shutdown then the shutdown does not complete.
This has been not been observed on multi-CPU systems. It has been observed on single CPU systems with a 1.5GHz Celeron CPU but not on a single CPU system with a XEON 2.80GHz CPU. (This CPU has hyperthreading capability but it is run with hyperthreading disabled and a single CPU kernel.)
Breaking into ddb from the console shows one thread in cbb_power() called from cbb_shutdown() and another thread in cbb_intr(). From setting breakpoints it appears the exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET); call in cbb_shutdown() causes a delayed interrupt request which, on slower CPUs, interrupts cbb_power() early in its execution and certainly before power to the socket is turned off. The interrupt apparently is not cleared by the interrupt handlers and repeats indefinitely, preventing cbb_power() making progress to the points of turning off power to the card. (On a multi-CPU system cbb_shutdown and cbb_intr() can run in parallel concurrently so the continuous interrupts don't stop cbb_power() making progress to the point of turning off power to the socket.)
>How-To-Repeat:
Shutdown a "slower" single CPU system with a PCMCIA-Compact Flash adapter in the slot of a TI PCI1520 Cardbus PCI bridge. (It is unknown if this problem occurs with other Cardbus PCI bridges.)
>Fix:
In cbb_shutdown() in sys/dev/pccbb/pccbb.c add disable_intr() before the exca_clrb() and enable_intr() after cbb_power() so the code reads:
disable_intr();
exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET);
cbb_set(sc, CBB_SOCKET_MASK, 0);
cbb_set(sc, CBB_SOCKET_EVENT, 0xffffffff);
cbb_power(brdev, CARD_OFF);
enable_intr();
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list