[sorry for the cross-post - I got no response when posted to the darwin-drivers list] I am writing a kernel USB driver (kext) that talks at its upper-edge to the Ethernet stack and to the USB stack at its lower edge (pardon the butchering of terminology here). I have a version of this driver running on 8/9. In the 8/9 version there are the following sources of interrupts (asynchronous events, if you will): * Timer * Network stack outbound data * Network stack polls for inbound data (on 8/9 the net stack polls and I think on X I call "up" with received data). * USB Read completions * USB write completions * USB control pipe completions * USB Interrupt pipe completions Without going into great detail, assume that each of these events must access some or all of the data structures within the driver that the other events access (i.e, a read completion access something that a timer completion also accesses). On my 8/9 driver, the only practical way to protect shared data structures is by selectively disabling interrupts at the appropriate places in the code where multiple events might touch shared data (since there is virtually no support for any other critical-section mechanisms on 8/9). Fast-forward to X. There seem to be a plethora of different ways to serialize, lock, etc. (work loops, IOLocks, semaphores, gates, mutexes, ) in drivers, with not a lot of documentation as to when or how or why you would choose one over another, when one will work or wont work, what you can and cant do from where (for example, what O/S calls are legal or illegal to make from a USB read-pipe completion?). My question is this: Given all the possible sources of asynchronous events I describe above (some of which are interrupt-level, others maybe not (not well documented either)), what mechanism should I use to protect my data structures? Is there one that will work for all (e.g., can I use an IOLock to protect everything from all sources?)? Do I have to use different methods? What works where (e.g., from a timer, you may use but you may not use "..."). What does not work and where? What I'd really like to do is that from any place in my code that needs to protect itself from one of the "other" sources of interrupts/entry I do a simple "lock()/unlock()" mechanism. Admittedly, I don't understand the workloop/gate mechanism (I understand some of the principals but not the mechanics). Can I register the USB callbacks with the workloop mechanism (do I even have to - are they already routed through the workloop?)? I see sample code in the Ethernet driver to register an interrupt function. Could someone explain to be how the underlying mechanism actually works? I see an interrupt function get registered but I don't see the "magic" behind preventing that function from getting called directly by the source of the interrupt - there's something behind the scenes going on that I don't understand. Your help is greatly appreciated. Scott _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Scott Taggart