More information please!
Hi Godfrey, Thanks for the response to my questions. Regarding your responses (edited below).
Who queued the Param blocks before?
The scenario under which it operates under OS8/9 is as follows: This is the layer hierarchy: Application ( Not ours ) | ^ Selector based call | | Response v | Plugin | ^ API based call | | Response v | Personality Immediate PB(Control/Status) | ^ or PBAsync(Read/Write) call | | Response v | Driver The Application makes a Plugin(SEL_OUTPUT) call with an array of buffers which it wants us to output. The Plugin calls Personality(Write) for each buffer which is ready to send. It will do this ZERO or more times during a Plugin(SEL_OUTPUT) call, depending upon how many of the buffers in the array are ready to send, but NOT yet sent. It will also look to see if any of the buffers have been output, and will tell the Application so that it can re-use them. NOTE: This is why we poll as we don't have control for most of the time. The Personality makes a Driver(PBWriteAsync), for each buffer it receives. These are queued by the Device Manager until the preceding call has completed. Once the IOCompletion() routine is called for a buffer, the next buffer is sent to the driver which starts outputting it. The Driver handles a single request at a time, except for Immediate calls, which access the specific routines directly. What I wanted to know was this: Is there an equivalent of the Device Manager Queue, or do I have to implement my own queueing system inside the driver to handle this sort of behaviour ?
So to initiate an asyncrhonous operation you make a subroutine call
to a driver somewhere. This call is 'synchronous', isn't it, by that
I mean you expect the routine to return don't you? So use Xs
synchronous routines to initiate an asynchronous I/O operation.
I have now implemented the Write as an IOConnectMethod... call, which needs to hand off the actual transfer to some other part of the driver, and then return with a suitable status. Q. Am I right in assuming that this mean my driver will require some sort of separate output thread in order to actually send the data ?
Your email doesn't make clear, are you really POLLING on 'ioResult'.
How often do you poll per second, can you measure this in your code
please? This is very bad behaviour on X.
Because of the lack of control (as described above), and also the portability requirements of the various layers (Win/Mac/Solaris), we used a polling approach as opposed to a completion routine approach. The polling checks the first item in the linked list, and if not ready it returns to the application which allows other processes to execute. If the item is ready (OK/Error) we deal with that and then check the next item.
On X we recommend the use of the Notification port API. First create
a port with IONotificationPortCreate. Then register it with your
driver using IOConnectSetNotificationPort(), this call calls
IOUserClient::registerNotificationPort inside your driver. This sets
the plumbing up from the kernel's point of view. Finally you need to
plumb the completion call back into your 'mainloop'. This is pretty
easy. Call IONotificationPortGetRunloopSource() then register the
this source with your applications runloop.
I have implemented a routine to create Notification Port and 'registered' it with the driver as per above. Q. Do I have to write my own 'custom' registerNotificationPort() method or can I use the one from the IOUserClient superclass ? Q. How do I notify the caller that the transfer has completed ? I have also implemented a routine to 'plumb' the completion routine back into the application's runloop. My problem is that, as described above, I don't have a runloop to plumb into. Q. What do I do here ? Can I create my own private runloop so that the I pass the buffer and it's length to the driver. These are extracted from a structure in the upper layers which contains more information about the contents of the buffer. Q. Can I pass in the address of the structure itself as a 'refcon' so that the completion notification can pass it back to the caller ? The driver does not need to access the structure, just pass it on. Thanks in advance for any advice, Peter Young (Struggling OSX PCI Driver developer) _______________________________________________ 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)
-
Peter Young