With current versions of Mac OS, you can write a native SIM by using the Mixed Mode Manager and passing universal procedure pointers to the transport (XPT) layer when registering the SIM. Native SIMs should also use CallUniversalProc when calling XPT routines.
PCI native SIMs are implemented similarly to other native drivers. The SIM installs a driver in the device tree with a driver,AAPL,MacOS,PowerPC property. Like other native drivers, SIMs export a driver description structure. The SCSI expert identifies a SIM by examining the service categories supported in the driver descriptor. SIMs have a serviceCategory of type kServiceCategoryScsiSIM. A driver supporting this service category should export a function named LoadSIM with the following interface:
OSErr LoadSIM (RegEntryIDPtr entry);
The SCSIexpert prepares the code fragment and calls this function after the SCSI transport layer is initialized. In response, the SIM should initialize itself the same way a NuBus SIM would by calling SCSIRegisterBus, as described in Inside Macintosh: Devices. Any nonzero result returned from LoadSIM causes the code fragment to be unloaded. Note that this is a ProcPtr -based interface, so you must pass UniversalProcPtr structures for all entry points. Those passed back by the XPT will also be UniversalProcPtr structures so native code should use CallUniversalProc when calling XPT layer procedures from the SIMInitRecord.
An typical PCI-based SIM descriptor is shown in Listing 15-1.
DriverDescription TheDriverDescription =
{
// signature information
kTheDescriptionSignature,
kInitialDriverDescriptor,
// type info
"\pFor Rent ",
1,0,0,0, // major, minor, stage, rev
// OS runtime info
kDriverIsUnderExpertControl,
"\p.MySCSISIM ",
0,0,0,0,0,0,0,0, // reserve 8 longs
// OS service info
1, // number of service categories
kServiceCategoryScsiSIM,
0,
1,0,0,0 // major, minor, stage, rev
};
For the Startup Disk control panel to be able to select a boot device from a SIM correctly, the SCSIBusInquiry fields scsiHBAslotNumber and scsiSIMsRsrcID must uniquely identify the SIM from other SIMs and PCI cards. Each SIM should identify itself when registering with the system by placing a RegEntryID value in the SIMInitInfo parameter block. The XPT layer will calculate unique values for the SCSIBusInquiry fields and supply them to the SIMInit routine. From then on the SIM must return these values from SCSIBusInquiry. Three new fields-- simSlotNumber, simSRsrcID, and simRegEntry --have been defined in the SIMInitInfo parameter block to hold these values. The new parameter block is defined as follows:
UInt8 *SIMstaticPtr;
long staticSize;
SIMInitUPP SIMInit;
SIMActionUPP SIMAction;
SCSIInterruptUPP SIM_ISR;
SCSIInterruptUPP SIMInterruptPoll;
SIMActionUPP NewOldCall;
UInt16 ioPBSize;
Boolean oldCallCapable;
UInt8 simInfoUnused1;
long simInternalUse;
SCSIUPP XPT_ISR;
SCSIUPP EnteringSIM;
SCSIUPP ExitingSIM;
SCSIMakeCallbackUPP MakeCallback;
UInt16 busID;
UInt8 simSlotNumber; // output
UInt8 simSRsrcID; // output
RegEntryIDPtr simRegEntry; // input