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.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
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
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.
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.
56 #include "intel_ata.h"
57 #include "intel_sata.h"
58 #include "intel_sat.h"
59 #include "sci_base_state.h"
60 #include "scic_remote_device.h"
61 #include "scic_sds_controller.h"
62 #include "scic_sds_port.h"
63 #include "scic_sds_remote_device.h"
64 #include "scic_sds_request.h"
65 #include "sci_environment.h"
67 #include "scu_event_codes.h"
70 * This method will perform the STP request completion processing common to IO
71 * requests and task requests of all types
72 * @device: This parameter specifies the device for which the request is being
74 * @request: This parameter specifies the request being completed.
76 * This method returns an indication as to whether the request processing
77 * completed successfully.
79 static enum sci_status
scic_sds_stp_remote_device_complete_request(
80 struct scic_sds_remote_device
*device
,
81 struct scic_sds_request
*request
)
83 enum sci_status status
;
85 status
= scic_sds_io_request_complete(request
);
87 if (status
== SCI_SUCCESS
) {
88 status
= scic_sds_port_complete_io(
89 device
->owning_port
, device
, request
);
91 if (status
== SCI_SUCCESS
) {
92 scic_sds_remote_device_decrement_request_count(device
);
93 if (request
->sci_status
== SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
) {
95 * This request causes hardware error, device needs to be Lun Reset.
96 * So here we force the state machine to IDLE state so the rest IOs
97 * can reach RNC state handler, these IOs will be completed by RNC with
98 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */
99 sci_base_state_machine_change_state(
100 &device
->ready_substate_machine
,
101 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
103 } else if (scic_sds_remote_device_get_request_count(device
) == 0) {
104 sci_base_state_machine_change_state(
105 &device
->ready_substate_machine
,
106 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
112 if (status
!= SCI_SUCCESS
)
113 dev_err(scirdev_to_dev(device
),
114 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
115 "could not complete\n",
126 * *****************************************************************************
127 * * STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
128 * ***************************************************************************** */
131 * This is the READY NCQ substate handler to start task management request. In
132 * this routine, we suspend and resume the RNC.
133 * @device: The target device a task management request towards to.
134 * @request: The task request.
136 * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to
137 * let controller_start_task_handler know that the controller can't post TC for
138 * task request yet, instead, when RNC gets resumed, a controller_continue_task
139 * callback will be called.
141 static enum sci_status
scic_sds_stp_remote_device_ready_substate_start_request_handler(
142 struct scic_sds_remote_device
*device
,
143 struct scic_sds_request
*request
)
145 enum sci_status status
;
147 /* Will the port allow the io request to start? */
148 status
= device
->owning_port
->state_handlers
->start_io_handler(
149 device
->owning_port
, device
, request
);
150 if (status
!= SCI_SUCCESS
)
153 status
= scic_sds_remote_node_context_start_task(device
->rnc
, request
);
154 if (status
!= SCI_SUCCESS
)
157 status
= request
->state_handlers
->start_handler(request
);
158 if (status
!= SCI_SUCCESS
)
162 * Note: If the remote device state is not IDLE this will replace
163 * the request that probably resulted in the task management request.
165 device
->working_request
= request
;
166 sci_base_state_machine_change_state(&device
->ready_substate_machine
,
167 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
);
170 * The remote node context must cleanup the TCi to NCQ mapping table.
171 * The only way to do this correctly is to either write to the TLCR
172 * register or to invalidate and repost the RNC. In either case the
173 * remote node context state machine will take the correct action when
174 * the remote node context is suspended and later resumed.
176 scic_sds_remote_node_context_suspend(device
->rnc
,
177 SCI_SOFTWARE_SUSPENSION
, NULL
, NULL
);
178 scic_sds_remote_node_context_resume(device
->rnc
,
179 scic_sds_remote_device_continue_request
,
183 scic_sds_remote_device_start_request(device
, request
, status
);
185 * We need to let the controller start request handler know that it can't
186 * post TC yet. We will provide a callback function to post TC when RNC gets
189 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS
;
193 * *****************************************************************************
194 * * STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
195 * ***************************************************************************** */
198 * This method will handle the start io operation for a sata device that is in
199 * the command idle state. - Evalute the type of IO request to be started -
200 * If its an NCQ request change to NCQ substate - If its any other command
201 * change to the CMD substate
205 * If this is a softreset we may want to have a different substate.
208 static enum sci_status
scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
209 struct scic_sds_remote_device
*sci_dev
,
210 struct scic_sds_request
*request
)
212 enum sci_status status
;
213 struct isci_request
*isci_request
=
214 (struct isci_request
*)sci_object_get_association(request
);
217 /* Will the port allow the io request to start? */
218 status
= sci_dev
->owning_port
->state_handlers
->start_io_handler(
219 sci_dev
->owning_port
, sci_dev
, request
);
220 if (status
!= SCI_SUCCESS
)
223 status
= scic_sds_remote_node_context_start_io(sci_dev
->rnc
, request
);
224 if (status
!= SCI_SUCCESS
)
227 status
= request
->state_handlers
->start_handler(request
);
228 if (status
!= SCI_SUCCESS
)
231 if (isci_sata_get_sat_protocol(isci_request
) == SAT_PROTOCOL_FPDMA
) {
232 sci_base_state_machine_change_state(&sci_dev
->ready_substate_machine
,
233 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
);
235 sci_dev
->working_request
= request
;
236 sci_base_state_machine_change_state(&sci_dev
->ready_substate_machine
,
237 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
);
240 scic_sds_remote_device_start_request(sci_dev
, request
, status
);
247 * @[in]: device The device received event.
248 * @[in]: event_code The event code.
250 * This method will handle the event for a sata device that is in the idle
251 * state. We pick up suspension events to handle specifically to this state. We
252 * resume the RNC right away. enum sci_status
254 static enum sci_status
scic_sds_stp_remote_device_ready_idle_substate_event_handler(
255 struct scic_sds_remote_device
*sci_dev
,
258 enum sci_status status
;
260 status
= scic_sds_remote_device_general_event_handler(sci_dev
, event_code
);
262 if (status
== SCI_SUCCESS
) {
263 if (scu_get_event_type(event_code
) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
264 || scu_get_event_type(event_code
) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX
) {
265 status
= scic_sds_remote_node_context_resume(
266 sci_dev
->rnc
, NULL
, NULL
);
275 * *****************************************************************************
276 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
277 * ***************************************************************************** */
279 static enum sci_status
scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
280 struct scic_sds_remote_device
*sci_dev
,
281 struct scic_sds_request
*request
)
283 enum sci_status status
;
284 struct isci_request
*isci_request
=
285 (struct isci_request
*)sci_object_get_association(request
);
287 if (isci_sata_get_sat_protocol(isci_request
) == SAT_PROTOCOL_FPDMA
) {
288 status
= sci_dev
->owning_port
->state_handlers
->start_io_handler(
289 sci_dev
->owning_port
,
293 if (status
== SCI_SUCCESS
) {
294 status
= scic_sds_remote_node_context_start_io(
298 if (status
== SCI_SUCCESS
)
299 status
= request
->state_handlers
->start_handler(request
);
301 scic_sds_remote_device_start_request(sci_dev
,
306 status
= SCI_FAILURE_INVALID_STATE
;
313 * This method will handle events received while the STP device is in the ready
315 * @sci_dev: This is the device object that is receiving the event.
316 * @event_code: The event code to process.
321 static enum sci_status
scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
322 struct scic_sds_remote_device
*sci_dev
,
325 enum sci_status status
;
326 struct sata_fis_header
*frame_header
;
328 status
= scic_sds_unsolicited_frame_control_get_header(
329 &(scic_sds_remote_device_get_controller(sci_dev
)->uf_control
),
331 (void **)&frame_header
334 if (status
== SCI_SUCCESS
) {
335 if (frame_header
->fis_type
== SATA_FIS_TYPE_SETDEVBITS
&&
336 (frame_header
->status
& ATA_STATUS_REG_ERROR_BIT
)) {
337 sci_dev
->not_ready_reason
=
338 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED
;
341 * / @todo Check sactive and complete associated IO
345 sci_base_state_machine_change_state(
346 &sci_dev
->ready_substate_machine
,
347 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
349 } else if (frame_header
->fis_type
== SATA_FIS_TYPE_REGD2H
&&
350 (frame_header
->status
& ATA_STATUS_REG_ERROR_BIT
)) {
353 * Some devices return D2H FIS when an NCQ error is detected.
354 * Treat this like an SDB error FIS ready reason.
356 sci_dev
->not_ready_reason
=
357 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED
;
359 sci_base_state_machine_change_state(
360 &sci_dev
->ready_substate_machine
,
361 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
364 status
= SCI_FAILURE
;
367 scic_sds_controller_release_frame(
368 scic_sds_remote_device_get_controller(sci_dev
), frame_index
376 * *****************************************************************************
377 * * STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
378 * ***************************************************************************** */
381 * This device is already handling a command it can not accept new commands
382 * until this one is complete.
388 static enum sci_status
scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
389 struct scic_sds_remote_device
*device
,
390 struct scic_sds_request
*request
)
392 return SCI_FAILURE_INVALID_STATE
;
395 static enum sci_status
scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
396 struct scic_sds_remote_device
*sci_dev
,
399 enum sci_status status
;
401 status
= scic_sds_remote_node_context_suspend(
402 sci_dev
->rnc
, suspend_type
, NULL
, NULL
408 static enum sci_status
scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
409 struct scic_sds_remote_device
*sci_dev
,
412 enum sci_status status
;
415 * / The device doe not process any UF received from the hardware while
416 * / in this state. All unsolicited frames are forwarded to the io request
418 status
= scic_sds_io_request_frame_handler(
419 sci_dev
->working_request
,
428 * *****************************************************************************
429 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
430 * ***************************************************************************** */
433 * *****************************************************************************
434 * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS
435 * ***************************************************************************** */
438 * *****************************************************************************
439 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
440 * ***************************************************************************** */
441 static enum sci_status
scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
442 struct scic_sds_remote_device
*device
,
443 struct scic_sds_request
*request
)
445 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
;
451 * This method will perform the STP request (both io or task) completion
452 * processing for await reset state.
453 * @device: This parameter specifies the device for which the request is being
455 * @request: This parameter specifies the request being completed.
457 * This method returns an indication as to whether the request processing
458 * completed successfully.
460 static enum sci_status
scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
461 struct scic_sds_remote_device
*device
,
462 struct scic_sds_request
*request
)
464 struct scic_sds_request
*sci_req
= (struct scic_sds_request
*)request
;
465 enum sci_status status
;
467 status
= scic_sds_io_request_complete(sci_req
);
469 if (status
== SCI_SUCCESS
) {
470 status
= scic_sds_port_complete_io(
471 device
->owning_port
, device
, sci_req
474 if (status
== SCI_SUCCESS
)
475 scic_sds_remote_device_decrement_request_count(device
);
478 if (status
!= SCI_SUCCESS
)
479 dev_err(scirdev_to_dev(device
),
480 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
481 "could not complete\n",
491 #if !defined(DISABLE_ATAPI)
493 * *****************************************************************************
494 * * STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
495 * ***************************************************************************** */
499 * @[in]: device The device received event.
500 * @[in]: event_code The event code.
502 * This method will handle the event for a ATAPI device that is in the ATAPI
503 * ERROR state. We pick up suspension events to handle specifically to this
504 * state. We resume the RNC right away. We then complete the outstanding IO to
505 * this device. enum sci_status
507 enum sci_status
scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
508 struct scic_sds_remote_device
*sci_dev
,
511 enum sci_status status
;
513 status
= scic_sds_remote_device_general_event_handler(sci_dev
, event_code
);
515 if (status
== SCI_SUCCESS
) {
516 if (scu_get_event_type(event_code
) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
517 || scu_get_event_type(event_code
) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX
) {
518 status
= scic_sds_remote_node_context_resume(
520 sci_dev
->working_request
->state_handlers
->parent
.complete_handler
,
521 (void *)sci_dev
->working_request
528 #endif /* !defined(DISABLE_ATAPI) */
530 /* --------------------------------------------------------------------------- */
532 static const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table
[] = {
533 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
] = {
534 .start_handler
= scic_sds_remote_device_default_start_handler
,
535 .stop_handler
= scic_sds_remote_device_ready_state_stop_handler
,
536 .fail_handler
= scic_sds_remote_device_default_fail_handler
,
537 .destruct_handler
= scic_sds_remote_device_default_destruct_handler
,
538 .reset_handler
= scic_sds_remote_device_ready_state_reset_handler
,
539 .reset_complete_handler
= scic_sds_remote_device_default_reset_complete_handler
,
540 .start_io_handler
= scic_sds_stp_remote_device_ready_idle_substate_start_io_handler
,
541 .complete_io_handler
= scic_sds_remote_device_default_complete_request_handler
,
542 .continue_io_handler
= scic_sds_remote_device_default_continue_request_handler
,
543 .start_task_handler
= scic_sds_stp_remote_device_ready_substate_start_request_handler
,
544 .complete_task_handler
= scic_sds_remote_device_default_complete_request_handler
,
545 .suspend_handler
= scic_sds_remote_device_default_suspend_handler
,
546 .resume_handler
= scic_sds_remote_device_default_resume_handler
,
547 .event_handler
= scic_sds_stp_remote_device_ready_idle_substate_event_handler
,
548 .frame_handler
= scic_sds_remote_device_default_frame_handler
550 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
] = {
551 .start_handler
= scic_sds_remote_device_default_start_handler
,
552 .stop_handler
= scic_sds_remote_device_ready_state_stop_handler
,
553 .fail_handler
= scic_sds_remote_device_default_fail_handler
,
554 .destruct_handler
= scic_sds_remote_device_default_destruct_handler
,
555 .reset_handler
= scic_sds_remote_device_ready_state_reset_handler
,
556 .reset_complete_handler
= scic_sds_remote_device_default_reset_complete_handler
,
557 .start_io_handler
= scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler
,
558 .complete_io_handler
= scic_sds_stp_remote_device_complete_request
,
559 .continue_io_handler
= scic_sds_remote_device_default_continue_request_handler
,
560 .start_task_handler
= scic_sds_stp_remote_device_ready_substate_start_request_handler
,
561 .complete_task_handler
= scic_sds_stp_remote_device_complete_request
,
562 .suspend_handler
= scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler
,
563 .resume_handler
= scic_sds_remote_device_default_resume_handler
,
564 .event_handler
= scic_sds_remote_device_general_event_handler
,
565 .frame_handler
= scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
567 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
] = {
568 .start_handler
= scic_sds_remote_device_default_start_handler
,
569 .stop_handler
= scic_sds_remote_device_ready_state_stop_handler
,
570 .fail_handler
= scic_sds_remote_device_default_fail_handler
,
571 .destruct_handler
= scic_sds_remote_device_default_destruct_handler
,
572 .reset_handler
= scic_sds_remote_device_ready_state_reset_handler
,
573 .reset_complete_handler
= scic_sds_remote_device_default_reset_complete_handler
,
574 .start_io_handler
= scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler
,
575 .complete_io_handler
= scic_sds_stp_remote_device_complete_request
,
576 .continue_io_handler
= scic_sds_remote_device_default_continue_request_handler
,
577 .start_task_handler
= scic_sds_stp_remote_device_ready_substate_start_request_handler
,
578 .complete_task_handler
= scic_sds_stp_remote_device_complete_request
,
579 .suspend_handler
= scic_sds_remote_device_default_suspend_handler
,
580 .resume_handler
= scic_sds_remote_device_default_resume_handler
,
581 .event_handler
= scic_sds_remote_device_general_event_handler
,
582 .frame_handler
= scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
584 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
] = {
585 .start_handler
= scic_sds_remote_device_default_start_handler
,
586 .stop_handler
= scic_sds_remote_device_ready_state_stop_handler
,
587 .fail_handler
= scic_sds_remote_device_default_fail_handler
,
588 .destruct_handler
= scic_sds_remote_device_default_destruct_handler
,
589 .reset_handler
= scic_sds_remote_device_ready_state_reset_handler
,
590 .reset_complete_handler
= scic_sds_remote_device_default_reset_complete_handler
,
591 .start_io_handler
= scic_sds_remote_device_default_start_request_handler
,
592 .complete_io_handler
= scic_sds_stp_remote_device_complete_request
,
593 .continue_io_handler
= scic_sds_remote_device_default_continue_request_handler
,
594 .start_task_handler
= scic_sds_stp_remote_device_ready_substate_start_request_handler
,
595 .complete_task_handler
= scic_sds_stp_remote_device_complete_request
,
596 .suspend_handler
= scic_sds_remote_device_default_suspend_handler
,
597 .resume_handler
= scic_sds_remote_device_default_resume_handler
,
598 .event_handler
= scic_sds_remote_device_general_event_handler
,
599 .frame_handler
= scic_sds_remote_device_general_frame_handler
601 #if !defined(DISABLE_ATAPI)
602 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
] = {
603 .start_handler
= scic_sds_remote_device_default_start_handler
,
604 .stop_handler
= scic_sds_remote_device_ready_state_stop_handler
,
605 .fail_handler
= scic_sds_remote_device_default_fail_handler
,
606 .destruct_handler
= scic_sds_remote_device_default_destruct_handler
,
607 .reset_handler
= scic_sds_remote_device_ready_state_reset_handler
,
608 .reset_complete_handler
= scic_sds_remote_device_default_reset_complete_handler
,
609 .start_io_handler
= scic_sds_remote_device_default_start_request_handler
,
610 .complete_io_handler
= scic_sds_stp_remote_device_complete_request
,
611 .continue_io_handler
= scic_sds_remote_device_default_continue_request_handler
,
612 .start_task_handler
= scic_sds_stp_remote_device_ready_substate_start_request_handler
,
613 .complete_task_handler
= scic_sds_stp_remote_device_complete_request
,
614 .suspend_handler
= scic_sds_remote_device_default_suspend_handler
,
615 .resume_handler
= scic_sds_remote_device_default_resume_handler
,
616 .event_handler
= scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler
,
617 .frame_handler
= scic_sds_remote_device_general_frame_handler
620 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
] = {
621 .start_handler
= scic_sds_remote_device_default_start_handler
,
622 .stop_handler
= scic_sds_remote_device_ready_state_stop_handler
,
623 .fail_handler
= scic_sds_remote_device_default_fail_handler
,
624 .destruct_handler
= scic_sds_remote_device_default_destruct_handler
,
625 .reset_handler
= scic_sds_remote_device_ready_state_reset_handler
,
626 .reset_complete_handler
= scic_sds_remote_device_default_reset_complete_handler
,
627 .start_io_handler
= scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler
,
628 .complete_io_handler
= scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler
,
629 .continue_io_handler
= scic_sds_remote_device_default_continue_request_handler
,
630 .start_task_handler
= scic_sds_stp_remote_device_ready_substate_start_request_handler
,
631 .complete_task_handler
= scic_sds_stp_remote_device_complete_request
,
632 .suspend_handler
= scic_sds_remote_device_default_suspend_handler
,
633 .resume_handler
= scic_sds_remote_device_default_resume_handler
,
634 .event_handler
= scic_sds_remote_device_general_event_handler
,
635 .frame_handler
= scic_sds_remote_device_general_frame_handler
640 * *****************************************************************************
641 * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
642 * ***************************************************************************** */
645 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *user_cookie
)
647 struct scic_sds_remote_device
*sci_dev
= user_cookie
;
648 struct isci_remote_device
*idev
= sci_object_get_association(sci_dev
);
649 struct scic_sds_controller
*scic
= scic_sds_remote_device_get_controller(sci_dev
);
650 struct isci_host
*ihost
= sci_object_get_association(scic
);
653 * For NCQ operation we do not issue a
654 * scic_cb_remote_device_not_ready(). As a result, avoid sending
655 * the ready notification.
657 if (sci_dev
->ready_substate_machine
.previous_state_id
!=
658 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
)
659 isci_remote_device_ready(ihost
, idev
);
663 * *****************************************************************************
664 * * STP REMOTE DEVICE READY IDLE SUBSTATE
665 * ***************************************************************************** */
669 * @device: This is the SCI base object which is cast into a
670 * struct scic_sds_remote_device object.
673 static void scic_sds_stp_remote_device_ready_idle_substate_enter(
674 struct sci_base_object
*device
)
676 struct scic_sds_remote_device
*sci_dev
;
678 sci_dev
= (struct scic_sds_remote_device
*)device
;
682 scic_sds_stp_remote_device_ready_substate_handler_table
,
683 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
686 sci_dev
->working_request
= NULL
;
688 if (scic_sds_remote_node_context_is_ready(sci_dev
->rnc
)) {
690 * Since the RNC is ready, it's alright to finish completion
691 * processing (e.g. signal the remote device is ready). */
692 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
696 scic_sds_remote_node_context_resume(
698 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler
,
704 static void scic_sds_stp_remote_device_ready_cmd_substate_enter(struct sci_base_object
*object
)
706 struct scic_sds_remote_device
*sci_dev
= container_of(object
, typeof(*sci_dev
),
708 struct scic_sds_controller
*scic
= scic_sds_remote_device_get_controller(sci_dev
);
709 struct isci_host
*ihost
= sci_object_get_association(scic
);
710 struct isci_remote_device
*idev
= sci_object_get_association(sci_dev
);
712 BUG_ON(sci_dev
->working_request
== NULL
);
714 SET_STATE_HANDLER(sci_dev
,
715 scic_sds_stp_remote_device_ready_substate_handler_table
,
716 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
);
718 isci_remote_device_not_ready(ihost
, idev
,
719 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
);
722 static void scic_sds_stp_remote_device_ready_ncq_substate_enter(struct sci_base_object
*object
)
724 struct scic_sds_remote_device
*sci_dev
= container_of(object
, typeof(*sci_dev
),
726 SET_STATE_HANDLER(sci_dev
,
727 scic_sds_stp_remote_device_ready_substate_handler_table
,
728 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
);
731 static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base_object
*object
)
733 struct scic_sds_remote_device
*sci_dev
= container_of(object
, typeof(*sci_dev
),
735 struct scic_sds_controller
*scic
= scic_sds_remote_device_get_controller(sci_dev
);
736 struct isci_host
*ihost
= sci_object_get_association(scic
);
737 struct isci_remote_device
*idev
= sci_object_get_association(sci_dev
);
739 SET_STATE_HANDLER(sci_dev
,
740 scic_sds_stp_remote_device_ready_substate_handler_table
,
741 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
);
743 if (sci_dev
->not_ready_reason
==
744 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED
)
745 isci_remote_device_not_ready(ihost
, idev
, sci_dev
->not_ready_reason
);
749 * *****************************************************************************
750 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
751 * ***************************************************************************** */
754 * The enter routine to READY AWAIT RESET substate.
755 * @device: This is the SCI base object which is cast into a
756 * struct scic_sds_remote_device object.
759 static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
760 struct sci_base_object
*device
)
762 struct scic_sds_remote_device
*sci_dev
;
764 sci_dev
= (struct scic_sds_remote_device
*)device
;
768 scic_sds_stp_remote_device_ready_substate_handler_table
,
769 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
773 #if !defined(DISABLE_ATAPI)
775 * *****************************************************************************
776 * * STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
777 * ***************************************************************************** */
780 * The enter routine to READY ATAPI ERROR substate.
781 * @device: This is the SCI base object which is cast into a
782 * struct scic_sds_remote_device object.
785 void scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
786 struct sci_base_object
*device
)
788 struct scic_sds_remote_device
*sci_dev
;
790 sci_dev
= (struct scic_sds_remote_device
*)device
;
794 scic_sds_stp_remote_device_ready_substate_handler_table
,
795 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
798 #endif /* !defined(DISABLE_ATAPI) */
800 /* --------------------------------------------------------------------------- */
802 const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table
[] = {
803 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
] = {
804 .enter_state
= scic_sds_stp_remote_device_ready_idle_substate_enter
,
806 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
] = {
807 .enter_state
= scic_sds_stp_remote_device_ready_cmd_substate_enter
,
809 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
] = {
810 .enter_state
= scic_sds_stp_remote_device_ready_ncq_substate_enter
,
812 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
] = {
813 .enter_state
= scic_sds_stp_remote_device_ready_ncq_error_substate_enter
,
815 #if !defined(DISABLE_ATAPI)
816 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
] = {
817 .enter_state
= scic_sds_stp_remote_device_ready_atapi_error_substate_enter
,
820 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
] = {
821 .enter_state
= scic_sds_stp_remote_device_ready_await_reset_substate_enter
,