isci: Intel(R) C600 Series Chipset Storage Control Unit Driver
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / isci / core / scic_sds_smp_remote_device.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  *   * Neither the name of Intel Corporation nor the names of its
40  *     contributors may be used to endorse or promote products derived
41  *     from this software without specific prior written permission.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54  */
55
56 /**
57  * This file contains This file contains the ready substate handlers for a SMP
58  *    device.
59  *
60  *
61  */
62
63 #include "sci_environment.h"
64 #include "scic_user_callback.h"
65 #include "scic_sds_remote_device.h"
66 #include "scic_sds_controller.h"
67 #include "scic_sds_port.h"
68 #include "scic_sds_request.h"
69 #include "scu_event_codes.h"
70 #include "scu_task_context.h"
71
72
73 /*
74  * *****************************************************************************
75  * *  SMP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
76  * ***************************************************************************** */
77
78 /**
79  *
80  * @[in]: device The device the io is sent to.
81  * @[in]: request The io to start.
82  *
83  * This method will handle the start io operation for a SMP device that is in
84  * the idle state. enum sci_status
85  */
86 static enum sci_status scic_sds_smp_remote_device_ready_idle_substate_start_io_handler(
87         struct sci_base_remote_device *device,
88         struct sci_base_request *request)
89 {
90         enum sci_status status;
91         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
92         struct scic_sds_request *io_request  = (struct scic_sds_request *)request;
93
94         /* Will the port allow the io request to start? */
95         status = this_device->owning_port->state_handlers->start_io_handler(
96                 this_device->owning_port,
97                 this_device,
98                 io_request
99                 );
100
101         if (status == SCI_SUCCESS) {
102                 status =
103                         scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
104
105                 if (status == SCI_SUCCESS) {
106                         status = scic_sds_request_start(io_request);
107                 }
108
109                 if (status == SCI_SUCCESS) {
110                         this_device->working_request = io_request;
111
112                         sci_base_state_machine_change_state(
113                                 &this_device->ready_substate_machine,
114                                 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
115                                 );
116                 }
117
118                 scic_sds_remote_device_start_request(this_device, io_request, status);
119         }
120
121         return status;
122 }
123
124
125 /*
126  * ******************************************************************************
127  * * SMP REMOTE DEVICE READY SUBSTATE CMD HANDLERS
128  * ****************************************************************************** */
129 /**
130  *
131  * @device: This is the device object that is receiving the IO.
132  * @request: The io to start.
133  *
134  * This device is already handling a command it can not accept new commands
135  * until this one is complete. enum sci_status
136  */
137 static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler(
138         struct sci_base_remote_device *device,
139         struct sci_base_request *request)
140 {
141         return SCI_FAILURE_INVALID_STATE;
142 }
143
144
145 /**
146  * this is the complete_io_handler for smp device at ready cmd substate.
147  * @device: This is the device object that is receiving the IO.
148  * @request: The io to start.
149  *
150  * enum sci_status
151  */
152 static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler(
153         struct sci_base_remote_device *device,
154         struct sci_base_request *request)
155 {
156         enum sci_status status;
157         struct scic_sds_remote_device *this_device;
158         struct scic_sds_request *the_request;
159
160         this_device = (struct scic_sds_remote_device *)device;
161         the_request = (struct scic_sds_request *)request;
162
163         status = scic_sds_io_request_complete(the_request);
164
165         if (status == SCI_SUCCESS) {
166                 status = scic_sds_port_complete_io(
167                         this_device->owning_port, this_device, the_request);
168
169                 if (status == SCI_SUCCESS) {
170                         scic_sds_remote_device_decrement_request_count(this_device);
171                         sci_base_state_machine_change_state(
172                                 &this_device->ready_substate_machine,
173                                 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
174                                 );
175                 } else
176                         dev_err(scirdev_to_dev(this_device),
177                                 "%s: SCIC SDS Remote Device 0x%p io request "
178                                 "0x%p could not be completd on the port 0x%p "
179                                 "failed with status %d.\n",
180                                 __func__,
181                                 this_device,
182                                 the_request,
183                                 this_device->owning_port,
184                                 status);
185         }
186
187         return status;
188 }
189
190 /**
191  * This is frame handler for smp device ready cmd substate.
192  * @this_device: This is the device object that is receiving the frame.
193  * @frame_index: The index for the frame received.
194  *
195  * enum sci_status
196  */
197 static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handler(
198         struct scic_sds_remote_device *this_device,
199         u32 frame_index)
200 {
201         enum sci_status status;
202
203         /*
204          * / The device does not process any UF received from the hardware while
205          * / in this state.  All unsolicited frames are forwarded to the io request
206          * / object. */
207         status = scic_sds_io_request_frame_handler(
208                 this_device->working_request,
209                 frame_index
210                 );
211
212         return status;
213 }
214
215 /* --------------------------------------------------------------------------- */
216
217 struct scic_sds_remote_device_state_handler
218 scic_sds_smp_remote_device_ready_substate_handler_table[
219         SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
220 {
221         /* SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE */
222         {
223                 {
224                         scic_sds_remote_device_default_start_handler,
225                         scic_sds_remote_device_ready_state_stop_handler,
226                         scic_sds_remote_device_default_fail_handler,
227                         scic_sds_remote_device_default_destruct_handler,
228                         scic_sds_remote_device_default_reset_handler,
229                         scic_sds_remote_device_default_reset_complete_handler,
230                         scic_sds_smp_remote_device_ready_idle_substate_start_io_handler,
231                         scic_sds_remote_device_default_complete_request_handler,
232                         scic_sds_remote_device_default_continue_request_handler,
233                         scic_sds_remote_device_default_start_request_handler,
234                         scic_sds_remote_device_default_complete_request_handler
235                 },
236                 scic_sds_remote_device_default_suspend_handler,
237                 scic_sds_remote_device_default_resume_handler,
238                 scic_sds_remote_device_general_event_handler,
239                 scic_sds_remote_device_default_frame_handler
240         },
241         /* SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD */
242         {
243                 {
244                         scic_sds_remote_device_default_start_handler,
245                         scic_sds_remote_device_ready_state_stop_handler,
246                         scic_sds_remote_device_default_fail_handler,
247                         scic_sds_remote_device_default_destruct_handler,
248                         scic_sds_remote_device_default_reset_handler,
249                         scic_sds_remote_device_default_reset_complete_handler,
250                         scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler,
251                         scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler,
252                         scic_sds_remote_device_default_continue_request_handler,
253                         scic_sds_remote_device_default_start_request_handler,
254                         scic_sds_remote_device_default_complete_request_handler
255                 },
256                 scic_sds_remote_device_default_suspend_handler,
257                 scic_sds_remote_device_default_resume_handler,
258                 scic_sds_remote_device_general_event_handler,
259                 scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
260         }
261 };
262 /*
263  * This file is provided under a dual BSD/GPLv2 license.  When using or
264  * redistributing this file, you may do so under either license.
265  *
266  * GPL LICENSE SUMMARY
267  *
268  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
269  *
270  * This program is free software; you can redistribute it and/or modify
271  * it under the terms of version 2 of the GNU General Public License as
272  * published by the Free Software Foundation.
273  *
274  * This program is distributed in the hope that it will be useful, but
275  * WITHOUT ANY WARRANTY; without even the implied warranty of
276  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
277  * General Public License for more details.
278  *
279  * You should have received a copy of the GNU General Public License
280  * along with this program; if not, write to the Free Software
281  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
282  * The full GNU General Public License is included in this distribution
283  * in the file called LICENSE.GPL.
284  *
285  * BSD LICENSE
286  *
287  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
288  * All rights reserved.
289  *
290  * Redistribution and use in source and binary forms, with or without
291  * modification, are permitted provided that the following conditions
292  * are met:
293  *
294  *   * Redistributions of source code must retain the above copyright
295  *     notice, this list of conditions and the following disclaimer.
296  *   * Redistributions in binary form must reproduce the above copyright
297  *     notice, this list of conditions and the following disclaimer in
298  *     the documentation and/or other materials provided with the
299  *     distribution.
300  *   * Neither the name of Intel Corporation nor the names of its
301  *     contributors may be used to endorse or promote products derived
302  *     from this software without specific prior written permission.
303  *
304  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
305  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
307  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
308  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
309  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
310  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
311  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
312  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
313  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
314  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
315  */
316
317 /**
318  * This file contains the enter and exit functions for the
319  *    struct scic_sds_remote_device ready substate machine.
320  *
321  *
322  */
323
324 #include "scic_remote_device.h"
325 #include "scic_user_callback.h"
326 #include "scic_sds_remote_device.h"
327 #include "scic_sds_controller.h"
328 #include "scic_sds_port.h"
329 #include "sci_util.h"
330 #include "sci_environment.h"
331
332 /**
333  *
334  * @object: This is the struct sci_base_object which is cast into a
335  *    struct scic_sds_remote_device.
336  *
337  * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method.
338  * This method sets the ready cmd substate handlers and reports the device as
339  * ready. none
340  */
341 static void scic_sds_smp_remote_device_ready_idle_substate_enter(
342         struct sci_base_object *object)
343 {
344         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
345
346         SET_STATE_HANDLER(
347                 this_device,
348                 scic_sds_smp_remote_device_ready_substate_handler_table,
349                 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
350                 );
351
352         scic_cb_remote_device_ready(
353                 scic_sds_remote_device_get_controller(this_device), this_device);
354 }
355
356 /**
357  *
358  * @object: This is the struct sci_base_object which is cast into a
359  *    struct scic_sds_remote_device.
360  *
361  * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This
362  * method sets the remote device objects ready cmd substate handlers, and
363  * notify core user that the device is not ready. none
364  */
365 static void scic_sds_smp_remote_device_ready_cmd_substate_enter(
366         struct sci_base_object *object)
367 {
368         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
369
370         BUG_ON(this_device->working_request == NULL);
371
372         SET_STATE_HANDLER(
373                 this_device,
374                 scic_sds_smp_remote_device_ready_substate_handler_table,
375                 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
376                 );
377
378         scic_cb_remote_device_not_ready(
379                 scic_sds_remote_device_get_controller(this_device),
380                 this_device,
381                 SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED
382                 );
383 }
384
385 /**
386  *
387  * @object: This is the struct sci_base_object which is cast into a
388  *    struct scic_sds_remote_device.
389  *
390  * This is the SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_CMD exit method. none
391  */
392 static void scic_sds_smp_remote_device_ready_cmd_substate_exit(
393         struct sci_base_object *object)
394 {
395         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
396
397         this_device->working_request = NULL;
398 }
399
400 /* --------------------------------------------------------------------------- */
401
402 const struct sci_base_state scic_sds_smp_remote_device_ready_substate_table[] = {
403         [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
404                 .enter_state = scic_sds_smp_remote_device_ready_idle_substate_enter,
405         },
406         [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
407                 .enter_state = scic_sds_smp_remote_device_ready_cmd_substate_enter,
408                 .exit_state  = scic_sds_smp_remote_device_ready_cmd_substate_exit,
409         },
410 };