]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/isci/scil/scif_sas_remote_device_state_handlers.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / isci / scil / scif_sas_remote_device_state_handlers.c
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license.  When using or
3  * redistributing this file, you may do so under either license.
4  *
5  * GPL LICENSE SUMMARY
6  *
7  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21  * The full GNU General Public License is included in this distribution
22  * in the file called LICENSE.GPL.
23  *
24  * BSD LICENSE
25  *
26  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  *   * Redistributions of source code must retain the above copyright
34  *     notice, this list of conditions and the following disclaimer.
35  *   * Redistributions in binary form must reproduce the above copyright
36  *     notice, this list of conditions and the following disclaimer in
37  *     the documentation and/or other materials provided with the
38  *     distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51  */
52
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
55
56 /**
57  * @file
58  *
59  * @brief This file contains all of the method implementations pertaining
60  *        to the framework remote device state handler methods.
61  */
62
63 #include <dev/isci/scil/scic_remote_device.h>
64
65 #include <dev/isci/scil/scif_sas_logger.h>
66 #include <dev/isci/scil/scif_sas_remote_device.h>
67 #include <dev/isci/scil/scif_sas_domain.h>
68 #include <dev/isci/scil/scif_sas_task_request.h>
69 #include <dev/isci/scil/scif_sas_internal_io_request.h>
70
71 //******************************************************************************
72 //* S T O P P E D   H A N D L E R S
73 //******************************************************************************
74
75 /**
76  * @brief This method provides STOPPED state specific handling for
77  *        when the framework attempts to start the remote device.  This
78  *        method attempts to transition the state machine into the
79  *        STARTING state.  If this is unsuccessful, then there is a direct
80  *        transition into the FAILED state.
81  *
82  * @param[in]  remote_device This parameter specifies the remote device
83  *             object for which the framework is attempting to start.
84  *
85  * @return This method returns an indication as to whether the start
86  *         operating began successfully.
87  */
88 static
89 SCI_STATUS scif_sas_remote_device_stopped_start_handler(
90    SCI_BASE_REMOTE_DEVICE_T * remote_device
91 )
92 {
93    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
94                                           remote_device;
95
96    sci_base_state_machine_change_state(
97       &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STARTING
98    );
99
100    // Check to see if the state transition occurred without issue.
101    if (sci_base_state_machine_get_state(&fw_device->parent.state_machine)
102        == SCI_BASE_REMOTE_DEVICE_STATE_FAILED)
103    {
104       SCIF_LOG_WARNING((
105          sci_base_object_get_logger(fw_device),
106          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
107          "Domain:0x%x Device:0x%x Status:0x%x failed to start\n",
108          fw_device->domain, fw_device, fw_device->operation_status
109       ));
110    }
111
112    return fw_device->operation_status;
113 }
114
115 /**
116  * @brief This method provides STOPPED state specific handling for
117  *        when the user attempts to destruct the remote device.
118  *
119  * @param[in]  remote_device This parameter specifies the remote device
120  *             object for which the framework is attempting to start.
121  *
122  * @return This method returns an indication as to whether the destruct
123  *         operation completed successfully.
124  */
125 static
126 SCI_STATUS scif_sas_remote_device_stopped_destruct_handler(
127    SCI_BASE_REMOTE_DEVICE_T * remote_device
128 )
129 {
130    SCI_STATUS                 status;
131    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
132                                           remote_device;
133
134    SMP_DISCOVER_RESPONSE_PROTOCOLS_T  dev_protocols;
135    scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
136
137    //For smp device, need to clear its smp phy list first.
138    if(dev_protocols.u.bits.attached_smp_target)
139       scif_sas_smp_remote_device_removed(fw_device);
140
141    status = scic_remote_device_destruct(fw_device->core_object);
142    if (status == SCI_SUCCESS)
143    {
144       sci_base_state_machine_change_state(
145          &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FINAL
146       );
147
148       scif_sas_remote_device_deinitialize_state_logging(fw_device);
149    }
150    else
151    {
152       SCIF_LOG_ERROR((
153          sci_base_object_get_logger(fw_device),
154          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
155          "Device:0x%x Status:0x%x failed to destruct core device\n",
156          fw_device
157       ));
158    }
159
160    return status;
161 }
162
163 //******************************************************************************
164 //* S T O P P I N G   H A N D L E R S
165 //******************************************************************************
166
167 /**
168  * @brief This method provides STOPPING state specific handling for
169  *        when the core remote device object issues a stop completion
170  *        notification.
171  *
172  * @note There is no need to ensure all IO/Task requests are complete
173  *       before transitioning to the STOPPED state.  The SCI Core will
174  *       ensure this is accomplished.
175  *
176  * @param[in]  remote_device This parameter specifies the remote device
177  *             object for which the completion occurred.
178  * @param[in]  completion_status This parameter specifies the status
179  *             of the completion operation.
180  *
181  * @return none.
182  */
183 static
184 void scif_sas_remote_device_stopping_stop_complete_handler(
185    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
186    SCI_STATUS                 completion_status
187 )
188 {
189    // Transition directly to the STOPPED state since the core ensures
190    // all IO/Tasks are complete.
191    sci_base_state_machine_change_state(
192       &fw_device->parent.state_machine,
193       SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
194    );
195
196    if (completion_status != SCI_SUCCESS)
197    {
198       SCIF_LOG_ERROR((
199          sci_base_object_get_logger(fw_device),
200          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
201          "Device:0x%x Status:0x%x failed to stop core device\n",
202          fw_device, completion_status
203       ));
204
205       // Something is seriously wrong.  Stopping the core remote device
206       // shouldn't fail in anyway.
207       scif_cb_controller_error(fw_device->domain->controller,
208               SCI_CONTROLLER_REMOTE_DEVICE_ERROR);
209    }
210 }
211
212 /**
213  * @brief This method provides STOPPING state handling for high priority
214  *        IO requests, when the framework attempts to complete a high
215  *        priority request.
216  *
217  * @param[in]  remote_device This parameter specifies the remote device
218  *             object for which to complete the high priority IO.
219  * @param[in]  io_request This parameter specifies the IO request to be
220  *             completed.
221  * @param[in]  response_data This parameter is ignored, since the device
222  *             is in the stopping state.
223  *
224  * @return This method always returns success.
225  */
226 static
227 SCI_STATUS scif_sas_remote_device_stopping_complete_high_priority_io_handler(
228    SCI_BASE_REMOTE_DEVICE_T * remote_device,
229    SCI_BASE_REQUEST_T       * io_request,
230    void                     * response_data,
231    SCI_IO_STATUS              completion_status
232 )
233 {
234    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
235                                           remote_device;
236    SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T *) io_request;
237
238    SCIF_LOG_TRACE((
239       sci_base_object_get_logger(remote_device),
240       SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
241       "scif_sas_remote_device_stopping_complete_high_priority_io_handler(0x%x,0x%x,0x%x) enter\n",
242       remote_device, io_request, response_data
243    ));
244
245    fw_device->request_count--;
246
247    if (fw_request->is_internal == TRUE)
248    {
249       scif_sas_internal_io_request_complete(
250          fw_device->domain->controller,
251          (SCIF_SAS_INTERNAL_IO_REQUEST_T *) io_request,
252          SCI_SUCCESS
253       );
254    }
255
256    return SCI_SUCCESS;
257 }
258
259 //******************************************************************************
260 //* F A I L E D   H A N D L E R S
261 //******************************************************************************
262
263 /**
264  * @brief This method provides FAILED state specific handling for
265  *        when the remote device is being stopped by the framework.
266  *
267  * @param[in]  remote_device This parameter specifies the remote device
268  *             object for which the stop operation is being requested.
269  *
270  * @return This method returns an indication as to whether the failure
271  *         operation completed successfully.
272  */
273 static
274 SCI_STATUS scif_sas_remote_device_failed_stop_handler(
275    SCI_BASE_REMOTE_DEVICE_T * remote_device
276 )
277 {
278    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
279                                           remote_device;
280
281    SCIF_LOG_WARNING((
282       sci_base_object_get_logger(fw_device),
283       SCIF_LOG_OBJECT_REMOTE_DEVICE,
284       "RemoteDevice:0x%x stopping failed device\n",
285       fw_device
286    ));
287
288    sci_base_state_machine_change_state(
289       &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
290    );
291
292    /// @todo Fix the return code handling.
293    return SCI_FAILURE;
294 }
295
296 //******************************************************************************
297 //* D E F A U L T   H A N D L E R S
298 //******************************************************************************
299
300 /**
301  * @brief This method provides default handling (i.e. returns an error);
302  *        when a user attempts to start a remote device and a start operation
303  *        is not allowed.
304  *
305  * @param[in]  remote_device This parameter specifies the remote device object
306  *             on which the user is attempting to perform a start operation.
307  *
308  * @return This method returns an indication that start operations are not
309  *         allowed.
310  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
311  */
312 SCI_STATUS scif_sas_remote_device_default_start_handler(
313    SCI_BASE_REMOTE_DEVICE_T * remote_device
314 )
315 {
316    SCIF_LOG_WARNING((
317       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
318       SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
319       "RemoteDevice:0x%x State:0x%x invalid state to start\n",
320       remote_device,
321       sci_base_state_machine_get_state(
322          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
323    ));
324
325    return SCI_FAILURE_INVALID_STATE;
326 }
327
328 /**
329  * @brief This method provides default handling (i.e. returns an error);
330  *        when a user attempts to stop a remote device and a stop operation
331  *        is not allowed.
332  *
333  * @param[in]  remote_device This parameter specifies the remote device object
334  *             on which the user is attempting to perform a stop operation.
335  *
336  * @return This method returns an indication that stop operations are not
337  *         allowed.
338  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
339  */
340 SCI_STATUS scif_sas_remote_device_default_stop_handler(
341    SCI_BASE_REMOTE_DEVICE_T * remote_device
342 )
343 {
344    SCIF_LOG_WARNING((
345       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
346       SCIF_LOG_OBJECT_REMOTE_DEVICE,
347       "RemoteDevice:0x%x State:0x%x invalid state to stop\n",
348       remote_device,
349       sci_base_state_machine_get_state(
350          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
351    ));
352
353    return SCI_FAILURE_INVALID_STATE;
354 }
355
356 /**
357  * @brief This method provides default handling (i.e. returns an error);
358  *        when there is an attempt to fail a remote device from an invalid
359  *        state.
360  *
361  * @param[in]  remote_device This parameter specifies the remote device
362  *             object on which there is an attempt to fail the device.
363  *
364  * @return This method returns an indication that the fail transition is not
365  *         allowed.
366  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
367  */
368 static
369 SCI_STATUS scif_sas_remote_device_default_fail_handler(
370    SCI_BASE_REMOTE_DEVICE_T * remote_device
371 )
372 {
373    SCIF_LOG_WARNING((
374       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
375       SCIF_LOG_OBJECT_REMOTE_DEVICE,
376       "RemoteDevice:0x%x State:0x%x invalid state to fail device\n",
377       remote_device,
378       sci_base_state_machine_get_state(
379          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
380    ));
381
382    return SCI_FAILURE_INVALID_STATE;
383 }
384
385 /**
386  * @brief This method provides default handling (i.e. returns an error);
387  *        when there is an attempt to destruct a remote device from an
388  *        invalid state.
389  *
390  * @param[in]  remote_device This parameter specifies the remote device
391  *             object on which there is an attempt to fail the device.
392  *
393  * @return This method returns an indication that the fail transition is not
394  *         allowed.
395  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
396  */
397 SCI_STATUS scif_sas_remote_device_default_destruct_handler(
398    SCI_BASE_REMOTE_DEVICE_T * remote_device
399 )
400 {
401    SCIF_LOG_WARNING((
402       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
403       SCIF_LOG_OBJECT_REMOTE_DEVICE,
404       "RemoteDevice:0x%x State:0x%x invalid state to destruct.\n",
405       remote_device,
406       sci_base_state_machine_get_state(
407          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
408    ));
409
410    return SCI_FAILURE_INVALID_STATE;
411 }
412
413 /**
414  * @brief This method provides default handling (i.e. returns an error);
415  *        when there is an attempt to reset a remote device from an invalid
416  *        state.
417  *
418  * @param[in]  remote_device This parameter specifies the remote device
419  *             object on which there is an attempt to fail the device.
420  *
421  * @return This method returns an indication that the fail transition is not
422  *         allowed.
423  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
424  */
425 SCI_STATUS scif_sas_remote_device_default_reset_handler(
426    SCI_BASE_REMOTE_DEVICE_T * remote_device
427 )
428 {
429    SCIF_LOG_WARNING((
430       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
431       SCIF_LOG_OBJECT_REMOTE_DEVICE,
432       "RemoteDevice:0x%x State:0x%x invalid state to reset.\n",
433       remote_device,
434       sci_base_state_machine_get_state(
435          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
436    ));
437
438    return SCI_FAILURE_INVALID_STATE;
439 }
440
441 /**
442  * @brief This method provides default handling (i.e. returns an error);
443  *        when there is an attempt to complete a reset to the remote device
444  *        from an invalid state.
445  *
446  * @param[in]  remote_device This parameter specifies the remote device
447  *             object on which there is an attempt to fail the device.
448  *
449  * @return This method returns an indication that the fail transition is not
450  *         allowed.
451  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
452  */
453 SCI_STATUS scif_sas_remote_device_default_reset_complete_handler(
454    SCI_BASE_REMOTE_DEVICE_T * remote_device
455 )
456 {
457    SCIF_LOG_WARNING((
458       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
459       SCIF_LOG_OBJECT_REMOTE_DEVICE,
460       "RemoteDevice:0x%x State:0x%x invalid state to complete reset.\n",
461       remote_device,
462       sci_base_state_machine_get_state(
463          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
464    ));
465
466    return SCI_FAILURE_INVALID_STATE;
467 }
468
469 /**
470  * @brief This method provides default handling (i.e. returns an error);
471  *        when a user attempts to start an IO on a remote device and a start
472  *        IO operation is not allowed.
473  *
474  * @param[in]  remote_device This parameter specifies the remote device
475  *             object on which the user is attempting to perform a start IO
476  *             operation.
477  * @param[in]  io_request This parameter specifies the IO request to be
478  *             started.
479  *
480  * @return This method returns an indication that start IO operations
481  *         are not allowed.
482  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
483  */
484 SCI_STATUS scif_sas_remote_device_default_start_io_handler(
485    SCI_BASE_REMOTE_DEVICE_T * remote_device,
486    SCI_BASE_REQUEST_T       * io_request
487 )
488 {
489    SCIF_LOG_WARNING((
490       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
491       SCIF_LOG_OBJECT_REMOTE_DEVICE,
492       "RemoteDevice:0x%x State:0x%x invalid state to start IO.\n",
493       remote_device,
494       sci_base_state_machine_get_state(
495          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
496    ));
497
498    return SCI_FAILURE_INVALID_STATE;
499 }
500
501 /**
502  * @brief This method provides default handling (i.e. returns an error);
503  *        when a user attempts to complete an IO on a remote device and a
504  *        complete IO operation is not allowed.
505  *
506  * @param[in]  remote_device This parameter specifies the remote device
507  *             object on which the user is attempting to perform a complete
508  *             IO operation.
509  * @param[in]  io_request This parameter specifies the IO request to be
510  *             completed.
511  *
512  * @return This method returns an indication that complete IO operations
513  *         are not allowed.
514  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
515  */
516 SCI_STATUS scif_sas_remote_device_default_complete_io_handler(
517    SCI_BASE_REMOTE_DEVICE_T * remote_device,
518    SCI_BASE_REQUEST_T       * io_request
519 )
520 {
521    SCIF_LOG_WARNING((
522       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
523       SCIF_LOG_OBJECT_REMOTE_DEVICE,
524       "RemoteDevice:0x%x State:0x%x invalid state to complete IO\n",
525       remote_device,
526       sci_base_state_machine_get_state(
527          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
528    ));
529
530    return SCI_FAILURE_INVALID_STATE;
531 }
532
533
534 /**
535  * @brief This method provides default handling (i.e. returns an error);
536  *        when a user attempts to complete an IO on a remote device and a
537  *        complete IO operation is not allowed.
538  *
539  * @param[in]  remote_device This parameter specifies the remote device
540  *             object on which the user is attempting to perform a start IO
541  *             operation.
542  * @param[in]  io_request This parameter specifies the IO request to be
543  *             started.
544  *
545  * @return This method returns an indication that complete IO operations
546  *         are not allowed.
547  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
548  */
549 SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler(
550    SCI_BASE_REMOTE_DEVICE_T * remote_device,
551    SCI_BASE_REQUEST_T       * io_request,
552    void                     * response_data,
553    SCI_IO_STATUS              completion_status
554 )
555 {
556    SCIF_LOG_WARNING((
557       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
558       SCIF_LOG_OBJECT_REMOTE_DEVICE,
559       "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n",
560       remote_device,
561       sci_base_state_machine_get_state(
562          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
563    ));
564
565    return SCI_FAILURE_INVALID_STATE;
566 }
567
568
569 /**
570  * @brief This method provides default handling (i.e. returns an error);
571  *        when a user attempts to continue an IO on a remote device and a
572  *        continue IO operation is not allowed.
573  *
574  * @param[in]  remote_device This parameter specifies the remote device
575  *             object on which the user is attempting to perform a start IO
576  *             operation.
577  * @param[in]  io_request This parameter specifies the IO request to be
578  *             started.
579  *
580  * @return This method returns an indication that continue IO operations
581  *         are not allowed.
582  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
583  */
584 SCI_STATUS scif_sas_remote_device_default_continue_io_handler(
585    SCI_BASE_REMOTE_DEVICE_T * remote_device,
586    SCI_BASE_REQUEST_T       * io_request
587 )
588 {
589    SCIF_LOG_WARNING((
590       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
591       SCIF_LOG_OBJECT_REMOTE_DEVICE,
592       "RemoteDevice:0x%x State:0x%x invalid state to continue IO\n",
593       remote_device,
594       sci_base_state_machine_get_state(
595          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
596    ));
597
598    return SCI_FAILURE_INVALID_STATE;
599 }
600
601 /**
602  * @brief This method provides default handling (i.e. returns an error);
603  *        when a user attempts to start a task on a remote device and a
604  *        start task operation is not allowed.
605  *
606  * @param[in]  remote_device This parameter specifies the remote device
607  *             object on which the user is attempting to perform a start
608  *             task operation.
609  * @param[in]  task_request This parameter specifies the task management
610  *             request to be started.
611  *
612  * @return This method returns an indication that start task operations
613  *         are not allowed.
614  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
615  */
616 SCI_STATUS scif_sas_remote_device_default_start_task_handler(
617    SCI_BASE_REMOTE_DEVICE_T * remote_device,
618    SCI_BASE_REQUEST_T       * task_request
619 )
620 {
621    SCIF_LOG_WARNING((
622       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
623       SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
624       "RemoteDevice:0x%x State:0x%x invalid state to start task\n",
625       remote_device,
626       sci_base_state_machine_get_state(
627          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
628    ));
629
630    return SCI_FAILURE_INVALID_STATE;
631 }
632
633 /**
634  * @brief This method provides default handling (i.e. returns an error);
635  *        when a user attempts to complete a task on a remote device and a
636  *        complete task operation is not allowed.
637  *
638  * @param[in]  remote_device This parameter specifies the remote device object
639  *             on which the user is attempting to perform a complete task
640  *             operation.
641  * @param[in]  task_request This parameter specifies the task management
642  *             request to be completed.
643  *
644  * @return This method returns an indication that complete task operations
645  *         are not allowed.
646  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
647  */
648 SCI_STATUS scif_sas_remote_device_default_complete_task_handler(
649    SCI_BASE_REMOTE_DEVICE_T * remote_device,
650    SCI_BASE_REQUEST_T       * task_request
651 )
652 {
653    SCIF_LOG_WARNING((
654       sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
655       SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
656       "RemoteDevice:0x%x State:0x%x invalid state to complete task\n",
657       remote_device,
658       sci_base_state_machine_get_state(
659          &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
660    ));
661
662    return SCI_FAILURE_INVALID_STATE;
663 }
664
665 /**
666  * @brief This method provides default handling (i.e. returns an error);
667  *        for when the core issues a start completion notification and
668  *        such a notification isn't supported.
669  *
670  * @param[in]  remote_device This parameter specifies the remote device object
671  *             for which the completion notification has occured.
672  * @param[in]  completion_status This parameter specifies the status
673  *             of the completion operation.
674  *
675  * @return none.
676  */
677 void scif_sas_remote_device_default_start_complete_handler(
678    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
679    SCI_STATUS                 completion_status
680 )
681 {
682    SCIF_LOG_WARNING((
683       sci_base_object_get_logger(fw_device),
684       SCIF_LOG_OBJECT_REMOTE_DEVICE,
685       "RemoteDevice:0x%x State:0x%x invalid state to start complete\n",
686       fw_device,
687       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
688    ));
689 }
690
691 /**
692  * @brief This method provides default handling (i.e. returns an error);
693  *        for when the core issues a stop completion notification and
694  *        such a notification isn't supported.
695  *
696  * @param[in]  remote_device This parameter specifies the remote device object
697  *             for which the completion notification has occured.
698  * @param[in]  completion_status This parameter specifies the status
699  *             of the completion operation.
700  *
701  * @return none.
702  */
703 void scif_sas_remote_device_default_stop_complete_handler(
704    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
705    SCI_STATUS                 completion_status
706 )
707 {
708    SCIF_LOG_WARNING((
709       sci_base_object_get_logger(fw_device),
710       SCIF_LOG_OBJECT_REMOTE_DEVICE,
711       "RemoteDevice:0x%x State:0x%x invalid state to stop complete\n",
712       fw_device,
713       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
714    ));
715 }
716
717 /**
718  * @brief This method provides default handling (i.e. returns an error);
719  *        for when the core issues a ready notification and such a
720  *        notification isn't supported.
721  *
722  * @param[in]  remote_device This parameter specifies the remote device object
723  *             for which the notification has occured.
724  *
725  * @return none.
726  */
727 void scif_sas_remote_device_default_ready_handler(
728    SCIF_SAS_REMOTE_DEVICE_T * fw_device
729 )
730 {
731    SCIF_LOG_WARNING((
732       sci_base_object_get_logger(fw_device),
733       SCIF_LOG_OBJECT_REMOTE_DEVICE,
734       "RemoteDevice:0x%x State:0x%x invalid state to handle ready\n",
735       fw_device,
736       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
737    ));
738 }
739
740 /**
741  * @brief This method provides default handling (i.e. returns an error);
742  *        for when the core issues a not ready notification and such a
743  *        notification isn't supported.
744  *
745  * @param[in]  remote_device This parameter specifies the remote device object
746  *             for which the notification has occured.
747  *
748  * @return none.
749  */
750 void scif_sas_remote_device_default_not_ready_handler(
751    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
752    U32                        reason_code
753 )
754 {
755    SCIF_LOG_WARNING((
756       sci_base_object_get_logger(fw_device),
757       SCIF_LOG_OBJECT_REMOTE_DEVICE,
758       "RemoteDevice:0x%x State:0x%x invalid state to handle not ready\n",
759       fw_device,
760       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
761    ));
762 }
763
764 #if !defined(DISABLE_WIDE_PORTED_TARGETS)
765 /**
766  * @brief This method provides handling of device start complete duing
767  *        UPDATING_PORT_WIDTH state.
768  *
769  * @param[in]  remote_device This parameter specifies the remote device object
770  *             which is start complete.
771  *
772  * @return none.
773  */
774 static
775 SCI_STATUS scif_sas_remote_device_updating_port_width_state_complete_io_handler(
776    SCI_BASE_REMOTE_DEVICE_T * remote_device,
777    SCI_BASE_REQUEST_T       * io_request
778 )
779 {
780    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
781                                           remote_device;
782    fw_device->request_count--;
783
784    //If the request count is zero, go ahead to update the RNC.
785    if (fw_device->request_count == 0 )
786    {
787       if (fw_device->destination_state == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING)
788       {
789          //if the destination state of this device change to STOPPING, no matter
790          //whether we need to update the port width, just make the device
791          //go to the STOPPING state, the device will be removed anyway.
792          sci_base_state_machine_change_state(
793             &fw_device->parent.state_machine,
794             SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
795          );
796       }
797       else
798       {
799          //stop the device, upon the stop complete callback, start the device again
800          //with the updated port width.
801          scic_remote_device_stop(
802             fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
803       }
804    }
805
806    return SCI_SUCCESS;
807 }
808
809
810 /**
811  * @brief This method provides handling of device start complete duing
812  *        UPDATING_PORT_WIDTH state.
813  *
814  * @param[in]  remote_device This parameter specifies the remote device object
815  *             which is start complete.
816  *
817  * @return none.
818  */
819 static
820 void scif_sas_remote_device_updating_port_width_state_start_complete_handler(
821    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
822    SCI_STATUS                 completion_status
823 )
824 {
825    SCIF_LOG_INFO((
826       sci_base_object_get_logger(fw_device),
827       SCIF_LOG_OBJECT_REMOTE_DEVICE,
828       "RemoteDevice:0x%x updating port width state start complete handler\n",
829       fw_device,
830       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
831    ));
832
833    if ( fw_device->destination_state
834            == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
835    {
836       //if the destination state of this device change to STOPPING, no matter
837       //whether we need to update the port width again, just make the device
838       //go to the STOPPING state.
839       sci_base_state_machine_change_state(
840          &fw_device->parent.state_machine,
841          SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
842       );
843    }
844    else if ( scic_remote_device_get_port_width(fw_device->core_object)
845                 != fw_device->device_port_width
846             && fw_device->device_port_width != 0)
847    {
848       scic_remote_device_stop(
849          fw_device->core_object,
850          SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT
851       );
852    }
853    else
854    {
855       //Port width updating succeeds. Transfer to destination state.
856       sci_base_state_machine_change_state(
857          &fw_device->parent.state_machine,
858          SCI_BASE_REMOTE_DEVICE_STATE_READY
859       );
860    }
861 }
862
863 /**
864  * @brief This method provides handling of device stop complete duing
865  *        UPDATING_PORT_WIDTH state.
866  *
867  * @param[in]  remote_device This parameter specifies the remote device object
868  *             which is stop complete.
869  *
870  * @return none.
871  */
872 static
873 void scif_sas_remote_device_updating_port_width_state_stop_complete_handler(
874    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
875    SCI_STATUS                 completion_status
876 )
877 {
878    SCIF_LOG_INFO((
879       sci_base_object_get_logger(fw_device),
880       SCIF_LOG_OBJECT_REMOTE_DEVICE,
881       "RemoteDevice:0x%x updating port width state stop complete handler\n",
882       fw_device,
883       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
884    ));
885
886    if ( fw_device->destination_state
887            == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
888    {
889       //Device directly transits to STOPPED STATE from UPDATING_PORT_WIDTH state,
890       fw_device->domain->device_start_count--;
891
892       //if the destination state of this device change to STOPPING, no matter
893       //whether we need to update the port width again, just make the device
894       //go to the STOPPED state.
895       sci_base_state_machine_change_state(
896          &fw_device->parent.state_machine,
897          SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
898       );
899    }
900    else
901    {
902       scic_remote_device_set_port_width(
903          fw_device->core_object,
904          fw_device->device_port_width
905       );
906
907       //Device stop complete, means the RNC has been destructed. Now we need to
908       //start core device so the RNC with updated port width will be posted.
909       scic_remote_device_start(
910          fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
911    }
912 }
913
914 /**
915  * @brief This method provides handling (i.e. returns an error);
916  *        when a user attempts to stop a remote device during the updating
917  *        port width state, it will record the destination state for this
918  *        device to be STOPPING, instead of usually READY state.
919  *
920  * @param[in]  remote_device This parameter specifies the remote device object
921  *             on which the user is attempting to perform a stop operation.
922  *
923  * @return This method always return SCI_SUCCESS.
924  */
925 static
926 SCI_STATUS scif_sas_remote_device_updating_port_width_state_stop_handler(
927    SCI_BASE_REMOTE_DEVICE_T * remote_device
928 )
929 {
930    SCIF_SAS_REMOTE_DEVICE_T * fw_device =
931       (SCIF_SAS_REMOTE_DEVICE_T *)remote_device;
932
933    SCIF_LOG_INFO((
934       sci_base_object_get_logger(fw_device),
935       SCIF_LOG_OBJECT_REMOTE_DEVICE,
936       "RemoteDevice:0x%x updating port width state stop handler\n",
937       fw_device,
938       sci_base_state_machine_get_state(&fw_device->parent.state_machine)
939    ));
940
941    //Can't stop the device right now. Remember the pending stopping request.
942    //When exit the UPDATING_PORT_WIDTH state, we will check this variable
943    //to decide which state to go.
944    fw_device->destination_state =
945       SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING;
946
947    return SCI_SUCCESS;
948 }
949
950 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
951
952 #define scif_sas_remote_device_stopping_complete_io_handler   \
953         scif_sas_remote_device_ready_operational_complete_io_handler
954 #define scif_sas_remote_device_stopping_complete_task_handler \
955         scif_sas_remote_device_ready_operational_complete_task_handler
956
957 SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
958 scif_sas_remote_device_state_handler_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] =
959 {
960    // SCI_BASE_REMOTE_DEVICE_STATE_INITIAL
961    {
962       {
963          scif_sas_remote_device_default_start_handler,
964          scif_sas_remote_device_default_stop_handler,
965          scif_sas_remote_device_default_fail_handler,
966          scif_sas_remote_device_default_destruct_handler,
967          scif_sas_remote_device_default_reset_handler,
968          scif_sas_remote_device_default_reset_complete_handler,
969          scif_sas_remote_device_default_start_io_handler,
970          scif_sas_remote_device_default_complete_io_handler,
971          scif_sas_remote_device_default_continue_io_handler,
972          scif_sas_remote_device_default_start_task_handler,
973          scif_sas_remote_device_default_complete_task_handler
974       },
975       scif_sas_remote_device_default_start_complete_handler,
976       scif_sas_remote_device_default_stop_complete_handler,
977       scif_sas_remote_device_default_ready_handler,
978       scif_sas_remote_device_default_not_ready_handler,
979       scif_sas_remote_device_default_start_io_handler,
980       scif_sas_remote_device_default_complete_high_priority_io_handler
981    },
982    // SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
983    {
984       {
985          scif_sas_remote_device_stopped_start_handler,
986          scif_sas_remote_device_default_stop_handler,
987          scif_sas_remote_device_default_fail_handler,
988          scif_sas_remote_device_stopped_destruct_handler,
989          scif_sas_remote_device_default_reset_handler,
990          scif_sas_remote_device_default_reset_complete_handler,
991          scif_sas_remote_device_default_start_io_handler,
992          scif_sas_remote_device_default_complete_io_handler,
993          scif_sas_remote_device_default_continue_io_handler,
994          scif_sas_remote_device_default_start_task_handler,
995          scif_sas_remote_device_default_complete_task_handler
996       },
997       scif_sas_remote_device_default_start_complete_handler,
998       scif_sas_remote_device_default_stop_complete_handler,
999       scif_sas_remote_device_default_ready_handler,
1000       scif_sas_remote_device_default_not_ready_handler,
1001       scif_sas_remote_device_default_start_io_handler,
1002       scif_sas_remote_device_default_complete_high_priority_io_handler
1003    },
1004    // SCI_BASE_REMOTE_DEVICE_STATE_STARTING
1005    {
1006       {
1007          scif_sas_remote_device_default_start_handler,
1008          scif_sas_remote_device_default_stop_handler,
1009          scif_sas_remote_device_default_fail_handler,
1010          scif_sas_remote_device_default_destruct_handler,
1011          scif_sas_remote_device_default_reset_handler,
1012          scif_sas_remote_device_default_reset_complete_handler,
1013          scif_sas_remote_device_default_start_io_handler,
1014          scif_sas_remote_device_default_complete_io_handler,
1015          scif_sas_remote_device_default_continue_io_handler,
1016          scif_sas_remote_device_default_start_task_handler,
1017          scif_sas_remote_device_default_complete_task_handler
1018       },
1019       scif_sas_remote_device_default_start_complete_handler,
1020       scif_sas_remote_device_default_stop_complete_handler,
1021       scif_sas_remote_device_default_ready_handler,
1022       scif_sas_remote_device_default_not_ready_handler,
1023       scif_sas_remote_device_default_start_io_handler,
1024       scif_sas_remote_device_default_complete_high_priority_io_handler
1025    },
1026    // SCI_BASE_REMOTE_DEVICE_STATE_READY - see substate handlers
1027    {
1028       {
1029          scif_sas_remote_device_default_start_handler,
1030          scif_sas_remote_device_default_stop_handler,
1031          scif_sas_remote_device_default_fail_handler,
1032          scif_sas_remote_device_default_destruct_handler,
1033          scif_sas_remote_device_default_reset_handler,
1034          scif_sas_remote_device_default_reset_complete_handler,
1035          scif_sas_remote_device_default_start_io_handler,
1036          scif_sas_remote_device_default_complete_io_handler,
1037          scif_sas_remote_device_default_continue_io_handler,
1038          scif_sas_remote_device_default_start_task_handler,
1039          scif_sas_remote_device_default_complete_task_handler
1040       },
1041       scif_sas_remote_device_default_start_complete_handler,
1042       scif_sas_remote_device_default_stop_complete_handler,
1043       scif_sas_remote_device_default_ready_handler,
1044       scif_sas_remote_device_default_not_ready_handler,
1045       scif_sas_remote_device_default_start_io_handler,
1046       scif_sas_remote_device_default_complete_high_priority_io_handler
1047    },
1048    // SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1049    {
1050       {
1051          scif_sas_remote_device_default_start_handler,
1052          scif_sas_remote_device_default_stop_handler,
1053          scif_sas_remote_device_default_fail_handler,
1054          scif_sas_remote_device_default_destruct_handler,
1055          scif_sas_remote_device_default_reset_handler,
1056          scif_sas_remote_device_default_reset_complete_handler,
1057          scif_sas_remote_device_default_start_io_handler,
1058          scif_sas_remote_device_stopping_complete_io_handler,
1059          scif_sas_remote_device_default_continue_io_handler,
1060          scif_sas_remote_device_default_start_task_handler,
1061          scif_sas_remote_device_stopping_complete_task_handler
1062       },
1063       scif_sas_remote_device_default_start_complete_handler,
1064       scif_sas_remote_device_stopping_stop_complete_handler,
1065       scif_sas_remote_device_default_ready_handler,
1066       scif_sas_remote_device_default_not_ready_handler,
1067       scif_sas_remote_device_default_start_io_handler,
1068       scif_sas_remote_device_stopping_complete_high_priority_io_handler
1069    },
1070    // SCI_BASE_REMOTE_DEVICE_STATE_FAILED
1071    {
1072       {
1073          scif_sas_remote_device_default_start_handler,
1074          scif_sas_remote_device_failed_stop_handler,
1075          scif_sas_remote_device_default_fail_handler,
1076          scif_sas_remote_device_default_destruct_handler,
1077          scif_sas_remote_device_default_reset_handler,
1078          scif_sas_remote_device_default_reset_complete_handler,
1079          scif_sas_remote_device_default_start_io_handler,
1080          scif_sas_remote_device_default_complete_io_handler,
1081          scif_sas_remote_device_default_continue_io_handler,
1082          scif_sas_remote_device_default_start_task_handler,
1083          scif_sas_remote_device_default_complete_task_handler
1084       },
1085       scif_sas_remote_device_default_start_complete_handler,
1086       scif_sas_remote_device_default_stop_complete_handler,
1087       scif_sas_remote_device_default_ready_handler,
1088       scif_sas_remote_device_default_not_ready_handler,
1089       scif_sas_remote_device_default_start_io_handler,
1090       scif_sas_remote_device_default_complete_high_priority_io_handler
1091    },
1092    // SCI_BASE_REMOTE_DEVICE_STATE_RESETTING - is unused by framework
1093    {
1094       {
1095          scif_sas_remote_device_default_start_handler,
1096          scif_sas_remote_device_default_stop_handler,
1097          scif_sas_remote_device_default_fail_handler,
1098          scif_sas_remote_device_default_destruct_handler,
1099          scif_sas_remote_device_default_reset_handler,
1100          scif_sas_remote_device_default_reset_complete_handler,
1101          scif_sas_remote_device_default_start_io_handler,
1102          scif_sas_remote_device_default_complete_io_handler,
1103          scif_sas_remote_device_default_continue_io_handler,
1104          scif_sas_remote_device_default_start_task_handler,
1105          scif_sas_remote_device_default_complete_task_handler
1106       },
1107       scif_sas_remote_device_default_start_complete_handler,
1108       scif_sas_remote_device_default_stop_complete_handler,
1109       scif_sas_remote_device_default_ready_handler,
1110       scif_sas_remote_device_default_not_ready_handler,
1111       scif_sas_remote_device_default_start_io_handler,
1112       scif_sas_remote_device_default_complete_high_priority_io_handler
1113    },
1114 #if !defined(DISABLE_WIDE_PORTED_TARGETS)
1115    // SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH
1116    {
1117       {
1118          scif_sas_remote_device_default_start_handler,
1119          scif_sas_remote_device_updating_port_width_state_stop_handler,
1120          scif_sas_remote_device_default_fail_handler,
1121          scif_sas_remote_device_default_destruct_handler,
1122          scif_sas_remote_device_default_reset_handler,
1123          scif_sas_remote_device_default_reset_complete_handler,
1124          scif_sas_remote_device_default_start_io_handler,
1125          scif_sas_remote_device_updating_port_width_state_complete_io_handler,
1126          scif_sas_remote_device_default_continue_io_handler,
1127          scif_sas_remote_device_default_start_task_handler,
1128          scif_sas_remote_device_default_complete_task_handler
1129       },
1130       scif_sas_remote_device_updating_port_width_state_start_complete_handler,
1131       scif_sas_remote_device_updating_port_width_state_stop_complete_handler,
1132       scif_sas_remote_device_default_ready_handler,
1133       scif_sas_remote_device_default_not_ready_handler,
1134       scif_sas_remote_device_default_start_io_handler,
1135       scif_sas_remote_device_default_complete_high_priority_io_handler
1136    },
1137 #endif
1138    // SCI_BASE_REMOTE_DEVICE_STATE_FINAL
1139    {
1140       {
1141          scif_sas_remote_device_default_start_handler,
1142          scif_sas_remote_device_default_stop_handler,
1143          scif_sas_remote_device_default_fail_handler,
1144          scif_sas_remote_device_default_destruct_handler,
1145          scif_sas_remote_device_default_reset_handler,
1146          scif_sas_remote_device_default_reset_complete_handler,
1147          scif_sas_remote_device_default_start_io_handler,
1148          scif_sas_remote_device_default_complete_io_handler,
1149          scif_sas_remote_device_default_continue_io_handler,
1150          scif_sas_remote_device_default_start_task_handler,
1151          scif_sas_remote_device_default_complete_task_handler
1152       },
1153       scif_sas_remote_device_default_start_complete_handler,
1154       scif_sas_remote_device_default_stop_complete_handler,
1155       scif_sas_remote_device_default_ready_handler,
1156       scif_sas_remote_device_default_not_ready_handler,
1157       scif_sas_remote_device_default_start_io_handler,
1158       scif_sas_remote_device_default_complete_high_priority_io_handler
1159    }
1160 };
1161