Re: Best way to implement multiple UserClient connections?
Re: Best way to implement multiple UserClient connections?
- Subject: Re: Best way to implement multiple UserClient connections?
- From: Phil Jordan <email@hidden>
- Date: Wed, 19 Sep 2012 17:41:18 +0200
Hi James,
I've written a few IOUserClient implementations, so I'll try to help...
On Mon, Sep 17, 2012 at 9:39 AM, James Wise <
email@hidden> wrote:
> Currently I have multiple UserClients connecting to the kext, all based
> IOUserClient, but the most used connections are an InputUserClient, and an
> OutputUserClient.
> In turn these two user clients, attach/listen to the input interrupts or the
> output interrupts that are generated on the card itself.
>
> Now the card in question contains not 1, but 2 pairs of interrupts, that is,
> a total of 4 ( 2 in, 2 out)
To clarify my understanding of your situation: these interrupt presumably correspond to independent subdevices or ports on the device itself. You currently have up to 2 user client instances, one for input and one for output, each of which are hardcoded to one of the two interrupt sources. Correct?
Are these 4 independent ports (interfaces, units, devices, whatever) which happen to be one or the other direction, or would one of the inputs always be paired with one of the outputs? It sounds like the former, but I'd like to clear this up 100%.
> There is very little different between the input and output UserClients.
> Basically the only difference is when we request a user Client the name
> requested is different input vs ouput,
> ie. the kext lists different names in it's plist, which then determines
> which UserClient we connect to.
> and this then dictates which interrupts on the card we listen to for that
> UserClient.
> (they actually instance exactly the same IOUserClient derived class, just
> with slight different options.)
OK.
> As much as anything i am really after information regarding best practice,
> not just what will work, but the BEST way to make things work
>
> [options 1-4]
Can I pick "none of the above"? ;-)
There is an established pattern/convention in the IOKit of creating child IOService instances to identify multiple ports/subdevices/interfaces/etc. on a larger physical device. If you look at the output from
ioreg -i
you should spot a few IOUSBDevice (subclass) instances, which typically have multiple IOUSBInterface child objects. These child objects can then be matched by clients independently.
Bearing that in mind, I would suggest a provider/client hierarchy that looks something like this:
+-o IOPCIDevice +-o MyWholeCardDevice
+-o MyInputInterface
| +-o MyInputInterfaceUserClient
+-o MyOutputInterface
| +-o MyOutputInterfaceUserClient
+-o MyInputInterface
| +-o MyInputInterfaceUserClient
+-o MyOutputInterface
+-o MyOutputInterfaceUserClient
(assuming a PCI device and assuming your 4 ports are independent, see above)
You mention that the input and output code is very similar, so you could use a common superclass for them, the class hierarchy would look like this:
(Subclass : Superclass)
MyWholeCardDevice : IOService
MyInterface : IOService
MyInputInterface : MyInterface
MyOutputInterface : MyInterface
MyInterfaceUserClient : IOUserClient
MyInputInterfaceUserClient : MyInterfaceUserClient
MyOutputInterfaceUserClient : MyInterfaceUserClient
The Input and Output specialisations for interfaces and user client would (by your description) contain very little code, but having them as different classes can help with matching.
As for going about implementing this, MyWholeCardDevice's start() method presumably initialises the device and enumerates the ports, and possibly sets up the event sources. When each port is ready, you would then create a corresponding MyInputInterface or MyOutputInterface instance that knows which port on MyWholeCardDevice it represents. Each such interface object would have the "IOUserClientClass" property set to the corresponding class name, along with something to identify the port (I assume the user space app will need to know which port it's using). When ready, you call registerService() on the interface object to make it available for matching.
The user space framework can then open the service, creating the user client. The user client doesn't talk directly to MyWholeCardDevice but rather through the MyInputInterface or MyOutputInterface object. Each interface object can restrict itself to one user client to enforce exclusive use, but the individual interfaces can be used independently. Identifying ports (and direction) can be done entirely via IORegistryEntry properties, which reduces/simplifies your user methods.
If there literally is no input or output specific code, you can also make the direction a property on a single interface class, and avoid having separate input and output interfaces and user clients.
I hope that makes sense, let me know if anything is unclear.
> Anyway I know my Questions probably seem a bit all over the place, but i am
> struggling to find good examples of more complex
> kext/UserClient setups and examples, the docs and examples on Apple's
> website are helpful and useful,
> but are also simple and provide more technical guidance than a higher level
> architectural guidance for more complex situations.
> I also have Amit Sings OSX fundamentals book, which is good, but sort of out
> of date now, and again doesn't really cover more complex examples such as
> this.
Yeah, I think everyone has this problem. The Halvorsen book (discosure: I was one of the reviewers) is a little more practical for driver development than Singh's (and somewhat more up to date) but still leaves a lot to the imagination when you actually try to implement a driver yourself.
Hope that helps,
phil
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden