3.1 Entry Points, Functions, and Routines

This section provides prototypes for the entry points, functions, and routines required in a HAM by NWPA. A developer can use these prototypes to plumb the shell of a HAM. Detailed descriptions of the data structures and entry points can be found in Structures. To fit properly in the architecture, a HAM is required to provide the following:

Prototypes and definitions of these routines are the responsibility of HAM developers. Complete functional specifications of the entry points can be found in Functions, and descriptions of the HAM Type Zero functions can be found in HACB Type Zero Functions.

The name of each entry point is left to the discretion of the HAM developer; however, each entry point must provide the respective functionality described in this guide.

For consistency in referring to these entry points and HAM functions within the text and in code examples, this guide gives each a generic name having a HAM prefix. Whenever an entry point or function with this prefix is encountered, it indicates that the routine is HAM-specific. The italic typeface indicates that the name is arbitrary.

3.1.1 Load/Unload Entry Points

A HAM must provide three standard NLM entry points for the OS. These entry points are made visible to the OS through a definition (.def) file that is processed by the NLMLINK utility. A sample definition file is provided in Sample Definition File. The prototypes of these entry points, along with their generic names follow.

HAM_Load Point

HAM_Load is the HAM's load-time entry point. It is called when the systems operator issues a LOAD command on the HAM from the console. HAM_Load is called on a blocking thread. Through this entry point, a HAM receives its OS-generated resource handle (loadHandle), which is an ID to the LOAD console screen, and a pointer to the LOAD command line string that contains the hardware resource options that are specified by the systems operator. These hardware options include resources such as interrupts, DMA channels, memory decoding for memory-mapped I/O, ports, and even custom command-line options.

HAM_Load is responsible for allocating any resources needed to make the HAM operational, configuring the HAM (based on the hardware options specified on the LOAD command line), and registering the HAM and its I/O entry points with NWPA. The following is the prototype for HAM_Load:

    LONG HAM_Load (
       LONG   loadHandle, 
       LONG   screenID, 
       BYTE  *commandLine
    );
    

HAM_Unload_Check Point

HAM_Unload_Check is the HAM's initial unload-time entry point. It is called when the systems operator issues an UNLOAD command on the HAM from the console. HAM_Unload_Check is called on a blocking thread. It is responsible for checking to see if any of the HAM's devices are currently being used by an NLM application and return use-status. HAM_Unload_Check returns the use-status returned by NPA_Unload_Module_Check. For example:

    LONG HAM_Unload_Check (LONG screenID) 
       { 
       return(NPA_Unload_Module_Check(...)); 
       }
    

From this return value, the OS can determine if any of the devices managed by the HAM are locked. If any devices are locked, the OS displays a message at the console listing the devices that deactivate and the corresponding NetWare volumes that dismount if the action is continued. The user then has the option to either continue or abort the unload.

HAM_Unload Point

HAM_Unload is the HAM's final unload-time entry point, meaning that the unload thread already called HAM_Unload_Check and the systems operator chose to continue, so the unload thread was allowed to continue and call HAM_Unload. HAM_Unload unregisters the HAM from NWPA and returns allocated resources back to the system. Once the HAM is unloaded, all devices attached to the buses it was managing are inaccessible. The prototype for HAM_Unload is as follows:

    void HAM_Unload (void);
    

3.1.2 I/O Entry Points

A HAM must provide additional entry points that allow NWPA to route I/O requests to the module and to retrieve the resultant data. These entry points are made visible to the system when the HAM registers itself with NWPA by calling NPA_Register_HAM_Module. Additionally, all of these entry points have non-blocking context, meaning that they must perform their respective functions quickly and return control back to their respective calling processes. The prototypes of these entry points, along with their generic names, follow.

HAM_Execute_HACB Point

HAM_Execute_HACB is the HAM's entry point for receiving HACB I/O requests and routing them to their respective devices through the host adapter. As long as the host adapter can accept a request, HAM_Execute_HACB should issue it to the adapter and then return to the calling process. If the host adapter is temporarily unable to process a request (for example, due to a busy condition), HAM_Execute_HACB should place the request on an internal queue for the target device and return to the calling process. The fundamental rule for this entry point regarding a HACB I/O request is to do it or queue it.

    LONG HAM_Execute_HACB (
       LONG     hamBusHandle, 
       HACBDef *HACB); 
    
    

HAM_Abort_HACB Point

HAM_Abort_HACB is the HAM's entry point for receiving aborts on HACB requests. HAM_Abort_HACB locates the target HACB, posts an abort code, and returns the HACB to the CDM layer by calling HAI_Complete_HACB.

    LONG HAM_Abort_HACB (
       LONG               hamBusHandle, 
       struct HACBStruct *HACB, 
       LONG               flag); 
    
    

HAM_Check_Option Point

HAM_Check_Option is the HAM's entry point for receiving and verifying command line options. The entry point is called during two separate NWPA processes:

  • During the command line parsing phase of HAM initialization.
  • During the actual registration of hardware options.
    LONG HAM_Check_Option (
       struct NPAOptionStruct *option, 
       LONG                 instance, 
       LONG                 flag); 
    
    

The HAM invokes these two NWPA processes at different points in its load-time entry point, HAM_Load.

HAM_Software_Hot_Replace Point

This entry point is optional. The HAM needs to implement HAM_Software_Hot_Replace only if it plans to support hot replacement.

HAM_Software_Hot_Replace is the HAM's entry point for dynamically performing version updates. This entry point allows a later-version HAM driver to exchange configuration information with an earlier-version HAM that is currently loaded and operating on the server. The information exchange is in preparation for a dynamic swap of the modules without dismounting any volumes or disrupting the I/O channel for a lengthy period of time. At Novell, this process is called software hot replacement. For more details on how to implement this feature, see Software Hot Replacement.

    LONG HAM_Software_Hot_Replace (
       LONG   messageLength, 
       void  *message); 
    
    

HAM_ISR Point

HAM_ISR is the HAM's interrupt-time entry point, or interrupt service routine (ISR). The NetWare OS fields the actual hardware interrupt generated by the adapter board and routes its handling to the routine that registered for the interrupt. The HAM registers its ISR during its initialization entry point, HAM_Load, by calling NPA_Register_HAM_Module. The HAM registers the IRQ level it services by calling NPA_Register_Options during the hardware options registration phase of HAM_Load. HAM_ISR must provide logic to service completion of all I/O requests, provide the strategy for determining what device completed the request, post appropriate HACB completion codes, and initiate the next request on the device's process queue.

If the HAM intends to support software-hot-replacement, it can have only a single ISR.

    LONG HAM_ISR (LONG irqLevel); 
    
    

3.1.3 Timeout Routine

The HAM must provide a routine that times out HACB requests which grossly exceed expected device-process time. The purpose is to provide a mechanism to return process control back to the OS from a hung-device condition. The HAM's timeout routine runs as a periodic, background process, and it gets initially scheduled for triggering at load-time during HAM_Load. The prototype of this routine, along with its generic name, is as follows:

    void HAM_Timeout (LONG parameter);
    

HAM_Timeout is an asynchronous countdown-timer routine set up by calling NPA_Spawn_Thread. HAM_Timeout is triggered after the time interval specified as an input parameter to NPA_Spawn_Thread elapses.

NPA_Spawn_Thread is a one-shot API, meaning that it schedules the triggering of HAM_Timeout once per request. Therefore, after HAM_Timeout triggers and performs its task, it should reschedule itself by calling NPA_Spawn_Thread again in order to continue its periodic triggering.

HAM_Timeout allows the HAM to time out an I/O request when the time interval specified in the timeoutAmount field of the HACB expires. The timeout countdown begins when the HAM issues the request to the host. For more details about the countdown, refer to the description of the HACBStruct timeoutAmount field.

3.1.4 HACB Type Zero Functions

HAMs must allow different types of HACB requests to be processed. The HACB's type is the value in its hacbType field, which is set either by the CDM I/O routine building the HACB or by NWPA. The CDM or NWPA then fills the HACB's command area overlay with a command structure appropriate to the HACB's type.The hacbType = 0 requests contain adapter-specific Host Adapter command structures.

NWPA requires a HAM to implement functions that handle as many hacbType = 0 requests as are applicable to the adapter the HAM will manage. Some of the hacbType = 0 requests ask for information about the HAM, the host adapter, or attached devices. The HAM receives requests of this type through the union to the Host Adapter command block of the HACB.

Requests to perform these functions are received by the HAM in the form of HACB messages through the HAM's entry point. Prototypes for these functions are not given because their implementation is programmer dependent. HAM_Execute_HACB can either execute the statements that compromise the functions or call separate functions that contain these statements. The HAM determines which function to perform based on the parameters contained in the union to the Host adapter command block of the HACB. For more detailed descriptions, see HACB Type Zero Functions.

HACB Type Zero functions are also known as HAM functions, and they are static functions that can generally be completed immediately within the context of HAM_Execute_HACB.

For more information on the HACB type zero functions, see HACB Type Zero Functions.

3.1.5 Host Adapter Interface Routines

The HAM is expected to implement routines that use HACB information to construct appropriate command blocks in the adapter-specific protocol and issue them to the host. A HAM is required to support HACB requests only with a type suitable to the adapter it supports. The following table contains the current NWPA definitions for HACB request types:

hacbType = 1

Requests have an I/O command structure conforming to SCSI protocol. The HAM receives requests of this type through the union to the SCSI command block of the HACB.

hacbType = 2

Requests have an I/O command structure conforming to IDE-ATA/ATAPI protocol. The HAM receives requests of this type through the union to the IDE-ATA or the ATAPI command block of the HACB. The HAM determines whether the command is ATAPI by examining the device type or a flag that is set according to the device structure that is indicated by the device handle.

hacbType = 4

Requests have an I/O command structure conforming to SATA (Serial ATA) protocol. The HAM receives requests of this type through the union to the SATA command block of the HACB.

For whatever adapter type the HAM supports, it must provide the adapter-interface-specific routines that implement the respective commands.