isci: Removed sci_base_object from scic_sds_remote_device.
[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;
7392d275 212 struct isci_request *isci_request =
38aa74eb 213 (struct isci_request *)sci_object_get_association(request);
6f231dda
DW
214
215
216 /* Will the port allow the io request to start? */
0ea99d52
MT
217 status = sci_dev->owning_port->state_handlers->start_io_handler(
218 sci_dev->owning_port, sci_dev, request);
38aa74eb
CH
219 if (status != SCI_SUCCESS)
220 return status;
6f231dda 221
7ab92c9e 222 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
38aa74eb
CH
223 if (status != SCI_SUCCESS)
224 goto out;
6f231dda 225
38aa74eb
CH
226 status = request->state_handlers->start_handler(request);
227 if (status != SCI_SUCCESS)
228 goto out;
6f231dda 229
38aa74eb 230 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
0ea99d52 231 sci_base_state_machine_change_state(&sci_dev->ready_substate_machine,
38aa74eb
CH
232 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
233 } else {
0ea99d52
MT
234 sci_dev->working_request = request;
235 sci_base_state_machine_change_state(&sci_dev->ready_substate_machine,
38aa74eb 236 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
6f231dda 237 }
38aa74eb 238out:
0ea99d52 239 scic_sds_remote_device_start_request(sci_dev, request, status);
6f231dda
DW
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 */
253static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
e2023b87 254 struct scic_sds_remote_device *sci_dev,
6f231dda
DW
255 u32 event_code)
256{
257 enum sci_status status;
258
e2023b87 259 status = scic_sds_remote_device_general_event_handler(sci_dev, event_code);
6f231dda
DW
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(
7ab92c9e 265 &sci_dev->rnc, NULL, NULL);
6f231dda
DW
266 }
267 }
268
269 return status;
270}
271
272
273/*
274 * *****************************************************************************
275 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
276 * ***************************************************************************** */
277
278static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
0ea99d52 279 struct scic_sds_remote_device *sci_dev,
38aa74eb 280 struct scic_sds_request *request)
6f231dda
DW
281{
282 enum sci_status status;
7392d275 283 struct isci_request *isci_request =
38aa74eb 284 (struct isci_request *)sci_object_get_association(request);
7392d275
DJ
285
286 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
0ea99d52
MT
287 status = sci_dev->owning_port->state_handlers->start_io_handler(
288 sci_dev->owning_port,
289 sci_dev,
38aa74eb 290 request);
7ab92c9e
DW
291 if (status != SCI_SUCCESS)
292 return status;
6f231dda 293
7ab92c9e
DW
294 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
295 if (status != SCI_SUCCESS)
296 return status;
6f231dda 297
7ab92c9e 298 status = request->state_handlers->start_handler(request);
6f231dda 299
7ab92c9e 300 scic_sds_remote_device_start_request(sci_dev, request, status);
7392d275 301 } else
6f231dda 302 status = SCI_FAILURE_INVALID_STATE;
6f231dda
DW
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.
e2023b87 311 * @sci_dev: This is the device object that is receiving the event.
6f231dda
DW
312 * @event_code: The event code to process.
313 *
314 * enum sci_status
315 */
316
317static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
e2023b87 318 struct scic_sds_remote_device *sci_dev,
6f231dda
DW
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(
e2023b87 325 &(scic_sds_remote_device_get_controller(sci_dev)->uf_control),
6f231dda
DW
326 frame_index,
327 (void **)&frame_header
328 );
329
330 if (status == SCI_SUCCESS) {
3ff0121a
PS
331 if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
332 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
e2023b87 333 sci_dev->not_ready_reason =
3ff0121a
PS
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(
e2023b87 342 &sci_dev->ready_substate_machine,
3ff0121a
PS
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 */
e2023b87 352 sci_dev->not_ready_reason =
6f231dda
DW
353 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
354
355 sci_base_state_machine_change_state(
e2023b87 356 &sci_dev->ready_substate_machine,
6f231dda
DW
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(
e2023b87 364 scic_sds_remote_device_get_controller(sci_dev), frame_index
6f231dda
DW
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 */
384static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
0ea99d52 385 struct scic_sds_remote_device *device,
38aa74eb 386 struct scic_sds_request *request)
6f231dda
DW
387{
388 return SCI_FAILURE_INVALID_STATE;
389}
390
391static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
e2023b87 392 struct scic_sds_remote_device *sci_dev,
6f231dda
DW
393 u32 suspend_type)
394{
395 enum sci_status status;
396
7ab92c9e
DW
397 status = scic_sds_remote_node_context_suspend(&sci_dev->rnc,
398 suspend_type, NULL, NULL);
6f231dda
DW
399
400 return status;
401}
402
403static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
e2023b87 404 struct scic_sds_remote_device *sci_dev,
6f231dda
DW
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(
e2023b87 414 sci_dev->working_request,
6f231dda
DW
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 * ***************************************************************************** */
436static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
0ea99d52 437 struct scic_sds_remote_device *device,
38aa74eb 438 struct scic_sds_request *request)
6f231dda
DW
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 */
455static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
0ea99d52 456 struct scic_sds_remote_device *device,
38aa74eb 457 struct scic_sds_request *request)
6f231dda 458{
e2023b87 459 struct scic_sds_request *sci_req = (struct scic_sds_request *)request;
6f231dda
DW
460 enum sci_status status;
461
e2023b87 462 status = scic_sds_io_request_complete(sci_req);
6f231dda
DW
463
464 if (status == SCI_SUCCESS) {
465 status = scic_sds_port_complete_io(
e2023b87 466 device->owning_port, device, sci_req
6f231dda
DW
467 );
468
469 if (status == SCI_SUCCESS)
0ea99d52 470 scic_sds_remote_device_decrement_request_count(device);
6f231dda
DW
471 }
472
473 if (status != SCI_SUCCESS)
0ea99d52 474 dev_err(scirdev_to_dev(device),
6f231dda
DW
475 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
476 "could not complete\n",
477 __func__,
0ea99d52
MT
478 device->owning_port,
479 device,
e2023b87 480 sci_req,
6f231dda
DW
481 status);
482
483 return status;
484}
485
35173d57 486static const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = {
db48255b 487 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
0ea99d52
MT
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,
db48255b
HD
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
6f231dda 503 },
db48255b 504 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
0ea99d52
MT
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,
db48255b
HD
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
6f231dda 520 },
db48255b 521 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
0ea99d52
MT
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,
db48255b
HD
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
6f231dda 537 },
db48255b 538 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
0ea99d52
MT
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,
db48255b
HD
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
6f231dda 554 },
db48255b 555 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
0ea99d52
MT
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,
db48255b
HD
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
6f231dda
DW
571 }
572};
573
6f231dda
DW
574/*
575 * *****************************************************************************
576 * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
577 * ***************************************************************************** */
578
037afc78
DW
579static void
580scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *user_cookie)
6f231dda 581{
037afc78 582 struct scic_sds_remote_device *sci_dev = user_cookie;
5d937e96 583 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
037afc78 584 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
d3757c3a 585 struct isci_host *ihost = scic->ihost;
6f231dda
DW
586
587 /*
588 * For NCQ operation we do not issue a
589 * scic_cb_remote_device_not_ready(). As a result, avoid sending
09d7da13
DJ
590 * the ready notification.
591 */
592 if (sci_dev->ready_substate_machine.previous_state_id !=
593 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
037afc78 594 isci_remote_device_ready(ihost, idev);
6f231dda
DW
595}
596
597/*
598 * *****************************************************************************
599 * * STP REMOTE DEVICE READY IDLE SUBSTATE
600 * ***************************************************************************** */
601
602/**
603 *
9a0fff7b 604 * @device: This is the object which is cast into a
6f231dda
DW
605 * struct scic_sds_remote_device object.
606 *
607 */
9a0fff7b 608static void scic_sds_stp_remote_device_ready_idle_substate_enter(void *device)
6f231dda 609{
5d937e96 610 struct scic_sds_remote_device *sci_dev = device;
6f231dda
DW
611
612 SET_STATE_HANDLER(
e2023b87 613 sci_dev,
6f231dda
DW
614 scic_sds_stp_remote_device_ready_substate_handler_table,
615 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
616 );
617
e2023b87 618 sci_dev->working_request = NULL;
6f231dda 619
7ab92c9e 620 if (scic_sds_remote_node_context_is_ready(&sci_dev->rnc)) {
6f231dda
DW
621 /*
622 * Since the RNC is ready, it's alright to finish completion
623 * processing (e.g. signal the remote device is ready). */
624 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
e2023b87 625 sci_dev
6f231dda
DW
626 );
627 } else {
628 scic_sds_remote_node_context_resume(
7ab92c9e 629 &sci_dev->rnc,
6f231dda 630 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
7ab92c9e 631 sci_dev);
6f231dda
DW
632 }
633}
634
9a0fff7b 635static void scic_sds_stp_remote_device_ready_cmd_substate_enter(void *object)
6f231dda 636{
5d937e96 637 struct scic_sds_remote_device *sci_dev = object;
037afc78 638 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
d3757c3a 639 struct isci_host *ihost = scic->ihost;
5d937e96 640 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
6f231dda 641
09d7da13 642 BUG_ON(sci_dev->working_request == NULL);
6f231dda 643
037afc78
DW
644 SET_STATE_HANDLER(sci_dev,
645 scic_sds_stp_remote_device_ready_substate_handler_table,
646 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
6f231dda 647
037afc78
DW
648 isci_remote_device_not_ready(ihost, idev,
649 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
6f231dda
DW
650}
651
9a0fff7b 652static void scic_sds_stp_remote_device_ready_ncq_substate_enter(void *object)
6f231dda 653{
5d937e96 654 struct scic_sds_remote_device *sci_dev = object;
037afc78
DW
655 SET_STATE_HANDLER(sci_dev,
656 scic_sds_stp_remote_device_ready_substate_handler_table,
657 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
6f231dda
DW
658}
659
9a0fff7b
MP
660static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
661 void *object)
6f231dda 662{
5d937e96 663 struct scic_sds_remote_device *sci_dev = object;
037afc78 664 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
d3757c3a 665 struct isci_host *ihost = scic->ihost;
5d937e96 666 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
6f231dda 667
037afc78
DW
668 SET_STATE_HANDLER(sci_dev,
669 scic_sds_stp_remote_device_ready_substate_handler_table,
670 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
6f231dda 671
09d7da13
DJ
672 if (sci_dev->not_ready_reason ==
673 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
037afc78 674 isci_remote_device_not_ready(ihost, idev, sci_dev->not_ready_reason);
6f231dda
DW
675}
676
677/*
678 * *****************************************************************************
679 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
680 * ***************************************************************************** */
681
682/**
683 * The enter routine to READY AWAIT RESET substate.
9a0fff7b 684 * @device: This is the object which is cast into a
6f231dda
DW
685 * struct scic_sds_remote_device object.
686 *
687 */
688static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
9a0fff7b 689 void *device)
6f231dda 690{
e2023b87 691 struct scic_sds_remote_device *sci_dev;
6f231dda 692
e2023b87 693 sci_dev = (struct scic_sds_remote_device *)device;
6f231dda
DW
694
695 SET_STATE_HANDLER(
e2023b87 696 sci_dev,
6f231dda
DW
697 scic_sds_stp_remote_device_ready_substate_handler_table,
698 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
699 );
700}
701
6f231dda
DW
702const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = {
703 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
704 .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
705 },
706 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
707 .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
708 },
709 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
710 .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
711 },
712 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
713 .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
714 },
6f231dda
DW
715 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
716 .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
717 },
718};
This page took 0.066815 seconds and 5 git commands to generate.