1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris/**
57230557Sjimharris * @file
58230557Sjimharris *
59230557Sjimharris * @brief This file contains all of the method implementations pertaining
60230557Sjimharris *        to the framework remote device STARTING sub-state handler methods.
61230557Sjimharris *        The STARTING sub-state machine is responsible for ensuring that
62230557Sjimharris *        all initialization and configuration for a particular remote
63230557Sjimharris *        device is complete before transitioning to the READY state
64230557Sjimharris *        (i.e. before allowing normal host IO).
65230557Sjimharris */
66230557Sjimharris
67230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
68230557Sjimharris
69230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h>
70230557Sjimharris#include <dev/isci/scil/scif_sas_remote_device.h>
71230557Sjimharris#include <dev/isci/scil/scif_sas_domain.h>
72230557Sjimharris#include <dev/isci/scil/scif_sas_task_request.h>
73230557Sjimharris
74230557Sjimharris//******************************************************************************
75230557Sjimharris//* G E N E R A L   S T O P   H A N D L E R S
76230557Sjimharris//******************************************************************************
77230557Sjimharris
78230557Sjimharris/**
79230557Sjimharris * @brief This method provides startig sub-state specific handling for
80230557Sjimharris *        when the remote device is requested to stop.  This will occur
81230557Sjimharris *        when there is a link failure during the starting operation.
82230557Sjimharris *
83230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
84230557Sjimharris *             object for which the failure condition occurred.
85230557Sjimharris *
86230557Sjimharris * @return This method returns an indication as to whether the failure
87230557Sjimharris *         operation completed successfully.
88230557Sjimharris */
89230557Sjimharrisstatic
90230557SjimharrisSCI_STATUS
91230557Sjimharrisscif_sas_remote_device_starting_state_general_stop_handler(
92230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
93230557Sjimharris)
94230557Sjimharris{
95230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
96230557Sjimharris                                          remote_device;
97230557Sjimharris
98230557Sjimharris   SCIF_LOG_INFO((
99230557Sjimharris      sci_base_object_get_logger(fw_device),
100230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
101230557Sjimharris      "RemoteDevice:0x%x starting device requested to stop\n",
102230557Sjimharris      fw_device
103230557Sjimharris   ));
104230557Sjimharris
105230557Sjimharris   fw_device->domain->device_start_in_progress_count--;
106230557Sjimharris
107230557Sjimharris   sci_base_state_machine_change_state(
108230557Sjimharris      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
109230557Sjimharris   );
110230557Sjimharris
111230557Sjimharris   return SCI_SUCCESS;
112230557Sjimharris}
113230557Sjimharris
114230557Sjimharris//******************************************************************************
115230557Sjimharris//* A W A I T   C O M P L E T E   H A N D L E R S
116230557Sjimharris//******************************************************************************
117230557Sjimharris
118230557Sjimharris/**
119230557Sjimharris * @brief This method provides AWAIT START COMPLETE sub-state specific
120230557Sjimharris *        handling for when the remote device undergoes a failure
121230557Sjimharris *        condition.
122230557Sjimharris *
123230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
124230557Sjimharris *             object for which the failure condition occurred.
125230557Sjimharris *
126230557Sjimharris * @return This method returns an indication as to whether the failure
127230557Sjimharris *         operation completed successfully.
128230557Sjimharris */
129230557Sjimharrisstatic
130230557SjimharrisSCI_STATUS scif_sas_remote_device_starting_await_complete_fail_handler(
131230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
132230557Sjimharris)
133230557Sjimharris{
134230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
135230557Sjimharris                                          remote_device;
136230557Sjimharris
137230557Sjimharris   SCIF_LOG_WARNING((
138230557Sjimharris      sci_base_object_get_logger(fw_device),
139230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
140230557Sjimharris      "RemoteDevice:0x%x starting device failed, start complete not received\n",
141230557Sjimharris      fw_device
142230557Sjimharris   ));
143230557Sjimharris
144230557Sjimharris   sci_base_state_machine_change_state(
145230557Sjimharris      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FAILED
146230557Sjimharris   );
147230557Sjimharris
148230557Sjimharris   return SCI_SUCCESS;
149230557Sjimharris}
150230557Sjimharris
151230557Sjimharris/**
152230557Sjimharris * @brief This method provides AWAIT COMPLETE state specific handling for
153230557Sjimharris *        when the core remote device object issues a device not ready
154230557Sjimharris *        notification.  In the AWAIT COMPLETE state we do not inform
155230557Sjimharris *        the framework user of the state change of the device, since the
156230557Sjimharris *        user is unaware of the remote device start process.
157230557Sjimharris *
158230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
159230557Sjimharris *             object for which the notification occurred.
160230557Sjimharris *
161230557Sjimharris * @return none.
162230557Sjimharris */
163230557Sjimharrisstatic
164230557Sjimharrisvoid scif_sas_remote_device_starting_await_complete_not_ready_handler(
165230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
166230557Sjimharris   U32                        reason_code
167230557Sjimharris)
168230557Sjimharris{
169230557Sjimharris}
170230557Sjimharris
171230557Sjimharris/**
172230557Sjimharris * @brief This method provides AWAIT START COMPLETE sub-state specific
173230557Sjimharris *        handling for when the core provides a start complete notification
174230557Sjimharris *        for the remote device.  If the start completion status indicates
175230557Sjimharris *        a successful start, then the device is transitioned into the
176230557Sjimharris *        READY state.  All other status cause a transition to the
177230557Sjimharris *        FAILED state and a scif_cb_controller_error() notification
178230557Sjimharris *        message to the framework user.
179230557Sjimharris *
180230557Sjimharris * @param[in]  fw_device This parameter specifies the remote device
181230557Sjimharris *             object for which the notification has occurred.
182230557Sjimharris *
183230557Sjimharris * @return none.
184230557Sjimharris */
185230557Sjimharrisstatic
186230557Sjimharrisvoid scif_sas_remote_device_starting_await_complete_start_complete_handler(
187230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
188230557Sjimharris   SCI_STATUS                 completion_status
189230557Sjimharris)
190230557Sjimharris{
191230557Sjimharris   if (completion_status == SCI_SUCCESS)
192230557Sjimharris   {
193230557Sjimharris      /** @todo need to add support for resetting the device first.  This can
194230557Sjimharris                wait until 1.3. */
195230557Sjimharris      /** @todo Update to comprehend situations (i.e. SATA) where config is
196230557Sjimharris                needed. */
197230557Sjimharris
198230557Sjimharris      sci_base_state_machine_change_state(
199230557Sjimharris         &fw_device->starting_substate_machine,
200230557Sjimharris         SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_READY
201230557Sjimharris      );
202230557Sjimharris   }
203230557Sjimharris   else
204230557Sjimharris   {
205230557Sjimharris      SCIF_LOG_WARNING((
206230557Sjimharris         sci_base_object_get_logger(fw_device),
207230557Sjimharris         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
208230557Sjimharris         "Device:0x%x Status:0x%x failed to start core device\n",
209230557Sjimharris         fw_device
210230557Sjimharris      ));
211230557Sjimharris
212230557Sjimharris      sci_base_state_machine_change_state(
213230557Sjimharris         &fw_device->parent.state_machine,
214230557Sjimharris         SCI_BASE_REMOTE_DEVICE_STATE_FAILED
215230557Sjimharris      );
216230557Sjimharris
217230557Sjimharris      // Something is seriously wrong.  Starting the core remote device
218230557Sjimharris      // shouldn't fail in anyway in this state.
219230557Sjimharris      scif_cb_controller_error(fw_device->domain->controller,
220230557Sjimharris              SCI_CONTROLLER_REMOTE_DEVICE_ERROR);
221230557Sjimharris   }
222230557Sjimharris}
223230557Sjimharris
224230557Sjimharris//******************************************************************************
225230557Sjimharris//* C O M P L E T E   H A N D L E R S
226230557Sjimharris//******************************************************************************
227230557Sjimharris
228230557Sjimharris/**
229230557Sjimharris * @brief This method provides STARTING AWAIT READY sub-state specific
230230557Sjimharris *        handling for when the core provides a device ready notification
231230557Sjimharris *        for the remote device.  This essentially, causes a transition
232230557Sjimharris *        of the framework remote device into the READY state.
233230557Sjimharris *
234230557Sjimharris * @param[in]  fw_device This parameter specifies the remote device
235230557Sjimharris *             object for which the notification has occurred.
236230557Sjimharris *
237230557Sjimharris * @return none.
238230557Sjimharris */
239230557Sjimharrisstatic
240230557Sjimharrisvoid scif_sas_remote_device_starting_await_ready_ready_handler(
241230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device
242230557Sjimharris)
243230557Sjimharris{
244230557Sjimharris#if !defined(DISABLE_WIDE_PORTED_TARGETS)
245230557Sjimharris   if (fw_device->destination_state ==
246230557Sjimharris          SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UPDATING_PORT_WIDTH)
247230557Sjimharris   {
248230557Sjimharris      {
249230557Sjimharris         sci_base_state_machine_change_state(
250230557Sjimharris            &fw_device->parent.state_machine,
251230557Sjimharris            SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH
252230557Sjimharris         );
253230557Sjimharris      }
254230557Sjimharris   }
255230557Sjimharris   else
256230557Sjimharris#endif
257230557Sjimharris   {
258230557Sjimharris      sci_base_state_machine_change_state(
259230557Sjimharris         &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_READY
260230557Sjimharris      );
261230557Sjimharris   }
262230557Sjimharris
263230557Sjimharris#if !defined(DISABLE_WIDE_PORTED_TARGETS)
264230557Sjimharris   scif_sas_domain_remote_device_start_complete(fw_device->domain,fw_device);
265230557Sjimharris#endif
266230557Sjimharris}
267230557Sjimharris
268230557Sjimharris
269230557SjimharrisSCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
270230557Sjimharrisscif_sas_remote_device_starting_substate_handler_table[] =
271230557Sjimharris{
272230557Sjimharris   // SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_COMPLETE
273230557Sjimharris   {
274230557Sjimharris      {
275230557Sjimharris         scif_sas_remote_device_default_start_handler,
276230557Sjimharris         scif_sas_remote_device_starting_state_general_stop_handler,
277230557Sjimharris         scif_sas_remote_device_starting_await_complete_fail_handler,
278230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
279230557Sjimharris         scif_sas_remote_device_default_reset_handler,
280230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
281230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
282230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
283230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
284230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
285230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
286230557Sjimharris      },
287230557Sjimharris      scif_sas_remote_device_starting_await_complete_start_complete_handler,
288230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
289230557Sjimharris      scif_sas_remote_device_default_ready_handler,
290230557Sjimharris      scif_sas_remote_device_starting_await_complete_not_ready_handler,
291230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
292230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
293230557Sjimharris   },
294230557Sjimharris   // SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_READY
295230557Sjimharris   {
296230557Sjimharris      {
297230557Sjimharris         scif_sas_remote_device_default_start_handler,
298230557Sjimharris         scif_sas_remote_device_starting_state_general_stop_handler,
299230557Sjimharris         scif_sas_remote_device_starting_await_complete_fail_handler,
300230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
301230557Sjimharris         scif_sas_remote_device_default_reset_handler,
302230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
303230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
304230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
305230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
306230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
307230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
308230557Sjimharris      },
309230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
310230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
311230557Sjimharris      scif_sas_remote_device_starting_await_ready_ready_handler,
312230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
313230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
314230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
315230557Sjimharris   }
316230557Sjimharris};
317230557Sjimharris
318