HACBStruct
A data structure, or message packet, packing I/O requests into a protocol-specific command block (such as SCSI or IDE-ATA).
typedef struct HACBStruct { LONG hacbPutHandle; LONG hacbCompletion; LONG controlInfo; WORD hacbType; WORD timeoutAmount; LONG deviceHandle; LONG dataBufferLen; void *vDataBufferPtr; void *pDataBufferPtr; LONG errorSenseBufferLen; void *vErrorSenseBufferPtr; void *pErrorSenseBufferPtr; LONG reserved[6]; struct HAMSpaceStruct { BYTE remainder[64]; } hamSpace; union /* Command Block Overlay Area */ { struct /*HACB Type = 0: Host Adapter Cmd Structure */ { LONG function; LONG parameter0; LONG parameter1; LONG parameter2; BYTE reserved[12]; }host; struct /*HACB Type 1:SCSI Adapter Cmd Structure */ { BYTE cdb[16]; BYTE reserved[11]; BYTE cdbLen; }scsi; struct /*HACB Type 2: IDE-ATA Adapter Cmd Structure/* /* Note: This is one of two cases of the Type 2 HACB */ { BYTE sectorCount; BYTE LBALow; BYTE LBAMid; BYTE LBAHigh; BYTE device; BYTE command; BYTE sectorCount1; BYTE LBALow1; BYTE LBAMid1; BYTE LBAHigh1; BYTE reserved[17]; BYTE capabilities; }ata; struct /*HACB Type 2: IDE-ATA ATAPI Cmd Structure */ /* Note: This is one of two cases of the Type 2 HACB */ { BYTE feature; BYTE byteCountLow; BYTE byteCountHigh; BYTE deviceHead; BYTE command; BYTE packet[16]; BYTE reserved[7]; }atapi; struct /*HACB Type 3:CDM Custom Cmd Structure*/ { LONG function; LONG parameter0; LONG parameter1; LONG parameter2; LONG returnParameter; BYTE reserved[8]; }custom; struct /*HACB Type 4: SATA (Serial ATA) Cmd Structure*/ { BYTE reserved0[2]; BYTE command; BYTE features; BYTE LBALow; BYTE LBAMid; BYTE LBAHigh; BYTE device; BYTE LBALow1; BYTE LBAMid1; BYTE LBAHigh1; BYTE features1; BYTE sectorCount; BYTE sectorCount1; BYTE capabilities; BYTE reserved1; BYTE packet[12]; }sata; }command; }HACBDef;
CDMs and HAMs must not alter this handle. Also, do not confuse this field with the msgPutHandle field of the CDMMessageStruct. Their values and purposes are different.
NWPA uses this handle to track a HACB through different execution stages. Many of the APIs described in this manual, such as HAI_Complete_HACB, need this handle as an argument. When a SuperHACB is first allocated using CDI_Allocate_HACB, NWPA initializes this field of the enveloped HACB with a value. When the HACB is sent for execution (this occurs when a CDM calls either CDI_Execute_HACB or CDI_Blocking_Execute_HACB on the HACB) NWPA generates and places a new value in this field handle.
NWPA allows for status codes under the following interfaces:
This field is set by the HAM. The HAM completes a HACB request by calling HAI_Complete_HACB, which then informs the CDM layer. The HAM routine handling HACB completion, however, must post status to this field prior to calling HAI_Complete_HACB. The CDM reads the value in this field during its callback entry point, CDM_Callback, to determine whether the HACB completed successfully or not, and to determine the target device's current queue state. A hierarchy is associated with the status values placed in this field. The upper WORD (16 bits) indicates the following:
The lower WORD gives further resolution by being a qualifier that indicates additional status information. For some categories, however, the value in the lower WORD is either not applicable or undefined in NWPA. For processor independence reasons, this field needs to be processed as a LONG. Therefore, HAMs and CDMs must use macros to encode and decode this field. The HAM can use the following macro and use it to encode a HACB's completion status:
#define SET_STATUS(UpperWord, LowerWord) ((UpperWord)<<16) | ((LowerWord) & 0xFFFF))
The CDM can use the GET_MSW or GET_LSW macros and use them in its callback to decode the completion status of the HACB and the device, respectively. These macros are defined as follows:
The CDM can use the GET_MSW or GET_LSW macros and use them in its callback to decode the completion status of the HACB and the device, respectively. These macros are defined as follows:
#define GET_MSW(hacbCompletion)(((hacbCompletion)>>16) & 0xFFFF)
#define GET_LSW(hacbCompletion)((hacbCompletion) & 0xFFFF)
Section 11.1, HACB Completion Codes lists the HACB completion status values currently defined in NWPA along with a detailed set of descriptions for each value.
When the HACB direction is from the CDM to the HAM, it generally indicates that the CDM has received an I/O message from an upper layer for which it will build a HACB I/O request recognized by the HAM. In this case, this field is to contain a bitmap of operational control flags. These flags are set by the CDM to indicate operational conditions associated with a HACB request. The HAM reads these flags to determine the conditions specified by the CDM. The setting of control flags for a HACB request reflects the most common use of this field. The CDM control or I/O routine that is building the HACB has the flexibility to toggle these flags to set the proper combination needed for the request.
The following table lists the control flag values currently defined in NWPA along with their respective descriptions.
Flag Value |
Description |
---|---|
0x00000001 |
Bit 0 (LSB) is the Priority_HACB_Bit. When set, it indicates to the HAM that this request is a priority request, giving it precedence over non-priority requests in the HAM's device process queue. When cleared (zero), it indicates that this request is a non-priority request. Priority requests are ordered on a Last-In-First-Out (LIFO) basis. |
0x00000002 |
Bit 1 is the Data_Direction_Bit. When set, data flow is to the device. When cleared, data flow is from the device. |
0x00000004 |
Bit 2 is the Freeze_Queue_Bit. The CDM can cause single-step execution of HACB requests by toggling this bit. If the CDM sets this bit in the HACB-and sends the HACB to the HAM for processing, it indicates to the HAM that it must freeze this device's process queue immediately after issuing this HACB request to the device. If the CDM clears the bit (zero), it indicates to the HAM to continue normal operation of the device’s process queue even after issuing this HACB to the device. Bit 9 (No_Freeze_Queue_Bit) and this bit cannot both be set at the same time. If both bits are set, a Malformed HACB (0x0003000B) error will result. |
0x00000008 |
Bit 3 is the Timeout_Granularity_Bit. When set, the bit indicates that the value specified in the timeoutAmount field is in minutes. When cleared, the bit indicates that the value specified in the timeoutAmount field is in seconds. |
0x00000010 |
Bit 4 is the Scatter_Gather_Bit. When set, it indicates the following to the HAM:
When cleared, it indicates the following:
|
0x00000020 |
Bit 5 is currently reserved by NetWare. |
0x00000040 |
Bit 6 is the Preserve_Order_Bit. When set, the HAM preserves the current request order in the device queue. When cleared, the requests in the device queue can be ordered as prescribed by the HAM. This feature is provided so that a CDM supporting sequential devices can control the order of request execution. |
0x00000080 |
Bit 7 is the No_Disconnect_Bit for use with SCSI. When set, it indicates no disconnect. |
0x00000100 |
Bit 8 is the No_Data_Transfer_Bit. When set, it indicates that the issued request does not require the transfer of data, and the function of the Data_Direction_Bit is ignored. If the CDM sets this flag it must also zero out the HACB's dataBufferLen field. Setting this flag does not affect the HACB's error sense buffer or its length. When cleared, it indicates that the issued request requires the transfer of data. The direction of transfer is indicated by the Data_Direction_Bit |
0x00000200 |
Bit 9 is the No_Freeze_Queue_Bit. The CDM can prevent the queue from being frozen regardless of error condition by setting this bit. Bit 2 (Freeze_Queue_Bit) and this bit cannot both be set at the same time. If both bits are set, a Malformed HACB (0x0003000B) error results. |
0x00000400 |
Bit 10 is the Master_HACB_Bit. This is a specialized HACB used to send special commands when HACBs have been disabled using NPA_Config. This HACB will bypass the NPA_Config. |
0x00000800 to 0x80000000 |
Bits 11 through 31 (MSB) are reserved by NetWare. |
When the HACB direction is from the HAM to the CDM, it generally indicates that the device has completed the I/O request, and the HAM is ready to post completion status and send the HACB back to the CDM.
For IDE-ATA drivers, the controlInfo field contains the following information:
This field value is set either by the CDM, through one of its control or I/O routines, or by NWPA. The CDM or NWPA fills the HACB's command block overlay area with a command structure appropriate to the HACB’s type.
By checking this field, the HAM can determine what command structure to expect in the HACB.
The requests can be hacbType = 0 through 3, or hacbType = novellAssignedModuleID. If the request is not a hacbType = 0 request or the hacbType does not match the adapter haType (see HAMInfoStruct), the hacbType must be the novellAssignedModuleID. The HAM must check this field and report an Unsupported Interface Type (0x00030044) error if the novellAssignedModuleID is not supported. The HAM must otherwise service the request and send the appropriate command to the device as needed.
The following table defines the HACB request types.
The main purpose of this time limit is to provide a recovery point (see HAM_Timeout) from a hung device. CDMs are required to set a value in this field for all non-zero type HACBs (hacbType =1 or 2) it issues to the HAM. The timeout countdown begins when the HAM issues the request to the device. The time spent in the HAM's device queue is not included in the countdown. However, because the HAM might not have any control over a request after it is issued, time spent queued in hardware caches on the adapter (and/or on the device) is included in the countdown. The CDM sets the value in this field because it has the device-specific intelligence to know how long a request should take to complete. However, because a request might spend additional time queued in caches (particularly a cache on the adapter of which the CDM may not be aware), the CDM should allow leeway in assigning this value. The general rule that a CDM should follow is to set an optimal value that will cause a timeout only if typical process time is grossly exceeded. The CDM indicates the timeout granularity, in seconds or minutes, by setting Timeout_Granularity_Bit (0x00000008) in the HACB's controlInfo field. When the bit is set, the granularity is in minutes. When the bit is not set, the granularity is in seconds.
NOTE:NOTE: The HAM can receive hacbType = 0 requests with this field set to zero. Generally, these requests are asking the HAM to perform adapter-specific functions for which NWPA has no way of knowing how much time it should take to complete. An example would be a request for the HAM to scan the host bus for attached devices.
For these hacbType = 0 requests, the HAM must make a reasonable decision as to the amount of time it will allow the request to process before timing it out. The HAM must ensure that these requests never hang.
This field is set by the CDM I/O routine that builds the HACB request. The HAM generates this handle and reports it to NWPA. The HAM must be able to locate its devices and their respective queues from this handle. NWPA then makes this handle available to the CDM. In order for a CDM to channel requests to a target device, it must provide the appropriate HAM-generated device handle in this field of the HACB.
If the flag is set, this field contains the number of elements in NWPA-generated scatter/gather request list. If the flag is not set, this field contains the length, in bytes, of the request's data buffer. In either case, the field is set by the CDM I/O routine that builds the HACB. This value is obtained from the bufferLength field of the corresponding CDM message [see CDMMessageStruct] associated with the HACB. NWPA passed a pointer to this CDM message as an input parameter to the CDM's entry point that received the HACB.
NWPA provides this field to support host adapter boards that use programmed I/O. The CDM I/O or Control routine that builds the HACB places the appropriate value in this field, which it obtains from the buffer field of the CDM Message [see CDMMessageStruct] associated with the HACB. NWPA passed a pointer to this CDM Message as an input parameter to the CDM's entry point that received the HACB. The structure of the buffer it points at depends on whether or not the Scatter_Gather_Bit is set. If the flag is set, this field contains the virtual starting address of the scatter/gather request list. The scatter/gather list is either generated by an NWPA filter or a Media Manager NLM application. If the flag is not set, this field contains the virtual address of the request's data buffer.
NWPA calculates the physical (absolute) address of the buffer pointed at by vDataBufferPtr and places the address in this field. NWPA provides the physical address to support adapters that use DMA or bus-mastering.
The structure of the buffer it points at depends on whether or not the Scatter_Gather_Bit is set.
In either case, calculating this field value is not the concern of the CDM at HACB build time. However, for safety, the CDM I/O routine building the HACB should initialize the field to zero. After the CDM I/O routine calls CDI_Execute_HACB, NWPA calculates the physical address and places it in this field before sending the HACB to the HAM. Refer to Section 2.3, Scatter/Gather List for a description of NWPA's scatter/gather format and how it affects this field.
NOTE:NWPA guarantees this buffer to be physically contiguous.
This field's value specifies the size, in bytes, of the error sense buffer pointed at by the vErrorSenseBufferPtr and pErrorSenseBufferPtr fields. Essentially, the value of this field should be the size of NWPA's ErrorSenseInfoStruct plus any additional error sense bytes the CDM chooses to append to this structure.
NWPA provides this field to support host adapter boards that perform auto error sense under programmed I/O. When the CDM detects that auto error sense is active for a target device, it allocates an I/O contiguous buffer (using NPA_Allocate_Memory) and assigns the buffer's NetWare logical address to this field. The structure of this buffer is defined by NWPA's ErrorSenseInfoStruct plus any additional error sense bytes the CDM chooses to append to this structure. For adapters with auto error sense turned on, the HAM must copy auto error sense information into the buffer pointed at by this field.
NWPA calculates the physical (absolute) address of the buffer pointed at by vDataBufferPtr and places the address in this field. NWPA provides the physical address to support adapters that use DMA or bus-mastering. Calculating this field value is not the concern of the CDM at HACB build time. However, for safety, the CDM I/O routine building the HACB should initialize the field to zero. After the CDM I/O routine calls CDI_Execute_HACB, NWPA calculates the physical address and places it in this field before sending the HACB to the HAM.
NOTE:NWPA guarantees this buffer to be physically contiguous.
This field can be used for anything necessary to complete the HACB request, such as linked list management of the HACB queue or custom command blocks such as disk structures, card structures, or control blocks. This parameter is referenced in NPA.H. The only restriction is that this structure must be exactly 64 bytes.
As a reminder for the HAM, the HACB is not guaranteed to be below the 16-megabyte boundary, which might affect how this field can be used. Additionally, this field is uninitialized.
This section describes the different structures defined for the HACB's command overlay area (union). NWPA defines the following types of command structures for this area:
The CDM I/O routine that builds the HACB is responsible for selecting the appropriate structure, setting the structure's fields, and setting the hacbType field, all of which are based on the adapter type the CDM is designed to support.
The HAM that receives the HACB can verify that the HACB is compatible with the adapter type it is designed to support by reading the value in the hacbType field.
The Host Adapter Command Structure corresponds to hacbType = 0 requests. This structure is used when adapter-specific commands are issued such as scanning for attached devices or getting adapter-specific information. Its field descriptions are as follows:
The following table maps the possible values for this field to their corresponding HAM functions. Full descriptions of these HAM functions can be found in HACB Type Zero Functions.
The SCSI Adapter Command Structure corresponds to hacbType = 1 requests. This structure is used when a command is issued to a device attached to a SCSI adapter.
Its field descriptions are as follows:
The IDE-ATA Adapter Command Structure corresponds to hacbType = 2 requests. This structure is used when a command is issued to a device attached to an IDE-ATA adapter. There are two cases of this HACB type, depending on the IDE standard being used (IDE-ATA vs. ATAPI).
The field descriptions for the IDE-ATA case are as follows:
The high capacity bit (0x04) must be set for the IDE driver to recognize the sectorCount1, LBALow1, LBAMid1, and LBAHigh1 register values. Setting this bit on devices that do not recognize these registers might result in an error and a failed request. If bit 10 (0x0400) is set in word 86 of the drive's IDENTIFY DEVICE table, the device is 48-bit compatible.
For the IDE driver to perform Auto Error Sense (see Section 3.7, Auto Error Sense), the auto error sense bit (0x08) must be set. When set, the IDE driver performs a REQUEST SENSE command during the context of its ISR that immediately follows the detection of an IDE check condition. It returns the sense information in the structure pointed to by the HACB's vErrorSenseBufferPtr, provided that it points to a valid error sense buffer that was set up by the CDM. Using this functionality eliminates the CDM having to send the HAM a separate Request Sense command to detect errors.
The ATAPI Adapter Command Structure corresponds to hacbType = 2 requests. This structure is used when a command is issued to a device attached to an IDE-ATA adapter, which supports the interface defined in the ATA Packet Interface for CD-ROMs specification, SFF-8020.
The field descriptions for the ATAPI case are as follows:
The Custom HAM corresponds to hacbType = 3 requests. The custom HAM allows the developer to write a monolithic device driver intended to control and access specialized hardware that does not fit into either the SCSI or IDE paradigms.
The custom HAM performs the role of both CDM and HAM by accepting CDM messages (encapsulated within a HACB) and issuing requests to the adapter hardware. The function, parameter0, parameter1, and parameter2 fields are identical to the fields in the CDMMessageStruct. Its field descriptions are as follows:
The SATA Adapter Command Structure corresponds to hacbType = 4 requests. This structure is used when a command is issued to a device that is attached to a Serial ATA adapter and reflects the Register - Host to Device structure that is specified in the Serial ATA: High Speed Serialized AT Attachment Revision 1.0a Specification.
The field descriptions for the SATA case are as follows:
For the SATA driver to perform Auto Error Sense, the auto error sense bit (0x08) must be set. When set, the SATA driver performs a REQUEST SENSE command during the context of its ISR that immediately follows the detection of an ATA check condition. It returns the sense information in the structure pointed to by the HACB’s vErrorSenseBufferPtr, provided that it points to a valid error sense buffer that was set up by the CDM. Using this functionality eliminates the CDM having to send the HAM a separate REQUEST SENSE command to detect errors.
The HACB structure is a data packet containing a device control or I/O command issued by a CDM or NWPA. HACBStruct defines the HACB structure and gives a description of its fields.
Certain fields in the HACB are pre-initialized by NWPA at allocation, and their values must be maintained. Therefore, do not clear or zero out the HACB. In the SFT III™ (System Fault Tolerance) environment, only the data in the HACB's data buffer, error sense buffer, hacbCompletion, and controlInfo fields get mirrored between the fault tolerant servers.
The HACB is encapsulated in the Super Host Adapter Control Block [HACBStruct or SuperHACBStruct], which is a data structure providing additional space for CDM developers to attach additional CDM state information. The CDM uses a SuperHACB to build a device-specific I/O request from a CDM message [see CDMMessageStruct] it receives from NWPA.
As a data member of the SuperHACB, the CDM places device specific commands in the HACB and initiates its execution by sending it to the HAM via NWPA. The HAM passes the information in the HACB to the target device for processing.
This structure is passed between a Custom Device Module (CDM) and a Host Adapter Module (HAM) via NWPA. These modules interface with NWPA through the CDI and HAI interfaces, respectively.
Certain fields in the HACB are pre-initialized by NWPA at allocation, and their values must be maintained. Therefore, do not clear or zero out the HACB.