コード例 #1
0
/**
 *
 *
 * @param[in] this_device
 * @param[in] frame_index
 *
 * @return SCI_STATUS
 */
static
SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
   SCIC_SDS_REMOTE_DEVICE_T * this_device,
   U32                        frame_index
)
{
   SCI_STATUS           status;
   SATA_FIS_HEADER_T  * frame_header;

   status = scic_sds_unsolicited_frame_control_get_header(
      &(scic_sds_remote_device_get_controller(this_device)->uf_control),
      frame_index,
      (void **)&frame_header
   );

   if (status == SCI_SUCCESS)
   {
      if (
            (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS)
         && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
         )
      {
         this_device->not_ready_reason =
            SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;

         /** @todo Check sactive and complete associated IO if any. */

         sci_base_state_machine_change_state(
            &this_device->ready_substate_machine,
            SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
         );
      }
      else if (
            (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
         && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
         )
      {
         // Some devices return D2H FIS when an NCQ error is detected.
         // Treat this like an SDB error FIS ready reason.
         this_device->not_ready_reason =
            SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;

         sci_base_state_machine_change_state(
            &this_device->ready_substate_machine,
            SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
         );
      }
      else
      {
         status = SCI_FAILURE;
      }

      scic_sds_controller_release_frame(
         scic_sds_remote_device_get_controller(this_device), frame_index
      );
   }

   return status;
}
コード例 #2
0
/**
 *
 *
 * @param[in] device This is the SCI base object which is cast into a
 *       SCIC_SDS_REMOTE_DEVICE object.
 *
 * @return none
 */
static
void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
   SCI_BASE_OBJECT_T * device
)
{
   SCIC_SDS_REMOTE_DEVICE_T * this_device;

   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;

   SET_STATE_HANDLER(
      this_device,
      scic_sds_stp_remote_device_ready_substate_handler_table,
      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
   );

   if(this_device->not_ready_reason ==
         SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
   {
      scic_cb_remote_device_not_ready(
         scic_sds_remote_device_get_controller(this_device),
         this_device,
         this_device->not_ready_reason
      );
   }
}
コード例 #3
0
/**
 * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method. This
 * method sets the ready cmd substate handlers and reports the device as ready.
 *
 * @param[in] object This is the SCI_BASE_OBJECT which is cast into a
 *       SCIC_SDS_REMOTE_DEVICE.
 *
 * @return none
 */
static
void scic_sds_smp_remote_device_ready_idle_substate_enter(
   SCI_BASE_OBJECT_T *object
)
{
   SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object;

   SET_STATE_HANDLER(
      this_device,
      scic_sds_smp_remote_device_ready_substate_handler_table,
      SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
   );

   scic_cb_remote_device_ready(
      scic_sds_remote_device_get_controller(this_device), this_device);
}
コード例 #4
0
/**
* This method will update the RNC buffer and post the invalidate request.
*
* @param[in] this_rnc The remote node context object that is to be
*       invalidated.
*
* @return none
*/
static
void scic_sds_remote_node_context_invalidate_context_buffer(
   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
)
{
   SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer;

   rnc_buffer = scic_sds_controller_get_remote_node_context_buffer(
      scic_sds_remote_device_get_controller(this_rnc->device),
      this_rnc->remote_node_index
         );

   rnc_buffer->ssp.is_valid = FALSE;

   scic_sds_remote_device_post_request(
      this_rnc->device,
      SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE
         );
}
コード例 #5
0
static
void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
   void * user_cookie
)
{
   SCIC_SDS_REMOTE_DEVICE_T * this_device;
   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_cookie;

   // For NCQ operation we do not issue a
   // scic_cb_remote_device_not_ready().  As a result, avoid sending
   // the ready notification.
   if (this_device->ready_substate_machine.previous_state_id
       != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
   {
      scic_cb_remote_device_ready(
         scic_sds_remote_device_get_controller(this_device), this_device
      );
   }
}
コード例 #6
0
/**
 * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This
 * method sets the remote device objects ready cmd substate handlers, and notify
 * core user that the device is not ready.
 *
 * @param[in] object This is the SCI_BASE_OBJECT which is cast into a
 *       SCIC_SDS_REMOTE_DEVICE.
 *
 * @return none
 */
static
void scic_sds_smp_remote_device_ready_cmd_substate_enter(
   SCI_BASE_OBJECT_T *object
)
{
   SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object;

   ASSERT(this_device->working_request != NULL);

   SET_STATE_HANDLER(
      this_device,
      scic_sds_smp_remote_device_ready_substate_handler_table,
      SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
   );

   scic_cb_remote_device_not_ready(
      scic_sds_remote_device_get_controller(this_device),
      this_device,
      SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED
   );
}
コード例 #7
0
/**
* This method will mark the rnc buffer as being valid and post the request to
* the hardware.
*
* @param[in] this_rnc The remote node context object that is to be
*            validated.
*
* @return none
*/
static
void scic_sds_remote_node_context_validate_context_buffer(
   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
)
{
   SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer;

   rnc_buffer = scic_sds_controller_get_remote_node_context_buffer(
      scic_sds_remote_device_get_controller(this_rnc->device),
      this_rnc->remote_node_index
         );

   rnc_buffer->ssp.is_valid = TRUE;

   if (
      !this_rnc->device->is_direct_attached
         && this_rnc->device->target_protocols.u.bits.attached_stp_target
         )
   {
      scic_sds_remote_device_post_request(
         this_rnc->device,
         SCU_CONTEXT_COMMAND_POST_RNC_96
            );
   }
   else
   {
      scic_sds_remote_device_post_request(
         this_rnc->device,
         SCU_CONTEXT_COMMAND_POST_RNC_32
            );

      if (this_rnc->device->is_direct_attached)
      {
         scic_sds_port_setup_transports(
            this_rnc->device->owning_port,
            this_rnc->remote_node_index
               );
      }
   }
}
コード例 #8
0
/**
* This method will construct the RNC buffer for this remote device object.
*
* @param[in] this_device The remote device to use to construct the RNC
*       buffer.
* @param[in] rnc The buffer into which the remote device data will be copied.
*
* @return none
*/
   void scic_sds_remote_node_context_construct_buffer(
   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
      )
{
   SCU_REMOTE_NODE_CONTEXT_T * rnc;
   SCIC_SDS_CONTROLLER_T     * the_controller;

   the_controller = scic_sds_remote_device_get_controller(this_rnc->device);

   rnc = scic_sds_controller_get_remote_node_context_buffer(
      the_controller, this_rnc->remote_node_index);

   memset(
      rnc,
      0x00,
      sizeof(SCU_REMOTE_NODE_CONTEXT_T)
         * scic_sds_remote_device_node_count(this_rnc->device)
         );

   rnc->ssp.remote_node_index = this_rnc->remote_node_index;
   rnc->ssp.remote_node_port_width = this_rnc->device->device_port_width;
   rnc->ssp.logical_port_index =
      scic_sds_remote_device_get_port_index(this_rnc->device);

   rnc->ssp.remote_sas_address_hi = SCIC_SWAP_DWORD(this_rnc->device->device_address.high);
   rnc->ssp.remote_sas_address_lo = SCIC_SWAP_DWORD(this_rnc->device->device_address.low);

   rnc->ssp.nexus_loss_timer_enable = TRUE;
   rnc->ssp.check_bit               = FALSE;
   rnc->ssp.is_valid                = FALSE;
   rnc->ssp.is_remote_node_context  = TRUE;
   rnc->ssp.function_number         = 0;

   rnc->ssp.arbitration_wait_time = 0;


   if (
      this_rnc->device->target_protocols.u.bits.attached_sata_device
         || this_rnc->device->target_protocols.u.bits.attached_stp_target
         )
   {
      rnc->ssp.connection_occupancy_timeout =
         the_controller->user_parameters.sds1.stp_max_occupancy_timeout;
      rnc->ssp.connection_inactivity_timeout =
         the_controller->user_parameters.sds1.stp_inactivity_timeout;
   }
   else
   {
      rnc->ssp.connection_occupancy_timeout  =
         the_controller->user_parameters.sds1.ssp_max_occupancy_timeout;
      rnc->ssp.connection_inactivity_timeout =
         the_controller->user_parameters.sds1.ssp_inactivity_timeout;
   }

   rnc->ssp.initial_arbitration_wait_time = 0;

   // Open Address Frame Parameters
   rnc->ssp.oaf_connection_rate = this_rnc->device->connection_rate;
   rnc->ssp.oaf_features = 0;
   rnc->ssp.oaf_source_zone_group = 0;
   rnc->ssp.oaf_more_compatibility_features = 0;
}