From 4b33981ade7cf723f3f32809e34192376c9a10f8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 May 2011 17:36:38 -0700 Subject: [PATCH] isci: unify phy data structures Make scic_sds_phy a member of isci_phy and merge their lifetimes which means removing the phy table from scic_sds_controller in favor of the one at that isci_host level. Reported-by: Christoph Hellwig Signed-off-by: Dan Williams --- drivers/scsi/isci/core/scic_sds_controller.c | 100 +++------ drivers/scsi/isci/core/scic_sds_controller.h | 6 - drivers/scsi/isci/core/scic_sds_phy.c | 6 +- drivers/scsi/isci/core/scic_sds_phy.h | 6 - drivers/scsi/isci/core/scic_sds_port.c | 2 +- .../core/scic_sds_port_configuration_agent.c | 209 ++++++++---------- drivers/scsi/isci/phy.c | 86 +++---- drivers/scsi/isci/phy.h | 41 ++-- drivers/scsi/isci/port.c | 42 +--- drivers/scsi/isci/sci_environment.h | 2 +- 10 files changed, 187 insertions(+), 313 deletions(-) diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index b59548254e24..4ad31550c8ae 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c @@ -673,6 +673,7 @@ static void scic_sds_controller_phy_timer_stop(struct scic_sds_controller *scic) */ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_controller *scic) { + struct isci_host *ihost = scic_to_ihost(scic); struct scic_sds_oem_params *oem = &scic->oem_parameters.sds1; struct scic_sds_phy *sci_phy; enum sci_status status; @@ -688,7 +689,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro u8 index; for (index = 0; index < SCI_MAX_PHYS; index++) { - sci_phy = &scic->phy_table[index]; + sci_phy = &ihost->phys[index].sci; state = sci_phy->state_machine.current_state_id; if (!scic_sds_phy_get_port(sci_phy)) @@ -719,7 +720,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro scic_sds_controller_phy_timer_stop(scic); } } else { - sci_phy = &scic->phy_table[scic->next_phy_to_start]; + sci_phy = &ihost->phys[scic->next_phy_to_start].sci; if (oem->controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) { if (scic_sds_phy_get_port(sci_phy) == NULL) { @@ -748,7 +749,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro "to stop phy %d because of status " "%d.\n", __func__, - scic->phy_table[scic->next_phy_to_start].phy_index, + ihost->phys[scic->next_phy_to_start].sci.phy_index, status); } @@ -792,23 +793,22 @@ static enum sci_status scic_sds_controller_stop_phys(struct scic_sds_controller u32 index; enum sci_status status; enum sci_status phy_status; + struct isci_host *ihost = scic_to_ihost(scic); status = SCI_SUCCESS; for (index = 0; index < SCI_MAX_PHYS; index++) { - phy_status = scic_sds_phy_stop(&scic->phy_table[index]); + phy_status = scic_sds_phy_stop(&ihost->phys[index].sci); - if ( - (phy_status != SCI_SUCCESS) - && (phy_status != SCI_FAILURE_INVALID_STATE) - ) { + if (phy_status != SCI_SUCCESS && + phy_status != SCI_FAILURE_INVALID_STATE) { status = SCI_FAILURE; dev_warn(scic_to_dev(scic), "%s: Controller stop operation failed to stop " "phy %d because of status %d.\n", __func__, - scic->phy_table[index].phy_index, phy_status); + ihost->phys[index].sci.phy_index, phy_status); } } @@ -1069,21 +1069,13 @@ static void scic_sds_controller_sdma_completion( } } -/** - * - * @scic: - * @completion_entry: - * - * This method processes an unsolicited frame message. This is called from - * within the controller completion handler. none - */ -static void scic_sds_controller_unsolicited_frame( - struct scic_sds_controller *scic, - u32 completion_entry) +static void scic_sds_controller_unsolicited_frame(struct scic_sds_controller *scic, + u32 completion_entry) { u32 index; u32 frame_index; + struct isci_host *ihost = scic_to_ihost(scic); struct scu_unsolicited_frame_header *frame_header; struct scic_sds_phy *phy; struct scic_sds_remote_device *device; @@ -1092,10 +1084,8 @@ static void scic_sds_controller_unsolicited_frame( frame_index = SCU_GET_FRAME_INDEX(completion_entry); - frame_header - = scic->uf_control.buffers.array[frame_index].header; - scic->uf_control.buffers.array[frame_index].state - = UNSOLICITED_FRAME_IN_USE; + frame_header = scic->uf_control.buffers.array[frame_index].header; + scic->uf_control.buffers.array[frame_index].state = UNSOLICITED_FRAME_IN_USE; if (SCU_GET_FRAME_ERROR(completion_entry)) { /* @@ -1108,10 +1098,8 @@ static void scic_sds_controller_unsolicited_frame( if (frame_header->is_address_frame) { index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry); - phy = &scic->phy_table[index]; - if (phy != NULL) { - result = scic_sds_phy_frame_handler(phy, frame_index); - } + phy = &ihost->phys[index].sci; + result = scic_sds_phy_frame_handler(phy, frame_index); } else { index = SCU_GET_COMPLETION_INDEX(completion_entry); @@ -1122,7 +1110,7 @@ static void scic_sds_controller_unsolicited_frame( * device that has not yet been created. In either case forwared * the frame to the PE and let it take care of the frame data. */ index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry); - phy = &scic->phy_table[index]; + phy = &ihost->phys[index].sci; result = scic_sds_phy_frame_handler(phy, frame_index); } else { if (index < scic->remote_node_entries) @@ -1144,21 +1132,14 @@ static void scic_sds_controller_unsolicited_frame( } } -/** - * This method processes an event completion entry. This is called from within - * the controller completion handler. - * @scic: - * @completion_entry: - * - */ -static void scic_sds_controller_event_completion( - struct scic_sds_controller *scic, - u32 completion_entry) +static void scic_sds_controller_event_completion(struct scic_sds_controller *scic, + u32 completion_entry) { - u32 index; + struct isci_host *ihost = scic_to_ihost(scic); struct scic_sds_request *io_request; struct scic_sds_remote_device *device; struct scic_sds_phy *phy; + u32 index; index = SCU_GET_COMPLETION_INDEX(completion_entry); @@ -1237,7 +1218,7 @@ static void scic_sds_controller_event_completion( * we get the event notification. This is a type 4 event. */ case SCU_EVENT_TYPE_OSSP_EVENT: index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry); - phy = &scic->phy_table[index]; + phy = &ihost->phys[index].sci; scic_sds_phy_event_handler(phy, completion_entry); break; @@ -2154,38 +2135,6 @@ enum sci_task_status scic_controller_start_task( return status; } -/** - * scic_controller_get_phy_handle() - This method simply provides the user with - * a unique handle for a given SAS/SATA phy index/identifier. - * @controller: This parameter represents the handle to the controller object - * from which to retrieve a phy (SAS or SATA) handle. - * @phy_index: This parameter specifies the phy index in the controller for - * which to retrieve the phy handle. 0 <= phy_index < maximum number of phys. - * @phy_handle: This parameter specifies the retrieved phy handle to be - * provided to the caller. - * - * Indicate if the retrieval of the phy handle was successful. SCI_SUCCESS This - * value is returned if the retrieval was successful. SCI_FAILURE_INVALID_PHY - * This value is returned if the supplied phy id is not in the supported range. - */ -enum sci_status scic_controller_get_phy_handle( - struct scic_sds_controller *scic, - u8 phy_index, - struct scic_sds_phy **phy_handle) -{ - if (phy_index < ARRAY_SIZE(scic->phy_table)) { - *phy_handle = &scic->phy_table[phy_index]; - - return SCI_SUCCESS; - } - - dev_err(scic_to_dev(scic), - "%s: Controller:0x%p PhyId:0x%x invalid phy index\n", - __func__, scic, phy_index); - - return SCI_FAILURE_INVALID_PHY; -} - /** * scic_controller_allocate_io_tag() - This method will allocate a tag from the * pool of free IO tags. Direct allocation of IO tags by the SCI Core user @@ -2724,7 +2673,7 @@ enum sci_status scic_controller_initialize(struct scic_sds_controller *scic) (result == SCI_SUCCESS) && (index < SCI_MAX_PHYS); index++) { result = scic_sds_phy_initialize( - &scic->phy_table[index], + &ihost->phys[index].sci, &scic->scu_registers->peg0.pe[index].tl, &scic->scu_registers->peg0.pe[index].ll); } @@ -2979,6 +2928,7 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic, void __iomem *scu_base, void __iomem *smu_base) { + struct isci_host *ihost = scic_to_ihost(scic); u8 i; sci_base_state_machine_construct(&scic->state_machine, @@ -3000,7 +2950,7 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic, /* Construct the phys for this controller */ for (i = 0; i < SCI_MAX_PHYS; i++) { /* Add all the PHYs to the dummy port */ - scic_sds_phy_construct(&scic->phy_table[i], + scic_sds_phy_construct(&ihost->phys[i].sci, &scic->port_table[SCI_MAX_PORTS], i); } diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h index 0a9bb8b77256..aaaf15ab7cfb 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.h +++ b/drivers/scsi/isci/core/scic_sds_controller.h @@ -167,12 +167,6 @@ struct scic_sds_controller { */ struct scic_sds_port port_table[SCI_MAX_PORTS + 1]; - /** - * This field is the array of phy objects that are controlled by this - * controller object. - */ - struct scic_sds_phy phy_table[SCI_MAX_PHYS]; - /** * This field is the array of device objects that are currently constructed * for this controller object. This table is used as a fast lookup of device diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c index 8f1e3db6bb2e..f0f4c74e4619 100644 --- a/drivers/scsi/isci/core/scic_sds_phy.c +++ b/drivers/scsi/isci/core/scic_sds_phy.c @@ -436,7 +436,7 @@ void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy *sci_phy, struct sci_sas_address *sas_address) { struct sas_identify_frame *iaf; - struct isci_phy *iphy = sci_phy->iphy; + struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); iaf = &iphy->frame_rcvd.iaf; memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE); @@ -1099,7 +1099,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler enum sci_status result; u32 *frame_words; struct sas_identify_frame iaf; - struct isci_phy *iphy = sci_phy->iphy; + struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); result = scic_sds_unsolicited_frame_control_get_header( &(scic_sds_phy_get_controller(sci_phy)->uf_control), @@ -1164,7 +1164,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handle enum sci_status result; struct dev_to_host_fis *frame_header; u32 *fis_frame_data; - struct isci_phy *iphy = sci_phy->iphy; + struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); result = scic_sds_unsolicited_frame_control_get_header( &(scic_sds_phy_get_controller(sci_phy)->uf_control), diff --git a/drivers/scsi/isci/core/scic_sds_phy.h b/drivers/scsi/isci/core/scic_sds_phy.h index b6a0ed1045df..c40c09b0c726 100644 --- a/drivers/scsi/isci/core/scic_sds_phy.h +++ b/drivers/scsi/isci/core/scic_sds_phy.h @@ -217,7 +217,6 @@ enum scic_sds_phy_protocol { SCIC_SDS_MAX_PHY_PROTOCOLS }; -struct isci_phy; /** * struct scic_sds_phy - This structure contains or references all of the data * necessary to represent the core phy object and SCU harware protocol @@ -226,11 +225,6 @@ struct isci_phy; * */ struct scic_sds_phy { - /** - * This field depicts the peer object for the phy. - */ - struct isci_phy *iphy; - /** * This field contains the information for the base phy state machine. */ diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c index e1c873406e50..84b8abb421a3 100644 --- a/drivers/scsi/isci/core/scic_sds_port.c +++ b/drivers/scsi/isci/core/scic_sds_port.c @@ -645,7 +645,7 @@ void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port, struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); struct isci_port *iport = sci_port->iport; struct isci_host *ihost = scic_to_ihost(scic); - struct isci_phy *iphy = sci_phy->iphy; + struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); sci_port->active_phy_mask &= ~(1 << sci_phy->phy_index); diff --git a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c index 6b2fb445a8f7..aa7ac95ecbc6 100644 --- a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c +++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c @@ -170,32 +170,27 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports( struct scic_sds_controller *controller, struct scic_sds_port_configuration_agent *port_agent) { + struct isci_host *ihost = scic_to_ihost(controller); struct sci_sas_address first_address; struct sci_sas_address second_address; /* * Sanity check the max ranges for all the phys the max index * is always equal to the port range index */ - if ( - (port_agent->phy_valid_port_range[0].max_index != 0) - || (port_agent->phy_valid_port_range[1].max_index != 1) - || (port_agent->phy_valid_port_range[2].max_index != 2) - || (port_agent->phy_valid_port_range[3].max_index != 3) - ) { + if (port_agent->phy_valid_port_range[0].max_index != 0 || + port_agent->phy_valid_port_range[1].max_index != 1 || + port_agent->phy_valid_port_range[2].max_index != 2 || + port_agent->phy_valid_port_range[3].max_index != 3) return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; - } /* * This is a request to configure a single x4 port or at least attempt * to make all the phys into a single port */ - if ( - (port_agent->phy_valid_port_range[0].min_index == 0) - && (port_agent->phy_valid_port_range[1].min_index == 0) - && (port_agent->phy_valid_port_range[2].min_index == 0) - && (port_agent->phy_valid_port_range[3].min_index == 0) - ) { + if (port_agent->phy_valid_port_range[0].min_index == 0 && + port_agent->phy_valid_port_range[1].min_index == 0 && + port_agent->phy_valid_port_range[2].min_index == 0 && + port_agent->phy_valid_port_range[3].min_index == 0) return SCI_SUCCESS; - } /* * This is a degenerate case where phy 1 and phy 2 are assigned @@ -210,8 +205,8 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports( * PE0 and PE3 can never have the same SAS Address unless they * are part of the same x4 wide port and we have already checked * for this condition. */ - scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address); - scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address); + scic_sds_phy_get_sas_address(&ihost->phys[0].sci, &first_address); + scic_sds_phy_get_sas_address(&ihost->phys[3].sci, &second_address); if (sci_sas_address_compare(first_address, second_address) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; @@ -221,12 +216,10 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports( * PE0 and PE1 are configured into a 2x1 ports make sure that the * SAS Address for PE0 and PE2 are different since they can not be * part of the same port. */ - if ( - (port_agent->phy_valid_port_range[0].min_index == 0) - && (port_agent->phy_valid_port_range[1].min_index == 1) - ) { - scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address); - scic_sds_phy_get_sas_address(&controller->phy_table[2], &second_address); + if (port_agent->phy_valid_port_range[0].min_index == 0 && + port_agent->phy_valid_port_range[1].min_index == 1) { + scic_sds_phy_get_sas_address(&ihost->phys[0].sci, &first_address); + scic_sds_phy_get_sas_address(&ihost->phys[2].sci, &second_address); if (sci_sas_address_compare(first_address, second_address) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; @@ -237,12 +230,10 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports( * PE2 and PE3 are configured into a 2x1 ports make sure that the * SAS Address for PE1 and PE3 are different since they can not be * part of the same port. */ - if ( - (port_agent->phy_valid_port_range[2].min_index == 2) - && (port_agent->phy_valid_port_range[3].min_index == 3) - ) { - scic_sds_phy_get_sas_address(&controller->phy_table[1], &first_address); - scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address); + if (port_agent->phy_valid_port_range[2].min_index == 2 && + port_agent->phy_valid_port_range[3].min_index == 3) { + scic_sds_phy_get_sas_address(&ihost->phys[1].sci, &first_address); + scic_sds_phy_get_sas_address(&ihost->phys[3].sci, &second_address); if (sci_sas_address_compare(first_address, second_address) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; @@ -267,6 +258,7 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration( struct scic_sds_controller *controller, struct scic_sds_port_configuration_agent *port_agent) { + struct isci_host *ihost = scic_to_ihost(controller); u32 phy_mask; u32 assigned_phy_mask; struct sci_sas_address sas_address; @@ -281,68 +273,64 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration( for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) { phy_mask = controller->oem_parameters.sds1.ports[port_index].phy_mask; - if (phy_mask != 0) { - /* - * Make sure that one or more of the phys were not already assinged to - * a different port. */ - if ((phy_mask & ~assigned_phy_mask) == 0) { - return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; - } + if (!phy_mask) + continue; + /* + * Make sure that one or more of the phys were not already assinged to + * a different port. */ + if ((phy_mask & ~assigned_phy_mask) == 0) { + return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; + } - /* Find the starting phy index for this round through the loop */ - for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) { - if ((1 << phy_index) & phy_mask) { - scic_sds_phy_get_sas_address( - &controller->phy_table[phy_index], &sas_address - ); + /* Find the starting phy index for this round through the loop */ + for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) { + if ((phy_mask & (1 << phy_index)) == 0) + continue; + scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci, + &sas_address); - /* - * The phy_index can be used as the starting point for the - * port range since the hardware starts all logical ports - * the same as the PE index. */ - port_agent->phy_valid_port_range[phy_index].min_index = port_index; - port_agent->phy_valid_port_range[phy_index].max_index = phy_index; - - if (phy_index != port_index) { - return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; - } + /* + * The phy_index can be used as the starting point for the + * port range since the hardware starts all logical ports + * the same as the PE index. */ + port_agent->phy_valid_port_range[phy_index].min_index = port_index; + port_agent->phy_valid_port_range[phy_index].max_index = phy_index; - break; - } + if (phy_index != port_index) { + return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } - /* - * See how many additional phys are being added to this logical port. - * Note: We have not moved the current phy_index so we will actually - * compare the startting phy with itself. - * This is expected and required to add the phy to the port. */ - while (phy_index < SCI_MAX_PHYS) { - if ((1 << phy_index) & phy_mask) { - scic_sds_phy_get_sas_address( - &controller->phy_table[phy_index], &phy_assigned_address - ); - - if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) { - /* - * The phy mask specified that this phy is part of the same port - * as the starting phy and it is not so fail this configuration */ - return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; - } + break; + } - port_agent->phy_valid_port_range[phy_index].min_index = port_index; - port_agent->phy_valid_port_range[phy_index].max_index = phy_index; + /* + * See how many additional phys are being added to this logical port. + * Note: We have not moved the current phy_index so we will actually + * compare the startting phy with itself. + * This is expected and required to add the phy to the port. */ + while (phy_index < SCI_MAX_PHYS) { + if ((phy_mask & (1 << phy_index)) == 0) + continue; + scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci, + &phy_assigned_address); + + if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) { + /* + * The phy mask specified that this phy is part of the same port + * as the starting phy and it is not so fail this configuration */ + return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; + } - scic_sds_port_add_phy( - &controller->port_table[port_index], - &controller->phy_table[phy_index] - ); + port_agent->phy_valid_port_range[phy_index].min_index = port_index; + port_agent->phy_valid_port_range[phy_index].max_index = phy_index; - assigned_phy_mask |= (1 << phy_index); - } + scic_sds_port_add_phy(&controller->port_table[port_index], + &ihost->phys[phy_index].sci); - phy_index++; - } + assigned_phy_mask |= (1 << phy_index); } + + phy_index++; } return scic_sds_port_configuration_agent_validate_ports(controller, port_agent); @@ -355,12 +343,12 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration( * device objects before a new series of link up notifications because a link * down has allowed a better port configuration. */ -static void scic_sds_mpc_agent_timeout_handler( - void *object) +static void scic_sds_mpc_agent_timeout_handler(void *object) { u8 index; - struct scic_sds_controller *controller = (struct scic_sds_controller *)object; - struct scic_sds_port_configuration_agent *port_agent = &controller->port_agent; + struct scic_sds_controller *scic = object; + struct isci_host *ihost = scic_to_ihost(scic); + struct scic_sds_port_configuration_agent *port_agent = &scic->port_agent; u16 configure_phy_mask; port_agent->timer_pending = false; @@ -369,13 +357,12 @@ static void scic_sds_mpc_agent_timeout_handler( configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask; for (index = 0; index < SCI_MAX_PHYS; index++) { + struct scic_sds_phy *sci_phy = &ihost->phys[index].sci; + if (configure_phy_mask & (1 << index)) { - port_agent->link_up_handler( - controller, - port_agent, - scic_sds_phy_get_port(&controller->phy_table[index]), - &controller->phy_table[index] - ); + port_agent->link_up_handler(scic, port_agent, + scic_sds_phy_get_port(sci_phy), + sci_phy); } } } @@ -489,6 +476,7 @@ static enum sci_status scic_sds_apc_agent_validate_phy_configuration( u8 port_index; struct sci_sas_address sas_address; struct sci_sas_address phy_assigned_address; + struct isci_host *ihost = scic_to_ihost(controller); phy_index = 0; @@ -496,14 +484,12 @@ static enum sci_status scic_sds_apc_agent_validate_phy_configuration( port_index = phy_index; /* Get the assigned SAS Address for the first PHY on the controller. */ - scic_sds_phy_get_sas_address( - &controller->phy_table[phy_index], &sas_address - ); + scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci, + &sas_address); while (++phy_index < SCI_MAX_PHYS) { - scic_sds_phy_get_sas_address( - &controller->phy_table[phy_index], &phy_assigned_address - ); + scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci, + &phy_assigned_address); /* Verify each of the SAS address are all the same for every PHY */ if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) { @@ -739,33 +725,30 @@ static void scic_sds_apc_agent_link_down( } } -/** - * - * - * This routine will try to configure the phys into ports when the timer fires. - */ -static void scic_sds_apc_agent_timeout_handler( - void *object) +/* configure the phys into ports when the timer fires */ +static void scic_sds_apc_agent_timeout_handler(void *object) { u32 index; struct scic_sds_port_configuration_agent *port_agent; - struct scic_sds_controller *controller = (struct scic_sds_controller *)object; + struct scic_sds_controller *scic = object; + struct isci_host *ihost = scic_to_ihost(scic); u16 configure_phy_mask; - port_agent = scic_sds_controller_get_port_configuration_agent(controller); + port_agent = scic_sds_controller_get_port_configuration_agent(scic); port_agent->timer_pending = false; configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask; - if (configure_phy_mask != 0x00) { - for (index = 0; index < SCI_MAX_PHYS; index++) { - if (configure_phy_mask & (1 << index)) { - scic_sds_apc_agent_configure_ports( - controller, port_agent, &controller->phy_table[index], false - ); - } - } + if (!configure_phy_mask) + return; + + for (index = 0; index < SCI_MAX_PHYS; index++) { + if ((configure_phy_mask & (1 << index)) == 0) + continue; + + scic_sds_apc_agent_configure_ports(scic, port_agent, + &ihost->phys[index].sci, false); } } diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 160790a0de0e..328004918329 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c @@ -63,61 +63,35 @@ struct scic_sds_phy; extern enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy); extern enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy); -/** - * isci_phy_init() - This function is called by the probe function to - * initialize the phy objects. This func assumes that the isci_port objects - * associated with the SCU have been initialized. - * @isci_phy: This parameter specifies the isci_phy object to initialize - * @isci_host: This parameter specifies the parent SCU host object for this - * isci_phy - * @index: This parameter specifies which SCU phy associates with this - * isci_phy. Generally, SCU phy 0 relates isci_phy 0, etc. - * - */ -void isci_phy_init( - struct isci_phy *phy, - struct isci_host *isci_host, - int index) +void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index) { - struct scic_sds_phy *scic_phy; union scic_oem_parameters oem; - enum sci_status status = SCI_SUCCESS; - u64 sas_addr; - - /*--------------- SCU_Phy Initialization Stuff -----------------------*/ - - status = scic_controller_get_phy_handle(&isci_host->sci, index, &scic_phy); - if (status == SCI_SUCCESS) { - phy->sci_phy_handle = scic_phy; - scic_phy->iphy = phy; - } else - dev_err(&isci_host->pdev->dev, - "failed scic_controller_get_phy_handle\n"); - - scic_oem_parameters_get(&isci_host->sci, &oem); - sas_addr = oem.sds1.phys[index].sas_address.high; - sas_addr <<= 32; - sas_addr |= oem.sds1.phys[index].sas_address.low; - swab64s(&sas_addr); - - memcpy(phy->sas_addr, &sas_addr, sizeof(sas_addr)); - - phy->isci_port = NULL; - phy->sas_phy.enabled = 0; - phy->sas_phy.id = index; - phy->sas_phy.sas_addr = &phy->sas_addr[0]; - phy->sas_phy.frame_rcvd = (u8 *)&phy->frame_rcvd; - phy->sas_phy.ha = &isci_host->sas_ha; - phy->sas_phy.lldd_phy = phy; - phy->sas_phy.enabled = 1; - phy->sas_phy.class = SAS; - phy->sas_phy.iproto = SAS_PROTOCOL_ALL; - phy->sas_phy.tproto = 0; - phy->sas_phy.type = PHY_TYPE_PHYSICAL; - phy->sas_phy.role = PHY_ROLE_INITIATOR; - phy->sas_phy.oob_mode = OOB_NOT_CONNECTED; - phy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN; - memset((u8 *)&phy->frame_rcvd, 0, sizeof(phy->frame_rcvd)); + u64 sci_sas_addr; + __be64 sas_addr; + + scic_oem_parameters_get(&ihost->sci, &oem); + sci_sas_addr = oem.sds1.phys[index].sas_address.high; + sci_sas_addr <<= 32; + sci_sas_addr |= oem.sds1.phys[index].sas_address.low; + sas_addr = cpu_to_be64(sci_sas_addr); + memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr)); + + iphy->isci_port = NULL; + iphy->sas_phy.enabled = 0; + iphy->sas_phy.id = index; + iphy->sas_phy.sas_addr = &iphy->sas_addr[0]; + iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd; + iphy->sas_phy.ha = &ihost->sas_ha; + iphy->sas_phy.lldd_phy = iphy; + iphy->sas_phy.enabled = 1; + iphy->sas_phy.class = SAS; + iphy->sas_phy.iproto = SAS_PROTOCOL_ALL; + iphy->sas_phy.tproto = 0; + iphy->sas_phy.type = PHY_TYPE_PHYSICAL; + iphy->sas_phy.role = PHY_ROLE_INITIATOR; + iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED; + iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN; + memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd)); } @@ -147,14 +121,14 @@ int isci_phy_control(struct asd_sas_phy *sas_phy, switch (func) { case PHY_FUNC_DISABLE: spin_lock_irqsave(&ihost->scic_lock, flags); - scic_sds_phy_stop(iphy->sci_phy_handle); + scic_sds_phy_stop(&iphy->sci); spin_unlock_irqrestore(&ihost->scic_lock, flags); break; case PHY_FUNC_LINK_RESET: spin_lock_irqsave(&ihost->scic_lock, flags); - scic_sds_phy_stop(iphy->sci_phy_handle); - scic_sds_phy_start(iphy->sci_phy_handle); + scic_sds_phy_stop(&iphy->sci); + scic_sds_phy_start(&iphy->sci); spin_unlock_irqrestore(&ihost->scic_lock, flags); break; diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h index 21f6050eadbe..93ec2d4a9c30 100644 --- a/drivers/scsi/isci/phy.h +++ b/drivers/scsi/isci/phy.h @@ -54,24 +54,17 @@ */ -#if !defined(_ISCI_PHY_H_) +#ifndef _ISCI_PHY_H_ #define _ISCI_PHY_H_ -#include "port.h" -#include "host.h" #include #include - - -/** - * struct isci_phy - This class implements the ISCI specific representation of - * the phy object. - * - * - */ +#include "scic_sds_phy.h" +#include "port.h" +#include "host.h" struct isci_phy { - struct scic_sds_phy *sci_phy_handle; + struct scic_sds_phy sci; struct asd_sas_phy sas_phy; struct isci_port *isci_port; u8 sas_addr[SAS_ADDR_SIZE]; @@ -82,17 +75,21 @@ struct isci_phy { } frame_rcvd; }; -#define to_isci_phy(p) \ - container_of(p, struct isci_phy, sas_phy); +static inline struct isci_phy *to_isci_phy(struct asd_sas_phy *sas_phy) +{ + struct isci_phy *iphy = container_of(sas_phy, typeof(*iphy), sas_phy); + + return iphy; +} + +static inline struct isci_phy *sci_phy_to_iphy(struct scic_sds_phy *sci_phy) +{ + struct isci_phy *iphy = container_of(sci_phy, typeof(*iphy), sci); -void isci_phy_init( - struct isci_phy *phy, - struct isci_host *isci_host, - int index); + return iphy; +} -int isci_phy_control( - struct asd_sas_phy *phy, - enum phy_func func, - void *buf); +void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index); +int isci_phy_control(struct asd_sas_phy *phy, enum phy_func func, void *buf); #endif /* !defined(_ISCI_PHY_H_) */ diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 6110306e8e23..5e87fedb5676 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -120,44 +120,26 @@ static void isci_port_change_state( spin_unlock_irqrestore(&isci_port->state_lock, flags); } -void isci_port_bc_change_received( - struct isci_host *isci_host, - struct scic_sds_port *port, - struct scic_sds_phy *phy) +void isci_port_bc_change_received(struct isci_host *ihost, + struct scic_sds_port *sci_port, + struct scic_sds_phy *sci_phy) { - struct isci_phy *isci_phy = phy->iphy; + struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); - dev_dbg(&isci_host->pdev->dev, - "%s: isci_phy = %p, sas_phy = %p\n", - __func__, - isci_phy, - &isci_phy->sas_phy); - - isci_host->sas_ha.notify_port_event( - &isci_phy->sas_phy, - PORTE_BROADCAST_RCVD - ); + dev_dbg(&ihost->pdev->dev, "%s: iphy = %p, sas_phy = %p\n", + __func__, iphy, &iphy->sas_phy); - scic_port_enable_broadcast_change_notification(port); + ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD); + scic_port_enable_broadcast_change_notification(sci_port); } -/** - * isci_port_link_up() - This function is called by the sci core when a link - * becomes active. the identify address frame is retrieved from the core and - * a notify port event is sent to libsas. - * @isci_host: This parameter specifies the isci host object. - * @port: This parameter specifies the sci port with the active link. - * @phy: This parameter specifies the sci phy with the active link. - * - */ -void isci_port_link_up( - struct isci_host *isci_host, - struct scic_sds_port *port, - struct scic_sds_phy *phy) +void isci_port_link_up(struct isci_host *isci_host, + struct scic_sds_port *port, + struct scic_sds_phy *phy) { unsigned long flags; struct scic_port_properties properties; - struct isci_phy *isci_phy = phy->iphy; + struct isci_phy *isci_phy = sci_phy_to_iphy(phy); struct isci_port *isci_port = port->iport; unsigned long success = true; diff --git a/drivers/scsi/isci/sci_environment.h b/drivers/scsi/isci/sci_environment.h index 8394f60c5c2b..bb07ed31b51c 100644 --- a/drivers/scsi/isci/sci_environment.h +++ b/drivers/scsi/isci/sci_environment.h @@ -67,7 +67,7 @@ static inline struct device *scic_to_dev(struct scic_sds_controller *scic) static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy) { - struct isci_phy *iphy = sci_phy->iphy; + struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host) return NULL; -- 2.34.1