The IOS carries out port registration for port drivers. Such drivers usually have direct access to the device hardware and typically register at the lowest initialization layers.
The IOS first sends a packet for an AEP_INITIALIZE function to the driver's asynchronous event routine. The packet consists of an AEP_bi_init structure in which the IOS has set these members:
AEP_func | AEP_INITIALIZE |
AEP_lgn | Current initialization layer |
AEP_bi_i_hdevnode | Address of device node for the driver |
AEP_bi_i_dcb | Inquiry DCB structure |
AEP_bi_flags | 0 |
AEP_bi_reference_data | Reference data from the driver's DRP structure |
All other members are undefined.
When the driver receives this function, the driver creates one or more DDB structures using the ISP_CREATE_DDB function (sent to the IOS service routine whose address is given by the ILB_service_rtn member). The ISP_CREATE_DDB function creates a DDB structure of a given size and adds it to the chain of DDB structures associated with the DVT structure for the driver. After the driver has created the DDB structures, it indicates success by setting the AEP_result member to AEP_SUCCESS and returning to the IOS.
If a port driver successfully completes initialization, the IOS sends a AEP_DEVICE_INQUIRY function to the driver. The IOS sets the AEP_i_d_dcb member to the address of a DCB structure called the inquiry DCB. This structure includes a 0-based unit number identifying the unit that the IOS is querying. If the given unit exists, the driver sets the DCB_product_id, DCB_vendor_id and DCB_rev_level members to appropriate values and returns AEP_SUCCESS. The IOS then sends an AEP_CONFIG_DCB function to all the layer drivers.
If the given unit does not exist, the driver returns AEP_NO_INQ_DATA to direct the IOS to inquire about the next unit. If the given unit number is greater than the maximum number of units supported by the device, the driver returns AEP_NO_MORE_DEVICES to stop the inquiry. The IOS continues to send AEP_DEVICE_INQUIRY functions until the driver returns AEP_NO_MORE_DEVICES or the IOS has sent 128 (units 0 through 127) functions for the given DDB structure.
The IOS automatically repeats the entire initialization sequence, starting with the AEP_INITIALIZE function, for the port driver if the port driver controls more than one controller. Although not typically needed, a port driver can also direct the IOS to repeat the initialization sequence by setting the AEP_bi_flags member to AEP_BI_FL_SEND_CONFIG_AGAIN.
If a SCSI port driver initializes successfully, IOS makes as many inquiries as is specified in AEP_bi_i_max_target member returned in response to the AEP_INITIALIZE function. The IOS uses the scan order specified by the AEP_bi_flags value. If AEP_BI_FL_SCSI_SCAN_DOWN is set, the IOS scans in the reverse order.
Then the IOS sends a packet for an AEP_CONFIG_DCB function. The packet consists of a AEP_dcb_config structure in which the IOS has set these members:
AEP_func | AEP_CONFIG_DCB |
AEP_lgn | Current initialization layer |
AEP_d_c_dcb | Initialized DCB structure |
AEP_ddb | Current DDB structure |
The driver processes the AEP_CONFIG_DCB function by setting the various members of the DCB structure to values specifying geometry information, such as cylinder count and sector count. The driver then inserts itself in the calldown list for the DCB by the ISP_INSERT_CALLDOWN function (sent to the IOS service routine whose address is given by the ILB_service_rtn member). The ISP_INSERT_CALLDOWN function places the address of the driver's I/O request handling routine in the list. To indicate success, the driver sets the AEP_result member to 0 and returns to the IOS. To complete the function, the IOS creates a real DCB and fills it with information supplied by the driver.
The IOS completes port registration by sending the AEP_BOOT_COMPLETE function to all drivers. The function is a notification to the driver to unload itself if desired. For example, a VSD may choose to unload if it has determined that it has inserted itself in none of the DCBs in the system. A driver unloads itself by returning AEP_FAILURE. This directs the IOS to deregister and unload the driver. No DDB pointer is passed with the function, so the driver receives the call once only.
In some cases, the IOS may send an AEP_CONFIG_DCB command before sending an AEP_DEVICE_INQUIRY function. In particular, the IOS does this if the driver has set the DRP_IO_FOR_INQ_AEP bit in the DRP_feature_code member of its DRP structure. This bit indicates that the driver needs to issue I/O requests to process the AEP_DEVICE_INQUIRY function. During port registration, the IOS checks for this bit and passes a packet for an AEP_CONFIG_DCB function for the given DCB prior to calling AEP_DEVICE_INQUIRE functions. The driver processes this call by inserting the driver's I/O request handler in the calldown stack of the DCB.
AEP, DCB, DDB, DRP