isci: Intel(R) C600 Series Chipset Storage Control Unit Driver
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / scsi / isci / core / scic_sds_stp_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 the ready substate handlers for an STP device.
58  *
59  *
60  */
61
62 #include "intel_sat.h"
63 #include "intel_ata.h"
64 #include "intel_sata.h"
65 #include "sci_environment.h"
66 #include "scic_remote_device.h"
67 #include "scic_user_callback.h"
68 #include "scic_sds_controller.h"
69 #include "scic_sds_port.h"
70 #include "scic_sds_remote_device.h"
71 #include "scic_sds_request.h"
72 #include "scu_event_codes.h"
73
74 /**
75  * This method will perform the STP request completion processing common to IO
76  *    requests and task requests of all types
77  * @device: This parameter specifies the device for which the request is being
78  *    completed.
79  * @request: This parameter specifies the request being completed.
80  *
81  * This method returns an indication as to whether the request processing
82  * completed successfully.
83  */
84 static enum sci_status scic_sds_stp_remote_device_complete_request(
85         struct sci_base_remote_device *device,
86         struct sci_base_request *request)
87 {
88         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
89         struct scic_sds_request *the_request = (struct scic_sds_request *)request;
90         enum sci_status status;
91
92         status = scic_sds_io_request_complete(the_request);
93
94         if (status == SCI_SUCCESS) {
95                 status = scic_sds_port_complete_io(
96                         this_device->owning_port, this_device, the_request
97                         );
98
99                 if (status == SCI_SUCCESS) {
100                         scic_sds_remote_device_decrement_request_count(this_device);
101                         if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
102                                 /*
103                                  * This request causes hardware error, device needs to be Lun Reset.
104                                  * So here we force the state machine to IDLE state so the rest IOs
105                                  * can reach RNC state handler, these IOs will be completed by RNC with
106                                  * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */
107                                 sci_base_state_machine_change_state(
108                                         &this_device->ready_substate_machine,
109                                         SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
110                                         );
111                         } else if (scic_sds_remote_device_get_request_count(this_device) == 0) {
112                                 sci_base_state_machine_change_state(
113                                         &this_device->ready_substate_machine,
114                                         SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
115                                         );
116                         }
117                 }
118         }
119
120         if (status != SCI_SUCCESS)
121                 dev_err(scirdev_to_dev(this_device),
122                         "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
123                         "could not complete\n",
124                         __func__,
125                         this_device->owning_port,
126                         this_device,
127                         the_request,
128                         status);
129
130         return status;
131 }
132
133 /*
134  * *****************************************************************************
135  * *  STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
136  * ***************************************************************************** */
137
138 /**
139  * This is the READY NCQ substate handler to start task management request. In
140  *    this routine, we suspend and resume the RNC.
141  * @device: The target device a task management request towards to.
142  * @request: The task request.
143  *
144  * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to
145  * let controller_start_task_handler know that the controller can't post TC for
146  * task request yet, instead, when RNC gets resumed, a controller_continue_task
147  * callback will be called.
148  */
149 static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
150         struct sci_base_remote_device *device,
151         struct sci_base_request *request)
152 {
153         enum sci_status status;
154         struct scic_sds_remote_device *this_device  = (struct scic_sds_remote_device *)device;
155         struct scic_sds_request *this_request = (struct scic_sds_request *)request;
156
157         /* Will the port allow the io request to start? */
158         status = this_device->owning_port->state_handlers->start_io_handler(
159                 this_device->owning_port,
160                 this_device,
161                 this_request
162                 );
163
164         if (SCI_SUCCESS == status) {
165                 status =
166                         scic_sds_remote_node_context_start_task(this_device->rnc, this_request);
167
168                 if (SCI_SUCCESS == status) {
169                         status = this_request->state_handlers->parent.start_handler(request);
170                 }
171
172                 if (status == SCI_SUCCESS) {
173                         /*
174                          * / @note If the remote device state is not IDLE this will replace
175                          * /       the request that probably resulted in the task management
176                          * /       request. */
177                         this_device->working_request = this_request;
178
179                         sci_base_state_machine_change_state(
180                                 &this_device->ready_substate_machine,
181                                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
182                                 );
183
184                         /*
185                          * The remote node context must cleanup the TCi to NCQ mapping table.
186                          * The only way to do this correctly is to either write to the TLCR
187                          * register or to invalidate and repost the RNC. In either case the
188                          * remote node context state machine will take the correct action when
189                          * the remote node context is suspended and later resumed. */
190                         scic_sds_remote_node_context_suspend(
191                                 this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
192
193                         scic_sds_remote_node_context_resume(
194                                 this_device->rnc,
195                                 (SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
196                                 scic_sds_remote_device_continue_request,
197                                 this_device);
198                 }
199
200                 scic_sds_remote_device_start_request(this_device, this_request, status);
201
202                 /*
203                  * We need to let the controller start request handler know that it can't
204                  * post TC yet. We will provide a callback function to post TC when RNC gets
205                  * resumed. */
206                 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
207         }
208
209         return status;
210 }
211
212 /*
213  * *****************************************************************************
214  * *  STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
215  * ***************************************************************************** */
216
217 /**
218  * This method will handle the start io operation for a sata device that is in
219  *    the command idle state. - Evalute the type of IO request to be started -
220  *    If its an NCQ request change to NCQ substate - If its any other command
221  *    change to the CMD substate
222  * @device:
223  * @request:
224  *
225  * If this is a softreset we may want to have a different substate. enum sci_status
226  */
227 static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
228         struct sci_base_remote_device *device,
229         struct sci_base_request *request)
230 {
231         enum sci_status status;
232         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
233         struct scic_sds_request *io_request  = (struct scic_sds_request *)request;
234
235
236         /* Will the port allow the io request to start? */
237         status = this_device->owning_port->state_handlers->start_io_handler(
238                 this_device->owning_port,
239                 this_device,
240                 io_request
241                 );
242
243         if (status == SCI_SUCCESS) {
244                 status =
245                         scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
246
247                 if (status == SCI_SUCCESS) {
248                         status = io_request->state_handlers->parent.start_handler(request);
249                 }
250
251                 if (status == SCI_SUCCESS) {
252                         if (
253                                 scic_cb_request_get_sat_protocol(io_request->user_request)
254                                 == SAT_PROTOCOL_FPDMA
255                                 ) {
256                                 sci_base_state_machine_change_state(
257                                         &this_device->ready_substate_machine,
258                                         SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
259                                         );
260                         } else {
261                                 this_device->working_request = io_request;
262
263                                 sci_base_state_machine_change_state(
264                                         &this_device->ready_substate_machine,
265                                         SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
266                                         );
267                         }
268                 }
269
270                 scic_sds_remote_device_start_request(this_device, io_request, status);
271         }
272
273         return status;
274 }
275
276
277 /**
278  *
279  * @[in]: device The device received event.
280  * @[in]: event_code The event code.
281  *
282  * This method will handle the event for a sata device that is in the idle
283  * state. We pick up suspension events to handle specifically to this state. We
284  * resume the RNC right away. enum sci_status
285  */
286 static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
287         struct scic_sds_remote_device *this_device,
288         u32 event_code)
289 {
290         enum sci_status status;
291
292         status = scic_sds_remote_device_general_event_handler(this_device, event_code);
293
294         if (status == SCI_SUCCESS) {
295                 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
296                     || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
297                         status = scic_sds_remote_node_context_resume(
298                                 this_device->rnc, NULL, NULL);
299                 }
300         }
301
302         return status;
303 }
304
305
306 /*
307  * *****************************************************************************
308  * *  STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
309  * ***************************************************************************** */
310
311 static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
312         struct sci_base_remote_device *device,
313         struct sci_base_request *request)
314 {
315         enum sci_status status;
316         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
317         struct scic_sds_request *io_request  = (struct scic_sds_request *)request;
318
319         if (
320                 scic_cb_request_get_sat_protocol(io_request->user_request)
321                 == SAT_PROTOCOL_FPDMA
322                 ) {
323                 status = this_device->owning_port->state_handlers->start_io_handler(
324                         this_device->owning_port,
325                         this_device,
326                         io_request
327                         );
328
329                 if (status == SCI_SUCCESS) {
330                         status = scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
331
332                         if (status == SCI_SUCCESS) {
333                                 status = io_request->state_handlers->parent.start_handler(request);
334                         }
335
336                         scic_sds_remote_device_start_request(this_device, io_request, status);
337                 }
338         } else {
339                 status = SCI_FAILURE_INVALID_STATE;
340         }
341
342         return status;
343 }
344
345
346 /**
347  * This method will handle events received while the STP device is in the ready
348  *    command substate.
349  * @this_device: This is the device object that is receiving the event.
350  * @event_code: The event code to process.
351  *
352  * enum sci_status
353  */
354
355 static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
356         struct scic_sds_remote_device *this_device,
357         u32 frame_index)
358 {
359         enum sci_status status;
360         struct sata_fis_header *frame_header;
361
362         status = scic_sds_unsolicited_frame_control_get_header(
363                 &(scic_sds_remote_device_get_controller(this_device)->uf_control),
364                 frame_index,
365                 (void **)&frame_header
366                 );
367
368         if (status == SCI_SUCCESS) {
369                 if (
370                         (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS)
371                         && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
372                         ) {
373                         this_device->not_ready_reason =
374                                 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
375
376                         sci_base_state_machine_change_state(
377                                 &this_device->ready_substate_machine,
378                                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
379                                 );
380                 } else {
381                         status = SCI_FAILURE;
382                 }
383
384                 scic_sds_controller_release_frame(
385                         scic_sds_remote_device_get_controller(this_device), frame_index
386                         );
387         }
388
389         return status;
390 }
391
392 /*
393  * *****************************************************************************
394  * *  STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
395  * ***************************************************************************** */
396
397 /**
398  * This device is already handling a command it can not accept new commands
399  *    until this one is complete.
400  * @device:
401  * @request:
402  *
403  * enum sci_status
404  */
405 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
406         struct sci_base_remote_device *device,
407         struct sci_base_request *request)
408 {
409         return SCI_FAILURE_INVALID_STATE;
410 }
411
412 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
413         struct scic_sds_remote_device *this_device,
414         u32 suspend_type)
415 {
416         enum sci_status status;
417
418         status = scic_sds_remote_node_context_suspend(
419                 this_device->rnc, suspend_type, NULL, NULL
420                 );
421
422         return status;
423 }
424
425 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
426         struct scic_sds_remote_device *this_device,
427         u32 frame_index)
428 {
429         enum sci_status status;
430
431         /*
432          * / The device doe not process any UF received from the hardware while
433          * / in this state.  All unsolicited frames are forwarded to the io request
434          * / object. */
435         status = scic_sds_io_request_frame_handler(
436                 this_device->working_request,
437                 frame_index
438                 );
439
440         return status;
441 }
442
443
444 /*
445  * *****************************************************************************
446  * *  STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
447  * ***************************************************************************** */
448
449 /*
450  * *****************************************************************************
451  * *  STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS
452  * ***************************************************************************** */
453
454 /*
455  * *****************************************************************************
456  * *  STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
457  * ***************************************************************************** */
458 static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
459         struct sci_base_remote_device *device,
460         struct sci_base_request *request)
461 {
462         return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
463 }
464
465
466
467 /**
468  * This method will perform the STP request (both io or task) completion
469  *    processing for await reset state.
470  * @device: This parameter specifies the device for which the request is being
471  *    completed.
472  * @request: This parameter specifies the request being completed.
473  *
474  * This method returns an indication as to whether the request processing
475  * completed successfully.
476  */
477 static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
478         struct sci_base_remote_device *device,
479         struct sci_base_request *request)
480 {
481         struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
482         struct scic_sds_request *the_request = (struct scic_sds_request *)request;
483         enum sci_status status;
484
485         status = scic_sds_io_request_complete(the_request);
486
487         if (status == SCI_SUCCESS) {
488                 status = scic_sds_port_complete_io(
489                         this_device->owning_port, this_device, the_request
490                         );
491
492                 if (status == SCI_SUCCESS)
493                         scic_sds_remote_device_decrement_request_count(this_device);
494         }
495
496         if (status != SCI_SUCCESS)
497                 dev_err(scirdev_to_dev(this_device),
498                         "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
499                         "could not complete\n",
500                         __func__,
501                         this_device->owning_port,
502                         this_device,
503                         the_request,
504                         status);
505
506         return status;
507 }
508
509 #if !defined(DISABLE_ATAPI)
510 /*
511  * *****************************************************************************
512  * *  STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
513  * ***************************************************************************** */
514
515 /**
516  *
517  * @[in]: device The device received event.
518  * @[in]: event_code The event code.
519  *
520  * This method will handle the event for a ATAPI device that is in the ATAPI
521  * ERROR state. We pick up suspension events to handle specifically to this
522  * state. We resume the RNC right away. We then complete the outstanding IO to
523  * this device. enum sci_status
524  */
525 enum sci_status scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
526         struct scic_sds_remote_device *this_device,
527         u32 event_code)
528 {
529         enum sci_status status;
530
531         status = scic_sds_remote_device_general_event_handler(this_device, event_code);
532
533         if (status == SCI_SUCCESS) {
534                 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
535                     || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
536                         status = scic_sds_remote_node_context_resume(
537                                 this_device->rnc,
538                                 this_device->working_request->state_handlers->parent.complete_handler,
539                                 (void *)this_device->working_request
540                                 );
541                 }
542         }
543
544         return status;
545 }
546 #endif /* !defined(DISABLE_ATAPI) */
547
548 /* --------------------------------------------------------------------------- */
549
550 struct scic_sds_remote_device_state_handler
551 scic_sds_stp_remote_device_ready_substate_handler_table[
552         SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
553 {
554         /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE */
555         {
556                 {
557                         scic_sds_remote_device_default_start_handler,
558                         scic_sds_remote_device_ready_state_stop_handler,
559                         scic_sds_remote_device_default_fail_handler,
560                         scic_sds_remote_device_default_destruct_handler,
561                         scic_sds_remote_device_ready_state_reset_handler,
562                         scic_sds_remote_device_default_reset_complete_handler,
563                         scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
564                         scic_sds_remote_device_default_complete_request_handler,
565                         scic_sds_remote_device_default_continue_request_handler,
566                         scic_sds_stp_remote_device_ready_substate_start_request_handler,
567                         scic_sds_remote_device_default_complete_request_handler
568                 },
569                 scic_sds_remote_device_default_suspend_handler,
570                 scic_sds_remote_device_default_resume_handler,
571                 scic_sds_stp_remote_device_ready_idle_substate_event_handler,
572                 scic_sds_remote_device_default_frame_handler
573         },
574         /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD */
575         {
576                 {
577                         scic_sds_remote_device_default_start_handler,
578                         scic_sds_remote_device_ready_state_stop_handler,
579                         scic_sds_remote_device_default_fail_handler,
580                         scic_sds_remote_device_default_destruct_handler,
581                         scic_sds_remote_device_ready_state_reset_handler,
582                         scic_sds_remote_device_default_reset_complete_handler,
583                         scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
584                         scic_sds_stp_remote_device_complete_request,
585                         scic_sds_remote_device_default_continue_request_handler,
586                         scic_sds_stp_remote_device_ready_substate_start_request_handler,
587                         scic_sds_stp_remote_device_complete_request,
588                 },
589                 scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
590                 scic_sds_remote_device_default_resume_handler,
591                 scic_sds_remote_device_general_event_handler,
592                 scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
593         },
594         /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ */
595         {
596                 {
597                         scic_sds_remote_device_default_start_handler,
598                         scic_sds_remote_device_ready_state_stop_handler,
599                         scic_sds_remote_device_default_fail_handler,
600                         scic_sds_remote_device_default_destruct_handler,
601                         scic_sds_remote_device_ready_state_reset_handler,
602                         scic_sds_remote_device_default_reset_complete_handler,
603                         scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
604                         scic_sds_stp_remote_device_complete_request,
605                         scic_sds_remote_device_default_continue_request_handler,
606                         scic_sds_stp_remote_device_ready_substate_start_request_handler,
607                         scic_sds_stp_remote_device_complete_request
608                 },
609                 scic_sds_remote_device_default_suspend_handler,
610                 scic_sds_remote_device_default_resume_handler,
611                 scic_sds_remote_device_general_event_handler,
612                 scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
613         },
614         /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR */
615         {
616                 {
617                         scic_sds_remote_device_default_start_handler,
618                         scic_sds_remote_device_ready_state_stop_handler,
619                         scic_sds_remote_device_default_fail_handler,
620                         scic_sds_remote_device_default_destruct_handler,
621                         scic_sds_remote_device_ready_state_reset_handler,
622                         scic_sds_remote_device_default_reset_complete_handler,
623                         scic_sds_remote_device_default_start_request_handler,
624                         scic_sds_stp_remote_device_complete_request,
625                         scic_sds_remote_device_default_continue_request_handler,
626                         scic_sds_stp_remote_device_ready_substate_start_request_handler,
627                         scic_sds_stp_remote_device_complete_request
628                 },
629                 scic_sds_remote_device_default_suspend_handler,
630                 scic_sds_remote_device_default_resume_handler,
631                 scic_sds_remote_device_general_event_handler,
632                 scic_sds_remote_device_general_frame_handler
633         },
634 #if !defined(DISABLE_ATAPI)
635         /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR */
636         {
637                 {
638                         scic_sds_remote_device_default_start_handler,
639                         scic_sds_remote_device_ready_state_stop_handler,
640                         scic_sds_remote_device_default_fail_handler,
641                         scic_sds_remote_device_default_destruct_handler,
642                         scic_sds_remote_device_ready_state_reset_handler,
643                         scic_sds_remote_device_default_reset_complete_handler,
644                         scic_sds_remote_device_default_start_request_handler,
645                         scic_sds_stp_remote_device_complete_request,
646                         scic_sds_remote_device_default_continue_request_handler,
647                         scic_sds_stp_remote_device_ready_substate_start_request_handler,
648                         scic_sds_stp_remote_device_complete_request
649                 },
650                 scic_sds_remote_device_default_suspend_handler,
651                 scic_sds_remote_device_default_resume_handler,
652                 scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler,
653                 scic_sds_remote_device_general_frame_handler
654         },
655 #endif
656         /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET */
657         {
658                 {
659                         scic_sds_remote_device_default_start_handler,
660                         scic_sds_remote_device_ready_state_stop_handler,
661                         scic_sds_remote_device_default_fail_handler,
662                         scic_sds_remote_device_default_destruct_handler,
663                         scic_sds_remote_device_ready_state_reset_handler,
664                         scic_sds_remote_device_default_reset_complete_handler,
665                         scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
666                         scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
667                         scic_sds_remote_device_default_continue_request_handler,
668                         scic_sds_stp_remote_device_ready_substate_start_request_handler,
669                         scic_sds_stp_remote_device_complete_request
670                 },
671                 scic_sds_remote_device_default_suspend_handler,
672                 scic_sds_remote_device_default_resume_handler,
673                 scic_sds_remote_device_general_event_handler,
674                 scic_sds_remote_device_general_frame_handler
675         }
676 };
677
678 /*
679  * This file is provided under a dual BSD/GPLv2 license.  When using or
680  * redistributing this file, you may do so under either license.
681  *
682  * GPL LICENSE SUMMARY
683  *
684  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
685  *
686  * This program is free software; you can redistribute it and/or modify
687  * it under the terms of version 2 of the GNU General Public License as
688  * published by the Free Software Foundation.
689  *
690  * This program is distributed in the hope that it will be useful, but
691  * WITHOUT ANY WARRANTY; without even the implied warranty of
692  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
693  * General Public License for more details.
694  *
695  * You should have received a copy of the GNU General Public License
696  * along with this program; if not, write to the Free Software
697  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
698  * The full GNU General Public License is included in this distribution
699  * in the file called LICENSE.GPL.
700  *
701  * BSD LICENSE
702  *
703  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
704  * All rights reserved.
705  *
706  * Redistribution and use in source and binary forms, with or without
707  * modification, are permitted provided that the following conditions
708  * are met:
709  *
710  *   * Redistributions of source code must retain the above copyright
711  *     notice, this list of conditions and the following disclaimer.
712  *   * Redistributions in binary form must reproduce the above copyright
713  *     notice, this list of conditions and the following disclaimer in
714  *     the documentation and/or other materials provided with the
715  *     distribution.
716  *   * Neither the name of Intel Corporation nor the names of its
717  *     contributors may be used to endorse or promote products derived
718  *     from this software without specific prior written permission.
719  *
720  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
721  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
722  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
723  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
724  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
725  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
726  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
727  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
728  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
729  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
730  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
731  */
732
733 #include "sci_base_state.h"
734 #include "scic_remote_device.h"
735 #include "scic_user_callback.h"
736 #include "scic_sds_controller.h"
737 #include "scic_sds_port.h"
738 #include "scic_sds_remote_device.h"
739 #include "sci_util.h"
740 #include "sci_environment.h"
741
742 /*
743  * *****************************************************************************
744  * *  STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
745  * ***************************************************************************** */
746
747 static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
748         void *user_cookie)
749 {
750         struct scic_sds_remote_device *this_device;
751
752         this_device = (struct scic_sds_remote_device *)user_cookie;
753
754         /*
755          * For NCQ operation we do not issue a
756          * scic_cb_remote_device_not_ready().  As a result, avoid sending
757          * the ready notification. */
758         if (this_device->ready_substate_machine.previous_state_id
759             != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) {
760                 scic_cb_remote_device_ready(
761                         scic_sds_remote_device_get_controller(this_device), this_device
762                         );
763         }
764 }
765
766 /*
767  * *****************************************************************************
768  * *  STP REMOTE DEVICE READY IDLE SUBSTATE
769  * ***************************************************************************** */
770
771 /**
772  *
773  * @device: This is the SCI base object which is cast into a
774  *    struct scic_sds_remote_device object.
775  *
776  */
777 static void scic_sds_stp_remote_device_ready_idle_substate_enter(
778         struct sci_base_object *device)
779 {
780         struct scic_sds_remote_device *this_device;
781
782         this_device = (struct scic_sds_remote_device *)device;
783
784         SET_STATE_HANDLER(
785                 this_device,
786                 scic_sds_stp_remote_device_ready_substate_handler_table,
787                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
788                 );
789
790         this_device->working_request = NULL;
791
792         if (scic_sds_remote_node_context_is_ready(this_device->rnc)) {
793                 /*
794                  * Since the RNC is ready, it's alright to finish completion
795                  * processing (e.g. signal the remote device is ready). */
796                 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
797                         this_device
798                         );
799         } else {
800                 scic_sds_remote_node_context_resume(
801                         this_device->rnc,
802                         scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
803                         this_device
804                         );
805         }
806 }
807
808 /*
809  * *****************************************************************************
810  * *  STP REMOTE DEVICE READY CMD SUBSTATE
811  * ***************************************************************************** */
812
813 /**
814  *
815  * @device: This is the SCI base object which is cast into a
816  *    struct scic_sds_remote_device object.
817  *
818  */
819 static void scic_sds_stp_remote_device_ready_cmd_substate_enter(
820         struct sci_base_object *device)
821 {
822         struct scic_sds_remote_device *this_device;
823
824         this_device = (struct scic_sds_remote_device *)device;
825
826         BUG_ON(this_device->working_request == NULL);
827
828         SET_STATE_HANDLER(
829                 this_device,
830                 scic_sds_stp_remote_device_ready_substate_handler_table,
831                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
832                 );
833
834         scic_cb_remote_device_not_ready(
835                 scic_sds_remote_device_get_controller(this_device),
836                 this_device,
837                 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
838                 );
839 }
840
841 /*
842  * *****************************************************************************
843  * *  STP REMOTE DEVICE READY NCQ SUBSTATE
844  * ***************************************************************************** */
845
846 /**
847  *
848  * @device: This is the SCI base object which is cast into a
849  *    struct scic_sds_remote_device object.
850  *
851  */
852 static void scic_sds_stp_remote_device_ready_ncq_substate_enter(
853         struct sci_base_object *device)
854 {
855         struct scic_sds_remote_device *this_device;
856
857         this_device = (struct scic_sds_remote_device *)device;
858
859         SET_STATE_HANDLER(
860                 this_device,
861                 scic_sds_stp_remote_device_ready_substate_handler_table,
862                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
863                 );
864 }
865
866 /*
867  * *****************************************************************************
868  * *  STP REMOTE DEVICE READY NCQ ERROR SUBSTATE
869  * ***************************************************************************** */
870
871 /**
872  *
873  * @device: This is the SCI base object which is cast into a
874  *    struct scic_sds_remote_device object.
875  *
876  */
877 static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
878         struct sci_base_object *device)
879 {
880         struct scic_sds_remote_device *this_device;
881
882         this_device = (struct scic_sds_remote_device *)device;
883
884         SET_STATE_HANDLER(
885                 this_device,
886                 scic_sds_stp_remote_device_ready_substate_handler_table,
887                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
888                 );
889
890         if (this_device->not_ready_reason ==
891             SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) {
892                 scic_cb_remote_device_not_ready(
893                         scic_sds_remote_device_get_controller(this_device),
894                         this_device,
895                         this_device->not_ready_reason
896                         );
897         }
898 }
899
900 /*
901  * *****************************************************************************
902  * *  STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
903  * ***************************************************************************** */
904
905 /**
906  * The enter routine to READY AWAIT RESET substate.
907  * @device: This is the SCI base object which is cast into a
908  *    struct scic_sds_remote_device object.
909  *
910  */
911 static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
912         struct sci_base_object *device)
913 {
914         struct scic_sds_remote_device *this_device;
915
916         this_device = (struct scic_sds_remote_device *)device;
917
918         SET_STATE_HANDLER(
919                 this_device,
920                 scic_sds_stp_remote_device_ready_substate_handler_table,
921                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
922                 );
923 }
924
925 #if !defined(DISABLE_ATAPI)
926 /*
927  * *****************************************************************************
928  * *  STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
929  * ***************************************************************************** */
930
931 /**
932  * The enter routine to READY ATAPI ERROR substate.
933  * @device: This is the SCI base object which is cast into a
934  *    struct scic_sds_remote_device object.
935  *
936  */
937 void scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
938         struct sci_base_object *device)
939 {
940         struct scic_sds_remote_device *this_device;
941
942         this_device = (struct scic_sds_remote_device *)device;
943
944         SET_STATE_HANDLER(
945                 this_device,
946                 scic_sds_stp_remote_device_ready_substate_handler_table,
947                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
948                 );
949 }
950 #endif /* !defined(DISABLE_ATAPI) */
951
952 /* --------------------------------------------------------------------------- */
953
954 const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = {
955         [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
956                 .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
957         },
958         [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
959                 .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
960         },
961         [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
962                 .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
963         },
964         [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
965                 .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
966         },
967 #if !defined(DISABLE_ATAPI)
968         [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR] = {
969                 .enter_state = scic_sds_stp_remote_device_ready_atapi_error_substate_enter,
970         },
971 #endif
972         [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
973                 .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
974         },
975 };