summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdmund Nadolski <edmund.nadolski@intel.com>2011-05-19 20:00:51 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:49 -0700
commitac0eeb4f774261d1da21a68169f7ddd4f6c082fc (patch)
tree28953f87b323fdc73f00642115910aab619e0150
parent5553ba2be0f3e3741e1a885a33d2b89921f9fd48 (diff)
downloadlinux-ac0eeb4f774261d1da21a68169f7ddd4f6c082fc.tar.gz
linux-ac0eeb4f774261d1da21a68169f7ddd4f6c082fc.tar.bz2
linux-ac0eeb4f774261d1da21a68169f7ddd4f6c082fc.zip
isci: convert port config agent timer to sci_timer
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com> [squashed collateral cleanups] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/host.c2
-rw-r--r--drivers/scsi/isci/host.h11
-rw-r--r--drivers/scsi/isci/port_config.c117
3 files changed, 53 insertions, 77 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index a3269b6fa225..468357ffc771 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1366,6 +1366,8 @@ void isci_host_deinit(struct isci_host *ihost)
del_timer_sync(&sci_port->timer.timer);
}
+ del_timer_sync(&ihost->sci.port_agent.timer.timer);
+
isci_timer_list_destroy(ihost);
}
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 784e1355e8ec..deb0ee031f27 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -122,7 +122,7 @@ struct scic_sds_port_configuration_agent {
bool timer_pending;
port_config_fn link_up_handler;
port_config_fn link_down_handler;
- void *timer;
+ struct sci_timer timer;
};
/**
@@ -569,15 +569,6 @@ static inline struct isci_host *scic_to_ihost(struct scic_sds_controller *scic)
}
/**
- * scic_sds_controller_get_port_configuration_agent() -
- *
- * This is a helper macro to get the port configuration agent from the
- * controller object.
- */
-#define scic_sds_controller_get_port_configuration_agent(controller) \
- (&(controller)->port_agent)
-
-/**
* scic_sds_controller_get_protocol_engine_group() -
*
* This macro returns the protocol engine group for this controller object.
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c
index ca76f493c30d..1cde7b9165f4 100644
--- a/drivers/scsi/isci/port_config.c
+++ b/drivers/scsi/isci/port_config.c
@@ -328,21 +328,25 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
return scic_sds_port_configuration_agent_validate_ports(controller, port_agent);
}
-/**
- *
- *
- * This timer routine is used to allow the SCI User to rediscover or change
- * 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 mpc_agent_timeout(unsigned long data)
{
u8 index;
- 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;
+ struct sci_timer *tmr = (struct sci_timer *)data;
+ struct scic_sds_port_configuration_agent *port_agent;
+ struct scic_sds_controller *scic;
+ struct isci_host *ihost;
+ unsigned long flags;
u16 configure_phy_mask;
+ port_agent = container_of(tmr, typeof(*port_agent), timer);
+ scic = container_of(port_agent, typeof(*scic), port_agent);
+ ihost = scic_to_ihost(scic);
+
+ spin_lock_irqsave(&ihost->scic_lock, flags);
+
+ if (tmr->cancel)
+ goto done;
+
port_agent->timer_pending = false;
/* Find the mask of phys that are reported read but as yet unconfigured into a port */
@@ -357,6 +361,9 @@ static void scic_sds_mpc_agent_timeout_handler(void *object)
sci_phy);
}
}
+
+done:
+ spin_unlock_irqrestore(&ihost->scic_lock, flags);
}
/**
@@ -441,8 +448,8 @@ static void scic_sds_mpc_agent_link_down(
!port_agent->timer_pending) {
port_agent->timer_pending = true;
- isci_timer_start(port_agent->timer,
- SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT);
+ sci_mod_timer(&port_agent->timer,
+ SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT);
}
scic_sds_port_link_down(sci_port, sci_phy);
@@ -500,31 +507,6 @@ static enum sci_status scic_sds_apc_agent_validate_phy_configuration(
/**
*
- * @controller: This is the controller that to which the port agent is assigned.
- * @port_agent: This is the port agent that is requesting the timer start
- * operation.
- * @phy: This is the phy that has caused the timer operation to be scheduled.
- *
- * This routine will restart the automatic port configuration timeout timer for
- * the next time period. This could be caused by either a link down event or a
- * link up event where we can not yet tell to which port a phy belongs.
- */
-static inline void scic_sds_apc_agent_start_timer(
- struct scic_sds_controller *scic,
- struct scic_sds_port_configuration_agent *port_agent,
- struct scic_sds_phy *sci_phy,
- u32 timeout)
-{
- if (port_agent->timer_pending)
- isci_timer_stop(port_agent->timer);
-
- port_agent->timer_pending = true;
-
- isci_timer_start(port_agent->timer, timeout);
-}
-
-/**
- *
* @controller: This is the controller object that receives the link up
* notification.
* @phy: This is the phy object which has gone link up.
@@ -635,9 +617,17 @@ static void scic_sds_apc_agent_configure_ports(
break;
case SCIC_SDS_APC_START_TIMER:
- scic_sds_apc_agent_start_timer(
- controller, port_agent, phy, SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION
- );
+ /*
+ * This can occur for either a link down event, or a link
+ * up event where we cannot yet tell the port to which a
+ * phy belongs.
+ */
+ if (port_agent->timer_pending)
+ sci_del_timer(&port_agent->timer);
+
+ port_agent->timer_pending = true;
+ sci_mod_timer(&port_agent->timer,
+ SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
break;
case SCIC_SDS_APC_SKIP_PHY:
@@ -719,15 +709,24 @@ static void scic_sds_apc_agent_link_down(
}
/* configure the phys into ports when the timer fires */
-static void scic_sds_apc_agent_timeout_handler(void *object)
+static void apc_agent_timeout(unsigned long data)
{
u32 index;
+ struct sci_timer *tmr = (struct sci_timer *)data;
struct scic_sds_port_configuration_agent *port_agent;
- struct scic_sds_controller *scic = object;
- struct isci_host *ihost = scic_to_ihost(scic);
+ struct scic_sds_controller *scic;
+ struct isci_host *ihost;
+ unsigned long flags;
u16 configure_phy_mask;
- port_agent = scic_sds_controller_get_port_configuration_agent(scic);
+ port_agent = container_of(tmr, typeof(*port_agent), timer);
+ scic = container_of(port_agent, typeof(*scic), port_agent);
+ ihost = scic_to_ihost(scic);
+
+ spin_lock_irqsave(&ihost->scic_lock, flags);
+
+ if (tmr->cancel)
+ goto done;
port_agent->timer_pending = false;
@@ -743,6 +742,9 @@ static void scic_sds_apc_agent_timeout_handler(void *object)
scic_sds_apc_agent_configure_ports(scic, port_agent,
&ihost->phys[index].sci, false);
}
+
+done:
+ spin_unlock_irqrestore(&ihost->scic_lock, flags);
}
/*
@@ -769,7 +771,6 @@ void scic_sds_port_configuration_agent_construct(
port_agent->link_down_handler = NULL;
port_agent->timer_pending = false;
- port_agent->timer = NULL;
for (index = 0; index < SCI_MAX_PORTS; index++) {
port_agent->phy_valid_port_range[index].min_index = 0;
@@ -781,9 +782,8 @@ enum sci_status scic_sds_port_configuration_agent_initialize(
struct scic_sds_controller *scic,
struct scic_sds_port_configuration_agent *port_agent)
{
- enum sci_status status = SCI_SUCCESS;
+ enum sci_status status;
enum scic_port_configuration_mode mode;
- struct isci_host *ihost = scic_to_ihost(scic);
mode = scic->oem_parameters.sds1.controller.mode_type;
@@ -794,10 +794,7 @@ enum sci_status scic_sds_port_configuration_agent_initialize(
port_agent->link_up_handler = scic_sds_mpc_agent_link_up;
port_agent->link_down_handler = scic_sds_mpc_agent_link_down;
- port_agent->timer = isci_timer_create(
- ihost,
- scic,
- scic_sds_mpc_agent_timeout_handler);
+ sci_init_timer(&port_agent->timer, mpc_agent_timeout);
} else {
status = scic_sds_apc_agent_validate_phy_configuration(
scic, port_agent);
@@ -805,21 +802,7 @@ enum sci_status scic_sds_port_configuration_agent_initialize(
port_agent->link_up_handler = scic_sds_apc_agent_link_up;
port_agent->link_down_handler = scic_sds_apc_agent_link_down;
- port_agent->timer = isci_timer_create(
- ihost,
- scic,
- scic_sds_apc_agent_timeout_handler);
- }
-
- /* Make sure we have actually gotten a timer */
- if ((status == SCI_SUCCESS) && (port_agent->timer == NULL)) {
- dev_err(scic_to_dev(scic),
- "%s: Controller 0x%p automatic port configuration "
- "agent could not get timer.\n",
- __func__,
- scic);
-
- status = SCI_FAILURE;
+ sci_init_timer(&port_agent->timer, apc_agent_timeout);
}
return status;