From e531381e2f8a68b8737c63c7bb890ad80b2470bd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 7 May 2011 10:11:43 -0700 Subject: [PATCH] isci: unify port data structures Make scic_sds_port a member of isci_port and merge their lifetimes which means removing the port table from scic_sds_controller in favor of the one at the isci_host level. Merge ihost->sas_ports into ihost->ports. _ Reported-by: Christoph Hellwig Signed-off-by: Dan Williams --- drivers/scsi/isci/core/scic_sds_controller.c | 19 ++++---- drivers/scsi/isci/core/scic_sds_controller.h | 7 --- drivers/scsi/isci/core/scic_sds_port.c | 44 +++++++------------ drivers/scsi/isci/core/scic_sds_port.h | 5 --- .../core/scic_sds_port_configuration_agent.c | 18 ++++---- drivers/scsi/isci/host.c | 6 +-- drivers/scsi/isci/host.h | 7 +-- drivers/scsi/isci/init.c | 4 +- drivers/scsi/isci/port.c | 41 ++++++----------- drivers/scsi/isci/port.h | 25 ++++------- drivers/scsi/isci/remote_device.c | 2 +- drivers/scsi/isci/sci_environment.h | 2 +- 12 files changed, 67 insertions(+), 113 deletions(-) diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index 4ad31550c8ae..4179bdf3eda7 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c @@ -623,9 +623,10 @@ static enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller u32 index; enum sci_status port_status; enum sci_status status = SCI_SUCCESS; + struct isci_host *ihost = scic_to_ihost(scic); for (index = 0; index < scic->logical_port_entries; index++) { - struct scic_sds_port *sci_port = &scic->port_table[index]; + struct scic_sds_port *sci_port = &ihost->ports[index].sci; scic_sds_port_handler_t stop; stop = sci_port->state_handlers->stop_handler; @@ -2686,7 +2687,7 @@ enum sci_status scic_controller_initialize(struct scic_sds_controller *scic) (result == SCI_SUCCESS); index++) { result = scic_sds_port_initialize( - &scic->port_table[index], + &ihost->ports[index].sci, &scic->scu_registers->peg0.ptsg.port[index], &scic->scu_registers->peg0.ptsg.protocol_engine, &scic->scu_registers->peg0.viit[index]); @@ -2709,8 +2710,9 @@ enum sci_status scic_controller_initialize(struct scic_sds_controller *scic) } enum sci_status scic_controller_start(struct scic_sds_controller *scic, - u32 timeout) + u32 timeout) { + struct isci_host *ihost = scic_to_ihost(scic); enum sci_status result; u16 index; @@ -2752,10 +2754,9 @@ enum sci_status scic_controller_start(struct scic_sds_controller *scic, /* Start all of the ports on this controller */ for (index = 0; index < scic->logical_port_entries; index++) { - struct scic_sds_port *sci_port = &scic->port_table[index]; + struct scic_sds_port *sci_port = &ihost->ports[index].sci; - result = sci_port->state_handlers->start_handler( - sci_port); + result = sci_port->state_handlers->start_handler(sci_port); if (result) return result; } @@ -2944,14 +2945,14 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic, /* Construct the ports for this controller */ for (i = 0; i < SCI_MAX_PORTS; i++) - scic_sds_port_construct(&scic->port_table[i], i, scic); - scic_sds_port_construct(&scic->port_table[i], SCIC_SDS_DUMMY_PORT, scic); + scic_sds_port_construct(&ihost->ports[i].sci, i, scic); + scic_sds_port_construct(&ihost->ports[i].sci, SCIC_SDS_DUMMY_PORT, 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(&ihost->phys[i].sci, - &scic->port_table[SCI_MAX_PORTS], i); + &ihost->ports[SCI_MAX_PORTS].sci, i); } scic->invalid_phy_mask = 0; diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h index aaaf15ab7cfb..0d5047319cbf 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.h +++ b/drivers/scsi/isci/core/scic_sds_controller.h @@ -160,13 +160,6 @@ struct scic_sds_controller { */ struct scic_sds_port_configuration_agent port_agent; - /** - * This field is the array of port objects that are controlled by this - * controller object. There is one dummy port object also contained within - * this controller object. - */ - struct scic_sds_port port_table[SCI_MAX_PORTS + 1]; - /** * 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_port.c b/drivers/scsi/isci/core/scic_sds_port.c index 84b8abb421a3..01288dd44fb6 100644 --- a/drivers/scsi/isci/core/scic_sds_port.c +++ b/drivers/scsi/isci/core/scic_sds_port.c @@ -283,18 +283,14 @@ static enum sci_status scic_sds_port_clear_phy( struct scic_sds_phy *phy) { /* Make sure that this phy is part of this port */ - if ( - (port->phy_table[phy->phy_index] == phy) - && (scic_sds_phy_get_port(phy) == port) - ) { - /* Yep it is assigned to this port so remove it */ - scic_sds_phy_set_port( - phy, - &scic_sds_port_get_controller(port)->port_table[SCI_MAX_PORTS] - ); + if (port->phy_table[phy->phy_index] == phy && + scic_sds_phy_get_port(phy) == port) { + struct scic_sds_controller *scic = port->owning_controller; + struct isci_host *ihost = scic_to_ihost(scic); + /* Yep it is assigned to this port so remove it */ + scic_sds_phy_set_port(phy, &ihost->ports[SCI_MAX_PORTS].sci); port->phy_table[phy->phy_index] = NULL; - return SCI_SUCCESS; } @@ -643,7 +639,7 @@ void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port, bool do_notify_user) { struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); struct isci_host *ihost = scic_to_ihost(scic); struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); @@ -1620,10 +1616,9 @@ static void scic_sds_port_ready_substate_operational_enter(void *object) { u32 index; struct scic_sds_port *sci_port = object; - struct scic_sds_controller *scic = - scic_sds_port_get_controller(sci_port); + struct scic_sds_controller *scic = sci_port->owning_controller; struct isci_host *ihost = scic_to_ihost(scic); - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); scic_sds_port_set_ready_state_handlers( sci_port, @@ -1661,10 +1656,9 @@ static void scic_sds_port_ready_substate_operational_enter(void *object) static void scic_sds_port_ready_substate_operational_exit(void *object) { struct scic_sds_port *sci_port = object; - struct scic_sds_controller *scic = - scic_sds_port_get_controller(sci_port); + struct scic_sds_controller *scic = sci_port->owning_controller; struct isci_host *ihost = scic_to_ihost(scic); - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); /* * Kill the dummy task for this port if it has not yet posted @@ -1692,10 +1686,9 @@ static void scic_sds_port_ready_substate_operational_exit(void *object) static void scic_sds_port_ready_substate_configuring_enter(void *object) { struct scic_sds_port *sci_port = object; - struct scic_sds_controller *scic = - scic_sds_port_get_controller(sci_port); + struct scic_sds_controller *scic = sci_port->owning_controller; struct isci_host *ihost = scic_to_ihost(scic); - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); scic_sds_port_set_ready_state_handlers( sci_port, @@ -2259,7 +2252,7 @@ static void scic_sds_port_ready_state_enter(void *object) struct scic_sds_port *sci_port = object; struct scic_sds_controller *scic = sci_port->owning_controller; struct isci_host *ihost = scic_to_ihost(scic); - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); u32 prev_state; /* Put the ready state handlers in place though they will not be there long */ @@ -2366,7 +2359,7 @@ scic_sds_port_stopping_state_exit(void *object) static void scic_sds_port_failed_state_enter(void *object) { struct scic_sds_port *sci_port = object; - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); scic_sds_port_set_base_state_handlers(sci_port, SCI_BASE_PORT_STATE_FAILED); @@ -2398,11 +2391,9 @@ static const struct sci_base_state scic_sds_port_state_table[] = { } }; -void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 port_index, +void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 index, struct scic_sds_controller *scic) { - u32 index; - sci_base_state_machine_construct(&sci_port->state_machine, sci_port, scic_sds_port_state_table, @@ -2416,7 +2407,7 @@ void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 port_index, SCIC_SDS_PORT_READY_SUBSTATE_WAITING); sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT; - sci_port->physical_port_index = port_index; + sci_port->physical_port_index = index; sci_port->active_phy_mask = 0; sci_port->owning_controller = scic; @@ -2428,7 +2419,6 @@ void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 port_index, sci_port->reserved_tci = SCU_DUMMY_INDEX; sci_port->timer_handle = NULL; - sci_port->port_task_scheduler_registers = NULL; for (index = 0; index < SCI_MAX_PHYS; index++) diff --git a/drivers/scsi/isci/core/scic_sds_port.h b/drivers/scsi/isci/core/scic_sds_port.h index 213d42330b4b..3633561b686a 100644 --- a/drivers/scsi/isci/core/scic_sds_port.h +++ b/drivers/scsi/isci/core/scic_sds_port.h @@ -151,17 +151,12 @@ enum scic_sds_port_states { }; -struct isci_port; /** * struct scic_sds_port * * The core port object provides the the abstraction for an SCU port. */ struct scic_sds_port { - /** - * The field specifies the peer object for the port. - */ - struct isci_port *iport; /** * This field contains the information for the base port state machine. 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 aa7ac95ecbc6..2d3d067396d3 100644 --- a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c +++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c @@ -141,14 +141,15 @@ static struct scic_sds_port *scic_sds_port_configuration_agent_find_port( scic_sds_phy_get_attached_sas_address(phy, &phy_attached_device_address); for (i = 0; i < scic->logical_port_entries; i++) { - struct scic_sds_port *port = &scic->port_table[i]; + struct isci_host *ihost = scic_to_ihost(scic); + struct scic_sds_port *sci_port = &ihost->ports[i].sci; - scic_sds_port_get_sas_address(port, &port_sas_address); - scic_sds_port_get_attached_sas_address(port, &port_attached_device_address); + scic_sds_port_get_sas_address(sci_port, &port_sas_address); + scic_sds_port_get_attached_sas_address(sci_port, &port_attached_device_address); - if ((sci_sas_address_compare(port_sas_address, phy_sas_address) == 0) && - (sci_sas_address_compare(port_attached_device_address, phy_attached_device_address) == 0)) - return port; + if (sci_sas_address_compare(port_sas_address, phy_sas_address) == 0 && + sci_sas_address_compare(port_attached_device_address, phy_attached_device_address) == 0) + return sci_port; } return NULL; @@ -324,7 +325,7 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration( port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; - scic_sds_port_add_phy(&controller->port_table[port_index], + scic_sds_port_add_phy(&ihost->ports[port_index].sci, &ihost->phys[phy_index].sci); assigned_phy_mask |= (1 << phy_index); @@ -550,6 +551,7 @@ static void scic_sds_apc_agent_configure_ports( enum sci_status status; struct scic_sds_port *port; enum SCIC_SDS_APC_ACTIVITY apc_activity = SCIC_SDS_APC_SKIP_PHY; + struct isci_host *ihost = scic_to_ihost(controller); port = scic_sds_port_configuration_agent_find_port(controller, phy); @@ -571,7 +573,7 @@ static void scic_sds_apc_agent_configure_ports( port_index++ ) { - port = &controller->port_table[port_index]; + port = &ihost->ports[port_index].sci; /* First we must make sure that this PHY can be added to this Port. */ if (scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)) { diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index d180ad8a8bcf..cdd99304c363 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c @@ -277,10 +277,10 @@ void isci_host_deinit(struct isci_host *ihost) isci_host_change_state(ihost, isci_stopping); for (i = 0; i < SCI_MAX_PORTS; i++) { - struct isci_port *port = &ihost->isci_ports[i]; + struct isci_port *iport = &ihost->ports[i]; struct isci_remote_device *idev, *d; - list_for_each_entry_safe(idev, d, &port->remote_dev_list, node) { + list_for_each_entry_safe(idev, d, &iport->remote_dev_list, node) { isci_remote_device_change_state(idev, isci_stopping); isci_remote_device_stop(ihost, idev); } @@ -442,7 +442,7 @@ int isci_host_init(struct isci_host *isci_host) return -ENOMEM; for (i = 0; i < SCI_MAX_PORTS; i++) - isci_port_init(&isci_host->isci_ports[i], isci_host, i); + isci_port_init(&isci_host->ports[i], isci_host, i); for (i = 0; i < SCI_MAX_PHYS; i++) isci_phy_init(&isci_host->phys[i], isci_host, i); diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 00e4854e20d9..5a414c31a877 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h @@ -84,12 +84,7 @@ struct isci_host { struct dma_pool *dma_pool; unsigned int dma_pool_alloc_size; struct isci_phy phys[SCI_MAX_PHYS]; - - /* isci_ports and sas_ports are implicitly parallel to the - * ports maintained by the core - */ - struct isci_port isci_ports[SCI_MAX_PORTS]; - struct asd_sas_port sas_ports[SCI_MAX_PORTS]; + struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ struct sas_ha_struct sas_ha; int can_queue; diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index a5d5c0b97d00..522d39f9e132 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -221,8 +221,8 @@ static int isci_register_sas_ha(struct isci_host *isci_host) /* set the array of phy and port structs. */ for (i = 0; i < SCI_MAX_PHYS; i++) { - sas_phys[i] = &(isci_host->phys[i].sas_phy); - sas_ports[i] = &(isci_host->sas_ports[i]); + sas_phys[i] = &isci_host->phys[i].sas_phy; + sas_ports[i] = &isci_host->ports[i].sas_port; } sas_ha->sas_phy = sas_phys; diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 5e87fedb5676..35e2e517f671 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -70,29 +70,30 @@ #include "request.h" #include "core/scic_sds_controller.h" -static void isci_port_change_state( - struct isci_port *isci_port, - enum isci_status status); +static void isci_port_change_state(struct isci_port *iport, enum isci_status status) +{ + unsigned long flags; + dev_dbg(&iport->isci_host->pdev->dev, + "%s: iport = %p, state = 0x%x\n", + __func__, iport, status); + /* XXX pointless lock */ + spin_lock_irqsave(&iport->state_lock, flags); + iport->status = status; + spin_unlock_irqrestore(&iport->state_lock, flags); +} void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index) { - struct scic_sds_port *sci_port; - INIT_LIST_HEAD(&iport->remote_dev_list); INIT_LIST_HEAD(&iport->domain_dev_list); spin_lock_init(&iport->state_lock); init_completion(&iport->start_complete); iport->isci_host = ihost; isci_port_change_state(iport, isci_freed); - - sci_port = &ihost->sci.port_table[index]; - iport->sci_port_handle = sci_port; - sci_port->iport = iport; } - /** * isci_port_get_state() - This function gets the status of the port object. * @isci_port: This parameter points to the isci_port object @@ -105,21 +106,6 @@ enum isci_status isci_port_get_state( return isci_port->status; } -static void isci_port_change_state( - struct isci_port *isci_port, - enum isci_status status) -{ - unsigned long flags; - - dev_dbg(&isci_port->isci_host->pdev->dev, - "%s: isci_port = %p, state = 0x%x\n", - __func__, isci_port, status); - - spin_lock_irqsave(&isci_port->state_lock, flags); - isci_port->status = status; - spin_unlock_irqrestore(&isci_port->state_lock, flags); -} - void isci_port_bc_change_received(struct isci_host *ihost, struct scic_sds_port *sci_port, struct scic_sds_phy *sci_phy) @@ -140,7 +126,7 @@ void isci_port_link_up(struct isci_host *isci_host, unsigned long flags; struct scic_port_properties properties; struct isci_phy *isci_phy = sci_phy_to_iphy(phy); - struct isci_port *isci_port = port->iport; + struct isci_port *isci_port = sci_port_to_iport(port); unsigned long success = true; BUG_ON(isci_phy->isci_port != NULL); @@ -346,8 +332,7 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor spin_lock_irqsave(&ihost->scic_lock, flags); #define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT - status = scic_port_hard_reset(iport->sci_port_handle, - ISCI_PORT_RESET_TIMEOUT); + status = scic_port_hard_reset(&iport->sci, ISCI_PORT_RESET_TIMEOUT); spin_unlock_irqrestore(&ihost->scic_lock, flags); diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h index ac1ac86ead6f..355034542e4c 100644 --- a/drivers/scsi/isci/port.h +++ b/drivers/scsi/isci/port.h @@ -53,19 +53,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - * This file contains the isci_port object definition. - * - * port.h - */ - -#if !defined(_ISCI_PORT_H_) +#ifndef _ISCI_PORT_H_ #define _ISCI_PORT_H_ +#include "scic_sds_port.h" struct isci_phy; struct isci_host; -struct scic_sds_phy; - enum isci_status { isci_freed = 0x00, @@ -84,9 +77,6 @@ enum isci_status { * */ struct isci_port { - - struct scic_sds_port *sci_port_handle; - enum isci_status status; struct isci_host *isci_host; struct asd_sas_port sas_port; @@ -96,16 +86,19 @@ struct isci_port { struct completion start_complete; struct completion hard_reset_complete; enum sci_status hard_reset_status; + struct scic_sds_port sci; }; -#define to_isci_port(p) \ - container_of(p, struct isci_port, sas_port); +static inline struct isci_port *sci_port_to_iport(struct scic_sds_port *sci_port) +{ + struct isci_port *iport = container_of(sci_port, typeof(*iport), sci); + + return iport; +} enum isci_status isci_port_get_state( struct isci_port *isci_port); - - void isci_port_formed( struct asd_sas_phy *); diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 734d028448b0..a441c23b6859 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c @@ -1264,7 +1264,7 @@ static enum sci_status scic_remote_device_start(struct scic_sds_remote_device *s static enum sci_status isci_remote_device_construct(struct isci_port *iport, struct isci_remote_device *idev) { - struct scic_sds_port *sci_port = iport->sci_port_handle; + struct scic_sds_port *sci_port = &iport->sci; struct isci_host *ihost = iport->isci_host; struct domain_device *dev = idev->domain_dev; enum sci_status status; diff --git a/drivers/scsi/isci/sci_environment.h b/drivers/scsi/isci/sci_environment.h index bb07ed31b51c..1806969fc435 100644 --- a/drivers/scsi/isci/sci_environment.h +++ b/drivers/scsi/isci/sci_environment.h @@ -77,7 +77,7 @@ static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy) static inline struct device *sciport_to_dev(struct scic_sds_port *sci_port) { - struct isci_port *iport = sci_port->iport; + struct isci_port *iport = sci_port_to_iport(sci_port); if (!iport || !iport->isci_host) return NULL; -- 2.20.1