From 2ec53eb4d5b301e5c9c386da5685894d572772a5 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 4 May 2011 18:01:22 -0700 Subject: [PATCH] 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 Signed-off-by: Dan Williams --- drivers/scsi/isci/core/intel_sas.h | 156 +----------------- drivers/scsi/isci/core/scic_sds_request.c | 41 +++-- drivers/scsi/isci/core/scic_sds_smp_request.c | 104 +++++------- drivers/scsi/isci/request.c | 48 +++--- drivers/scsi/isci/sas.h | 107 ++++++++++++ 5 files changed, 196 insertions(+), 260 deletions(-) diff --git a/drivers/scsi/isci/core/intel_sas.h b/drivers/scsi/isci/core/intel_sas.h index 3d4ca12df5ff..d10c3824dbe4 100644 --- a/drivers/scsi/isci/core/intel_sas.h +++ b/drivers/scsi/isci/core/intel_sas.h @@ -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 * SMP DISCOVER RESPONSE frame. For specific information on each of these @@ -227,136 +213,6 @@ struct smp_response_header { 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 @@ -493,6 +349,7 @@ struct smp_response_report_phy_sata { }; +#define SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH 1016 struct smp_response_vendor_specific { 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_RESPONSE 0x41 diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c index ef59e019398e..8eb3c7e59ec5 100644 --- a/drivers/scsi/isci/core/scic_sds_request.c +++ b/drivers/scsi/isci/core/scic_sds_request.c @@ -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, - struct scic_sds_remote_device *sci_dev, - u16 io_tag, - void *user_io_request_object, - struct scic_sds_request *sci_req, - struct scic_sds_request **new_scic_io_request_handle) +enum sci_status +scic_io_request_construct(struct scic_sds_controller *scic, + struct scic_sds_remote_device *sci_dev, + u16 io_tag, + void *user_req, + struct scic_sds_request *sci_req, + struct scic_sds_request **new_sci_req) { struct domain_device *dev = sci_dev_to_domain(sci_dev); enum sci_status status = SCI_SUCCESS; /* Build the common part of the request */ - scic_sds_general_request_construct(scic, sci_dev, io_tag, - user_io_request_object, sci_req); + scic_sds_general_request_construct(scic, + 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; - if (dev->dev_type == SAS_END_DEV) { + if (dev->dev_type == SAS_END_DEV) 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); - 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)) { 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 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; if (status == SCI_SUCCESS) { - memset(sci_req->task_context_buffer, 0, - SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab)); - *new_scic_io_request_handle = sci_req; + memset(sci_req->task_context_buffer, + 0, + SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab)); + *new_sci_req = sci_req; } return status; diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c index 2815da288750..7d7bd2e29d8f 100644 --- a/drivers/scsi/isci/core/scic_sds_smp_request.c +++ b/drivers/scsi/isci/core/scic_sds_smp_request.c @@ -53,6 +53,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "sas.h" #include "intel_sas.h" #include "sci_base_state_machine.h" #include "scic_controller.h" @@ -67,7 +68,7 @@ static void scu_smp_request_construct_task_context( 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) { return sizeof(struct scic_sds_request) - + sizeof(struct smp_request) + + sizeof(struct smp_req) + sizeof(struct smp_response) + sizeof(struct scu_task_context) + 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) \ (((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() - @@ -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 - * 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 +/* + * This function will fill in the SCU Task Context for a SMP request. The * following important settings are utilized: -# task_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. -# @@ -166,26 +154,26 @@ void scic_sds_smp_request_assign_buffers( * constructed. * */ -static void scu_smp_request_construct_task_context( - struct scic_sds_request *sds_request, - struct smp_request *smp_request) +static void +scu_smp_request_construct_task_context(struct scic_sds_request *sci_req, + struct smp_req *smp_req) { 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_port *target_port; + struct scic_sds_port *sci_port; struct scu_task_context *task_context; /* byte swap the smp request. */ - scic_word_copy_with_swap(sds_request->command_buffer, - (u32 *)smp_request, - sizeof(struct smp_request) / sizeof(u32)); + scic_word_copy_with_swap(sci_req->command_buffer, + (u32 *)smp_req, + 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); - sci_dev = scic_sds_request_get_device(sds_request); - target_port = scic_sds_request_get_port(sds_request); + scic = scic_sds_request_get_controller(sci_req); + sci_dev = scic_sds_request_get_device(sci_req); + sci_port = scic_sds_request_get_port(sci_req); /* * 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->connection_rate = sci_dev->connection_rate; task_context->protocol_engine_index = - scic_sds_controller_get_protocol_engine_group(controller); - task_context->logical_port_index = - scic_sds_port_get_index(target_port); + scic_sds_controller_get_protocol_engine_group(scic); + task_context->logical_port_index = scic_sds_port_get_index(sci_port); task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP; task_context->abort = 0; task_context->valid = SCU_TASK_CONTEXT_VALID; @@ -220,8 +207,7 @@ static void scu_smp_request_construct_task_context( task_context->address_modifier = 0; /* 10h */ - task_context->ssp_command_iu_length = - smp_request->header.request_length; + task_context->ssp_command_iu_length = smp_req->req_len; /* 14h */ 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 * copy the frist DWord from command IU to this location. */ memcpy((void *)(&task_context->type.smp), - sds_request->command_buffer, + sci_req->command_buffer, sizeof(u32)); /* @@ -241,19 +227,18 @@ static void scu_smp_request_construct_task_context( */ 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 * the data */ - sds_request->post_context = + sci_req->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC | - (scic_sds_controller_get_protocol_engine_group( - controller) << + (scic_sds_controller_get_protocol_engine_group(scic) << 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) | - scic_sds_io_tag_get_index(sds_request->io_tag)); + scic_sds_io_tag_get_index(sci_req->io_tag)); } else { /* * 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 * until we get a TCi. */ - sds_request->post_context = + sci_req->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC | - (scic_sds_controller_get_protocol_engine_group( - controller) << + (scic_sds_controller_get_protocol_engine_group(scic) << 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)); } @@ -274,9 +258,9 @@ static void scu_smp_request_construct_task_context( * Copy the physical address for the command buffer to the SCU Task * 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 *) - (sds_request->command_buffer) + + (sci_req->command_buffer) + sizeof(u32)); 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) { - 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) 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 * functions under SAS 2.0, a zero request length really indicates * a non-zero default length. */ - if (smp_req->header.request_length == 0) { - switch (smp_req->header.function) { - case SMP_FUNCTION_DISCOVER: - case SMP_FUNCTION_REPORT_PHY_ERROR_LOG: - case SMP_FUNCTION_REPORT_PHY_SATA: - case SMP_FUNCTION_REPORT_ROUTE_INFORMATION: - smp_req->header.request_length = 2; + if (smp_req->req_len == 0) { + switch (smp_req->func) { + case SMP_DISCOVER: + case SMP_REPORT_PHY_ERR_LOG: + case SMP_REPORT_PHY_SATA: + case SMP_REPORT_ROUTE_INFO: + smp_req->req_len = 2; break; - case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION: - case SMP_FUNCTION_PHY_CONTROL: - case SMP_FUNCTION_PHY_TEST: - smp_req->header.request_length = 9; + case SMP_CONF_ROUTE_INFO: + case SMP_PHY_CONTROL: + case SMP_PHY_TEST_FUNCTION: + smp_req->req_len = 9; break; /* Default - zero is a valid default for 2.0. */ } diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 501df3ca4280..36adc1589efa 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -61,7 +61,8 @@ #include "request.h" #include "sata.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( struct isci_request *request) @@ -113,47 +114,37 @@ static enum sci_status isci_request_stp_request_construct( return status; } -/** - * isci_smp_request_build() - This function builds the smp request object. - * @isci_host: This parameter specifies the ISCI host object - * @request: This parameter points to the isci_request object allocated in the +/* + * isci_smp_request_build() - This function builds the smp request. + * @ireq: This parameter points to the isci_request allocated in the * 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. */ -static enum sci_status isci_smp_request_build( - struct isci_request *request) +static enum sci_status isci_smp_request_build(struct isci_request *ireq) { 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 = - scic_io_request_get_command_iu_address( - request->sci_request_handle - ); + dev_dbg(&ireq->isci_host->pdev->dev, + "%s: request = %p\n", __func__, ireq); - dev_dbg(&request->isci_host->pdev->dev, - "%s: request = %p\n", - __func__, - request); - dev_dbg(&request->isci_host->pdev->dev, + dev_dbg(&ireq->isci_host->pdev->dev, "%s: smp_req len = %d\n", __func__, task->smp_task.smp_req.length); /* copy the smp_command to the address; */ sg_copy_to_buffer(&task->smp_task.smp_req, 1, - (char *)command_iu_address, - sizeof(struct smp_request) - ); + (char *)cmd_iu, + 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) - dev_warn(&request->isci_host->pdev->dev, - "%s: scic_io_request_construct_smp failed with " - "status = %d\n", + dev_warn(&ireq->isci_host->pdev->dev, + "%s: failed with status = %d\n", __func__, status); @@ -1073,9 +1064,8 @@ void isci_request_io_request_complete( sg_copy_from_buffer( &task->smp_task.smp_resp, 1, command_iu_address - + sizeof(struct smp_request), - sizeof(struct smp_resp) - ); + + sizeof(struct smp_req), + sizeof(struct smp_resp)); } else if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { diff --git a/drivers/scsi/isci/sas.h b/drivers/scsi/isci/sas.h index 1a1e9bc125c3..f5d7e6a51070 100644 --- a/drivers/scsi/isci/sas.h +++ b/drivers/scsi/isci/sas.h @@ -55,6 +55,9 @@ #ifndef _SCI_SAS_H_ #define _SCI_SAS_H_ + +#include + /* * SATA FIS Types These constants depict the various SATA FIS types devined in * the serial ATA specification. @@ -106,4 +109,108 @@ struct ssp_task_iu { u8 _r_c[12]; } __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 -- 2.34.1