Ok, I think I figured out a proper solution, for clarity I will reiterate the entire solution. It's a lengthy mail, but please do read it and tell me what you guys think about it.
We want to implement a .defs file with control procedures, which can ofcourse be independant of libchannel. The only real requirement of the procedueres is that they have a mach_port_t parameter (like all(?) procedures that opperate on a file.) The control server for such a subsytem, will consist of the server module generated from the .defs file, the corresponding stubs and a function table struct. The function table will have a pointer for each procedure in .defs, typically with the same signature except with the port exchanged for a channel, and also subsystem id of the .defs file. The stubs jobs will be to determine which channel is implemented by the given port, find the function table stored in the channel associated with this subsystem and then forward the call to the right function in the table (exchanging port and channel.) To make this possible libchannel provides the following functions. error_t channel_trans_find_channel (mach_port_t port, struct channel **channel) Find and return in CHANNEL the channel that underlies PORT. This function is to be implemented by the translator using libchannel. (implementing it in channelio should be trivial as it only has one node.) XXX a channel_t *channel_trans_find_channel (mach_port_t) signature might be more useful, as it can be used as a mig intrans function. Decisions, decisions... error_t channel_find_control_interface (const *channel, int subsystem_id void **ft) Find and return in FT the function table in CHANNEL that implements the subsystem SUBSYSTEM_ID. A stub would then look something like this. error_t keyboard_S_get_mode (mach_port_t port, int *mode) { struct channel *channel; struct keyboard_ft *ft; error_t err; err = channel_trans_find_channel (port, &channel) if (err) return err; err = channel_find_control_interface (channel, KEYBOARD_SUBSYSTEM_ID, &if) if (err) return err; if (iface->get_mode) return iface->get_mode (channel, mode) return EOPNOTSUPP; } A channel will need to provide a list of demuxer functions and a mapping from subsystem ids to function tables. The channel's class will be repsonsible for filling these in by either providing implementations itself or use the contents of a sub-channel's lists. Note that the lists can not be in the class itself. For instance, a keyboard channel can only provide a keyboard control inteface not a mouse one, even though a mouse channel is a member of the device class. Finally, libchannel will provide a demuxer that uses the demuxers in the channel. This is done simply be going through the list until a demuxer accepts the message. Cheers, Fredrik _______________________________________________ Bug-hurd mailing list Bug-hurd@gnu.org http://lists.gnu.org/mailman/listinfo/bug-hurd