Protection Questions
Protection Questions
- Subject: Protection Questions
- From: Scott Taggart <email@hidden>
- Date: Mon, 03 Jun 2002 13:51:53 -0700
[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 | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.