diff options
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_sas.c')
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.c | 16 | 
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index a85d73de7c8..8a44bc92bc7 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -434,6 +434,7 @@ static int pm8001_task_exec(struct sas_task *task, const int num,  		ccb->n_elem = n_elem;  		ccb->ccb_tag = tag;  		ccb->task = t; +		ccb->device = pm8001_dev;  		switch (t->task_proto) {  		case SAS_PROTOCOL_SMP:  			rc = pm8001_task_prep_smp(pm8001_ha, ccb); @@ -447,7 +448,6 @@ static int pm8001_task_exec(struct sas_task *task, const int num,  			break;  		case SAS_PROTOCOL_SATA:  		case SAS_PROTOCOL_STP: -		case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:  			rc = pm8001_task_prep_ata(pm8001_ha, ccb);  			break;  		default: @@ -704,6 +704,8 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev,  	int res, retry;  	struct sas_task *task = NULL;  	struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); +	struct pm8001_device *pm8001_dev = dev->lldd_dev; +	DECLARE_COMPLETION_ONSTACK(completion_setstate);  	for (retry = 0; retry < 3; retry++) {  		task = sas_alloc_slow_task(GFP_KERNEL); @@ -729,6 +731,12 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev,  			goto ex_err;  		}  		wait_for_completion(&task->slow_task->completion); +		if (pm8001_ha->chip_id != chip_8001) { +			pm8001_dev->setds_completion = &completion_setstate; +				PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, +					pm8001_dev, 0x01); +			wait_for_completion(&completion_setstate); +		}  		res = -TMF_RESP_FUNC_FAILED;  		/* Even TMF timed out, return direct. */  		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { @@ -858,13 +866,11 @@ ex_err:  static void pm8001_dev_gone_notify(struct domain_device *dev)  {  	unsigned long flags = 0; -	u32 tag;  	struct pm8001_hba_info *pm8001_ha;  	struct pm8001_device *pm8001_dev = dev->lldd_dev;  	pm8001_ha = pm8001_find_ha_by_dev(dev);  	spin_lock_irqsave(&pm8001_ha->lock, flags); -	pm8001_tag_alloc(pm8001_ha, &tag);  	if (pm8001_dev) {  		u32 device_id = pm8001_dev->device_id; @@ -1091,15 +1097,17 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun)  	struct pm8001_tmf_task tmf_task;  	struct pm8001_device *pm8001_dev = dev->lldd_dev;  	struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); +	DECLARE_COMPLETION_ONSTACK(completion_setstate);  	if (dev_is_sata(dev)) {  		struct sas_phy *phy = sas_get_local_phy(dev);  		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,  			dev, 1, 0);  		rc = sas_phy_reset(phy, 1);  		sas_put_local_phy(phy); +		pm8001_dev->setds_completion = &completion_setstate;  		rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,  			pm8001_dev, 0x01); -		msleep(2000); +		wait_for_completion(&completion_setstate);  	} else {  		tmf_task.tmf = TMF_LU_RESET;  		rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);  | 
