isci: Removed struct sci_base_object from state machine.
[deliverable/linux.git] / drivers / scsi / isci / 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_sds_controller.h"
61 #include "scic_sds_port.h"
62 #include "remote_device.h"
63 #include "scic_sds_request.h"
64 #include "sci_environment.h"
65 #include "sci_util.h"
66 #include "scu_event_codes.h"
67
68 /**
69 * This method will perform the STP request completion processing common to IO
70 * requests and task requests of all types
71 * @device: This parameter specifies the device for which the request is being
72 * completed.
73 * @request: This parameter specifies the request being completed.
74 *
75 * This method returns an indication as to whether the request processing
76 * completed successfully.
77 */
78 static enum sci_status scic_sds_stp_remote_device_complete_request(
79 struct scic_sds_remote_device *device,
80 struct scic_sds_request *request)
81 {
82 enum sci_status status;
83
84 status = scic_sds_io_request_complete(request);
85
86 if (status == SCI_SUCCESS) {
87 status = scic_sds_port_complete_io(
88 device->owning_port, device, request);
89
90 if (status == SCI_SUCCESS) {
91 scic_sds_remote_device_decrement_request_count(device);
92 if (request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
93 /*
94 * This request causes hardware error, device needs to be Lun Reset.
95 * So here we force the state machine to IDLE state so the rest IOs
96 * can reach RNC state handler, these IOs will be completed by RNC with
97 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */
98 sci_base_state_machine_change_state(
99 &device->ready_substate_machine,
100 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
101 );
102 } else if (scic_sds_remote_device_get_request_count(device) == 0) {
103 sci_base_state_machine_change_state(
104 &device->ready_substate_machine,
105 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
106 );
107 }
108 }
109 }
110
111 if (status != SCI_SUCCESS)
112 dev_err(scirdev_to_dev(device),
113 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
114 "could not complete\n",
115 __func__,
116 device->owning_port,
117 device,
118 request,
119 status);
120
121 return status;
122 }
123
124 /*
125 * *****************************************************************************
126 * * STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
127 * ***************************************************************************** */
128
129 /**
130 * This is the READY NCQ substate handler to start task management request. In
131 * this routine, we suspend and resume the RNC.
132 * @device: The target device a task management request towards to.
133 * @request: The task request.
134 *
135 * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to
136 * let controller_start_task_handler know that the controller can't post TC for
137 * task request yet, instead, when RNC gets resumed, a controller_continue_task
138 * callback will be called.
139 */
140 static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
141 struct scic_sds_remote_device *device,
142 struct scic_sds_request *request)
143 {
144 enum sci_status status;
145
146 /* Will the port allow the io request to start? */
147 status = device->owning_port->state_handlers->start_io_handler(
148 device->owning_port, device, request);
149 if (status != SCI_SUCCESS)
150 return status;
151
152 status = scic_sds_remote_node_context_start_task(&device->rnc, request);
153 if (status != SCI_SUCCESS)
154 goto out;
155
156 status = request->state_handlers->start_handler(request);
157 if (status != SCI_SUCCESS)
158 goto out;
159
160 /*
161 * Note: If the remote device state is not IDLE this will replace
162 * the request that probably resulted in the task management request.
163 */
164 device->working_request = request;
165 sci_base_state_machine_change_state(&device->ready_substate_machine,
166 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
167
168 /*
169 * The remote node context must cleanup the TCi to NCQ mapping table.
170 * The only way to do this correctly is to either write to the TLCR
171 * register or to invalidate and repost the RNC. In either case the
172 * remote node context state machine will take the correct action when
173 * the remote node context is suspended and later resumed.
174 */
175 scic_sds_remote_node_context_suspend(&device->rnc,
176 SCI_SOFTWARE_SUSPENSION, NULL, NULL);
177 scic_sds_remote_node_context_resume(&device->rnc,
178 scic_sds_remote_device_continue_request,
179 device);
180
181 out:
182 scic_sds_remote_device_start_request(device, request, status);
183 /*
184 * We need to let the controller start request handler know that it can't
185 * post TC yet. We will provide a callback function to post TC when RNC gets
186 * resumed.
187 */
188 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
189 }
190
191 /*
192 * *****************************************************************************
193 * * STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
194 * ***************************************************************************** */
195
196 /**
197 * This method will handle the start io operation for a sata device that is in
198 * the command idle state. - Evalute the type of IO request to be started -
199 * If its an NCQ request change to NCQ substate - If its any other command
200 * change to the CMD substate
201 * @device:
202 * @request:
203 *
204 * If this is a softreset we may want to have a different substate.
205 * enum sci_status
206 */
207 static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
208 struct scic_sds_remote_device *sci_dev,
209 struct scic_sds_request *request)
210 {
211 enum sci_status status;
212 struct isci_request *isci_request =
213 (struct isci_request *)sci_object_get_association(request);
214
215
216 /* Will the port allow the io request to start? */
217 status = sci_dev->owning_port->state_handlers->start_io_handler(
218 sci_dev->owning_port, sci_dev, request);
219 if (status != SCI_SUCCESS)
220 return status;
221
222 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
223 if (status != SCI_SUCCESS)
224 goto out;
225
226 status = request->state_handlers->start_handler(request);
227 if (status != SCI_SUCCESS)
228 goto out;
229
230 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
231 sci_base_state_machine_change_state(&sci_dev->ready_substate_machine,
232 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
233 } else {
234 sci_dev->working_request = request;
235 sci_base_state_machine_change_state(&sci_dev->ready_substate_machine,
236 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
237 }
238 out:
239 scic_sds_remote_device_start_request(sci_dev, request, status);
240 return status;
241 }
242
243
244 /**
245 *
246 * @[in]: device The device received event.
247 * @[in]: event_code The event code.
248 *
249 * This method will handle the event for a sata device that is in the idle
250 * state. We pick up suspension events to handle specifically to this state. We
251 * resume the RNC right away. enum sci_status
252 */
253 static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
254 struct scic_sds_remote_device *sci_dev,
255 u32 event_code)
256 {
257 enum sci_status status;
258
259 status = scic_sds_remote_device_general_event_handler(sci_dev, event_code);
260
261 if (status == SCI_SUCCESS) {
262 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
263 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
264 status = scic_sds_remote_node_context_resume(
265 &sci_dev->rnc, NULL, NULL);
266 }
267 }
268
269 return status;
270 }
271
272
273 /*
274 * *****************************************************************************
275 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
276 * ***************************************************************************** */
277
278 static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
279 struct scic_sds_remote_device *sci_dev,
280 struct scic_sds_request *request)
281 {
282 enum sci_status status;
283 struct isci_request *isci_request =
284 (struct isci_request *)sci_object_get_association(request);
285
286 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
287 status = sci_dev->owning_port->state_handlers->start_io_handler(
288 sci_dev->owning_port,
289 sci_dev,
290 request);
291 if (status != SCI_SUCCESS)
292 return status;
293
294 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
295 if (status != SCI_SUCCESS)
296 return status;
297
298 status = request->state_handlers->start_handler(request);
299
300 scic_sds_remote_device_start_request(sci_dev, request, status);
301 } else
302 status = SCI_FAILURE_INVALID_STATE;
303
304 return status;
305 }
306
307
308 /**
309 * This method will handle events received while the STP device is in the ready
310 * command substate.
311 * @sci_dev: This is the device object that is receiving the event.
312 * @event_code: The event code to process.
313 *
314 * enum sci_status
315 */
316
317 static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
318 struct scic_sds_remote_device *sci_dev,
319 u32 frame_index)
320 {
321 enum sci_status status;
322 struct sata_fis_header *frame_header;
323
324 status = scic_sds_unsolicited_frame_control_get_header(
325 &(scic_sds_remote_device_get_controller(sci_dev)->uf_control),
326 frame_index,
327 (void **)&frame_header
328 );
329
330 if (status == SCI_SUCCESS) {
331 if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
332 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
333 sci_dev->not_ready_reason =
334 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
335
336 /*
337 * / @todo Check sactive and complete associated IO
338 * if any.
339 */
340
341 sci_base_state_machine_change_state(
342 &sci_dev->ready_substate_machine,
343 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
344 );
345 } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H &&
346 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
347
348 /*
349 * Some devices return D2H FIS when an NCQ error is detected.
350 * Treat this like an SDB error FIS ready reason.
351 */
352 sci_dev->not_ready_reason =
353 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
354
355 sci_base_state_machine_change_state(
356 &sci_dev->ready_substate_machine,
357 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
358 );
359 } else {
360 status = SCI_FAILURE;
361 }
362
363 scic_sds_controller_release_frame(
364 scic_sds_remote_device_get_controller(sci_dev), frame_index
365 );
366 }
367
368 return status;
369 }
370
371 /*
372 * *****************************************************************************
373 * * STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
374 * ***************************************************************************** */
375
376 /**
377 * This device is already handling a command it can not accept new commands
378 * until this one is complete.
379 * @device:
380 * @request:
381 *
382 * enum sci_status
383 */
384 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
385 struct scic_sds_remote_device *device,
386 struct scic_sds_request *request)
387 {
388 return SCI_FAILURE_INVALID_STATE;
389 }
390
391 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
392 struct scic_sds_remote_device *sci_dev,
393 u32 suspend_type)
394 {
395 enum sci_status status;
396
397 status = scic_sds_remote_node_context_suspend(&sci_dev->rnc,
398 suspend_type, NULL, NULL);
399
400 return status;
401 }
402
403 static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
404 struct scic_sds_remote_device *sci_dev,
405 u32 frame_index)
406 {
407 enum sci_status status;
408
409 /*
410 * / The device doe not process any UF received from the hardware while
411 * / in this state. All unsolicited frames are forwarded to the io request
412 * / object. */
413 status = scic_sds_io_request_frame_handler(
414 sci_dev->working_request,
415 frame_index
416 );
417
418 return status;
419 }
420
421
422 /*
423 * *****************************************************************************
424 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
425 * ***************************************************************************** */
426
427 /*
428 * *****************************************************************************
429 * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS
430 * ***************************************************************************** */
431
432 /*
433 * *****************************************************************************
434 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
435 * ***************************************************************************** */
436 static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
437 struct scic_sds_remote_device *device,
438 struct scic_sds_request *request)
439 {
440 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
441 }
442
443
444
445 /**
446 * This method will perform the STP request (both io or task) completion
447 * processing for await reset state.
448 * @device: This parameter specifies the device for which the request is being
449 * completed.
450 * @request: This parameter specifies the request being completed.
451 *
452 * This method returns an indication as to whether the request processing
453 * completed successfully.
454 */
455 static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
456 struct scic_sds_remote_device *device,
457 struct scic_sds_request *request)
458 {
459 struct scic_sds_request *sci_req = (struct scic_sds_request *)request;
460 enum sci_status status;
461
462 status = scic_sds_io_request_complete(sci_req);
463
464 if (status == SCI_SUCCESS) {
465 status = scic_sds_port_complete_io(
466 device->owning_port, device, sci_req
467 );
468
469 if (status == SCI_SUCCESS)
470 scic_sds_remote_device_decrement_request_count(device);
471 }
472
473 if (status != SCI_SUCCESS)
474 dev_err(scirdev_to_dev(device),
475 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
476 "could not complete\n",
477 __func__,
478 device->owning_port,
479 device,
480 sci_req,
481 status);
482
483 return status;
484 }
485
486 static const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = {
487 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
488 .start_handler = scic_sds_remote_device_default_start_handler,
489 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
490 .fail_handler = scic_sds_remote_device_default_fail_handler,
491 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
492 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
493 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
494 .start_io_handler = scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
495 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
496 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
497 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
498 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
499 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
500 .resume_handler = scic_sds_remote_device_default_resume_handler,
501 .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler,
502 .frame_handler = scic_sds_remote_device_default_frame_handler
503 },
504 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
505 .start_handler = scic_sds_remote_device_default_start_handler,
506 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
507 .fail_handler = scic_sds_remote_device_default_fail_handler,
508 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
509 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
510 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
511 .start_io_handler = scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
512 .complete_io_handler = scic_sds_stp_remote_device_complete_request,
513 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
514 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
515 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
516 .suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
517 .resume_handler = scic_sds_remote_device_default_resume_handler,
518 .event_handler = scic_sds_remote_device_general_event_handler,
519 .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
520 },
521 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
522 .start_handler = scic_sds_remote_device_default_start_handler,
523 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
524 .fail_handler = scic_sds_remote_device_default_fail_handler,
525 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
526 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
527 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
528 .start_io_handler = scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
529 .complete_io_handler = scic_sds_stp_remote_device_complete_request,
530 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
531 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
532 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
533 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
534 .resume_handler = scic_sds_remote_device_default_resume_handler,
535 .event_handler = scic_sds_remote_device_general_event_handler,
536 .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
537 },
538 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
539 .start_handler = scic_sds_remote_device_default_start_handler,
540 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
541 .fail_handler = scic_sds_remote_device_default_fail_handler,
542 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
543 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
544 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
545 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
546 .complete_io_handler = scic_sds_stp_remote_device_complete_request,
547 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
548 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
549 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
550 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
551 .resume_handler = scic_sds_remote_device_default_resume_handler,
552 .event_handler = scic_sds_remote_device_general_event_handler,
553 .frame_handler = scic_sds_remote_device_general_frame_handler
554 },
555 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
556 .start_handler = scic_sds_remote_device_default_start_handler,
557 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
558 .fail_handler = scic_sds_remote_device_default_fail_handler,
559 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
560 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
561 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
562 .start_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
563 .complete_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
564 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
565 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
566 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
567 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
568 .resume_handler = scic_sds_remote_device_default_resume_handler,
569 .event_handler = scic_sds_remote_device_general_event_handler,
570 .frame_handler = scic_sds_remote_device_general_frame_handler
571 }
572 };
573
574 /*
575 * *****************************************************************************
576 * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
577 * ***************************************************************************** */
578
579 static void
580 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *user_cookie)
581 {
582 struct scic_sds_remote_device *sci_dev = user_cookie;
583 struct isci_remote_device *idev = sci_object_get_association(sci_dev);
584 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
585 struct isci_host *ihost = sci_object_get_association(scic);
586
587 /*
588 * For NCQ operation we do not issue a
589 * scic_cb_remote_device_not_ready(). As a result, avoid sending
590 * the ready notification.
591 */
592 if (sci_dev->ready_substate_machine.previous_state_id !=
593 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
594 isci_remote_device_ready(ihost, idev);
595 }
596
597 /*
598 * *****************************************************************************
599 * * STP REMOTE DEVICE READY IDLE SUBSTATE
600 * ***************************************************************************** */
601
602 /**
603 *
604 * @device: This is the object which is cast into a
605 * struct scic_sds_remote_device object.
606 *
607 */
608 static void scic_sds_stp_remote_device_ready_idle_substate_enter(void *device)
609 {
610 struct scic_sds_remote_device *sci_dev;
611
612 sci_dev = (struct scic_sds_remote_device *)device;
613
614 SET_STATE_HANDLER(
615 sci_dev,
616 scic_sds_stp_remote_device_ready_substate_handler_table,
617 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
618 );
619
620 sci_dev->working_request = NULL;
621
622 if (scic_sds_remote_node_context_is_ready(&sci_dev->rnc)) {
623 /*
624 * Since the RNC is ready, it's alright to finish completion
625 * processing (e.g. signal the remote device is ready). */
626 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
627 sci_dev
628 );
629 } else {
630 scic_sds_remote_node_context_resume(
631 &sci_dev->rnc,
632 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
633 sci_dev);
634 }
635 }
636
637 static void scic_sds_stp_remote_device_ready_cmd_substate_enter(void *object)
638 {
639 struct scic_sds_remote_device *sci_dev = container_of(object, typeof(*sci_dev),
640 parent);
641 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
642 struct isci_host *ihost = sci_object_get_association(scic);
643 struct isci_remote_device *idev = sci_object_get_association(sci_dev);
644
645 BUG_ON(sci_dev->working_request == NULL);
646
647 SET_STATE_HANDLER(sci_dev,
648 scic_sds_stp_remote_device_ready_substate_handler_table,
649 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
650
651 isci_remote_device_not_ready(ihost, idev,
652 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
653 }
654
655 static void scic_sds_stp_remote_device_ready_ncq_substate_enter(void *object)
656 {
657 struct scic_sds_remote_device *sci_dev = container_of(object, typeof(*sci_dev),
658 parent);
659 SET_STATE_HANDLER(sci_dev,
660 scic_sds_stp_remote_device_ready_substate_handler_table,
661 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
662 }
663
664 static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
665 void *object)
666 {
667 struct scic_sds_remote_device *sci_dev = container_of(object, typeof(*sci_dev),
668 parent);
669 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
670 struct isci_host *ihost = sci_object_get_association(scic);
671 struct isci_remote_device *idev = sci_object_get_association(sci_dev);
672
673 SET_STATE_HANDLER(sci_dev,
674 scic_sds_stp_remote_device_ready_substate_handler_table,
675 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
676
677 if (sci_dev->not_ready_reason ==
678 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
679 isci_remote_device_not_ready(ihost, idev, sci_dev->not_ready_reason);
680 }
681
682 /*
683 * *****************************************************************************
684 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
685 * ***************************************************************************** */
686
687 /**
688 * The enter routine to READY AWAIT RESET substate.
689 * @device: This is the object which is cast into a
690 * struct scic_sds_remote_device object.
691 *
692 */
693 static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
694 void *device)
695 {
696 struct scic_sds_remote_device *sci_dev;
697
698 sci_dev = (struct scic_sds_remote_device *)device;
699
700 SET_STATE_HANDLER(
701 sci_dev,
702 scic_sds_stp_remote_device_ready_substate_handler_table,
703 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
704 );
705 }
706
707 const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = {
708 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
709 .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
710 },
711 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
712 .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
713 },
714 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
715 .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
716 },
717 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
718 .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
719 },
720 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
721 .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
722 },
723 };
This page took 0.048508 seconds and 5 git commands to generate.