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