task.c 24.2 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 55 56
/*
 * 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.
 */

#include <linux/completion.h>
57
#include <linux/irqflags.h>
58
#include "sas.h"
59
#include <scsi/libsas.h>
60 61
#include "remote_device.h"
#include "remote_node_context.h"
62 63 64
#include "isci.h"
#include "request.h"
#include "task.h"
65
#include "host.h"
66

67
/**
68 69 70 71 72 73
* isci_task_refuse() - complete the request to the upper layer driver in
*     the case where an I/O needs to be completed back in the submit path.
* @ihost: host on which the the request was queued
* @task: request to complete
* @response: response code for the completed task.
* @status: status code for the completed task.
74 75
*
*/
76 77 78 79
static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
			     enum service_response response,
			     enum exec_status status)

80
{
81
	unsigned long flags;
82

83 84 85
	/* Normal notification (task_done) */
	dev_dbg(&ihost->pdev->dev, "%s: task = %p, response=%d, status=%d\n",
		__func__, task, response, status);
86

87
	spin_lock_irqsave(&task->task_state_lock, flags);
88

89 90
	task->task_status.resp = response;
	task->task_status.stat = status;
91

92 93 94 95 96 97 98 99
	/* Normal notification (task_done) */
	task->task_state_flags |= SAS_TASK_STATE_DONE;
	task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
				    SAS_TASK_STATE_PENDING);
	task->lldd_task = NULL;
	spin_unlock_irqrestore(&task->task_state_lock, flags);

	task->task_done(task);
100
}
101

102 103 104 105
#define for_each_sas_task(num, task) \
	for (; num > 0; num--,\
	     task = list_entry(task->list.next, struct sas_task, list))

106 107 108 109 110 111 112 113 114

static inline int isci_device_io_ready(struct isci_remote_device *idev,
				       struct sas_task *task)
{
	return idev ? test_bit(IDEV_IO_READY, &idev->flags) ||
		      (test_bit(IDEV_IO_NCQERROR, &idev->flags) &&
		       isci_task_is_ncq_recovery(task))
		    : 0;
}
115 116 117 118 119 120 121 122 123 124 125 126
/**
 * isci_task_execute_task() - This function is one of the SAS Domain Template
 *    functions. This function is called by libsas to send a task down to
 *    hardware.
 * @task: This parameter specifies the SAS task to send.
 * @num: This parameter specifies the number of tasks to queue.
 * @gfp_flags: This parameter specifies the context of this call.
 *
 * status, zero indicates success.
 */
int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
{
127
	struct isci_host *ihost = dev_to_ihost(task->dev);
128
	struct isci_remote_device *idev;
129
	unsigned long flags;
130
	bool io_ready;
131
	u16 tag;
132

133
	dev_dbg(&ihost->pdev->dev, "%s: num=%d\n", __func__, num);
134

135
	for_each_sas_task(num, task) {
136 137
		enum sci_status status = SCI_FAILURE;

138 139
		spin_lock_irqsave(&ihost->scic_lock, flags);
		idev = isci_lookup_device(task->dev);
140
		io_ready = isci_device_io_ready(idev, task);
141
		tag = isci_alloc_tag(ihost);
142
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
143

144 145 146 147
		dev_dbg(&ihost->pdev->dev,
			"task: %p, num: %d dev: %p idev: %p:%#lx cmd = %p\n",
			task, num, task->dev, idev, idev ? idev->flags : 0,
			task->uldd_task);
148

149 150 151
		if (!idev) {
			isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,
					 SAS_DEVICE_UNKNOWN);
152
		} else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {
153 154 155 156 157
			/* Indicate QUEUE_FULL so that the scsi midlayer
			 * retries.
			  */
			isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,
					 SAS_QUEUE_FULL);
158 159 160
		} else {
			/* There is a device and it's ready for I/O. */
			spin_lock_irqsave(&task->task_state_lock, flags);
161

162
			if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
163
				/* The I/O was aborted. */
164 165
				spin_unlock_irqrestore(&task->task_state_lock,
						       flags);
166

167 168 169
				isci_task_refuse(ihost, task,
						 SAS_TASK_UNDELIVERED,
						 SAM_STAT_TASK_ABORTED);
170
			} else {
171 172
				task->task_state_flags |= SAS_TASK_AT_INITIATOR;
				spin_unlock_irqrestore(&task->task_state_lock, flags);
173 174

				/* build and send the request. */
D
Dan Williams 已提交
175
				status = isci_request_execute(ihost, idev, task, tag);
176 177 178 179 180 181 182 183

				if (status != SCI_SUCCESS) {

					spin_lock_irqsave(&task->task_state_lock, flags);
					/* Did not really start this command. */
					task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
					spin_unlock_irqrestore(&task->task_state_lock, flags);

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
					if (test_bit(IDEV_GONE, &idev->flags)) {

						/* Indicate that the device
						 * is gone.
						 */
						isci_task_refuse(ihost, task,
							SAS_TASK_UNDELIVERED,
							SAS_DEVICE_UNKNOWN);
					} else {
						/* Indicate QUEUE_FULL so that
						 * the scsi midlayer retries.
						 * If the request failed for
						 * remote device reasons, it
						 * gets returned as
						 * SAS_TASK_UNDELIVERED next
						 * time through.
						 */
						isci_task_refuse(ihost, task,
							SAS_TASK_COMPLETE,
							SAS_QUEUE_FULL);
					}
205
				}
206 207
			}
		}
208 209 210 211 212 213 214 215
		if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {
			spin_lock_irqsave(&ihost->scic_lock, flags);
			/* command never hit the device, so just free
			 * the tci and skip the sequence increment
			 */
			isci_tci_free(ihost, ISCI_TAG_TCI(tag));
			spin_unlock_irqrestore(&ihost->scic_lock, flags);
		}
216
		isci_put_device(idev);
217
	}
218 219 220
	return 0;
}

D
Dan Williams 已提交
221
static struct isci_request *isci_task_request_build(struct isci_host *ihost,
222
						    struct isci_remote_device *idev,
223
						    u16 tag, struct isci_tmf *isci_tmf)
224 225
{
	enum sci_status status = SCI_FAILURE;
D
Dan Williams 已提交
226
	struct isci_request *ireq = NULL;
227
	struct domain_device *dev;
228

D
Dan Williams 已提交
229
	dev_dbg(&ihost->pdev->dev,
230 231
		"%s: isci_tmf = %p\n", __func__, isci_tmf);

D
Dan Williams 已提交
232
	dev = idev->domain_dev;
233 234

	/* do common allocation and init of request object. */
D
Dan Williams 已提交
235
	ireq = isci_tmf_request_from_tag(ihost, isci_tmf, tag);
D
Dan Williams 已提交
236 237
	if (!ireq)
		return NULL;
238 239

	/* let the core do it's construct. */
240
	status = sci_task_request_construct(ihost, idev, tag,
241
					     ireq);
242 243

	if (status != SCI_SUCCESS) {
D
Dan Williams 已提交
244
		dev_warn(&ihost->pdev->dev,
245
			 "%s: sci_task_request_construct failed - "
246 247 248
			 "status = 0x%x\n",
			 __func__,
			 status);
D
Dan Williams 已提交
249
		return NULL;
250 251
	}

252
	/* XXX convert to get this from task->tproto like other drivers */
253
	if (dev->dev_type == SAS_END_DEVICE) {
254
		isci_tmf->proto = SAS_PROTOCOL_SSP;
255
		status = sci_task_request_construct_ssp(ireq);
256
		if (status != SCI_SUCCESS)
D
Dan Williams 已提交
257
			return NULL;
258 259
	}

D
Dan Williams 已提交
260
	return ireq;
261 262
}

263 264 265
static int isci_task_execute_tmf(struct isci_host *ihost,
				 struct isci_remote_device *idev,
				 struct isci_tmf *tmf, unsigned long timeout_ms)
266 267
{
	DECLARE_COMPLETION_ONSTACK(completion);
268
	enum sci_task_status status = SCI_TASK_FAILURE;
D
Dan Williams 已提交
269
	struct isci_request *ireq;
270 271
	int ret = TMF_RESP_FUNC_FAILED;
	unsigned long flags;
E
Edmund Nadolski 已提交
272
	unsigned long timeleft;
273 274 275 276 277 278 279 280
	u16 tag;

	spin_lock_irqsave(&ihost->scic_lock, flags);
	tag = isci_alloc_tag(ihost);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);

	if (tag == SCI_CONTROLLER_INVALID_IO_TAG)
		return ret;
281 282 283 284

	/* sanity check, return TMF_RESP_FUNC_FAILED
	 * if the device is not there and ready.
	 */
285 286 287
	if (!idev ||
	    (!test_bit(IDEV_IO_READY, &idev->flags) &&
	     !test_bit(IDEV_IO_NCQERROR, &idev->flags))) {
D
Dan Williams 已提交
288
		dev_dbg(&ihost->pdev->dev,
289
			"%s: idev = %p not ready (%#lx)\n",
290
			__func__,
291
			idev, idev ? idev->flags : 0);
292
		goto err_tci;
293
	} else
D
Dan Williams 已提交
294
		dev_dbg(&ihost->pdev->dev,
295 296
			"%s: idev = %p\n",
			__func__, idev);
297 298 299

	/* Assign the pointer to the TMF's completion kernel wait structure. */
	tmf->complete = &completion;
300
	tmf->status = SCI_FAILURE_TIMEOUT;
301

302
	ireq = isci_task_request_build(ihost, idev, tag, tmf);
303 304
	if (!ireq)
		goto err_tci;
305

D
Dan Williams 已提交
306
	spin_lock_irqsave(&ihost->scic_lock, flags);
307 308

	/* start the TMF io. */
309
	status = sci_controller_start_task(ihost, idev, ireq);
310

311
	if (status != SCI_TASK_SUCCESS) {
D
Dan Williams 已提交
312
		dev_dbg(&ihost->pdev->dev,
313 314 315
			 "%s: start_io failed - status = 0x%x, request = %p\n",
			 __func__,
			 status,
D
Dan Williams 已提交
316 317
			 ireq);
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
D
Dan Williams 已提交
318
		goto err_tci;
319
	}
D
Dan Williams 已提交
320
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
321

322 323 324
	/* The RNC must be unsuspended before the TMF can get a response. */
	isci_remote_device_resume_from_abort(ihost, idev);

325
	/* Wait for the TMF to complete, or a timeout. */
E
Edmund Nadolski 已提交
326
	timeleft = wait_for_completion_timeout(&completion,
327
					       msecs_to_jiffies(timeout_ms));
E
Edmund Nadolski 已提交
328 329

	if (timeleft == 0) {
330 331 332
		/* The TMF did not complete - this could be because
		 * of an unplug.  Terminate the TMF request now.
		 */
333
		isci_remote_device_suspend_terminate(ihost, idev, ireq);
E
Edmund Nadolski 已提交
334
	}
335

336
	isci_print_tmf(ihost, tmf);
337 338 339 340

	if (tmf->status == SCI_SUCCESS)
		ret =  TMF_RESP_FUNC_COMPLETE;
	else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {
D
Dan Williams 已提交
341
		dev_dbg(&ihost->pdev->dev,
342 343 344 345 346 347 348
			"%s: tmf.status == "
			"SCI_FAILURE_IO_RESPONSE_VALID\n",
			__func__);
		ret =  TMF_RESP_FUNC_COMPLETE;
	}
	/* Else - leave the default "failed" status alone. */

D
Dan Williams 已提交
349
	dev_dbg(&ihost->pdev->dev,
350 351
		"%s: completed request = %p\n",
		__func__,
D
Dan Williams 已提交
352
		ireq);
353 354

	return ret;
355 356 357 358 359 360 361

 err_tci:
	spin_lock_irqsave(&ihost->scic_lock, flags);
	isci_tci_free(ihost, ISCI_TAG_TCI(tag));
	spin_unlock_irqrestore(&ihost->scic_lock, flags);

	return ret;
362 363
}

364
static void isci_task_build_tmf(struct isci_tmf *tmf,
365
				enum isci_tmf_function_codes code)
366 367
{
	memset(tmf, 0, sizeof(*tmf));
368
	tmf->tmf_code = code;
369
}
370

371 372 373
static void isci_task_build_abort_task_tmf(struct isci_tmf *tmf,
					   enum isci_tmf_function_codes code,
					   struct isci_request *old_request)
374
{
375
	isci_task_build_tmf(tmf, code);
376
	tmf->io_tag = old_request->io_tag;
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
}

/**
 * isci_task_send_lu_reset_sas() - This function is called by of the SAS Domain
 *    Template functions.
 * @lun: This parameter specifies the lun to be reset.
 *
 * status, zero indicates success.
 */
static int isci_task_send_lu_reset_sas(
	struct isci_host *isci_host,
	struct isci_remote_device *isci_device,
	u8 *lun)
{
	struct isci_tmf tmf;
	int ret = TMF_RESP_FUNC_FAILED;

	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_host = %p, isci_device = %p\n",
		__func__, isci_host, isci_device);
	/* Send the LUN reset to the target.  By the time the call returns,
	 * the TMF has fully exected in the target (in which case the return
	 * value is "TMF_RESP_FUNC_COMPLETE", or the request timed-out (or
	 * was otherwise unable to be executed ("TMF_RESP_FUNC_FAILED").
	 */
402
	isci_task_build_tmf(&tmf, isci_tmf_ssp_lun_reset);
403 404

	#define ISCI_LU_RESET_TIMEOUT_MS 2000 /* 2 second timeout. */
405
	ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, ISCI_LU_RESET_TIMEOUT_MS);
406 407 408 409 410 411 412 413 414 415 416 417 418

	if (ret == TMF_RESP_FUNC_COMPLETE)
		dev_dbg(&isci_host->pdev->dev,
			"%s: %p: TMF_LU_RESET passed\n",
			__func__, isci_device);
	else
		dev_dbg(&isci_host->pdev->dev,
			"%s: %p: TMF_LU_RESET failed (%x)\n",
			__func__, isci_device, ret);

	return ret;
}

419
int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
420
{
421
	struct isci_host *ihost = dev_to_ihost(dev);
422
	struct isci_remote_device *idev;
423
	unsigned long flags;
424
	int ret = TMF_RESP_FUNC_COMPLETE;
425

426
	spin_lock_irqsave(&ihost->scic_lock, flags);
427
	idev = isci_get_device(dev->lldd_dev);
428
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
429

430
	dev_dbg(&ihost->pdev->dev,
431
		"%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
432
		__func__, dev, ihost, idev);
433

434
	if (!idev) {
435
		/* If the device is gone, escalate to I_T_Nexus_Reset. */
436
		dev_dbg(&ihost->pdev->dev, "%s: No dev\n", __func__);
437

438
		ret = TMF_RESP_FUNC_FAILED;
439
		goto out;
440 441
	}

442 443 444 445 446 447 448 449
	/* Suspend the RNC, kill all TCs */
	if (isci_remote_device_suspend_terminate(ihost, idev, NULL)
	    != SCI_SUCCESS) {
		/* The suspend/terminate only fails if isci_get_device fails */
		ret = TMF_RESP_FUNC_FAILED;
		goto out;
	}
	/* All pending I/Os have been terminated and cleaned up. */
450 451 452 453 454 455
	if (!test_bit(IDEV_GONE, &idev->flags)) {
		if (dev_is_sata(dev))
			sas_ata_schedule_reset(dev);
		else
			/* Send the task management part of the reset. */
			ret = isci_task_send_lu_reset_sas(ihost, idev, lun);
456
	}
457
 out:
458
	isci_put_device(idev);
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
	return ret;
}


/*	 int (*lldd_clear_nexus_port)(struct asd_sas_port *); */
int isci_task_clear_nexus_port(struct asd_sas_port *port)
{
	return TMF_RESP_FUNC_FAILED;
}



int isci_task_clear_nexus_ha(struct sas_ha_struct *ha)
{
	return TMF_RESP_FUNC_FAILED;
}

/* Task Management Functions. Must be called from process context.	 */

/**
 * isci_task_abort_task() - This function is one of the SAS Domain Template
 *    functions. This function is called by libsas to abort a specified task.
 * @task: This parameter specifies the SAS task to abort.
 *
 * status, zero indicates success.
 */
int isci_task_abort_task(struct sas_task *task)
{
487
	struct isci_host *ihost = dev_to_ihost(task->dev);
488
	DECLARE_COMPLETION_ONSTACK(aborted_io_completion);
489
	struct isci_request       *old_request = NULL;
490
	struct isci_remote_device *idev = NULL;
491 492 493
	struct isci_tmf           tmf;
	int                       ret = TMF_RESP_FUNC_FAILED;
	unsigned long             flags;
494
	int                       target_done_already = 0;
495 496 497 498 499 500

	/* Get the isci_request reference from the task.  Note that
	 * this check does not depend on the pending request list
	 * in the device, because tasks driving resets may land here
	 * after completion in the core.
	 */
501
	spin_lock_irqsave(&ihost->scic_lock, flags);
502 503 504 505 506 507 508
	spin_lock(&task->task_state_lock);

	old_request = task->lldd_task;

	/* If task is already done, the request isn't valid */
	if (!(task->task_state_flags & SAS_TASK_STATE_DONE) &&
	    (task->task_state_flags & SAS_TASK_AT_INITIATOR) &&
509
	    old_request) {
510
		idev = isci_get_device(task->dev->lldd_dev);
511 512 513
		target_done_already = test_bit(IREQ_COMPLETE_IN_TARGET,
					       &old_request->flags);
	}
514
	spin_unlock(&task->task_state_lock);
515
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
516

517
	dev_warn(&ihost->pdev->dev,
518 519 520 521 522 523 524 525 526 527 528
		 "%s: dev = %p (%s%s), task = %p, old_request == %p\n",
		 __func__, idev,
		 (dev_is_sata(task->dev) ? "STP/SATA"
					 : ((dev_is_expander(task->dev))
						? "SMP"
						: "SSP")),
		 ((idev) ? ((test_bit(IDEV_GONE, &idev->flags))
			   ? " IDEV_GONE"
			   : "")
			 : " <NULL>"),
		 task, old_request);
529

530 531 532
	/* Device reset conditions signalled in task_state_flags are the
	 * responsbility of libsas to observe at the start of the error
	 * handler thread.
533
	 */
534
	if (!idev || !old_request) {
535 536 537
		/* The request has already completed and there
		* is nothing to do here other than to set the task
		* done bit, and indicate that the task abort function
538
		* was successful.
539 540 541 542 543 544
		*/
		spin_lock_irqsave(&task->task_state_lock, flags);
		task->task_state_flags |= SAS_TASK_STATE_DONE;
		task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
					    SAS_TASK_STATE_PENDING);
		spin_unlock_irqrestore(&task->task_state_lock, flags);
545

546
		ret = TMF_RESP_FUNC_COMPLETE;
547

548 549 550
		dev_warn(&ihost->pdev->dev,
			 "%s: abort task not needed for %p\n",
			 __func__, task);
551
		goto out;
552
	}
553 554 555 556 557 558 559 560
	/* Suspend the RNC, kill the TC */
	if (isci_remote_device_suspend_terminate(ihost, idev, old_request)
	    != SCI_SUCCESS) {
		dev_warn(&ihost->pdev->dev,
			 "%s: isci_remote_device_reset_terminate(dev=%p, "
				 "req=%p, task=%p) failed\n",
			 __func__, idev, old_request, task);
		ret = TMF_RESP_FUNC_FAILED;
561
		goto out;
562
	}
563 564
	spin_lock_irqsave(&ihost->scic_lock, flags);

D
Dan Williams 已提交
565
	if (task->task_proto == SAS_PROTOCOL_SMP ||
566
	    sas_protocol_ata(task->task_proto) ||
567
	    target_done_already ||
568
	    test_bit(IDEV_GONE, &idev->flags)) {
569

570
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
571

572 573 574
		/* No task to send, so explicitly resume the device here */
		isci_remote_device_resume_from_abort(ihost, idev);

575 576
		dev_warn(&ihost->pdev->dev,
			 "%s: %s request"
577 578
				 " or complete_in_target (%d), "
				 "or IDEV_GONE (%d), thus no TMF\n",
579 580 581 582 583 584 585 586
			 __func__,
			 ((task->task_proto == SAS_PROTOCOL_SMP)
			  ? "SMP"
			  : (sas_protocol_ata(task->task_proto)
				? "SATA/STP"
				: "<other>")
			  ),
			 test_bit(IREQ_COMPLETE_IN_TARGET,
587 588
				  &old_request->flags),
			 test_bit(IDEV_GONE, &idev->flags));
589

590 591 592 593 594 595 596
		spin_lock_irqsave(&task->task_state_lock, flags);
		task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
					    SAS_TASK_STATE_PENDING);
		task->task_state_flags |= SAS_TASK_STATE_DONE;
		spin_unlock_irqrestore(&task->task_state_lock, flags);

		ret = TMF_RESP_FUNC_COMPLETE;
597 598
	} else {
		/* Fill in the tmf stucture */
599
		isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort,
600
					       old_request);
601

602
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
603

604
		/* Send the task management request. */
605
		#define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */
606
		ret = isci_task_execute_tmf(ihost, idev, &tmf,
607
					    ISCI_ABORT_TASK_TIMEOUT_MS);
608
	}
609
out:
610 611 612
	dev_warn(&ihost->pdev->dev,
		 "%s: Done; dev = %p, task = %p , old_request == %p\n",
		 __func__, idev, task, old_request);
613
	isci_put_device(idev);
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
	return ret;
}

/**
 * isci_task_abort_task_set() - This function is one of the SAS Domain Template
 *    functions. This is one of the Task Management functoins called by libsas,
 *    to abort all task for the given lun.
 * @d_device: This parameter specifies the domain device associated with this
 *    request.
 * @lun: This parameter specifies the lun associated with this request.
 *
 * status, zero indicates success.
 */
int isci_task_abort_task_set(
	struct domain_device *d_device,
	u8 *lun)
{
	return TMF_RESP_FUNC_FAILED;
}


/**
 * isci_task_clear_aca() - This function is one of the SAS Domain Template
 *    functions. This is one of the Task Management functoins called by libsas.
 * @d_device: This parameter specifies the domain device associated with this
 *    request.
 * @lun: This parameter specifies the lun	 associated with this request.
 *
 * status, zero indicates success.
 */
int isci_task_clear_aca(
	struct domain_device *d_device,
	u8 *lun)
{
	return TMF_RESP_FUNC_FAILED;
}



/**
 * isci_task_clear_task_set() - This function is one of the SAS Domain Template
 *    functions. This is one of the Task Management functoins called by libsas.
 * @d_device: This parameter specifies the domain device associated with this
 *    request.
 * @lun: This parameter specifies the lun	 associated with this request.
 *
 * status, zero indicates success.
 */
int isci_task_clear_task_set(
	struct domain_device *d_device,
	u8 *lun)
{
	return TMF_RESP_FUNC_FAILED;
}


/**
 * isci_task_query_task() - This function is implemented to cause libsas to
 *    correctly escalate the failed abort to a LUN or target reset (this is
 *    because sas_scsi_find_task libsas function does not correctly interpret
 *    all return codes from the abort task call).  When TMF_RESP_FUNC_SUCC is
 *    returned, libsas turns this into a LUN reset; when FUNC_FAILED is
 *    returned, libsas will turn this into a target reset
 * @task: This parameter specifies the sas task being queried.
 * @lun: This parameter specifies the lun associated with this request.
 *
 * status, zero indicates success.
 */
int isci_task_query_task(
	struct sas_task *task)
{
	/* See if there is a pending device reset for this device. */
	if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
		return TMF_RESP_FUNC_FAILED;
	else
		return TMF_RESP_FUNC_SUCC;
}

692
/*
693 694
 * isci_task_request_complete() - This function is called by the sci core when
 *    an task request completes.
695 696
 * @ihost: This parameter specifies the ISCI host object
 * @ireq: This parameter is the completed isci_request object.
697 698 699 700 701
 * @completion_status: This parameter specifies the completion status from the
 *    sci core.
 *
 * none.
 */
702 703 704 705
void
isci_task_request_complete(struct isci_host *ihost,
			   struct isci_request *ireq,
			   enum sci_task_status completion_status)
706
{
707
	struct isci_tmf *tmf = isci_request_access_tmf(ireq);
708
	struct completion *tmf_complete = NULL;
709

710
	dev_dbg(&ihost->pdev->dev,
711
		"%s: request = %p, status=%d\n",
712
		__func__, ireq, completion_status);
713

D
Dan Williams 已提交
714
	set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);
715

716 717 718 719 720 721 722 723 724 725 726 727 728 729
	if (tmf) {
		tmf->status = completion_status;

		if (tmf->proto == SAS_PROTOCOL_SSP) {
			memcpy(&tmf->resp.resp_iu,
			       &ireq->ssp.rsp,
			       SSP_RESP_IU_MAX_SIZE);
		} else if (tmf->proto == SAS_PROTOCOL_SATA) {
			memcpy(&tmf->resp.d2h_fis,
			       &ireq->stp.rsp,
			       sizeof(struct dev_to_host_fis));
		}
		/* PRINT_TMF( ((struct isci_tmf *)request->task)); */
		tmf_complete = tmf->complete;
730
	}
731
	sci_controller_complete_io(ihost, ireq->target_device, ireq);
732
	/* set the 'terminated' flag handle to make sure it cannot be terminated
733 734
	 *  or completed again.
	 */
D
Dan Williams 已提交
735
	set_bit(IREQ_TERMINATED, &ireq->flags);
736

737 738 739
	if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
		wake_up_all(&ihost->eventq);

740 741
	if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags))
		isci_free_tag(ihost, ireq->io_tag);
742

743
	/* The task management part completes last. */
744 745
	if (tmf_complete)
		complete(tmf_complete);
746 747
}

748
static int isci_reset_device(struct isci_host *ihost,
749
			     struct domain_device *dev,
750
			     struct isci_remote_device *idev)
751
{
752
	int rc = TMF_RESP_FUNC_COMPLETE, reset_stat = -1;
753 754
	struct sas_phy *phy = sas_get_local_phy(dev);
	struct isci_port *iport = dev->port->lldd_port;
755

D
Dan Williams 已提交
756
	dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);
757

758 759 760
	/* Suspend the RNC, terminate all outstanding TCs. */
	if (isci_remote_device_suspend_terminate(ihost, idev, NULL)
	    != SCI_SUCCESS) {
761 762
		rc = TMF_RESP_FUNC_FAILED;
		goto out;
763
	}
764 765 766 767 768 769
	/* Note that since the termination for outstanding requests succeeded,
	 * this function will return success.  This is because the resets will
	 * only fail if the device has been removed (ie. hotplug), and the
	 * primary duty of this function is to cleanup tasks, so that is the
	 * relevant status.
	 */
770 771 772 773 774 775 776 777 778
	if (!test_bit(IDEV_GONE, &idev->flags)) {
		if (scsi_is_sas_phy_local(phy)) {
			struct isci_phy *iphy = &ihost->phys[phy->number];

			reset_stat = isci_port_perform_hard_reset(ihost, iport,
								  iphy);
		} else
			reset_stat = sas_phy_reset(phy, !dev_is_sata(dev));
	}
779
	/* Explicitly resume the RNC here, since there was no task sent. */
780
	isci_remote_device_resume_from_abort(ihost, idev);
781

782 783
	dev_dbg(&ihost->pdev->dev, "%s: idev %p complete, reset_stat=%d.\n",
		__func__, idev, reset_stat);
784 785
 out:
	sas_put_local_phy(phy);
D
Dan Williams 已提交
786 787
	return rc;
}
788

D
Dan Williams 已提交
789 790 791 792 793
int isci_task_I_T_nexus_reset(struct domain_device *dev)
{
	struct isci_host *ihost = dev_to_ihost(dev);
	struct isci_remote_device *idev;
	unsigned long flags;
794
	int ret;
D
Dan Williams 已提交
795 796

	spin_lock_irqsave(&ihost->scic_lock, flags);
797
	idev = isci_get_device(dev->lldd_dev);
D
Dan Williams 已提交
798 799
	spin_unlock_irqrestore(&ihost->scic_lock, flags);

800 801 802 803
	if (!idev) {
		/* XXX: need to cleanup any ireqs targeting this
		 * domain_device
		 */
804
		ret = -ENODEV;
805 806
		goto out;
	}
D
Dan Williams 已提交
807

808
	ret = isci_reset_device(ihost, dev, idev);
809 810 811
 out:
	isci_put_device(idev);
	return ret;
D
Dan Williams 已提交
812
}