aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler/scsi_dh_rdac.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-02-26 21:55:51 -0500
committerDavid S. Miller <davem@davemloft.net>2012-02-26 21:55:51 -0500
commitff4783ce78c08d2990126ce1874250ae8e72bbd2 (patch)
tree5c95885a4ab768101dd72942b57c238d452a7565 /drivers/scsi/device_handler/scsi_dh_rdac.c
parent622121719934f60378279eb440d3cec2fc3176d2 (diff)
parent203738e548cefc3fc3c2f73a9063176c9f3583d5 (diff)
downloadkernel_goldelico_gta04-ff4783ce78c08d2990126ce1874250ae8e72bbd2.zip
kernel_goldelico_gta04-ff4783ce78c08d2990126ce1874250ae8e72bbd2.tar.gz
kernel_goldelico_gta04-ff4783ce78c08d2990126ce1874250ae8e72bbd2.tar.bz2
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/sfc/rx.c Overlapping changes in drivers/net/ethernet/sfc/rx.c, one to change the rx_buf->is_page boolean into a set of u16 flags, and another to adjust how ->ip_summed is initialized. Signed-off-by: David S. Miller <davem@davemloft.net>
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 53a31c7..20c4557 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)
struct rdac_controller *ctlr;
ctlr = container_of(kref, struct rdac_controller, kref);
- flush_workqueue(kmpath_rdacd);
- spin_lock(&list_lock);
list_del(&ctlr->node);
- spin_unlock(&list_lock);
kfree(ctlr);
}
@@ -376,20 +373,17 @@ static struct rdac_controller *get_controller(int index, char *array_name,
{
struct rdac_controller *ctlr, *tmp;
- spin_lock(&list_lock);
-
list_for_each_entry(tmp, &ctlr_list, node) {
if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) &&
(tmp->index == index) &&
(tmp->host == sdev->host)) {
kref_get(&tmp->kref);
- spin_unlock(&list_lock);
return tmp;
}
}
ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC);
if (!ctlr)
- goto done;
+ return NULL;
/* initialize fields of controller */
memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN);
@@ -405,8 +399,7 @@ static struct rdac_controller *get_controller(int index, char *array_name,
INIT_WORK(&ctlr->ms_work, send_mode_select);
INIT_LIST_HEAD(&ctlr->ms_head);
list_add(&ctlr->node, &ctlr_list);
-done:
- spin_unlock(&list_lock);
+
return ctlr;
}
@@ -517,9 +510,12 @@ static int initialize_controller(struct scsi_device *sdev,
index = 0;
else
index = 1;
+
+ spin_lock(&list_lock);
h->ctlr = get_controller(index, array_name, array_id, sdev);
if (!h->ctlr)
err = SCSI_DH_RES_TEMP_UNAVAIL;
+ spin_unlock(&list_lock);
}
return err;
}
@@ -906,7 +902,9 @@ static int rdac_bus_attach(struct scsi_device *sdev)
return 0;
clean_ctlr:
+ spin_lock(&list_lock);
kref_put(&h->ctlr->kref, release_controller);
+ spin_unlock(&list_lock);
failed:
kfree(scsi_dh_data);
@@ -921,14 +919,19 @@ static void rdac_bus_detach( struct scsi_device *sdev )
struct rdac_dh_data *h;
unsigned long flags;
- spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
scsi_dh_data = sdev->scsi_dh_data;
+ h = (struct rdac_dh_data *) scsi_dh_data->buf;
+ if (h->ctlr && h->ctlr->ms_queued)
+ flush_workqueue(kmpath_rdacd);
+
+ spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
sdev->scsi_dh_data = NULL;
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
- h = (struct rdac_dh_data *) scsi_dh_data->buf;
+ spin_lock(&list_lock);
if (h->ctlr)
kref_put(&h->ctlr->kref, release_controller);
+ spin_unlock(&list_lock);
kfree(scsi_dh_data);
module_put(THIS_MODULE);
sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME);