3.3 HAM Device Queues

A HAM is required to implement and manage a HACB request queue for each device attached to the adapter it supports. Queue management routines are to be provided by the HAM, and they must implement the behavior outlined in this subsection.

If a HAM supports an adapter that can queue requests on the adapter, it needs to implement whatever measures are necessary to ensure that the queue state protocol discussed in this section is followed.

This section covers the following topics:

3.3.1 Request Hierarchy

HACB Type 0 requests have highest priority and should be executed immediately in the order they are received. HACB Type 0 requests really do not have to be queued because they map to HAM-specific functions that do not require processing by a device. An example is the request corresponding to HAM_Return_Bus_Info (Function 0x00). This function merely returns information about the HAM and can be completed immediately. HACB Type 0 requests can happen at any time, and if they need to be queued, they should probably be placed in a separate queue explicitly for HAM functions rather than in a device queue. Other HACB Type (1, 2, 3) requests do map to specific devices, so they do need to be queued if they cannot be executed immediately. These types of requests can be processed as priority HACBs or as normal HACBs depending on whether the Priority_HACB_Bit is set in the HACB's controlInfo field.

The following list shows the execution order of HACB requests in a device queue:

  1. Priority HACB requests (Priority_HACB_Bit is set) have the highest priority in the device queue. Immediately upon receipt of a priority HACB, the HAM should place the HACB at the head of the device queue and issue it to the device.

    Priority HACB requests are generally used by the CDM and NWPA for diagnostics and error recovery. By setting both the Priority_HACB_Bit and the Freeze_Queue_Bit, the CDM or NWPA can execute HACB requests in lock-step fashion.

    If multiple priority requests are placed in the queue due to a device busy condition, they are executed on a LIFO basis.

  2. Normal HACB requests (Priority_HACB_Bit is cleared) have the lowest priority. These requests are the most frequent and should be placed at the end of the queue.

Unless the queue contains a HACB request with the Preserve_Order_Bit set (this condition is described in the next subsection), the HAM can reorder normal requests in a device queue to optimize performance. However, the routines that handle the reordering must implement fairness so that any one, normal HACB request gets executed in a timely fashion instead of always being pushed to the back of the queue.

3.3.2 Preserve-Execution-Order Requests

To support sequential devices where preserving the execution order of requests is critical, NWPA defines a Preserve_Order_Bit for the HACB. This flag also resides in the HACB's controlInfo field. HACBs with this flag set are a special case of normal HACB requests. When the HAM receives a HACB with the Preserve_Order_Bit set, it must always place the request at the back of the device queue.

The Preserve_Order_Bit indicates that all requests currently positioned in front must be executed before the preserve-order request, and any new requests that get placed in the queue must be executed after the preserve-order request. If multiple preserve-order requests are in the queue, this paradigm must be extended to maintain the prescribed behavior.

Priority HACB requests, as explained in the previous subsection, are the one exception to the preserve-order rule. Priority HACB requests always get placed at the front of the queue even if preserve-order requests are present.

3.3.3 Queue State

This subsection defines the state conditions of a device queue. A device queue has two states:

  • frozen

    A frozen state means that the issuing of requests in the queue to the adapter/device is halted; however, queue management does not stop. If the HAM receives any new requests for a frozen queue, it still must accept them and place them in their proper sequence in the queue.

  • unfrozen

    An unfrozen state means that requests continue to be issued to the adapter/device.

In the event of an error, the HAM is expected to freeze the queue of the device that caused the error, post the appropriate completion status as prescribed in the description of the HACB's hacbCompletion field in Host Adapter Control Block, and complete the HACB using HAI_Complete_HACB.

If the HAM is managing multiple devices, freezing one device queue does not affect the state of any of the others. Also, the HAM must keep the queue frozen until that device either receives a HAM_Unfreeze_Queue (Function 0x03) request or a priority request with No_Freeze_Queue_Bit set. After receiving one of these requests, the queue starts up again.

During normal I/O functions, the HAM controls the queue state from two different time points:

  • HACB receive-time point

    The receive-time point is the HAM's entry point that receives HACB requests prior to sending them to the adapter/device HAM_Execute_HACB).

  • HACB completion-time point

    The completion-time point is the HAM's entry point that completes the HACB after it has been processed by the device (HAM_ISR).

Queue state management is as follows:

HACB Receive-Time Point

At HACB Receive Time HAM_Execute_HACB.

    if (Priority_HACB_Bit set)
    {
       Place HACB at head of queue;
       Issue HACB to adapter/device;
       if (Freeze_Queue_Bit set)
          Freeze device queue;
       return;
    }
    /* For any other HACB at head of queue */
    else
    {
       if ((queue is empty) && (adapter/device
       notBUSY))
       {
           Issue HACB to adapter/device;
    
            if (Freeze_Queue_Bit set)
               Freeze device queue; 
             return;
       }
       else
          Place HACB at back of queue;
       return;
    }
    
    if (HAM's HAM_Unfreeze_Queue
    (Function 0x03) function is called)
      {
          Unfreeze target device queue;
           Issue next request in queue to adapter/device;
           return;
      } 
    

HACB Completion-Time Point

At HACB Completion Time HAM_ISR

    if (error occurred)
    {
       Determine device queue state (frozen/unfrozen)
       and  error code according to Section 11.1, HACB Completion
    Codes;
    
    Set hacbCompletion code from current device queue status and current error code;
    
    Complete HACB back to NWPA;
    
    if (device queue is unfrozen)
       Issue next request in queue to adapter/device;
    
       return;
    }
    Set the current error code to Successful_Completion; 
    /* No error occurred, check for the implicitUNFREEZE_QUEUE within HACB */
    
    if ((Priority_HACB_Bit == set) && (Freeze_Queue_Bit   == clear))
       UNFREEZE the queue for the current device;
    
    else
    
       Do NOT modify current queue state status for this
       device;
    
    Set hacbCompletion code from current device queue status and current error code;
    
    Complete HACB back to NWPA;
    
    if (device queue is unfrozen)   Issue next request in queue to adapter/device;
    
    return;
    
    if (HAM's HAM_Unfreeze_Queue
    (Function 0x03) function is called)
      {
          Unfreeze target device queue;
           Issue next request in queue to adapter/device;
           return;
      } 
    

The HAM should never freeze a device queue on a request that was dirty aborted. If during its ISR, the HAM detects a HACB request that was dirty aborted, the HAM should complete the HACB with the abort completion code, even if the request generated an error.