コード例 #1
0
static int smp_ata_check_ready(struct ata_link *link)
{
	int res;
	struct ata_port *ap = link->ap;
	struct domain_device *dev = ap->private_data;
	struct domain_device *ex_dev = dev->parent;
	struct sas_phy *phy = sas_get_local_phy(dev);
	struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy->number];

	res = sas_ex_phy_discover(ex_dev, phy->number);
	sas_put_local_phy(phy);

	/* break the wait early if the expander is unreachable,
	 * otherwise keep polling
	 */
	if (res == -ECOMM)
		return res;
	if (res != SMP_RESP_FUNC_ACC)
		return 0;

	switch (ex_phy->attached_dev_type) {
	case SATA_PENDING:
		return 0;
	case SAS_END_DEV:
		if (ex_phy->attached_sata_dev)
			return sas_ata_clear_pending(dev, ex_phy);
	default:
		return -ENODEV;
	}
}
コード例 #2
0
int asd_I_T_nexus_reset(struct domain_device *dev)
{
	int res, tmp_res, i;
	struct sas_phy *phy = sas_get_local_phy(dev);
	int reset_type = (dev->dev_type == SATA_DEV ||
			  (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;

	asd_clear_nexus_I_T(dev, NEXUS_PHASE_PRE);
	
	ASD_DPRINTK("sending %s reset to %s\n",
		    reset_type ? "hard" : "soft", dev_name(&phy->dev));
	res = sas_phy_reset(phy, reset_type);
	if (res == TMF_RESP_FUNC_COMPLETE || res == -ENODEV) {
		
		msleep(500);
		
		asd_clear_nexus_I_T(dev, NEXUS_PHASE_POST);
	}
	for (i = 0 ; i < 3; i++) {
		tmp_res = asd_clear_nexus_I_T(dev, NEXUS_PHASE_RESUME);
		if (tmp_res == TC_RESUME)
			goto out;
		msleep(500);
	}

	dev_printk(KERN_ERR, &phy->dev,
		   "Failed to resume nexus after reset 0x%x\n", tmp_res);

	res = TMF_RESP_FUNC_FAILED;
 out:
	sas_put_local_phy(phy);
	return res;
}
コード例 #3
0
ファイル: task.c プロジェクト: Geni-HP/PlainKernel
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;
}
コード例 #4
0
ファイル: task.c プロジェクト: u9621071/kernel-uek-UEK3
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;
}
コード例 #5
0
		scb->clear_nexus.flags = SEND_Q | NOTINQ;
		break;
	case NEXUS_PHASE_RESUME:
		scb->clear_nexus.flags = RESUME_TX;
	}
	scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
						   dev->lldd_dev);
	CLEAR_NEXUS_POST;
}

int asd_I_T_nexus_reset(struct domain_device *dev)
{
	int res, tmp_res, i;
<<<<<<< HEAD
<<<<<<< HEAD
	struct sas_phy *phy = sas_get_local_phy(dev);
=======
	struct sas_phy *phy = sas_find_local_phy(dev);
>>>>>>> 73a10a64c2f389351ff1594d88983f47c8de08f0
=======
	struct sas_phy *phy = sas_find_local_phy(dev);
>>>>>>> ae1773bb70f3d7cf73324ce8fba787e01d8fa9f2
	/* Standard mandates link reset for ATA  (type 0) and
	 * hard reset for SSP (type 1) */
	int reset_type = (dev->dev_type == SATA_DEV ||
			  (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;

	asd_clear_nexus_I_T(dev, NEXUS_PHASE_PRE);
	/* send a hard reset */
	ASD_DPRINTK("sending %s reset to %s\n",
		    reset_type ? "hard" : "soft", dev_name(&phy->dev));