To replace the IODone routine and its associated low memory global jIODone, a new routine has been added to the Device Manager called IOCommandIsComplete. The difference between IODone and IOCommandIsComplete is that while IODone initiates request completion processing for a request that is implicitly designated by the request queue head, a caller of IOCommandIsComplete must explicitly specify the request that is to be completed.
After a nonimmediate IOCommandKind command has been accepted, the driver performs the actions implied by the command and the IO parameter block contents. When the command has been processed, the driver must complete the command.
The driver must identify the command it is completing; this is done by passing the command ID to IOCommandIsComplete. The command ID is provided to a driver as the first parameter to its I/O entry point, as well as being stored in the IO parameter block's ioCmdAddr field ( ThePb -> ioParam.ioCmdAddr ).
As a result of a completion, the Device Manager takes several actions. If the command was performed synchronously, the I/O trap finishes. If the command was performed asynchronously, the requested I/O completion routine is invoked. The routine IOCommandIsComplete stores the status value in the I/O parameter block result field. It also starts the next request if the driver isn't concurrent and there is a request queued. The driver should never try to modify result.
Under current versions of the Mac OS command ID == ¶m block. Your driver should not rely on this always being true.