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