diff options
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 167 |
1 files changed, 4 insertions, 163 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index a72a18eabe24..3d43bb245ac8 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #include "hpsa.h" | 53 | #include "hpsa.h" |
54 | 54 | ||
55 | /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ | 55 | /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ |
56 | #define HPSA_DRIVER_VERSION "2.0.1-3" | 56 | #define HPSA_DRIVER_VERSION "2.0.2-1" |
57 | #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" | 57 | #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" |
58 | 58 | ||
59 | /* How long to wait (in milliseconds) for board to go into simple mode */ | 59 | /* How long to wait (in milliseconds) for board to go into simple mode */ |
@@ -212,133 +212,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh) | |||
212 | return (struct ctlr_info *) *priv; | 212 | return (struct ctlr_info *) *priv; |
213 | } | 213 | } |
214 | 214 | ||
215 | static struct task_struct *hpsa_scan_thread; | ||
216 | static DEFINE_MUTEX(hpsa_scan_mutex); | ||
217 | static LIST_HEAD(hpsa_scan_q); | ||
218 | static int hpsa_scan_func(void *data); | ||
219 | |||
220 | /** | ||
221 | * add_to_scan_list() - add controller to rescan queue | ||
222 | * @h: Pointer to the controller. | ||
223 | * | ||
224 | * Adds the controller to the rescan queue if not already on the queue. | ||
225 | * | ||
226 | * returns 1 if added to the queue, 0 if skipped (could be on the | ||
227 | * queue already, or the controller could be initializing or shutting | ||
228 | * down). | ||
229 | **/ | ||
230 | static int add_to_scan_list(struct ctlr_info *h) | ||
231 | { | ||
232 | struct ctlr_info *test_h; | ||
233 | int found = 0; | ||
234 | int ret = 0; | ||
235 | |||
236 | if (h->busy_initializing) | ||
237 | return 0; | ||
238 | |||
239 | /* | ||
240 | * If we don't get the lock, it means the driver is unloading | ||
241 | * and there's no point in scheduling a new scan. | ||
242 | */ | ||
243 | if (!mutex_trylock(&h->busy_shutting_down)) | ||
244 | return 0; | ||
245 | |||
246 | mutex_lock(&hpsa_scan_mutex); | ||
247 | list_for_each_entry(test_h, &hpsa_scan_q, scan_list) { | ||
248 | if (test_h == h) { | ||
249 | found = 1; | ||
250 | break; | ||
251 | } | ||
252 | } | ||
253 | if (!found && !h->busy_scanning) { | ||
254 | INIT_COMPLETION(h->scan_wait); | ||
255 | list_add_tail(&h->scan_list, &hpsa_scan_q); | ||
256 | ret = 1; | ||
257 | } | ||
258 | mutex_unlock(&hpsa_scan_mutex); | ||
259 | mutex_unlock(&h->busy_shutting_down); | ||
260 | |||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * remove_from_scan_list() - remove controller from rescan queue | ||
266 | * @h: Pointer to the controller. | ||
267 | * | ||
268 | * Removes the controller from the rescan queue if present. Blocks if | ||
269 | * the controller is currently conducting a rescan. The controller | ||
270 | * can be in one of three states: | ||
271 | * 1. Doesn't need a scan | ||
272 | * 2. On the scan list, but not scanning yet (we remove it) | ||
273 | * 3. Busy scanning (and not on the list). In this case we want to wait for | ||
274 | * the scan to complete to make sure the scanning thread for this | ||
275 | * controller is completely idle. | ||
276 | **/ | ||
277 | static void remove_from_scan_list(struct ctlr_info *h) | ||
278 | { | ||
279 | struct ctlr_info *test_h, *tmp_h; | ||
280 | |||
281 | mutex_lock(&hpsa_scan_mutex); | ||
282 | list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) { | ||
283 | if (test_h == h) { /* state 2. */ | ||
284 | list_del(&h->scan_list); | ||
285 | complete_all(&h->scan_wait); | ||
286 | mutex_unlock(&hpsa_scan_mutex); | ||
287 | return; | ||
288 | } | ||
289 | } | ||
290 | if (h->busy_scanning) { /* state 3. */ | ||
291 | mutex_unlock(&hpsa_scan_mutex); | ||
292 | wait_for_completion(&h->scan_wait); | ||
293 | } else { /* state 1, nothing to do. */ | ||
294 | mutex_unlock(&hpsa_scan_mutex); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | /* hpsa_scan_func() - kernel thread used to rescan controllers | ||
299 | * @data: Ignored. | ||
300 | * | ||
301 | * A kernel thread used scan for drive topology changes on | ||
302 | * controllers. The thread processes only one controller at a time | ||
303 | * using a queue. Controllers are added to the queue using | ||
304 | * add_to_scan_list() and removed from the queue either after done | ||
305 | * processing or using remove_from_scan_list(). | ||
306 | * | ||
307 | * returns 0. | ||
308 | **/ | ||
309 | static int hpsa_scan_func(__attribute__((unused)) void *data) | ||
310 | { | ||
311 | struct ctlr_info *h; | ||
312 | int host_no; | ||
313 | |||
314 | while (1) { | ||
315 | set_current_state(TASK_INTERRUPTIBLE); | ||
316 | schedule(); | ||
317 | if (kthread_should_stop()) | ||
318 | break; | ||
319 | |||
320 | while (1) { | ||
321 | mutex_lock(&hpsa_scan_mutex); | ||
322 | if (list_empty(&hpsa_scan_q)) { | ||
323 | mutex_unlock(&hpsa_scan_mutex); | ||
324 | break; | ||
325 | } | ||
326 | h = list_entry(hpsa_scan_q.next, struct ctlr_info, | ||
327 | scan_list); | ||
328 | list_del(&h->scan_list); | ||
329 | h->busy_scanning = 1; | ||
330 | mutex_unlock(&hpsa_scan_mutex); | ||
331 | host_no = h->scsi_host ? h->scsi_host->host_no : -1; | ||
332 | hpsa_scan_start(h->scsi_host); | ||
333 | complete_all(&h->scan_wait); | ||
334 | mutex_lock(&hpsa_scan_mutex); | ||
335 | h->busy_scanning = 0; | ||
336 | mutex_unlock(&hpsa_scan_mutex); | ||
337 | } | ||
338 | } | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int check_for_unit_attention(struct ctlr_info *h, | 215 | static int check_for_unit_attention(struct ctlr_info *h, |
343 | struct CommandList *c) | 216 | struct CommandList *c) |
344 | { | 217 | { |
@@ -356,21 +229,8 @@ static int check_for_unit_attention(struct ctlr_info *h, | |||
356 | break; | 229 | break; |
357 | case REPORT_LUNS_CHANGED: | 230 | case REPORT_LUNS_CHANGED: |
358 | dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " | 231 | dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " |
359 | "changed\n", h->ctlr); | 232 | "changed, action required\n", h->ctlr); |
360 | /* | 233 | /* |
361 | * Here, we could call add_to_scan_list and wake up the scan thread, | ||
362 | * except that it's quite likely that we will get more than one | ||
363 | * REPORT_LUNS_CHANGED condition in quick succession, which means | ||
364 | * that those which occur after the first one will likely happen | ||
365 | * *during* the hpsa_scan_thread's rescan. And the rescan code is not | ||
366 | * robust enough to restart in the middle, undoing what it has already | ||
367 | * done, and it's not clear that it's even possible to do this, since | ||
368 | * part of what it does is notify the SCSI mid layer, which starts | ||
369 | * doing it's own i/o to read partition tables and so on, and the | ||
370 | * driver doesn't have visibility to know what might need undoing. | ||
371 | * In any event, if possible, it is horribly complicated to get right | ||
372 | * so we just don't do it for now. | ||
373 | * | ||
374 | * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. | 234 | * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. |
375 | */ | 235 | */ |
376 | break; | 236 | break; |
@@ -397,10 +257,7 @@ static ssize_t host_store_rescan(struct device *dev, | |||
397 | struct ctlr_info *h; | 257 | struct ctlr_info *h; |
398 | struct Scsi_Host *shost = class_to_shost(dev); | 258 | struct Scsi_Host *shost = class_to_shost(dev); |
399 | h = shost_to_hba(shost); | 259 | h = shost_to_hba(shost); |
400 | if (add_to_scan_list(h)) { | 260 | hpsa_scan_start(h->scsi_host); |
401 | wake_up_process(hpsa_scan_thread); | ||
402 | wait_for_completion_interruptible(&h->scan_wait); | ||
403 | } | ||
404 | return count; | 261 | return count; |
405 | } | 262 | } |
406 | 263 | ||
@@ -3553,8 +3410,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
3553 | h->busy_initializing = 1; | 3410 | h->busy_initializing = 1; |
3554 | INIT_HLIST_HEAD(&h->cmpQ); | 3411 | INIT_HLIST_HEAD(&h->cmpQ); |
3555 | INIT_HLIST_HEAD(&h->reqQ); | 3412 | INIT_HLIST_HEAD(&h->reqQ); |
3556 | mutex_init(&h->busy_shutting_down); | ||
3557 | init_completion(&h->scan_wait); | ||
3558 | rc = hpsa_pci_init(h, pdev); | 3413 | rc = hpsa_pci_init(h, pdev); |
3559 | if (rc != 0) | 3414 | if (rc != 0) |
3560 | goto clean1; | 3415 | goto clean1; |
@@ -3702,8 +3557,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) | |||
3702 | return; | 3557 | return; |
3703 | } | 3558 | } |
3704 | h = pci_get_drvdata(pdev); | 3559 | h = pci_get_drvdata(pdev); |
3705 | mutex_lock(&h->busy_shutting_down); | ||
3706 | remove_from_scan_list(h); | ||
3707 | hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ | 3560 | hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ |
3708 | hpsa_shutdown(pdev); | 3561 | hpsa_shutdown(pdev); |
3709 | iounmap(h->vaddr); | 3562 | iounmap(h->vaddr); |
@@ -3724,7 +3577,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) | |||
3724 | */ | 3577 | */ |
3725 | pci_release_regions(pdev); | 3578 | pci_release_regions(pdev); |
3726 | pci_set_drvdata(pdev, NULL); | 3579 | pci_set_drvdata(pdev, NULL); |
3727 | mutex_unlock(&h->busy_shutting_down); | ||
3728 | kfree(h); | 3580 | kfree(h); |
3729 | } | 3581 | } |
3730 | 3582 | ||
@@ -3878,23 +3730,12 @@ clean_up: | |||
3878 | */ | 3730 | */ |
3879 | static int __init hpsa_init(void) | 3731 | static int __init hpsa_init(void) |
3880 | { | 3732 | { |
3881 | int err; | 3733 | return pci_register_driver(&hpsa_pci_driver); |
3882 | /* Start the scan thread */ | ||
3883 | hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan"); | ||
3884 | if (IS_ERR(hpsa_scan_thread)) { | ||
3885 | err = PTR_ERR(hpsa_scan_thread); | ||
3886 | return -ENODEV; | ||
3887 | } | ||
3888 | err = pci_register_driver(&hpsa_pci_driver); | ||
3889 | if (err) | ||
3890 | kthread_stop(hpsa_scan_thread); | ||
3891 | return err; | ||
3892 | } | 3734 | } |
3893 | 3735 | ||
3894 | static void __exit hpsa_cleanup(void) | 3736 | static void __exit hpsa_cleanup(void) |
3895 | { | 3737 | { |
3896 | pci_unregister_driver(&hpsa_pci_driver); | 3738 | pci_unregister_driver(&hpsa_pci_driver); |
3897 | kthread_stop(hpsa_scan_thread); | ||
3898 | } | 3739 | } |
3899 | 3740 | ||
3900 | module_init(hpsa_init); | 3741 | module_init(hpsa_init); |