remote_device.c 43.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * BSD LICENSE
 *
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
D
Dave Jiang 已提交
55
#include <scsi/sas.h>
56
#include <linux/bitops.h>
57 58 59 60 61 62 63 64
#include "isci.h"
#include "port.h"
#include "remote_device.h"
#include "request.h"
#include "remote_node_context.h"
#include "scu_event_codes.h"
#include "task.h"

65
/**
66
 * isci_remote_device_not_ready() - This function is called by the ihost when
67 68 69 70 71
 *    the remote device is not ready. We mark the isci device as ready (not
 *    "ready_for_io") and signal the waiting proccess.
 * @isci_host: This parameter specifies the isci host object.
 * @isci_device: This parameter specifies the remote device
 *
72
 * sci_lock is held on entrance to this function.
73 74 75 76
 */
static void isci_remote_device_not_ready(struct isci_host *ihost,
				  struct isci_remote_device *idev, u32 reason)
{
77
	struct isci_request *ireq;
78

79 80 81
	dev_dbg(&ihost->pdev->dev,
		"%s: isci_device = %p\n", __func__, idev);

82 83
	switch (reason) {
	case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED:
84
		set_bit(IDEV_GONE, &idev->flags);
85 86 87 88 89 90 91 92 93 94 95
		break;
	case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
		set_bit(IDEV_IO_NCQERROR, &idev->flags);

		/* Kill all outstanding requests for the device. */
		list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) {

			dev_dbg(&ihost->pdev->dev,
				"%s: isci_device = %p request = %p\n",
				__func__, idev, ireq);

96
			sci_controller_terminate_request(ihost,
97
							  idev,
98
							  ireq);
99 100 101
		}
		/* Fall through into the default case... */
	default:
102
		clear_bit(IDEV_IO_READY, &idev->flags);
103 104
		break;
	}
105 106 107
}

/**
108
 * isci_remote_device_ready() - This function is called by the ihost when the
109 110 111 112 113 114 115 116 117 118 119
 *    remote device is ready. We mark the isci device as ready and signal the
 *    waiting proccess.
 * @ihost: our valid isci_host
 * @idev: remote device
 *
 */
static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote_device *idev)
{
	dev_dbg(&ihost->pdev->dev,
		"%s: idev = %p\n", __func__, idev);

120
	clear_bit(IDEV_IO_NCQERROR, &idev->flags);
121
	set_bit(IDEV_IO_READY, &idev->flags);
122 123 124 125
	if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags))
		wake_up(&ihost->eventq);
}

126 127 128 129 130
/* called once the remote node context is ready to be freed.
 * The remote device can now report that its stop operation is complete. none
 */
static void rnc_destruct_done(void *_dev)
{
131
	struct isci_remote_device *idev = _dev;
132

133 134
	BUG_ON(idev->started_request_count != 0);
	sci_change_state(&idev->sm, SCI_DEV_STOPPED);
135
}
136

137
static enum sci_status sci_remote_device_terminate_requests(struct isci_remote_device *idev)
138
{
139
	struct isci_host *ihost = idev->owning_port->owning_controller;
140
	enum sci_status status  = SCI_SUCCESS;
141
	u32 i;
142

143
	for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
D
Dan Williams 已提交
144
		struct isci_request *ireq = ihost->reqs[i];
145 146
		enum sci_status s;

D
Dan Williams 已提交
147
		if (!test_bit(IREQ_ACTIVE, &ireq->flags) ||
148
		    ireq->target_device != idev)
149
			continue;
D
Dan Williams 已提交
150

151
		s = sci_controller_terminate_request(ihost, idev, ireq);
152 153 154 155 156 157 158
		if (s != SCI_SUCCESS)
			status = s;
	}

	return status;
}

159
enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
160
					u32 timeout)
161
{
162
	struct sci_base_state_machine *sm = &idev->sm;
163
	enum sci_remote_device_states state = sm->current_state_id;
164 165

	switch (state) {
E
Edmund Nadolski 已提交
166 167 168
	case SCI_DEV_INITIAL:
	case SCI_DEV_FAILED:
	case SCI_DEV_FINAL:
169
	default:
170
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
171 172
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
E
Edmund Nadolski 已提交
173
	case SCI_DEV_STOPPED:
174
		return SCI_SUCCESS;
E
Edmund Nadolski 已提交
175
	case SCI_DEV_STARTING:
176
		/* device not started so there had better be no requests */
177
		BUG_ON(idev->started_request_count != 0);
178
		sci_remote_node_context_destruct(&idev->rnc,
179
						      rnc_destruct_done, idev);
180 181 182
		/* Transition to the stopping state and wait for the
		 * remote node to complete being posted and invalidated.
		 */
E
Edmund Nadolski 已提交
183
		sci_change_state(sm, SCI_DEV_STOPPING);
184
		return SCI_SUCCESS;
E
Edmund Nadolski 已提交
185 186 187 188 189 190 191 192 193
	case SCI_DEV_READY:
	case SCI_STP_DEV_IDLE:
	case SCI_STP_DEV_CMD:
	case SCI_STP_DEV_NCQ:
	case SCI_STP_DEV_NCQ_ERROR:
	case SCI_STP_DEV_AWAIT_RESET:
	case SCI_SMP_DEV_IDLE:
	case SCI_SMP_DEV_CMD:
		sci_change_state(sm, SCI_DEV_STOPPING);
194
		if (idev->started_request_count == 0) {
195
			sci_remote_node_context_destruct(&idev->rnc,
196
							      rnc_destruct_done, idev);
197 198
			return SCI_SUCCESS;
		} else
199
			return sci_remote_device_terminate_requests(idev);
200
		break;
E
Edmund Nadolski 已提交
201
	case SCI_DEV_STOPPING:
202 203 204 205
		/* All requests should have been terminated, but if there is an
		 * attempt to stop a device already in the stopping state, then
		 * try again to terminate.
		 */
206
		return sci_remote_device_terminate_requests(idev);
E
Edmund Nadolski 已提交
207 208
	case SCI_DEV_RESETTING:
		sci_change_state(sm, SCI_DEV_STOPPING);
209 210
		return SCI_SUCCESS;
	}
211 212
}

213
enum sci_status sci_remote_device_reset(struct isci_remote_device *idev)
214
{
215
	struct sci_base_state_machine *sm = &idev->sm;
216
	enum sci_remote_device_states state = sm->current_state_id;
217 218

	switch (state) {
E
Edmund Nadolski 已提交
219 220 221 222 223 224 225 226 227
	case SCI_DEV_INITIAL:
	case SCI_DEV_STOPPED:
	case SCI_DEV_STARTING:
	case SCI_SMP_DEV_IDLE:
	case SCI_SMP_DEV_CMD:
	case SCI_DEV_STOPPING:
	case SCI_DEV_FAILED:
	case SCI_DEV_RESETTING:
	case SCI_DEV_FINAL:
228
	default:
229
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
230 231
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
E
Edmund Nadolski 已提交
232 233 234 235 236 237 238
	case SCI_DEV_READY:
	case SCI_STP_DEV_IDLE:
	case SCI_STP_DEV_CMD:
	case SCI_STP_DEV_NCQ:
	case SCI_STP_DEV_NCQ_ERROR:
	case SCI_STP_DEV_AWAIT_RESET:
		sci_change_state(sm, SCI_DEV_RESETTING);
239 240
		return SCI_SUCCESS;
	}
241 242
}

243
enum sci_status sci_remote_device_reset_complete(struct isci_remote_device *idev)
244
{
245
	struct sci_base_state_machine *sm = &idev->sm;
246
	enum sci_remote_device_states state = sm->current_state_id;
247

E
Edmund Nadolski 已提交
248
	if (state != SCI_DEV_RESETTING) {
249
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
250 251 252
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
253

E
Edmund Nadolski 已提交
254
	sci_change_state(sm, SCI_DEV_READY);
255 256
	return SCI_SUCCESS;
}
257

258
enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
259
					       u32 suspend_type)
260
{
261
	struct sci_base_state_machine *sm = &idev->sm;
262
	enum sci_remote_device_states state = sm->current_state_id;
263

E
Edmund Nadolski 已提交
264
	if (state != SCI_STP_DEV_CMD) {
265
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
266 267 268 269
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

270
	return sci_remote_node_context_suspend(&idev->rnc,
271
						    suspend_type, NULL, NULL);
272 273
}

274
enum sci_status sci_remote_device_frame_handler(struct isci_remote_device *idev,
275
						     u32 frame_index)
276
{
277
	struct sci_base_state_machine *sm = &idev->sm;
278
	enum sci_remote_device_states state = sm->current_state_id;
279
	struct isci_host *ihost = idev->owning_port->owning_controller;
280 281 282
	enum sci_status status;

	switch (state) {
E
Edmund Nadolski 已提交
283 284 285 286 287 288
	case SCI_DEV_INITIAL:
	case SCI_DEV_STOPPED:
	case SCI_DEV_STARTING:
	case SCI_STP_DEV_IDLE:
	case SCI_SMP_DEV_IDLE:
	case SCI_DEV_FINAL:
289
	default:
290
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
291 292
			 __func__, state);
		/* Return the frame back to the controller */
293
		sci_controller_release_frame(ihost, frame_index);
294
		return SCI_FAILURE_INVALID_STATE;
E
Edmund Nadolski 已提交
295 296 297 298 299 300
	case SCI_DEV_READY:
	case SCI_STP_DEV_NCQ_ERROR:
	case SCI_STP_DEV_AWAIT_RESET:
	case SCI_DEV_STOPPING:
	case SCI_DEV_FAILED:
	case SCI_DEV_RESETTING: {
301
		struct isci_request *ireq;
D
Dave Jiang 已提交
302 303 304
		struct ssp_frame_hdr hdr;
		void *frame_header;
		ssize_t word_cnt;
305

306
		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
307
								       frame_index,
D
Dave Jiang 已提交
308
								       &frame_header);
309 310 311
		if (status != SCI_SUCCESS)
			return status;

D
Dave Jiang 已提交
312 313 314
		word_cnt = sizeof(hdr) / sizeof(u32);
		sci_swab32_cpy(&hdr, frame_header, word_cnt);

315
		ireq = sci_request_by_tag(ihost, be16_to_cpu(hdr.tag));
316
		if (ireq && ireq->target_device == idev) {
317
			/* The IO request is now in charge of releasing the frame */
318
			status = sci_io_request_frame_handler(ireq, frame_index);
319 320 321 322
		} else {
			/* We could not map this tag to a valid IO
			 * request Just toss the frame and continue
			 */
323
			sci_controller_release_frame(ihost, frame_index);
324 325 326
		}
		break;
	}
E
Edmund Nadolski 已提交
327
	case SCI_STP_DEV_NCQ: {
328
		struct dev_to_host_fis *hdr;
329

330
		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
331 332 333 334 335
								       frame_index,
								       (void **)&hdr);
		if (status != SCI_SUCCESS)
			return status;

336 337
		if (hdr->fis_type == FIS_SETDEVBITS &&
		    (hdr->status & ATA_ERR)) {
338
			idev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
339 340

			/* TODO Check sactive and complete associated IO if any. */
E
Edmund Nadolski 已提交
341
			sci_change_state(sm, SCI_STP_DEV_NCQ_ERROR);
342 343
		} else if (hdr->fis_type == FIS_REGD2H &&
			   (hdr->status & ATA_ERR)) {
344 345 346 347
			/*
			 * Some devices return D2H FIS when an NCQ error is detected.
			 * Treat this like an SDB error FIS ready reason.
			 */
348 349
			idev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
			sci_change_state(&idev->sm, SCI_STP_DEV_NCQ_ERROR);
350 351 352
		} else
			status = SCI_FAILURE;

353
		sci_controller_release_frame(ihost, frame_index);
354 355
		break;
	}
E
Edmund Nadolski 已提交
356 357
	case SCI_STP_DEV_CMD:
	case SCI_SMP_DEV_CMD:
358 359 360 361
		/* The device does not process any UF received from the hardware while
		 * in this state.  All unsolicited frames are forwarded to the io request
		 * object.
		 */
362
		status = sci_io_request_frame_handler(idev->working_request, frame_index);
363 364 365 366
		break;
	}

	return status;
367 368
}

369
static bool is_remote_device_ready(struct isci_remote_device *idev)
370
{
371

372
	struct sci_base_state_machine *sm = &idev->sm;
373
	enum sci_remote_device_states state = sm->current_state_id;
374 375

	switch (state) {
E
Edmund Nadolski 已提交
376 377 378 379 380 381 382 383
	case SCI_DEV_READY:
	case SCI_STP_DEV_IDLE:
	case SCI_STP_DEV_CMD:
	case SCI_STP_DEV_NCQ:
	case SCI_STP_DEV_NCQ_ERROR:
	case SCI_STP_DEV_AWAIT_RESET:
	case SCI_SMP_DEV_IDLE:
	case SCI_SMP_DEV_CMD:
384 385 386 387 388 389
		return true;
	default:
		return false;
	}
}

D
Dan Williams 已提交
390 391 392 393 394 395 396 397 398 399 400 401
/*
 * called once the remote node context has transisitioned to a ready
 * state (after suspending RX and/or TX due to early D2H fis)
 */
static void atapi_remote_device_resume_done(void *_dev)
{
	struct isci_remote_device *idev = _dev;
	struct isci_request *ireq = idev->working_request;

	sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
}

402
enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev,
403 404
						     u32 event_code)
{
405
	struct sci_base_state_machine *sm = &idev->sm;
406
	enum sci_remote_device_states state = sm->current_state_id;
407 408 409 410 411 412
	enum sci_status status;

	switch (scu_get_event_type(event_code)) {
	case SCU_EVENT_TYPE_RNC_OPS_MISC:
	case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
	case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
413
		status = sci_remote_node_context_event_handler(&idev->rnc, event_code);
414 415 416 417 418 419
		break;
	case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
		if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
			status = SCI_SUCCESS;

			/* Suspend the associated RNC */
420
			sci_remote_node_context_suspend(&idev->rnc,
421 422 423
							      SCI_SOFTWARE_SUSPENSION,
							      NULL, NULL);

424
			dev_dbg(scirdev_to_dev(idev),
425
				"%s: device: %p event code: %x: %s\n",
426 427
				__func__, idev, event_code,
				is_remote_device_ready(idev)
428 429 430 431 432 433 434
				? "I_T_Nexus_Timeout event"
				: "I_T_Nexus_Timeout event in wrong state");

			break;
		}
	/* Else, fall through and treat as unhandled... */
	default:
435
		dev_dbg(scirdev_to_dev(idev),
436
			"%s: device: %p event code: %x: %s\n",
437 438
			__func__, idev, event_code,
			is_remote_device_ready(idev)
439 440 441 442 443 444 445 446 447
			? "unexpected event"
			: "unexpected event in wrong state");
		status = SCI_FAILURE_INVALID_STATE;
		break;
	}

	if (status != SCI_SUCCESS)
		return status;

D
Dan Williams 已提交
448 449 450 451 452 453 454 455 456 457
	if (state == SCI_STP_DEV_ATAPI_ERROR) {
		/* For ATAPI error state resume the RNC right away. */
		if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
		    scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
			return sci_remote_node_context_resume(&idev->rnc,
							      atapi_remote_device_resume_done,
							      idev);
		}
	}

E
Edmund Nadolski 已提交
458
	if (state == SCI_STP_DEV_IDLE) {
459 460 461 462 463 464

		/* We pick up suspension events to handle specifically to this
		 * state. We resume the RNC right away.
		 */
		if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
		    scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
465
			status = sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
466 467 468
	}

	return status;
469 470
}

471
static void sci_remote_device_start_request(struct isci_remote_device *idev,
472
						 struct isci_request *ireq,
473
						 enum sci_status status)
474
{
475
	struct isci_port *iport = idev->owning_port;
476 477 478

	/* cleanup requests that failed after starting on the port */
	if (status != SCI_SUCCESS)
479
		sci_port_complete_io(iport, idev, ireq);
480
	else {
481
		kref_get(&idev->kref);
D
Dan Williams 已提交
482
		idev->started_request_count++;
483
	}
484 485
}

486
enum sci_status sci_remote_device_start_io(struct isci_host *ihost,
487
						struct isci_remote_device *idev,
488
						struct isci_request *ireq)
489
{
490
	struct sci_base_state_machine *sm = &idev->sm;
491
	enum sci_remote_device_states state = sm->current_state_id;
492
	struct isci_port *iport = idev->owning_port;
493 494 495
	enum sci_status status;

	switch (state) {
E
Edmund Nadolski 已提交
496 497 498 499 500 501 502 503
	case SCI_DEV_INITIAL:
	case SCI_DEV_STOPPED:
	case SCI_DEV_STARTING:
	case SCI_STP_DEV_NCQ_ERROR:
	case SCI_DEV_STOPPING:
	case SCI_DEV_FAILED:
	case SCI_DEV_RESETTING:
	case SCI_DEV_FINAL:
504
	default:
505
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
506 507
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
E
Edmund Nadolski 已提交
508
	case SCI_DEV_READY:
509 510 511 512 513
		/* attempt to start an io request for this device object. The remote
		 * device object will issue the start request for the io and if
		 * successful it will start the request for the port object then
		 * increment its own request count.
		 */
514
		status = sci_port_start_io(iport, idev, ireq);
515 516 517
		if (status != SCI_SUCCESS)
			return status;

518
		status = sci_remote_node_context_start_io(&idev->rnc, ireq);
519 520 521
		if (status != SCI_SUCCESS)
			break;

522
		status = sci_request_start(ireq);
523
		break;
E
Edmund Nadolski 已提交
524
	case SCI_STP_DEV_IDLE: {
525 526 527 528 529 530 531 532
		/* handle the start io operation for a sata device that is in
		 * the command idle state. - Evalute the type of IO request to
		 * be started - If its an NCQ request change to NCQ substate -
		 * If its any other command change to the CMD substate
		 *
		 * If this is a softreset we may want to have a different
		 * substate.
		 */
533
		enum sci_remote_device_states new_state;
534
		struct sas_task *task = isci_request_access_task(ireq);
535

536
		status = sci_port_start_io(iport, idev, ireq);
537 538 539
		if (status != SCI_SUCCESS)
			return status;

540
		status = sci_remote_node_context_start_io(&idev->rnc, ireq);
541 542 543
		if (status != SCI_SUCCESS)
			break;

544
		status = sci_request_start(ireq);
545 546 547
		if (status != SCI_SUCCESS)
			break;

548
		if (task->ata_task.use_ncq)
E
Edmund Nadolski 已提交
549
			new_state = SCI_STP_DEV_NCQ;
550
		else {
551
			idev->working_request = ireq;
E
Edmund Nadolski 已提交
552
			new_state = SCI_STP_DEV_CMD;
553
		}
E
Edmund Nadolski 已提交
554
		sci_change_state(sm, new_state);
555 556
		break;
	}
E
Edmund Nadolski 已提交
557
	case SCI_STP_DEV_NCQ: {
558 559 560
		struct sas_task *task = isci_request_access_task(ireq);

		if (task->ata_task.use_ncq) {
561
			status = sci_port_start_io(iport, idev, ireq);
562 563 564
			if (status != SCI_SUCCESS)
				return status;

565
			status = sci_remote_node_context_start_io(&idev->rnc, ireq);
566 567 568
			if (status != SCI_SUCCESS)
				break;

569
			status = sci_request_start(ireq);
570 571 572
		} else
			return SCI_FAILURE_INVALID_STATE;
		break;
573
	}
E
Edmund Nadolski 已提交
574
	case SCI_STP_DEV_AWAIT_RESET:
575
		return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
E
Edmund Nadolski 已提交
576
	case SCI_SMP_DEV_IDLE:
577
		status = sci_port_start_io(iport, idev, ireq);
578 579 580
		if (status != SCI_SUCCESS)
			return status;

581
		status = sci_remote_node_context_start_io(&idev->rnc, ireq);
582 583 584
		if (status != SCI_SUCCESS)
			break;

585
		status = sci_request_start(ireq);
586 587 588
		if (status != SCI_SUCCESS)
			break;

589 590
		idev->working_request = ireq;
		sci_change_state(&idev->sm, SCI_SMP_DEV_CMD);
591
		break;
E
Edmund Nadolski 已提交
592 593
	case SCI_STP_DEV_CMD:
	case SCI_SMP_DEV_CMD:
594 595 596 597 598 599
		/* device is already handling a command it can not accept new commands
		 * until this one is complete.
		 */
		return SCI_FAILURE_INVALID_STATE;
	}

600
	sci_remote_device_start_request(idev, ireq, status);
601
	return status;
602 603
}

604
static enum sci_status common_complete_io(struct isci_port *iport,
605
					  struct isci_remote_device *idev,
606
					  struct isci_request *ireq)
607
{
608 609
	enum sci_status status;

610
	status = sci_request_complete(ireq);
611 612 613
	if (status != SCI_SUCCESS)
		return status;

614
	status = sci_port_complete_io(iport, idev, ireq);
615 616 617
	if (status != SCI_SUCCESS)
		return status;

618
	sci_remote_device_decrement_request_count(idev);
619 620 621
	return status;
}

622
enum sci_status sci_remote_device_complete_io(struct isci_host *ihost,
623
						   struct isci_remote_device *idev,
624
						   struct isci_request *ireq)
625
{
626
	struct sci_base_state_machine *sm = &idev->sm;
627
	enum sci_remote_device_states state = sm->current_state_id;
628
	struct isci_port *iport = idev->owning_port;
629 630 631
	enum sci_status status;

	switch (state) {
E
Edmund Nadolski 已提交
632 633 634 635 636 637 638
	case SCI_DEV_INITIAL:
	case SCI_DEV_STOPPED:
	case SCI_DEV_STARTING:
	case SCI_STP_DEV_IDLE:
	case SCI_SMP_DEV_IDLE:
	case SCI_DEV_FAILED:
	case SCI_DEV_FINAL:
639
	default:
640
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
641 642
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
E
Edmund Nadolski 已提交
643 644 645
	case SCI_DEV_READY:
	case SCI_STP_DEV_AWAIT_RESET:
	case SCI_DEV_RESETTING:
646
		status = common_complete_io(iport, idev, ireq);
647
		break;
E
Edmund Nadolski 已提交
648 649 650
	case SCI_STP_DEV_CMD:
	case SCI_STP_DEV_NCQ:
	case SCI_STP_DEV_NCQ_ERROR:
D
Dan Williams 已提交
651
	case SCI_STP_DEV_ATAPI_ERROR:
652
		status = common_complete_io(iport, idev, ireq);
653 654 655
		if (status != SCI_SUCCESS)
			break;

656
		if (ireq->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
657 658 659 660 661
			/* This request causes hardware error, device needs to be Lun Reset.
			 * So here we force the state machine to IDLE state so the rest IOs
			 * can reach RNC state handler, these IOs will be completed by RNC with
			 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
			 */
E
Edmund Nadolski 已提交
662
			sci_change_state(sm, SCI_STP_DEV_AWAIT_RESET);
D
Dan Williams 已提交
663
		} else if (idev->started_request_count == 0)
E
Edmund Nadolski 已提交
664
			sci_change_state(sm, SCI_STP_DEV_IDLE);
665
		break;
E
Edmund Nadolski 已提交
666
	case SCI_SMP_DEV_CMD:
667
		status = common_complete_io(iport, idev, ireq);
668 669
		if (status != SCI_SUCCESS)
			break;
E
Edmund Nadolski 已提交
670
		sci_change_state(sm, SCI_SMP_DEV_IDLE);
671
		break;
E
Edmund Nadolski 已提交
672
	case SCI_DEV_STOPPING:
673
		status = common_complete_io(iport, idev, ireq);
674 675 676
		if (status != SCI_SUCCESS)
			break;

D
Dan Williams 已提交
677
		if (idev->started_request_count == 0)
678
			sci_remote_node_context_destruct(&idev->rnc,
D
Dan Williams 已提交
679 680
							 rnc_destruct_done,
							 idev);
681 682 683 684
		break;
	}

	if (status != SCI_SUCCESS)
685
		dev_err(scirdev_to_dev(idev),
686
			"%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
687
			"could not complete\n", __func__, iport,
688
			idev, ireq, status);
689
	else
690
		isci_put_device(idev);
691 692

	return status;
693 694
}

695
static void sci_remote_device_continue_request(void *dev)
696
{
697
	struct isci_remote_device *idev = dev;
698 699

	/* we need to check if this request is still valid to continue. */
700
	if (idev->working_request)
701
		sci_controller_continue_io(idev->working_request);
702 703
}

704
enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
705
						  struct isci_remote_device *idev,
706
						  struct isci_request *ireq)
707
{
708
	struct sci_base_state_machine *sm = &idev->sm;
709
	enum sci_remote_device_states state = sm->current_state_id;
710
	struct isci_port *iport = idev->owning_port;
711 712 713
	enum sci_status status;

	switch (state) {
E
Edmund Nadolski 已提交
714 715 716 717 718 719 720 721 722
	case SCI_DEV_INITIAL:
	case SCI_DEV_STOPPED:
	case SCI_DEV_STARTING:
	case SCI_SMP_DEV_IDLE:
	case SCI_SMP_DEV_CMD:
	case SCI_DEV_STOPPING:
	case SCI_DEV_FAILED:
	case SCI_DEV_RESETTING:
	case SCI_DEV_FINAL:
723
	default:
724
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
725 726
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
E
Edmund Nadolski 已提交
727 728 729 730 731
	case SCI_STP_DEV_IDLE:
	case SCI_STP_DEV_CMD:
	case SCI_STP_DEV_NCQ:
	case SCI_STP_DEV_NCQ_ERROR:
	case SCI_STP_DEV_AWAIT_RESET:
732
		status = sci_port_start_io(iport, idev, ireq);
733 734 735
		if (status != SCI_SUCCESS)
			return status;

736
		status = sci_remote_node_context_start_task(&idev->rnc, ireq);
737 738 739
		if (status != SCI_SUCCESS)
			goto out;

740
		status = sci_request_start(ireq);
741 742 743 744 745 746 747
		if (status != SCI_SUCCESS)
			goto out;

		/* Note: If the remote device state is not IDLE this will
		 * replace the request that probably resulted in the task
		 * management request.
		 */
748
		idev->working_request = ireq;
E
Edmund Nadolski 已提交
749
		sci_change_state(sm, SCI_STP_DEV_CMD);
750 751 752 753 754 755 756 757

		/* The remote node context must cleanup the TCi to NCQ mapping
		 * table.  The only way to do this correctly is to either write
		 * to the TLCR register or to invalidate and repost the RNC. In
		 * either case the remote node context state machine will take
		 * the correct action when the remote node context is suspended
		 * and later resumed.
		 */
758
		sci_remote_node_context_suspend(&idev->rnc,
759
				SCI_SOFTWARE_SUSPENSION, NULL, NULL);
760 761
		sci_remote_node_context_resume(&idev->rnc,
				sci_remote_device_continue_request,
762
						    idev);
763 764

	out:
765
		sci_remote_device_start_request(idev, ireq, status);
766 767 768 769 770
		/* We need to let the controller start request handler know that
		 * it can't post TC yet. We will provide a callback function to
		 * post TC when RNC gets resumed.
		 */
		return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
E
Edmund Nadolski 已提交
771
	case SCI_DEV_READY:
772
		status = sci_port_start_io(iport, idev, ireq);
773 774 775
		if (status != SCI_SUCCESS)
			return status;

776
		status = sci_remote_node_context_start_task(&idev->rnc, ireq);
777 778 779
		if (status != SCI_SUCCESS)
			break;

780
		status = sci_request_start(ireq);
781 782
		break;
	}
783
	sci_remote_device_start_request(idev, ireq, status);
784 785

	return status;
786 787
}

D
Dan Williams 已提交
788
void sci_remote_device_post_request(struct isci_remote_device *idev, u32 request)
789
{
D
Dan Williams 已提交
790
	struct isci_port *iport = idev->owning_port;
791 792
	u32 context;

D
Dan Williams 已提交
793 794 795 796
	context = request |
		  (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
		  (iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
		  idev->rnc.remote_node_index;
797

D
Dan Williams 已提交
798
	sci_controller_post_request(iport->owning_controller, context);
799 800
}

801
/* called once the remote node context has transisitioned to a
802
 * ready state.  This is the indication that the remote device object can also
803
 * transition to ready.
804
 */
805
static void remote_device_resume_done(void *_dev)
806
{
807
	struct isci_remote_device *idev = _dev;
808

809
	if (is_remote_device_ready(idev))
810
		return;
811

812
	/* go 'ready' if we are not already in a ready state */
813
	sci_change_state(&idev->sm, SCI_DEV_READY);
814 815
}

816
static void sci_stp_remote_device_ready_idle_substate_resume_complete_handler(void *_dev)
817
{
818
	struct isci_remote_device *idev = _dev;
819
	struct isci_host *ihost = idev->owning_port->owning_controller;
820 821 822 823

	/* For NCQ operation we do not issue a isci_remote_device_not_ready().
	 * As a result, avoid sending the ready notification.
	 */
824
	if (idev->sm.previous_state_id != SCI_STP_DEV_NCQ)
825
		isci_remote_device_ready(ihost, idev);
826 827
}

828
static void sci_remote_device_initial_state_enter(struct sci_base_state_machine *sm)
829
{
830
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
831

832
	/* Initial state is a transitional state to the stopped state */
833
	sci_change_state(&idev->sm, SCI_DEV_STOPPED);
834
}
835

836
/**
837
 * sci_remote_device_destruct() - free remote node context and destruct
838 839 840 841 842 843 844 845 846 847 848
 * @remote_device: This parameter specifies the remote device to be destructed.
 *
 * Remote device objects are a limited resource.  As such, they must be
 * protected.  Thus calls to construct and destruct are mutually exclusive and
 * non-reentrant. The return value shall indicate if the device was
 * successfully destructed or if some failure occurred. enum sci_status This value
 * is returned if the device is successfully destructed.
 * SCI_FAILURE_INVALID_REMOTE_DEVICE This value is returned if the supplied
 * device isn't valid (e.g. it's already been destoryed, the handle isn't
 * valid, etc.).
 */
849
static enum sci_status sci_remote_device_destruct(struct isci_remote_device *idev)
850
{
851
	struct sci_base_state_machine *sm = &idev->sm;
852
	enum sci_remote_device_states state = sm->current_state_id;
853
	struct isci_host *ihost;
854

E
Edmund Nadolski 已提交
855
	if (state != SCI_DEV_STOPPED) {
856
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
857 858 859 860
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

861
	ihost = idev->owning_port->owning_controller;
862
	sci_controller_free_remote_node_context(ihost, idev,
863 864
						     idev->rnc.remote_node_index);
	idev->rnc.remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
E
Edmund Nadolski 已提交
865
	sci_change_state(sm, SCI_DEV_FINAL);
866 867

	return SCI_SUCCESS;
868
}
869 870 871

/**
 * isci_remote_device_deconstruct() - This function frees an isci_remote_device.
D
Dan Williams 已提交
872 873
 * @ihost: This parameter specifies the isci host object.
 * @idev: This parameter specifies the remote device to be freed.
874 875
 *
 */
D
Dan Williams 已提交
876
static void isci_remote_device_deconstruct(struct isci_host *ihost, struct isci_remote_device *idev)
877
{
D
Dan Williams 已提交
878 879
	dev_dbg(&ihost->pdev->dev,
		"%s: isci_device = %p\n", __func__, idev);
880 881 882 883 884

	/* There should not be any outstanding io's. All paths to
	 * here should go through isci_remote_device_nuke_requests.
	 * If we hit this condition, we will need a way to complete
	 * io requests in process */
885
	BUG_ON(!list_empty(&idev->reqs_in_process));
886

887
	sci_remote_device_destruct(idev);
D
Dan Williams 已提交
888
	list_del_init(&idev->node);
889
	isci_put_device(idev);
890 891
}

892
static void sci_remote_device_stopped_state_enter(struct sci_base_state_machine *sm)
893
{
894
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
895
	struct isci_host *ihost = idev->owning_port->owning_controller;
896 897 898 899 900
	u32 prev_state;

	/* If we are entering from the stopping state let the SCI User know that
	 * the stop operation has completed.
	 */
901
	prev_state = idev->sm.previous_state_id;
E
Edmund Nadolski 已提交
902
	if (prev_state == SCI_DEV_STOPPING)
903
		isci_remote_device_deconstruct(ihost, idev);
904

905
	sci_controller_remote_device_stopped(ihost, idev);
906 907
}

908
static void sci_remote_device_starting_state_enter(struct sci_base_state_machine *sm)
909
{
910
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
D
Dan Williams 已提交
911
	struct isci_host *ihost = idev->owning_port->owning_controller;
912 913 914 915 916

	isci_remote_device_not_ready(ihost, idev,
				     SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED);
}

917
static void sci_remote_device_ready_state_enter(struct sci_base_state_machine *sm)
918
{
919
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
920
	struct isci_host *ihost = idev->owning_port->owning_controller;
921
	struct domain_device *dev = idev->domain_dev;
922

923
	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) {
924
		sci_change_state(&idev->sm, SCI_STP_DEV_IDLE);
925
	} else if (dev_is_expander(dev)) {
926
		sci_change_state(&idev->sm, SCI_SMP_DEV_IDLE);
927
	} else
928
		isci_remote_device_ready(ihost, idev);
929 930
}

931
static void sci_remote_device_ready_state_exit(struct sci_base_state_machine *sm)
932
{
933 934
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
	struct domain_device *dev = idev->domain_dev;
935 936

	if (dev->dev_type == SAS_END_DEV) {
937
		struct isci_host *ihost = idev->owning_port->owning_controller;
938

939
		isci_remote_device_not_ready(ihost, idev,
940 941 942 943
					     SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED);
	}
}

944
static void sci_remote_device_resetting_state_enter(struct sci_base_state_machine *sm)
945
{
946
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
947

948
	sci_remote_node_context_suspend(
949
		&idev->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
950 951
}

952
static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm)
953
{
954
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
955

956
	sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
957 958
}

959
static void sci_stp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
960
{
961
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
962

963
	idev->working_request = NULL;
964
	if (sci_remote_node_context_is_ready(&idev->rnc)) {
965 966 967
		/*
		 * Since the RNC is ready, it's alright to finish completion
		 * processing (e.g. signal the remote device is ready). */
968
		sci_stp_remote_device_ready_idle_substate_resume_complete_handler(idev);
969
	} else {
970 971
		sci_remote_node_context_resume(&idev->rnc,
			sci_stp_remote_device_ready_idle_substate_resume_complete_handler,
972
			idev);
973 974 975
	}
}

976
static void sci_stp_remote_device_ready_cmd_substate_enter(struct sci_base_state_machine *sm)
977
{
978
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
D
Dan Williams 已提交
979
	struct isci_host *ihost = idev->owning_port->owning_controller;
980

981
	BUG_ON(idev->working_request == NULL);
982

983
	isci_remote_device_not_ready(ihost, idev,
984 985 986
				     SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
}

987
static void sci_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base_state_machine *sm)
988
{
989
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
D
Dan Williams 已提交
990
	struct isci_host *ihost = idev->owning_port->owning_controller;
991

992
	if (idev->not_ready_reason == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
993
		isci_remote_device_not_ready(ihost, idev,
994
					     idev->not_ready_reason);
995 996
}

997
static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
998
{
999
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
D
Dan Williams 已提交
1000
	struct isci_host *ihost = idev->owning_port->owning_controller;
1001

1002
	isci_remote_device_ready(ihost, idev);
1003 1004
}

1005
static void sci_smp_remote_device_ready_cmd_substate_enter(struct sci_base_state_machine *sm)
1006
{
1007
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
D
Dan Williams 已提交
1008
	struct isci_host *ihost = idev->owning_port->owning_controller;
1009

1010
	BUG_ON(idev->working_request == NULL);
1011

1012
	isci_remote_device_not_ready(ihost, idev,
1013 1014 1015
				     SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED);
}

1016
static void sci_smp_remote_device_ready_cmd_substate_exit(struct sci_base_state_machine *sm)
1017
{
1018
	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
1019

1020
	idev->working_request = NULL;
1021
}
1022

1023
static const struct sci_base_state sci_remote_device_state_table[] = {
E
Edmund Nadolski 已提交
1024
	[SCI_DEV_INITIAL] = {
1025
		.enter_state = sci_remote_device_initial_state_enter,
1026
	},
E
Edmund Nadolski 已提交
1027
	[SCI_DEV_STOPPED] = {
1028
		.enter_state = sci_remote_device_stopped_state_enter,
1029
	},
E
Edmund Nadolski 已提交
1030
	[SCI_DEV_STARTING] = {
1031
		.enter_state = sci_remote_device_starting_state_enter,
1032
	},
E
Edmund Nadolski 已提交
1033
	[SCI_DEV_READY] = {
1034 1035
		.enter_state = sci_remote_device_ready_state_enter,
		.exit_state  = sci_remote_device_ready_state_exit
1036
	},
E
Edmund Nadolski 已提交
1037
	[SCI_STP_DEV_IDLE] = {
1038
		.enter_state = sci_stp_remote_device_ready_idle_substate_enter,
1039
	},
E
Edmund Nadolski 已提交
1040
	[SCI_STP_DEV_CMD] = {
1041
		.enter_state = sci_stp_remote_device_ready_cmd_substate_enter,
1042
	},
E
Edmund Nadolski 已提交
1043 1044
	[SCI_STP_DEV_NCQ] = { },
	[SCI_STP_DEV_NCQ_ERROR] = {
1045
		.enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter,
1046
	},
D
Dan Williams 已提交
1047
	[SCI_STP_DEV_ATAPI_ERROR] = { },
E
Edmund Nadolski 已提交
1048 1049
	[SCI_STP_DEV_AWAIT_RESET] = { },
	[SCI_SMP_DEV_IDLE] = {
1050
		.enter_state = sci_smp_remote_device_ready_idle_substate_enter,
1051
	},
E
Edmund Nadolski 已提交
1052
	[SCI_SMP_DEV_CMD] = {
1053 1054
		.enter_state = sci_smp_remote_device_ready_cmd_substate_enter,
		.exit_state  = sci_smp_remote_device_ready_cmd_substate_exit,
1055
	},
E
Edmund Nadolski 已提交
1056 1057 1058
	[SCI_DEV_STOPPING] = { },
	[SCI_DEV_FAILED] = { },
	[SCI_DEV_RESETTING] = {
1059 1060
		.enter_state = sci_remote_device_resetting_state_enter,
		.exit_state  = sci_remote_device_resetting_state_exit
1061
	},
E
Edmund Nadolski 已提交
1062
	[SCI_DEV_FINAL] = { },
1063 1064 1065
};

/**
1066
 * sci_remote_device_construct() - common construction
1067 1068 1069
 * @sci_port: SAS/SATA port through which this device is accessed.
 * @sci_dev: remote device to construct
 *
1070 1071
 * This routine just performs benign initialization and does not
 * allocate the remote_node_context which is left to
1072
 * sci_remote_device_[de]a_construct().  sci_remote_device_destruct()
1073
 * frees the remote_node_context(s) for the device.
1074
 */
1075
static void sci_remote_device_construct(struct isci_port *iport,
1076
				  struct isci_remote_device *idev)
1077
{
1078 1079
	idev->owning_port = iport;
	idev->started_request_count = 0;
1080

1081
	sci_init_sm(&idev->sm, sci_remote_device_state_table, SCI_DEV_INITIAL);
1082

1083
	sci_remote_node_context_construct(&idev->rnc,
1084 1085 1086 1087
					       SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
}

/**
1088
 * sci_remote_device_da_construct() - construct direct attached device.
1089 1090 1091
 *
 * The information (e.g. IAF, Signature FIS, etc.) necessary to build
 * the device is known to the SCI Core since it is contained in the
1092 1093
 * sci_phy object.  Remote node context(s) is/are a global resource
 * allocated by this routine, freed by sci_remote_device_destruct().
1094 1095 1096 1097 1098 1099
 *
 * Returns:
 * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
 * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
 * sata-only controller instance.
 * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
1100
 */
1101
static enum sci_status sci_remote_device_da_construct(struct isci_port *iport,
1102
						       struct isci_remote_device *idev)
1103 1104
{
	enum sci_status status;
1105
	struct sci_port_properties properties;
1106
	struct domain_device *dev = idev->domain_dev;
1107

1108
	sci_remote_device_construct(iport, idev);
1109

1110 1111 1112 1113
	/*
	 * This information is request to determine how many remote node context
	 * entries will be needed to store the remote node.
	 */
1114
	idev->is_direct_attached = true;
1115 1116 1117 1118 1119

	sci_port_get_properties(iport, &properties);
	/* Get accurate port width from port's phy mask for a DA device. */
	idev->device_port_width = hweight32(properties.phy_mask);

1120
	status = sci_controller_allocate_remote_node_context(iport->owning_controller,
1121 1122
								  idev,
								  &idev->rnc.remote_node_index);
1123

1124 1125
	if (status != SCI_SUCCESS)
		return status;
1126

1127 1128 1129 1130
	if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV ||
	    (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev))
		/* pass */;
	else
1131
		return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
1132

1133
	idev->connection_rate = sci_port_get_max_allowed_speed(iport);
1134

1135
	return SCI_SUCCESS;
1136 1137 1138
}

/**
1139
 * sci_remote_device_ea_construct() - construct expander attached device
1140 1141
 *
 * Remote node context(s) is/are a global resource allocated by this
1142
 * routine, freed by sci_remote_device_destruct().
1143 1144 1145 1146 1147 1148
 *
 * Returns:
 * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
 * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
 * sata-only controller instance.
 * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
1149
 */
1150
static enum sci_status sci_remote_device_ea_construct(struct isci_port *iport,
1151
						       struct isci_remote_device *idev)
1152
{
1153
	struct domain_device *dev = idev->domain_dev;
1154 1155
	enum sci_status status;

1156
	sci_remote_device_construct(iport, idev);
1157

1158
	status = sci_controller_allocate_remote_node_context(iport->owning_controller,
1159 1160
								  idev,
								  &idev->rnc.remote_node_index);
1161 1162
	if (status != SCI_SUCCESS)
		return status;
1163

1164 1165 1166 1167 1168
	if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV ||
	    (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev))
		/* pass */;
	else
		return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
1169

1170 1171 1172 1173 1174 1175 1176
	/*
	 * For SAS-2 the physical link rate is actually a logical link
	 * rate that incorporates multiplexing.  The SCU doesn't
	 * incorporate multiplexing and for the purposes of the
	 * connection the logical link rate is that same as the
	 * physical.  Furthermore, the SAS-2 and SAS-1.1 fields overlay
	 * one another, so this code works for both situations. */
1177
	idev->connection_rate = min_t(u16, sci_port_get_max_allowed_speed(iport),
D
Dan Williams 已提交
1178
					 dev->linkrate);
1179

1180
	/* / @todo Should I assign the port width by reading all of the phys on the port? */
1181
	idev->device_port_width = 1;
1182

1183
	return SCI_SUCCESS;
1184 1185 1186
}

/**
1187
 * sci_remote_device_start() - This method will start the supplied remote
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
 *    device.  This method enables normal IO requests to flow through to the
 *    remote device.
 * @remote_device: This parameter specifies the device to be started.
 * @timeout: This parameter specifies the number of milliseconds in which the
 *    start operation should complete.
 *
 * An indication of whether the device was successfully started. SCI_SUCCESS
 * This value is returned if the device was successfully started.
 * SCI_FAILURE_INVALID_PHY This value is returned if the user attempts to start
 * the device when there have been no phys added to it.
 */
1199
static enum sci_status sci_remote_device_start(struct isci_remote_device *idev,
1200
						u32 timeout)
1201
{
1202
	struct sci_base_state_machine *sm = &idev->sm;
1203
	enum sci_remote_device_states state = sm->current_state_id;
1204 1205
	enum sci_status status;

E
Edmund Nadolski 已提交
1206
	if (state != SCI_DEV_STOPPED) {
1207
		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
1208 1209 1210 1211
			 __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

1212
	status = sci_remote_node_context_resume(&idev->rnc,
1213
						     remote_device_resume_done,
1214
						     idev);
1215 1216 1217
	if (status != SCI_SUCCESS)
		return status;

E
Edmund Nadolski 已提交
1218
	sci_change_state(sm, SCI_DEV_STARTING);
1219 1220

	return SCI_SUCCESS;
1221
}
1222

D
Dan Williams 已提交
1223 1224
static enum sci_status isci_remote_device_construct(struct isci_port *iport,
						    struct isci_remote_device *idev)
1225
{
D
Dan Williams 已提交
1226 1227 1228
	struct isci_host *ihost = iport->isci_host;
	struct domain_device *dev = idev->domain_dev;
	enum sci_status status;
1229

D
Dan Williams 已提交
1230
	if (dev->parent && dev_is_expander(dev->parent))
1231
		status = sci_remote_device_ea_construct(iport, idev);
D
Dan Williams 已提交
1232
	else
1233
		status = sci_remote_device_da_construct(iport, idev);
1234 1235

	if (status != SCI_SUCCESS) {
D
Dan Williams 已提交
1236 1237
		dev_dbg(&ihost->pdev->dev, "%s: construct failed: %d\n",
			__func__, status);
1238 1239 1240 1241 1242

		return status;
	}

	/* start the device. */
1243
	status = sci_remote_device_start(idev, ISCI_REMOTE_DEVICE_START_TIMEOUT);
1244

D
Dan Williams 已提交
1245 1246 1247
	if (status != SCI_SUCCESS)
		dev_warn(&ihost->pdev->dev, "remote device start failed: %d\n",
			 status);
1248 1249 1250 1251

	return status;
}

1252
void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev)
1253 1254 1255
{
	DECLARE_COMPLETION_ONSTACK(aborted_task_completion);

1256 1257
	dev_dbg(&ihost->pdev->dev,
		"%s: idev = %p\n", __func__, idev);
1258 1259

	/* Cleanup all requests pending for this device. */
1260
	isci_terminate_pending_requests(ihost, idev);
1261

1262 1263
	dev_dbg(&ihost->pdev->dev,
		"%s: idev = %p, done\n", __func__, idev);
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
}

/**
 * This function builds the isci_remote_device when a libsas dev_found message
 *    is received.
 * @isci_host: This parameter specifies the isci host object.
 * @port: This parameter specifies the isci_port conected to this device.
 *
 * pointer to new isci_remote_device.
 */
static struct isci_remote_device *
D
Dan Williams 已提交
1275
isci_remote_device_alloc(struct isci_host *ihost, struct isci_port *iport)
1276
{
D
Dan Williams 已提交
1277 1278
	struct isci_remote_device *idev;
	int i;
1279

D
Dan Williams 已提交
1280
	for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
1281
		idev = &ihost->devices[i];
D
Dan Williams 已提交
1282 1283 1284
		if (!test_and_set_bit(IDEV_ALLOCATED, &idev->flags))
			break;
	}
1285

D
Dan Williams 已提交
1286 1287
	if (i >= SCI_MAX_REMOTE_DEVICES) {
		dev_warn(&ihost->pdev->dev, "%s: failed\n", __func__);
1288 1289 1290
		return NULL;
	}

1291 1292 1293 1294 1295 1296
	if (WARN_ONCE(!list_empty(&idev->reqs_in_process), "found requests in process\n"))
		return NULL;

	if (WARN_ONCE(!list_empty(&idev->node), "found non-idle remote device\n"))
		return NULL;

D
Dan Williams 已提交
1297
	return idev;
1298 1299
}

1300 1301 1302 1303 1304 1305 1306 1307 1308
void isci_remote_device_release(struct kref *kref)
{
	struct isci_remote_device *idev = container_of(kref, typeof(*idev), kref);
	struct isci_host *ihost = idev->isci_port->isci_host;

	idev->domain_dev = NULL;
	idev->isci_port = NULL;
	clear_bit(IDEV_START_PENDING, &idev->flags);
	clear_bit(IDEV_STOP_PENDING, &idev->flags);
1309
	clear_bit(IDEV_IO_READY, &idev->flags);
1310 1311 1312 1313 1314 1315
	clear_bit(IDEV_GONE, &idev->flags);
	smp_mb__before_clear_bit();
	clear_bit(IDEV_ALLOCATED, &idev->flags);
	wake_up(&ihost->eventq);
}

1316 1317 1318 1319 1320 1321
/**
 * isci_remote_device_stop() - This function is called internally to stop the
 *    remote device.
 * @isci_host: This parameter specifies the isci host object.
 * @isci_device: This parameter specifies the remote device.
 *
1322
 * The status of the ihost request to stop.
1323
 */
1324
enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
1325 1326 1327 1328
{
	enum sci_status status;
	unsigned long flags;

1329 1330
	dev_dbg(&ihost->pdev->dev,
		"%s: isci_device = %p\n", __func__, idev);
1331

1332 1333 1334 1335
	spin_lock_irqsave(&ihost->scic_lock, flags);
	idev->domain_dev->lldd_dev = NULL; /* disable new lookups */
	set_bit(IDEV_GONE, &idev->flags);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
1336 1337

	/* Kill all outstanding requests. */
1338
	isci_remote_device_nuke_requests(ihost, idev);
1339

1340
	set_bit(IDEV_STOP_PENDING, &idev->flags);
1341

1342
	spin_lock_irqsave(&ihost->scic_lock, flags);
1343
	status = sci_remote_device_stop(idev, 50);
1344
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
1345 1346

	/* Wait for the stop complete callback. */
1347 1348 1349
	if (WARN_ONCE(status != SCI_SUCCESS, "failed to stop device\n"))
		/* nothing to wait for */;
	else
1350
		wait_for_device_stop(ihost, idev);
1351 1352 1353 1354 1355 1356 1357 1358 1359 1360

	return status;
}

/**
 * isci_remote_device_gone() - This function is called by libsas when a domain
 *    device is removed.
 * @domain_device: This parameter specifies the libsas domain device.
 *
 */
1361
void isci_remote_device_gone(struct domain_device *dev)
1362
{
1363
	struct isci_host *ihost = dev_to_ihost(dev);
1364
	struct isci_remote_device *idev = dev->lldd_dev;
1365

1366
	dev_dbg(&ihost->pdev->dev,
1367
		"%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
1368
		__func__, dev, idev, idev->isci_port);
1369

1370
	isci_remote_device_stop(ihost, idev);
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
}


/**
 * isci_remote_device_found() - This function is called by libsas when a remote
 *    device is discovered. A remote device object is created and started. the
 *    function then sleeps until the sci core device started message is
 *    received.
 * @domain_device: This parameter specifies the libsas domain device.
 *
 * status, zero indicates success.
 */
1383
int isci_remote_device_found(struct domain_device *dev)
1384
{
1385 1386
	struct isci_host *isci_host = dev_to_ihost(dev);
	struct isci_port *isci_port = dev->port->lldd_port;
1387 1388 1389 1390
	struct isci_remote_device *isci_device;
	enum sci_status status;

	dev_dbg(&isci_host->pdev->dev,
1391
		"%s: domain_device = %p\n", __func__, dev);
1392

1393 1394
	if (!isci_port)
		return -ENODEV;
1395 1396

	isci_device = isci_remote_device_alloc(isci_host, isci_port);
D
Dan Williams 已提交
1397 1398
	if (!isci_device)
		return -ENODEV;
1399

1400
	kref_init(&isci_device->kref);
1401
	INIT_LIST_HEAD(&isci_device->node);
1402 1403

	spin_lock_irq(&isci_host->scic_lock);
1404
	isci_device->domain_dev = dev;
1405 1406 1407
	isci_device->isci_port = isci_port;
	list_add_tail(&isci_device->node, &isci_port->remote_dev_list);

1408
	set_bit(IDEV_START_PENDING, &isci_device->flags);
1409 1410 1411 1412 1413 1414
	status = isci_remote_device_construct(isci_port, isci_device);

	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_device = %p\n",
		__func__, isci_device);

1415 1416
	if (status == SCI_SUCCESS) {
		/* device came up, advertise it to the world */
1417
		dev->lldd_dev = isci_device;
1418 1419 1420
	} else
		isci_put_device(isci_device);
	spin_unlock_irq(&isci_host->scic_lock);
1421

1422 1423 1424
	/* wait for the device ready callback. */
	wait_for_device_start(isci_host, isci_device);

1425
	return status == SCI_SUCCESS ? 0 : -ENODEV;
1426
}