[ Bottom of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]

Kernel Extensions and Device Support Programming Concepts

Understanding the sc_buf Structure

The sc_buf structure is used for communication between the SCSI device driver and the SCSI adapter device driver during an initiator I/O request. This structure is passed to and from the strategy routine in the same way a standard driver uses a struct buf structure.

Fields in the sc_buf Structure

The sc_buf structure contains certain fields used to pass a SCSI command and associated parameters to the SCSI adapter device driver. Other fields within this structure are used to pass returned status back to the SCSI device driver. The sc_buf structure is defined in the /usr/include/sys/scsi.h file.

Fields in the sc_buf structure are used as follows:

  1. Reserved fields should be set to a value of 0, except where noted.
  2. The bufstruct field contains a copy of the standard buf buffer structure that documents the I/O request. Included in this structure, for example, are the buffer address, byte count, and transfer direction. The b_work field in the buf structure is reserved for use by the SCSI adapter device driver. The current definition of the buf structure is in the /usr/include/sys/buf.h include file.
  3. The bp field points to the original buffer structure received by the SCSI Device Driver from the caller, if any. This can be a chain of entries in the case of spanned transfers (SCSI commands that transfer data from or to more than one system-memory buffer). A null pointer indicates a nonspanned transfer. The null value specifically tells the SCSI adapter device driver that all the information needed to perform the DMA data transfer is contained in the bufstruct fields of the sc_buf structure. If the bp field is set to a non-null value, the sc_buf.resvd1 field must have a value of null, or else the operation is not allowed.
  4. The scsi_command field, defined as a scsi structure, contains, for example, the SCSI ID, SCSI command length, SCSI command, and a flag variable:
    1. The scsi_length field is the number of bytes in the actual SCSI command. This is normally 6, 10, or 12 (decimal).
    2. The scsi_id field is the SCSI physical unit ID.
    3. The scsi_flags field contains the following bit flags:
      SC_NODISC
      Do not allow the target to disconnect during this command.
      SC_ASYNC
      Do not allow the adapter to negotiate for synchronous transfer to the SCSI device.

      During normal use, the SC_NODISC bit should not be set. Setting this bit allows a device executing commands to monopolize the SCSI bus. Sometimes it is desirable for a particular device to maintain control of the bus once it has successfully arbitrated for it; for instance, when this is the only device on the SCSI bus or the only device that will be in use. For performance reasons, it might not be desirable to go through SCSI selections again to save SCSI bus overhead on each command.

      Also during normal use, the SC_ASYNC bit must not be set. It should be set only in cases where a previous command to the device ended in an unexpected SCSI bus free condition. This condition is noted as SC_SCSI_BUS_FAULT in the general_card_status field of the sc_cmd structure. Because other errors might also result in the SC_SCSI_BUS_FAULT flag being set, the SC_ASYNC bit should only be set on the last retry of the failed command.

    4. The sc_cmd structure contains the physical SCSI command block. The 6 to 12 bytes of a single SCSI command are stored in consecutive bytes, with the op code and logical unit identified individually. The sc_cmd structure contains the following fields:
      • The scsi_op_code field specifies the standard SCSI op code for this command.
      • The lun field specifies the standard SCSI logical unit for the physical SCSI device controller. Typically, there will be one LUN per controller (LUN=0, for example) for devices with imbedded controllers. Only the upper 3 bits of this field contain the actual LUN ID. If addressing LUN's 0 - 7, this lun field should always be filled in with the LUN value. When addressing LUN's 8 - 31, this lun field should be set to 0 and the LUN value should be placed into the sc_buf.lun field described in this section.
      • The scsi_bytes field contains the remaining command-unique bytes of the SCSI command block. The actual number of bytes depends on the value in the scsi_op_code field.
      • The resvd1 field is set to a non-null value to indicate a request for a gathered write. A gathered write means the SCSI command conducts a system-to-device data transfer where multiple, noncontiguous system buffers contain the write data. This data is transferred in order as a single data transfer for the SCSI command in this sc_buf structure.

        The contents of the resvd1 field, if non-null, must be a pointer to the uio structure that is passed to the SCSI device driver. The SCSI adapter device driver treats the resvd1 field as a pointer to a uio structure that accesses the iovec structures containing pointers to the data. There are no address-alignment restrictions on the data in the iovec structures. The only restriction is that the total transfer length of all the data must not exceed the maximum transfer length for the adapter device driver.

        The sc_buf.bufstruct.b_un.b_addr field, which normally contains the starting system-buffer address, is ignored and can be altered by the SCSI adapter device driver when the sc_buf is returned. The sc_buf.bufstruct.b_bcount field should be set by the caller to the total transfer length for the data.

  5. The timeout_value field specifies the time-out limit (in seconds) to be used for completion of this command. A time-out value of 0 means no time-out is applied to this I/O request.
  6. The status_validity field contains an output parameter that can have one of the following bit flags as a value:
    SC_SCSI_ERROR
    The scsi_status field is valid.
    SC_ADAPTER_ERROR
    The general_card_status field is valid.
  7. The scsi_status field in the sc_buf structure is an output parameter that provides valid SCSI command completion status when its status_validity bit is nonzero. The sc_buf.bufstruct.b_error field should be set to EIO anytime the scsi_status field is valid. Typical status values include:
    SC_GOOD_STATUS
    The target successfully completed the command.
    SC_CHECK_CONDITION
    The target is reporting an error, exception, or other conditions.
    SC_BUSY_STATUS
    The target is currently busy and cannot accept a command now.
    SC_RESERVATION_CONFLICT
    The target is reserved by another initiator and cannot be accessed.
    SC_COMMAND_TERMINATED
    The target terminated this command after receiving a terminate I/O process message from the SCSI adapter.
    SC_QUEUE_FULL
    The target's command queue is full, so this command is returned.
  8. The general_card_status field is an output parameter that is valid when its status_validity bit is nonzero. The sc_buf.bufstruct.b_error field should be set to EIO anytime the general_card_status field is valid. This field contains generic SCSI adapter card status. It is intentionally general in coverage so that it can report error status from any typical SCSI adapter.

    If an error is detected during execution of a SCSI command, and the error prevented the SCSI command from actually being sent to the SCSI bus by the adapter, then the error should be processed or recovered, or both, by the SCSI adapter device driver.

    If it is recovered successfully by the SCSI adapter device driver, the error is logged, as appropriate, but is not reflected in the general_card_status byte. If the error cannot be recovered by the SCSI adapter device driver, the appropriate general_card_status bit is set and the sc_buf structure is returned to the SCSI device driver for further processing.

    If an error is detected after the command was actually sent to the SCSI device, then it should be processed or recovered, or both, by the SCSI device driver.

    For error logging, the SCSI adapter device driver logs SCSI bus- and adapter-related conditions, where as the SCSI device driver logs SCSI device-related errors. In the following description, a capital letter "A" after the error name indicates that the SCSI adapter device driver handles error logging. A capital letter "H" indicates that the SCSI device driver handles error logging.

    Some of the following error conditions indicate a SCSI device failure. Others are SCSI bus- or adapter-related.

    SC_HOST_IO_BUS_ERR (A)
    The system I/O bus generated or detected an error during a DMA or Programmed I/O (PIO) transfer.
    SC_SCSI_BUS_FAULT (H)
    The SCSI bus protocol or hardware was unsuccessful.
    SC_CMD_TIMEOUT (H)
    The command timed out before completion.
    SC_NO_DEVICE_RESPONSE (H)
    The target device did not respond to selection phase.
    SC_ADAPTER_HDW_FAILURE (A)
    The adapter indicated an onboard hardware failure.
    SC_ADAPTER_SFW_FAILURE (A)
    The adapter indicated microcode failure.
    SC_FUSE_OR_TERMINAL_PWR (A)
    The adapter indicated a blown terminator fuse or bad termination.
    SC_SCSI_BUS_RESET (A)
    The adapter indicated the SCSI bus has been reset.
  9. When the SCSI device driver queues multiple transactions to a device, the adap_q_status field indicates whether or not the SCSI adapter driver has cleared its queue for this device after an error has occurred. The flag of SC_DID_NOT CLEAR_Q indicates that the SCSI adapter driver has not cleared its queue for this device and that it is in a halted state (so none of the pending queued transactions are sent to the device).
  10. The lun field provides addressability of up to 32 logical units (LUNs). This field specifies the standard SCSI LUN for the physical SCSI device controller. If addressing LUN's 0 - 7, both this lun field (sc_buf.lun) and the lun field located in the scsi_command structure (sc_buf.scsi_command.scsi_cmd.lun) should be set to the LUN value. If addressing LUN's 8 - 31, this lun field (sc_buf.lun) should be set to the LUN value and the lun field located in the scsi_command structure (sc_buf.scsi_command.scsi_cmd.lun) should be set to 0.
    Logical Unit Numbers (LUNs)
    lun Fields LUN 0 - 7 LUN 8 - 31
    sc_buf.lun LUN Value LUN Value
    sc_buf.scsi_command.scsi_cmd.lun LUN Value 0
    Note
    LUN value is the current value of LUN.
  11. The q_tag_msg field indicates if the SCSI adapter can attempt to queue this transaction to the device. This information causes the SCSI adapter to fill in the Queue Tag Message Code of the queue tag message for a SCSI command. The following values are valid for this field:
    SC_NO_Q
    Specifies that the SCSI adapter does not send a queue tag message for this command, and so the device does not allow more than one SCSI command on its command queue. This value must be used for all commands sent to SCSI devices that do not support command tag queuing.
    SC_SIMPLE_Q
    Specifies placing this command in the device's command queue. The device determines the order that it executes commands in its queue. The SCSI-2 specification calls this value the "Simple Queue Tag Message."
    SC_HEAD_OF_Q
    Specifies placing this command first in the device's command queue. This command does not preempt an active command at the device, but it is executed before all other commands in the command queue. The SCSI-2 specification calls this value the "Head of Queue Tag Message."
    SC_ORDERED_Q
    Specifies placing this command in the device's command queue. The device processes these commands in the order that they are received. The SCSI-2 specification calls this value the "Ordered Queue Tag Message."
    Note
    Commands with the value of SC_NO_Q for the q_tag_msg field (except for request sense commands) should not be queued to a device whose queue contains a command with another value for q_tag_msg. If commands with the SC_NO_Q value (except for request sense) are sent to the device, then the SCSI device driver must make sure that no active commands are using different values for q_tag_msg. Similarly, the SCSI device driver must also make sure that a command with a q_tag_msg value of SC_ORDERED_Q, SC_HEAD_Q, or SC_SIMPLE_Q is not sent to a device that has a command with the q_tag_msg field of SC_NO_Q.
  12. The flags field contains bit flags sent from the SCSI device driver to the SCSI adapter device driver. The following flags are defined:
    SC_RESUME
    When set, means the SCSI adapter device driver should resume transaction queuing for this ID/LUN. Error recovery is complete after a SCIOHALT operation, check condition, or severe SCSI bus error. This flag is used to restart the SCSI adapter device driver following a reported error.
    SC_DELAY_CMD
    When set, means the SCSI adapter device driver should delay sending this command (following a SCSI reset or BDR to this device) by at least the number of seconds specified to the SCSI adapter device driver in its configuration information. For SCSI devices that do not require this function, this flag should not be set.
    SC_Q_CLR
    When set, means the SCSI adapter driver should clear its transaction queue for this ID/LUN. The transaction containing this flag setting does not require an actual SCSI command in the sc_buf because it is flushed back to the SCSI device driver with the rest of the transactions for this ID/LUN. However, this transaction must have the SCSI ID field (sc_buf.scsi_command.scsi_id) and the LUN fields (sc_buf.scsi_command.scsi_cmd.lun and sc_buf.lun) filled in with the device's SCSI ID and logical unit number (LUN). This flag is valid only during error recovery of a check condition or command terminated at a command tag queuing device when the SC_DID_NOT_CLR_Q flag is set in the sc_buf.adap_q_status field.
    Note
    When addressing LUN's 8 - 31, be sure to see the description of the sc_buf.lun field within the sc_buf structure.
    SC_Q_RESUME
    When set, means that the SCSI adapter driver should resume its halted transaction queue for this ID/LUN. The transaction containing this flag setting does not require an actual SCSI command to be sent to the SCSI adapter driver. However, this transaction must have the sc_buf.scsi_command.scsi_id and sc_buf.scsi_command.scsi_cmd.lun fields filled in with the device's SCSI ID and logical unit number. If the transaction containing this flag setting is the first issued by the SCSI device driver after it receives an error (indicating that the adapter driver's queue is halted), then the SC_RESUME flag must be set also.
    Note
    When addressing LUN's 8 - 31, be sure to see the description of the sc_buf.lun field within the sc_buf structure.

[ Top of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]