cCall [ilb.ILB_int_io_criteria_rtn],<<OFFSET32 IOP>>
or eax, eax
jnz error
This service is used by IOS layer drivers located within the IOS layered driver hierarchy. IOS clients should use ILB_io_criteria_rtn instead.
The service ensures that total transfer count does not exceed the maximum allowed, checks for too many logical SGDs (Scatter-Gather Descriptors), and optionally audits linear buffer start addresses and buffer lengths for WORD or DWORD alignment.
If this service has been so requested, it will generate a list of physical SGD's into memory pointed to by IOR_sgd_lin_phys. It will work from either a single linear address (IORF_SCATTER_GATHER=FALSE) or from a linear scatter-gather list (IORF_SCATTER_GATHER=TRUE).
The physical SGD conversion service is performed by calling the _CopyPageTable function to obtain the list of page table entries (PTEs) corresponding to the linear address space(s) specified. Next, the service routine attempts to concatenate PTEs whose physical addresses are contiguous, into a single physical SGD if possible. The maximum allowed size of each physical SGD is 65535 bytes; this limit will be observed while concatenating physical SGDs. If processing of the linear address space(s) results in too many physical SGDs being created (IOR_num_sgds becomes greater than the smaller of 17 or DCB_max_sg_elements), the io_criteria routine reports an error. This service fails if any linear buffer (pointed to by IOR_buffer_ptr or the SGD field BD_SG_Buffer_Ptr) being processed is larger than 512K.
A successful call is indicated if the EAX register returns 0.
The following table lists the fields used by this service.
Table 1. Fields used by ILB_io_criteria_rtn:
Field | Usage | Purpose |
---|---|---|
DCB_apparent_blk_shift | Read | See IOR_flags & IORF_CHAR_COMMAND |
DCB_device_flags & DCB_DEV_RMM | Read | If FALSE, uses physical DCB pointer (pDCB = pDCB->physical_dcb). If TRUE, uses logical (original) DCB. |
DCB_dmd_flags & DCB_dmd_dword_align | Read | If this demand flag is set, criteria routine will verify that dword alignment of the I/O buffer is being adhered to. |
DCB_dmd_flags & DCB_dmd_phys_sgd | Read | If set, criteria routine will attempt to create a list of up to 17 physical SGDs. |
DCB_dmd_flags & DCB_dmd_phys_sgd_ptr | Read | This demand flag (originally intended to cause the IOR_sgd_lin_phys address to be a physical address instead of a linear address) is currently not implemented; do not set this bit, to avoid unpredictable results. |
DCB_dmd_flags & DCB_dmd_word_align | Read | If this demand flag is set, criteria routine will verify that word alignment of the I/O buffer is being adhered to. |
DCB_max_sg_elements | Read | See IOR_flags & IORF_SCATTER_GATHER. |
DCB_max_xfer_len | Read | This is always a byte count. Used to audit IOR_xfer_count |
DCB_physical_dcb | Read | Used to access the DCB; except if an RMM device, the IOP_original_DCB is used. |
IOP_original_dcb | Read | Used to obtain pointer to logical DCB |
IOR_buffer_ptr | Read | Points to either a linear buffer space, unless IORF_SCATTER_GATHER is set, in which case it points to a list of linear (logical) scatter-gather descriptors. |
IOR_flags & IORF_CHAR_COMMAND | Read | If FALSE, the count specified in IOR_xfer_count is a block count, and must be shifted left by DCB_apparent_blk_shift to indicate the byte count |
IOR_flags & IORF_IO_TOO_BIG | Write | Set if IOR_xfer_count is too long (this bit is tested after the criteria routine fails) |
IOR_flags & IORF_PHYS_SGDS | Write | Set by criteria routine to indicate that the physical sgd (IOR_sgd_lin_phys) list was successfully set up. |
IOR_flags & IORF_SCATTER_GATHER | Read | If set, criteria routine audits the actual number of logical SGD's pointed to by IOR_buffer_ptr, against the legal maximum, which is DCB_max_sg_elements. |
IOR_func | Read | If IOR_func == IOR_SCSI_PASS_THROUGH, and IORF_SCATTER_GATHER==FALSE, the io_criteria routine will allow a "misaligned" address or count to succeed. For example, a count of 7 (odd) will actually succeed if the DCB_dmd_word_align bit is set and the start address is even. This is done to accommodate ASPI requests for example. |
IOR_ios_private_1 & IOS_PR_FL_MAYBE_BAD_ALIGN | Read/ Write | Used as a temporary variable within the io_criteria routine. |
IOR_num_sgds | Write | If DCB_dmd_phys_sgd is TRUE, the criteria routine will fill in this field to provide you with the number of physical SGD elements in IOR_sgd_lin_phys. |
IOR_sgd_lin_phys | Read | Points to the physical scatter/gather descriptor list area. If DCB_dmd_phys_sgd is TRUE, the criteria routine will fill in this list to provide you with up to 17 physical addresses of the scatter-gather blocks. |
IOR_xfer_count | Read | If IORF_SCATTER_GATHER=FALSE, this field contains the IOR_buffer_ptr's block or byte count; this count is audited by the criteria routine. |
A successful call returns (0). A non-zero value indicates an error. If an error occurs, use the following table to help pinpoint the cause of the error:
Table 2. ILB_io_criteria_rtn error conditions
IOP state before the io_criteria routine is called | Error condition description | Other indicators returned by io_criteria when error exit occurs |
---|---|---|
IORF_SCATTER_GATHER = TRUE,
and dmd_dword_align or dmd_word_align demand flag(s) are TRUE |
Either the start address or length of any of the linear scatter-gather descriptors failed the WORD or DWORD alignment check. Alignment checking is NOT performed if physical SGDs are requested and only one physical SGD is produced (since all adapters which have restrictions only have them for multiple SGDs) | None. |
IORF_SCATTER_GATHER = FALSE,
and dmd_dword_align or dmd_word_align demand flag(s) are TRUE |
Either the start address (IOR_buffer_ptr) or length (IOR_xfer_count) failed the WORD or DWORD alignment check. Alignment checking is NOT performed if IOR_func = IOR_SCSI_PASS_THROUGH (such as in an ASPI request) | None. |
The total transfer count (IOR_xfer_count; shifted left by DCB_apparent_blk_shift if IORF_CHAR_COMMAND is FALSE) is greater than DCB_max_xfer_len | IOR_flags bit IORF_IO_TOO_BIG is set to TRUE. This generally indicates to IOS that it must perform double buffering (breaking the transfer into smaller chunks). | |
DCB_dmd_phys_sgd = FALSE, and IORF_SCATTER_GATHER = TRUE | The number of logical SGDs set up (at IOR_buffer_ptr) is greater than DCB_max_sg_elements | None. |
DCB_dmd_phys_sgd = TRUE | The total transfer count (IOR_xfer_count; shifted left by DCB_apparent_blk_shift if IORF_CHAR_COMMAND is FALSE) is greater than 512 * 1024 (512K) | IOR_flags bit IORF_IO_TOO_BIG is set to TRUE. |
DCB_dmd_phys_sgd = TRUE | The number of physical SGDs that the io_criteria routine created from the logical (linear) SGDs is greater than 17 or greater than DCB_max_sg_elements | IOR_flags bit IORF_IO_TOO_BIG is set to TRUE.
IOR_num_sgds contains the offending count. |
ILB, IOP