aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/request.c
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-03-31 16:10:36 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:00:36 -0400
commitce4f75def3999fbe454da9aa733ed322bc671b06 (patch)
tree363f8b709731c55d99b316ae0be2705f144b036a /drivers/scsi/isci/request.c
parentf219f010a355487638bf2fff4724a420e7158fd2 (diff)
isci: Free host lock for SATA/STP abort escalation at submission time.
In the case of I/O requests that fail at submit time because of a pending reset condition, the host lock for SATA/STP devices must be managed for any SCSI-initiated I/O before sas_task_abort is called. Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r--drivers/scsi/isci/request.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index c6ce9d0c50c2..946caaeb66c6 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -53,6 +53,7 @@
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */ 54 */
55 55
56#include <scsi/sas_ata.h>
56#include "isci.h" 57#include "isci.h"
57#include "scic_remote_device.h" 58#include "scic_remote_device.h"
58#include "scic_io_request.h" 59#include "scic_io_request.h"
@@ -356,33 +357,6 @@ int isci_request_alloc_tmf(
356} 357}
357 358
358/** 359/**
359 * isci_request_signal_device_reset() - This function will set the "device
360 * needs target reset" flag in the given sas_tasks' task_state_flags, and
361 * then cause the task to be added into the SCSI error handler queue which
362 * will eventually be escalated to a target reset.
363 *
364 *
365 */
366static void isci_request_signal_device_reset(
367 struct isci_request *isci_request)
368{
369 unsigned long flags;
370 struct sas_task *task = isci_request_access_task(isci_request);
371
372 dev_dbg(&isci_request->isci_host->pdev->dev,
373 "%s: request=%p, task=%p\n", __func__, isci_request, task);
374
375 spin_lock_irqsave(&task->task_state_lock, flags);
376 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
377 spin_unlock_irqrestore(&task->task_state_lock, flags);
378
379 /* Cause this task to be scheduled in the SCSI error handler
380 * thread.
381 */
382 sas_task_abort(task);
383}
384
385/**
386 * isci_request_execute() - This function allocates the isci_request object, 360 * isci_request_execute() - This function allocates the isci_request object,
387 * all fills in some common fields. 361 * all fills in some common fields.
388 * @isci_host: This parameter specifies the ISCI host object 362 * @isci_host: This parameter specifies the ISCI host object
@@ -453,11 +427,18 @@ int isci_request_execute(
453 /* Save the tag for possible task mgmt later. */ 427 /* Save the tag for possible task mgmt later. */
454 request->io_tag = scic_io_request_get_io_tag( 428 request->io_tag = scic_io_request_get_io_tag(
455 request->sci_request_handle); 429 request->sci_request_handle);
430 } else {
431 /* The request did not really start in the
432 * hardware, so clear the request handle
433 * here so no terminations will be done.
434 */
435 request->sci_request_handle = NULL;
456 } 436 }
437
457 } else 438 } else
458 dev_warn(&isci_host->pdev->dev, 439 dev_warn(&isci_host->pdev->dev,
459 "%s: failed request start\n", 440 "%s: failed request start (0x%x)\n",
460 __func__); 441 __func__, status);
461 442
462 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 443 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
463 444
@@ -467,7 +448,26 @@ int isci_request_execute(
467 * handler thread to work on this I/O and that 448 * handler thread to work on this I/O and that
468 * we want a device reset. 449 * we want a device reset.
469 */ 450 */
470 isci_request_signal_device_reset(request); 451 spin_lock_irqsave(&task->task_state_lock, flags);
452 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
453 spin_unlock_irqrestore(&task->task_state_lock, flags);
454
455 /* Cause this task to be scheduled in the SCSI error handler
456 * thread.
457 */
458 if (dev_is_sata(task->dev)) {
459 /* Since we are still in the submit path, and since
460 * libsas takes the host lock on behalf of SATA
461 * devices before I/O starts, we need to unlock
462 * before we can put the task in the error path.
463 */
464 raw_local_irq_save(flags);
465 spin_unlock(isci_host->shost->host_lock);
466 sas_task_abort(task);
467 spin_lock(isci_host->shost->host_lock);
468 raw_local_irq_restore(flags);
469 } else
470 sas_task_abort(task);
471 471
472 /* Change the status, since we are holding 472 /* Change the status, since we are holding
473 * the I/O until it is managed by the SCSI 473 * the I/O until it is managed by the SCSI