aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/hpsa.c167
-rw-r--r--drivers/scsi/hpsa.h3
2 files changed, 4 insertions, 166 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
215static struct task_struct *hpsa_scan_thread;
216static DEFINE_MUTEX(hpsa_scan_mutex);
217static LIST_HEAD(hpsa_scan_q);
218static 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 **/
230static 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 **/
277static 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 **/
309static 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
342static int check_for_unit_attention(struct ctlr_info *h, 215static 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 */
3879static int __init hpsa_init(void) 3731static 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
3894static void __exit hpsa_cleanup(void) 3736static 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
3900module_init(hpsa_init); 3741module_init(hpsa_init);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index a0502b3ac17e..fc15215145d9 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -97,9 +97,6 @@ struct ctlr_info {
97 int scan_finished; 97 int scan_finished;
98 spinlock_t scan_lock; 98 spinlock_t scan_lock;
99 wait_queue_head_t scan_wait_queue; 99 wait_queue_head_t scan_wait_queue;
100 struct mutex busy_shutting_down;
101 struct list_head scan_list;
102 struct completion scan_wait;
103 100
104 struct Scsi_Host *scsi_host; 101 struct Scsi_Host *scsi_host;
105 spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ 102 spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */