isci: convert power control timer to sci_timer
Edmund Nadolski [Fri, 20 May 2011 03:17:47 +0000 (20:17 -0700)]
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

drivers/scsi/isci/host.c
drivers/scsi/isci/host.h

index aa00cce..7b497f2 100644 (file)
@@ -1374,6 +1374,8 @@ void isci_host_deinit(struct isci_host *ihost)
 
        del_timer_sync(&ihost->sci.port_agent.timer.timer);
 
+       del_timer_sync(&ihost->sci.power_control.timer.timer);
+
        isci_timer_list_destroy(ihost);
 }
 
@@ -1935,67 +1937,55 @@ static enum sci_status scic_sds_controller_initialize_phy_startup(struct scic_sd
        return SCI_SUCCESS;
 }
 
-static void scic_sds_controller_power_control_timer_start(struct scic_sds_controller *scic)
+static void power_control_timeout(unsigned long data)
 {
-       isci_timer_start(scic->power_control.timer,
-                        SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
+       struct sci_timer *tmr = (struct sci_timer *)data;
+       struct scic_sds_controller *scic = container_of(tmr, typeof(*scic), power_control.timer);
+       struct isci_host *ihost = scic_to_ihost(scic);
+       struct scic_sds_phy *sci_phy;
+       unsigned long flags;
+       u8 i;
 
-       scic->power_control.timer_started = true;
-}
+       spin_lock_irqsave(&ihost->scic_lock, flags);
 
-static void scic_sds_controller_power_control_timer_stop(struct scic_sds_controller *scic)
-{
-       if (scic->power_control.timer_started) {
-               isci_timer_stop(scic->power_control.timer);
+       if (tmr->cancel)
+               goto done;
+
+       scic->power_control.phys_granted_power = 0;
+
+       if (scic->power_control.phys_waiting == 0) {
                scic->power_control.timer_started = false;
+               goto done;
        }
-}
-
-static void scic_sds_controller_power_control_timer_restart(struct scic_sds_controller *scic)
-{
-       scic_sds_controller_power_control_timer_stop(scic);
-       scic_sds_controller_power_control_timer_start(scic);
-}
 
-static void scic_sds_controller_power_control_timer_handler(
-       void *controller)
-{
-       struct scic_sds_controller *scic;
+       for (i = 0; i < SCI_MAX_PHYS; i++) {
 
-       scic = (struct scic_sds_controller *)controller;
+               if (scic->power_control.phys_waiting == 0)
+                       break;
 
-       scic->power_control.phys_granted_power = 0;
+               sci_phy = scic->power_control.requesters[i];
+               if (sci_phy == NULL)
+                       continue;
 
-       if (scic->power_control.phys_waiting == 0) {
-               scic->power_control.timer_started = false;
-       } else {
-               struct scic_sds_phy *sci_phy = NULL;
-               u8 i;
-
-               for (i = 0;
-                    (i < SCI_MAX_PHYS)
-                    && (scic->power_control.phys_waiting != 0);
-                    i++) {
-                       if (scic->power_control.requesters[i] != NULL) {
-                               if (scic->power_control.phys_granted_power <
-                                   scic->oem_parameters.sds1.controller.max_concurrent_dev_spin_up) {
-                                       sci_phy = scic->power_control.requesters[i];
-                                       scic->power_control.requesters[i] = NULL;
-                                       scic->power_control.phys_waiting--;
-                                       scic->power_control.phys_granted_power++;
-                                       scic_sds_phy_consume_power_handler(sci_phy);
-                               } else {
-                                       break;
-                               }
-                       }
-               }
+               if (scic->power_control.phys_granted_power >=
+                   scic->oem_parameters.sds1.controller.max_concurrent_dev_spin_up)
+                       break;
 
-               /*
-                * It doesn't matter if the power list is empty, we need to start the
-                * timer in case another phy becomes ready.
-                */
-               scic_sds_controller_power_control_timer_start(scic);
+               scic->power_control.requesters[i] = NULL;
+               scic->power_control.phys_waiting--;
+               scic->power_control.phys_granted_power++;
+               scic_sds_phy_consume_power_handler(sci_phy);
        }
+
+       /*
+        * It doesn't matter if the power list is empty, we need to start the
+        * timer in case another phy becomes ready.
+        */
+       sci_mod_timer(tmr, SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
+       scic->power_control.timer_started = true;
+
+done:
+       spin_unlock_irqrestore(&ihost->scic_lock, flags);
 }
 
 /**
@@ -2019,7 +2009,13 @@ void scic_sds_controller_power_control_queue_insert(
                 * stop and start the power_control timer. When the timer fires, the
                 * no_of_phys_granted_power will be set to 0
                 */
-               scic_sds_controller_power_control_timer_restart(scic);
+               if (scic->power_control.timer_started)
+                       sci_del_timer(&scic->power_control.timer);
+
+               sci_mod_timer(&scic->power_control.timer,
+                                SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
+               scic->power_control.timer_started = true;
+
        } else {
                /* Add the phy in the waiting list */
                scic->power_control.requesters[sci_phy->phy_index] = sci_phy;
@@ -2224,10 +2220,7 @@ static enum sci_status scic_controller_set_mode(struct scic_sds_controller *scic
 
 static void scic_sds_controller_initialize_power_control(struct scic_sds_controller *scic)
 {
-       struct isci_host *ihost = scic_to_ihost(scic);
-       scic->power_control.timer = isci_timer_create(ihost,
-                                                     scic,
-                                       scic_sds_controller_power_control_timer_handler);
+       sci_init_timer(&scic->power_control.timer, power_control_timeout);
 
        memset(scic->power_control.requesters, 0,
               sizeof(scic->power_control.requesters));
index deb0ee0..2be935f 100644 (file)
@@ -83,10 +83,9 @@ struct scic_power_control {
        bool timer_started;
 
        /**
-        * This field is the handle to the driver timer object.  This timer is used to
-        * control when the directed attached disks can consume power.
+        * Timer to control when the directed attached disks can consume power.
         */
-       void *timer;
+       struct sci_timer timer;
 
        /**
         * This field is used to keep track of how many phys are put into the