aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMike Miller <mikem@beardog.cce.hp.com>2010-02-25 15:03:12 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-03 08:06:48 -0500
commit31468401ccf64322ca99fe05fbe64f1551240f57 (patch)
treee74aca4b1f6bda2aec3d84d0296361f86a48da67 /drivers/scsi
parente9ea04a65ad842452cbee92b5c865af7fed17f63 (diff)
[SCSI] hpsa: remove scan thread
The intent of the scan thread was to allow a UNIT ATTENTION/LUN DATA CHANGED condition encountered in the interrupt handler to trigger a rescan of devices, which can't be done in interrupt context. However, we weren't able to get this to work, due to multiple such UNIT ATTENTION conditions arriving during the rescan, during updating of the SCSI mid layer, etc. There's no way to tell the devices, "stand still while I scan you!" Since it doesn't work, there's no point in having the thread, as the rescan triggered via ioctl or sysfs can be done without such a thread. Signed-off-by: Mike Miller <mikem@beardog.cce.hp.com> Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
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[]; */