diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 98 | 
1 files changed, 67 insertions, 31 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index f3da592f7bc..35a13867495 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struct *work)  	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);  } +/** + * mpt2sas_base_start_watchdog - start the fault_reset_work_q + * @ioc: pointer to scsi command object + * Context: sleep. + * + * Return nothing. + */ +void +mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc) +{ +	unsigned long	 flags; + +	if (ioc->fault_reset_work_q) +		return; + +	/* initialize fault polling */ +	INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); +	snprintf(ioc->fault_reset_work_q_name, +	    sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id); +	ioc->fault_reset_work_q = +		create_singlethread_workqueue(ioc->fault_reset_work_q_name); +	if (!ioc->fault_reset_work_q) { +		printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n", +		    ioc->name, __func__, __LINE__); +			return; +	} +	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); +	if (ioc->fault_reset_work_q) +		queue_delayed_work(ioc->fault_reset_work_q, +		    &ioc->fault_reset_work, +		    msecs_to_jiffies(FAULT_POLLING_INTERVAL)); +	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); +} + +/** + * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q + * @ioc: pointer to scsi command object + * Context: sleep. + * + * Return nothing. + */ +void +mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc) +{ +	unsigned long	 flags; +	struct workqueue_struct *wq; + +	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); +	wq = ioc->fault_reset_work_q; +	ioc->fault_reset_work_q = NULL; +	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); +	if (wq) { +		if (!cancel_delayed_work(&ioc->fault_reset_work)) +			flush_workqueue(wq); +		destroy_workqueue(wq); +	} +} +  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING  /**   * _base_sas_ioc_info - verbose translation of the ioc status @@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)  	if (sas_loginfo.dw.bus_type != 3 /*SAS*/)  		return; +	/* each nexus loss loginfo */ +	if (log_info == 0x31170000) +		return; +  	/* eat the loginfos associated with task aborts */  	if (ioc->ignore_loginfos && (log_info == 30050000 || log_info ==  	    0x31140000 || log_info == 0x31130000)) @@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)  		}  	} -	pci_set_drvdata(pdev, ioc->shost);  	_base_mask_interrupts(ioc);  	r = _base_enable_msix(ioc);  	if (r) @@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)  	ioc->pci_irq = -1;  	pci_release_selected_regions(ioc->pdev, ioc->bars);  	pci_disable_device(pdev); -	pci_set_drvdata(pdev, NULL);  	return r;  } @@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)  	ioc->chip_phys = 0;  	pci_release_selected_regions(ioc->pdev, ioc->bars);  	pci_disable_device(pdev); -	pci_set_drvdata(pdev, NULL);  	return;  } @@ -3205,7 +3264,6 @@ int  mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)  {  	int r, i; -	unsigned long	 flags;  	dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,  	    __func__)); @@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)  	if (r)  		return r; +	pci_set_drvdata(ioc->pdev, ioc->shost);  	r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);  	if (r)  		goto out_free_resources; @@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)  	if (r)  		goto out_free_resources; -	/* initialize fault polling */ -	INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); -	snprintf(ioc->fault_reset_work_q_name, -	    sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id); -	ioc->fault_reset_work_q = -		create_singlethread_workqueue(ioc->fault_reset_work_q_name); -	if (!ioc->fault_reset_work_q) { -		printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n", -		    ioc->name, __func__, __LINE__); -			goto out_free_resources; -	} -	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); -	if (ioc->fault_reset_work_q) -		queue_delayed_work(ioc->fault_reset_work_q, -		    &ioc->fault_reset_work, -		    msecs_to_jiffies(FAULT_POLLING_INTERVAL)); -	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); +	mpt2sas_base_start_watchdog(ioc);  	return 0;   out_free_resources: @@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)  	ioc->remove_host = 1;  	mpt2sas_base_free_resources(ioc);  	_base_release_memory_pools(ioc); +	pci_set_drvdata(ioc->pdev, NULL);  	kfree(ioc->tm_cmds.reply);  	kfree(ioc->transport_cmds.reply);  	kfree(ioc->config_cmds.reply); @@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)  void  mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)  { -	unsigned long	 flags; -	struct workqueue_struct *wq;  	dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,  	    __func__)); -	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); -	wq = ioc->fault_reset_work_q; -	ioc->fault_reset_work_q = NULL; -	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); -	if (!cancel_delayed_work(&ioc->fault_reset_work)) -		flush_workqueue(wq); -	destroy_workqueue(wq); - +	mpt2sas_base_stop_watchdog(ioc);  	mpt2sas_base_free_resources(ioc);  	_base_release_memory_pools(ioc); +	pci_set_drvdata(ioc->pdev, NULL);  	kfree(ioc->pfacts);  	kfree(ioc->ctl_cmds.reply);  	kfree(ioc->base_cmds.reply);  | 
