aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c88
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c2
3 files changed, 64 insertions, 28 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index ed9965e4b96b..c29c4f9851b9 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)
119 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 119 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
120} 120}
121 121
122/**
123 * mpt2sas_base_start_watchdog - start the fault_reset_work_q
124 * @ioc: pointer to scsi command object
125 * Context: sleep.
126 *
127 * Return nothing.
128 */
129void
130mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc)
131{
132 unsigned long flags;
133
134 if (ioc->fault_reset_work_q)
135 return;
136
137 /* initialize fault polling */
138 INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
139 snprintf(ioc->fault_reset_work_q_name,
140 sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
141 ioc->fault_reset_work_q =
142 create_singlethread_workqueue(ioc->fault_reset_work_q_name);
143 if (!ioc->fault_reset_work_q) {
144 printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
145 ioc->name, __func__, __LINE__);
146 return;
147 }
148 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
149 if (ioc->fault_reset_work_q)
150 queue_delayed_work(ioc->fault_reset_work_q,
151 &ioc->fault_reset_work,
152 msecs_to_jiffies(FAULT_POLLING_INTERVAL));
153 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
154}
155
156/**
157 * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
158 * @ioc: pointer to scsi command object
159 * Context: sleep.
160 *
161 * Return nothing.
162 */
163void
164mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
165{
166 unsigned long flags;
167 struct workqueue_struct *wq;
168
169 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
170 wq = ioc->fault_reset_work_q;
171 ioc->fault_reset_work_q = NULL;
172 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
173 if (wq) {
174 if (!cancel_delayed_work(&ioc->fault_reset_work))
175 flush_workqueue(wq);
176 destroy_workqueue(wq);
177 }
178}
179
122#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 180#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
123/** 181/**
124 * _base_sas_ioc_info - verbose translation of the ioc status 182 * _base_sas_ioc_info - verbose translation of the ioc status
@@ -3209,7 +3267,6 @@ int
3209mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) 3267mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3210{ 3268{
3211 int r, i; 3269 int r, i;
3212 unsigned long flags;
3213 3270
3214 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3271 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3215 __func__)); 3272 __func__));
@@ -3292,23 +3349,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3292 if (r) 3349 if (r)
3293 goto out_free_resources; 3350 goto out_free_resources;
3294 3351
3295 /* initialize fault polling */ 3352 mpt2sas_base_start_watchdog(ioc);
3296 INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
3297 snprintf(ioc->fault_reset_work_q_name,
3298 sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
3299 ioc->fault_reset_work_q =
3300 create_singlethread_workqueue(ioc->fault_reset_work_q_name);
3301 if (!ioc->fault_reset_work_q) {
3302 printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
3303 ioc->name, __func__, __LINE__);
3304 goto out_free_resources;
3305 }
3306 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3307 if (ioc->fault_reset_work_q)
3308 queue_delayed_work(ioc->fault_reset_work_q,
3309 &ioc->fault_reset_work,
3310 msecs_to_jiffies(FAULT_POLLING_INTERVAL));
3311 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3312 return 0; 3353 return 0;
3313 3354
3314 out_free_resources: 3355 out_free_resources:
@@ -3341,20 +3382,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3341void 3382void
3342mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) 3383mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3343{ 3384{
3344 unsigned long flags;
3345 struct workqueue_struct *wq;
3346 3385
3347 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3386 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3348 __func__)); 3387 __func__));
3349 3388
3350 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3389 mpt2sas_base_stop_watchdog(ioc);
3351 wq = ioc->fault_reset_work_q;
3352 ioc->fault_reset_work_q = NULL;
3353 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3354 if (!cancel_delayed_work(&ioc->fault_reset_work))
3355 flush_workqueue(wq);
3356 destroy_workqueue(wq);
3357
3358 mpt2sas_base_free_resources(ioc); 3390 mpt2sas_base_free_resources(ioc);
3359 _base_release_memory_pools(ioc); 3391 _base_release_memory_pools(ioc);
3360 kfree(ioc->pfacts); 3392 kfree(ioc->pfacts);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 286c185fa9e4..a29935726e7a 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -673,6 +673,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
673 673
674/* base shared API */ 674/* base shared API */
675extern struct list_head mpt2sas_ioc_list; 675extern struct list_head mpt2sas_ioc_list;
676void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc);
677void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc);
676 678
677int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc); 679int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc);
678void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc); 680void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 25c8d8294af6..2e9a4445596f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -5824,6 +5824,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state)
5824 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 5824 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5825 u32 device_state; 5825 u32 device_state;
5826 5826
5827 mpt2sas_base_stop_watchdog(ioc);
5827 flush_scheduled_work(); 5828 flush_scheduled_work();
5828 scsi_block_requests(shost); 5829 scsi_block_requests(shost);
5829 device_state = pci_choose_state(pdev, state); 5830 device_state = pci_choose_state(pdev, state);
@@ -5866,6 +5867,7 @@ _scsih_resume(struct pci_dev *pdev)
5866 5867
5867 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); 5868 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
5868 scsi_unblock_requests(shost); 5869 scsi_unblock_requests(shost);
5870 mpt2sas_base_start_watchdog(ioc);
5869 return 0; 5871 return 0;
5870} 5872}
5871#endif /* CONFIG_PM */ 5873#endif /* CONFIG_PM */