diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 88 |
1 files changed, 60 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 | */ | ||
| 129 | void | ||
| 130 | mpt2sas_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 | */ | ||
| 163 | void | ||
| 164 | mpt2sas_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 | |||
| 3209 | mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | 3267 | mpt2sas_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) | |||
| 3341 | void | 3382 | void |
| 3342 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | 3383 | mpt2sas_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); |
