aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c98
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)
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
@@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
440 if (sas_loginfo.dw.bus_type != 3 /*SAS*/) 498 if (sas_loginfo.dw.bus_type != 3 /*SAS*/)
441 return; 499 return;
442 500
501 /* each nexus loss loginfo */
502 if (log_info == 0x31170000)
503 return;
504
443 /* eat the loginfos associated with task aborts */ 505 /* eat the loginfos associated with task aborts */
444 if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == 506 if (ioc->ignore_loginfos && (log_info == 30050000 || log_info ==
445 0x31140000 || log_info == 0x31130000)) 507 0x31140000 || log_info == 0x31130000))
@@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1109 } 1171 }
1110 } 1172 }
1111 1173
1112 pci_set_drvdata(pdev, ioc->shost);
1113 _base_mask_interrupts(ioc); 1174 _base_mask_interrupts(ioc);
1114 r = _base_enable_msix(ioc); 1175 r = _base_enable_msix(ioc);
1115 if (r) 1176 if (r)
@@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1132 ioc->pci_irq = -1; 1193 ioc->pci_irq = -1;
1133 pci_release_selected_regions(ioc->pdev, ioc->bars); 1194 pci_release_selected_regions(ioc->pdev, ioc->bars);
1134 pci_disable_device(pdev); 1195 pci_disable_device(pdev);
1135 pci_set_drvdata(pdev, NULL);
1136 return r; 1196 return r;
1137} 1197}
1138 1198
@@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3191 ioc->chip_phys = 0; 3251 ioc->chip_phys = 0;
3192 pci_release_selected_regions(ioc->pdev, ioc->bars); 3252 pci_release_selected_regions(ioc->pdev, ioc->bars);
3193 pci_disable_device(pdev); 3253 pci_disable_device(pdev);
3194 pci_set_drvdata(pdev, NULL);
3195 return; 3254 return;
3196} 3255}
3197 3256
@@ -3205,7 +3264,6 @@ int
3205mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) 3264mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3206{ 3265{
3207 int r, i; 3266 int r, i;
3208 unsigned long flags;
3209 3267
3210 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3268 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3211 __func__)); 3269 __func__));
@@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3214 if (r) 3272 if (r)
3215 return r; 3273 return r;
3216 3274
3275 pci_set_drvdata(ioc->pdev, ioc->shost);
3217 r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 3276 r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3218 if (r) 3277 if (r)
3219 goto out_free_resources; 3278 goto out_free_resources;
@@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3288 if (r) 3347 if (r)
3289 goto out_free_resources; 3348 goto out_free_resources;
3290 3349
3291 /* initialize fault polling */ 3350 mpt2sas_base_start_watchdog(ioc);
3292 INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
3293 snprintf(ioc->fault_reset_work_q_name,
3294 sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
3295 ioc->fault_reset_work_q =
3296 create_singlethread_workqueue(ioc->fault_reset_work_q_name);
3297 if (!ioc->fault_reset_work_q) {
3298 printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
3299 ioc->name, __func__, __LINE__);
3300 goto out_free_resources;
3301 }
3302 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3303 if (ioc->fault_reset_work_q)
3304 queue_delayed_work(ioc->fault_reset_work_q,
3305 &ioc->fault_reset_work,
3306 msecs_to_jiffies(FAULT_POLLING_INTERVAL));
3307 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3308 return 0; 3351 return 0;
3309 3352
3310 out_free_resources: 3353 out_free_resources:
@@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3312 ioc->remove_host = 1; 3355 ioc->remove_host = 1;
3313 mpt2sas_base_free_resources(ioc); 3356 mpt2sas_base_free_resources(ioc);
3314 _base_release_memory_pools(ioc); 3357 _base_release_memory_pools(ioc);
3358 pci_set_drvdata(ioc->pdev, NULL);
3315 kfree(ioc->tm_cmds.reply); 3359 kfree(ioc->tm_cmds.reply);
3316 kfree(ioc->transport_cmds.reply); 3360 kfree(ioc->transport_cmds.reply);
3317 kfree(ioc->config_cmds.reply); 3361 kfree(ioc->config_cmds.reply);
@@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3337void 3381void
3338mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) 3382mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3339{ 3383{
3340 unsigned long flags;
3341 struct workqueue_struct *wq;
3342 3384
3343 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3385 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3344 __func__)); 3386 __func__));
3345 3387
3346 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3388 mpt2sas_base_stop_watchdog(ioc);
3347 wq = ioc->fault_reset_work_q;
3348 ioc->fault_reset_work_q = NULL;
3349 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3350 if (!cancel_delayed_work(&ioc->fault_reset_work))
3351 flush_workqueue(wq);
3352 destroy_workqueue(wq);
3353
3354 mpt2sas_base_free_resources(ioc); 3389 mpt2sas_base_free_resources(ioc);
3355 _base_release_memory_pools(ioc); 3390 _base_release_memory_pools(ioc);
3391 pci_set_drvdata(ioc->pdev, NULL);
3356 kfree(ioc->pfacts); 3392 kfree(ioc->pfacts);
3357 kfree(ioc->ctl_cmds.reply); 3393 kfree(ioc->ctl_cmds.reply);
3358 kfree(ioc->base_cmds.reply); 3394 kfree(ioc->base_cmds.reply);