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 state handler methods.
61230557Sjimharris */
62230557Sjimharris
63230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
64230557Sjimharris
65230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h>
66230557Sjimharris#include <dev/isci/scil/scif_sas_remote_device.h>
67230557Sjimharris#include <dev/isci/scil/scif_sas_domain.h>
68230557Sjimharris#include <dev/isci/scil/scif_sas_task_request.h>
69230557Sjimharris#include <dev/isci/scil/scif_sas_internal_io_request.h>
70230557Sjimharris
71230557Sjimharris//******************************************************************************
72230557Sjimharris//* S T O P P E D   H A N D L E R S
73230557Sjimharris//******************************************************************************
74230557Sjimharris
75230557Sjimharris/**
76230557Sjimharris * @brief This method provides STOPPED state specific handling for
77230557Sjimharris *        when the framework attempts to start the remote device.  This
78230557Sjimharris *        method attempts to transition the state machine into the
79230557Sjimharris *        STARTING state.  If this is unsuccessful, then there is a direct
80230557Sjimharris *        transition into the FAILED state.
81230557Sjimharris *
82230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
83230557Sjimharris *             object for which the framework is attempting to start.
84230557Sjimharris *
85230557Sjimharris * @return This method returns an indication as to whether the start
86230557Sjimharris *         operating began successfully.
87230557Sjimharris */
88230557Sjimharrisstatic
89230557SjimharrisSCI_STATUS scif_sas_remote_device_stopped_start_handler(
90230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
91230557Sjimharris)
92230557Sjimharris{
93230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
94230557Sjimharris                                          remote_device;
95230557Sjimharris
96230557Sjimharris   sci_base_state_machine_change_state(
97230557Sjimharris      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STARTING
98230557Sjimharris   );
99230557Sjimharris
100230557Sjimharris   // Check to see if the state transition occurred without issue.
101230557Sjimharris   if (sci_base_state_machine_get_state(&fw_device->parent.state_machine)
102230557Sjimharris       == SCI_BASE_REMOTE_DEVICE_STATE_FAILED)
103230557Sjimharris   {
104230557Sjimharris      SCIF_LOG_WARNING((
105230557Sjimharris         sci_base_object_get_logger(fw_device),
106230557Sjimharris         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
107230557Sjimharris         "Domain:0x%x Device:0x%x Status:0x%x failed to start\n",
108230557Sjimharris         fw_device->domain, fw_device, fw_device->operation_status
109230557Sjimharris      ));
110230557Sjimharris   }
111230557Sjimharris
112230557Sjimharris   return fw_device->operation_status;
113230557Sjimharris}
114230557Sjimharris
115230557Sjimharris/**
116230557Sjimharris * @brief This method provides STOPPED state specific handling for
117230557Sjimharris *        when the user attempts to destruct the remote device.
118230557Sjimharris *
119230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
120230557Sjimharris *             object for which the framework is attempting to start.
121230557Sjimharris *
122230557Sjimharris * @return This method returns an indication as to whether the destruct
123230557Sjimharris *         operation completed successfully.
124230557Sjimharris */
125230557Sjimharrisstatic
126230557SjimharrisSCI_STATUS scif_sas_remote_device_stopped_destruct_handler(
127230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
128230557Sjimharris)
129230557Sjimharris{
130230557Sjimharris   SCI_STATUS                 status;
131230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
132230557Sjimharris                                          remote_device;
133230557Sjimharris
134230557Sjimharris   SMP_DISCOVER_RESPONSE_PROTOCOLS_T  dev_protocols;
135230557Sjimharris   scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
136230557Sjimharris
137230557Sjimharris   //For smp device, need to clear its smp phy list first.
138230557Sjimharris   if(dev_protocols.u.bits.attached_smp_target)
139230557Sjimharris      scif_sas_smp_remote_device_removed(fw_device);
140230557Sjimharris
141230557Sjimharris   status = scic_remote_device_destruct(fw_device->core_object);
142230557Sjimharris   if (status == SCI_SUCCESS)
143230557Sjimharris   {
144230557Sjimharris      sci_base_state_machine_change_state(
145230557Sjimharris         &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FINAL
146230557Sjimharris      );
147230557Sjimharris
148230557Sjimharris      scif_sas_remote_device_deinitialize_state_logging(fw_device);
149230557Sjimharris   }
150230557Sjimharris   else
151230557Sjimharris   {
152230557Sjimharris      SCIF_LOG_ERROR((
153230557Sjimharris         sci_base_object_get_logger(fw_device),
154230557Sjimharris         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
155230557Sjimharris         "Device:0x%x Status:0x%x failed to destruct core device\n",
156230557Sjimharris         fw_device
157230557Sjimharris      ));
158230557Sjimharris   }
159230557Sjimharris
160230557Sjimharris   return status;
161230557Sjimharris}
162230557Sjimharris
163230557Sjimharris//******************************************************************************
164230557Sjimharris//* S T O P P I N G   H A N D L E R S
165230557Sjimharris//******************************************************************************
166230557Sjimharris
167230557Sjimharris/**
168230557Sjimharris * @brief This method provides STOPPING state specific handling for
169230557Sjimharris *        when the core remote device object issues a stop completion
170230557Sjimharris *        notification.
171230557Sjimharris *
172230557Sjimharris * @note There is no need to ensure all IO/Task requests are complete
173230557Sjimharris *       before transitioning to the STOPPED state.  The SCI Core will
174230557Sjimharris *       ensure this is accomplished.
175230557Sjimharris *
176230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
177230557Sjimharris *             object for which the completion occurred.
178230557Sjimharris * @param[in]  completion_status This parameter specifies the status
179230557Sjimharris *             of the completion operation.
180230557Sjimharris *
181230557Sjimharris * @return none.
182230557Sjimharris */
183230557Sjimharrisstatic
184230557Sjimharrisvoid scif_sas_remote_device_stopping_stop_complete_handler(
185230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
186230557Sjimharris   SCI_STATUS                 completion_status
187230557Sjimharris)
188230557Sjimharris{
189230557Sjimharris   // Transition directly to the STOPPED state since the core ensures
190230557Sjimharris   // all IO/Tasks are complete.
191230557Sjimharris   sci_base_state_machine_change_state(
192230557Sjimharris      &fw_device->parent.state_machine,
193230557Sjimharris      SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
194230557Sjimharris   );
195230557Sjimharris
196230557Sjimharris   if (completion_status != SCI_SUCCESS)
197230557Sjimharris   {
198230557Sjimharris      SCIF_LOG_ERROR((
199230557Sjimharris         sci_base_object_get_logger(fw_device),
200230557Sjimharris         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
201230557Sjimharris         "Device:0x%x Status:0x%x failed to stop core device\n",
202230557Sjimharris         fw_device, completion_status
203230557Sjimharris      ));
204230557Sjimharris
205230557Sjimharris      // Something is seriously wrong.  Stopping the core remote device
206230557Sjimharris      // shouldn't fail in anyway.
207230557Sjimharris      scif_cb_controller_error(fw_device->domain->controller,
208230557Sjimharris              SCI_CONTROLLER_REMOTE_DEVICE_ERROR);
209230557Sjimharris   }
210230557Sjimharris}
211230557Sjimharris
212230557Sjimharris/**
213230557Sjimharris * @brief This method provides STOPPING state handling for high priority
214230557Sjimharris *        IO requests, when the framework attempts to complete a high
215230557Sjimharris *        priority request.
216230557Sjimharris *
217230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
218230557Sjimharris *             object for which to complete the high priority IO.
219230557Sjimharris * @param[in]  io_request This parameter specifies the IO request to be
220230557Sjimharris *             completed.
221230557Sjimharris * @param[in]  response_data This parameter is ignored, since the device
222230557Sjimharris *             is in the stopping state.
223230557Sjimharris *
224230557Sjimharris * @return This method always returns success.
225230557Sjimharris */
226230557Sjimharrisstatic
227230557SjimharrisSCI_STATUS scif_sas_remote_device_stopping_complete_high_priority_io_handler(
228230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
229230557Sjimharris   SCI_BASE_REQUEST_T       * io_request,
230230557Sjimharris   void                     * response_data,
231230557Sjimharris   SCI_IO_STATUS              completion_status
232230557Sjimharris)
233230557Sjimharris{
234230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
235230557Sjimharris                                          remote_device;
236230557Sjimharris   SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T *) io_request;
237230557Sjimharris
238230557Sjimharris   SCIF_LOG_TRACE((
239230557Sjimharris      sci_base_object_get_logger(remote_device),
240230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
241230557Sjimharris      "scif_sas_remote_device_stopping_complete_high_priority_io_handler(0x%x,0x%x,0x%x) enter\n",
242230557Sjimharris      remote_device, io_request, response_data
243230557Sjimharris   ));
244230557Sjimharris
245230557Sjimharris   fw_device->request_count--;
246230557Sjimharris
247230557Sjimharris   if (fw_request->is_internal == TRUE)
248230557Sjimharris   {
249230557Sjimharris      scif_sas_internal_io_request_complete(
250230557Sjimharris         fw_device->domain->controller,
251230557Sjimharris         (SCIF_SAS_INTERNAL_IO_REQUEST_T *) io_request,
252230557Sjimharris         SCI_SUCCESS
253230557Sjimharris      );
254230557Sjimharris   }
255230557Sjimharris
256230557Sjimharris   return SCI_SUCCESS;
257230557Sjimharris}
258230557Sjimharris
259230557Sjimharris//******************************************************************************
260230557Sjimharris//* F A I L E D   H A N D L E R S
261230557Sjimharris//******************************************************************************
262230557Sjimharris
263230557Sjimharris/**
264230557Sjimharris * @brief This method provides FAILED state specific handling for
265230557Sjimharris *        when the remote device is being stopped by the framework.
266230557Sjimharris *
267230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
268230557Sjimharris *             object for which the stop operation is being requested.
269230557Sjimharris *
270230557Sjimharris * @return This method returns an indication as to whether the failure
271230557Sjimharris *         operation completed successfully.
272230557Sjimharris */
273230557Sjimharrisstatic
274230557SjimharrisSCI_STATUS scif_sas_remote_device_failed_stop_handler(
275230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
276230557Sjimharris)
277230557Sjimharris{
278230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
279230557Sjimharris                                          remote_device;
280230557Sjimharris
281230557Sjimharris   SCIF_LOG_WARNING((
282230557Sjimharris      sci_base_object_get_logger(fw_device),
283230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
284230557Sjimharris      "RemoteDevice:0x%x stopping failed device\n",
285230557Sjimharris      fw_device
286230557Sjimharris   ));
287230557Sjimharris
288230557Sjimharris   sci_base_state_machine_change_state(
289230557Sjimharris      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
290230557Sjimharris   );
291230557Sjimharris
292230557Sjimharris   /// @todo Fix the return code handling.
293230557Sjimharris   return SCI_FAILURE;
294230557Sjimharris}
295230557Sjimharris
296230557Sjimharris//******************************************************************************
297230557Sjimharris//* D E F A U L T   H A N D L E R S
298230557Sjimharris//******************************************************************************
299230557Sjimharris
300230557Sjimharris/**
301230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
302230557Sjimharris *        when a user attempts to start a remote device and a start operation
303230557Sjimharris *        is not allowed.
304230557Sjimharris *
305230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
306230557Sjimharris *             on which the user is attempting to perform a start operation.
307230557Sjimharris *
308230557Sjimharris * @return This method returns an indication that start operations are not
309230557Sjimharris *         allowed.
310230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
311230557Sjimharris */
312230557SjimharrisSCI_STATUS scif_sas_remote_device_default_start_handler(
313230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
314230557Sjimharris)
315230557Sjimharris{
316230557Sjimharris   SCIF_LOG_WARNING((
317230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
318230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
319230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to start\n",
320230557Sjimharris      remote_device,
321230557Sjimharris      sci_base_state_machine_get_state(
322230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
323230557Sjimharris   ));
324230557Sjimharris
325230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
326230557Sjimharris}
327230557Sjimharris
328230557Sjimharris/**
329230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
330230557Sjimharris *        when a user attempts to stop a remote device and a stop operation
331230557Sjimharris *        is not allowed.
332230557Sjimharris *
333230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
334230557Sjimharris *             on which the user is attempting to perform a stop operation.
335230557Sjimharris *
336230557Sjimharris * @return This method returns an indication that stop operations are not
337230557Sjimharris *         allowed.
338230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
339230557Sjimharris */
340230557SjimharrisSCI_STATUS scif_sas_remote_device_default_stop_handler(
341230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
342230557Sjimharris)
343230557Sjimharris{
344230557Sjimharris   SCIF_LOG_WARNING((
345230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
346230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
347230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to stop\n",
348230557Sjimharris      remote_device,
349230557Sjimharris      sci_base_state_machine_get_state(
350230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
351230557Sjimharris   ));
352230557Sjimharris
353230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
354230557Sjimharris}
355230557Sjimharris
356230557Sjimharris/**
357230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
358230557Sjimharris *        when there is an attempt to fail a remote device from an invalid
359230557Sjimharris *        state.
360230557Sjimharris *
361230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
362230557Sjimharris *             object on which there is an attempt to fail the device.
363230557Sjimharris *
364230557Sjimharris * @return This method returns an indication that the fail transition is not
365230557Sjimharris *         allowed.
366230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
367230557Sjimharris */
368230557Sjimharrisstatic
369230557SjimharrisSCI_STATUS scif_sas_remote_device_default_fail_handler(
370230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
371230557Sjimharris)
372230557Sjimharris{
373230557Sjimharris   SCIF_LOG_WARNING((
374230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
375230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
376230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to fail device\n",
377230557Sjimharris      remote_device,
378230557Sjimharris      sci_base_state_machine_get_state(
379230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
380230557Sjimharris   ));
381230557Sjimharris
382230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
383230557Sjimharris}
384230557Sjimharris
385230557Sjimharris/**
386230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
387230557Sjimharris *        when there is an attempt to destruct a remote device from an
388230557Sjimharris *        invalid state.
389230557Sjimharris *
390230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
391230557Sjimharris *             object on which there is an attempt to fail the device.
392230557Sjimharris *
393230557Sjimharris * @return This method returns an indication that the fail transition is not
394230557Sjimharris *         allowed.
395230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
396230557Sjimharris */
397230557SjimharrisSCI_STATUS scif_sas_remote_device_default_destruct_handler(
398230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
399230557Sjimharris)
400230557Sjimharris{
401230557Sjimharris   SCIF_LOG_WARNING((
402230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
403230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
404230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to destruct.\n",
405230557Sjimharris      remote_device,
406230557Sjimharris      sci_base_state_machine_get_state(
407230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
408230557Sjimharris   ));
409230557Sjimharris
410230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
411230557Sjimharris}
412230557Sjimharris
413230557Sjimharris/**
414230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
415230557Sjimharris *        when there is an attempt to reset a remote device from an invalid
416230557Sjimharris *        state.
417230557Sjimharris *
418230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
419230557Sjimharris *             object on which there is an attempt to fail the device.
420230557Sjimharris *
421230557Sjimharris * @return This method returns an indication that the fail transition is not
422230557Sjimharris *         allowed.
423230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
424230557Sjimharris */
425230557SjimharrisSCI_STATUS scif_sas_remote_device_default_reset_handler(
426230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
427230557Sjimharris)
428230557Sjimharris{
429230557Sjimharris   SCIF_LOG_WARNING((
430230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
431230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
432230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to reset.\n",
433230557Sjimharris      remote_device,
434230557Sjimharris      sci_base_state_machine_get_state(
435230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
436230557Sjimharris   ));
437230557Sjimharris
438230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
439230557Sjimharris}
440230557Sjimharris
441230557Sjimharris/**
442230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
443230557Sjimharris *        when there is an attempt to complete a reset to the remote device
444230557Sjimharris *        from an invalid state.
445230557Sjimharris *
446230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
447230557Sjimharris *             object on which there is an attempt to fail the device.
448230557Sjimharris *
449230557Sjimharris * @return This method returns an indication that the fail transition is not
450230557Sjimharris *         allowed.
451230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
452230557Sjimharris */
453230557SjimharrisSCI_STATUS scif_sas_remote_device_default_reset_complete_handler(
454230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
455230557Sjimharris)
456230557Sjimharris{
457230557Sjimharris   SCIF_LOG_WARNING((
458230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
459230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
460230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to complete reset.\n",
461230557Sjimharris      remote_device,
462230557Sjimharris      sci_base_state_machine_get_state(
463230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
464230557Sjimharris   ));
465230557Sjimharris
466230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
467230557Sjimharris}
468230557Sjimharris
469230557Sjimharris/**
470230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
471230557Sjimharris *        when a user attempts to start an IO on a remote device and a start
472230557Sjimharris *        IO operation is not allowed.
473230557Sjimharris *
474230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
475230557Sjimharris *             object on which the user is attempting to perform a start IO
476230557Sjimharris *             operation.
477230557Sjimharris * @param[in]  io_request This parameter specifies the IO request to be
478230557Sjimharris *             started.
479230557Sjimharris *
480230557Sjimharris * @return This method returns an indication that start IO operations
481230557Sjimharris *         are not allowed.
482230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
483230557Sjimharris */
484230557SjimharrisSCI_STATUS scif_sas_remote_device_default_start_io_handler(
485230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
486230557Sjimharris   SCI_BASE_REQUEST_T       * io_request
487230557Sjimharris)
488230557Sjimharris{
489230557Sjimharris   SCIF_LOG_WARNING((
490230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
491230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
492230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to start IO.\n",
493230557Sjimharris      remote_device,
494230557Sjimharris      sci_base_state_machine_get_state(
495230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
496230557Sjimharris   ));
497230557Sjimharris
498230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
499230557Sjimharris}
500230557Sjimharris
501230557Sjimharris/**
502230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
503230557Sjimharris *        when a user attempts to complete an IO on a remote device and a
504230557Sjimharris *        complete IO operation is not allowed.
505230557Sjimharris *
506230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
507230557Sjimharris *             object on which the user is attempting to perform a complete
508230557Sjimharris *             IO operation.
509230557Sjimharris * @param[in]  io_request This parameter specifies the IO request to be
510230557Sjimharris *             completed.
511230557Sjimharris *
512230557Sjimharris * @return This method returns an indication that complete IO operations
513230557Sjimharris *         are not allowed.
514230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
515230557Sjimharris */
516230557SjimharrisSCI_STATUS scif_sas_remote_device_default_complete_io_handler(
517230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
518230557Sjimharris   SCI_BASE_REQUEST_T       * io_request
519230557Sjimharris)
520230557Sjimharris{
521230557Sjimharris   SCIF_LOG_WARNING((
522230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
523230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
524230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to complete IO\n",
525230557Sjimharris      remote_device,
526230557Sjimharris      sci_base_state_machine_get_state(
527230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
528230557Sjimharris   ));
529230557Sjimharris
530230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
531230557Sjimharris}
532230557Sjimharris
533230557Sjimharris
534230557Sjimharris/**
535230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
536230557Sjimharris *        when a user attempts to complete an IO on a remote device and a
537230557Sjimharris *        complete IO operation is not allowed.
538230557Sjimharris *
539230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
540230557Sjimharris *             object on which the user is attempting to perform a start IO
541230557Sjimharris *             operation.
542230557Sjimharris * @param[in]  io_request This parameter specifies the IO request to be
543230557Sjimharris *             started.
544230557Sjimharris *
545230557Sjimharris * @return This method returns an indication that complete IO operations
546230557Sjimharris *         are not allowed.
547230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
548230557Sjimharris */
549230557SjimharrisSCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler(
550230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
551230557Sjimharris   SCI_BASE_REQUEST_T       * io_request,
552230557Sjimharris   void                     * response_data,
553230557Sjimharris   SCI_IO_STATUS              completion_status
554230557Sjimharris)
555230557Sjimharris{
556230557Sjimharris   SCIF_LOG_WARNING((
557230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
558230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
559230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n",
560230557Sjimharris      remote_device,
561230557Sjimharris      sci_base_state_machine_get_state(
562230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
563230557Sjimharris   ));
564230557Sjimharris
565230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
566230557Sjimharris}
567230557Sjimharris
568230557Sjimharris
569230557Sjimharris/**
570230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
571230557Sjimharris *        when a user attempts to continue an IO on a remote device and a
572230557Sjimharris *        continue IO operation is not allowed.
573230557Sjimharris *
574230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
575230557Sjimharris *             object on which the user is attempting to perform a start IO
576230557Sjimharris *             operation.
577230557Sjimharris * @param[in]  io_request This parameter specifies the IO request to be
578230557Sjimharris *             started.
579230557Sjimharris *
580230557Sjimharris * @return This method returns an indication that continue IO operations
581230557Sjimharris *         are not allowed.
582230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
583230557Sjimharris */
584230557SjimharrisSCI_STATUS scif_sas_remote_device_default_continue_io_handler(
585230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
586230557Sjimharris   SCI_BASE_REQUEST_T       * io_request
587230557Sjimharris)
588230557Sjimharris{
589230557Sjimharris   SCIF_LOG_WARNING((
590230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
591230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
592230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to continue IO\n",
593230557Sjimharris      remote_device,
594230557Sjimharris      sci_base_state_machine_get_state(
595230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
596230557Sjimharris   ));
597230557Sjimharris
598230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
599230557Sjimharris}
600230557Sjimharris
601230557Sjimharris/**
602230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
603230557Sjimharris *        when a user attempts to start a task on a remote device and a
604230557Sjimharris *        start task operation is not allowed.
605230557Sjimharris *
606230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device
607230557Sjimharris *             object on which the user is attempting to perform a start
608230557Sjimharris *             task operation.
609230557Sjimharris * @param[in]  task_request This parameter specifies the task management
610230557Sjimharris *             request to be started.
611230557Sjimharris *
612230557Sjimharris * @return This method returns an indication that start task operations
613230557Sjimharris *         are not allowed.
614230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
615230557Sjimharris */
616230557SjimharrisSCI_STATUS scif_sas_remote_device_default_start_task_handler(
617230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
618230557Sjimharris   SCI_BASE_REQUEST_T       * task_request
619230557Sjimharris)
620230557Sjimharris{
621230557Sjimharris   SCIF_LOG_WARNING((
622230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
623230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
624230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to start task\n",
625230557Sjimharris      remote_device,
626230557Sjimharris      sci_base_state_machine_get_state(
627230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
628230557Sjimharris   ));
629230557Sjimharris
630230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
631230557Sjimharris}
632230557Sjimharris
633230557Sjimharris/**
634230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
635230557Sjimharris *        when a user attempts to complete a task on a remote device and a
636230557Sjimharris *        complete task operation is not allowed.
637230557Sjimharris *
638230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
639230557Sjimharris *             on which the user is attempting to perform a complete task
640230557Sjimharris *             operation.
641230557Sjimharris * @param[in]  task_request This parameter specifies the task management
642230557Sjimharris *             request to be completed.
643230557Sjimharris *
644230557Sjimharris * @return This method returns an indication that complete task operations
645230557Sjimharris *         are not allowed.
646230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
647230557Sjimharris */
648230557SjimharrisSCI_STATUS scif_sas_remote_device_default_complete_task_handler(
649230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
650230557Sjimharris   SCI_BASE_REQUEST_T       * task_request
651230557Sjimharris)
652230557Sjimharris{
653230557Sjimharris   SCIF_LOG_WARNING((
654230557Sjimharris      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
655230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
656230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to complete task\n",
657230557Sjimharris      remote_device,
658230557Sjimharris      sci_base_state_machine_get_state(
659230557Sjimharris         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
660230557Sjimharris   ));
661230557Sjimharris
662230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
663230557Sjimharris}
664230557Sjimharris
665230557Sjimharris/**
666230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
667230557Sjimharris *        for when the core issues a start completion notification and
668230557Sjimharris *        such a notification isn't supported.
669230557Sjimharris *
670230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
671298955Spfg *             for which the completion notification has occurred.
672230557Sjimharris * @param[in]  completion_status This parameter specifies the status
673230557Sjimharris *             of the completion operation.
674230557Sjimharris *
675230557Sjimharris * @return none.
676230557Sjimharris */
677230557Sjimharrisvoid scif_sas_remote_device_default_start_complete_handler(
678230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
679230557Sjimharris   SCI_STATUS                 completion_status
680230557Sjimharris)
681230557Sjimharris{
682230557Sjimharris   SCIF_LOG_WARNING((
683230557Sjimharris      sci_base_object_get_logger(fw_device),
684230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
685230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to start complete\n",
686230557Sjimharris      fw_device,
687230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
688230557Sjimharris   ));
689230557Sjimharris}
690230557Sjimharris
691230557Sjimharris/**
692230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
693230557Sjimharris *        for when the core issues a stop completion notification and
694230557Sjimharris *        such a notification isn't supported.
695230557Sjimharris *
696230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
697298955Spfg *             for which the completion notification has occurred.
698230557Sjimharris * @param[in]  completion_status This parameter specifies the status
699230557Sjimharris *             of the completion operation.
700230557Sjimharris *
701230557Sjimharris * @return none.
702230557Sjimharris */
703230557Sjimharrisvoid scif_sas_remote_device_default_stop_complete_handler(
704230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
705230557Sjimharris   SCI_STATUS                 completion_status
706230557Sjimharris)
707230557Sjimharris{
708230557Sjimharris   SCIF_LOG_WARNING((
709230557Sjimharris      sci_base_object_get_logger(fw_device),
710230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
711230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to stop complete\n",
712230557Sjimharris      fw_device,
713230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
714230557Sjimharris   ));
715230557Sjimharris}
716230557Sjimharris
717230557Sjimharris/**
718230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
719230557Sjimharris *        for when the core issues a ready notification and such a
720230557Sjimharris *        notification isn't supported.
721230557Sjimharris *
722230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
723298955Spfg *             for which the notification has occurred.
724230557Sjimharris *
725230557Sjimharris * @return none.
726230557Sjimharris */
727230557Sjimharrisvoid scif_sas_remote_device_default_ready_handler(
728230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device
729230557Sjimharris)
730230557Sjimharris{
731230557Sjimharris   SCIF_LOG_WARNING((
732230557Sjimharris      sci_base_object_get_logger(fw_device),
733230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
734230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to handle ready\n",
735230557Sjimharris      fw_device,
736230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
737230557Sjimharris   ));
738230557Sjimharris}
739230557Sjimharris
740230557Sjimharris/**
741230557Sjimharris * @brief This method provides default handling (i.e. returns an error);
742230557Sjimharris *        for when the core issues a not ready notification and such a
743230557Sjimharris *        notification isn't supported.
744230557Sjimharris *
745230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
746298955Spfg *             for which the notification has occurred.
747230557Sjimharris *
748230557Sjimharris * @return none.
749230557Sjimharris */
750230557Sjimharrisvoid scif_sas_remote_device_default_not_ready_handler(
751230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
752230557Sjimharris   U32                        reason_code
753230557Sjimharris)
754230557Sjimharris{
755230557Sjimharris   SCIF_LOG_WARNING((
756230557Sjimharris      sci_base_object_get_logger(fw_device),
757230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
758230557Sjimharris      "RemoteDevice:0x%x State:0x%x invalid state to handle not ready\n",
759230557Sjimharris      fw_device,
760230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
761230557Sjimharris   ));
762230557Sjimharris}
763230557Sjimharris
764230557Sjimharris#if !defined(DISABLE_WIDE_PORTED_TARGETS)
765230557Sjimharris/**
766230557Sjimharris * @brief This method provides handling of device start complete duing
767230557Sjimharris *        UPDATING_PORT_WIDTH state.
768230557Sjimharris *
769230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
770230557Sjimharris *             which is start complete.
771230557Sjimharris *
772230557Sjimharris * @return none.
773230557Sjimharris */
774230557Sjimharrisstatic
775230557SjimharrisSCI_STATUS scif_sas_remote_device_updating_port_width_state_complete_io_handler(
776230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device,
777230557Sjimharris   SCI_BASE_REQUEST_T       * io_request
778230557Sjimharris)
779230557Sjimharris{
780230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
781230557Sjimharris                                          remote_device;
782230557Sjimharris   fw_device->request_count--;
783230557Sjimharris
784230557Sjimharris   //If the request count is zero, go ahead to update the RNC.
785230557Sjimharris   if (fw_device->request_count == 0 )
786230557Sjimharris   {
787230557Sjimharris      if (fw_device->destination_state == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING)
788230557Sjimharris      {
789230557Sjimharris         //if the destination state of this device change to STOPPING, no matter
790230557Sjimharris         //whether we need to update the port width, just make the device
791230557Sjimharris         //go to the STOPPING state, the device will be removed anyway.
792230557Sjimharris         sci_base_state_machine_change_state(
793230557Sjimharris            &fw_device->parent.state_machine,
794230557Sjimharris            SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
795230557Sjimharris         );
796230557Sjimharris      }
797230557Sjimharris      else
798230557Sjimharris      {
799230557Sjimharris         //stop the device, upon the stop complete callback, start the device again
800230557Sjimharris         //with the updated port width.
801230557Sjimharris         scic_remote_device_stop(
802230557Sjimharris            fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
803230557Sjimharris      }
804230557Sjimharris   }
805230557Sjimharris
806230557Sjimharris   return SCI_SUCCESS;
807230557Sjimharris}
808230557Sjimharris
809230557Sjimharris
810230557Sjimharris/**
811230557Sjimharris * @brief This method provides handling of device start complete duing
812230557Sjimharris *        UPDATING_PORT_WIDTH state.
813230557Sjimharris *
814230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
815230557Sjimharris *             which is start complete.
816230557Sjimharris *
817230557Sjimharris * @return none.
818230557Sjimharris */
819230557Sjimharrisstatic
820230557Sjimharrisvoid scif_sas_remote_device_updating_port_width_state_start_complete_handler(
821230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
822230557Sjimharris   SCI_STATUS                 completion_status
823230557Sjimharris)
824230557Sjimharris{
825230557Sjimharris   SCIF_LOG_INFO((
826230557Sjimharris      sci_base_object_get_logger(fw_device),
827230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
828230557Sjimharris      "RemoteDevice:0x%x updating port width state start complete handler\n",
829230557Sjimharris      fw_device,
830230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
831230557Sjimharris   ));
832230557Sjimharris
833230557Sjimharris   if ( fw_device->destination_state
834230557Sjimharris           == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
835230557Sjimharris   {
836230557Sjimharris      //if the destination state of this device change to STOPPING, no matter
837230557Sjimharris      //whether we need to update the port width again, just make the device
838230557Sjimharris      //go to the STOPPING state.
839230557Sjimharris      sci_base_state_machine_change_state(
840230557Sjimharris         &fw_device->parent.state_machine,
841230557Sjimharris         SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
842230557Sjimharris      );
843230557Sjimharris   }
844230557Sjimharris   else if ( scic_remote_device_get_port_width(fw_device->core_object)
845230557Sjimharris                != fw_device->device_port_width
846230557Sjimharris            && fw_device->device_port_width != 0)
847230557Sjimharris   {
848230557Sjimharris      scic_remote_device_stop(
849230557Sjimharris         fw_device->core_object,
850230557Sjimharris         SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT
851230557Sjimharris      );
852230557Sjimharris   }
853230557Sjimharris   else
854230557Sjimharris   {
855230557Sjimharris      //Port width updating succeeds. Transfer to destination state.
856230557Sjimharris      sci_base_state_machine_change_state(
857230557Sjimharris         &fw_device->parent.state_machine,
858230557Sjimharris         SCI_BASE_REMOTE_DEVICE_STATE_READY
859230557Sjimharris      );
860230557Sjimharris   }
861230557Sjimharris}
862230557Sjimharris
863230557Sjimharris/**
864230557Sjimharris * @brief This method provides handling of device stop complete duing
865230557Sjimharris *        UPDATING_PORT_WIDTH state.
866230557Sjimharris *
867230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
868230557Sjimharris *             which is stop complete.
869230557Sjimharris *
870230557Sjimharris * @return none.
871230557Sjimharris */
872230557Sjimharrisstatic
873230557Sjimharrisvoid scif_sas_remote_device_updating_port_width_state_stop_complete_handler(
874230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
875230557Sjimharris   SCI_STATUS                 completion_status
876230557Sjimharris)
877230557Sjimharris{
878230557Sjimharris   SCIF_LOG_INFO((
879230557Sjimharris      sci_base_object_get_logger(fw_device),
880230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
881230557Sjimharris      "RemoteDevice:0x%x updating port width state stop complete handler\n",
882230557Sjimharris      fw_device,
883230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
884230557Sjimharris   ));
885230557Sjimharris
886230557Sjimharris   if ( fw_device->destination_state
887230557Sjimharris           == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
888230557Sjimharris   {
889230557Sjimharris      //Device directly transits to STOPPED STATE from UPDATING_PORT_WIDTH state,
890230557Sjimharris      fw_device->domain->device_start_count--;
891230557Sjimharris
892230557Sjimharris      //if the destination state of this device change to STOPPING, no matter
893230557Sjimharris      //whether we need to update the port width again, just make the device
894230557Sjimharris      //go to the STOPPED state.
895230557Sjimharris      sci_base_state_machine_change_state(
896230557Sjimharris         &fw_device->parent.state_machine,
897230557Sjimharris         SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
898230557Sjimharris      );
899230557Sjimharris   }
900230557Sjimharris   else
901230557Sjimharris   {
902230557Sjimharris      scic_remote_device_set_port_width(
903230557Sjimharris         fw_device->core_object,
904230557Sjimharris         fw_device->device_port_width
905230557Sjimharris      );
906230557Sjimharris
907230557Sjimharris      //Device stop complete, means the RNC has been destructed. Now we need to
908230557Sjimharris      //start core device so the RNC with updated port width will be posted.
909230557Sjimharris      scic_remote_device_start(
910230557Sjimharris         fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
911230557Sjimharris   }
912230557Sjimharris}
913230557Sjimharris
914230557Sjimharris/**
915230557Sjimharris * @brief This method provides handling (i.e. returns an error);
916230557Sjimharris *        when a user attempts to stop a remote device during the updating
917230557Sjimharris *        port width state, it will record the destination state for this
918230557Sjimharris *        device to be STOPPING, instead of usually READY state.
919230557Sjimharris *
920230557Sjimharris * @param[in]  remote_device This parameter specifies the remote device object
921230557Sjimharris *             on which the user is attempting to perform a stop operation.
922230557Sjimharris *
923230557Sjimharris * @return This method always return SCI_SUCCESS.
924230557Sjimharris */
925230557Sjimharrisstatic
926230557SjimharrisSCI_STATUS scif_sas_remote_device_updating_port_width_state_stop_handler(
927230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * remote_device
928230557Sjimharris)
929230557Sjimharris{
930230557Sjimharris   SCIF_SAS_REMOTE_DEVICE_T * fw_device =
931230557Sjimharris      (SCIF_SAS_REMOTE_DEVICE_T *)remote_device;
932230557Sjimharris
933230557Sjimharris   SCIF_LOG_INFO((
934230557Sjimharris      sci_base_object_get_logger(fw_device),
935230557Sjimharris      SCIF_LOG_OBJECT_REMOTE_DEVICE,
936230557Sjimharris      "RemoteDevice:0x%x updating port width state stop handler\n",
937230557Sjimharris      fw_device,
938230557Sjimharris      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
939230557Sjimharris   ));
940230557Sjimharris
941230557Sjimharris   //Can't stop the device right now. Remember the pending stopping request.
942230557Sjimharris   //When exit the UPDATING_PORT_WIDTH state, we will check this variable
943230557Sjimharris   //to decide which state to go.
944230557Sjimharris   fw_device->destination_state =
945230557Sjimharris      SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING;
946230557Sjimharris
947230557Sjimharris   return SCI_SUCCESS;
948230557Sjimharris}
949230557Sjimharris
950230557Sjimharris#endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
951230557Sjimharris
952230557Sjimharris#define scif_sas_remote_device_stopping_complete_io_handler   \
953230557Sjimharris        scif_sas_remote_device_ready_operational_complete_io_handler
954230557Sjimharris#define scif_sas_remote_device_stopping_complete_task_handler \
955230557Sjimharris        scif_sas_remote_device_ready_operational_complete_task_handler
956230557Sjimharris
957230557SjimharrisSCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
958230557Sjimharrisscif_sas_remote_device_state_handler_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] =
959230557Sjimharris{
960230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_INITIAL
961230557Sjimharris   {
962230557Sjimharris      {
963230557Sjimharris         scif_sas_remote_device_default_start_handler,
964230557Sjimharris         scif_sas_remote_device_default_stop_handler,
965230557Sjimharris         scif_sas_remote_device_default_fail_handler,
966230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
967230557Sjimharris         scif_sas_remote_device_default_reset_handler,
968230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
969230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
970230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
971230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
972230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
973230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
974230557Sjimharris      },
975230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
976230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
977230557Sjimharris      scif_sas_remote_device_default_ready_handler,
978230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
979230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
980230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
981230557Sjimharris   },
982230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
983230557Sjimharris   {
984230557Sjimharris      {
985230557Sjimharris         scif_sas_remote_device_stopped_start_handler,
986230557Sjimharris         scif_sas_remote_device_default_stop_handler,
987230557Sjimharris         scif_sas_remote_device_default_fail_handler,
988230557Sjimharris         scif_sas_remote_device_stopped_destruct_handler,
989230557Sjimharris         scif_sas_remote_device_default_reset_handler,
990230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
991230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
992230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
993230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
994230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
995230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
996230557Sjimharris      },
997230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
998230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
999230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1000230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1001230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1002230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1003230557Sjimharris   },
1004230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_STARTING
1005230557Sjimharris   {
1006230557Sjimharris      {
1007230557Sjimharris         scif_sas_remote_device_default_start_handler,
1008230557Sjimharris         scif_sas_remote_device_default_stop_handler,
1009230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1010230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1011230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1012230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1013230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1014230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
1015230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1016230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1017230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
1018230557Sjimharris      },
1019230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
1020230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
1021230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1022230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1023230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1024230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1025230557Sjimharris   },
1026230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_READY - see substate handlers
1027230557Sjimharris   {
1028230557Sjimharris      {
1029230557Sjimharris         scif_sas_remote_device_default_start_handler,
1030230557Sjimharris         scif_sas_remote_device_default_stop_handler,
1031230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1032230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1033230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1034230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1035230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1036230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
1037230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1038230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1039230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
1040230557Sjimharris      },
1041230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
1042230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
1043230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1044230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1045230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1046230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1047230557Sjimharris   },
1048230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1049230557Sjimharris   {
1050230557Sjimharris      {
1051230557Sjimharris         scif_sas_remote_device_default_start_handler,
1052230557Sjimharris         scif_sas_remote_device_default_stop_handler,
1053230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1054230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1055230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1056230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1057230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1058230557Sjimharris         scif_sas_remote_device_stopping_complete_io_handler,
1059230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1060230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1061230557Sjimharris         scif_sas_remote_device_stopping_complete_task_handler
1062230557Sjimharris      },
1063230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
1064230557Sjimharris      scif_sas_remote_device_stopping_stop_complete_handler,
1065230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1066230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1067230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1068230557Sjimharris      scif_sas_remote_device_stopping_complete_high_priority_io_handler
1069230557Sjimharris   },
1070230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_FAILED
1071230557Sjimharris   {
1072230557Sjimharris      {
1073230557Sjimharris         scif_sas_remote_device_default_start_handler,
1074230557Sjimharris         scif_sas_remote_device_failed_stop_handler,
1075230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1076230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1077230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1078230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1079230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1080230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
1081230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1082230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1083230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
1084230557Sjimharris      },
1085230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
1086230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
1087230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1088230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1089230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1090230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1091230557Sjimharris   },
1092230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_RESETTING - is unused by framework
1093230557Sjimharris   {
1094230557Sjimharris      {
1095230557Sjimharris         scif_sas_remote_device_default_start_handler,
1096230557Sjimharris         scif_sas_remote_device_default_stop_handler,
1097230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1098230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1099230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1100230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1101230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1102230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
1103230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1104230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1105230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
1106230557Sjimharris      },
1107230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
1108230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
1109230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1110230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1111230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1112230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1113230557Sjimharris   },
1114230557Sjimharris#if !defined(DISABLE_WIDE_PORTED_TARGETS)
1115230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH
1116230557Sjimharris   {
1117230557Sjimharris      {
1118230557Sjimharris         scif_sas_remote_device_default_start_handler,
1119230557Sjimharris         scif_sas_remote_device_updating_port_width_state_stop_handler,
1120230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1121230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1122230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1123230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1124230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1125230557Sjimharris         scif_sas_remote_device_updating_port_width_state_complete_io_handler,
1126230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1127230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1128230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
1129230557Sjimharris      },
1130230557Sjimharris      scif_sas_remote_device_updating_port_width_state_start_complete_handler,
1131230557Sjimharris      scif_sas_remote_device_updating_port_width_state_stop_complete_handler,
1132230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1133230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1134230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1135230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1136230557Sjimharris   },
1137230557Sjimharris#endif
1138230557Sjimharris   // SCI_BASE_REMOTE_DEVICE_STATE_FINAL
1139230557Sjimharris   {
1140230557Sjimharris      {
1141230557Sjimharris         scif_sas_remote_device_default_start_handler,
1142230557Sjimharris         scif_sas_remote_device_default_stop_handler,
1143230557Sjimharris         scif_sas_remote_device_default_fail_handler,
1144230557Sjimharris         scif_sas_remote_device_default_destruct_handler,
1145230557Sjimharris         scif_sas_remote_device_default_reset_handler,
1146230557Sjimharris         scif_sas_remote_device_default_reset_complete_handler,
1147230557Sjimharris         scif_sas_remote_device_default_start_io_handler,
1148230557Sjimharris         scif_sas_remote_device_default_complete_io_handler,
1149230557Sjimharris         scif_sas_remote_device_default_continue_io_handler,
1150230557Sjimharris         scif_sas_remote_device_default_start_task_handler,
1151230557Sjimharris         scif_sas_remote_device_default_complete_task_handler
1152230557Sjimharris      },
1153230557Sjimharris      scif_sas_remote_device_default_start_complete_handler,
1154230557Sjimharris      scif_sas_remote_device_default_stop_complete_handler,
1155230557Sjimharris      scif_sas_remote_device_default_ready_handler,
1156230557Sjimharris      scif_sas_remote_device_default_not_ready_handler,
1157230557Sjimharris      scif_sas_remote_device_default_start_io_handler,
1158230557Sjimharris      scif_sas_remote_device_default_complete_high_priority_io_handler
1159230557Sjimharris   }
1160230557Sjimharris};
1161230557Sjimharris
1162