isci: remote device and node cleanup step1
[deliverable/linux.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 };
This page took 0.052463 seconds and 5 git commands to generate.