There's a deadlock in isoio() on a multiprocessor, arising from a conflict in order of acquiring locks. (Not just theory: I've seen it happen on my dual-processor Epia system.) Consider this scenario: isoio() on cpu1: 1 isoio calls sleep(&e->wr, isoready, e) /sys/src/9/pc/usbuhci.c:1173 2 sleep calls lock(&e->wr) /sys/src/9/port/proc.c:740 3 sleep calls isoready(e) /sys/src/9/port/proc.c:755 4 isoready calls ilock(&ctlr->activends) /sys/src/9/pc/usbuhci.c:1093 5 isoready calls iunlock(&ctlr->activends) /sys/src/9/pc/usbuhci.c:1095 6 sleep calls unlock(&e->wr) /sys/src/9/port/proc.c:762 interrupt() on cpu0: 7 interrupt calls ilock(&ctlr->activends) /sys/src/9/pc/usbuhci.c:1043 8 interrupt calls cleaniso(e, ) /sys/src/9/pc/usbuhci.c:1052 9 cleaniso calls wakeup(&e->wr) /sys/src/9/pc/usbuhci.c:1015 10 wakeup calls lock(&e->wr) /sys/src/9/port/proc.c:864 11 wakeup calls unlock(&e->wr) /sys/src/9/port/proc.c:876 12 interrupt calls iunlock(&ctlr->activends) /sys/src/9/pc/usbuhci.c:1055 An interleaving of events containing 2 - 7 - 10 - 4 leads to deadlock. I developed a fix which involved locking the individual endpoints instead of locking ctlr->activends, but when I checked it with Sape he pointed out that a simple revision to isoreadyx() would mean that it can be called without locking at all. So here's a simple patch based on Sape's suggestion. (Tested by playing audio for 24 hours on the above dual- processor system, without incident.) -- Richard Miller