Previous Book Contents Book Index Next

Inside Macintosh: Devices /
Chapter 4 - SCSI Manager 4.3

Writing a SCSI Interface Module

This section provides additional information that HBA developers need to write a SCSI interface module.

SIM Initialization and Operation

When SCSI Manager 4.3 is present in ROM, the Start Manager loads any SIM drivers it finds in the declaration ROM of all installed expansion cards. A SIM driver may contain the actual SIM, or it may contain code to load the SIM from some other location (such as a device attached to the expansion card). The Start Manager searches for SIM drivers using the Slot Manager SNextTypeSRsrc function, and loads all drivers matching the following criteria:
sResource typeConstantValue

After loading a SIM driver, the Start Manager calls the driver's open routine. If the SIM is contained in the driver, it should register itself with the XPT at this time. If the registration is successful, the open routine should return noErr. If the open routine returns an error result, the Start Manager removes the driver from the unit table and releases it from memory. A SIM loader can use this technique to remove itself after loading and registering the actual SIM. Because no other driver entry points are used, you do not need to implement the close, prime, status, or control routines, but they should return appropriate errors.

For Macintosh models that do not include SCSI Manager 4.3 in ROM, your SIM can either provide its own temporary XPT or wait until SCSI Manager 4.3 is installed by the system before registering with the XPT. If you wait for SCSI Manager 4.3 to load, devices on your bus cannot be used as the boot device or as the paging device for virtual memory but can be mounted after SCSI Manager 4.3 is running and your bus is registered.

If your SIM supplies its own XPT, your SIM and XPT must be prepared for the possibility that a system patch will install a new XPT later. To provide a consistent environment for driver clients of your SIM when the XPT is replaced, your XPT must maintain information about any virtual ID numbers it assigns (including a driver registration table) and correctly fill in the XPT fields of the bus inquiry record. When the SCSI Manager4.3 XPT loads, it uses the SCSIGetVirtualIDInfo, SCSILookupRefNumXref, and SCSIBusInquiry functions to query your XPT, then calls the SetTrapAddress function to install itself. Next, it uses your XPT to send a SCSIRegisterWithNewXPT command to each registered SIM. A SIM must respond by using the SCSIReregisterBus function to export its assigned bus number, entry points, and static data storage pointer to the new XPT. Finally, the SCSI Manager 4.3 XPT calls your XPT with a SCSIKillXPT command. Your XPT should then release any memory it has allocated and remove or disable any patches it may have installed.

Your XPT must reserve bus number 0 for the built-in SCSI bus. For Macintosh computers with dual SCSI buses, you must reserve bus numbers 0 and 1. If the SCSI Manager 4.3 XPT is installed after your XPT, it will assign these bus numbers to the built-in buses.

After determining the presence of the XPT, a SIM should register itself using the SCSIRegisterBus function. The SIM initialization record for this request contains the SIM's function entry points, required static data storage size, and the oldCallCapable status of the SIM. The SIM initialization record, defined by the SIMInitInfo data type, is shown on page 4-36. The XPT allocates the requested number of bytes for the SIM's static storage, fills in the appropriate fields of the SIM initialization record, and then calls the SIM's SIMInit function. If the SIMInit function returns noErr, the XPT completes the registration process, making the SIM available to the system. If SIMInit returns an error, the registration request fails.

Once the registration is complete, the XPT makes calls to the SIMAction entry point whenever a SCSIAction request is received that is destined for this bus. The XPT passes a pointer to the parameter block and a pointer to the SIM's static storage to the SIMAction function. The SIM should parse the parameter block for illegal or unsupported parameters and return an error result if necessary. After queuing the request, the SIMAction function should return to the XPT. When the request completes, the SIM calls the XPT's MakeCallback function with the appropriate parameter block. The XPT then calls the client's completion routine.

Other types of requests should be implemented to conform to the function descriptions provided in this chapter. Functions or features not implemented by the SIM should return appropriate errors (for example, scsiFunctionNotAvailable or scsiProvideFail).

The SIMInteruptPoll function is called during the Device Manager's synchronous wait loop to give time to the SIM when interrupts are masked. The sole parameter is a pointer to the SIM's static data, which is passed on the stack. Because this call does not imply the presence of an interrupt, the SIM should check for interrupts before proceeding.

The EnteringSIM and ExitingSIM functions provide compatibility with the Virtual Memory Manager and should be called every time the SIM is entered and exited, respectively. In other words, these two function calls should surround all SIM entry and exit points, including interrupt handlers and callbacks to client code made through the MakeCallback function.

Parameter blocks must appear to the client to be queued on a per-LUN basis, because queue freezing and unfreezing are performed one LUN at a time. The actual implementation may vary as long as this appearance is maintained.

Supporting the Original SCSI Manager

If your SIM indicates that it is capable of supporting original SCSI Manager functions, the XPT adds it to the list of buses that are searched when a SCSISelect request is received.

The XPT is responsible for converting original SCSI Manager functions into the proper format and submitting them to the SIM. It also receives the results for each of the functions from the SIM and returns them to the client.

When it receives a SCSIGet request, the XPT simply notes that the call was made by setting an internal flag, then returns to the caller. In response to a SCSISelect request, the XPT generates a SCSIOldCall request and submits it to the SIM's SIMAction entry point. The scsiDevice field of the parameter block contains the bus number of the SIM, the target ID specified in the SCSISelect request, and a LUN of 0. This parameter block should be queued like any other.

When your SIM receives a SCSIOldCall request, it should attempt to select the device and return a result code to the XPT in the scsiOldCallResult field of the parameter block (scsiRequestComplete if successful and scsiSelectTimeout if not). Intermediate function results are not communicated through the scsiResult field because this would be interpreted as completion of the entire transaction rather than only the portion of the transaction resulting from a single original function. As subsequent original function calls are made, the XPT fills in the appropriate fields of the parameter block and calls the SIM's NewOldCall entry point. Table 4-1 shows the original function parameters and the fields that are filled in by the XPT.
Table 4-1 Original SCSI Manager parameter conversion
FunctionParameterDirectionParameter block fieldNotes
SCSIGet   XPT handles internally.
SCSISelecttargetID-->scsiDevicebus set by XPT, LUN = 0.
Field is a pointer.
SCSIRead, SCSIWrite, SCSIRBlind,
tibPtr-->scsiDataPtrField is a pointer.
Field contains status.
Field contains message.
Time in Time Manager format.
SCSIMsgInmessage<--scsiSCSImessageField contains message.
SCSIMsgOutmessage-->scsiSCSImessageField contains message.
SCSIReset  Translated to SCSIResetBus.
SCSIStat  XPT handles internally.

To provide the highest level of compatibility with the original SCSI Manager, a SIM should be able to perform a SCSI arbitration and select process independently of a SCSI message-out or command phase. A SIM that requires the CDB or message-out bytes in order to perform a select operation will be unable to execute the SCSISelect function properly, and must always return noErr to a SCSISelect request. This can create a false indication of the presence of a device at a SCSI ID, causing all future SCSISelect requests to that SCSI ID to be directed only to that bus. Devices installed on buses that registered after that bus would not be accessible through the original interface.

Handshaking of Blind Transfers

Handshaking instructions are used to prevent bus errors when a target fails to deliver the next byte within the processor bus error timeout period. This timeout is 250 milliseconds for the Macintosh SE and 16 microseconds for all Macintosh models since the Macintosh II.

The SCSI Manager 4.3 SIM requires this handshaking information for blind transfers when DMA is not available. Your SIM does not need to pay attention to the scsiHandshake field unless your hardware requires it.

Supporting DMA

DMA typically requires that the data buffer affected by the transfer be locked (so that the physical address does not change) and that it be non-cacheable. SCSI Manager 4.3 provides an improved version of the LockMemory function, which you can call at interrupt time as long as the affected pages are already held in real memory. You can also call the GetPhysical function at interrupt time, but only on pages that are locked.

Loading Drivers

The Start Manager is normally responsible for loading SCSI drivers. However, if the startup device specified in PRAM is on a third-party HBA and the SIM is a Slot Manager device, the Start Manager will call the boot record of the card's declaration ROM. The boot record code should examine the dCtlExtDev field to determine which SCSI device is the startup device and then load a driver from that device (and only that device).

All other drivers are loaded by the Start Manager, but SIMs are given the opportunity to override this if necessary. Before the Start Manager attempts to load a driver from a device, it calls the SIM with a SCSILoadDriver request. If the function succeeds, the Start Manager does nothing further with that device. If the function fails (the normal case), the Start Manager reads the partition map on the device and loads a driver from it. If this fails, the Start Manager calls the SIM again with a SCSILoadDriver request, this time with the scsiDiskLoadFailed parameter set to indicate that no driver was available on the media.

This facility allows a SIM to provide a default driver to be used instead of any driver that may be on the device. For example, if a SIM does support the original SCSI Manager, it can use the second SCSILoadDriver request to load a SCSI Manager 4.3-compatible driver if none is present on the device.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
3 JUL 1996