Пример #1
0
int asd_I_T_nexus_reset(struct domain_device *dev)
{
	int res, tmp_res, i;
	struct sas_phy *phy = sas_find_local_phy(dev);
	/* 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));
	res = sas_phy_reset(phy, reset_type);
	if (res == TMF_RESP_FUNC_COMPLETE) {
		/* wait for the maximum settle time */
		msleep(500);
		/* clear all outstanding commands (keep nexus suspended) */
		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)
			return res;
		msleep(500);
	}

	/* This is a bit of a problem:  the sequencer is still suspended
	 * and is refusing to resume.  Hope it will resume on a bigger hammer
	 * or the disk is lost */
	dev_printk(KERN_ERR, &phy->dev,
		   "Failed to resume nexus after reset 0x%x\n", tmp_res);

	return TMF_RESP_FUNC_FAILED;
}
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;
}