Blaz Antonic writes:
>
> > Thinking in the bath last night I came up with a way of building user space
>
> How romantic :-)
>
> > We create a meta driver called something like the user device driver which
> > has a whole load of generically named devices in /dev/udd0 -- /dev/udd<n>.
>
> It is a nice idea indeed and i'd be very interested in it.
>
> However i have a thought about your mechanism:
>
> > while ((y = ioctl(x, UDD_WAIT_REQUEST, &bar)) == 0) {
> > process_device_request(&bar);
> > }
>
> We are burning CPU cycles using this while loop. Isn't there some way to
> put user space driver to sleep (and oput it on some alternative process
> list so scheduler skips it and gives CPU cycles to other tasks) and wake
> it up when needed (by moving it to the task list). Of course you
> wouldn't process to sleep when every single request is processed but
> only after certain duration of time spent idling.
When the ioctl call is made, the process sleeps in kernel mode until a
request is ready, then the ioctl returns.
Basically the users space driver does not ever go into a tight loop.
>
> Alternatively you could call schedule() when while loop finishes for the
> 5th time (for examp[le) with no request pending.
>
> > ioctl(x, UDD_REQUEST_COMPLETE, &reply);
> >
> > return;
>
> Anyway, i wouldn't use ioctl() as the trigger for user space driver, i'd
> rather use universal function (int invoke_udd) that functions just like
> ioctl, but can carry over ioctl requests too (otherwise it becomes
> complicated to differ between requests that are udd dependent and those
> that are driver dependent, ioctl commands could have same number if you
> know what i mean).
I prefer to use ioctl because it means we don't have to add any
non-standard system calls, which I don't like doing.
There is no confusion between ioctls sent to the meta driver, and ioctls
sent to the users space driver because all those sent to the meta driver
go through /dev/udd (minor number 0), and the others go through the other
devices.
>
> So driver would loop while it doesn't get positive reply from
> invoke_udd(parameters). When it gets the call it executes local function
> (read/write/ioctl/anything) depending on the parameters passed to it
> through invoke_udd parameters).
As I explained above it won't loop until it gets a request and processes
it.
>
> When request is processed (with either sucess or some error) driver
> would call back some other function (the ioctl in your example, which i
> don't like as i stated above). This function would take care of setting
> global kernel variables (well, not global for whole kernel, just for
> metadriver stub). Metadriver functions (read/write/ioctl/others) would
> be still waiting for reply from udd at that moment in a while loop of
> their own. When that global variables were altered (at least errno and
> request_processed) the function would know something has happened and
> act according to errno. When it comes to an end it would clear
> request_processed flag in order to allow new requests to be issued).
We can use wait queues to deal with this stuff. When the meta driver gives
a request to the udd, it sleeps on that requests wait queue. When the udd
calls the kernel saying the request is complete, the kernel function the
wakes the queue up again.
>
> > I can write the meta driver for this scheme, and a sample driver which will
> > probably be a loopback driver as this is the most simple to implement.
>
> All this has one big BUT: it is slow, as slow as message passing system
> (this is message passing approach) can be. If you make the scheduler
> _much_ smarter then it might work out with relatively large buffers.
> Otherwise you can say goodbye to performance of serial at 115200, and
> block device or any network device. UNLESS: all the functions we get in
> the udd can be triggered by hardware interrupt (IRQ). In that case we
> don't loose much.
I don't see any reason why we can't give hardware interrupts directly to
the udd process. All we need is a call that the meta driver accepts which
includes the address of the service routine, and the IRQ required.
>
> I can help you writing the metadriver or some other driver (serial, for
> example) as udd.
> Send me your sources if you need any help with any part of the combo.
> BTW, that register_udd function would also take care of seizing
> interrupts, right ? And we need some ioperm() like function - i just
> don't feel like everyone is going to mess around with all the io ports,
> irqs, dma, etc.
>
> Are you going to write the metadriver or shall i do it ?
>
I will write a bare bones sample implementation which can be used as a
refernce point for discusion. You are right I should leave this until after
0.0.75.
Al