aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler/scsi_dh_rdac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh_rdac.c')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 53a31c753cb1..20c4557f5abd 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -364,10 +364,7 @@ static void release_controller(struct kref *kref)
364 struct rdac_controller *ctlr; 364 struct rdac_controller *ctlr;
365 ctlr = container_of(kref, struct rdac_controller, kref); 365 ctlr = container_of(kref, struct rdac_controller, kref);
366 366
367 flush_workqueue(kmpath_rdacd);
368 spin_lock(&list_lock);
369 list_del(&ctlr->node); 367 list_del(&ctlr->node);
370 spin_unlock(&list_lock);
371 kfree(ctlr); 368 kfree(ctlr);
372} 369}
373 370
@@ -376,20 +373,17 @@ static struct rdac_controller *get_controller(int index, char *array_name,
376{ 373{
377 struct rdac_controller *ctlr, *tmp; 374 struct rdac_controller *ctlr, *tmp;
378 375
379 spin_lock(&list_lock);
380
381 list_for_each_entry(tmp, &ctlr_list, node) { 376 list_for_each_entry(tmp, &ctlr_list, node) {
382 if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) && 377 if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) &&
383 (tmp->index == index) && 378 (tmp->index == index) &&
384 (tmp->host == sdev->host)) { 379 (tmp->host == sdev->host)) {
385 kref_get(&tmp->kref); 380 kref_get(&tmp->kref);
386 spin_unlock(&list_lock);
387 return tmp; 381 return tmp;
388 } 382 }
389 } 383 }
390 ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC); 384 ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC);
391 if (!ctlr) 385 if (!ctlr)
392 goto done; 386 return NULL;
393 387
394 /* initialize fields of controller */ 388 /* initialize fields of controller */
395 memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN); 389 memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN);
@@ -405,8 +399,7 @@ static struct rdac_controller *get_controller(int index, char *array_name,
405 INIT_WORK(&ctlr->ms_work, send_mode_select); 399 INIT_WORK(&ctlr->ms_work, send_mode_select);
406 INIT_LIST_HEAD(&ctlr->ms_head); 400 INIT_LIST_HEAD(&ctlr->ms_head);
407 list_add(&ctlr->node, &ctlr_list); 401 list_add(&ctlr->node, &ctlr_list);
408done: 402
409 spin_unlock(&list_lock);
410 return ctlr; 403 return ctlr;
411} 404}
412 405
@@ -517,9 +510,12 @@ static int initialize_controller(struct scsi_device *sdev,
517 index = 0; 510 index = 0;
518 else 511 else
519 index = 1; 512 index = 1;
513
514 spin_lock(&list_lock);
520 h->ctlr = get_controller(index, array_name, array_id, sdev); 515 h->ctlr = get_controller(index, array_name, array_id, sdev);
521 if (!h->ctlr) 516 if (!h->ctlr)
522 err = SCSI_DH_RES_TEMP_UNAVAIL; 517 err = SCSI_DH_RES_TEMP_UNAVAIL;
518 spin_unlock(&list_lock);
523 } 519 }
524 return err; 520 return err;
525} 521}
@@ -906,7 +902,9 @@ static int rdac_bus_attach(struct scsi_device *sdev)
906 return 0; 902 return 0;
907 903
908clean_ctlr: 904clean_ctlr:
905 spin_lock(&list_lock);
909 kref_put(&h->ctlr->kref, release_controller); 906 kref_put(&h->ctlr->kref, release_controller);
907 spin_unlock(&list_lock);
910 908
911failed: 909failed:
912 kfree(scsi_dh_data); 910 kfree(scsi_dh_data);
@@ -921,14 +919,19 @@ static void rdac_bus_detach( struct scsi_device *sdev )
921 struct rdac_dh_data *h; 919 struct rdac_dh_data *h;
922 unsigned long flags; 920 unsigned long flags;
923 921
924 spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
925 scsi_dh_data = sdev->scsi_dh_data; 922 scsi_dh_data = sdev->scsi_dh_data;
923 h = (struct rdac_dh_data *) scsi_dh_data->buf;
924 if (h->ctlr && h->ctlr->ms_queued)
925 flush_workqueue(kmpath_rdacd);
926
927 spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
926 sdev->scsi_dh_data = NULL; 928 sdev->scsi_dh_data = NULL;
927 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); 929 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
928 930
929 h = (struct rdac_dh_data *) scsi_dh_data->buf; 931 spin_lock(&list_lock);
930 if (h->ctlr) 932 if (h->ctlr)
931 kref_put(&h->ctlr->kref, release_controller); 933 kref_put(&h->ctlr->kref, release_controller);
934 spin_unlock(&list_lock);
932 kfree(scsi_dh_data); 935 kfree(scsi_dh_data);
933 module_put(THIS_MODULE); 936 module_put(THIS_MODULE);
934 sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME); 937 sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME);