Q: Does anyone make use of an intercepting completion-routine for a
block-storage-device driver?
If so, do you have any suggestions for how best to properly access the
IOMemoryDescriptor buffer contents from within that completion routine
as I have a situation where it appears (to me) I am doing nothing
wrong but can pretty reliably create a panic. This error occurs in
both 10.2.8 and 10.3.X
// ----------------------------------------------------------
Briefly - here's the situation:
A) My generic block driver overrides a variety of
'IOBlockStorageDriver' that matches my media.
B) My app places vanilla, synchronous, device-calls like 'read(fd,
buf, siz)' commands to the OS
C) The driver may decide to manipulate some of the data on it's way
back from the lower level drivers. If so, my driver driver redirects
the completion call to itself.
D) In the completion call of my driver, data is read from and written
to the buffers of existing IOMemoryDescriptors. There is never an
'out-of-range' access or error. Prior to the panic, the data is
always successfully accessed, modified, and returned intact to my app.
There is never an exception incurred as part of the execution of my
completion routine.
E) At the end of my completion routine, the original completion
routine struct is passed on.
F) At some cumulative point - where I may have transferred a few
hundred megabytes of data thru this mechanism - a kernel panic occurs.
Depending on how quickly I might make calls, this can occur in a
couple of minutes or a couple of hours.
// ----------------------------------------------------------
If curious about the specifics: In my driver's 'read' call, I do the
following to prepare to service the returned data via my completion
routine:
// *** SETUP FOR COMPLETION CALL ***
// -----------------------------------------------------------
// static array of original completion routine struct contents
sSavedStorageCompletion[mStorageCompletionIndex] = completion;
// save off IOMemoryDescriptor* from original read-call args
sIOMDBuffers[mStorageCompletionIndex] = buffer;
// substitute local completion address into struct
completion.action = MyStorageCompletion; // call here when done
completion.target = (void*) this; // pass in ptr to this obj
completion.parameter = (void*)(mStorageCompletionIndex); // index to
saved data
mStorageCompletionIndex++; // maintain index for use with next
call
if( mStorageCompletionIndex >= kIOStorageCompletionMax)
mStorageCompletionIndex = 0;
I then send the substitute 'completion' struct off to the super to
actually read the data
// ----------------------------------------------------------
// *** COMPLETION CALL ACTIVITY ***
IOMemoryDescriptor* memoryDesc = sIOMDBuffers[dex];
IOStorageCompletion completion = sSavedStorageCompletion[dex];
int bufrlen = memoryDesc->getLength();
bytesRead = memoryDesc->readBytes(0, (void*)mybuf, bufrlen));
<do reads and writes to data in IOMemoryDescriptor buffer>
bytesWritten = memoryDesc->writeBytes(bytesRead, mybuf, bytesRead);
(*completion.action)( completion.target, completion.parameter,
status, actualByteCount);
// ----------------------------------------------------------
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-drivers mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/darwin-drivers/email@hidden
This email sent to email@hidden