blob: 80eccdc1090fd60e013c5627bb67892b8347df85 [file] [log] [blame]
Dan Williams6f231dd2011-07-02 22:56:22 -07001/*
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 */
Dan Williams88f3b622011-04-22 19:18:03 -070055#include "intel_sas.h"
Dan Williamsab2e8f72011-04-27 16:32:45 -070056#include "intel_ata.h"
Dan Williams6f231dd2011-07-02 22:56:22 -070057#include "isci.h"
Dan Williams6f231dd2011-07-02 22:56:22 -070058#include "port.h"
59#include "remote_device.h"
60#include "request.h"
Dan Williams88f3b622011-04-22 19:18:03 -070061#include "scic_controller.h"
62#include "scic_io_request.h"
63#include "scic_phy.h"
64#include "scic_port.h"
65#include "scic_sds_controller.h"
66#include "scic_sds_phy.h"
67#include "scic_sds_port.h"
68#include "remote_node_context.h"
69#include "scic_sds_request.h"
70#include "sci_environment.h"
71#include "sci_util.h"
72#include "scu_event_codes.h"
Dan Williams6f231dd2011-07-02 22:56:22 -070073#include "task.h"
74
Dan Williamsab2e8f72011-04-27 16:32:45 -070075/**
76 * isci_remote_device_change_state() - This function gets the status of the
77 * remote_device object.
78 * @isci_device: This parameter points to the isci_remote_device object
79 *
80 * status of the object as a isci_status enum.
81 */
82void isci_remote_device_change_state(
83 struct isci_remote_device *isci_device,
84 enum isci_status status)
85{
86 unsigned long flags;
87
88 spin_lock_irqsave(&isci_device->state_lock, flags);
89 isci_device->status = status;
90 spin_unlock_irqrestore(&isci_device->state_lock, flags);
91}
92
93/**
94 * isci_remote_device_not_ready() - This function is called by the scic when
95 * the remote device is not ready. We mark the isci device as ready (not
96 * "ready_for_io") and signal the waiting proccess.
97 * @isci_host: This parameter specifies the isci host object.
98 * @isci_device: This parameter specifies the remote device
99 *
100 */
101static void isci_remote_device_not_ready(struct isci_host *ihost,
102 struct isci_remote_device *idev, u32 reason)
103{
104 dev_dbg(&ihost->pdev->dev,
105 "%s: isci_device = %p\n", __func__, idev);
106
107 if (reason == SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED)
108 isci_remote_device_change_state(idev, isci_stopping);
109 else
110 /* device ready is actually a "not ready for io" state. */
111 isci_remote_device_change_state(idev, isci_ready);
112}
113
114/**
115 * isci_remote_device_ready() - This function is called by the scic when the
116 * remote device is ready. We mark the isci device as ready and signal the
117 * waiting proccess.
118 * @ihost: our valid isci_host
119 * @idev: remote device
120 *
121 */
122static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote_device *idev)
123{
124 dev_dbg(&ihost->pdev->dev,
125 "%s: idev = %p\n", __func__, idev);
126
127 isci_remote_device_change_state(idev, isci_ready_for_io);
128 if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags))
129 wake_up(&ihost->eventq);
130}
131
132
133
Dan Williams88f3b622011-04-22 19:18:03 -0700134enum sci_status scic_remote_device_stop(
135 struct scic_sds_remote_device *sci_dev,
136 u32 timeout)
137{
138 return sci_dev->state_handlers->stop_handler(sci_dev);
139}
Dan Williams6f231dd2011-07-02 22:56:22 -0700140
141
Dan Williams88f3b622011-04-22 19:18:03 -0700142enum sci_status scic_remote_device_reset(
143 struct scic_sds_remote_device *sci_dev)
144{
145 return sci_dev->state_handlers->reset_handler(sci_dev);
146}
147
148
149enum sci_status scic_remote_device_reset_complete(
150 struct scic_sds_remote_device *sci_dev)
151{
152 return sci_dev->state_handlers->reset_complete_handler(sci_dev);
153}
154
Dan Williams88f3b622011-04-22 19:18:03 -0700155#define SCIC_SDS_REMOTE_DEVICE_MINIMUM_TIMER_COUNT (0)
156#define SCIC_SDS_REMOTE_DEVICE_MAXIMUM_TIMER_COUNT (SCI_MAX_REMOTE_DEVICES)
157
Dan Williams88f3b622011-04-22 19:18:03 -0700158/**
159 *
160 * @sci_dev: The remote device for which the suspend is being requested.
161 *
162 * This method invokes the remote device suspend state handler. enum sci_status
163 */
164enum sci_status scic_sds_remote_device_suspend(
165 struct scic_sds_remote_device *sci_dev,
166 u32 suspend_type)
167{
168 return sci_dev->state_handlers->suspend_handler(sci_dev, suspend_type);
169}
170
171/**
172 *
173 * @sci_dev: The remote device for which the event handling is being
174 * requested.
175 * @frame_index: This is the frame index that is being processed.
176 *
177 * This method invokes the frame handler for the remote device state machine
178 * enum sci_status
179 */
180enum sci_status scic_sds_remote_device_frame_handler(
181 struct scic_sds_remote_device *sci_dev,
182 u32 frame_index)
183{
184 return sci_dev->state_handlers->frame_handler(sci_dev, frame_index);
185}
186
187/**
188 *
189 * @sci_dev: The remote device for which the event handling is being
190 * requested.
191 * @event_code: This is the event code that is to be processed.
192 *
193 * This method invokes the remote device event handler. enum sci_status
194 */
195enum sci_status scic_sds_remote_device_event_handler(
196 struct scic_sds_remote_device *sci_dev,
197 u32 event_code)
198{
199 return sci_dev->state_handlers->event_handler(sci_dev, event_code);
200}
201
202/**
203 *
204 * @controller: The controller that is starting the io request.
205 * @sci_dev: The remote device for which the start io handling is being
206 * requested.
207 * @io_request: The io request that is being started.
208 *
209 * This method invokes the remote device start io handler. enum sci_status
210 */
211enum sci_status scic_sds_remote_device_start_io(
212 struct scic_sds_controller *controller,
213 struct scic_sds_remote_device *sci_dev,
214 struct scic_sds_request *io_request)
215{
216 return sci_dev->state_handlers->start_io_handler(
217 sci_dev, io_request);
218}
219
220/**
221 *
222 * @controller: The controller that is completing the io request.
223 * @sci_dev: The remote device for which the complete io handling is being
224 * requested.
225 * @io_request: The io request that is being completed.
226 *
227 * This method invokes the remote device complete io handler. enum sci_status
228 */
229enum sci_status scic_sds_remote_device_complete_io(
230 struct scic_sds_controller *controller,
231 struct scic_sds_remote_device *sci_dev,
232 struct scic_sds_request *io_request)
233{
234 return sci_dev->state_handlers->complete_io_handler(
235 sci_dev, io_request);
236}
237
238/**
239 *
240 * @controller: The controller that is starting the task request.
241 * @sci_dev: The remote device for which the start task handling is being
242 * requested.
243 * @io_request: The task request that is being started.
244 *
245 * This method invokes the remote device start task handler. enum sci_status
246 */
247enum sci_status scic_sds_remote_device_start_task(
248 struct scic_sds_controller *controller,
249 struct scic_sds_remote_device *sci_dev,
250 struct scic_sds_request *io_request)
251{
252 return sci_dev->state_handlers->start_task_handler(
253 sci_dev, io_request);
254}
255
256/**
257 *
Dan Williams88f3b622011-04-22 19:18:03 -0700258 * @sci_dev:
259 * @request:
260 *
261 * This method takes the request and bulids an appropriate SCU context for the
262 * request and then requests the controller to post the request. none
263 */
264void scic_sds_remote_device_post_request(
265 struct scic_sds_remote_device *sci_dev,
266 u32 request)
267{
268 u32 context;
269
270 context = scic_sds_remote_device_build_command_context(sci_dev, request);
271
272 scic_sds_controller_post_request(
273 scic_sds_remote_device_get_controller(sci_dev),
274 context
275 );
276}
277
Dan Williamsab2e8f72011-04-27 16:32:45 -0700278/* called once the remote node context is ready to be freed.
Dan Williams88f3b622011-04-22 19:18:03 -0700279 * The remote device can now report that its stop operation is complete. none
280 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700281static void scic_sds_cb_remote_device_rnc_destruct_complete(void *_dev)
Dan Williams88f3b622011-04-22 19:18:03 -0700282{
Dan Williamsab2e8f72011-04-27 16:32:45 -0700283 struct scic_sds_remote_device *sci_dev = _dev;
Dan Williams88f3b622011-04-22 19:18:03 -0700284
285 BUG_ON(sci_dev->started_request_count != 0);
Dan Williams88f3b622011-04-22 19:18:03 -0700286 sci_base_state_machine_change_state(&sci_dev->state_machine,
287 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED);
288}
289
Dan Williamsab2e8f72011-04-27 16:32:45 -0700290/* called once the remote node context has transisitioned to a
Dan Williams88f3b622011-04-22 19:18:03 -0700291 * ready state. This is the indication that the remote device object can also
Dan Williamsab2e8f72011-04-27 16:32:45 -0700292 * transition to ready.
Dan Williams88f3b622011-04-22 19:18:03 -0700293 */
Dan Williamseb229672011-05-01 14:05:57 -0700294static void remote_device_resume_done(void *_dev)
Dan Williams88f3b622011-04-22 19:18:03 -0700295{
Dan Williamsab2e8f72011-04-27 16:32:45 -0700296 struct scic_sds_remote_device *sci_dev = _dev;
297 enum scic_sds_remote_device_states state;
Dan Williams88f3b622011-04-22 19:18:03 -0700298
Dan Williamsab2e8f72011-04-27 16:32:45 -0700299 state = sci_dev->state_machine.current_state_id;
300 switch (state) {
301 case SCI_BASE_REMOTE_DEVICE_STATE_READY:
302 case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
303 case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
304 case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ:
305 case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR:
306 case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET:
307 case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
308 case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
309 break;
310 default:
311 /* go 'ready' if we are not already in a ready state */
312 sci_base_state_machine_change_state(&sci_dev->state_machine,
313 SCI_BASE_REMOTE_DEVICE_STATE_READY);
314 break;
Dan Williams88f3b622011-04-22 19:18:03 -0700315 }
316}
317
318/**
319 *
320 * @device: This parameter specifies the device for which the request is being
321 * started.
322 * @request: This parameter specifies the request being started.
323 * @status: This parameter specifies the current start operation status.
324 *
325 * This method will perform the STP request start processing common to IO
326 * requests and task requests of all types. none
327 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700328static void scic_sds_remote_device_start_request(
Dan Williams88f3b622011-04-22 19:18:03 -0700329 struct scic_sds_remote_device *sci_dev,
330 struct scic_sds_request *sci_req,
331 enum sci_status status)
332{
333 /* We still have a fault in starting the io complete it on the port */
334 if (status == SCI_SUCCESS)
335 scic_sds_remote_device_increment_request_count(sci_dev);
336 else{
337 sci_dev->owning_port->state_handlers->complete_io_handler(
338 sci_dev->owning_port, sci_dev, sci_req
339 );
340 }
341}
342
343
344/**
345 *
346 * @request: This parameter specifies the request being continued.
347 *
348 * This method will continue to post tc for a STP request. This method usually
349 * serves as a callback when RNC gets resumed during a task management
350 * sequence. none
351 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700352static void scic_sds_remote_device_continue_request(void *dev)
Dan Williams88f3b622011-04-22 19:18:03 -0700353{
354 struct scic_sds_remote_device *sci_dev = dev;
355
356 /* we need to check if this request is still valid to continue. */
357 if (sci_dev->working_request)
358 scic_controller_continue_io(sci_dev->working_request);
359}
360
361/**
362 * This method will terminate all of the IO requests in the controllers IO
363 * request table that were targeted for this device.
364 * @sci_dev: This parameter specifies the remote device for which to
365 * attempt to terminate all requests.
366 *
367 * This method returns an indication as to whether all requests were
368 * successfully terminated. If a single request fails to be terminated, then
369 * this method will return the failure.
370 */
371static enum sci_status scic_sds_remote_device_terminate_requests(
372 struct scic_sds_remote_device *sci_dev)
373{
374 enum sci_status status = SCI_SUCCESS;
375 enum sci_status terminate_status = SCI_SUCCESS;
376 struct scic_sds_request *sci_req;
377 u32 index;
378 u32 request_count = sci_dev->started_request_count;
379
380 for (index = 0;
381 (index < SCI_MAX_IO_REQUESTS) && (request_count > 0);
382 index++) {
383 sci_req = sci_dev->owning_port->owning_controller->io_request_table[index];
384
385 if ((sci_req != NULL) && (sci_req->target_device == sci_dev)) {
386 terminate_status = scic_controller_terminate_request(
387 sci_dev->owning_port->owning_controller,
388 sci_dev,
389 sci_req
390 );
391
392 if (terminate_status != SCI_SUCCESS)
393 status = terminate_status;
394
395 request_count--;
396 }
397 }
398
399 return status;
400}
401
402static enum sci_status
403default_device_handler(struct scic_sds_remote_device *sci_dev,
404 const char *func)
405{
406 dev_warn(scirdev_to_dev(sci_dev),
407 "%s: in wrong state: %d\n", func,
408 sci_base_state_machine_get_state(&sci_dev->state_machine));
409 return SCI_FAILURE_INVALID_STATE;
410}
411
Dan Williams88f3b622011-04-22 19:18:03 -0700412static enum sci_status scic_sds_remote_device_default_stop_handler(
413 struct scic_sds_remote_device *sci_dev)
414{
415 return default_device_handler(sci_dev, __func__);
416}
417
Dan Williamsab2e8f72011-04-27 16:32:45 -0700418static enum sci_status scic_sds_remote_device_default_fail_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700419 struct scic_sds_remote_device *sci_dev)
420{
421 return default_device_handler(sci_dev, __func__);
422}
423
Dan Williamsab2e8f72011-04-27 16:32:45 -0700424static enum sci_status scic_sds_remote_device_default_destruct_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700425 struct scic_sds_remote_device *sci_dev)
426{
427 return default_device_handler(sci_dev, __func__);
428}
429
Dan Williamsab2e8f72011-04-27 16:32:45 -0700430static enum sci_status scic_sds_remote_device_default_reset_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700431 struct scic_sds_remote_device *sci_dev)
432{
433 return default_device_handler(sci_dev, __func__);
434}
435
Dan Williamsab2e8f72011-04-27 16:32:45 -0700436static enum sci_status scic_sds_remote_device_default_reset_complete_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700437 struct scic_sds_remote_device *sci_dev)
438{
439 return default_device_handler(sci_dev, __func__);
440}
441
Dan Williamsab2e8f72011-04-27 16:32:45 -0700442static enum sci_status scic_sds_remote_device_default_suspend_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700443 struct scic_sds_remote_device *sci_dev, u32 suspend_type)
444{
445 return default_device_handler(sci_dev, __func__);
446}
447
Dan Williamsab2e8f72011-04-27 16:32:45 -0700448static enum sci_status scic_sds_remote_device_default_resume_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700449 struct scic_sds_remote_device *sci_dev)
450{
451 return default_device_handler(sci_dev, __func__);
452}
453
454/**
455 *
456 * @device: The struct scic_sds_remote_device which is then cast into a
457 * struct scic_sds_remote_device.
458 * @event_code: The event code that the struct scic_sds_controller wants the device
459 * object to process.
460 *
461 * This method is the default event handler. It will call the RNC state
462 * machine handler for any RNC events otherwise it will log a warning and
463 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
464 */
465static enum sci_status scic_sds_remote_device_core_event_handler(
466 struct scic_sds_remote_device *sci_dev,
467 u32 event_code,
468 bool is_ready_state)
469{
470 enum sci_status status;
471
472 switch (scu_get_event_type(event_code)) {
473 case SCU_EVENT_TYPE_RNC_OPS_MISC:
474 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
475 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
476 status = scic_sds_remote_node_context_event_handler(&sci_dev->rnc, event_code);
477 break;
478 case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
479
480 if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
481 status = SCI_SUCCESS;
482
483 /* Suspend the associated RNC */
484 scic_sds_remote_node_context_suspend(&sci_dev->rnc,
485 SCI_SOFTWARE_SUSPENSION,
486 NULL, NULL);
487
488 dev_dbg(scirdev_to_dev(sci_dev),
489 "%s: device: %p event code: %x: %s\n",
490 __func__, sci_dev, event_code,
491 (is_ready_state)
492 ? "I_T_Nexus_Timeout event"
493 : "I_T_Nexus_Timeout event in wrong state");
494
495 break;
496 }
497 /* Else, fall through and treat as unhandled... */
498
499 default:
500 dev_dbg(scirdev_to_dev(sci_dev),
501 "%s: device: %p event code: %x: %s\n",
502 __func__, sci_dev, event_code,
503 (is_ready_state)
504 ? "unexpected event"
505 : "unexpected event in wrong state");
506 status = SCI_FAILURE_INVALID_STATE;
507 break;
508 }
509
510 return status;
511}
512/**
513 *
514 * @device: The struct scic_sds_remote_device which is then cast into a
515 * struct scic_sds_remote_device.
516 * @event_code: The event code that the struct scic_sds_controller wants the device
517 * object to process.
518 *
519 * This method is the default event handler. It will call the RNC state
520 * machine handler for any RNC events otherwise it will log a warning and
521 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
522 */
523static enum sci_status scic_sds_remote_device_default_event_handler(
524 struct scic_sds_remote_device *sci_dev,
525 u32 event_code)
526{
527 return scic_sds_remote_device_core_event_handler(sci_dev,
528 event_code,
529 false);
530}
531
532/**
533 *
534 * @device: The struct scic_sds_remote_device which is then cast into a
535 * struct scic_sds_remote_device.
536 * @frame_index: The frame index for which the struct scic_sds_controller wants this
537 * device object to process.
538 *
539 * This method is the default unsolicited frame handler. It logs a warning,
540 * releases the frame and returns a failure. enum sci_status
541 * SCI_FAILURE_INVALID_STATE
542 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700543static enum sci_status scic_sds_remote_device_default_frame_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700544 struct scic_sds_remote_device *sci_dev,
545 u32 frame_index)
546{
547 dev_warn(scirdev_to_dev(sci_dev),
548 "%s: SCIC Remote Device requested to handle frame %x "
549 "while in wrong state %d\n",
550 __func__,
551 frame_index,
552 sci_base_state_machine_get_state(
553 &sci_dev->state_machine));
554
555 /* Return the frame back to the controller */
556 scic_sds_controller_release_frame(
557 scic_sds_remote_device_get_controller(sci_dev), frame_index
558 );
559
560 return SCI_FAILURE_INVALID_STATE;
561}
562
Dan Williamsab2e8f72011-04-27 16:32:45 -0700563static enum sci_status scic_sds_remote_device_default_start_request_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700564 struct scic_sds_remote_device *sci_dev,
565 struct scic_sds_request *request)
566{
567 return default_device_handler(sci_dev, __func__);
568}
569
Dan Williamsab2e8f72011-04-27 16:32:45 -0700570static enum sci_status scic_sds_remote_device_default_complete_request_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700571 struct scic_sds_remote_device *sci_dev,
572 struct scic_sds_request *request)
573{
574 return default_device_handler(sci_dev, __func__);
575}
576
Dan Williamsab2e8f72011-04-27 16:32:45 -0700577static enum sci_status scic_sds_remote_device_default_continue_request_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700578 struct scic_sds_remote_device *sci_dev,
579 struct scic_sds_request *request)
580{
581 return default_device_handler(sci_dev, __func__);
582}
583
584/**
585 *
586 * @device: The struct scic_sds_remote_device which is then cast into a
587 * struct scic_sds_remote_device.
588 * @frame_index: The frame index for which the struct scic_sds_controller wants this
589 * device object to process.
590 *
591 * This method is a general ssp frame handler. In most cases the device object
592 * needs to route the unsolicited frame processing to the io request object.
593 * This method decodes the tag for the io request object and routes the
594 * unsolicited frame to that object. enum sci_status SCI_FAILURE_INVALID_STATE
595 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700596static enum sci_status scic_sds_remote_device_general_frame_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700597 struct scic_sds_remote_device *sci_dev,
598 u32 frame_index)
599{
600 enum sci_status result;
601 struct sci_ssp_frame_header *frame_header;
602 struct scic_sds_request *io_request;
603
604 result = scic_sds_unsolicited_frame_control_get_header(
605 &(scic_sds_remote_device_get_controller(sci_dev)->uf_control),
606 frame_index,
607 (void **)&frame_header
608 );
609
610 if (SCI_SUCCESS == result) {
611 io_request = scic_sds_controller_get_io_request_from_tag(
612 scic_sds_remote_device_get_controller(sci_dev), frame_header->tag);
613
614 if ((io_request == NULL)
615 || (io_request->target_device != sci_dev)) {
616 /*
617 * We could not map this tag to a valid IO request
618 * Just toss the frame and continue */
619 scic_sds_controller_release_frame(
620 scic_sds_remote_device_get_controller(sci_dev), frame_index
621 );
622 } else {
623 /* The IO request is now in charge of releasing the frame */
624 result = io_request->state_handlers->frame_handler(
625 io_request, frame_index);
626 }
627 }
628
629 return result;
630}
631
632/**
633 *
634 * @[in]: sci_dev This is the device object that is receiving the event.
635 * @[in]: event_code The event code to process.
636 *
637 * This is a common method for handling events reported to the remote device
638 * from the controller object. enum sci_status
639 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700640static enum sci_status scic_sds_remote_device_general_event_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700641 struct scic_sds_remote_device *sci_dev,
642 u32 event_code)
643{
644 return scic_sds_remote_device_core_event_handler(sci_dev,
645 event_code,
646 true);
647}
648
Dan Williams88f3b622011-04-22 19:18:03 -0700649static enum sci_status scic_sds_remote_device_stopped_state_stop_handler(
650 struct scic_sds_remote_device *sci_dev)
651{
652 return SCI_SUCCESS;
653}
654
655/**
656 *
657 * @sci_dev: The struct scic_sds_remote_device which is cast into a
658 * struct scic_sds_remote_device.
659 *
660 * This method will destruct a struct scic_sds_remote_device that is in a stopped
661 * state. This is the only state from which a destruct request will succeed.
662 * The RNi for this struct scic_sds_remote_device is returned to the free pool and the
663 * device object transitions to the SCI_BASE_REMOTE_DEVICE_STATE_FINAL.
664 * enum sci_status SCI_SUCCESS
665 */
666static enum sci_status scic_sds_remote_device_stopped_state_destruct_handler(
667 struct scic_sds_remote_device *sci_dev)
668{
669 struct scic_sds_controller *scic;
670
671 scic = scic_sds_remote_device_get_controller(sci_dev);
672 scic_sds_controller_free_remote_node_context(scic, sci_dev,
673 sci_dev->rnc.remote_node_index);
674 sci_dev->rnc.remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
675
676 sci_base_state_machine_change_state(&sci_dev->state_machine,
677 SCI_BASE_REMOTE_DEVICE_STATE_FINAL);
678
679 return SCI_SUCCESS;
680}
681
682/*
683 * *****************************************************************************
684 * * STARTING STATE HANDLERS
685 * ***************************************************************************** */
686
687static enum sci_status scic_sds_remote_device_starting_state_stop_handler(
688 struct scic_sds_remote_device *sci_dev)
689{
690 /*
691 * This device has not yet started so there had better be no IO requests
692 */
693 BUG_ON(sci_dev->started_request_count != 0);
694
695 /*
696 * Destroy the remote node context
697 */
698 scic_sds_remote_node_context_destruct(&sci_dev->rnc,
699 scic_sds_cb_remote_device_rnc_destruct_complete, sci_dev);
700
701 /*
702 * Transition to the stopping state and wait for the remote node to
703 * complete being posted and invalidated.
704 */
705 sci_base_state_machine_change_state(&sci_dev->state_machine,
706 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING);
707
708 return SCI_SUCCESS;
709}
710
Dan Williamsab2e8f72011-04-27 16:32:45 -0700711static enum sci_status scic_sds_remote_device_ready_state_stop_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700712 struct scic_sds_remote_device *sci_dev)
713{
714 enum sci_status status = SCI_SUCCESS;
715
716 /* Request the parent state machine to transition to the stopping state */
717 sci_base_state_machine_change_state(&sci_dev->state_machine,
718 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING);
719
720 if (sci_dev->started_request_count == 0) {
721 scic_sds_remote_node_context_destruct(&sci_dev->rnc,
722 scic_sds_cb_remote_device_rnc_destruct_complete,
723 sci_dev);
724 } else
725 status = scic_sds_remote_device_terminate_requests(sci_dev);
726
727 return status;
728}
729
730/**
731 *
732 * @device: The struct scic_sds_remote_device object which is cast to a
733 * struct scic_sds_remote_device object.
734 *
735 * This is the ready state device reset handler enum sci_status
736 */
Dan Williamsab2e8f72011-04-27 16:32:45 -0700737static enum sci_status scic_sds_remote_device_ready_state_reset_handler(
Dan Williams88f3b622011-04-22 19:18:03 -0700738 struct scic_sds_remote_device *sci_dev)
739{
740 /* Request the parent state machine to transition to the stopping state */
741 sci_base_state_machine_change_state(&sci_dev->state_machine,
742 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING);
743
744 return SCI_SUCCESS;
745}
746
747/*
748 * This method will attempt to start a task request for this device object. The
749 * remote device object will issue the start request for the task and if
750 * successful it will start the request for the port object then increment its
751 * own requet count. enum sci_status SCI_SUCCESS if the task request is started for
752 * this device object. SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request
753 * object could not get the resources to start.
754 */
755static enum sci_status scic_sds_remote_device_ready_state_start_task_handler(
756 struct scic_sds_remote_device *sci_dev,
757 struct scic_sds_request *request)
758{
759 enum sci_status result;
760
761 /* See if the port is in a state where we can start the IO request */
762 result = scic_sds_port_start_io(
763 scic_sds_remote_device_get_port(sci_dev), sci_dev, request);
764
765 if (result == SCI_SUCCESS) {
766 result = scic_sds_remote_node_context_start_task(&sci_dev->rnc,
767 request);
768 if (result == SCI_SUCCESS)
769 result = scic_sds_request_start(request);
770
771 scic_sds_remote_device_start_request(sci_dev, request, result);
772 }
773
774 return result;
775}
776
777/*
778 * This method will attempt to start an io request for this device object. The
779 * remote device object will issue the start request for the io and if
780 * successful it will start the request for the port object then increment its
781 * own requet count. enum sci_status SCI_SUCCESS if the io request is started for
782 * this device object. SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request
783 * object could not get the resources to start.
784 */
785static enum sci_status scic_sds_remote_device_ready_state_start_io_handler(
786 struct scic_sds_remote_device *sci_dev,
787 struct scic_sds_request *request)
788{
789 enum sci_status result;
790
791 /* See if the port is in a state where we can start the IO request */
792 result = scic_sds_port_start_io(
793 scic_sds_remote_device_get_port(sci_dev), sci_dev, request);
794
795 if (result == SCI_SUCCESS) {
796 result = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
797 if (result == SCI_SUCCESS)
798 result = scic_sds_request_start(request);
799
800 scic_sds_remote_device_start_request(sci_dev, request, result);
801 }
802
803 return result;
804}
805
806/*
807 * This method will complete the request for the remote device object. The
808 * method will call the completion handler for the request object and if
809 * successful it will complete the request on the port object then decrement
810 * its own started_request_count. enum sci_status
811 */
812static enum sci_status scic_sds_remote_device_ready_state_complete_request_handler(
813 struct scic_sds_remote_device *sci_dev,
814 struct scic_sds_request *request)
815{
816 enum sci_status result;
817
818 result = scic_sds_request_complete(request);
819
820 if (result != SCI_SUCCESS)
821 return result;
822
823 /* See if the port is in a state
824 * where we can start the IO request */
825 result = scic_sds_port_complete_io(
826 scic_sds_remote_device_get_port(sci_dev),
827 sci_dev, request);
828
829 if (result == SCI_SUCCESS)
830 scic_sds_remote_device_decrement_request_count(sci_dev);
831
832 return result;
833}
834
835/*
836 * *****************************************************************************
837 * * STOPPING STATE HANDLERS
838 * ***************************************************************************** */
839
840/**
841 *
842 * @sci_dev: The struct scic_sds_remote_device which is cast into a
843 * struct scic_sds_remote_device.
844 *
845 * This method will stop a struct scic_sds_remote_device that is already in the
846 * SCI_BASE_REMOTE_DEVICE_STATE_STOPPING state. This is not considered an error
847 * since we allow a stop request on a device that is alreay stopping or
848 * stopped. enum sci_status SCI_SUCCESS
849 */
850static enum sci_status scic_sds_remote_device_stopping_state_stop_handler(
851 struct scic_sds_remote_device *device)
852{
853 /*
854 * All requests should have been terminated, but if there is an
855 * attempt to stop a device already in the stopping state, then
856 * try again to terminate. */
857 return scic_sds_remote_device_terminate_requests(device);
858}
859
860
861/**
862 *
863 * @device: The device object for which the request is completing.
864 * @request: The task request that is being completed.
865 *
866 * This method completes requests for this struct scic_sds_remote_device while it is
867 * in the SCI_BASE_REMOTE_DEVICE_STATE_STOPPING state. This method calls the
868 * complete method for the request object and if that is successful the port
869 * object is called to complete the task request. Then the device object itself
870 * completes the task request. If struct scic_sds_remote_device started_request_count
871 * goes to 0 and the invalidate RNC request has completed the device object can
872 * transition to the SCI_BASE_REMOTE_DEVICE_STATE_STOPPED. enum sci_status
873 */
874static enum sci_status scic_sds_remote_device_stopping_state_complete_request_handler(
875 struct scic_sds_remote_device *sci_dev,
876 struct scic_sds_request *request)
877{
878 enum sci_status status = SCI_SUCCESS;
879
880 status = scic_sds_request_complete(request);
881
882 if (status != SCI_SUCCESS)
883 return status;
884
885 status = scic_sds_port_complete_io(scic_sds_remote_device_get_port(sci_dev),
886 sci_dev, request);
887 if (status != SCI_SUCCESS)
888 return status;
889
890 scic_sds_remote_device_decrement_request_count(sci_dev);
891
892 if (scic_sds_remote_device_get_request_count(sci_dev) == 0)
893 scic_sds_remote_node_context_destruct(&sci_dev->rnc,
894 scic_sds_cb_remote_device_rnc_destruct_complete,
895 sci_dev);
896 return SCI_SUCCESS;
897}
898
Dan Williams88f3b622011-04-22 19:18:03 -0700899static enum sci_status scic_sds_remote_device_resetting_state_reset_complete_handler(
900 struct scic_sds_remote_device *sci_dev)
901{
Dan Williamsab2e8f72011-04-27 16:32:45 -0700902 sci_base_state_machine_change_state(&sci_dev->state_machine,
903 SCI_BASE_REMOTE_DEVICE_STATE_READY);
Dan Williams88f3b622011-04-22 19:18:03 -0700904
905 return SCI_SUCCESS;
906}
907
Dan Williams88f3b622011-04-22 19:18:03 -0700908static enum sci_status scic_sds_remote_device_resetting_state_stop_handler(
909 struct scic_sds_remote_device *sci_dev)
910{
911 sci_base_state_machine_change_state(
912 &sci_dev->state_machine,
913 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
914 );
915
916 return SCI_SUCCESS;
917}
918
Dan Williamsab2e8f72011-04-27 16:32:45 -0700919/* complete requests for this device while it is in the
920 * SCI_BASE_REMOTE_DEVICE_STATE_RESETTING state. This method calls the complete
921 * method for the request object and if that is successful the port object is
922 * called to complete the task request. Then the device object itself completes
923 * the task request. enum sci_status
Dan Williams88f3b622011-04-22 19:18:03 -0700924 */
925static enum sci_status scic_sds_remote_device_resetting_state_complete_request_handler(
926 struct scic_sds_remote_device *sci_dev,
927 struct scic_sds_request *request)
928{
929 enum sci_status status = SCI_SUCCESS;
930
931 status = scic_sds_request_complete(request);
932
933 if (status == SCI_SUCCESS) {
934 status = scic_sds_port_complete_io(
935 scic_sds_remote_device_get_port(sci_dev),
936 sci_dev, request);
937
938 if (status == SCI_SUCCESS) {
939 scic_sds_remote_device_decrement_request_count(sci_dev);
940 }
941 }
942
943 return status;
944}
945
Dan Williamsab2e8f72011-04-27 16:32:45 -0700946static enum sci_status scic_sds_stp_remote_device_complete_request(struct scic_sds_remote_device *sci_dev,
947 struct scic_sds_request *sci_req)
948{
949 enum sci_status status;
950
951 status = scic_sds_io_request_complete(sci_req);
952 if (status != SCI_SUCCESS)
953 goto out;
954
955 status = scic_sds_port_complete_io(sci_dev->owning_port, sci_dev, sci_req);
956 if (status != SCI_SUCCESS)
957 goto out;
958
959 scic_sds_remote_device_decrement_request_count(sci_dev);
960 if (sci_req->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
961 /* This request causes hardware error, device needs to be Lun Reset.
962 * So here we force the state machine to IDLE state so the rest IOs
963 * can reach RNC state handler, these IOs will be completed by RNC with
964 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
965 */
966 sci_base_state_machine_change_state(&sci_dev->state_machine,
967 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET);
968 } else if (scic_sds_remote_device_get_request_count(sci_dev) == 0)
969 sci_base_state_machine_change_state(&sci_dev->state_machine,
970 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
971
972
973 out:
974 if (status != SCI_SUCCESS)
975 dev_err(scirdev_to_dev(sci_dev),
976 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
977 "could not complete\n", __func__, sci_dev->owning_port,
978 sci_dev, sci_req, status);
979
980 return status;
981}
982
983/* scic_sds_stp_remote_device_ready_substate_start_request_handler - start stp
984 * @device: The target device a task management request towards to.
985 * @request: The task request.
986 *
987 * This is the READY NCQ substate handler to start task management request. In
988 * this routine, we suspend and resume the RNC. enum sci_status Always return
989 * SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to let
990 * controller_start_task_handler know that the controller can't post TC for
991 * task request yet, instead, when RNC gets resumed, a controller_continue_task
992 * callback will be called.
993 */
994static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
995 struct scic_sds_remote_device *device,
996 struct scic_sds_request *request)
997{
998 enum sci_status status;
999
1000 /* Will the port allow the io request to start? */
1001 status = device->owning_port->state_handlers->start_io_handler(
1002 device->owning_port, device, request);
1003 if (status != SCI_SUCCESS)
1004 return status;
1005
1006 status = scic_sds_remote_node_context_start_task(&device->rnc, request);
1007 if (status != SCI_SUCCESS)
1008 goto out;
1009
1010 status = request->state_handlers->start_handler(request);
1011 if (status != SCI_SUCCESS)
1012 goto out;
1013
1014 /*
1015 * Note: If the remote device state is not IDLE this will replace
1016 * the request that probably resulted in the task management request.
1017 */
1018 device->working_request = request;
1019 sci_base_state_machine_change_state(&device->state_machine,
1020 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
1021
1022 /*
1023 * The remote node context must cleanup the TCi to NCQ mapping table.
1024 * The only way to do this correctly is to either write to the TLCR
1025 * register or to invalidate and repost the RNC. In either case the
1026 * remote node context state machine will take the correct action when
1027 * the remote node context is suspended and later resumed.
1028 */
1029 scic_sds_remote_node_context_suspend(&device->rnc,
1030 SCI_SOFTWARE_SUSPENSION, NULL, NULL);
1031 scic_sds_remote_node_context_resume(&device->rnc,
1032 scic_sds_remote_device_continue_request,
1033 device);
1034
1035out:
1036 scic_sds_remote_device_start_request(device, request, status);
1037 /*
1038 * We need to let the controller start request handler know that it can't
1039 * post TC yet. We will provide a callback function to post TC when RNC gets
1040 * resumed.
1041 */
1042 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
1043}
1044
1045/* handle the start io operation for a sata device that is in the command idle
1046 * state. - Evalute the type of IO request to be started - If its an NCQ
1047 * request change to NCQ substate - If its any other command change to the CMD
1048 * substate
1049 *
1050 * If this is a softreset we may want to have a different substate.
1051 */
1052static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
1053 struct scic_sds_remote_device *sci_dev,
1054 struct scic_sds_request *request)
1055{
1056 enum sci_status status;
1057 struct isci_request *isci_request = request->ireq;
1058 enum scic_sds_remote_device_states new_state;
1059
1060 /* Will the port allow the io request to start? */
1061 status = sci_dev->owning_port->state_handlers->start_io_handler(
1062 sci_dev->owning_port, sci_dev, request);
1063 if (status != SCI_SUCCESS)
1064 return status;
1065
1066 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
1067 if (status != SCI_SUCCESS)
1068 goto out;
1069
1070 status = request->state_handlers->start_handler(request);
1071 if (status != SCI_SUCCESS)
1072 goto out;
1073
1074 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA)
1075 new_state = SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ;
1076 else {
1077 sci_dev->working_request = request;
1078 new_state = SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD;
1079 }
1080 sci_base_state_machine_change_state(&sci_dev->state_machine, new_state);
1081out:
1082 scic_sds_remote_device_start_request(sci_dev, request, status);
1083 return status;
1084}
1085
1086
1087static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
1088 struct scic_sds_remote_device *sci_dev,
1089 u32 event_code)
1090{
1091 enum sci_status status;
1092
1093 status = scic_sds_remote_device_general_event_handler(sci_dev, event_code);
1094 if (status != SCI_SUCCESS)
1095 return status;
1096
1097 /* We pick up suspension events to handle specifically to this state. We
1098 * resume the RNC right away. enum sci_status
1099 */
1100 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
1101 scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
1102 status = scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL);
1103
1104 return status;
1105}
1106
1107static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
1108 struct scic_sds_remote_device *sci_dev,
1109 struct scic_sds_request *request)
1110{
1111 enum sci_status status;
1112 struct isci_request *isci_request = request->ireq;
1113 scic_sds_port_io_request_handler_t start_io;
1114
1115 if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
1116 start_io = sci_dev->owning_port->state_handlers->start_io_handler;
1117 status = start_io(sci_dev->owning_port, sci_dev, request);
1118 if (status != SCI_SUCCESS)
1119 return status;
1120
1121 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
Dan Williamsf619fff2011-05-01 10:13:04 -07001122 if (status == SCI_SUCCESS)
1123 status = request->state_handlers->start_handler(request);
Dan Williamsab2e8f72011-04-27 16:32:45 -07001124
1125 scic_sds_remote_device_start_request(sci_dev, request, status);
1126 } else
1127 status = SCI_FAILURE_INVALID_STATE;
1128
1129 return status;
1130}
1131
1132static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev,
1133 u32 frame_index)
1134{
1135 enum sci_status status;
1136 struct sata_fis_header *frame_header;
1137 struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller;
1138
1139 status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
1140 frame_index,
1141 (void **)&frame_header);
1142 if (status != SCI_SUCCESS)
1143 return status;
1144
1145 if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
1146 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
1147 sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
1148
1149 /* TODO Check sactive and complete associated IO if any. */
1150
1151 sci_base_state_machine_change_state(&sci_dev->state_machine,
1152 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
1153 } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H &&
1154 (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
1155 /*
1156 * Some devices return D2H FIS when an NCQ error is detected.
1157 * Treat this like an SDB error FIS ready reason.
1158 */
1159 sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
1160
1161 sci_base_state_machine_change_state(&sci_dev->state_machine,
1162 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
1163 } else
1164 status = SCI_FAILURE;
1165
1166 scic_sds_controller_release_frame(scic, frame_index);
1167
1168 return status;
1169}
1170
1171static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
1172 struct scic_sds_remote_device *device,
1173 struct scic_sds_request *request)
1174{
1175 /* device is already handling a command it can not accept new commands
1176 * until this one is complete.
1177 */
1178 return SCI_FAILURE_INVALID_STATE;
1179}
1180
1181static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
1182 struct scic_sds_remote_device *sci_dev,
1183 u32 suspend_type)
1184{
1185 enum sci_status status;
1186
1187 status = scic_sds_remote_node_context_suspend(&sci_dev->rnc,
1188 suspend_type, NULL, NULL);
1189
1190 return status;
1191}
1192
1193static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
1194 struct scic_sds_remote_device *sci_dev,
1195 u32 frame_index)
1196{
1197 /* The device doe not process any UF received from the hardware while
1198 * in this state. All unsolicited frames are forwarded to the io
1199 * request object.
1200 */
1201 return scic_sds_io_request_frame_handler(sci_dev->working_request,
1202 frame_index);
1203}
1204
1205static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
1206 struct scic_sds_remote_device *device,
1207 struct scic_sds_request *request)
1208{
1209 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
1210}
1211
1212static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
1213 struct scic_sds_remote_device *device,
1214 struct scic_sds_request *request)
1215{
1216 struct scic_sds_request *sci_req = request;
1217 enum sci_status status;
1218
1219 status = scic_sds_io_request_complete(sci_req);
1220 if (status != SCI_SUCCESS)
1221 goto out;
1222
1223 status = scic_sds_port_complete_io(device->owning_port, device, sci_req);
1224 if (status != SCI_SUCCESS)
1225 goto out;
1226
1227 scic_sds_remote_device_decrement_request_count(device);
1228 out:
1229 if (status != SCI_SUCCESS)
1230 dev_err(scirdev_to_dev(device),
1231 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
1232 "could not complete\n",
1233 __func__, device->owning_port, device, sci_req, status);
1234
1235 return status;
1236}
1237
1238static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *_dev)
1239{
1240 struct scic_sds_remote_device *sci_dev = _dev;
1241 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
1242 struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller;
1243
1244 /* For NCQ operation we do not issue a isci_remote_device_not_ready().
1245 * As a result, avoid sending the ready notification.
1246 */
1247 if (sci_dev->state_machine.previous_state_id != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
1248 isci_remote_device_ready(scic->ihost, idev);
1249}
1250
1251static enum sci_status scic_sds_smp_remote_device_ready_idle_substate_start_io_handler(
1252 struct scic_sds_remote_device *sci_dev,
1253 struct scic_sds_request *sci_req)
1254{
1255 enum sci_status status;
1256
1257 /* Will the port allow the io request to start? */
1258 status = sci_dev->owning_port->state_handlers->start_io_handler(
1259 sci_dev->owning_port, sci_dev, sci_req);
1260 if (status != SCI_SUCCESS)
1261 return status;
1262
1263 status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, sci_req);
1264 if (status != SCI_SUCCESS)
Dan Williamsf619fff2011-05-01 10:13:04 -07001265 goto out;
Dan Williamsab2e8f72011-04-27 16:32:45 -07001266
1267 status = scic_sds_request_start(sci_req);
1268 if (status != SCI_SUCCESS)
Dan Williamsf619fff2011-05-01 10:13:04 -07001269 goto out;
Dan Williamsab2e8f72011-04-27 16:32:45 -07001270
1271 sci_dev->working_request = sci_req;
1272 sci_base_state_machine_change_state(&sci_dev->state_machine,
1273 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
1274
Dan Williamsf619fff2011-05-01 10:13:04 -07001275 out:
Dan Williamsab2e8f72011-04-27 16:32:45 -07001276 scic_sds_remote_device_start_request(sci_dev, sci_req, status);
1277
1278 return status;
1279}
1280
1281static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler(
1282 struct scic_sds_remote_device *device,
1283 struct scic_sds_request *request)
1284{
1285 /* device is already handling a command it can not accept new commands
1286 * until this one is complete.
1287 */
1288 return SCI_FAILURE_INVALID_STATE;
1289}
1290
1291static enum sci_status
1292scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler(struct scic_sds_remote_device *sci_dev,
1293 struct scic_sds_request *sci_req)
1294{
1295 enum sci_status status;
1296
1297 status = scic_sds_io_request_complete(sci_req);
1298 if (status != SCI_SUCCESS)
1299 return status;
1300
1301 status = scic_sds_port_complete_io(sci_dev->owning_port, sci_dev, sci_req);
1302 if (status != SCI_SUCCESS) {
1303 dev_err(scirdev_to_dev(sci_dev),
1304 "%s: SCIC SDS Remote Device 0x%p io request "
1305 "0x%p could not be completd on the port 0x%p "
1306 "failed with status %d.\n", __func__, sci_dev, sci_req,
1307 sci_dev->owning_port, status);
1308 return status;
1309 }
1310
1311 scic_sds_remote_device_decrement_request_count(sci_dev);
1312 sci_base_state_machine_change_state(&sci_dev->state_machine,
1313 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
1314
1315 return status;
1316}
1317
1318static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handler(
1319 struct scic_sds_remote_device *sci_dev,
1320 u32 frame_index)
1321{
1322 enum sci_status status;
1323
1324 /* The device does not process any UF received from the hardware while
1325 * in this state. All unsolicited frames are forwarded to the io request
1326 * object.
1327 */
1328 status = scic_sds_io_request_frame_handler(
1329 sci_dev->working_request,
1330 frame_index
1331 );
1332
1333 return status;
1334}
1335
Dan Williams88f3b622011-04-22 19:18:03 -07001336static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = {
1337 [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001338 .stop_handler = scic_sds_remote_device_default_stop_handler,
1339 .fail_handler = scic_sds_remote_device_default_fail_handler,
1340 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1341 .reset_handler = scic_sds_remote_device_default_reset_handler,
1342 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1343 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1344 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1345 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1346 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1347 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1348 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1349 .resume_handler = scic_sds_remote_device_default_resume_handler,
1350 .event_handler = scic_sds_remote_device_default_event_handler,
1351 .frame_handler = scic_sds_remote_device_default_frame_handler
1352 },
1353 [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001354 .stop_handler = scic_sds_remote_device_stopped_state_stop_handler,
1355 .fail_handler = scic_sds_remote_device_default_fail_handler,
1356 .destruct_handler = scic_sds_remote_device_stopped_state_destruct_handler,
1357 .reset_handler = scic_sds_remote_device_default_reset_handler,
1358 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1359 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1360 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1361 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1362 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1363 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1364 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1365 .resume_handler = scic_sds_remote_device_default_resume_handler,
1366 .event_handler = scic_sds_remote_device_default_event_handler,
1367 .frame_handler = scic_sds_remote_device_default_frame_handler
1368 },
1369 [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001370 .stop_handler = scic_sds_remote_device_starting_state_stop_handler,
1371 .fail_handler = scic_sds_remote_device_default_fail_handler,
1372 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1373 .reset_handler = scic_sds_remote_device_default_reset_handler,
1374 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1375 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1376 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1377 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1378 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1379 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1380 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1381 .resume_handler = scic_sds_remote_device_default_resume_handler,
1382 .event_handler = scic_sds_remote_device_general_event_handler,
1383 .frame_handler = scic_sds_remote_device_default_frame_handler
1384 },
1385 [SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001386 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1387 .fail_handler = scic_sds_remote_device_default_fail_handler,
1388 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1389 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
1390 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1391 .start_io_handler = scic_sds_remote_device_ready_state_start_io_handler,
1392 .complete_io_handler = scic_sds_remote_device_ready_state_complete_request_handler,
1393 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1394 .start_task_handler = scic_sds_remote_device_ready_state_start_task_handler,
1395 .complete_task_handler = scic_sds_remote_device_ready_state_complete_request_handler,
1396 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1397 .resume_handler = scic_sds_remote_device_default_resume_handler,
1398 .event_handler = scic_sds_remote_device_general_event_handler,
1399 .frame_handler = scic_sds_remote_device_general_frame_handler,
1400 },
Dan Williamsab2e8f72011-04-27 16:32:45 -07001401 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001402 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1403 .fail_handler = scic_sds_remote_device_default_fail_handler,
1404 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1405 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
1406 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1407 .start_io_handler = scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
1408 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1409 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1410 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
1411 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1412 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1413 .resume_handler = scic_sds_remote_device_default_resume_handler,
1414 .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler,
1415 .frame_handler = scic_sds_remote_device_default_frame_handler
1416 },
1417 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001418 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1419 .fail_handler = scic_sds_remote_device_default_fail_handler,
1420 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1421 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
1422 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1423 .start_io_handler = scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
1424 .complete_io_handler = scic_sds_stp_remote_device_complete_request,
1425 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1426 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
1427 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
1428 .suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
1429 .resume_handler = scic_sds_remote_device_default_resume_handler,
1430 .event_handler = scic_sds_remote_device_general_event_handler,
1431 .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
1432 },
1433 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001434 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1435 .fail_handler = scic_sds_remote_device_default_fail_handler,
1436 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1437 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
1438 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1439 .start_io_handler = scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
1440 .complete_io_handler = scic_sds_stp_remote_device_complete_request,
1441 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1442 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
1443 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
1444 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1445 .resume_handler = scic_sds_remote_device_default_resume_handler,
1446 .event_handler = scic_sds_remote_device_general_event_handler,
1447 .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
1448 },
1449 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001450 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1451 .fail_handler = scic_sds_remote_device_default_fail_handler,
1452 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1453 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
1454 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1455 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1456 .complete_io_handler = scic_sds_stp_remote_device_complete_request,
1457 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1458 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
1459 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
1460 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1461 .resume_handler = scic_sds_remote_device_default_resume_handler,
1462 .event_handler = scic_sds_remote_device_general_event_handler,
1463 .frame_handler = scic_sds_remote_device_general_frame_handler
1464 },
1465 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001466 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1467 .fail_handler = scic_sds_remote_device_default_fail_handler,
1468 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1469 .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
1470 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1471 .start_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
1472 .complete_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
1473 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1474 .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
1475 .complete_task_handler = scic_sds_stp_remote_device_complete_request,
1476 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1477 .resume_handler = scic_sds_remote_device_default_resume_handler,
1478 .event_handler = scic_sds_remote_device_general_event_handler,
1479 .frame_handler = scic_sds_remote_device_general_frame_handler
1480 },
1481 [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001482 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1483 .fail_handler = scic_sds_remote_device_default_fail_handler,
1484 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1485 .reset_handler = scic_sds_remote_device_default_reset_handler,
1486 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1487 .start_io_handler = scic_sds_smp_remote_device_ready_idle_substate_start_io_handler,
1488 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1489 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1490 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1491 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1492 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1493 .resume_handler = scic_sds_remote_device_default_resume_handler,
1494 .event_handler = scic_sds_remote_device_general_event_handler,
1495 .frame_handler = scic_sds_remote_device_default_frame_handler
1496 },
1497 [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
Dan Williamsab2e8f72011-04-27 16:32:45 -07001498 .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
1499 .fail_handler = scic_sds_remote_device_default_fail_handler,
1500 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1501 .reset_handler = scic_sds_remote_device_default_reset_handler,
1502 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1503 .start_io_handler = scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler,
1504 .complete_io_handler = scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler,
1505 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1506 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1507 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1508 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1509 .resume_handler = scic_sds_remote_device_default_resume_handler,
1510 .event_handler = scic_sds_remote_device_general_event_handler,
1511 .frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
1512 },
Dan Williams88f3b622011-04-22 19:18:03 -07001513 [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001514 .stop_handler = scic_sds_remote_device_stopping_state_stop_handler,
1515 .fail_handler = scic_sds_remote_device_default_fail_handler,
1516 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1517 .reset_handler = scic_sds_remote_device_default_reset_handler,
1518 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1519 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1520 .complete_io_handler = scic_sds_remote_device_stopping_state_complete_request_handler,
1521 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1522 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1523 .complete_task_handler = scic_sds_remote_device_stopping_state_complete_request_handler,
1524 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1525 .resume_handler = scic_sds_remote_device_default_resume_handler,
1526 .event_handler = scic_sds_remote_device_general_event_handler,
1527 .frame_handler = scic_sds_remote_device_general_frame_handler
1528 },
1529 [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001530 .stop_handler = scic_sds_remote_device_default_stop_handler,
1531 .fail_handler = scic_sds_remote_device_default_fail_handler,
1532 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1533 .reset_handler = scic_sds_remote_device_default_reset_handler,
1534 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1535 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1536 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1537 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1538 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1539 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1540 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1541 .resume_handler = scic_sds_remote_device_default_resume_handler,
1542 .event_handler = scic_sds_remote_device_default_event_handler,
1543 .frame_handler = scic_sds_remote_device_general_frame_handler
1544 },
1545 [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001546 .stop_handler = scic_sds_remote_device_resetting_state_stop_handler,
1547 .fail_handler = scic_sds_remote_device_default_fail_handler,
1548 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1549 .reset_handler = scic_sds_remote_device_default_reset_handler,
1550 .reset_complete_handler = scic_sds_remote_device_resetting_state_reset_complete_handler,
1551 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1552 .complete_io_handler = scic_sds_remote_device_resetting_state_complete_request_handler,
1553 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1554 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1555 .complete_task_handler = scic_sds_remote_device_resetting_state_complete_request_handler,
1556 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1557 .resume_handler = scic_sds_remote_device_default_resume_handler,
1558 .event_handler = scic_sds_remote_device_default_event_handler,
1559 .frame_handler = scic_sds_remote_device_general_frame_handler
1560 },
1561 [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
Dan Williams88f3b622011-04-22 19:18:03 -07001562 .stop_handler = scic_sds_remote_device_default_stop_handler,
1563 .fail_handler = scic_sds_remote_device_default_fail_handler,
1564 .destruct_handler = scic_sds_remote_device_default_destruct_handler,
1565 .reset_handler = scic_sds_remote_device_default_reset_handler,
1566 .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
1567 .start_io_handler = scic_sds_remote_device_default_start_request_handler,
1568 .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
1569 .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
1570 .start_task_handler = scic_sds_remote_device_default_start_request_handler,
1571 .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
1572 .suspend_handler = scic_sds_remote_device_default_suspend_handler,
1573 .resume_handler = scic_sds_remote_device_default_resume_handler,
1574 .event_handler = scic_sds_remote_device_default_event_handler,
1575 .frame_handler = scic_sds_remote_device_default_frame_handler
1576 }
1577};
1578
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001579static void scic_sds_remote_device_initial_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001580{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001581 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001582
Dan Williams88f3b622011-04-22 19:18:03 -07001583 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1584 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL);
1585
1586 /* Initial state is a transitional state to the stopped state */
1587 sci_base_state_machine_change_state(&sci_dev->state_machine,
1588 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED);
1589}
1590
1591/**
Dan Williams88f3b622011-04-22 19:18:03 -07001592 * scic_remote_device_destruct() - free remote node context and destruct
1593 * @remote_device: This parameter specifies the remote device to be destructed.
1594 *
1595 * Remote device objects are a limited resource. As such, they must be
1596 * protected. Thus calls to construct and destruct are mutually exclusive and
1597 * non-reentrant. The return value shall indicate if the device was
1598 * successfully destructed or if some failure occurred. enum sci_status This value
1599 * is returned if the device is successfully destructed.
1600 * SCI_FAILURE_INVALID_REMOTE_DEVICE This value is returned if the supplied
1601 * device isn't valid (e.g. it's already been destoryed, the handle isn't
1602 * valid, etc.).
1603 */
1604static enum sci_status scic_remote_device_destruct(struct scic_sds_remote_device *sci_dev)
1605{
1606 return sci_dev->state_handlers->destruct_handler(sci_dev);
1607}
1608
Dan Williams6f231dd2011-07-02 22:56:22 -07001609/**
1610 * isci_remote_device_deconstruct() - This function frees an isci_remote_device.
Dan Williamsd9c37392011-03-03 17:59:32 -08001611 * @ihost: This parameter specifies the isci host object.
1612 * @idev: This parameter specifies the remote device to be freed.
Dan Williams6f231dd2011-07-02 22:56:22 -07001613 *
1614 */
Dan Williamsd9c37392011-03-03 17:59:32 -08001615static void isci_remote_device_deconstruct(struct isci_host *ihost, struct isci_remote_device *idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07001616{
Dan Williamsd9c37392011-03-03 17:59:32 -08001617 dev_dbg(&ihost->pdev->dev,
1618 "%s: isci_device = %p\n", __func__, idev);
Dan Williams6f231dd2011-07-02 22:56:22 -07001619
1620 /* There should not be any outstanding io's. All paths to
1621 * here should go through isci_remote_device_nuke_requests.
1622 * If we hit this condition, we will need a way to complete
1623 * io requests in process */
Dan Williamsd9c37392011-03-03 17:59:32 -08001624 while (!list_empty(&idev->reqs_in_process)) {
Dan Williams6f231dd2011-07-02 22:56:22 -07001625
Dan Williamsd9c37392011-03-03 17:59:32 -08001626 dev_err(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07001627 "%s: ** request list not empty! **\n", __func__);
1628 BUG();
1629 }
1630
Dan Williams57f20f42011-04-21 18:14:45 -07001631 scic_remote_device_destruct(&idev->sci);
Dan Williamsd9c37392011-03-03 17:59:32 -08001632 idev->domain_dev->lldd_dev = NULL;
1633 idev->domain_dev = NULL;
1634 idev->isci_port = NULL;
1635 list_del_init(&idev->node);
Dan Williams6ad31fe2011-03-04 12:10:29 -08001636
Dan Williamsd9c37392011-03-03 17:59:32 -08001637 clear_bit(IDEV_START_PENDING, &idev->flags);
1638 clear_bit(IDEV_STOP_PENDING, &idev->flags);
1639 wake_up(&ihost->eventq);
Dan Williams6f231dd2011-07-02 22:56:22 -07001640}
1641
Dan Williams88f3b622011-04-22 19:18:03 -07001642/**
1643 * isci_remote_device_stop_complete() - This function is called by the scic
1644 * when the remote device stop has completed. We mark the isci device as not
1645 * ready and remove the isci remote device.
1646 * @ihost: This parameter specifies the isci host object.
1647 * @idev: This parameter specifies the remote device.
1648 * @status: This parameter specifies status of the completion.
1649 *
1650 */
1651static void isci_remote_device_stop_complete(struct isci_host *ihost,
1652 struct isci_remote_device *idev)
1653{
1654 dev_dbg(&ihost->pdev->dev, "%s: complete idev = %p\n", __func__, idev);
1655
1656 isci_remote_device_change_state(idev, isci_stopped);
1657
1658 /* after stop, we can tear down resources. */
1659 isci_remote_device_deconstruct(ihost, idev);
1660}
1661
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001662static void scic_sds_remote_device_stopped_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001663{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001664 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001665 struct scic_sds_controller *scic;
1666 struct isci_remote_device *idev;
1667 struct isci_host *ihost;
1668 u32 prev_state;
1669
Dan Williams88f3b622011-04-22 19:18:03 -07001670 scic = scic_sds_remote_device_get_controller(sci_dev);
Maciej Patelczykd3757c32011-04-28 22:06:06 +00001671 ihost = scic->ihost;
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001672 idev = sci_dev_to_idev(sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07001673
1674 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1675 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED);
1676
1677 /* If we are entering from the stopping state let the SCI User know that
1678 * the stop operation has completed.
1679 */
1680 prev_state = sci_dev->state_machine.previous_state_id;
1681 if (prev_state == SCI_BASE_REMOTE_DEVICE_STATE_STOPPING)
1682 isci_remote_device_stop_complete(ihost, idev);
1683
1684 scic_sds_controller_remote_device_stopped(scic, sci_dev);
1685}
1686
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001687static void scic_sds_remote_device_starting_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001688{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001689 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001690 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
Maciej Patelczykd3757c32011-04-28 22:06:06 +00001691 struct isci_host *ihost = scic->ihost;
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001692 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07001693
1694 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1695 SCI_BASE_REMOTE_DEVICE_STATE_STARTING);
1696
1697 isci_remote_device_not_ready(ihost, idev,
1698 SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED);
1699}
1700
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001701static void scic_sds_remote_device_ready_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001702{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001703 struct scic_sds_remote_device *sci_dev = object;
Dan Williamsab2e8f72011-04-27 16:32:45 -07001704 struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller;
1705 struct domain_device *dev = sci_dev_to_domain(sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07001706
1707 SET_STATE_HANDLER(sci_dev,
1708 scic_sds_remote_device_state_handler_table,
1709 SCI_BASE_REMOTE_DEVICE_STATE_READY);
1710
1711 scic->remote_device_sequence[sci_dev->rnc.remote_node_index]++;
1712
Dan Williamsab2e8f72011-04-27 16:32:45 -07001713 if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) {
1714 sci_base_state_machine_change_state(&sci_dev->state_machine,
1715 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
1716 } else if (dev_is_expander(dev)) {
1717 sci_base_state_machine_change_state(&sci_dev->state_machine,
1718 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
1719 } else
1720 isci_remote_device_ready(scic->ihost, sci_dev_to_idev(sci_dev));
Dan Williams88f3b622011-04-22 19:18:03 -07001721}
1722
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001723static void scic_sds_remote_device_ready_state_exit(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001724{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001725 struct scic_sds_remote_device *sci_dev = object;
Dan Williamsab2e8f72011-04-27 16:32:45 -07001726 struct domain_device *dev = sci_dev_to_domain(sci_dev);
1727
1728 if (dev->dev_type == SAS_END_DEV) {
1729 struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller;
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001730 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07001731
Dan Williamsab2e8f72011-04-27 16:32:45 -07001732 isci_remote_device_not_ready(scic->ihost, idev,
Dan Williams88f3b622011-04-22 19:18:03 -07001733 SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED);
1734 }
1735}
1736
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001737static void scic_sds_remote_device_stopping_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001738{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001739 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001740
1741 SET_STATE_HANDLER(
1742 sci_dev,
1743 scic_sds_remote_device_state_handler_table,
1744 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1745 );
1746}
1747
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001748static void scic_sds_remote_device_failed_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001749{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001750 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001751
1752 SET_STATE_HANDLER(
1753 sci_dev,
1754 scic_sds_remote_device_state_handler_table,
1755 SCI_BASE_REMOTE_DEVICE_STATE_FAILED
1756 );
1757}
1758
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001759static void scic_sds_remote_device_resetting_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001760{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001761 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001762
1763 SET_STATE_HANDLER(
1764 sci_dev,
1765 scic_sds_remote_device_state_handler_table,
1766 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING
1767 );
1768
1769 scic_sds_remote_node_context_suspend(
1770 &sci_dev->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
1771}
1772
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001773static void scic_sds_remote_device_resetting_state_exit(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001774{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001775 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001776
1777 scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL);
1778}
1779
Maciej Patelczyk9a0fff72011-04-28 22:06:01 +00001780static void scic_sds_remote_device_final_state_enter(void *object)
Dan Williams88f3b622011-04-22 19:18:03 -07001781{
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001782 struct scic_sds_remote_device *sci_dev = object;
Dan Williams88f3b622011-04-22 19:18:03 -07001783
1784 SET_STATE_HANDLER(
1785 sci_dev,
1786 scic_sds_remote_device_state_handler_table,
1787 SCI_BASE_REMOTE_DEVICE_STATE_FINAL
1788 );
1789}
1790
Dan Williamsab2e8f72011-04-27 16:32:45 -07001791static void scic_sds_stp_remote_device_ready_idle_substate_enter(void *object)
1792{
1793 struct scic_sds_remote_device *sci_dev = object;
1794
1795 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1796 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
1797
1798 sci_dev->working_request = NULL;
1799 if (scic_sds_remote_node_context_is_ready(&sci_dev->rnc)) {
1800 /*
1801 * Since the RNC is ready, it's alright to finish completion
1802 * processing (e.g. signal the remote device is ready). */
1803 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(sci_dev);
1804 } else {
1805 scic_sds_remote_node_context_resume(&sci_dev->rnc,
1806 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
1807 sci_dev);
1808 }
1809}
1810
1811static void scic_sds_stp_remote_device_ready_cmd_substate_enter(void *object)
1812{
1813 struct scic_sds_remote_device *sci_dev = object;
1814 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
1815
1816 BUG_ON(sci_dev->working_request == NULL);
1817
1818 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1819 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
1820
1821 isci_remote_device_not_ready(scic->ihost, sci_dev_to_idev(sci_dev),
1822 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
1823}
1824
1825static void scic_sds_stp_remote_device_ready_ncq_substate_enter(void *object)
1826{
1827 struct scic_sds_remote_device *sci_dev = object;
1828
1829 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1830 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
1831}
1832
1833static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(void *object)
1834{
1835 struct scic_sds_remote_device *sci_dev = object;
1836 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
1837 struct isci_remote_device *idev = sci_dev_to_idev(sci_dev);
1838
1839 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1840 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
1841
1842 if (sci_dev->not_ready_reason == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
1843 isci_remote_device_not_ready(scic->ihost, idev,
1844 sci_dev->not_ready_reason);
1845}
1846
1847static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(void *object)
1848{
1849 struct scic_sds_remote_device *sci_dev = object;
1850
1851 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1852 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET);
1853}
1854
1855static void scic_sds_smp_remote_device_ready_idle_substate_enter(void *object)
1856{
1857 struct scic_sds_remote_device *sci_dev = object;
1858 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
1859
1860 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1861 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
1862
1863 isci_remote_device_ready(scic->ihost, sci_dev_to_idev(sci_dev));
1864}
1865
1866static void scic_sds_smp_remote_device_ready_cmd_substate_enter(void *object)
1867{
1868 struct scic_sds_remote_device *sci_dev = object;
1869 struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
1870
1871 BUG_ON(sci_dev->working_request == NULL);
1872
1873 SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table,
1874 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
1875
1876 isci_remote_device_not_ready(scic->ihost, sci_dev_to_idev(sci_dev),
1877 SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED);
1878}
1879
1880static void scic_sds_smp_remote_device_ready_cmd_substate_exit(void *object)
1881{
1882 struct scic_sds_remote_device *sci_dev = object;
1883
1884 sci_dev->working_request = NULL;
1885}
Dan Williams88f3b622011-04-22 19:18:03 -07001886
1887static const struct sci_base_state scic_sds_remote_device_state_table[] = {
1888 [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
1889 .enter_state = scic_sds_remote_device_initial_state_enter,
1890 },
1891 [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
1892 .enter_state = scic_sds_remote_device_stopped_state_enter,
1893 },
1894 [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
1895 .enter_state = scic_sds_remote_device_starting_state_enter,
1896 },
1897 [SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
1898 .enter_state = scic_sds_remote_device_ready_state_enter,
1899 .exit_state = scic_sds_remote_device_ready_state_exit
1900 },
Dan Williamsab2e8f72011-04-27 16:32:45 -07001901 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
1902 .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
1903 },
1904 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
1905 .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
1906 },
1907 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
1908 .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
1909 },
1910 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
1911 .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
1912 },
1913 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
1914 .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
1915 },
1916 [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
1917 .enter_state = scic_sds_smp_remote_device_ready_idle_substate_enter,
1918 },
1919 [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
1920 .enter_state = scic_sds_smp_remote_device_ready_cmd_substate_enter,
1921 .exit_state = scic_sds_smp_remote_device_ready_cmd_substate_exit,
1922 },
Dan Williams88f3b622011-04-22 19:18:03 -07001923 [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = {
1924 .enter_state = scic_sds_remote_device_stopping_state_enter,
1925 },
1926 [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
1927 .enter_state = scic_sds_remote_device_failed_state_enter,
1928 },
1929 [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
1930 .enter_state = scic_sds_remote_device_resetting_state_enter,
1931 .exit_state = scic_sds_remote_device_resetting_state_exit
1932 },
1933 [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
1934 .enter_state = scic_sds_remote_device_final_state_enter,
1935 },
1936};
1937
1938/**
Dan Williamsb87ee302011-04-25 11:48:29 -07001939 * scic_remote_device_construct() - common construction
Dan Williams88f3b622011-04-22 19:18:03 -07001940 * @sci_port: SAS/SATA port through which this device is accessed.
1941 * @sci_dev: remote device to construct
1942 *
Dan Williamsb87ee302011-04-25 11:48:29 -07001943 * This routine just performs benign initialization and does not
1944 * allocate the remote_node_context which is left to
1945 * scic_remote_device_[de]a_construct(). scic_remote_device_destruct()
1946 * frees the remote_node_context(s) for the device.
Dan Williams88f3b622011-04-22 19:18:03 -07001947 */
1948static void scic_remote_device_construct(struct scic_sds_port *sci_port,
1949 struct scic_sds_remote_device *sci_dev)
1950{
1951 sci_dev->owning_port = sci_port;
1952 sci_dev->started_request_count = 0;
Dan Williams88f3b622011-04-22 19:18:03 -07001953
1954 sci_base_state_machine_construct(
1955 &sci_dev->state_machine,
Maciej Patelczyk5d937e92011-04-28 22:06:21 +00001956 sci_dev,
Dan Williams88f3b622011-04-22 19:18:03 -07001957 scic_sds_remote_device_state_table,
1958 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL
1959 );
1960
1961 sci_base_state_machine_start(
1962 &sci_dev->state_machine
1963 );
1964
1965 scic_sds_remote_node_context_construct(&sci_dev->rnc,
1966 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
Dan Williams88f3b622011-04-22 19:18:03 -07001967}
1968
1969/**
Dan Williamsb87ee302011-04-25 11:48:29 -07001970 * scic_remote_device_da_construct() - construct direct attached device.
Dan Williams88f3b622011-04-22 19:18:03 -07001971 *
Dan Williamsb87ee302011-04-25 11:48:29 -07001972 * The information (e.g. IAF, Signature FIS, etc.) necessary to build
1973 * the device is known to the SCI Core since it is contained in the
1974 * scic_phy object. Remote node context(s) is/are a global resource
1975 * allocated by this routine, freed by scic_remote_device_destruct().
1976 *
1977 * Returns:
1978 * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
1979 * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
1980 * sata-only controller instance.
1981 * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
Dan Williams88f3b622011-04-22 19:18:03 -07001982 */
Dan Williamsb87ee302011-04-25 11:48:29 -07001983static enum sci_status scic_remote_device_da_construct(struct scic_sds_port *sci_port,
1984 struct scic_sds_remote_device *sci_dev)
Dan Williams88f3b622011-04-22 19:18:03 -07001985{
1986 enum sci_status status;
Dan Williamsa1a113b2011-04-21 18:44:45 -07001987 struct domain_device *dev = sci_dev_to_domain(sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07001988
Dan Williamsb87ee302011-04-25 11:48:29 -07001989 scic_remote_device_construct(sci_port, sci_dev);
1990
Dan Williams88f3b622011-04-22 19:18:03 -07001991 /*
1992 * This information is request to determine how many remote node context
1993 * entries will be needed to store the remote node.
1994 */
Dan Williams88f3b622011-04-22 19:18:03 -07001995 sci_dev->is_direct_attached = true;
Dan Williamsa1a113b2011-04-21 18:44:45 -07001996 status = scic_sds_controller_allocate_remote_node_context(sci_port->owning_controller,
1997 sci_dev,
Dan Williamsab2e8f72011-04-27 16:32:45 -07001998 &sci_dev->rnc.remote_node_index);
Dan Williams88f3b622011-04-22 19:18:03 -07001999
Dan Williamsa1a113b2011-04-21 18:44:45 -07002000 if (status != SCI_SUCCESS)
2001 return status;
Dan Williams88f3b622011-04-22 19:18:03 -07002002
Dan Williamsab2e8f72011-04-27 16:32:45 -07002003 if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV ||
2004 (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev))
2005 /* pass */;
2006 else
Dan Williamsa1a113b2011-04-21 18:44:45 -07002007 return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williams88f3b622011-04-22 19:18:03 -07002008
Dan Williamsa1a113b2011-04-21 18:44:45 -07002009 sci_dev->connection_rate = scic_sds_port_get_max_allowed_speed(sci_port);
Dan Williams88f3b622011-04-22 19:18:03 -07002010
Dan Williamsa1a113b2011-04-21 18:44:45 -07002011 /* / @todo Should I assign the port width by reading all of the phys on the port? */
2012 sci_dev->device_port_width = 1;
Dan Williams88f3b622011-04-22 19:18:03 -07002013
Dan Williamsa1a113b2011-04-21 18:44:45 -07002014 return SCI_SUCCESS;
Dan Williams88f3b622011-04-22 19:18:03 -07002015}
2016
Dan Williams88f3b622011-04-22 19:18:03 -07002017/**
Dan Williamsb87ee302011-04-25 11:48:29 -07002018 * scic_remote_device_ea_construct() - construct expander attached device
Dan Williams88f3b622011-04-22 19:18:03 -07002019 *
Dan Williamsb87ee302011-04-25 11:48:29 -07002020 * Remote node context(s) is/are a global resource allocated by this
2021 * routine, freed by scic_remote_device_destruct().
2022 *
2023 * Returns:
2024 * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
2025 * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
2026 * sata-only controller instance.
2027 * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
Dan Williams88f3b622011-04-22 19:18:03 -07002028 */
Dan Williamsb87ee302011-04-25 11:48:29 -07002029static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci_port,
Dan Williams00d680e2011-04-25 14:29:29 -07002030 struct scic_sds_remote_device *sci_dev)
Dan Williams88f3b622011-04-22 19:18:03 -07002031{
Dan Williamsa1a113b2011-04-21 18:44:45 -07002032 struct domain_device *dev = sci_dev_to_domain(sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07002033 enum sci_status status;
Dan Williams88f3b622011-04-22 19:18:03 -07002034
Dan Williamsb87ee302011-04-25 11:48:29 -07002035 scic_remote_device_construct(sci_port, sci_dev);
Dan Williams88f3b622011-04-22 19:18:03 -07002036
Dan Williamsab2e8f72011-04-27 16:32:45 -07002037 status = scic_sds_controller_allocate_remote_node_context(sci_port->owning_controller,
2038 sci_dev,
2039 &sci_dev->rnc.remote_node_index);
Dan Williamsa1a113b2011-04-21 18:44:45 -07002040 if (status != SCI_SUCCESS)
2041 return status;
Dan Williams88f3b622011-04-22 19:18:03 -07002042
Dan Williamsab2e8f72011-04-27 16:32:45 -07002043 if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV ||
2044 (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev))
2045 /* pass */;
2046 else
2047 return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williams88f3b622011-04-22 19:18:03 -07002048
Dan Williamsa1a113b2011-04-21 18:44:45 -07002049 /*
2050 * For SAS-2 the physical link rate is actually a logical link
2051 * rate that incorporates multiplexing. The SCU doesn't
2052 * incorporate multiplexing and for the purposes of the
2053 * connection the logical link rate is that same as the
2054 * physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay
2055 * one another, so this code works for both situations. */
2056 sci_dev->connection_rate = min_t(u16, scic_sds_port_get_max_allowed_speed(sci_port),
Dan Williams00d680e2011-04-25 14:29:29 -07002057 dev->linkrate);
Dan Williams88f3b622011-04-22 19:18:03 -07002058
Dan Williamsa1a113b2011-04-21 18:44:45 -07002059 /* / @todo Should I assign the port width by reading all of the phys on the port? */
2060 sci_dev->device_port_width = 1;
Dan Williams88f3b622011-04-22 19:18:03 -07002061
Dan Williamsab2e8f72011-04-27 16:32:45 -07002062 return SCI_SUCCESS;
Dan Williams88f3b622011-04-22 19:18:03 -07002063}
2064
2065/**
2066 * scic_remote_device_start() - This method will start the supplied remote
2067 * device. This method enables normal IO requests to flow through to the
2068 * remote device.
2069 * @remote_device: This parameter specifies the device to be started.
2070 * @timeout: This parameter specifies the number of milliseconds in which the
2071 * start operation should complete.
2072 *
2073 * An indication of whether the device was successfully started. SCI_SUCCESS
2074 * This value is returned if the device was successfully started.
2075 * SCI_FAILURE_INVALID_PHY This value is returned if the user attempts to start
2076 * the device when there have been no phys added to it.
2077 */
2078static enum sci_status scic_remote_device_start(struct scic_sds_remote_device *sci_dev,
Dan Williamseb229672011-05-01 14:05:57 -07002079 u32 timeout)
Dan Williams88f3b622011-04-22 19:18:03 -07002080{
Dan Williamseb229672011-05-01 14:05:57 -07002081 struct sci_base_state_machine *sm = &sci_dev->state_machine;
2082 enum scic_sds_remote_device_states state = sm->current_state_id;
2083 enum sci_status status;
2084
2085 if (state != SCI_BASE_REMOTE_DEVICE_STATE_STOPPED) {
2086 dev_warn(scirdev_to_dev(sci_dev), "%s: in wrong state: %d\n",
2087 __func__, state);
2088 return SCI_FAILURE_INVALID_STATE;
2089 }
2090
2091 status = scic_sds_remote_node_context_resume(&sci_dev->rnc,
2092 remote_device_resume_done,
2093 sci_dev);
2094 if (status != SCI_SUCCESS)
2095 return status;
2096
2097 sci_base_state_machine_change_state(sm, SCI_BASE_REMOTE_DEVICE_STATE_STARTING);
2098
2099 return SCI_SUCCESS;
Dan Williams88f3b622011-04-22 19:18:03 -07002100}
Dan Williams6f231dd2011-07-02 22:56:22 -07002101
Dan Williams00d680e2011-04-25 14:29:29 -07002102static enum sci_status isci_remote_device_construct(struct isci_port *iport,
2103 struct isci_remote_device *idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002104{
Dan Williams00d680e2011-04-25 14:29:29 -07002105 struct scic_sds_port *sci_port = iport->sci_port_handle;
2106 struct isci_host *ihost = iport->isci_host;
2107 struct domain_device *dev = idev->domain_dev;
2108 enum sci_status status;
Dan Williams6f231dd2011-07-02 22:56:22 -07002109
Dan Williams00d680e2011-04-25 14:29:29 -07002110 if (dev->parent && dev_is_expander(dev->parent))
2111 status = scic_remote_device_ea_construct(sci_port, &idev->sci);
2112 else
2113 status = scic_remote_device_da_construct(sci_port, &idev->sci);
Dan Williams6f231dd2011-07-02 22:56:22 -07002114
2115 if (status != SCI_SUCCESS) {
Dan Williams00d680e2011-04-25 14:29:29 -07002116 dev_dbg(&ihost->pdev->dev, "%s: construct failed: %d\n",
2117 __func__, status);
Dan Williams6f231dd2011-07-02 22:56:22 -07002118
2119 return status;
2120 }
2121
Dan Williams6f231dd2011-07-02 22:56:22 -07002122 /* start the device. */
Dan Williams00d680e2011-04-25 14:29:29 -07002123 status = scic_remote_device_start(&idev->sci, ISCI_REMOTE_DEVICE_START_TIMEOUT);
Dan Williams6f231dd2011-07-02 22:56:22 -07002124
Dan Williams00d680e2011-04-25 14:29:29 -07002125 if (status != SCI_SUCCESS)
2126 dev_warn(&ihost->pdev->dev, "remote device start failed: %d\n",
2127 status);
Dan Williams6f231dd2011-07-02 22:56:22 -07002128
2129 return status;
2130}
2131
Dan Williams4393aa42011-03-31 13:10:44 -07002132void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002133{
2134 DECLARE_COMPLETION_ONSTACK(aborted_task_completion);
Dan Williams6f231dd2011-07-02 22:56:22 -07002135
Dan Williams4393aa42011-03-31 13:10:44 -07002136 dev_dbg(&ihost->pdev->dev,
2137 "%s: idev = %p\n", __func__, idev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002138
2139 /* Cleanup all requests pending for this device. */
Dan Williams4393aa42011-03-31 13:10:44 -07002140 isci_terminate_pending_requests(ihost, idev, terminating);
Dan Williams6f231dd2011-07-02 22:56:22 -07002141
Dan Williams4393aa42011-03-31 13:10:44 -07002142 dev_dbg(&ihost->pdev->dev,
2143 "%s: idev = %p, done\n", __func__, idev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002144}
2145
Dan Williams6f231dd2011-07-02 22:56:22 -07002146/**
2147 * This function builds the isci_remote_device when a libsas dev_found message
2148 * is received.
2149 * @isci_host: This parameter specifies the isci host object.
2150 * @port: This parameter specifies the isci_port conected to this device.
2151 *
2152 * pointer to new isci_remote_device.
2153 */
2154static struct isci_remote_device *
Dan Williamsd9c37392011-03-03 17:59:32 -08002155isci_remote_device_alloc(struct isci_host *ihost, struct isci_port *iport)
Dan Williams6f231dd2011-07-02 22:56:22 -07002156{
Dan Williamsd9c37392011-03-03 17:59:32 -08002157 struct isci_remote_device *idev;
2158 int i;
Dan Williams6f231dd2011-07-02 22:56:22 -07002159
Dan Williamsd9c37392011-03-03 17:59:32 -08002160 for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
Dan Williams57f20f42011-04-21 18:14:45 -07002161 idev = &ihost->devices[i];
Dan Williamsd9c37392011-03-03 17:59:32 -08002162 if (!test_and_set_bit(IDEV_ALLOCATED, &idev->flags))
2163 break;
2164 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002165
Dan Williamsd9c37392011-03-03 17:59:32 -08002166 if (i >= SCI_MAX_REMOTE_DEVICES) {
2167 dev_warn(&ihost->pdev->dev, "%s: failed\n", __func__);
Dan Williams6f231dd2011-07-02 22:56:22 -07002168 return NULL;
2169 }
2170
Bartosz Barcinski6cb4d6b2011-04-12 17:28:43 -07002171 if (WARN_ONCE(!list_empty(&idev->reqs_in_process), "found requests in process\n"))
2172 return NULL;
2173
2174 if (WARN_ONCE(!list_empty(&idev->node), "found non-idle remote device\n"))
2175 return NULL;
2176
Dan Williamsd9c37392011-03-03 17:59:32 -08002177 isci_remote_device_change_state(idev, isci_freed);
Dan Williams6f231dd2011-07-02 22:56:22 -07002178
Dan Williamsd9c37392011-03-03 17:59:32 -08002179 return idev;
Dan Williams6f231dd2011-07-02 22:56:22 -07002180}
Dan Williams6f231dd2011-07-02 22:56:22 -07002181
2182/**
Dan Williams6f231dd2011-07-02 22:56:22 -07002183 * isci_remote_device_stop() - This function is called internally to stop the
2184 * remote device.
2185 * @isci_host: This parameter specifies the isci host object.
2186 * @isci_device: This parameter specifies the remote device.
2187 *
2188 * The status of the scic request to stop.
2189 */
Dan Williams6ad31fe2011-03-04 12:10:29 -08002190enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002191{
2192 enum sci_status status;
2193 unsigned long flags;
Dan Williams6f231dd2011-07-02 22:56:22 -07002194
Dan Williams6ad31fe2011-03-04 12:10:29 -08002195 dev_dbg(&ihost->pdev->dev,
2196 "%s: isci_device = %p\n", __func__, idev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002197
Dan Williams6ad31fe2011-03-04 12:10:29 -08002198 isci_remote_device_change_state(idev, isci_stopping);
Jeff Skirvin6e2802a2011-03-08 20:32:16 -07002199
2200 /* Kill all outstanding requests. */
Dan Williams4393aa42011-03-31 13:10:44 -07002201 isci_remote_device_nuke_requests(ihost, idev);
Jeff Skirvin6e2802a2011-03-08 20:32:16 -07002202
Dan Williams6ad31fe2011-03-04 12:10:29 -08002203 set_bit(IDEV_STOP_PENDING, &idev->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002204
Dan Williams6ad31fe2011-03-04 12:10:29 -08002205 spin_lock_irqsave(&ihost->scic_lock, flags);
Dan Williams57f20f42011-04-21 18:14:45 -07002206 status = scic_remote_device_stop(&idev->sci, 50);
Dan Williams6ad31fe2011-03-04 12:10:29 -08002207 spin_unlock_irqrestore(&ihost->scic_lock, flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002208
2209 /* Wait for the stop complete callback. */
Dan Williamsd9c37392011-03-03 17:59:32 -08002210 if (status == SCI_SUCCESS) {
Dan Williams6ad31fe2011-03-04 12:10:29 -08002211 wait_for_device_stop(ihost, idev);
Dan Williamsd9c37392011-03-03 17:59:32 -08002212 clear_bit(IDEV_ALLOCATED, &idev->flags);
2213 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002214
Dan Williams6ad31fe2011-03-04 12:10:29 -08002215 dev_dbg(&ihost->pdev->dev,
2216 "%s: idev = %p - after completion wait\n",
2217 __func__, idev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002218
Dan Williams6f231dd2011-07-02 22:56:22 -07002219 return status;
2220}
2221
2222/**
2223 * isci_remote_device_gone() - This function is called by libsas when a domain
2224 * device is removed.
2225 * @domain_device: This parameter specifies the libsas domain device.
2226 *
2227 */
Dan Williams6ad31fe2011-03-04 12:10:29 -08002228void isci_remote_device_gone(struct domain_device *dev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002229{
Dan Williams4393aa42011-03-31 13:10:44 -07002230 struct isci_host *ihost = dev_to_ihost(dev);
Dan Williams6ad31fe2011-03-04 12:10:29 -08002231 struct isci_remote_device *idev = dev->lldd_dev;
Dan Williams6f231dd2011-07-02 22:56:22 -07002232
Dan Williams6ad31fe2011-03-04 12:10:29 -08002233 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002234 "%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
Dan Williams6ad31fe2011-03-04 12:10:29 -08002235 __func__, dev, idev, idev->isci_port);
Dan Williams6f231dd2011-07-02 22:56:22 -07002236
Dan Williams6ad31fe2011-03-04 12:10:29 -08002237 isci_remote_device_stop(ihost, idev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002238}
2239
2240
2241/**
2242 * isci_remote_device_found() - This function is called by libsas when a remote
2243 * device is discovered. A remote device object is created and started. the
2244 * function then sleeps until the sci core device started message is
2245 * received.
2246 * @domain_device: This parameter specifies the libsas domain device.
2247 *
2248 * status, zero indicates success.
2249 */
2250int isci_remote_device_found(struct domain_device *domain_dev)
2251{
Dan Williams4393aa42011-03-31 13:10:44 -07002252 struct isci_host *isci_host = dev_to_ihost(domain_dev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002253 struct isci_port *isci_port;
2254 struct isci_phy *isci_phy;
2255 struct asd_sas_port *sas_port;
2256 struct asd_sas_phy *sas_phy;
2257 struct isci_remote_device *isci_device;
2258 enum sci_status status;
Dan Williams6f231dd2011-07-02 22:56:22 -07002259
Dan Williams6f231dd2011-07-02 22:56:22 -07002260 dev_dbg(&isci_host->pdev->dev,
2261 "%s: domain_device = %p\n", __func__, domain_dev);
2262
Dan Williams0cf89d12011-02-18 09:25:07 -08002263 wait_for_start(isci_host);
2264
Dan Williams6f231dd2011-07-02 22:56:22 -07002265 sas_port = domain_dev->port;
2266 sas_phy = list_first_entry(&sas_port->phy_list, struct asd_sas_phy,
2267 port_phy_el);
2268 isci_phy = to_isci_phy(sas_phy);
2269 isci_port = isci_phy->isci_port;
2270
2271 /* we are being called for a device on this port,
2272 * so it has to come up eventually
2273 */
2274 wait_for_completion(&isci_port->start_complete);
2275
2276 if ((isci_stopping == isci_port_get_state(isci_port)) ||
2277 (isci_stopped == isci_port_get_state(isci_port)))
2278 return -ENODEV;
2279
2280 isci_device = isci_remote_device_alloc(isci_host, isci_port);
Dan Williamsd9c37392011-03-03 17:59:32 -08002281 if (!isci_device)
2282 return -ENODEV;
Dan Williams6f231dd2011-07-02 22:56:22 -07002283
2284 INIT_LIST_HEAD(&isci_device->node);
2285 domain_dev->lldd_dev = isci_device;
2286 isci_device->domain_dev = domain_dev;
2287 isci_device->isci_port = isci_port;
2288 isci_remote_device_change_state(isci_device, isci_starting);
2289
2290
Dan Williams1a380452011-03-03 18:01:43 -08002291 spin_lock_irq(&isci_host->scic_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002292 list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
2293
Dan Williams6ad31fe2011-03-04 12:10:29 -08002294 set_bit(IDEV_START_PENDING, &isci_device->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002295 status = isci_remote_device_construct(isci_port, isci_device);
Dan Williams1a380452011-03-03 18:01:43 -08002296 spin_unlock_irq(&isci_host->scic_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002297
Dan Williams6f231dd2011-07-02 22:56:22 -07002298 dev_dbg(&isci_host->pdev->dev,
2299 "%s: isci_device = %p\n",
2300 __func__, isci_device);
2301
2302 if (status != SCI_SUCCESS) {
2303
Dan Williams1a380452011-03-03 18:01:43 -08002304 spin_lock_irq(&isci_host->scic_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002305 isci_remote_device_deconstruct(
2306 isci_host,
2307 isci_device
2308 );
Dan Williams1a380452011-03-03 18:01:43 -08002309 spin_unlock_irq(&isci_host->scic_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002310 return -ENODEV;
2311 }
2312
Dan Williams6ad31fe2011-03-04 12:10:29 -08002313 /* wait for the device ready callback. */
2314 wait_for_device_start(isci_host, isci_device);
2315
Dan Williams6f231dd2011-07-02 22:56:22 -07002316 return 0;
2317}
2318/**
2319 * isci_device_is_reset_pending() - This function will check if there is any
2320 * pending reset condition on the device.
2321 * @request: This parameter is the isci_device object.
2322 *
2323 * true if there is a reset pending for the device.
2324 */
2325bool isci_device_is_reset_pending(
2326 struct isci_host *isci_host,
2327 struct isci_remote_device *isci_device)
2328{
2329 struct isci_request *isci_request;
2330 struct isci_request *tmp_req;
2331 bool reset_is_pending = false;
2332 unsigned long flags;
2333
2334 dev_dbg(&isci_host->pdev->dev,
2335 "%s: isci_device = %p\n", __func__, isci_device);
2336
2337 spin_lock_irqsave(&isci_host->scic_lock, flags);
2338
2339 /* Check for reset on all pending requests. */
2340 list_for_each_entry_safe(isci_request, tmp_req,
2341 &isci_device->reqs_in_process, dev_node) {
2342 dev_dbg(&isci_host->pdev->dev,
2343 "%s: isci_device = %p request = %p\n",
2344 __func__, isci_device, isci_request);
2345
2346 if (isci_request->ttype == io_task) {
Dan Williams6f231dd2011-07-02 22:56:22 -07002347 struct sas_task *task = isci_request_access_task(
2348 isci_request);
2349
Bartosz Barcinski467e8552011-04-12 17:28:41 -07002350 spin_lock(&task->task_state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002351 if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
2352 reset_is_pending = true;
Bartosz Barcinski467e8552011-04-12 17:28:41 -07002353 spin_unlock(&task->task_state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002354 }
2355 }
2356
2357 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
2358
2359 dev_dbg(&isci_host->pdev->dev,
2360 "%s: isci_device = %p reset_is_pending = %d\n",
2361 __func__, isci_device, reset_is_pending);
2362
2363 return reset_is_pending;
2364}
2365
2366/**
2367 * isci_device_clear_reset_pending() - This function will clear if any pending
2368 * reset condition flags on the device.
2369 * @request: This parameter is the isci_device object.
2370 *
2371 * true if there is a reset pending for the device.
2372 */
Dan Williams4393aa42011-03-31 13:10:44 -07002373void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002374{
2375 struct isci_request *isci_request;
2376 struct isci_request *tmp_req;
Dan Williams6f231dd2011-07-02 22:56:22 -07002377 unsigned long flags = 0;
2378
Dan Williams4393aa42011-03-31 13:10:44 -07002379 dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n",
2380 __func__, idev, ihost);
Dan Williams6f231dd2011-07-02 22:56:22 -07002381
Dan Williams4393aa42011-03-31 13:10:44 -07002382 spin_lock_irqsave(&ihost->scic_lock, flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002383
2384 /* Clear reset pending on all pending requests. */
2385 list_for_each_entry_safe(isci_request, tmp_req,
Dan Williams4393aa42011-03-31 13:10:44 -07002386 &idev->reqs_in_process, dev_node) {
2387 dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n",
2388 __func__, idev, isci_request);
Dan Williams6f231dd2011-07-02 22:56:22 -07002389
2390 if (isci_request->ttype == io_task) {
2391
2392 unsigned long flags2;
2393 struct sas_task *task = isci_request_access_task(
2394 isci_request);
2395
2396 spin_lock_irqsave(&task->task_state_lock, flags2);
2397 task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
2398 spin_unlock_irqrestore(&task->task_state_lock, flags2);
2399 }
2400 }
Dan Williams4393aa42011-03-31 13:10:44 -07002401 spin_unlock_irqrestore(&ihost->scic_lock, flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002402}