]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/scsi/isci/core/scic_sds_stp_remote_device.c
isci: handle cases where a d2h fis is used report an ncq error
[mirror_ubuntu-bionic-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 #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"
66 #include "sci_util.h"
67 #include "scu_event_codes.h"
68
69 /**
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
73 * completed.
74 * @request: This parameter specifies the request being completed.
75 *
76 * This method returns an indication as to whether the request processing
77 * completed successfully.
78 */
79 static enum sci_status scic_sds_stp_remote_device_complete_request(
80 struct sci_base_remote_device *device,
81 struct sci_base_request *request)
82 {
83 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
84 struct scic_sds_request *the_request = (struct scic_sds_request *)request;
85 enum sci_status status;
86
87 status = scic_sds_io_request_complete(the_request);
88
89 if (status == SCI_SUCCESS) {
90 status = scic_sds_port_complete_io(
91 this_device->owning_port, this_device, the_request
92 );
93
94 if (status == SCI_SUCCESS) {
95 scic_sds_remote_device_decrement_request_count(this_device);
96 if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
97 /*
98 * This request causes hardware error, device needs to be Lun Reset.
99 * So here we force the state machine to IDLE state so the rest IOs
100 * can reach RNC state handler, these IOs will be completed by RNC with
101 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */
102 sci_base_state_machine_change_state(
103 &this_device->ready_substate_machine,
104 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
105 );
106 } else if (scic_sds_remote_device_get_request_count(this_device) == 0) {
107 sci_base_state_machine_change_state(
108 &this_device->ready_substate_machine,
109 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
110 );
111 }
112 }
113 }
114
115 if (status != SCI_SUCCESS)
116 dev_err(scirdev_to_dev(this_device),
117 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
118 "could not complete\n",
119 __func__,
120 this_device->owning_port,
121 this_device,
122 the_request,
123 status);
124
125 return status;
126 }
127
128 /*
129 * *****************************************************************************
130 * * STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
131 * ***************************************************************************** */
132
133 /**
134 * This is the READY NCQ substate handler to start task management request. In
135 * this routine, we suspend and resume the RNC.
136 * @device: The target device a task management request towards to.
137 * @request: The task request.
138 *
139 * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to
140 * let controller_start_task_handler know that the controller can't post TC for
141 * task request yet, instead, when RNC gets resumed, a controller_continue_task
142 * callback will be called.
143 */
144 static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
145 struct sci_base_remote_device *device,
146 struct sci_base_request *request)
147 {
148 enum sci_status status;
149 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
150 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
151
152 /* Will the port allow the io request to start? */
153 status = this_device->owning_port->state_handlers->start_io_handler(
154 this_device->owning_port,
155 this_device,
156 this_request
157 );
158
159 if (SCI_SUCCESS == status) {
160 status =
161 scic_sds_remote_node_context_start_task(this_device->rnc, this_request);
162
163 if (SCI_SUCCESS == status) {
164 status = this_request->state_handlers->parent.start_handler(request);
165 }
166
167 if (status == SCI_SUCCESS) {
168 /*
169 * / @note If the remote device state is not IDLE this will replace
170 * / the request that probably resulted in the task management
171 * / request. */
172 this_device->working_request = this_request;
173
174 sci_base_state_machine_change_state(
175 &this_device->ready_substate_machine,
176 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
177 );
178
179 /*
180 * The remote node context must cleanup the TCi to NCQ mapping table.
181 * The only way to do this correctly is to either write to the TLCR
182 * register or to invalidate and repost the RNC. In either case the
183 * remote node context state machine will take the correct action when
184 * the remote node context is suspended and later resumed. */
185 scic_sds_remote_node_context_suspend(
186 this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
187
188 scic_sds_remote_node_context_resume(
189 this_device->rnc,
190 scic_sds_remote_device_continue_request,
191 this_device);
192 }
193
194 scic_sds_remote_device_start_request(this_device, this_request, status);
195
196 /*
197 * We need to let the controller start request handler know that it can't
198 * post TC yet. We will provide a callback function to post TC when RNC gets
199 * resumed. */
200 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
201 }
202
203 return status;
204 }
205
206 /*
207 * *****************************************************************************
208 * * STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
209 * ***************************************************************************** */
210
211 /**
212 * This method will handle the start io operation for a sata device that is in
213 * the command idle state. - Evalute the type of IO request to be started -
214 * If its an NCQ request change to NCQ substate - If its any other command
215 * change to the CMD substate
216 * @device:
217 * @request:
218 *
219 * If this is a softreset we may want to have a different substate.
220 * enum sci_status
221 */
222 static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
223 struct sci_base_remote_device *base_device,
224 struct sci_base_request *base_request)
225 {
226 enum sci_status status;
227 struct scic_sds_remote_device *device =
228 (struct scic_sds_remote_device *)&base_device->parent;
229 struct scic_sds_request *sds_request =
230 (struct scic_sds_request *)&base_request->parent;
231 struct isci_request *isci_request =
232 (struct isci_request *)sci_object_get_association(sds_request);
233
234
235 /* Will the port allow the io request to start? */
236 status = device->owning_port->state_handlers->start_io_handler(
237 device->owning_port,
238 device,
239 sds_request);
240
241 if (status == SCI_SUCCESS) {
242 status =
243 scic_sds_remote_node_context_start_io(device->rnc,
244 sds_request);
245
246 if (status == SCI_SUCCESS)
247 status =
248 sds_request->state_handlers->
249 parent.start_handler(base_request);
250
251 if (status == SCI_SUCCESS) {
252 if (isci_sata_get_sat_protocol(isci_request) ==
253 SAT_PROTOCOL_FPDMA)
254 sci_base_state_machine_change_state(
255 &device->ready_substate_machine,
256 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
257 else {
258 device->working_request = sds_request;
259
260 sci_base_state_machine_change_state(
261 &device->ready_substate_machine,
262 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
263 }
264 }
265
266 scic_sds_remote_device_start_request(device,
267 sds_request,
268 status);
269 }
270
271 return status;
272 }
273
274
275 /**
276 *
277 * @[in]: device The device received event.
278 * @[in]: event_code The event code.
279 *
280 * This method will handle the event for a sata device that is in the idle
281 * state. We pick up suspension events to handle specifically to this state. We
282 * resume the RNC right away. enum sci_status
283 */
284 static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
285 struct scic_sds_remote_device *this_device,
286 u32 event_code)
287 {
288 enum sci_status status;
289
290 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
291
292 if (status == SCI_SUCCESS) {
293 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
294 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
295 status = scic_sds_remote_node_context_resume(
296 this_device->rnc, NULL, NULL);
297 }
298 }
299
300 return status;
301 }
302
303
304 /*
305 * *****************************************************************************
306 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
307 * ***************************************************************************** */
308
309 static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
310 struct sci_base_remote_device *base_device,
311 struct sci_base_request *base_request)
312 {
313 enum sci_status status;
314 struct scic_sds_remote_device *device =
315 (struct scic_sds_remote_device *)&base_device->parent;
316 struct scic_sds_request *sds_request =
317 (struct scic_sds_request *)&base_request->parent;
318 struct isci_request *isci_request =
319 (struct isci_request *)sci_object_get_association(sds_request);
320
321 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
322 status = device->owning_port->state_handlers->start_io_handler(
323 device->owning_port,
324 device,
325 sds_request);
326
327 if (status == SCI_SUCCESS) {
328 status = scic_sds_remote_node_context_start_io(
329 device->rnc,
330 sds_request);
331
332 if (status == SCI_SUCCESS)
333 status = sds_request->state_handlers->
334 parent.start_handler(base_request);
335
336 scic_sds_remote_device_start_request(device,
337 sds_request,
338 status);
339 }
340 } else
341 status = SCI_FAILURE_INVALID_STATE;
342
343 return status;
344 }
345
346
347 /**
348 * This method will handle events received while the STP device is in the ready
349 * command substate.
350 * @this_device: This is the device object that is receiving the event.
351 * @event_code: The event code to process.
352 *
353 * enum sci_status
354 */
355
356 static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
357 struct scic_sds_remote_device *this_device,
358 u32 frame_index)
359 {
360 enum sci_status status;
361 struct sata_fis_header *frame_header;
362
363 status = scic_sds_unsolicited_frame_control_get_header(
364 &(scic_sds_remote_device_get_controller(this_device)->uf_control),
365 frame_index,
366 (void **)&frame_header
367 );
368
369 if (status == SCI_SUCCESS) {
370 if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
371 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
372 this_device->not_ready_reason =
373 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
374
375 /*
376 * / @todo Check sactive and complete associated IO
377 * if any.
378 */
379
380 sci_base_state_machine_change_state(
381 &this_device->ready_substate_machine,
382 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
383 );
384 } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H &&
385 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
386
387 /*
388 * Some devices return D2H FIS when an NCQ error is detected.
389 * Treat this like an SDB error FIS ready reason.
390 */
391 this_device->not_ready_reason =
392 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
393
394 sci_base_state_machine_change_state(
395 &this_device->ready_substate_machine,
396 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
397 );
398 } else {
399 status = SCI_FAILURE;
400 }
401
402 scic_sds_controller_release_frame(
403 scic_sds_remote_device_get_controller(this_device), frame_index
404 );
405 }
406
407 return status;
408 }
409
410 /*
411 * *****************************************************************************
412 * * STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
413 * ***************************************************************************** */
414
415 /**
416 * This device is already handling a command it can not accept new commands
417 * until this one is complete.
418 * @device:
419 * @request:
420 *
421 * enum sci_status
422 */
423 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
424 struct sci_base_remote_device *device,
425 struct sci_base_request *request)
426 {
427 return SCI_FAILURE_INVALID_STATE;
428 }
429
430 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
431 struct scic_sds_remote_device *this_device,
432 u32 suspend_type)
433 {
434 enum sci_status status;
435
436 status = scic_sds_remote_node_context_suspend(
437 this_device->rnc, suspend_type, NULL, NULL
438 );
439
440 return status;
441 }
442
443 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
444 struct scic_sds_remote_device *this_device,
445 u32 frame_index)
446 {
447 enum sci_status status;
448
449 /*
450 * / The device doe not process any UF received from the hardware while
451 * / in this state. All unsolicited frames are forwarded to the io request
452 * / object. */
453 status = scic_sds_io_request_frame_handler(
454 this_device->working_request,
455 frame_index
456 );
457
458 return status;
459 }
460
461
462 /*
463 * *****************************************************************************
464 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
465 * ***************************************************************************** */
466
467 /*
468 * *****************************************************************************
469 * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS
470 * ***************************************************************************** */
471
472 /*
473 * *****************************************************************************
474 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
475 * ***************************************************************************** */
476 static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
477 struct sci_base_remote_device *device,
478 struct sci_base_request *request)
479 {
480 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
481 }
482
483
484
485 /**
486 * This method will perform the STP request (both io or task) completion
487 * processing for await reset state.
488 * @device: This parameter specifies the device for which the request is being
489 * completed.
490 * @request: This parameter specifies the request being completed.
491 *
492 * This method returns an indication as to whether the request processing
493 * completed successfully.
494 */
495 static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
496 struct sci_base_remote_device *device,
497 struct sci_base_request *request)
498 {
499 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
500 struct scic_sds_request *the_request = (struct scic_sds_request *)request;
501 enum sci_status status;
502
503 status = scic_sds_io_request_complete(the_request);
504
505 if (status == SCI_SUCCESS) {
506 status = scic_sds_port_complete_io(
507 this_device->owning_port, this_device, the_request
508 );
509
510 if (status == SCI_SUCCESS)
511 scic_sds_remote_device_decrement_request_count(this_device);
512 }
513
514 if (status != SCI_SUCCESS)
515 dev_err(scirdev_to_dev(this_device),
516 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
517 "could not complete\n",
518 __func__,
519 this_device->owning_port,
520 this_device,
521 the_request,
522 status);
523
524 return status;
525 }
526
527 #if !defined(DISABLE_ATAPI)
528 /*
529 * *****************************************************************************
530 * * STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
531 * ***************************************************************************** */
532
533 /**
534 *
535 * @[in]: device The device received event.
536 * @[in]: event_code The event code.
537 *
538 * This method will handle the event for a ATAPI device that is in the ATAPI
539 * ERROR state. We pick up suspension events to handle specifically to this
540 * state. We resume the RNC right away. We then complete the outstanding IO to
541 * this device. enum sci_status
542 */
543 enum sci_status scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
544 struct scic_sds_remote_device *this_device,
545 u32 event_code)
546 {
547 enum sci_status status;
548
549 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
550
551 if (status == SCI_SUCCESS) {
552 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
553 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
554 status = scic_sds_remote_node_context_resume(
555 this_device->rnc,
556 this_device->working_request->state_handlers->parent.complete_handler,
557 (void *)this_device->working_request
558 );
559 }
560 }
561
562 return status;
563 }
564 #endif /* !defined(DISABLE_ATAPI) */
565
566 /* --------------------------------------------------------------------------- */
567
568 const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = {
569 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
570 .parent.start_handler = scic_sds_remote_device_default_start_handler,
571 .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler,
572 .parent.fail_handler = scic_sds_remote_device_default_fail_handler,
573 .parent.destruct_handler = scic_sds_remote_device_default_destruct_handler,
574 .parent.reset_handler = scic_sds_remote_device_ready_state_reset_handler,
575 .parent.reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
576 .parent.start_io_handler = scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
577 .parent.complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
578 .parent.continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
579 .parent.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
580 .parent.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
581 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
582 .resume_handler = scic_sds_remote_device_default_resume_handler,
583 .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler,
584 .frame_handler = scic_sds_remote_device_default_frame_handler
585 },
586 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
587 .parent.start_handler = scic_sds_remote_device_default_start_handler,
588 .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler,
589 .parent.fail_handler = scic_sds_remote_device_default_fail_handler,
590 .parent.destruct_handler = scic_sds_remote_device_default_destruct_handler,
591 .parent.reset_handler = scic_sds_remote_device_ready_state_reset_handler,
592 .parent.reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
593 .parent.start_io_handler = scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
594 .parent.complete_io_handler = scic_sds_stp_remote_device_complete_request,
595 .parent.continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
596 .parent.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
597 .parent.complete_task_handler = scic_sds_stp_remote_device_complete_request,
598 .suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
599 .resume_handler = scic_sds_remote_device_default_resume_handler,
600 .event_handler = scic_sds_remote_device_general_event_handler,
601 .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
602 },
603 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
604 .parent.start_handler = scic_sds_remote_device_default_start_handler,
605 .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler,
606 .parent.fail_handler = scic_sds_remote_device_default_fail_handler,
607 .parent.destruct_handler = scic_sds_remote_device_default_destruct_handler,
608 .parent.reset_handler = scic_sds_remote_device_ready_state_reset_handler,
609 .parent.reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
610 .parent.start_io_handler = scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
611 .parent.complete_io_handler = scic_sds_stp_remote_device_complete_request,
612 .parent.continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
613 .parent.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
614 .parent.complete_task_handler = scic_sds_stp_remote_device_complete_request,
615 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
616 .resume_handler = scic_sds_remote_device_default_resume_handler,
617 .event_handler = scic_sds_remote_device_general_event_handler,
618 .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
619 },
620 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
621 .parent.start_handler = scic_sds_remote_device_default_start_handler,
622 .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler,
623 .parent.fail_handler = scic_sds_remote_device_default_fail_handler,
624 .parent.destruct_handler = scic_sds_remote_device_default_destruct_handler,
625 .parent.reset_handler = scic_sds_remote_device_ready_state_reset_handler,
626 .parent.reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
627 .parent.start_io_handler = scic_sds_remote_device_default_start_request_handler,
628 .parent.complete_io_handler = scic_sds_stp_remote_device_complete_request,
629 .parent.continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
630 .parent.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
631 .parent.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
636 },
637 #if !defined(DISABLE_ATAPI)
638 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR] = {
639 .parent.start_handler = scic_sds_remote_device_default_start_handler,
640 .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler,
641 .parent.fail_handler = scic_sds_remote_device_default_fail_handler,
642 .parent.destruct_handler = scic_sds_remote_device_default_destruct_handler,
643 .parent.reset_handler = scic_sds_remote_device_ready_state_reset_handler,
644 .parent.reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
645 .parent.start_io_handler = scic_sds_remote_device_default_start_request_handler,
646 .parent.complete_io_handler = scic_sds_stp_remote_device_complete_request,
647 .parent.continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
648 .parent.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
649 .parent.complete_task_handler = scic_sds_stp_remote_device_complete_request,
650 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
651 .resume_handler = scic_sds_remote_device_default_resume_handler,
652 .event_handler = scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler,
653 .frame_handler = scic_sds_remote_device_general_frame_handler
654 },
655 #endif
656 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
657 .parent.start_handler = scic_sds_remote_device_default_start_handler,
658 .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler,
659 .parent.fail_handler = scic_sds_remote_device_default_fail_handler,
660 .parent.destruct_handler = scic_sds_remote_device_default_destruct_handler,
661 .parent.reset_handler = scic_sds_remote_device_ready_state_reset_handler,
662 .parent.reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
663 .parent.start_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
664 .parent.complete_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
665 .parent.continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
666 .parent.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
667 .parent.complete_task_handler = scic_sds_stp_remote_device_complete_request,
668 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
669 .resume_handler = scic_sds_remote_device_default_resume_handler,
670 .event_handler = scic_sds_remote_device_general_event_handler,
671 .frame_handler = scic_sds_remote_device_general_frame_handler
672 }
673 };
674
675 /*
676 * *****************************************************************************
677 * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
678 * ***************************************************************************** */
679
680 static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
681 void *user_cookie)
682 {
683 struct scic_sds_remote_device *this_device;
684
685 this_device = (struct scic_sds_remote_device *)user_cookie;
686
687 /*
688 * For NCQ operation we do not issue a
689 * scic_cb_remote_device_not_ready(). As a result, avoid sending
690 * the ready notification. */
691 if (this_device->ready_substate_machine.previous_state_id
692 != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) {
693 isci_event_remote_device_ready(
694 scic_sds_remote_device_get_controller(this_device), this_device
695 );
696 }
697 }
698
699 /*
700 * *****************************************************************************
701 * * STP REMOTE DEVICE READY IDLE SUBSTATE
702 * ***************************************************************************** */
703
704 /**
705 *
706 * @device: This is the SCI base object which is cast into a
707 * struct scic_sds_remote_device object.
708 *
709 */
710 static void scic_sds_stp_remote_device_ready_idle_substate_enter(
711 struct sci_base_object *device)
712 {
713 struct scic_sds_remote_device *this_device;
714
715 this_device = (struct scic_sds_remote_device *)device;
716
717 SET_STATE_HANDLER(
718 this_device,
719 scic_sds_stp_remote_device_ready_substate_handler_table,
720 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
721 );
722
723 this_device->working_request = NULL;
724
725 if (scic_sds_remote_node_context_is_ready(this_device->rnc)) {
726 /*
727 * Since the RNC is ready, it's alright to finish completion
728 * processing (e.g. signal the remote device is ready). */
729 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
730 this_device
731 );
732 } else {
733 scic_sds_remote_node_context_resume(
734 this_device->rnc,
735 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
736 this_device
737 );
738 }
739 }
740
741 /*
742 * *****************************************************************************
743 * * STP REMOTE DEVICE READY CMD SUBSTATE
744 * ***************************************************************************** */
745
746 /**
747 *
748 * @device: This is the SCI base object which is cast into a
749 * struct scic_sds_remote_device object.
750 *
751 */
752 static void scic_sds_stp_remote_device_ready_cmd_substate_enter(
753 struct sci_base_object *device)
754 {
755 struct scic_sds_remote_device *this_device;
756
757 this_device = (struct scic_sds_remote_device *)device;
758
759 BUG_ON(this_device->working_request == NULL);
760
761 SET_STATE_HANDLER(
762 this_device,
763 scic_sds_stp_remote_device_ready_substate_handler_table,
764 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
765 );
766
767 isci_event_remote_device_not_ready(
768 scic_sds_remote_device_get_controller(this_device),
769 this_device,
770 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
771 );
772 }
773
774 /*
775 * *****************************************************************************
776 * * STP REMOTE DEVICE READY NCQ SUBSTATE
777 * ***************************************************************************** */
778
779 /**
780 *
781 * @device: This is the SCI base object which is cast into a
782 * struct scic_sds_remote_device object.
783 *
784 */
785 static void scic_sds_stp_remote_device_ready_ncq_substate_enter(
786 struct sci_base_object *device)
787 {
788 struct scic_sds_remote_device *this_device;
789
790 this_device = (struct scic_sds_remote_device *)device;
791
792 SET_STATE_HANDLER(
793 this_device,
794 scic_sds_stp_remote_device_ready_substate_handler_table,
795 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
796 );
797 }
798
799 /*
800 * *****************************************************************************
801 * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE
802 * ***************************************************************************** */
803
804 /**
805 *
806 * @device: This is the SCI base object which is cast into a
807 * struct scic_sds_remote_device object.
808 *
809 */
810 static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
811 struct sci_base_object *device)
812 {
813 struct scic_sds_remote_device *this_device;
814
815 this_device = (struct scic_sds_remote_device *)device;
816
817 SET_STATE_HANDLER(
818 this_device,
819 scic_sds_stp_remote_device_ready_substate_handler_table,
820 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
821 );
822
823 if (this_device->not_ready_reason ==
824 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) {
825 isci_event_remote_device_not_ready(
826 scic_sds_remote_device_get_controller(this_device),
827 this_device,
828 this_device->not_ready_reason
829 );
830 }
831 }
832
833 /*
834 * *****************************************************************************
835 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
836 * ***************************************************************************** */
837
838 /**
839 * The enter routine to READY AWAIT RESET substate.
840 * @device: This is the SCI base object which is cast into a
841 * struct scic_sds_remote_device object.
842 *
843 */
844 static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
845 struct sci_base_object *device)
846 {
847 struct scic_sds_remote_device *this_device;
848
849 this_device = (struct scic_sds_remote_device *)device;
850
851 SET_STATE_HANDLER(
852 this_device,
853 scic_sds_stp_remote_device_ready_substate_handler_table,
854 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
855 );
856 }
857
858 #if !defined(DISABLE_ATAPI)
859 /*
860 * *****************************************************************************
861 * * STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
862 * ***************************************************************************** */
863
864 /**
865 * The enter routine to READY ATAPI ERROR substate.
866 * @device: This is the SCI base object which is cast into a
867 * struct scic_sds_remote_device object.
868 *
869 */
870 void scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
871 struct sci_base_object *device)
872 {
873 struct scic_sds_remote_device *this_device;
874
875 this_device = (struct scic_sds_remote_device *)device;
876
877 SET_STATE_HANDLER(
878 this_device,
879 scic_sds_stp_remote_device_ready_substate_handler_table,
880 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
881 );
882 }
883 #endif /* !defined(DISABLE_ATAPI) */
884
885 /* --------------------------------------------------------------------------- */
886
887 const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = {
888 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
889 .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
890 },
891 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
892 .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
893 },
894 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
895 .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
896 },
897 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
898 .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
899 },
900 #if !defined(DISABLE_ATAPI)
901 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR] = {
902 .enter_state = scic_sds_stp_remote_device_ready_atapi_error_substate_enter,
903 },
904 #endif
905 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
906 .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
907 },
908 };