diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-04-02 08:15:20 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:00:37 -0400 |
commit | c629582d0dea42d8b3617f8c46ea2770b95e23aa (patch) | |
tree | e8c7af5050202929208945cad3e65714840c6f6e | |
parent | bc5c96748a5f2067193faa8131b2aa5f9775d309 (diff) |
isci: remove scic_controller state handlers
Remove the state handler indirections for the scic_controller, and replace
them with procedural calls that check for the correct state first.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/scsi/isci/core/scic_controller.h | 5 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.c | 847 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.h | 86 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_remote_device.c | 11 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_stp_request.c | 18 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 2 |
6 files changed, 193 insertions, 776 deletions
diff --git a/drivers/scsi/isci/core/scic_controller.h b/drivers/scsi/isci/core/scic_controller.h index 649b61ac5d6d..23a2c785fecd 100644 --- a/drivers/scsi/isci/core/scic_controller.h +++ b/drivers/scsi/isci/core/scic_controller.h | |||
@@ -110,11 +110,6 @@ enum sci_task_status scic_controller_start_task( | |||
110 | struct scic_sds_request *task_request, | 110 | struct scic_sds_request *task_request, |
111 | u16 io_tag); | 111 | u16 io_tag); |
112 | 112 | ||
113 | enum sci_status scic_controller_complete_task( | ||
114 | struct scic_sds_controller *controller, | ||
115 | struct scic_sds_remote_device *remote_device, | ||
116 | struct scic_sds_request *task_request); | ||
117 | |||
118 | enum sci_status scic_controller_terminate_request( | 113 | enum sci_status scic_controller_terminate_request( |
119 | struct scic_sds_controller *controller, | 114 | struct scic_sds_controller *controller, |
120 | struct scic_sds_remote_device *remote_device, | 115 | struct scic_sds_remote_device *remote_device, |
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index 4aae7b6361a7..f16a23a2f9e4 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c | |||
@@ -1453,46 +1453,45 @@ void scic_sds_controller_error_handler(struct scic_sds_controller *scic) | |||
1453 | 1453 | ||
1454 | 1454 | ||
1455 | 1455 | ||
1456 | void scic_sds_controller_link_up( | 1456 | void scic_sds_controller_link_up(struct scic_sds_controller *scic, |
1457 | struct scic_sds_controller *scic, | 1457 | struct scic_sds_port *port, struct scic_sds_phy *phy) |
1458 | struct scic_sds_port *sci_port, | 1458 | { |
1459 | struct scic_sds_phy *sci_phy) | 1459 | switch (scic->state_machine.current_state_id) { |
1460 | { | 1460 | case SCI_BASE_CONTROLLER_STATE_STARTING: |
1461 | scic_sds_controller_phy_handler_t link_up; | 1461 | scic_sds_controller_phy_timer_stop(scic); |
1462 | u32 state; | 1462 | scic->port_agent.link_up_handler(scic, &scic->port_agent, |
1463 | 1463 | port, phy); | |
1464 | state = scic->state_machine.current_state_id; | 1464 | scic_sds_controller_start_next_phy(scic); |
1465 | link_up = scic_sds_controller_state_handler_table[state].link_up; | 1465 | break; |
1466 | 1466 | case SCI_BASE_CONTROLLER_STATE_READY: | |
1467 | if (link_up) | 1467 | scic->port_agent.link_up_handler(scic, &scic->port_agent, |
1468 | link_up(scic, sci_port, sci_phy); | 1468 | port, phy); |
1469 | else | 1469 | break; |
1470 | default: | ||
1470 | dev_dbg(scic_to_dev(scic), | 1471 | dev_dbg(scic_to_dev(scic), |
1471 | "%s: SCIC Controller linkup event from phy %d in " | 1472 | "%s: SCIC Controller linkup event from phy %d in " |
1472 | "unexpected state %d\n", __func__, sci_phy->phy_index, | 1473 | "unexpected state %d\n", __func__, phy->phy_index, |
1473 | state); | 1474 | scic->state_machine.current_state_id); |
1475 | } | ||
1474 | } | 1476 | } |
1475 | 1477 | ||
1476 | 1478 | void scic_sds_controller_link_down(struct scic_sds_controller *scic, | |
1477 | void scic_sds_controller_link_down( | 1479 | struct scic_sds_port *port, struct scic_sds_phy *phy) |
1478 | struct scic_sds_controller *scic, | ||
1479 | struct scic_sds_port *sci_port, | ||
1480 | struct scic_sds_phy *sci_phy) | ||
1481 | { | 1480 | { |
1482 | u32 state; | 1481 | switch (scic->state_machine.current_state_id) { |
1483 | scic_sds_controller_phy_handler_t link_down; | 1482 | case SCI_BASE_CONTROLLER_STATE_STARTING: |
1484 | 1483 | case SCI_BASE_CONTROLLER_STATE_READY: | |
1485 | state = scic->state_machine.current_state_id; | 1484 | scic->port_agent.link_down_handler(scic, &scic->port_agent, |
1486 | link_down = scic_sds_controller_state_handler_table[state].link_down; | 1485 | port, phy); |
1487 | 1486 | break; | |
1488 | if (link_down) | 1487 | default: |
1489 | link_down(scic, sci_port, sci_phy); | ||
1490 | else | ||
1491 | dev_dbg(scic_to_dev(scic), | 1488 | dev_dbg(scic_to_dev(scic), |
1492 | "%s: SCIC Controller linkdown event from phy %d in " | 1489 | "%s: SCIC Controller linkdown event from phy %d in " |
1493 | "unexpected state %d\n", | 1490 | "unexpected state %d\n", |
1494 | __func__, | 1491 | __func__, |
1495 | sci_phy->phy_index, state); | 1492 | phy->phy_index, |
1493 | scic->state_machine.current_state_id); | ||
1494 | } | ||
1496 | } | 1495 | } |
1497 | 1496 | ||
1498 | /** | 1497 | /** |
@@ -1518,30 +1517,25 @@ static bool scic_sds_controller_has_remote_devices_stopping( | |||
1518 | /** | 1517 | /** |
1519 | * This method is called by the remote device to inform the controller | 1518 | * This method is called by the remote device to inform the controller |
1520 | * object that the remote device has stopped. | 1519 | * object that the remote device has stopped. |
1521 | * | ||
1522 | */ | 1520 | */ |
1523 | |||
1524 | void scic_sds_controller_remote_device_stopped(struct scic_sds_controller *scic, | 1521 | void scic_sds_controller_remote_device_stopped(struct scic_sds_controller *scic, |
1525 | struct scic_sds_remote_device *sci_dev) | 1522 | struct scic_sds_remote_device *sci_dev) |
1526 | { | 1523 | { |
1527 | 1524 | if (scic->state_machine.current_state_id != | |
1528 | u32 state; | 1525 | SCI_BASE_CONTROLLER_STATE_STOPPING) { |
1529 | scic_sds_controller_device_handler_t stopped; | ||
1530 | |||
1531 | state = scic->state_machine.current_state_id; | ||
1532 | stopped = scic_sds_controller_state_handler_table[state].device_stopped; | ||
1533 | |||
1534 | if (stopped) | ||
1535 | stopped(scic, sci_dev); | ||
1536 | else { | ||
1537 | dev_dbg(scic_to_dev(scic), | 1526 | dev_dbg(scic_to_dev(scic), |
1538 | "%s: SCIC Controller 0x%p remote device stopped event " | 1527 | "SCIC Controller 0x%p remote device stopped event " |
1539 | "from device 0x%p in unexpected state %d\n", | 1528 | "from device 0x%p in unexpected state %d\n", |
1540 | __func__, scic, sci_dev, state); | 1529 | scic, sci_dev, |
1530 | scic->state_machine.current_state_id); | ||
1531 | return; | ||
1541 | } | 1532 | } |
1542 | } | ||
1543 | |||
1544 | 1533 | ||
1534 | if (!scic_sds_controller_has_remote_devices_stopping(scic)) { | ||
1535 | sci_base_state_machine_change_state(&scic->state_machine, | ||
1536 | SCI_BASE_CONTROLLER_STATE_STOPPED); | ||
1537 | } | ||
1538 | } | ||
1545 | 1539 | ||
1546 | /** | 1540 | /** |
1547 | * This method will write to the SCU PCP register the request value. The method | 1541 | * This method will write to the SCU PCP register the request value. The method |
@@ -1841,40 +1835,6 @@ static void scic_sds_controller_set_default_config_parameters(struct scic_sds_co | |||
1841 | } | 1835 | } |
1842 | 1836 | ||
1843 | /** | 1837 | /** |
1844 | * scic_controller_initialize() - This method will initialize the controller | ||
1845 | * hardware managed by the supplied core controller object. This method | ||
1846 | * will bring the physical controller hardware out of reset and enable the | ||
1847 | * core to determine the capabilities of the hardware being managed. Thus, | ||
1848 | * the core controller can determine it's exact physical (DMA capable) | ||
1849 | * memory requirements. | ||
1850 | * @controller: This parameter specifies the controller to be initialized. | ||
1851 | * | ||
1852 | * The SCI Core user must have called scic_controller_construct() on the | ||
1853 | * supplied controller object previously. Indicate if the controller was | ||
1854 | * successfully initialized or if it failed in some way. SCI_SUCCESS This value | ||
1855 | * is returned if the controller hardware was successfully initialized. | ||
1856 | */ | ||
1857 | enum sci_status scic_controller_initialize( | ||
1858 | struct scic_sds_controller *scic) | ||
1859 | { | ||
1860 | enum sci_status status = SCI_FAILURE_INVALID_STATE; | ||
1861 | scic_sds_controller_handler_t initialize; | ||
1862 | u32 state; | ||
1863 | |||
1864 | state = scic->state_machine.current_state_id; | ||
1865 | initialize = scic_sds_controller_state_handler_table[state].initialize; | ||
1866 | |||
1867 | if (initialize) | ||
1868 | status = initialize(scic); | ||
1869 | else | ||
1870 | dev_warn(scic_to_dev(scic), | ||
1871 | "%s: SCIC Controller initialize operation requested " | ||
1872 | "in invalid state %d\n", __func__, state); | ||
1873 | |||
1874 | return status; | ||
1875 | } | ||
1876 | |||
1877 | /** | ||
1878 | * scic_controller_get_suggested_start_timeout() - This method returns the | 1838 | * scic_controller_get_suggested_start_timeout() - This method returns the |
1879 | * suggested scic_controller_start() timeout amount. The user is free to | 1839 | * suggested scic_controller_start() timeout amount. The user is free to |
1880 | * use any timeout value, but this method provides the suggested minimum | 1840 | * use any timeout value, but this method provides the suggested minimum |
@@ -1913,49 +1873,6 @@ u32 scic_controller_get_suggested_start_timeout( | |||
1913 | } | 1873 | } |
1914 | 1874 | ||
1915 | /** | 1875 | /** |
1916 | * scic_controller_start() - This method will start the supplied core | ||
1917 | * controller. This method will start the staggered spin up operation. The | ||
1918 | * SCI User completion callback is called when the following conditions are | ||
1919 | * met: -# the return status of this method is SCI_SUCCESS. -# after all of | ||
1920 | * the phys have successfully started or been given the opportunity to start. | ||
1921 | * @controller: the handle to the controller object to start. | ||
1922 | * @timeout: This parameter specifies the number of milliseconds in which the | ||
1923 | * start operation should complete. | ||
1924 | * | ||
1925 | * The SCI Core user must have filled in the physical memory descriptor | ||
1926 | * structure via the sci_controller_get_memory_descriptor_list() method. The | ||
1927 | * SCI Core user must have invoked the scic_controller_initialize() method | ||
1928 | * prior to invoking this method. The controller must be in the INITIALIZED or | ||
1929 | * STARTED state. Indicate if the controller start method succeeded or failed | ||
1930 | * in some way. SCI_SUCCESS if the start operation succeeded. | ||
1931 | * SCI_WARNING_ALREADY_IN_STATE if the controller is already in the STARTED | ||
1932 | * state. SCI_FAILURE_INVALID_STATE if the controller is not either in the | ||
1933 | * INITIALIZED or STARTED states. SCI_FAILURE_INVALID_MEMORY_DESCRIPTOR if | ||
1934 | * there are inconsistent or invalid values in the supplied | ||
1935 | * struct sci_physical_memory_descriptor array. | ||
1936 | */ | ||
1937 | enum sci_status scic_controller_start( | ||
1938 | struct scic_sds_controller *scic, | ||
1939 | u32 timeout) | ||
1940 | { | ||
1941 | enum sci_status status = SCI_FAILURE_INVALID_STATE; | ||
1942 | scic_sds_controller_timed_handler_t start; | ||
1943 | u32 state; | ||
1944 | |||
1945 | state = scic->state_machine.current_state_id; | ||
1946 | start = scic_sds_controller_state_handler_table[state].start; | ||
1947 | |||
1948 | if (start) | ||
1949 | status = start(scic, timeout); | ||
1950 | else | ||
1951 | dev_warn(scic_to_dev(scic), | ||
1952 | "%s: SCIC Controller start operation requested in " | ||
1953 | "invalid state %d\n", __func__, state); | ||
1954 | |||
1955 | return status; | ||
1956 | } | ||
1957 | |||
1958 | /** | ||
1959 | * scic_controller_stop() - This method will stop an individual controller | 1876 | * scic_controller_stop() - This method will stop an individual controller |
1960 | * object.This method will invoke the associated user callback upon | 1877 | * object.This method will invoke the associated user callback upon |
1961 | * completion. The completion callback is called when the following | 1878 | * completion. The completion callback is called when the following |
@@ -1977,21 +1894,18 @@ enum sci_status scic_controller_stop( | |||
1977 | struct scic_sds_controller *scic, | 1894 | struct scic_sds_controller *scic, |
1978 | u32 timeout) | 1895 | u32 timeout) |
1979 | { | 1896 | { |
1980 | enum sci_status status = SCI_FAILURE_INVALID_STATE; | 1897 | if (scic->state_machine.current_state_id != |
1981 | scic_sds_controller_timed_handler_t stop; | 1898 | SCI_BASE_CONTROLLER_STATE_READY) { |
1982 | u32 state; | ||
1983 | |||
1984 | state = scic->state_machine.current_state_id; | ||
1985 | stop = scic_sds_controller_state_handler_table[state].stop; | ||
1986 | |||
1987 | if (stop) | ||
1988 | status = stop(scic, timeout); | ||
1989 | else | ||
1990 | dev_warn(scic_to_dev(scic), | 1899 | dev_warn(scic_to_dev(scic), |
1991 | "%s: SCIC Controller stop operation requested in " | 1900 | "SCIC Controller stop operation requested in " |
1992 | "invalid state %d\n", __func__, state); | 1901 | "invalid state\n"); |
1902 | return SCI_FAILURE_INVALID_STATE; | ||
1903 | } | ||
1993 | 1904 | ||
1994 | return status; | 1905 | isci_timer_start(scic->timeout_timer, timeout); |
1906 | sci_base_state_machine_change_state(&scic->state_machine, | ||
1907 | SCI_BASE_CONTROLLER_STATE_STOPPING); | ||
1908 | return SCI_SUCCESS; | ||
1995 | } | 1909 | } |
1996 | 1910 | ||
1997 | /** | 1911 | /** |
@@ -2009,21 +1923,24 @@ enum sci_status scic_controller_stop( | |||
2009 | enum sci_status scic_controller_reset( | 1923 | enum sci_status scic_controller_reset( |
2010 | struct scic_sds_controller *scic) | 1924 | struct scic_sds_controller *scic) |
2011 | { | 1925 | { |
2012 | enum sci_status status = SCI_FAILURE_INVALID_STATE; | 1926 | switch (scic->state_machine.current_state_id) { |
2013 | scic_sds_controller_handler_t reset; | 1927 | case SCI_BASE_CONTROLLER_STATE_RESET: |
2014 | u32 state; | 1928 | case SCI_BASE_CONTROLLER_STATE_READY: |
2015 | 1929 | case SCI_BASE_CONTROLLER_STATE_STOPPED: | |
2016 | state = scic->state_machine.current_state_id; | 1930 | case SCI_BASE_CONTROLLER_STATE_FAILED: |
2017 | reset = scic_sds_controller_state_handler_table[state].reset; | 1931 | /* |
2018 | 1932 | * The reset operation is not a graceful cleanup, just | |
2019 | if (reset) | 1933 | * perform the state transition. |
2020 | status = reset(scic); | 1934 | */ |
2021 | else | 1935 | sci_base_state_machine_change_state(&scic->state_machine, |
1936 | SCI_BASE_CONTROLLER_STATE_RESETTING); | ||
1937 | return SCI_SUCCESS; | ||
1938 | default: | ||
2022 | dev_warn(scic_to_dev(scic), | 1939 | dev_warn(scic_to_dev(scic), |
2023 | "%s: SCIC Controller reset operation requested in " | 1940 | "SCIC Controller reset operation requested in " |
2024 | "invalid state %d\n", __func__, state); | 1941 | "invalid state\n"); |
2025 | 1942 | return SCI_FAILURE_INVALID_STATE; | |
2026 | return status; | 1943 | } |
2027 | } | 1944 | } |
2028 | 1945 | ||
2029 | /** | 1946 | /** |
@@ -2055,19 +1972,25 @@ enum sci_status scic_controller_reset( | |||
2055 | */ | 1972 | */ |
2056 | enum sci_io_status scic_controller_start_io( | 1973 | enum sci_io_status scic_controller_start_io( |
2057 | struct scic_sds_controller *scic, | 1974 | struct scic_sds_controller *scic, |
2058 | struct scic_sds_remote_device *remote_device, | 1975 | struct scic_sds_remote_device *rdev, |
2059 | struct scic_sds_request *request, | 1976 | struct scic_sds_request *req, |
2060 | u16 io_tag) | 1977 | u16 io_tag) |
2061 | { | 1978 | { |
2062 | u32 state; | 1979 | enum sci_status status; |
2063 | scic_sds_controller_start_request_handler_t start_io; | 1980 | |
1981 | if (scic->state_machine.current_state_id != | ||
1982 | SCI_BASE_CONTROLLER_STATE_READY) { | ||
1983 | dev_warn(scic_to_dev(scic), "invalid state to start I/O"); | ||
1984 | return SCI_FAILURE_INVALID_STATE; | ||
1985 | } | ||
2064 | 1986 | ||
2065 | state = scic->state_machine.current_state_id; | 1987 | status = scic_sds_remote_device_start_io(scic, rdev, req); |
2066 | start_io = scic_sds_controller_state_handler_table[state].start_io; | 1988 | if (status != SCI_SUCCESS) |
1989 | return status; | ||
2067 | 1990 | ||
2068 | return start_io(scic, | 1991 | scic->io_request_table[scic_sds_io_tag_get_index(req->io_tag)] = req; |
2069 | (struct sci_base_remote_device *) remote_device, | 1992 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); |
2070 | request, io_tag); | 1993 | return SCI_SUCCESS; |
2071 | } | 1994 | } |
2072 | 1995 | ||
2073 | /** | 1996 | /** |
@@ -2088,18 +2011,30 @@ enum sci_io_status scic_controller_start_io( | |||
2088 | */ | 2011 | */ |
2089 | enum sci_status scic_controller_terminate_request( | 2012 | enum sci_status scic_controller_terminate_request( |
2090 | struct scic_sds_controller *scic, | 2013 | struct scic_sds_controller *scic, |
2091 | struct scic_sds_remote_device *remote_device, | 2014 | struct scic_sds_remote_device *rdev, |
2092 | struct scic_sds_request *request) | 2015 | struct scic_sds_request *req) |
2093 | { | 2016 | { |
2094 | scic_sds_controller_request_handler_t terminate_request; | 2017 | enum sci_status status; |
2095 | u32 state; | 2018 | |
2019 | if (scic->state_machine.current_state_id != | ||
2020 | SCI_BASE_CONTROLLER_STATE_READY) { | ||
2021 | dev_warn(scic_to_dev(scic), | ||
2022 | "invalid state to terminate request\n"); | ||
2023 | return SCI_FAILURE_INVALID_STATE; | ||
2024 | } | ||
2096 | 2025 | ||
2097 | state = scic->state_machine.current_state_id; | 2026 | status = scic_sds_io_request_terminate(req); |
2098 | terminate_request = scic_sds_controller_state_handler_table[state].terminate_request; | 2027 | if (status != SCI_SUCCESS) |
2028 | return status; | ||
2099 | 2029 | ||
2100 | return terminate_request(scic, | 2030 | /* |
2101 | (struct sci_base_remote_device *)remote_device, | 2031 | * Utilize the original post context command and or in the POST_TC_ABORT |
2102 | request); | 2032 | * request sub-type. |
2033 | */ | ||
2034 | scic_sds_controller_post_request(scic, | ||
2035 | scic_sds_request_get_post_context(req) | | ||
2036 | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT); | ||
2037 | return SCI_SUCCESS; | ||
2103 | } | 2038 | } |
2104 | 2039 | ||
2105 | /** | 2040 | /** |
@@ -2126,18 +2061,44 @@ enum sci_status scic_controller_terminate_request( | |||
2126 | */ | 2061 | */ |
2127 | enum sci_status scic_controller_complete_io( | 2062 | enum sci_status scic_controller_complete_io( |
2128 | struct scic_sds_controller *scic, | 2063 | struct scic_sds_controller *scic, |
2129 | struct scic_sds_remote_device *remote_device, | 2064 | struct scic_sds_remote_device *rdev, |
2130 | struct scic_sds_request *request) | 2065 | struct scic_sds_request *request) |
2131 | { | 2066 | { |
2132 | u32 state; | 2067 | enum sci_status status; |
2133 | scic_sds_controller_request_handler_t complete_io; | 2068 | u16 index; |
2069 | |||
2070 | switch (scic->state_machine.current_state_id) { | ||
2071 | case SCI_BASE_CONTROLLER_STATE_STOPPING: | ||
2072 | /* XXX: Implement this function */ | ||
2073 | return SCI_FAILURE; | ||
2074 | case SCI_BASE_CONTROLLER_STATE_READY: | ||
2075 | status = scic_sds_remote_device_complete_io(scic, rdev, request); | ||
2076 | if (status != SCI_SUCCESS) | ||
2077 | return status; | ||
2078 | |||
2079 | index = scic_sds_io_tag_get_index(request->io_tag); | ||
2080 | scic->io_request_table[index] = NULL; | ||
2081 | return SCI_SUCCESS; | ||
2082 | default: | ||
2083 | dev_warn(scic_to_dev(scic), "invalid state to complete I/O"); | ||
2084 | return SCI_FAILURE_INVALID_STATE; | ||
2085 | } | ||
2086 | |||
2087 | } | ||
2088 | |||
2089 | enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req) | ||
2090 | { | ||
2091 | struct scic_sds_controller *scic = sci_req->owning_controller; | ||
2134 | 2092 | ||
2135 | state = scic->state_machine.current_state_id; | 2093 | if (scic->state_machine.current_state_id != |
2136 | complete_io = scic_sds_controller_state_handler_table[state].complete_io; | 2094 | SCI_BASE_CONTROLLER_STATE_READY) { |
2095 | dev_warn(scic_to_dev(scic), "invalid state to continue I/O"); | ||
2096 | return SCI_FAILURE_INVALID_STATE; | ||
2097 | } | ||
2137 | 2098 | ||
2138 | return complete_io(scic, | 2099 | scic->io_request_table[scic_sds_io_tag_get_index(sci_req->io_tag)] = sci_req; |
2139 | (struct sci_base_remote_device *)remote_device, | 2100 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req)); |
2140 | request); | 2101 | return SCI_SUCCESS; |
2141 | } | 2102 | } |
2142 | 2103 | ||
2143 | /** | 2104 | /** |
@@ -2170,71 +2131,45 @@ enum sci_status scic_controller_complete_io( | |||
2170 | */ | 2131 | */ |
2171 | enum sci_task_status scic_controller_start_task( | 2132 | enum sci_task_status scic_controller_start_task( |
2172 | struct scic_sds_controller *scic, | 2133 | struct scic_sds_controller *scic, |
2173 | struct scic_sds_remote_device *remote_device, | 2134 | struct scic_sds_remote_device *rdev, |
2174 | struct scic_sds_request *task_request, | 2135 | struct scic_sds_request *req, |
2175 | u16 task_tag) | 2136 | u16 task_tag) |
2176 | { | 2137 | { |
2177 | u32 state; | 2138 | enum sci_status status; |
2178 | scic_sds_controller_start_request_handler_t start_task; | ||
2179 | enum sci_task_status status = SCI_TASK_FAILURE_INVALID_STATE; | ||
2180 | |||
2181 | state = scic->state_machine.current_state_id; | ||
2182 | start_task = scic_sds_controller_state_handler_table[state].start_task; | ||
2183 | 2139 | ||
2184 | if (start_task) | 2140 | if (scic->state_machine.current_state_id != |
2185 | status = start_task(scic, | 2141 | SCI_BASE_CONTROLLER_STATE_READY) { |
2186 | (struct sci_base_remote_device *)remote_device, | ||
2187 | task_request, | ||
2188 | task_tag); | ||
2189 | else | ||
2190 | dev_warn(scic_to_dev(scic), | 2142 | dev_warn(scic_to_dev(scic), |
2191 | "%s: SCIC Controller starting task from invalid " | 2143 | "%s: SCIC Controller starting task from invalid " |
2192 | "state\n", | 2144 | "state\n", |
2193 | __func__); | 2145 | __func__); |
2146 | return SCI_TASK_FAILURE_INVALID_STATE; | ||
2147 | } | ||
2194 | 2148 | ||
2195 | return status; | 2149 | status = scic_sds_remote_device_start_task(scic, rdev, req); |
2196 | } | 2150 | switch (status) { |
2197 | 2151 | case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS: | |
2198 | /** | 2152 | scic->io_request_table[scic_sds_io_tag_get_index(req->io_tag)] = req; |
2199 | * scic_controller_complete_task() - This method will perform core specific | ||
2200 | * completion operations for task management request. After this method is | ||
2201 | * invoked, the user should consider the task request as invalid until it is | ||
2202 | * properly reused (i.e. re-constructed). | ||
2203 | * @controller: The handle to the controller object for which to complete the | ||
2204 | * task management request. | ||
2205 | * @remote_device: The handle to the remote device object for which to complete | ||
2206 | * the task management request. | ||
2207 | * @task_request: the handle to the task management request object to complete. | ||
2208 | * | ||
2209 | * Indicate if the controller successfully completed the task management | ||
2210 | * request. SCI_SUCCESS if the completion process was successful. | ||
2211 | */ | ||
2212 | enum sci_status scic_controller_complete_task( | ||
2213 | struct scic_sds_controller *scic, | ||
2214 | struct scic_sds_remote_device *remote_device, | ||
2215 | struct scic_sds_request *task_request) | ||
2216 | { | ||
2217 | u32 state; | ||
2218 | scic_sds_controller_request_handler_t complete_task; | ||
2219 | enum sci_status status = SCI_FAILURE_INVALID_STATE; | ||
2220 | 2153 | ||
2221 | state = scic->state_machine.current_state_id; | 2154 | /* |
2222 | complete_task = scic_sds_controller_state_handler_table[state].complete_task; | 2155 | * We will let framework know this task request started successfully, |
2156 | * although core is still woring on starting the request (to post tc when | ||
2157 | * RNC is resumed.) | ||
2158 | */ | ||
2159 | return SCI_SUCCESS; | ||
2160 | case SCI_SUCCESS: | ||
2161 | scic->io_request_table[scic_sds_io_tag_get_index(req->io_tag)] = req; | ||
2223 | 2162 | ||
2224 | if (complete_task) | 2163 | scic_sds_controller_post_request(scic, |
2225 | status = complete_task(scic, | 2164 | scic_sds_request_get_post_context(req)); |
2226 | (struct sci_base_remote_device *)remote_device, | 2165 | break; |
2227 | task_request); | 2166 | default: |
2228 | else | 2167 | break; |
2229 | dev_warn(scic_to_dev(scic), | 2168 | } |
2230 | "%s: SCIC Controller completing task from invalid " | ||
2231 | "state\n", | ||
2232 | __func__); | ||
2233 | 2169 | ||
2234 | return status; | 2170 | return status; |
2235 | } | 2171 | } |
2236 | 2172 | ||
2237 | |||
2238 | /** | 2173 | /** |
2239 | * scic_controller_get_port_handle() - This method simply provides the user | 2174 | * scic_controller_get_port_handle() - This method simply provides the user |
2240 | * with a unique handle for a given SAS/SATA core port index. | 2175 | * with a unique handle for a given SAS/SATA core port index. |
@@ -2706,52 +2641,23 @@ struct scic_sds_controller *scic_controller_alloc(struct device *dev) | |||
2706 | return devm_kzalloc(dev, sizeof(struct scic_sds_controller), GFP_KERNEL); | 2641 | return devm_kzalloc(dev, sizeof(struct scic_sds_controller), GFP_KERNEL); |
2707 | } | 2642 | } |
2708 | 2643 | ||
2709 | static enum sci_status | 2644 | enum sci_status scic_controller_initialize( |
2710 | default_controller_handler(struct scic_sds_controller *scic, const char *func) | 2645 | struct scic_sds_controller *scic) |
2711 | { | ||
2712 | dev_warn(scic_to_dev(scic), "%s: invalid state %d\n", func, | ||
2713 | scic->state_machine.current_state_id); | ||
2714 | |||
2715 | return SCI_FAILURE_INVALID_STATE; | ||
2716 | } | ||
2717 | |||
2718 | static enum sci_status scic_sds_controller_default_start_operation_handler( | ||
2719 | struct scic_sds_controller *scic, | ||
2720 | struct sci_base_remote_device *remote_device, | ||
2721 | struct scic_sds_request *request, | ||
2722 | u16 io_tag) | ||
2723 | { | ||
2724 | return default_controller_handler(scic, __func__); | ||
2725 | } | ||
2726 | |||
2727 | static enum sci_status scic_sds_controller_default_request_handler( | ||
2728 | struct scic_sds_controller *scic, | ||
2729 | struct sci_base_remote_device *remote_device, | ||
2730 | struct scic_sds_request *request) | ||
2731 | { | ||
2732 | return default_controller_handler(scic, __func__); | ||
2733 | } | ||
2734 | |||
2735 | static enum sci_status | ||
2736 | scic_sds_controller_general_reset_handler(struct scic_sds_controller *scic) | ||
2737 | { | ||
2738 | /* The reset operation is not a graceful cleanup just perform the state | ||
2739 | * transition. | ||
2740 | */ | ||
2741 | sci_base_state_machine_change_state(&scic->state_machine, | ||
2742 | SCI_BASE_CONTROLLER_STATE_RESETTING); | ||
2743 | |||
2744 | return SCI_SUCCESS; | ||
2745 | } | ||
2746 | |||
2747 | static enum sci_status | ||
2748 | scic_sds_controller_reset_state_initialize_handler(struct scic_sds_controller *scic) | ||
2749 | { | 2646 | { |
2750 | struct sci_base_state_machine *sm = &scic->state_machine; | 2647 | struct sci_base_state_machine *sm = &scic->state_machine; |
2751 | enum sci_status result = SCI_SUCCESS; | 2648 | enum sci_status result = SCI_SUCCESS; |
2752 | struct isci_host *ihost; | 2649 | struct isci_host *ihost; |
2753 | u32 index, state; | 2650 | u32 index, state; |
2754 | 2651 | ||
2652 | if (scic->state_machine.current_state_id != | ||
2653 | SCI_BASE_CONTROLLER_STATE_RESET) { | ||
2654 | dev_warn(scic_to_dev(scic), | ||
2655 | "SCIC Controller initialize operation requested " | ||
2656 | "in invalid state\n"); | ||
2657 | return SCI_FAILURE_INVALID_STATE; | ||
2658 | } | ||
2659 | |||
2660 | |||
2755 | ihost = sci_object_get_association(scic); | 2661 | ihost = sci_object_get_association(scic); |
2756 | 2662 | ||
2757 | sci_base_state_machine_change_state(sm, SCI_BASE_CONTROLLER_STATE_INITIALIZING); | 2663 | sci_base_state_machine_change_state(sm, SCI_BASE_CONTROLLER_STATE_INITIALIZING); |
@@ -2908,30 +2814,19 @@ scic_sds_controller_reset_state_initialize_handler(struct scic_sds_controller *s | |||
2908 | return result; | 2814 | return result; |
2909 | } | 2815 | } |
2910 | 2816 | ||
2911 | /* | 2817 | enum sci_status scic_controller_start(struct scic_sds_controller *scic, |
2912 | * ***************************************************************************** | 2818 | u32 timeout) |
2913 | * * INITIALIZED STATE HANDLERS | ||
2914 | * ***************************************************************************** */ | ||
2915 | |||
2916 | /* | ||
2917 | * This function is the struct scic_sds_controller start handler for the | ||
2918 | * initialized state. | ||
2919 | * - Validate we have a good memory descriptor table - Initialze the | ||
2920 | * physical memory before programming the hardware - Program the SCU hardware | ||
2921 | * with the physical memory addresses passed in the memory descriptor table. - | ||
2922 | * Initialzie the TCi pool - Initialize the RNi pool - Initialize the | ||
2923 | * completion queue - Initialize the unsolicited frame data - Take the SCU port | ||
2924 | * task scheduler out of reset - Start the first phy object. - Transition to | ||
2925 | * SCI_BASE_CONTROLLER_STATE_STARTING. enum sci_status SCI_SUCCESS if all of the | ||
2926 | * controller start operations complete | ||
2927 | * SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD if one or more of the memory | ||
2928 | * descriptor fields is invalid. | ||
2929 | */ | ||
2930 | static enum sci_status scic_sds_controller_initialized_state_start_handler( | ||
2931 | struct scic_sds_controller *scic, u32 timeout) | ||
2932 | { | 2819 | { |
2933 | u16 index; | ||
2934 | enum sci_status result; | 2820 | enum sci_status result; |
2821 | u16 index; | ||
2822 | |||
2823 | if (scic->state_machine.current_state_id != | ||
2824 | SCI_BASE_CONTROLLER_STATE_INITIALIZED) { | ||
2825 | dev_warn(scic_to_dev(scic), | ||
2826 | "SCIC Controller start operation requested in " | ||
2827 | "invalid state\n"); | ||
2828 | return SCI_FAILURE_INVALID_STATE; | ||
2829 | } | ||
2935 | 2830 | ||
2936 | /* Build the TCi free pool */ | 2831 | /* Build the TCi free pool */ |
2937 | sci_pool_initialize(scic->tci_pool); | 2832 | sci_pool_initialize(scic->tci_pool); |
@@ -2981,376 +2876,6 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler( | |||
2981 | return SCI_SUCCESS; | 2876 | return SCI_SUCCESS; |
2982 | } | 2877 | } |
2983 | 2878 | ||
2984 | /* | ||
2985 | * ***************************************************************************** | ||
2986 | * * INITIALIZED STATE HANDLERS | ||
2987 | * ***************************************************************************** */ | ||
2988 | |||
2989 | /** | ||
2990 | * | ||
2991 | * @controller: This is struct scic_sds_controller which receives the link up | ||
2992 | * notification. | ||
2993 | * @port: This is struct scic_sds_port with which the phy is associated. | ||
2994 | * @phy: This is the struct scic_sds_phy which has gone link up. | ||
2995 | * | ||
2996 | * This method is called when the struct scic_sds_controller is in the starting state | ||
2997 | * link up handler is called. This method will perform the following: - Stop | ||
2998 | * the phy timer - Start the next phy - Report the link up condition to the | ||
2999 | * port object none | ||
3000 | */ | ||
3001 | static void scic_sds_controller_starting_state_link_up_handler( | ||
3002 | struct scic_sds_controller *this_controller, | ||
3003 | struct scic_sds_port *port, | ||
3004 | struct scic_sds_phy *phy) | ||
3005 | { | ||
3006 | scic_sds_controller_phy_timer_stop(this_controller); | ||
3007 | |||
3008 | this_controller->port_agent.link_up_handler( | ||
3009 | this_controller, &this_controller->port_agent, port, phy | ||
3010 | ); | ||
3011 | /* scic_sds_port_link_up(port, phy); */ | ||
3012 | |||
3013 | scic_sds_controller_start_next_phy(this_controller); | ||
3014 | } | ||
3015 | |||
3016 | /** | ||
3017 | * | ||
3018 | * @controller: This is struct scic_sds_controller which receives the link down | ||
3019 | * notification. | ||
3020 | * @port: This is struct scic_sds_port with which the phy is associated. | ||
3021 | * @phy: This is the struct scic_sds_phy which has gone link down. | ||
3022 | * | ||
3023 | * This method is called when the struct scic_sds_controller is in the starting state | ||
3024 | * link down handler is called. - Report the link down condition to the port | ||
3025 | * object none | ||
3026 | */ | ||
3027 | static void scic_sds_controller_starting_state_link_down_handler( | ||
3028 | struct scic_sds_controller *this_controller, | ||
3029 | struct scic_sds_port *port, | ||
3030 | struct scic_sds_phy *phy) | ||
3031 | { | ||
3032 | this_controller->port_agent.link_down_handler( | ||
3033 | this_controller, &this_controller->port_agent, port, phy | ||
3034 | ); | ||
3035 | /* scic_sds_port_link_down(port, phy); */ | ||
3036 | } | ||
3037 | |||
3038 | static enum sci_status scic_sds_controller_ready_state_stop_handler( | ||
3039 | struct scic_sds_controller *scic, | ||
3040 | u32 timeout) | ||
3041 | { | ||
3042 | isci_timer_start(scic->timeout_timer, timeout); | ||
3043 | sci_base_state_machine_change_state(&scic->state_machine, | ||
3044 | SCI_BASE_CONTROLLER_STATE_STOPPING); | ||
3045 | return SCI_SUCCESS; | ||
3046 | } | ||
3047 | |||
3048 | /* | ||
3049 | * This method is called when the struct scic_sds_controller is in the ready state and | ||
3050 | * the start io handler is called. - Start the io request on the remote device | ||
3051 | * - if successful - assign the io_request to the io_request_table - post the | ||
3052 | * request to the hardware enum sci_status SCI_SUCCESS if the start io operation | ||
3053 | * succeeds SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could not be | ||
3054 | * allocated for the io request. SCI_FAILURE_INVALID_STATE if one or more | ||
3055 | * objects are not in a valid state to accept io requests. | ||
3056 | * | ||
3057 | * XXX: How does the io_tag parameter get assigned to the io request? | ||
3058 | */ | ||
3059 | static enum sci_status scic_sds_controller_ready_state_start_io_handler( | ||
3060 | struct scic_sds_controller *controller, | ||
3061 | struct sci_base_remote_device *remote_device, | ||
3062 | struct scic_sds_request *request, | ||
3063 | u16 io_tag) | ||
3064 | { | ||
3065 | enum sci_status status; | ||
3066 | |||
3067 | struct scic_sds_remote_device *the_device; | ||
3068 | |||
3069 | the_device = (struct scic_sds_remote_device *)remote_device; | ||
3070 | |||
3071 | status = scic_sds_remote_device_start_io(controller, the_device, request); | ||
3072 | |||
3073 | if (status != SCI_SUCCESS) | ||
3074 | return status; | ||
3075 | |||
3076 | controller->io_request_table[ | ||
3077 | scic_sds_io_tag_get_index(request->io_tag)] = request; | ||
3078 | scic_sds_controller_post_request(controller, | ||
3079 | scic_sds_request_get_post_context(request)); | ||
3080 | return SCI_SUCCESS; | ||
3081 | } | ||
3082 | |||
3083 | /* | ||
3084 | * This method is called when the struct scic_sds_controller is in the ready state and | ||
3085 | * the complete io handler is called. - Complete the io request on the remote | ||
3086 | * device - if successful - remove the io_request to the io_request_table | ||
3087 | * enum sci_status SCI_SUCCESS if the start io operation succeeds | ||
3088 | * SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid state to | ||
3089 | * accept io requests. | ||
3090 | */ | ||
3091 | static enum sci_status scic_sds_controller_ready_state_complete_io_handler( | ||
3092 | struct scic_sds_controller *controller, | ||
3093 | struct sci_base_remote_device *remote_device, | ||
3094 | struct scic_sds_request *request) | ||
3095 | { | ||
3096 | u16 index; | ||
3097 | enum sci_status status; | ||
3098 | struct scic_sds_remote_device *the_device; | ||
3099 | |||
3100 | the_device = (struct scic_sds_remote_device *)remote_device; | ||
3101 | |||
3102 | status = scic_sds_remote_device_complete_io(controller, the_device, | ||
3103 | request); | ||
3104 | if (status != SCI_SUCCESS) | ||
3105 | return status; | ||
3106 | |||
3107 | index = scic_sds_io_tag_get_index(request->io_tag); | ||
3108 | controller->io_request_table[index] = NULL; | ||
3109 | return SCI_SUCCESS; | ||
3110 | } | ||
3111 | |||
3112 | /* | ||
3113 | * This method is called when the struct scic_sds_controller is in the ready state and | ||
3114 | * the continue io handler is called. enum sci_status | ||
3115 | */ | ||
3116 | static enum sci_status scic_sds_controller_ready_state_continue_io_handler( | ||
3117 | struct scic_sds_controller *controller, | ||
3118 | struct sci_base_remote_device *remote_device, | ||
3119 | struct scic_sds_request *request) | ||
3120 | { | ||
3121 | controller->io_request_table[ | ||
3122 | scic_sds_io_tag_get_index(request->io_tag)] = request; | ||
3123 | scic_sds_controller_post_request(controller, | ||
3124 | scic_sds_request_get_post_context(request)); | ||
3125 | return SCI_SUCCESS; | ||
3126 | } | ||
3127 | |||
3128 | /* | ||
3129 | * This method is called when the struct scic_sds_controller is in the ready state and | ||
3130 | * the start task handler is called. - The remote device is requested to start | ||
3131 | * the task request - if successful - assign the task to the io_request_table - | ||
3132 | * post the request to the SCU hardware enum sci_status SCI_SUCCESS if the start io | ||
3133 | * operation succeeds SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could | ||
3134 | * not be allocated for the io request. SCI_FAILURE_INVALID_STATE if one or | ||
3135 | * more objects are not in a valid state to accept io requests. How does the io | ||
3136 | * tag get assigned in this code path? | ||
3137 | */ | ||
3138 | static enum sci_status scic_sds_controller_ready_state_start_task_handler( | ||
3139 | struct scic_sds_controller *controller, | ||
3140 | struct sci_base_remote_device *remote_device, | ||
3141 | struct scic_sds_request *request, | ||
3142 | u16 task_tag) | ||
3143 | { | ||
3144 | struct scic_sds_remote_device *the_device = (struct scic_sds_remote_device *) | ||
3145 | remote_device; | ||
3146 | enum sci_status status; | ||
3147 | |||
3148 | status = scic_sds_remote_device_start_task(controller, the_device, | ||
3149 | request); | ||
3150 | |||
3151 | if (status == SCI_SUCCESS) { | ||
3152 | controller->io_request_table[ | ||
3153 | scic_sds_io_tag_get_index(request->io_tag)] = request; | ||
3154 | |||
3155 | scic_sds_controller_post_request(controller, | ||
3156 | scic_sds_request_get_post_context(request)); | ||
3157 | } else if (status == SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS) { | ||
3158 | controller->io_request_table[ | ||
3159 | scic_sds_io_tag_get_index(request->io_tag)] = request; | ||
3160 | |||
3161 | /* | ||
3162 | * We will let framework know this task request started successfully, | ||
3163 | * although core is still woring on starting the request (to post tc when | ||
3164 | * RNC is resumed.) */ | ||
3165 | status = SCI_SUCCESS; | ||
3166 | } | ||
3167 | return status; | ||
3168 | } | ||
3169 | |||
3170 | /* | ||
3171 | * This method is called when the struct scic_sds_controller is in the ready state and | ||
3172 | * the terminate request handler is called. - call the io request terminate | ||
3173 | * function - if successful - post the terminate request to the SCU hardware | ||
3174 | * enum sci_status SCI_SUCCESS if the start io operation succeeds | ||
3175 | * SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid state to | ||
3176 | * accept io requests. | ||
3177 | */ | ||
3178 | static enum sci_status scic_sds_controller_ready_state_terminate_request_handler( | ||
3179 | struct scic_sds_controller *controller, | ||
3180 | struct sci_base_remote_device *remote_device, | ||
3181 | struct scic_sds_request *request) | ||
3182 | { | ||
3183 | enum sci_status status; | ||
3184 | |||
3185 | status = scic_sds_io_request_terminate(request); | ||
3186 | if (status != SCI_SUCCESS) | ||
3187 | return status; | ||
3188 | |||
3189 | /* | ||
3190 | * Utilize the original post context command and or in the POST_TC_ABORT | ||
3191 | * request sub-type. | ||
3192 | */ | ||
3193 | scic_sds_controller_post_request(controller, | ||
3194 | scic_sds_request_get_post_context(request) | | ||
3195 | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT); | ||
3196 | return SCI_SUCCESS; | ||
3197 | } | ||
3198 | |||
3199 | /** | ||
3200 | * | ||
3201 | * @controller: This is struct scic_sds_controller which receives the link up | ||
3202 | * notification. | ||
3203 | * @port: This is struct scic_sds_port with which the phy is associated. | ||
3204 | * @phy: This is the struct scic_sds_phy which has gone link up. | ||
3205 | * | ||
3206 | * This method is called when the struct scic_sds_controller is in the starting state | ||
3207 | * link up handler is called. This method will perform the following: - Stop | ||
3208 | * the phy timer - Start the next phy - Report the link up condition to the | ||
3209 | * port object none | ||
3210 | */ | ||
3211 | static void scic_sds_controller_ready_state_link_up_handler( | ||
3212 | struct scic_sds_controller *this_controller, | ||
3213 | struct scic_sds_port *port, | ||
3214 | struct scic_sds_phy *phy) | ||
3215 | { | ||
3216 | this_controller->port_agent.link_up_handler( | ||
3217 | this_controller, &this_controller->port_agent, port, phy | ||
3218 | ); | ||
3219 | } | ||
3220 | |||
3221 | /** | ||
3222 | * | ||
3223 | * @controller: This is struct scic_sds_controller which receives the link down | ||
3224 | * notification. | ||
3225 | * @port: This is struct scic_sds_port with which the phy is associated. | ||
3226 | * @phy: This is the struct scic_sds_phy which has gone link down. | ||
3227 | * | ||
3228 | * This method is called when the struct scic_sds_controller is in the starting state | ||
3229 | * link down handler is called. - Report the link down condition to the port | ||
3230 | * object none | ||
3231 | */ | ||
3232 | static void scic_sds_controller_ready_state_link_down_handler( | ||
3233 | struct scic_sds_controller *this_controller, | ||
3234 | struct scic_sds_port *port, | ||
3235 | struct scic_sds_phy *phy) | ||
3236 | { | ||
3237 | this_controller->port_agent.link_down_handler( | ||
3238 | this_controller, &this_controller->port_agent, port, phy | ||
3239 | ); | ||
3240 | } | ||
3241 | |||
3242 | /* | ||
3243 | * ***************************************************************************** | ||
3244 | * * STOPPING STATE HANDLERS | ||
3245 | * ***************************************************************************** */ | ||
3246 | |||
3247 | /** | ||
3248 | * This method is called when the struct scic_sds_controller is in a stopping state | ||
3249 | * and the complete io handler is called. - This function is not yet | ||
3250 | * implemented enum sci_status SCI_FAILURE | ||
3251 | */ | ||
3252 | static enum sci_status scic_sds_controller_stopping_state_complete_io_handler( | ||
3253 | struct scic_sds_controller *controller, | ||
3254 | struct sci_base_remote_device *remote_device, | ||
3255 | struct scic_sds_request *request) | ||
3256 | { | ||
3257 | /* XXX: Implement this function */ | ||
3258 | return SCI_FAILURE; | ||
3259 | } | ||
3260 | |||
3261 | /** | ||
3262 | * This method is called when the struct scic_sds_controller is in a stopping state | ||
3263 | * and the remote device has stopped. | ||
3264 | **/ | ||
3265 | static void scic_sds_controller_stopping_state_device_stopped_handler( | ||
3266 | struct scic_sds_controller *controller, | ||
3267 | struct scic_sds_remote_device *remote_device | ||
3268 | ) | ||
3269 | { | ||
3270 | if (!scic_sds_controller_has_remote_devices_stopping(controller)) { | ||
3271 | sci_base_state_machine_change_state(&controller->state_machine, | ||
3272 | SCI_BASE_CONTROLLER_STATE_STOPPED | ||
3273 | ); | ||
3274 | } | ||
3275 | } | ||
3276 | |||
3277 | const struct scic_sds_controller_state_handler scic_sds_controller_state_handler_table[] = { | ||
3278 | [SCI_BASE_CONTROLLER_STATE_INITIAL] = { | ||
3279 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3280 | .complete_io = scic_sds_controller_default_request_handler, | ||
3281 | .continue_io = scic_sds_controller_default_request_handler, | ||
3282 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3283 | }, | ||
3284 | [SCI_BASE_CONTROLLER_STATE_RESET] = { | ||
3285 | .reset = scic_sds_controller_general_reset_handler, | ||
3286 | .initialize = scic_sds_controller_reset_state_initialize_handler, | ||
3287 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3288 | .complete_io = scic_sds_controller_default_request_handler, | ||
3289 | .continue_io = scic_sds_controller_default_request_handler, | ||
3290 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3291 | }, | ||
3292 | [SCI_BASE_CONTROLLER_STATE_INITIALIZING] = { | ||
3293 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3294 | .complete_io = scic_sds_controller_default_request_handler, | ||
3295 | .continue_io = scic_sds_controller_default_request_handler, | ||
3296 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3297 | }, | ||
3298 | [SCI_BASE_CONTROLLER_STATE_INITIALIZED] = { | ||
3299 | .start = scic_sds_controller_initialized_state_start_handler, | ||
3300 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3301 | .complete_io = scic_sds_controller_default_request_handler, | ||
3302 | .continue_io = scic_sds_controller_default_request_handler, | ||
3303 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3304 | }, | ||
3305 | [SCI_BASE_CONTROLLER_STATE_STARTING] = { | ||
3306 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3307 | .complete_io = scic_sds_controller_default_request_handler, | ||
3308 | .continue_io = scic_sds_controller_default_request_handler, | ||
3309 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3310 | .link_up = scic_sds_controller_starting_state_link_up_handler, | ||
3311 | .link_down = scic_sds_controller_starting_state_link_down_handler | ||
3312 | }, | ||
3313 | [SCI_BASE_CONTROLLER_STATE_READY] = { | ||
3314 | .stop = scic_sds_controller_ready_state_stop_handler, | ||
3315 | .reset = scic_sds_controller_general_reset_handler, | ||
3316 | .start_io = scic_sds_controller_ready_state_start_io_handler, | ||
3317 | .complete_io = scic_sds_controller_ready_state_complete_io_handler, | ||
3318 | .continue_io = scic_sds_controller_ready_state_continue_io_handler, | ||
3319 | .start_task = scic_sds_controller_ready_state_start_task_handler, | ||
3320 | .complete_task = scic_sds_controller_ready_state_complete_io_handler, | ||
3321 | .terminate_request = scic_sds_controller_ready_state_terminate_request_handler, | ||
3322 | .link_up = scic_sds_controller_ready_state_link_up_handler, | ||
3323 | .link_down = scic_sds_controller_ready_state_link_down_handler | ||
3324 | }, | ||
3325 | [SCI_BASE_CONTROLLER_STATE_RESETTING] = { | ||
3326 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3327 | .complete_io = scic_sds_controller_default_request_handler, | ||
3328 | .continue_io = scic_sds_controller_default_request_handler, | ||
3329 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3330 | }, | ||
3331 | [SCI_BASE_CONTROLLER_STATE_STOPPING] = { | ||
3332 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3333 | .complete_io = scic_sds_controller_stopping_state_complete_io_handler, | ||
3334 | .continue_io = scic_sds_controller_default_request_handler, | ||
3335 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3336 | .device_stopped = scic_sds_controller_stopping_state_device_stopped_handler, | ||
3337 | }, | ||
3338 | [SCI_BASE_CONTROLLER_STATE_STOPPED] = { | ||
3339 | .reset = scic_sds_controller_general_reset_handler, | ||
3340 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3341 | .complete_io = scic_sds_controller_default_request_handler, | ||
3342 | .continue_io = scic_sds_controller_default_request_handler, | ||
3343 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3344 | }, | ||
3345 | [SCI_BASE_CONTROLLER_STATE_FAILED] = { | ||
3346 | .reset = scic_sds_controller_general_reset_handler, | ||
3347 | .start_io = scic_sds_controller_default_start_operation_handler, | ||
3348 | .complete_io = scic_sds_controller_default_request_handler, | ||
3349 | .continue_io = scic_sds_controller_default_request_handler, | ||
3350 | .terminate_request = scic_sds_controller_default_request_handler, | ||
3351 | }, | ||
3352 | }; | ||
3353 | |||
3354 | /** | 2879 | /** |
3355 | * | 2880 | * |
3356 | * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller | 2881 | * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller |
diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h index 163a9e11576a..9a646e5c7f45 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.h +++ b/drivers/scsi/isci/core/scic_sds_controller.h | |||
@@ -430,90 +430,6 @@ enum scic_sds_controller_states { | |||
430 | 430 | ||
431 | }; | 431 | }; |
432 | 432 | ||
433 | typedef enum sci_status (*scic_sds_controller_handler_t) | ||
434 | (struct scic_sds_controller *); | ||
435 | typedef enum sci_status (*scic_sds_controller_timed_handler_t) | ||
436 | (struct scic_sds_controller *, u32); | ||
437 | typedef enum sci_status (*scic_sds_controller_request_handler_t) | ||
438 | (struct scic_sds_controller *, | ||
439 | struct sci_base_remote_device *, | ||
440 | struct scic_sds_request *); | ||
441 | typedef enum sci_status (*scic_sds_controller_start_request_handler_t) | ||
442 | (struct scic_sds_controller *, | ||
443 | struct sci_base_remote_device *, | ||
444 | struct scic_sds_request *, u16); | ||
445 | typedef void (*scic_sds_controller_phy_handler_t) | ||
446 | (struct scic_sds_controller *, | ||
447 | struct scic_sds_port *, | ||
448 | struct scic_sds_phy *); | ||
449 | typedef void (*scic_sds_controller_device_handler_t) | ||
450 | (struct scic_sds_controller *, | ||
451 | struct scic_sds_remote_device *); | ||
452 | |||
453 | struct scic_sds_controller_state_handler { | ||
454 | /** | ||
455 | * The start_handler specifies the method invoked when a user attempts to | ||
456 | * start a controller. | ||
457 | */ | ||
458 | scic_sds_controller_timed_handler_t start; | ||
459 | |||
460 | /** | ||
461 | * The stop_handler specifies the method invoked when a user attempts to | ||
462 | * stop a controller. | ||
463 | */ | ||
464 | scic_sds_controller_timed_handler_t stop; | ||
465 | |||
466 | /** | ||
467 | * The reset_handler specifies the method invoked when a user attempts to | ||
468 | * reset a controller. | ||
469 | */ | ||
470 | scic_sds_controller_handler_t reset; | ||
471 | |||
472 | /** | ||
473 | * The initialize_handler specifies the method invoked when a user | ||
474 | * attempts to initialize a controller. | ||
475 | */ | ||
476 | scic_sds_controller_handler_t initialize; | ||
477 | |||
478 | /** | ||
479 | * The start_io_handler specifies the method invoked when a user | ||
480 | * attempts to start an IO request for a controller. | ||
481 | */ | ||
482 | scic_sds_controller_start_request_handler_t start_io; | ||
483 | |||
484 | /** | ||
485 | * The complete_io_handler specifies the method invoked when a user | ||
486 | * attempts to complete an IO request for a controller. | ||
487 | */ | ||
488 | scic_sds_controller_request_handler_t complete_io; | ||
489 | |||
490 | /** | ||
491 | * The continue_io_handler specifies the method invoked when a user | ||
492 | * attempts to continue an IO request for a controller. | ||
493 | */ | ||
494 | scic_sds_controller_request_handler_t continue_io; | ||
495 | |||
496 | /** | ||
497 | * The start_task_handler specifies the method invoked when a user | ||
498 | * attempts to start a task management request for a controller. | ||
499 | */ | ||
500 | scic_sds_controller_start_request_handler_t start_task; | ||
501 | |||
502 | /** | ||
503 | * The complete_task_handler specifies the method invoked when a user | ||
504 | * attempts to complete a task management request for a controller. | ||
505 | */ | ||
506 | scic_sds_controller_request_handler_t complete_task; | ||
507 | |||
508 | scic_sds_controller_request_handler_t terminate_request; | ||
509 | scic_sds_controller_phy_handler_t link_up; | ||
510 | scic_sds_controller_phy_handler_t link_down; | ||
511 | scic_sds_controller_device_handler_t device_stopped; | ||
512 | }; | ||
513 | |||
514 | extern const struct scic_sds_controller_state_handler | ||
515 | scic_sds_controller_state_handler_table[]; | ||
516 | |||
517 | /** | 433 | /** |
518 | * INCREMENT_QUEUE_GET() - | 434 | * INCREMENT_QUEUE_GET() - |
519 | * | 435 | * |
@@ -676,4 +592,6 @@ void scic_sds_controller_copy_task_context( | |||
676 | void scic_sds_controller_register_setup( | 592 | void scic_sds_controller_register_setup( |
677 | struct scic_sds_controller *this_controller); | 593 | struct scic_sds_controller *this_controller); |
678 | 594 | ||
595 | enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req); | ||
596 | |||
679 | #endif /* _SCIC_SDS_CONTROLLER_H_ */ | 597 | #endif /* _SCIC_SDS_CONTROLLER_H_ */ |
diff --git a/drivers/scsi/isci/core/scic_sds_remote_device.c b/drivers/scsi/isci/core/scic_sds_remote_device.c index cb49a33285d9..f0d1c098f9b6 100644 --- a/drivers/scsi/isci/core/scic_sds_remote_device.c +++ b/drivers/scsi/isci/core/scic_sds_remote_device.c | |||
@@ -558,17 +558,10 @@ void scic_sds_remote_device_start_request( | |||
558 | void scic_sds_remote_device_continue_request(void *dev) | 558 | void scic_sds_remote_device_continue_request(void *dev) |
559 | { | 559 | { |
560 | struct scic_sds_remote_device *sci_dev = dev; | 560 | struct scic_sds_remote_device *sci_dev = dev; |
561 | struct scic_sds_request *sci_req = sci_dev->working_request; | ||
562 | 561 | ||
563 | /* we need to check if this request is still valid to continue. */ | 562 | /* we need to check if this request is still valid to continue. */ |
564 | if (sci_req) { | 563 | if (sci_dev->working_request) |
565 | struct scic_sds_controller *scic = sci_req->owning_controller; | 564 | scic_controller_continue_io(sci_dev->working_request); |
566 | u32 state = scic->state_machine.current_state_id; | ||
567 | scic_sds_controller_request_handler_t continue_io; | ||
568 | |||
569 | continue_io = scic_sds_controller_state_handler_table[state].continue_io; | ||
570 | continue_io(scic, &sci_req->target_device->parent, sci_req); | ||
571 | } | ||
572 | } | 565 | } |
573 | 566 | ||
574 | /** | 567 | /** |
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.c b/drivers/scsi/isci/core/scic_sds_stp_request.c index 0b3bc65b8a2b..e4ca4e40ae87 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.c +++ b/drivers/scsi/isci/core/scic_sds_stp_request.c | |||
@@ -637,10 +637,7 @@ static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame( | |||
637 | u32 length) | 637 | u32 length) |
638 | { | 638 | { |
639 | struct scic_sds_stp_request *this_sds_stp_request = (struct scic_sds_stp_request *)this_request; | 639 | struct scic_sds_stp_request *this_sds_stp_request = (struct scic_sds_stp_request *)this_request; |
640 | scic_sds_controller_request_handler_t continue_io; | ||
641 | struct scu_sgl_element *current_sgl; | 640 | struct scu_sgl_element *current_sgl; |
642 | struct scic_sds_controller *scic; | ||
643 | u32 state; | ||
644 | 641 | ||
645 | /* | 642 | /* |
646 | * Recycle the TC and reconstruct it for sending out DATA FIS containing | 643 | * Recycle the TC and reconstruct it for sending out DATA FIS containing |
@@ -662,10 +659,7 @@ static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame( | |||
662 | task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA; | 659 | task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA; |
663 | 660 | ||
664 | /* send the new TC out. */ | 661 | /* send the new TC out. */ |
665 | scic = this_request->owning_controller; | 662 | return scic_controller_continue_io(this_request); |
666 | state = scic->state_machine.current_state_id; | ||
667 | continue_io = scic_sds_controller_state_handler_table[state].continue_io; | ||
668 | return continue_io(scic, &this_request->target_device->parent, this_request); | ||
669 | } | 663 | } |
670 | 664 | ||
671 | /** | 665 | /** |
@@ -1758,12 +1752,9 @@ static void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_complet | |||
1758 | struct sci_base_object *object) | 1752 | struct sci_base_object *object) |
1759 | { | 1753 | { |
1760 | struct scic_sds_request *this_request = (struct scic_sds_request *)object; | 1754 | struct scic_sds_request *this_request = (struct scic_sds_request *)object; |
1761 | scic_sds_controller_request_handler_t continue_io; | ||
1762 | struct scu_task_context *task_context; | 1755 | struct scu_task_context *task_context; |
1763 | struct sata_fis_reg_h2d *h2d_fis; | 1756 | struct sata_fis_reg_h2d *h2d_fis; |
1764 | struct scic_sds_controller *scic; | ||
1765 | enum sci_status status; | 1757 | enum sci_status status; |
1766 | u32 state; | ||
1767 | 1758 | ||
1768 | /* Clear the SRST bit */ | 1759 | /* Clear the SRST bit */ |
1769 | h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request); | 1760 | h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request); |
@@ -1774,12 +1765,7 @@ static void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_complet | |||
1774 | this_request->owning_controller, this_request->io_tag); | 1765 | this_request->owning_controller, this_request->io_tag); |
1775 | task_context->control_frame = 0; | 1766 | task_context->control_frame = 0; |
1776 | 1767 | ||
1777 | scic = this_request->owning_controller; | 1768 | status = scic_controller_continue_io(this_request); |
1778 | state = scic->state_machine.current_state_id; | ||
1779 | continue_io = scic_sds_controller_state_handler_table[state].continue_io; | ||
1780 | |||
1781 | status = continue_io(scic, &this_request->target_device->parent, this_request); | ||
1782 | |||
1783 | if (status == SCI_SUCCESS) { | 1769 | if (status == SCI_SUCCESS) { |
1784 | SET_STATE_HANDLER( | 1770 | SET_STATE_HANDLER( |
1785 | this_request, | 1771 | this_request, |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index c6c97ad58c9f..aa6b43067e25 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -1480,7 +1480,7 @@ void isci_task_request_complete( | |||
1480 | /* PRINT_TMF( ((struct isci_tmf *)request->task)); */ | 1480 | /* PRINT_TMF( ((struct isci_tmf *)request->task)); */ |
1481 | tmf_complete = tmf->complete; | 1481 | tmf_complete = tmf->complete; |
1482 | 1482 | ||
1483 | scic_controller_complete_task( | 1483 | scic_controller_complete_io( |
1484 | isci_host->core_controller, | 1484 | isci_host->core_controller, |
1485 | to_sci_dev(isci_device), | 1485 | to_sci_dev(isci_device), |
1486 | request->sci_request_handle | 1486 | request->sci_request_handle |