isci: Fixup of smp request
The struct smp_request data structure has be fixed up for Linux consumption. This probably should go to scsi/sas.h eventually. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
af5ae89350
commit
2ec53eb4d5
|
@ -198,20 +198,6 @@ struct sci_ssp_frame_header {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request_header - This structure defines the contents of an SMP
|
|
||||||
* Request header.
|
|
||||||
*
|
|
||||||
* For specific information on each of these individual fields please reference
|
|
||||||
* the SAS specification.
|
|
||||||
*/
|
|
||||||
struct smp_request_header {
|
|
||||||
u8 smp_frame_type; /* byte 0 */
|
|
||||||
u8 function; /* byte 1 */
|
|
||||||
u8 allocated_response_length; /* byte 2 */
|
|
||||||
u8 request_length; /* byte 3 */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct smp_response_header - This structure depicts the contents of the SAS
|
* struct smp_response_header - This structure depicts the contents of the SAS
|
||||||
* SMP DISCOVER RESPONSE frame. For specific information on each of these
|
* SMP DISCOVER RESPONSE frame. For specific information on each of these
|
||||||
|
@ -227,136 +213,6 @@ struct smp_response_header {
|
||||||
u8 response_length; /* byte 3 */
|
u8 response_length; /* byte 3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request_general - This structure defines the contents of an SMP
|
|
||||||
* Request that is comprised of the struct smp_request_header and a CRC.
|
|
||||||
*
|
|
||||||
* For specific information on each of these individual fields please reference
|
|
||||||
* the SAS specification.
|
|
||||||
*/
|
|
||||||
struct smp_request_general {
|
|
||||||
u32 crc; /* bytes 4-7 */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request_phy_identifier - This structure defines the contents of
|
|
||||||
* an SMP Request that is comprised of the struct smp_request_header and a phy
|
|
||||||
* identifier. Examples: SMP_REQUEST_DISCOVER, SMP_REQUEST_REPORT_PHY_SATA.
|
|
||||||
*
|
|
||||||
* For specific information on each of these individual fields please reference
|
|
||||||
* the SAS specification.
|
|
||||||
*/
|
|
||||||
struct smp_request_phy_identifier {
|
|
||||||
u32 reserved_byte4_7; /* bytes 4-7 */
|
|
||||||
|
|
||||||
u32 ignore_zone_group:1; /* byte 8 */
|
|
||||||
u32 reserved_byte8:7;
|
|
||||||
|
|
||||||
u32 phy_identifier:8; /* byte 9 */
|
|
||||||
u32 reserved_byte10:8; /* byte 10 */
|
|
||||||
u32 reserved_byte11:8; /* byte 11 */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request_configure_route_information - This structure defines the
|
|
||||||
* contents of an SMP Configure Route Information request.
|
|
||||||
*
|
|
||||||
* For specific information on each of these individual fields please reference
|
|
||||||
* the SAS specification.
|
|
||||||
*/
|
|
||||||
struct smp_request_configure_route_information {
|
|
||||||
u32 expected_expander_change_count:16; /* bytes 4-5 */
|
|
||||||
u32 expander_route_index_high:8;
|
|
||||||
u32 expander_route_index:8; /* bytes 6-7 */
|
|
||||||
|
|
||||||
u32 reserved_byte8:8; /* bytes 8 */
|
|
||||||
u32 phy_identifier:8; /* bytes 9 */
|
|
||||||
u32 reserved_byte_10_11:16; /* bytes 10-11 */
|
|
||||||
|
|
||||||
u32 reserved_byte_12_bit_0_6:7;
|
|
||||||
u32 disable_route_entry:1; /* byte 12 */
|
|
||||||
u32 reserved_byte_13_15:24; /* bytes 13-15 */
|
|
||||||
|
|
||||||
u32 routed_sas_address[2]; /* bytes 16-23 */
|
|
||||||
u8 reserved_byte_24_39[16]; /* bytes 24-39 */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request_phy_control - This structure defines the contents of an
|
|
||||||
* SMP Phy Controler request.
|
|
||||||
*
|
|
||||||
* For specific information on each of these individual fields please reference
|
|
||||||
* the SAS specification.
|
|
||||||
*/
|
|
||||||
struct smp_request_phy_control {
|
|
||||||
u16 expected_expander_change_count; /* byte 4-5 */
|
|
||||||
|
|
||||||
u16 reserved_byte_6_7; /* byte 6-7 */
|
|
||||||
u8 reserved_byte_8; /* byte 8 */
|
|
||||||
|
|
||||||
u8 phy_identifier; /* byte 9 */
|
|
||||||
u8 phy_operation; /* byte 10 */
|
|
||||||
|
|
||||||
u8 update_partial_pathway_timeout_value:1;
|
|
||||||
u8 reserved_byte_11_bit_1_7:7; /* byte 11 */
|
|
||||||
|
|
||||||
u8 reserved_byte_12_23[12]; /* byte 12-23 */
|
|
||||||
|
|
||||||
u8 attached_device_name[8]; /* byte 24-31 */
|
|
||||||
|
|
||||||
u8 reserved_byte_32_bit_3_0:4; /* byte 32 */
|
|
||||||
u8 programmed_minimum_physical_link_rate:4;
|
|
||||||
|
|
||||||
u8 reserved_byte_33_bit_3_0:4; /* byte 33 */
|
|
||||||
u8 programmed_maximum_physical_link_rate:4;
|
|
||||||
|
|
||||||
u16 reserved_byte_34_35; /* byte 34-35 */
|
|
||||||
|
|
||||||
u8 partial_pathway_timeout_value:4;
|
|
||||||
u8 reserved_byte_36_bit_4_7:4; /* byte 36 */
|
|
||||||
|
|
||||||
u16 reserved_byte_37_38; /* byte 37-38 */
|
|
||||||
u8 reserved_byte_39; /* byte 39 */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request_vendor_specific - This structure depicts the vendor
|
|
||||||
* specific space for SMP request.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH 1016
|
|
||||||
struct smp_request_vendor_specific {
|
|
||||||
u8 request_bytes[SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct smp_request - This structure simply unionizes the existing request
|
|
||||||
* structures into a common request type.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct smp_request {
|
|
||||||
struct smp_request_header header;
|
|
||||||
|
|
||||||
union { /* bytes 4-N */
|
|
||||||
struct smp_request_general report_general;
|
|
||||||
struct smp_request_phy_identifier discover;
|
|
||||||
struct smp_request_general report_manufacturer_information;
|
|
||||||
struct smp_request_phy_identifier report_phy_sata;
|
|
||||||
struct smp_request_phy_control phy_control;
|
|
||||||
struct smp_request_phy_identifier report_phy_error_log;
|
|
||||||
struct smp_request_phy_identifier report_route_information;
|
|
||||||
struct smp_request_configure_route_information configure_route_information;
|
|
||||||
struct smp_request_vendor_specific vendor_specific_request;
|
|
||||||
} request;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct smp_response_report_general - This structure depicts the SMP Report
|
* struct smp_response_report_general - This structure depicts the SMP Report
|
||||||
|
@ -493,6 +349,7 @@ struct smp_response_report_phy_sata {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH 1016
|
||||||
struct smp_response_vendor_specific {
|
struct smp_response_vendor_specific {
|
||||||
u8 response_bytes[SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH];
|
u8 response_bytes[SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH];
|
||||||
};
|
};
|
||||||
|
@ -517,17 +374,6 @@ struct smp_response {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SMP Request Functions */
|
|
||||||
#define SMP_FUNCTION_REPORT_GENERAL 0x00
|
|
||||||
#define SMP_FUNCTION_REPORT_MANUFACTURER_INFORMATION 0x01
|
|
||||||
#define SMP_FUNCTION_DISCOVER 0x10
|
|
||||||
#define SMP_FUNCTION_REPORT_PHY_ERROR_LOG 0x11
|
|
||||||
#define SMP_FUNCTION_REPORT_PHY_SATA 0x12
|
|
||||||
#define SMP_FUNCTION_REPORT_ROUTE_INFORMATION 0X13
|
|
||||||
#define SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION 0X90
|
|
||||||
#define SMP_FUNCTION_PHY_CONTROL 0x91
|
|
||||||
#define SMP_FUNCTION_PHY_TEST 0x92
|
|
||||||
|
|
||||||
#define SMP_FRAME_TYPE_REQUEST 0x40
|
#define SMP_FRAME_TYPE_REQUEST 0x40
|
||||||
#define SMP_FRAME_TYPE_RESPONSE 0x41
|
#define SMP_FRAME_TYPE_RESPONSE 0x41
|
||||||
|
|
||||||
|
|
|
@ -1658,38 +1658,47 @@ static void scic_sds_general_request_construct(struct scic_sds_controller *scic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum sci_status scic_io_request_construct(struct scic_sds_controller *scic,
|
enum sci_status
|
||||||
struct scic_sds_remote_device *sci_dev,
|
scic_io_request_construct(struct scic_sds_controller *scic,
|
||||||
u16 io_tag,
|
struct scic_sds_remote_device *sci_dev,
|
||||||
void *user_io_request_object,
|
u16 io_tag,
|
||||||
struct scic_sds_request *sci_req,
|
void *user_req,
|
||||||
struct scic_sds_request **new_scic_io_request_handle)
|
struct scic_sds_request *sci_req,
|
||||||
|
struct scic_sds_request **new_sci_req)
|
||||||
{
|
{
|
||||||
struct domain_device *dev = sci_dev_to_domain(sci_dev);
|
struct domain_device *dev = sci_dev_to_domain(sci_dev);
|
||||||
enum sci_status status = SCI_SUCCESS;
|
enum sci_status status = SCI_SUCCESS;
|
||||||
|
|
||||||
/* Build the common part of the request */
|
/* Build the common part of the request */
|
||||||
scic_sds_general_request_construct(scic, sci_dev, io_tag,
|
scic_sds_general_request_construct(scic,
|
||||||
user_io_request_object, sci_req);
|
sci_dev,
|
||||||
|
io_tag,
|
||||||
|
user_req,
|
||||||
|
sci_req);
|
||||||
|
|
||||||
if (sci_dev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
|
if (sci_dev->rnc.remote_node_index ==
|
||||||
|
SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
|
||||||
return SCI_FAILURE_INVALID_REMOTE_DEVICE;
|
return SCI_FAILURE_INVALID_REMOTE_DEVICE;
|
||||||
|
|
||||||
if (dev->dev_type == SAS_END_DEV) {
|
if (dev->dev_type == SAS_END_DEV)
|
||||||
scic_sds_ssp_io_request_assign_buffers(sci_req);
|
scic_sds_ssp_io_request_assign_buffers(sci_req);
|
||||||
} else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
|
else if ((dev->dev_type == SATA_DEV) ||
|
||||||
|
(dev->tproto & SAS_PROTOCOL_STP)) {
|
||||||
scic_sds_stp_request_assign_buffers(sci_req);
|
scic_sds_stp_request_assign_buffers(sci_req);
|
||||||
memset(sci_req->command_buffer, 0, sizeof(struct host_to_dev_fis));
|
memset(sci_req->command_buffer,
|
||||||
|
0,
|
||||||
|
sizeof(struct host_to_dev_fis));
|
||||||
} else if (dev_is_expander(dev)) {
|
} else if (dev_is_expander(dev)) {
|
||||||
scic_sds_smp_request_assign_buffers(sci_req);
|
scic_sds_smp_request_assign_buffers(sci_req);
|
||||||
memset(sci_req->command_buffer, 0, sizeof(struct smp_request));
|
memset(sci_req->command_buffer, 0, sizeof(struct smp_req));
|
||||||
} else
|
} else
|
||||||
status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
|
status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
|
||||||
|
|
||||||
if (status == SCI_SUCCESS) {
|
if (status == SCI_SUCCESS) {
|
||||||
memset(sci_req->task_context_buffer, 0,
|
memset(sci_req->task_context_buffer,
|
||||||
SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab));
|
0,
|
||||||
*new_scic_io_request_handle = sci_req;
|
SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab));
|
||||||
|
*new_sci_req = sci_req;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sas.h"
|
||||||
#include "intel_sas.h"
|
#include "intel_sas.h"
|
||||||
#include "sci_base_state_machine.h"
|
#include "sci_base_state_machine.h"
|
||||||
#include "scic_controller.h"
|
#include "scic_controller.h"
|
||||||
|
@ -67,7 +68,7 @@
|
||||||
|
|
||||||
static void scu_smp_request_construct_task_context(
|
static void scu_smp_request_construct_task_context(
|
||||||
struct scic_sds_request *sci_req,
|
struct scic_sds_request *sci_req,
|
||||||
struct smp_request *smp_request);
|
struct smp_req *smp_req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -77,7 +78,7 @@ static void scu_smp_request_construct_task_context(
|
||||||
u32 scic_sds_smp_request_get_object_size(void)
|
u32 scic_sds_smp_request_get_object_size(void)
|
||||||
{
|
{
|
||||||
return sizeof(struct scic_sds_request)
|
return sizeof(struct scic_sds_request)
|
||||||
+ sizeof(struct smp_request)
|
+ sizeof(struct smp_req)
|
||||||
+ sizeof(struct smp_response)
|
+ sizeof(struct smp_response)
|
||||||
+ sizeof(struct scu_task_context)
|
+ sizeof(struct scu_task_context)
|
||||||
+ SMP_CACHE_BYTES;
|
+ SMP_CACHE_BYTES;
|
||||||
|
@ -100,7 +101,7 @@ u32 scic_sds_smp_request_get_object_size(void)
|
||||||
*/
|
*/
|
||||||
#define scic_sds_smp_request_get_response_buffer(memory) \
|
#define scic_sds_smp_request_get_response_buffer(memory) \
|
||||||
(((char *)(scic_sds_smp_request_get_command_buffer(memory))) \
|
(((char *)(scic_sds_smp_request_get_command_buffer(memory))) \
|
||||||
+ sizeof(struct smp_request))
|
+ sizeof(struct smp_req))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scic_sds_smp_request_get_task_context_buffer() -
|
* scic_sds_smp_request_get_task_context_buffer() -
|
||||||
|
@ -142,21 +143,8 @@ void scic_sds_smp_request_assign_buffers(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* This method is called by the SCI user to build an SMP pass-through IO
|
* This function will fill in the SCU Task Context for a SMP request. The
|
||||||
* request.
|
|
||||||
* @scic_smp_request: This parameter specifies the handle to the io request
|
|
||||||
* object to be built.
|
|
||||||
* @passthru_cb: This parameter specifies the pointer to the callback structure
|
|
||||||
* that contains the function pointers
|
|
||||||
*
|
|
||||||
* - The user must have previously called scic_io_request_construct() on the
|
|
||||||
* supplied IO request. Indicate if the controller successfully built the IO
|
|
||||||
* request.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will fill in the SCU Task Context for a SMP request. The
|
|
||||||
* following important settings are utilized: -# task_type ==
|
* following important settings are utilized: -# task_type ==
|
||||||
* SCU_TASK_TYPE_SMP. This simply indicates that a normal request type
|
* SCU_TASK_TYPE_SMP. This simply indicates that a normal request type
|
||||||
* (i.e. non-raw frame) is being utilized to perform task management. -#
|
* (i.e. non-raw frame) is being utilized to perform task management. -#
|
||||||
|
@ -166,26 +154,26 @@ void scic_sds_smp_request_assign_buffers(
|
||||||
* constructed.
|
* constructed.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void scu_smp_request_construct_task_context(
|
static void
|
||||||
struct scic_sds_request *sds_request,
|
scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
|
||||||
struct smp_request *smp_request)
|
struct smp_req *smp_req)
|
||||||
{
|
{
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
struct scic_sds_controller *controller;
|
struct scic_sds_controller *scic;
|
||||||
struct scic_sds_remote_device *sci_dev;
|
struct scic_sds_remote_device *sci_dev;
|
||||||
struct scic_sds_port *target_port;
|
struct scic_sds_port *sci_port;
|
||||||
struct scu_task_context *task_context;
|
struct scu_task_context *task_context;
|
||||||
|
|
||||||
/* byte swap the smp request. */
|
/* byte swap the smp request. */
|
||||||
scic_word_copy_with_swap(sds_request->command_buffer,
|
scic_word_copy_with_swap(sci_req->command_buffer,
|
||||||
(u32 *)smp_request,
|
(u32 *)smp_req,
|
||||||
sizeof(struct smp_request) / sizeof(u32));
|
sizeof(struct smp_req) / sizeof(u32));
|
||||||
|
|
||||||
task_context = scic_sds_request_get_task_context(sds_request);
|
task_context = scic_sds_request_get_task_context(sci_req);
|
||||||
|
|
||||||
controller = scic_sds_request_get_controller(sds_request);
|
scic = scic_sds_request_get_controller(sci_req);
|
||||||
sci_dev = scic_sds_request_get_device(sds_request);
|
sci_dev = scic_sds_request_get_device(sci_req);
|
||||||
target_port = scic_sds_request_get_port(sds_request);
|
sci_port = scic_sds_request_get_port(sci_req);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill in the TC with the its required data
|
* Fill in the TC with the its required data
|
||||||
|
@ -195,9 +183,8 @@ static void scu_smp_request_construct_task_context(
|
||||||
task_context->initiator_request = 1;
|
task_context->initiator_request = 1;
|
||||||
task_context->connection_rate = sci_dev->connection_rate;
|
task_context->connection_rate = sci_dev->connection_rate;
|
||||||
task_context->protocol_engine_index =
|
task_context->protocol_engine_index =
|
||||||
scic_sds_controller_get_protocol_engine_group(controller);
|
scic_sds_controller_get_protocol_engine_group(scic);
|
||||||
task_context->logical_port_index =
|
task_context->logical_port_index = scic_sds_port_get_index(sci_port);
|
||||||
scic_sds_port_get_index(target_port);
|
|
||||||
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
|
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
|
||||||
task_context->abort = 0;
|
task_context->abort = 0;
|
||||||
task_context->valid = SCU_TASK_CONTEXT_VALID;
|
task_context->valid = SCU_TASK_CONTEXT_VALID;
|
||||||
|
@ -220,8 +207,7 @@ static void scu_smp_request_construct_task_context(
|
||||||
task_context->address_modifier = 0;
|
task_context->address_modifier = 0;
|
||||||
|
|
||||||
/* 10h */
|
/* 10h */
|
||||||
task_context->ssp_command_iu_length =
|
task_context->ssp_command_iu_length = smp_req->req_len;
|
||||||
smp_request->header.request_length;
|
|
||||||
|
|
||||||
/* 14h */
|
/* 14h */
|
||||||
task_context->transfer_length_bytes = 0;
|
task_context->transfer_length_bytes = 0;
|
||||||
|
@ -231,7 +217,7 @@ static void scu_smp_request_construct_task_context(
|
||||||
* since commandIU has been build by framework at this point, we just
|
* since commandIU has been build by framework at this point, we just
|
||||||
* copy the frist DWord from command IU to this location. */
|
* copy the frist DWord from command IU to this location. */
|
||||||
memcpy((void *)(&task_context->type.smp),
|
memcpy((void *)(&task_context->type.smp),
|
||||||
sds_request->command_buffer,
|
sci_req->command_buffer,
|
||||||
sizeof(u32));
|
sizeof(u32));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -241,19 +227,18 @@ static void scu_smp_request_construct_task_context(
|
||||||
*/
|
*/
|
||||||
task_context->task_phase = 0;
|
task_context->task_phase = 0;
|
||||||
|
|
||||||
if (sds_request->was_tag_assigned_by_user) {
|
if (sci_req->was_tag_assigned_by_user) {
|
||||||
/*
|
/*
|
||||||
* Build the task context now since we have already read
|
* Build the task context now since we have already read
|
||||||
* the data
|
* the data
|
||||||
*/
|
*/
|
||||||
sds_request->post_context =
|
sci_req->post_context =
|
||||||
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
(scic_sds_controller_get_protocol_engine_group(
|
(scic_sds_controller_get_protocol_engine_group(scic) <<
|
||||||
controller) <<
|
|
||||||
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
(scic_sds_port_get_index(target_port) <<
|
(scic_sds_port_get_index(sci_port) <<
|
||||||
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
|
||||||
scic_sds_io_tag_get_index(sds_request->io_tag));
|
scic_sds_io_tag_get_index(sci_req->io_tag));
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Build the task context now since we have already read
|
* Build the task context now since we have already read
|
||||||
|
@ -261,12 +246,11 @@ static void scu_smp_request_construct_task_context(
|
||||||
* I/O tag index is not assigned because we have to wait
|
* I/O tag index is not assigned because we have to wait
|
||||||
* until we get a TCi.
|
* until we get a TCi.
|
||||||
*/
|
*/
|
||||||
sds_request->post_context =
|
sci_req->post_context =
|
||||||
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
(scic_sds_controller_get_protocol_engine_group(
|
(scic_sds_controller_get_protocol_engine_group(scic) <<
|
||||||
controller) <<
|
|
||||||
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
(scic_sds_port_get_index(target_port) <<
|
(scic_sds_port_get_index(sci_port) <<
|
||||||
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,9 +258,9 @@ static void scu_smp_request_construct_task_context(
|
||||||
* Copy the physical address for the command buffer to the SCU Task
|
* Copy the physical address for the command buffer to the SCU Task
|
||||||
* Context command buffer should not contain command header.
|
* Context command buffer should not contain command header.
|
||||||
*/
|
*/
|
||||||
dma_addr = scic_io_request_get_dma_addr(sds_request,
|
dma_addr = scic_io_request_get_dma_addr(sci_req,
|
||||||
(char *)
|
(char *)
|
||||||
(sds_request->command_buffer) +
|
(sci_req->command_buffer) +
|
||||||
sizeof(u32));
|
sizeof(u32));
|
||||||
|
|
||||||
task_context->command_iu_upper = upper_32_bits(dma_addr);
|
task_context->command_iu_upper = upper_32_bits(dma_addr);
|
||||||
|
@ -577,7 +561,7 @@ static const struct sci_base_state scic_sds_smp_request_started_substate_table[]
|
||||||
*/
|
*/
|
||||||
enum sci_status scic_io_request_construct_smp(struct scic_sds_request *sci_req)
|
enum sci_status scic_io_request_construct_smp(struct scic_sds_request *sci_req)
|
||||||
{
|
{
|
||||||
struct smp_request *smp_req = kmalloc(sizeof(*smp_req), GFP_KERNEL);
|
struct smp_req *smp_req = kmalloc(sizeof(*smp_req), GFP_KERNEL);
|
||||||
|
|
||||||
if (!smp_req)
|
if (!smp_req)
|
||||||
return SCI_FAILURE_INSUFFICIENT_RESOURCES;
|
return SCI_FAILURE_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -600,18 +584,18 @@ enum sci_status scic_io_request_construct_smp(struct scic_sds_request *sci_req)
|
||||||
* Look at the SMP requests' header fields; for certain SAS 1.x SMP
|
* Look at the SMP requests' header fields; for certain SAS 1.x SMP
|
||||||
* functions under SAS 2.0, a zero request length really indicates
|
* functions under SAS 2.0, a zero request length really indicates
|
||||||
* a non-zero default length. */
|
* a non-zero default length. */
|
||||||
if (smp_req->header.request_length == 0) {
|
if (smp_req->req_len == 0) {
|
||||||
switch (smp_req->header.function) {
|
switch (smp_req->func) {
|
||||||
case SMP_FUNCTION_DISCOVER:
|
case SMP_DISCOVER:
|
||||||
case SMP_FUNCTION_REPORT_PHY_ERROR_LOG:
|
case SMP_REPORT_PHY_ERR_LOG:
|
||||||
case SMP_FUNCTION_REPORT_PHY_SATA:
|
case SMP_REPORT_PHY_SATA:
|
||||||
case SMP_FUNCTION_REPORT_ROUTE_INFORMATION:
|
case SMP_REPORT_ROUTE_INFO:
|
||||||
smp_req->header.request_length = 2;
|
smp_req->req_len = 2;
|
||||||
break;
|
break;
|
||||||
case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION:
|
case SMP_CONF_ROUTE_INFO:
|
||||||
case SMP_FUNCTION_PHY_CONTROL:
|
case SMP_PHY_CONTROL:
|
||||||
case SMP_FUNCTION_PHY_TEST:
|
case SMP_PHY_TEST_FUNCTION:
|
||||||
smp_req->header.request_length = 9;
|
smp_req->req_len = 9;
|
||||||
break;
|
break;
|
||||||
/* Default - zero is a valid default for 2.0. */
|
/* Default - zero is a valid default for 2.0. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,8 @@
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
#include "sata.h"
|
#include "sata.h"
|
||||||
#include "scu_completion_codes.h"
|
#include "scu_completion_codes.h"
|
||||||
#include "core/scic_sds_request.h"
|
#include "scic_sds_request.h"
|
||||||
|
#include "sas.h"
|
||||||
|
|
||||||
static enum sci_status isci_request_ssp_request_construct(
|
static enum sci_status isci_request_ssp_request_construct(
|
||||||
struct isci_request *request)
|
struct isci_request *request)
|
||||||
|
@ -113,47 +114,37 @@ static enum sci_status isci_request_stp_request_construct(
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* isci_smp_request_build() - This function builds the smp request object.
|
* isci_smp_request_build() - This function builds the smp request.
|
||||||
* @isci_host: This parameter specifies the ISCI host object
|
* @ireq: This parameter points to the isci_request allocated in the
|
||||||
* @request: This parameter points to the isci_request object allocated in the
|
|
||||||
* request construct function.
|
* request construct function.
|
||||||
* @sci_device: This parameter is the handle for the sci core's remote device
|
|
||||||
* object that is the destination for this request.
|
|
||||||
*
|
*
|
||||||
* SCI_SUCCESS on successfull completion, or specific failure code.
|
* SCI_SUCCESS on successfull completion, or specific failure code.
|
||||||
*/
|
*/
|
||||||
static enum sci_status isci_smp_request_build(
|
static enum sci_status isci_smp_request_build(struct isci_request *ireq)
|
||||||
struct isci_request *request)
|
|
||||||
{
|
{
|
||||||
enum sci_status status = SCI_FAILURE;
|
enum sci_status status = SCI_FAILURE;
|
||||||
struct sas_task *task = isci_request_access_task(request);
|
struct sas_task *task = isci_request_access_task(ireq);
|
||||||
|
struct scic_sds_request *sci_req = ireq->sci_request_handle;
|
||||||
|
void *cmd_iu = sci_req->command_buffer;
|
||||||
|
|
||||||
void *command_iu_address =
|
dev_dbg(&ireq->isci_host->pdev->dev,
|
||||||
scic_io_request_get_command_iu_address(
|
"%s: request = %p\n", __func__, ireq);
|
||||||
request->sci_request_handle
|
|
||||||
);
|
|
||||||
|
|
||||||
dev_dbg(&request->isci_host->pdev->dev,
|
dev_dbg(&ireq->isci_host->pdev->dev,
|
||||||
"%s: request = %p\n",
|
|
||||||
__func__,
|
|
||||||
request);
|
|
||||||
dev_dbg(&request->isci_host->pdev->dev,
|
|
||||||
"%s: smp_req len = %d\n",
|
"%s: smp_req len = %d\n",
|
||||||
__func__,
|
__func__,
|
||||||
task->smp_task.smp_req.length);
|
task->smp_task.smp_req.length);
|
||||||
|
|
||||||
/* copy the smp_command to the address; */
|
/* copy the smp_command to the address; */
|
||||||
sg_copy_to_buffer(&task->smp_task.smp_req, 1,
|
sg_copy_to_buffer(&task->smp_task.smp_req, 1,
|
||||||
(char *)command_iu_address,
|
(char *)cmd_iu,
|
||||||
sizeof(struct smp_request)
|
sizeof(struct smp_req));
|
||||||
);
|
|
||||||
|
|
||||||
status = scic_io_request_construct_smp(request->sci_request_handle);
|
status = scic_io_request_construct_smp(sci_req);
|
||||||
if (status != SCI_SUCCESS)
|
if (status != SCI_SUCCESS)
|
||||||
dev_warn(&request->isci_host->pdev->dev,
|
dev_warn(&ireq->isci_host->pdev->dev,
|
||||||
"%s: scic_io_request_construct_smp failed with "
|
"%s: failed with status = %d\n",
|
||||||
"status = %d\n",
|
|
||||||
__func__,
|
__func__,
|
||||||
status);
|
status);
|
||||||
|
|
||||||
|
@ -1073,9 +1064,8 @@ void isci_request_io_request_complete(
|
||||||
sg_copy_from_buffer(
|
sg_copy_from_buffer(
|
||||||
&task->smp_task.smp_resp, 1,
|
&task->smp_task.smp_resp, 1,
|
||||||
command_iu_address
|
command_iu_address
|
||||||
+ sizeof(struct smp_request),
|
+ sizeof(struct smp_req),
|
||||||
sizeof(struct smp_resp)
|
sizeof(struct smp_resp));
|
||||||
);
|
|
||||||
} else if (completion_status
|
} else if (completion_status
|
||||||
== SCI_IO_SUCCESS_IO_DONE_EARLY) {
|
== SCI_IO_SUCCESS_IO_DONE_EARLY) {
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@
|
||||||
|
|
||||||
#ifndef _SCI_SAS_H_
|
#ifndef _SCI_SAS_H_
|
||||||
#define _SCI_SAS_H_
|
#define _SCI_SAS_H_
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SATA FIS Types These constants depict the various SATA FIS types devined in
|
* SATA FIS Types These constants depict the various SATA FIS types devined in
|
||||||
* the serial ATA specification.
|
* the serial ATA specification.
|
||||||
|
@ -106,4 +109,108 @@ struct ssp_task_iu {
|
||||||
u8 _r_c[12];
|
u8 _r_c[12];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct smp_req_phy_id - This structure defines the contents of
|
||||||
|
* an SMP Request that is comprised of the struct smp_request_header and a
|
||||||
|
* phy identifier.
|
||||||
|
* Examples: SMP_REQUEST_DISCOVER, SMP_REQUEST_REPORT_PHY_SATA.
|
||||||
|
*
|
||||||
|
* For specific information on each of these individual fields please reference
|
||||||
|
* the SAS specification.
|
||||||
|
*/
|
||||||
|
struct smp_req_phy_id {
|
||||||
|
u8 _r_a[4]; /* bytes 4-7 */
|
||||||
|
|
||||||
|
u8 ign_zone_grp:1; /* byte 8 */
|
||||||
|
u8 _r_b:7;
|
||||||
|
|
||||||
|
u8 phy_id; /* byte 9 */
|
||||||
|
u8 _r_c; /* byte 10 */
|
||||||
|
u8 _r_d; /* byte 11 */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct smp_req_config_route_info - This structure defines the
|
||||||
|
* contents of an SMP Configure Route Information request.
|
||||||
|
*
|
||||||
|
* For specific information on each of these individual fields please reference
|
||||||
|
* the SAS specification.
|
||||||
|
*/
|
||||||
|
struct smp_req_conf_rtinfo {
|
||||||
|
u16 exp_change_cnt; /* bytes 4-5 */
|
||||||
|
u8 exp_rt_idx_hi; /* byte 6 */
|
||||||
|
u8 exp_rt_idx; /* byte 7 */
|
||||||
|
|
||||||
|
u8 _r_a; /* byte 8 */
|
||||||
|
u8 phy_id; /* byte 9 */
|
||||||
|
u16 _r_b; /* bytes 10-11 */
|
||||||
|
|
||||||
|
u8 _r_c:7; /* byte 12 */
|
||||||
|
u8 dis_rt_entry:1;
|
||||||
|
u8 _r_d[3]; /* bytes 13-15 */
|
||||||
|
|
||||||
|
u8 rt_sas_addr[8]; /* bytes 16-23 */
|
||||||
|
u8 _r_e[16]; /* bytes 24-39 */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct smp_req_phycntl - This structure defines the contents of an
|
||||||
|
* SMP Phy Controller request.
|
||||||
|
*
|
||||||
|
* For specific information on each of these individual fields please reference
|
||||||
|
* the SAS specification.
|
||||||
|
*/
|
||||||
|
struct smp_req_phycntl {
|
||||||
|
u16 exp_change_cnt; /* byte 4-5 */
|
||||||
|
|
||||||
|
u8 _r_a[3]; /* bytes 6-8 */
|
||||||
|
|
||||||
|
u8 phy_id; /* byte 9 */
|
||||||
|
u8 phy_op; /* byte 10 */
|
||||||
|
|
||||||
|
u8 upd_pathway:1; /* byte 11 */
|
||||||
|
u8 _r_b:7;
|
||||||
|
|
||||||
|
u8 _r_c[12]; /* byte 12-23 */
|
||||||
|
|
||||||
|
u8 att_dev_name[8]; /* byte 24-31 */
|
||||||
|
|
||||||
|
u8 _r_d:4; /* byte 32 */
|
||||||
|
u8 min_linkrate:4;
|
||||||
|
|
||||||
|
u8 _r_e:4; /* byte 33 */
|
||||||
|
u8 max_linkrate:4;
|
||||||
|
|
||||||
|
u8 _r_f[2]; /* byte 34-35 */
|
||||||
|
|
||||||
|
u8 pathway:4; /* byte 36 */
|
||||||
|
u8 _r_g:4;
|
||||||
|
|
||||||
|
u8 _r_h[3]; /* bytes 37-39 */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#define SMP_REQ_VENDOR_SPECIFIC_MAX_LEN 1016
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct smp_req - This structure simply unionizes the existing request
|
||||||
|
* structures into a common request type.
|
||||||
|
*
|
||||||
|
* XXX: This data structure may need to go to scsi/sas.h
|
||||||
|
*/
|
||||||
|
struct smp_req {
|
||||||
|
u8 type; /* byte 0 */
|
||||||
|
u8 func; /* byte 1 */
|
||||||
|
u8 alloc_resp_len; /* byte 2 */
|
||||||
|
u8 req_len; /* byte 3 */
|
||||||
|
|
||||||
|
union { /* bytes 4-N */
|
||||||
|
u32 smp_req_gen;
|
||||||
|
struct smp_req_phy_id phy_id;
|
||||||
|
struct smp_req_phycntl phy_cntl;
|
||||||
|
struct smp_req_conf_rtinfo conf_rt_info;
|
||||||
|
u8 vendor[SMP_REQ_VENDOR_SPECIFIC_MAX_LEN];
|
||||||
|
};
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue