aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/isci/port.c23
-rw-r--r--drivers/scsi/isci/task.c55
2 files changed, 57 insertions, 21 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index da0c4e1b9b30..2fb85bf75449 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -240,9 +240,32 @@ static void isci_port_link_down(struct isci_host *isci_host,
240 struct isci_phy *isci_phy, 240 struct isci_phy *isci_phy,
241 struct isci_port *isci_port) 241 struct isci_port *isci_port)
242{ 242{
243 struct isci_remote_device *isci_device;
244
243 dev_dbg(&isci_host->pdev->dev, 245 dev_dbg(&isci_host->pdev->dev,
244 "%s: isci_port = %p\n", __func__, isci_port); 246 "%s: isci_port = %p\n", __func__, isci_port);
245 247
248 if (isci_port) {
249
250 /* check to see if this is the last phy on this port. */
251 if (isci_phy->sas_phy.port &&
252 isci_phy->sas_phy.port->num_phys == 1) {
253 /* change the state for all devices on this port. The
254 * next task sent to this device will be returned as
255 * SAS_TASK_UNDELIVERED, and the scsi mid layer will
256 * remove the target
257 */
258 list_for_each_entry(isci_device,
259 &isci_port->remote_dev_list,
260 node) {
261 dev_dbg(&isci_host->pdev->dev,
262 "%s: isci_device = %p\n",
263 __func__, isci_device);
264 set_bit(IDEV_GONE, &isci_device->flags);
265 }
266 }
267 }
268
246 /* Notify libsas of the borken link, this will trigger calls to our 269 /* Notify libsas of the borken link, this will trigger calls to our
247 * isci_port_deformed and isci_dev_gone functions. 270 * isci_port_deformed and isci_dev_gone functions.
248 */ 271 */
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 084f8f73fade..6bc74eb012c9 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -421,7 +421,7 @@ int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
421 struct isci_host *ihost = dev_to_ihost(dev); 421 struct isci_host *ihost = dev_to_ihost(dev);
422 struct isci_remote_device *idev; 422 struct isci_remote_device *idev;
423 unsigned long flags; 423 unsigned long flags;
424 int ret; 424 int ret = TMF_RESP_FUNC_COMPLETE;
425 425
426 spin_lock_irqsave(&ihost->scic_lock, flags); 426 spin_lock_irqsave(&ihost->scic_lock, flags);
427 idev = isci_get_device(dev->lldd_dev); 427 idev = isci_get_device(dev->lldd_dev);
@@ -447,12 +447,12 @@ int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
447 goto out; 447 goto out;
448 } 448 }
449 /* All pending I/Os have been terminated and cleaned up. */ 449 /* All pending I/Os have been terminated and cleaned up. */
450 if (dev_is_sata(dev)) { 450 if (!test_bit(IDEV_GONE, &idev->flags)) {
451 sas_ata_schedule_reset(dev); 451 if (dev_is_sata(dev))
452 ret = TMF_RESP_FUNC_COMPLETE; 452 sas_ata_schedule_reset(dev);
453 } else { 453 else
454 /* Send the task management part of the reset. */ 454 /* Send the task management part of the reset. */
455 ret = isci_task_send_lu_reset_sas(ihost, idev, lun); 455 ret = isci_task_send_lu_reset_sas(ihost, idev, lun);
456 } 456 }
457 out: 457 out:
458 isci_put_device(idev); 458 isci_put_device(idev);
@@ -512,8 +512,17 @@ int isci_task_abort_task(struct sas_task *task)
512 spin_unlock_irqrestore(&ihost->scic_lock, flags); 512 spin_unlock_irqrestore(&ihost->scic_lock, flags);
513 513
514 dev_warn(&ihost->pdev->dev, 514 dev_warn(&ihost->pdev->dev,
515 "%s: dev = %p, task = %p, old_request == %p\n", 515 "%s: dev = %p (%s%s), task = %p, old_request == %p\n",
516 __func__, idev, task, old_request); 516 __func__, idev,
517 (dev_is_sata(task->dev) ? "STP/SATA"
518 : ((dev_is_expander(task->dev))
519 ? "SMP"
520 : "SSP")),
521 ((idev) ? ((test_bit(IDEV_GONE, &idev->flags))
522 ? " IDEV_GONE"
523 : "")
524 : " <NULL>"),
525 task, old_request);
517 526
518 /* Device reset conditions signalled in task_state_flags are the 527 /* Device reset conditions signalled in task_state_flags are the
519 * responsbility of libsas to observe at the start of the error 528 * responsbility of libsas to observe at the start of the error
@@ -552,7 +561,8 @@ int isci_task_abort_task(struct sas_task *task)
552 561
553 if (task->task_proto == SAS_PROTOCOL_SMP || 562 if (task->task_proto == SAS_PROTOCOL_SMP ||
554 sas_protocol_ata(task->task_proto) || 563 sas_protocol_ata(task->task_proto) ||
555 test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) { 564 test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags) ||
565 test_bit(IDEV_GONE, &idev->flags)) {
556 566
557 spin_unlock_irqrestore(&ihost->scic_lock, flags); 567 spin_unlock_irqrestore(&ihost->scic_lock, flags);
558 568
@@ -561,7 +571,8 @@ int isci_task_abort_task(struct sas_task *task)
561 571
562 dev_warn(&ihost->pdev->dev, 572 dev_warn(&ihost->pdev->dev,
563 "%s: %s request" 573 "%s: %s request"
564 " or complete_in_target (%d), thus no TMF\n", 574 " or complete_in_target (%d), "
575 "or IDEV_GONE (%d), thus no TMF\n",
565 __func__, 576 __func__,
566 ((task->task_proto == SAS_PROTOCOL_SMP) 577 ((task->task_proto == SAS_PROTOCOL_SMP)
567 ? "SMP" 578 ? "SMP"
@@ -570,7 +581,8 @@ int isci_task_abort_task(struct sas_task *task)
570 : "<other>") 581 : "<other>")
571 ), 582 ),
572 test_bit(IREQ_COMPLETE_IN_TARGET, 583 test_bit(IREQ_COMPLETE_IN_TARGET,
573 &old_request->flags)); 584 &old_request->flags),
585 test_bit(IDEV_GONE, &idev->flags));
574 586
575 spin_lock_irqsave(&task->task_state_lock, flags); 587 spin_lock_irqsave(&task->task_state_lock, flags);
576 task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | 588 task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
@@ -734,7 +746,7 @@ static int isci_reset_device(struct isci_host *ihost,
734 struct domain_device *dev, 746 struct domain_device *dev,
735 struct isci_remote_device *idev) 747 struct isci_remote_device *idev)
736{ 748{
737 int rc = TMF_RESP_FUNC_COMPLETE, reset_stat; 749 int rc = TMF_RESP_FUNC_COMPLETE, reset_stat = -1;
738 struct sas_phy *phy = sas_get_local_phy(dev); 750 struct sas_phy *phy = sas_get_local_phy(dev);
739 struct isci_port *iport = dev->port->lldd_port; 751 struct isci_port *iport = dev->port->lldd_port;
740 752
@@ -752,14 +764,15 @@ static int isci_reset_device(struct isci_host *ihost,
752 * primary duty of this function is to cleanup tasks, so that is the 764 * primary duty of this function is to cleanup tasks, so that is the
753 * relevant status. 765 * relevant status.
754 */ 766 */
755 767 if (!test_bit(IDEV_GONE, &idev->flags)) {
756 if (scsi_is_sas_phy_local(phy)) { 768 if (scsi_is_sas_phy_local(phy)) {
757 struct isci_phy *iphy = &ihost->phys[phy->number]; 769 struct isci_phy *iphy = &ihost->phys[phy->number];
758 770
759 reset_stat = isci_port_perform_hard_reset(ihost, iport, iphy); 771 reset_stat = isci_port_perform_hard_reset(ihost, iport,
760 } else 772 iphy);
761 reset_stat = sas_phy_reset(phy, !dev_is_sata(dev)); 773 } else
762 774 reset_stat = sas_phy_reset(phy, !dev_is_sata(dev));
775 }
763 /* Explicitly resume the RNC here, since there was no task sent. */ 776 /* Explicitly resume the RNC here, since there was no task sent. */
764 isci_remote_device_resume_from_abort(ihost, idev); 777 isci_remote_device_resume_from_abort(ihost, idev);
765 778