780 lines · c
1/*2 * This file is provided under a dual BSD/GPLv2 license. When using or3 * redistributing this file, you may do so under either license.4 *5 * GPL LICENSE SUMMARY6 *7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.8 *9 * This program is free software; you can redistribute it and/or modify10 * it under the terms of version 2 of the GNU General Public License as11 * published by the Free Software Foundation.12 *13 * This program is distributed in the hope that it will be useful, but14 * WITHOUT ANY WARRANTY; without even the implied warranty of15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU16 * General Public License for more details.17 *18 * You should have received a copy of the GNU General Public License19 * along with this program; if not, write to the Free Software20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.21 * The full GNU General Public License is included in this distribution22 * in the file called LICENSE.GPL.23 *24 * BSD LICENSE25 *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 without30 * modification, are permitted provided that the following conditions31 * are met:32 *33 * * Redistributions of source code must retain the above copyright34 * notice, this list of conditions and the following disclaimer.35 * * Redistributions in binary form must reproduce the above copyright36 * notice, this list of conditions and the following disclaimer in37 * the documentation and/or other materials provided with the38 * distribution.39 * * Neither the name of Intel Corporation nor the names of its40 * contributors may be used to endorse or promote products derived41 * from this software without specific prior written permission.42 *43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.54 */55 56#include <linux/completion.h>57#include <linux/irqflags.h>58#include "sas.h"59#include <scsi/libsas.h>60#include "remote_device.h"61#include "remote_node_context.h"62#include "isci.h"63#include "request.h"64#include "task.h"65#include "host.h"66 67/**68* isci_task_refuse() - complete the request to the upper layer driver in69* the case where an I/O needs to be completed back in the submit path.70* @ihost: host on which the the request was queued71* @task: request to complete72* @response: response code for the completed task.73* @status: status code for the completed task.74*75*/76static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,77 enum service_response response,78 enum exec_status status)79 80{81 unsigned long flags;82 83 /* Normal notification (task_done) */84 dev_dbg(&ihost->pdev->dev, "%s: task = %p, response=%d, status=%d\n",85 __func__, task, response, status);86 87 spin_lock_irqsave(&task->task_state_lock, flags);88 89 task->task_status.resp = response;90 task->task_status.stat = status;91 92 /* Normal notification (task_done) */93 task->task_state_flags |= SAS_TASK_STATE_DONE;94 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;95 task->lldd_task = NULL;96 spin_unlock_irqrestore(&task->task_state_lock, flags);97 98 task->task_done(task);99}100 101#define for_each_sas_task(num, task) \102 for (; num > 0; num--,\103 task = list_entry(task->list.next, struct sas_task, list))104 105 106static inline int isci_device_io_ready(struct isci_remote_device *idev,107 struct sas_task *task)108{109 return idev ? test_bit(IDEV_IO_READY, &idev->flags) ||110 (test_bit(IDEV_IO_NCQERROR, &idev->flags) &&111 isci_task_is_ncq_recovery(task))112 : 0;113}114/**115 * isci_task_execute_task() - This function is one of the SAS Domain Template116 * functions. This function is called by libsas to send a task down to117 * hardware.118 * @task: This parameter specifies the SAS task to send.119 * @gfp_flags: This parameter specifies the context of this call.120 *121 * status, zero indicates success.122 */123int isci_task_execute_task(struct sas_task *task, gfp_t gfp_flags)124{125 struct isci_host *ihost = dev_to_ihost(task->dev);126 struct isci_remote_device *idev;127 unsigned long flags;128 enum sci_status status = SCI_FAILURE;129 bool io_ready;130 u16 tag;131 132 spin_lock_irqsave(&ihost->scic_lock, flags);133 idev = isci_lookup_device(task->dev);134 io_ready = isci_device_io_ready(idev, task);135 tag = isci_alloc_tag(ihost);136 spin_unlock_irqrestore(&ihost->scic_lock, flags);137 138 dev_dbg(&ihost->pdev->dev,139 "task: %p, dev: %p idev: %p:%#lx cmd = %p\n",140 task, task->dev, idev, idev ? idev->flags : 0,141 task->uldd_task);142 143 if (!idev) {144 isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,145 SAS_DEVICE_UNKNOWN);146 } else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {147 /* Indicate QUEUE_FULL so that the scsi midlayer148 * retries.149 */150 isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,151 SAS_QUEUE_FULL);152 } else {153 /* There is a device and it's ready for I/O. */154 spin_lock_irqsave(&task->task_state_lock, flags);155 156 if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {157 /* The I/O was aborted. */158 spin_unlock_irqrestore(&task->task_state_lock, flags);159 160 isci_task_refuse(ihost, task,161 SAS_TASK_UNDELIVERED,162 SAS_SAM_STAT_TASK_ABORTED);163 } else {164 struct isci_request *ireq;165 166 /* do common allocation and init of request object. */167 ireq = isci_io_request_from_tag(ihost, task, tag);168 spin_unlock_irqrestore(&task->task_state_lock, flags);169 170 /* build and send the request. */171 /* do common allocation and init of request object. */172 status = isci_request_execute(ihost, idev, task, ireq);173 174 if (status != SCI_SUCCESS) {175 if (test_bit(IDEV_GONE, &idev->flags)) {176 /* Indicate that the device177 * is gone.178 */179 isci_task_refuse(ihost, task,180 SAS_TASK_UNDELIVERED,181 SAS_DEVICE_UNKNOWN);182 } else {183 /* Indicate QUEUE_FULL so that184 * the scsi midlayer retries.185 * If the request failed for186 * remote device reasons, it187 * gets returned as188 * SAS_TASK_UNDELIVERED next189 * time through.190 */191 isci_task_refuse(ihost, task,192 SAS_TASK_COMPLETE,193 SAS_QUEUE_FULL);194 }195 }196 }197 }198 199 if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {200 spin_lock_irqsave(&ihost->scic_lock, flags);201 /* command never hit the device, so just free202 * the tci and skip the sequence increment203 */204 isci_tci_free(ihost, ISCI_TAG_TCI(tag));205 spin_unlock_irqrestore(&ihost->scic_lock, flags);206 }207 208 isci_put_device(idev);209 return 0;210}211 212static struct isci_request *isci_task_request_build(struct isci_host *ihost,213 struct isci_remote_device *idev,214 u16 tag, struct isci_tmf *isci_tmf)215{216 enum sci_status status = SCI_FAILURE;217 struct isci_request *ireq = NULL;218 struct domain_device *dev;219 220 dev_dbg(&ihost->pdev->dev,221 "%s: isci_tmf = %p\n", __func__, isci_tmf);222 223 dev = idev->domain_dev;224 225 /* do common allocation and init of request object. */226 ireq = isci_tmf_request_from_tag(ihost, isci_tmf, tag);227 if (!ireq)228 return NULL;229 230 /* let the core do it's construct. */231 status = sci_task_request_construct(ihost, idev, tag,232 ireq);233 234 if (status != SCI_SUCCESS) {235 dev_warn(&ihost->pdev->dev,236 "%s: sci_task_request_construct failed - "237 "status = 0x%x\n",238 __func__,239 status);240 return NULL;241 }242 243 /* XXX convert to get this from task->tproto like other drivers */244 if (dev->dev_type == SAS_END_DEVICE) {245 isci_tmf->proto = SAS_PROTOCOL_SSP;246 sci_task_request_construct_ssp(ireq);247 }248 249 return ireq;250}251 252static int isci_task_execute_tmf(struct isci_host *ihost,253 struct isci_remote_device *idev,254 struct isci_tmf *tmf, unsigned long timeout_ms)255{256 DECLARE_COMPLETION_ONSTACK(completion);257 enum sci_status status = SCI_FAILURE;258 struct isci_request *ireq;259 int ret = TMF_RESP_FUNC_FAILED;260 unsigned long flags;261 unsigned long timeleft;262 u16 tag;263 264 spin_lock_irqsave(&ihost->scic_lock, flags);265 tag = isci_alloc_tag(ihost);266 spin_unlock_irqrestore(&ihost->scic_lock, flags);267 268 if (tag == SCI_CONTROLLER_INVALID_IO_TAG)269 return ret;270 271 /* sanity check, return TMF_RESP_FUNC_FAILED272 * if the device is not there and ready.273 */274 if (!idev ||275 (!test_bit(IDEV_IO_READY, &idev->flags) &&276 !test_bit(IDEV_IO_NCQERROR, &idev->flags))) {277 dev_dbg(&ihost->pdev->dev,278 "%s: idev = %p not ready (%#lx)\n",279 __func__,280 idev, idev ? idev->flags : 0);281 goto err_tci;282 } else283 dev_dbg(&ihost->pdev->dev,284 "%s: idev = %p\n",285 __func__, idev);286 287 /* Assign the pointer to the TMF's completion kernel wait structure. */288 tmf->complete = &completion;289 tmf->status = SCI_FAILURE_TIMEOUT;290 291 ireq = isci_task_request_build(ihost, idev, tag, tmf);292 if (!ireq)293 goto err_tci;294 295 spin_lock_irqsave(&ihost->scic_lock, flags);296 297 /* start the TMF io. */298 status = sci_controller_start_task(ihost, idev, ireq);299 300 if (status != SCI_SUCCESS) {301 dev_dbg(&ihost->pdev->dev,302 "%s: start_io failed - status = 0x%x, request = %p\n",303 __func__,304 status,305 ireq);306 spin_unlock_irqrestore(&ihost->scic_lock, flags);307 goto err_tci;308 }309 spin_unlock_irqrestore(&ihost->scic_lock, flags);310 311 /* The RNC must be unsuspended before the TMF can get a response. */312 isci_remote_device_resume_from_abort(ihost, idev);313 314 /* Wait for the TMF to complete, or a timeout. */315 timeleft = wait_for_completion_timeout(&completion,316 msecs_to_jiffies(timeout_ms));317 318 if (timeleft == 0) {319 /* The TMF did not complete - this could be because320 * of an unplug. Terminate the TMF request now.321 */322 isci_remote_device_suspend_terminate(ihost, idev, ireq);323 }324 325 isci_print_tmf(ihost, tmf);326 327 if (tmf->status == SCI_SUCCESS)328 ret = TMF_RESP_FUNC_COMPLETE;329 else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {330 dev_dbg(&ihost->pdev->dev,331 "%s: tmf.status == "332 "SCI_FAILURE_IO_RESPONSE_VALID\n",333 __func__);334 ret = TMF_RESP_FUNC_COMPLETE;335 }336 /* Else - leave the default "failed" status alone. */337 338 dev_dbg(&ihost->pdev->dev,339 "%s: completed request = %p\n",340 __func__,341 ireq);342 343 return ret;344 345 err_tci:346 spin_lock_irqsave(&ihost->scic_lock, flags);347 isci_tci_free(ihost, ISCI_TAG_TCI(tag));348 spin_unlock_irqrestore(&ihost->scic_lock, flags);349 350 return ret;351}352 353static void isci_task_build_tmf(struct isci_tmf *tmf,354 enum isci_tmf_function_codes code)355{356 memset(tmf, 0, sizeof(*tmf));357 tmf->tmf_code = code;358}359 360static void isci_task_build_abort_task_tmf(struct isci_tmf *tmf,361 enum isci_tmf_function_codes code,362 struct isci_request *old_request)363{364 isci_task_build_tmf(tmf, code);365 tmf->io_tag = old_request->io_tag;366}367 368/*369 * isci_task_send_lu_reset_sas() - This function is called by of the SAS Domain370 * Template functions.371 * @lun: This parameter specifies the lun to be reset.372 *373 * status, zero indicates success.374 */375static int isci_task_send_lu_reset_sas(376 struct isci_host *isci_host,377 struct isci_remote_device *isci_device,378 u8 *lun)379{380 struct isci_tmf tmf;381 int ret = TMF_RESP_FUNC_FAILED;382 383 dev_dbg(&isci_host->pdev->dev,384 "%s: isci_host = %p, isci_device = %p\n",385 __func__, isci_host, isci_device);386 /* Send the LUN reset to the target. By the time the call returns,387 * the TMF has fully exected in the target (in which case the return388 * value is "TMF_RESP_FUNC_COMPLETE", or the request timed-out (or389 * was otherwise unable to be executed ("TMF_RESP_FUNC_FAILED").390 */391 isci_task_build_tmf(&tmf, isci_tmf_ssp_lun_reset);392 393 #define ISCI_LU_RESET_TIMEOUT_MS 2000 /* 2 second timeout. */394 ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, ISCI_LU_RESET_TIMEOUT_MS);395 396 if (ret == TMF_RESP_FUNC_COMPLETE)397 dev_dbg(&isci_host->pdev->dev,398 "%s: %p: TMF_LU_RESET passed\n",399 __func__, isci_device);400 else401 dev_dbg(&isci_host->pdev->dev,402 "%s: %p: TMF_LU_RESET failed (%x)\n",403 __func__, isci_device, ret);404 405 return ret;406}407 408int isci_task_lu_reset(struct domain_device *dev, u8 *lun)409{410 struct isci_host *ihost = dev_to_ihost(dev);411 struct isci_remote_device *idev;412 unsigned long flags;413 int ret = TMF_RESP_FUNC_COMPLETE;414 415 spin_lock_irqsave(&ihost->scic_lock, flags);416 idev = isci_get_device(dev->lldd_dev);417 spin_unlock_irqrestore(&ihost->scic_lock, flags);418 419 dev_dbg(&ihost->pdev->dev,420 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",421 __func__, dev, ihost, idev);422 423 if (!idev) {424 /* If the device is gone, escalate to I_T_Nexus_Reset. */425 dev_dbg(&ihost->pdev->dev, "%s: No dev\n", __func__);426 427 ret = TMF_RESP_FUNC_FAILED;428 goto out;429 }430 431 /* Suspend the RNC, kill all TCs */432 if (isci_remote_device_suspend_terminate(ihost, idev, NULL)433 != SCI_SUCCESS) {434 /* The suspend/terminate only fails if isci_get_device fails */435 ret = TMF_RESP_FUNC_FAILED;436 goto out;437 }438 /* All pending I/Os have been terminated and cleaned up. */439 if (!test_bit(IDEV_GONE, &idev->flags)) {440 if (dev_is_sata(dev))441 sas_ata_schedule_reset(dev);442 else443 /* Send the task management part of the reset. */444 ret = isci_task_send_lu_reset_sas(ihost, idev, lun);445 }446 out:447 isci_put_device(idev);448 return ret;449}450 451 452/* int (*lldd_clear_nexus_port)(struct asd_sas_port *); */453int isci_task_clear_nexus_port(struct asd_sas_port *port)454{455 return TMF_RESP_FUNC_FAILED;456}457 458 459 460int isci_task_clear_nexus_ha(struct sas_ha_struct *ha)461{462 return TMF_RESP_FUNC_FAILED;463}464 465/* Task Management Functions. Must be called from process context. */466 467/**468 * isci_task_abort_task() - This function is one of the SAS Domain Template469 * functions. This function is called by libsas to abort a specified task.470 * @task: This parameter specifies the SAS task to abort.471 *472 * status, zero indicates success.473 */474int isci_task_abort_task(struct sas_task *task)475{476 struct isci_host *ihost = dev_to_ihost(task->dev);477 DECLARE_COMPLETION_ONSTACK(aborted_io_completion);478 struct isci_request *old_request = NULL;479 struct isci_remote_device *idev = NULL;480 struct isci_tmf tmf;481 int ret = TMF_RESP_FUNC_FAILED;482 unsigned long flags;483 int target_done_already = 0;484 485 /* Get the isci_request reference from the task. Note that486 * this check does not depend on the pending request list487 * in the device, because tasks driving resets may land here488 * after completion in the core.489 */490 spin_lock_irqsave(&ihost->scic_lock, flags);491 spin_lock(&task->task_state_lock);492 493 old_request = task->lldd_task;494 495 /* If task is already done, the request isn't valid */496 if (!(task->task_state_flags & SAS_TASK_STATE_DONE) &&497 old_request) {498 idev = isci_get_device(task->dev->lldd_dev);499 target_done_already = test_bit(IREQ_COMPLETE_IN_TARGET,500 &old_request->flags);501 }502 spin_unlock(&task->task_state_lock);503 spin_unlock_irqrestore(&ihost->scic_lock, flags);504 505 dev_warn(&ihost->pdev->dev,506 "%s: dev = %p (%s%s), task = %p, old_request == %p\n",507 __func__, idev,508 (dev_is_sata(task->dev) ? "STP/SATA"509 : ((dev_is_expander(task->dev->dev_type))510 ? "SMP"511 : "SSP")),512 ((idev) ? ((test_bit(IDEV_GONE, &idev->flags))513 ? " IDEV_GONE"514 : "")515 : " <NULL>"),516 task, old_request);517 518 /* Device reset conditions signalled in task_state_flags are the519 * responsbility of libsas to observe at the start of the error520 * handler thread.521 */522 if (!idev || !old_request) {523 /* The request has already completed and there524 * is nothing to do here other than to set the task525 * done bit, and indicate that the task abort function526 * was successful.527 */528 spin_lock_irqsave(&task->task_state_lock, flags);529 task->task_state_flags |= SAS_TASK_STATE_DONE;530 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;531 spin_unlock_irqrestore(&task->task_state_lock, flags);532 533 ret = TMF_RESP_FUNC_COMPLETE;534 535 dev_warn(&ihost->pdev->dev,536 "%s: abort task not needed for %p\n",537 __func__, task);538 goto out;539 }540 /* Suspend the RNC, kill the TC */541 if (isci_remote_device_suspend_terminate(ihost, idev, old_request)542 != SCI_SUCCESS) {543 dev_warn(&ihost->pdev->dev,544 "%s: isci_remote_device_reset_terminate(dev=%p, "545 "req=%p, task=%p) failed\n",546 __func__, idev, old_request, task);547 ret = TMF_RESP_FUNC_FAILED;548 goto out;549 }550 spin_lock_irqsave(&ihost->scic_lock, flags);551 552 if (task->task_proto == SAS_PROTOCOL_SMP ||553 sas_protocol_ata(task->task_proto) ||554 target_done_already ||555 test_bit(IDEV_GONE, &idev->flags)) {556 557 spin_unlock_irqrestore(&ihost->scic_lock, flags);558 559 /* No task to send, so explicitly resume the device here */560 isci_remote_device_resume_from_abort(ihost, idev);561 562 dev_warn(&ihost->pdev->dev,563 "%s: %s request"564 " or complete_in_target (%d), "565 "or IDEV_GONE (%d), thus no TMF\n",566 __func__,567 ((task->task_proto == SAS_PROTOCOL_SMP)568 ? "SMP"569 : (sas_protocol_ata(task->task_proto)570 ? "SATA/STP"571 : "<other>")572 ),573 test_bit(IREQ_COMPLETE_IN_TARGET,574 &old_request->flags),575 test_bit(IDEV_GONE, &idev->flags));576 577 spin_lock_irqsave(&task->task_state_lock, flags);578 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;579 task->task_state_flags |= SAS_TASK_STATE_DONE;580 spin_unlock_irqrestore(&task->task_state_lock, flags);581 582 ret = TMF_RESP_FUNC_COMPLETE;583 } else {584 /* Fill in the tmf structure */585 isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort,586 old_request);587 588 spin_unlock_irqrestore(&ihost->scic_lock, flags);589 590 /* Send the task management request. */591 #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */592 ret = isci_task_execute_tmf(ihost, idev, &tmf,593 ISCI_ABORT_TASK_TIMEOUT_MS);594 }595out:596 dev_warn(&ihost->pdev->dev,597 "%s: Done; dev = %p, task = %p , old_request == %p\n",598 __func__, idev, task, old_request);599 isci_put_device(idev);600 return ret;601}602 603/**604 * isci_task_abort_task_set() - This function is one of the SAS Domain Template605 * functions. This is one of the Task Management functoins called by libsas,606 * to abort all task for the given lun.607 * @d_device: This parameter specifies the domain device associated with this608 * request.609 * @lun: This parameter specifies the lun associated with this request.610 *611 * status, zero indicates success.612 */613int isci_task_abort_task_set(614 struct domain_device *d_device,615 u8 *lun)616{617 return TMF_RESP_FUNC_FAILED;618}619 620 621/**622 * isci_task_clear_task_set() - This function is one of the SAS Domain Template623 * functions. This is one of the Task Management functoins called by libsas.624 * @d_device: This parameter specifies the domain device associated with this625 * request.626 * @lun: This parameter specifies the lun associated with this request.627 *628 * status, zero indicates success.629 */630int isci_task_clear_task_set(631 struct domain_device *d_device,632 u8 *lun)633{634 return TMF_RESP_FUNC_FAILED;635}636 637 638/**639 * isci_task_query_task() - This function is implemented to cause libsas to640 * correctly escalate the failed abort to a LUN or target reset (this is641 * because sas_scsi_find_task libsas function does not correctly interpret642 * all return codes from the abort task call). When TMF_RESP_FUNC_SUCC is643 * returned, libsas turns this into a LUN reset; when FUNC_FAILED is644 * returned, libsas will turn this into a target reset645 * @task: This parameter specifies the sas task being queried.646 *647 * status, zero indicates success.648 */649int isci_task_query_task(650 struct sas_task *task)651{652 /* See if there is a pending device reset for this device. */653 if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)654 return TMF_RESP_FUNC_FAILED;655 else656 return TMF_RESP_FUNC_SUCC;657}658 659/*660 * isci_task_request_complete() - This function is called by the sci core when661 * an task request completes.662 * @ihost: This parameter specifies the ISCI host object663 * @ireq: This parameter is the completed isci_request object.664 * @completion_status: This parameter specifies the completion status from the665 * sci core.666 *667 * none.668 */669void670isci_task_request_complete(struct isci_host *ihost,671 struct isci_request *ireq,672 enum sci_task_status completion_status)673{674 struct isci_tmf *tmf = isci_request_access_tmf(ireq);675 struct completion *tmf_complete = NULL;676 677 dev_dbg(&ihost->pdev->dev,678 "%s: request = %p, status=%d\n",679 __func__, ireq, completion_status);680 681 set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);682 683 if (tmf) {684 tmf->status = completion_status;685 686 if (tmf->proto == SAS_PROTOCOL_SSP) {687 memcpy(tmf->resp.rsp_buf,688 ireq->ssp.rsp_buf,689 SSP_RESP_IU_MAX_SIZE);690 } else if (tmf->proto == SAS_PROTOCOL_SATA) {691 memcpy(&tmf->resp.d2h_fis,692 &ireq->stp.rsp,693 sizeof(struct dev_to_host_fis));694 }695 /* PRINT_TMF( ((struct isci_tmf *)request->task)); */696 tmf_complete = tmf->complete;697 }698 sci_controller_complete_io(ihost, ireq->target_device, ireq);699 /* set the 'terminated' flag handle to make sure it cannot be terminated700 * or completed again.701 */702 set_bit(IREQ_TERMINATED, &ireq->flags);703 704 if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))705 wake_up_all(&ihost->eventq);706 707 if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags))708 isci_free_tag(ihost, ireq->io_tag);709 710 /* The task management part completes last. */711 if (tmf_complete)712 complete(tmf_complete);713}714 715static int isci_reset_device(struct isci_host *ihost,716 struct domain_device *dev,717 struct isci_remote_device *idev)718{719 int rc = TMF_RESP_FUNC_COMPLETE, reset_stat = -1;720 struct sas_phy *phy = sas_get_local_phy(dev);721 struct isci_port *iport = dev->port->lldd_port;722 723 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);724 725 /* Suspend the RNC, terminate all outstanding TCs. */726 if (isci_remote_device_suspend_terminate(ihost, idev, NULL)727 != SCI_SUCCESS) {728 rc = TMF_RESP_FUNC_FAILED;729 goto out;730 }731 /* Note that since the termination for outstanding requests succeeded,732 * this function will return success. This is because the resets will733 * only fail if the device has been removed (ie. hotplug), and the734 * primary duty of this function is to cleanup tasks, so that is the735 * relevant status.736 */737 if (!test_bit(IDEV_GONE, &idev->flags)) {738 if (scsi_is_sas_phy_local(phy)) {739 struct isci_phy *iphy = &ihost->phys[phy->number];740 741 reset_stat = isci_port_perform_hard_reset(ihost, iport,742 iphy);743 } else744 reset_stat = sas_phy_reset(phy, !dev_is_sata(dev));745 }746 /* Explicitly resume the RNC here, since there was no task sent. */747 isci_remote_device_resume_from_abort(ihost, idev);748 749 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete, reset_stat=%d.\n",750 __func__, idev, reset_stat);751 out:752 sas_put_local_phy(phy);753 return rc;754}755 756int isci_task_I_T_nexus_reset(struct domain_device *dev)757{758 struct isci_host *ihost = dev_to_ihost(dev);759 struct isci_remote_device *idev;760 unsigned long flags;761 int ret;762 763 spin_lock_irqsave(&ihost->scic_lock, flags);764 idev = isci_get_device(dev->lldd_dev);765 spin_unlock_irqrestore(&ihost->scic_lock, flags);766 767 if (!idev) {768 /* XXX: need to cleanup any ireqs targeting this769 * domain_device770 */771 ret = -ENODEV;772 goto out;773 }774 775 ret = isci_reset_device(ihost, dev, idev);776 out:777 isci_put_device(idev);778 return ret;779}780