Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ec53eb4 authored by Dave Jiang's avatar Dave Jiang Committed by Dan Williams
Browse files

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: default avatarDave Jiang <dave.jiang@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent af5ae893
Loading
Loading
Loading
Loading
+1 −155
Original line number Original line Diff line number Diff line
@@ -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


+25 −16
Original line number Original line Diff line number Diff line
@@ -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
scic_io_request_construct(struct scic_sds_controller *scic,
			  struct scic_sds_remote_device *sci_dev,
			  struct scic_sds_remote_device *sci_dev,
			  u16 io_tag,
			  u16 io_tag,
					  void *user_io_request_object,
			  void *user_req,
			  struct scic_sds_request *sci_req,
			  struct scic_sds_request *sci_req,
					  struct scic_sds_request **new_scic_io_request_handle)
			  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,
		       0,
		       SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab));
		       SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab));
		*new_scic_io_request_handle = sci_req;
		*new_sci_req = sci_req;
	}
	}


	return status;
	return status;
+44 −60
Original line number Original line Diff line number Diff line
@@ -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. */
		}
		}
+19 −29
Original line number Original line Diff line number Diff line
@@ -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) {


+107 −0
Original line number Original line Diff line number Diff line
@@ -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