diff options
author | Edmund Nadolski <edmund.nadolski@intel.com> | 2011-05-19 23:17:47 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:49 -0400 |
commit | 0473661a125905240879456567e117ed8a58cf5d (patch) | |
tree | 47ad48e17b41a32c5d859dee5121737ba4c98ebb /drivers | |
parent | a628d478570d71fb8751ad09b8017139c5056002 (diff) |
isci: convert power control timer to sci_timer
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/host.c | 103 | ||||
-rw-r--r-- | drivers/scsi/isci/host.h | 5 |
2 files changed, 50 insertions, 58 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index aa00cce37821..7b497f2667b7 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -1374,6 +1374,8 @@ void isci_host_deinit(struct isci_host *ihost) | |||
1374 | 1374 | ||
1375 | del_timer_sync(&ihost->sci.port_agent.timer.timer); | 1375 | del_timer_sync(&ihost->sci.port_agent.timer.timer); |
1376 | 1376 | ||
1377 | del_timer_sync(&ihost->sci.power_control.timer.timer); | ||
1378 | |||
1377 | isci_timer_list_destroy(ihost); | 1379 | isci_timer_list_destroy(ihost); |
1378 | } | 1380 | } |
1379 | 1381 | ||
@@ -1935,67 +1937,55 @@ static enum sci_status scic_sds_controller_initialize_phy_startup(struct scic_sd | |||
1935 | return SCI_SUCCESS; | 1937 | return SCI_SUCCESS; |
1936 | } | 1938 | } |
1937 | 1939 | ||
1938 | static void scic_sds_controller_power_control_timer_start(struct scic_sds_controller *scic) | 1940 | static void power_control_timeout(unsigned long data) |
1939 | { | 1941 | { |
1940 | isci_timer_start(scic->power_control.timer, | 1942 | struct sci_timer *tmr = (struct sci_timer *)data; |
1941 | SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL); | 1943 | struct scic_sds_controller *scic = container_of(tmr, typeof(*scic), power_control.timer); |
1944 | struct isci_host *ihost = scic_to_ihost(scic); | ||
1945 | struct scic_sds_phy *sci_phy; | ||
1946 | unsigned long flags; | ||
1947 | u8 i; | ||
1942 | 1948 | ||
1943 | scic->power_control.timer_started = true; | 1949 | spin_lock_irqsave(&ihost->scic_lock, flags); |
1944 | } | ||
1945 | 1950 | ||
1946 | static void scic_sds_controller_power_control_timer_stop(struct scic_sds_controller *scic) | 1951 | if (tmr->cancel) |
1947 | { | 1952 | goto done; |
1948 | if (scic->power_control.timer_started) { | 1953 | |
1949 | isci_timer_stop(scic->power_control.timer); | 1954 | scic->power_control.phys_granted_power = 0; |
1955 | |||
1956 | if (scic->power_control.phys_waiting == 0) { | ||
1950 | scic->power_control.timer_started = false; | 1957 | scic->power_control.timer_started = false; |
1958 | goto done; | ||
1951 | } | 1959 | } |
1952 | } | ||
1953 | |||
1954 | static void scic_sds_controller_power_control_timer_restart(struct scic_sds_controller *scic) | ||
1955 | { | ||
1956 | scic_sds_controller_power_control_timer_stop(scic); | ||
1957 | scic_sds_controller_power_control_timer_start(scic); | ||
1958 | } | ||
1959 | 1960 | ||
1960 | static void scic_sds_controller_power_control_timer_handler( | 1961 | for (i = 0; i < SCI_MAX_PHYS; i++) { |
1961 | void *controller) | ||
1962 | { | ||
1963 | struct scic_sds_controller *scic; | ||
1964 | 1962 | ||
1965 | scic = (struct scic_sds_controller *)controller; | 1963 | if (scic->power_control.phys_waiting == 0) |
1964 | break; | ||
1966 | 1965 | ||
1967 | scic->power_control.phys_granted_power = 0; | 1966 | sci_phy = scic->power_control.requesters[i]; |
1967 | if (sci_phy == NULL) | ||
1968 | continue; | ||
1968 | 1969 | ||
1969 | if (scic->power_control.phys_waiting == 0) { | 1970 | if (scic->power_control.phys_granted_power >= |
1970 | scic->power_control.timer_started = false; | 1971 | scic->oem_parameters.sds1.controller.max_concurrent_dev_spin_up) |
1971 | } else { | 1972 | break; |
1972 | struct scic_sds_phy *sci_phy = NULL; | ||
1973 | u8 i; | ||
1974 | |||
1975 | for (i = 0; | ||
1976 | (i < SCI_MAX_PHYS) | ||
1977 | && (scic->power_control.phys_waiting != 0); | ||
1978 | i++) { | ||
1979 | if (scic->power_control.requesters[i] != NULL) { | ||
1980 | if (scic->power_control.phys_granted_power < | ||
1981 | scic->oem_parameters.sds1.controller.max_concurrent_dev_spin_up) { | ||
1982 | sci_phy = scic->power_control.requesters[i]; | ||
1983 | scic->power_control.requesters[i] = NULL; | ||
1984 | scic->power_control.phys_waiting--; | ||
1985 | scic->power_control.phys_granted_power++; | ||
1986 | scic_sds_phy_consume_power_handler(sci_phy); | ||
1987 | } else { | ||
1988 | break; | ||
1989 | } | ||
1990 | } | ||
1991 | } | ||
1992 | 1973 | ||
1993 | /* | 1974 | scic->power_control.requesters[i] = NULL; |
1994 | * It doesn't matter if the power list is empty, we need to start the | 1975 | scic->power_control.phys_waiting--; |
1995 | * timer in case another phy becomes ready. | 1976 | scic->power_control.phys_granted_power++; |
1996 | */ | 1977 | scic_sds_phy_consume_power_handler(sci_phy); |
1997 | scic_sds_controller_power_control_timer_start(scic); | ||
1998 | } | 1978 | } |
1979 | |||
1980 | /* | ||
1981 | * It doesn't matter if the power list is empty, we need to start the | ||
1982 | * timer in case another phy becomes ready. | ||
1983 | */ | ||
1984 | sci_mod_timer(tmr, SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL); | ||
1985 | scic->power_control.timer_started = true; | ||
1986 | |||
1987 | done: | ||
1988 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | ||
1999 | } | 1989 | } |
2000 | 1990 | ||
2001 | /** | 1991 | /** |
@@ -2019,7 +2009,13 @@ void scic_sds_controller_power_control_queue_insert( | |||
2019 | * stop and start the power_control timer. When the timer fires, the | 2009 | * stop and start the power_control timer. When the timer fires, the |
2020 | * no_of_phys_granted_power will be set to 0 | 2010 | * no_of_phys_granted_power will be set to 0 |
2021 | */ | 2011 | */ |
2022 | scic_sds_controller_power_control_timer_restart(scic); | 2012 | if (scic->power_control.timer_started) |
2013 | sci_del_timer(&scic->power_control.timer); | ||
2014 | |||
2015 | sci_mod_timer(&scic->power_control.timer, | ||
2016 | SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL); | ||
2017 | scic->power_control.timer_started = true; | ||
2018 | |||
2023 | } else { | 2019 | } else { |
2024 | /* Add the phy in the waiting list */ | 2020 | /* Add the phy in the waiting list */ |
2025 | scic->power_control.requesters[sci_phy->phy_index] = sci_phy; | 2021 | 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 | |||
2224 | 2220 | ||
2225 | static void scic_sds_controller_initialize_power_control(struct scic_sds_controller *scic) | 2221 | static void scic_sds_controller_initialize_power_control(struct scic_sds_controller *scic) |
2226 | { | 2222 | { |
2227 | struct isci_host *ihost = scic_to_ihost(scic); | 2223 | sci_init_timer(&scic->power_control.timer, power_control_timeout); |
2228 | scic->power_control.timer = isci_timer_create(ihost, | ||
2229 | scic, | ||
2230 | scic_sds_controller_power_control_timer_handler); | ||
2231 | 2224 | ||
2232 | memset(scic->power_control.requesters, 0, | 2225 | memset(scic->power_control.requesters, 0, |
2233 | sizeof(scic->power_control.requesters)); | 2226 | sizeof(scic->power_control.requesters)); |
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index deb0ee031f27..2be935fa6af2 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -83,10 +83,9 @@ struct scic_power_control { | |||
83 | bool timer_started; | 83 | bool timer_started; |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * This field is the handle to the driver timer object. This timer is used to | 86 | * Timer to control when the directed attached disks can consume power. |
87 | * control when the directed attached disks can consume power. | ||
88 | */ | 87 | */ |
89 | void *timer; | 88 | struct sci_timer timer; |
90 | 89 | ||
91 | /** | 90 | /** |
92 | * This field is used to keep track of how many phys are put into the | 91 | * This field is used to keep track of how many phys are put into the |