static int isci_reset_device(struct isci_host *ihost, struct domain_device *dev, struct isci_remote_device *idev) { int rc; unsigned long flags; enum sci_status status; struct sas_phy *phy = sas_get_local_phy(dev); struct isci_port *iport = dev->port->lldd_port; dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev); spin_lock_irqsave(&ihost->scic_lock, flags); status = sci_remote_device_reset(idev); spin_unlock_irqrestore(&ihost->scic_lock, flags); if (status != SCI_SUCCESS) { dev_dbg(&ihost->pdev->dev, "%s: sci_remote_device_reset(%p) returned %d!\n", __func__, idev, status); rc = TMF_RESP_FUNC_FAILED; goto out; } if (scsi_is_sas_phy_local(phy)) { struct isci_phy *iphy = &ihost->phys[phy->number]; rc = isci_port_perform_hard_reset(ihost, iport, iphy); } else rc = sas_phy_reset(phy, !dev_is_sata(dev)); /* Terminate in-progress I/O now. */ isci_remote_device_nuke_requests(ihost, idev); /* Since all pending TCs have been cleaned, resume the RNC. */ spin_lock_irqsave(&ihost->scic_lock, flags); status = sci_remote_device_reset_complete(idev); spin_unlock_irqrestore(&ihost->scic_lock, flags); if (status != SCI_SUCCESS) { dev_dbg(&ihost->pdev->dev, "%s: sci_remote_device_reset_complete(%p) " "returned %d!\n", __func__, idev, status); } dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev); out: sas_put_local_phy(phy); return rc; }
static int isci_reset_device(struct isci_host *ihost, struct domain_device *dev, struct isci_remote_device *idev) { int rc = TMF_RESP_FUNC_COMPLETE, reset_stat = -1; struct sas_phy *phy = sas_get_local_phy(dev); struct isci_port *iport = dev->port->lldd_port; dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev); /* Suspend the RNC, terminate all outstanding TCs. */ if (isci_remote_device_suspend_terminate(ihost, idev, NULL) != SCI_SUCCESS) { rc = TMF_RESP_FUNC_FAILED; goto out; } /* 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. */ 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)); } /* Explicitly resume the RNC here, since there was no task sent. */ isci_remote_device_resume_from_abort(ihost, idev); dev_dbg(&ihost->pdev->dev, "%s: idev %p complete, reset_stat=%d.\n", __func__, idev, reset_stat); out: sas_put_local_phy(phy); return rc; }