Subject: kern/11957: usb_transfer_complete() called at controller interrupt level
To: None <email@example.com>
From: None <firstname.lastname@example.org>
Date: 01/14/2001 12:33:17
>Synopsis: usb_transfer_complete() called at controller interrupt level
>Arrival-Date: Sun Jan 14 12:33:00 PST 2001
>Originator: Jason R. Thorpe
>Release: Jan 14, 2000 NetBSD-current
Zembu Labs, Inc.
System: NetBSD dr-evil 1.5Q NetBSD 1.5Q (DR-EVIL) #54: Thu Jan 11 13:06:44 PST 2001 thorpej@dr-evil:/u1/netbsd/src/sys/arch/i386/compile/DR-EVIL i386
usb_setup_transfer() is called by the controller drivers at
their interrupt level. This means that the driver callbacks
are called at controller interrupt level.
As a result of this, the USB network drivers, for example, use
splimp() to block both network and USB controller interrupts.
Besides generally being bad (blocks more interrupts that you
would otherwise need), it is a roadblock for some pending SMP
work (it is critical that this problem be fixed so that MP-safe
interrupt handlers can be integrated).
There are a couple of ways this could be fixed. The easiest,
it seems, would be to have the controller (UHCI, OHCI, and
eventually EHCI) drivers defer all of the real interrupt
processing to a software interrupt (either using the
softintr_schedule() API, if present, or a callout with a tick
count of 1; the lack of softintr_schedule() everywhere is a
bug orthogonal to this one).
With this approach, the controller drivers could then simply
be considered "bio" devices, and controller interrupts could
be registered with IPL_BIO and blocked with splbio(), and
splusb() could be defined to splsoftclock().
All USB device drivers would then need to be changed to
call the appropriate spl*() functions at the appropriate
times in their callback routines.