summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-01-21 05:32:14 +0000
committerShaun Ruffell <sruffell@digium.com>2011-01-21 05:32:14 +0000
commit5fbfc87f37554ccaf3309268ca20595a5412d528 (patch)
tree6499fdfb490e3c467ac7f8fa19093c084d57688f
parent8c51454d34bae9f17da7f93564a2954f99b9b8a9 (diff)
wcte12xp, wctdm24xxp: Do not call pci_set_drvdata after device initialization.
Instead of using pci_set_drvdata embed the 'struct voicebus_operations' directly in the context so we can use container_of to find the context. This resolves a problem where the 'remove_one' callback gets an invalid pointer to 'struct t1' if the VPMADT032 is in the middle of a reload when the module is unloading. DAHDI-783. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=9554 git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.4@9688 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c b/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
index cdba790..6fc6ecc 100644
--- a/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
+++ b/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
@@ -68,17 +68,14 @@ struct private_context {
struct voicebus *vb;
void *pvt;
struct completion done;
+ struct voicebus_operations ops;
};
-static void init_private_context(struct private_context *ctx)
-{
- init_completion(&ctx->done);
-}
-
static void handle_receive(struct voicebus *vb, struct list_head *buffers)
{
- struct private_context *ctx = pci_get_drvdata(vb->pdev);
struct vbb *vbb;
+ struct private_context *ctx = container_of(vb->ops,
+ struct private_context, ops);
list_for_each_entry(vbb, buffers, entry) {
__vpmadt032_receive(ctx->pvt, vbb->data);
if (__vpmadt032_done(ctx->pvt))
@@ -89,22 +86,24 @@ static void handle_receive(struct voicebus *vb, struct list_head *buffers)
static void handle_transmit(struct voicebus *vb, struct list_head *buffers)
{
struct vbb *vbb;
- struct private_context *ctx = pci_get_drvdata(vb->pdev);
+ struct private_context *ctx = container_of(vb->ops,
+ struct private_context, ops);
list_for_each_entry(vbb, buffers, entry)
__vpmadt032_transmit(ctx->pvt, vbb->data);
}
-static const struct voicebus_operations loader_operations = {
- .handle_receive = handle_receive,
- .handle_transmit = handle_transmit,
-};
+static void init_private_context(struct private_context *ctx)
+{
+ init_completion(&ctx->done);
+ ctx->ops.handle_receive = handle_receive;
+ ctx->ops.handle_transmit = handle_transmit;
+}
static int vpmadt032_load_firmware(struct voicebus *vb)
{
int ret = 0;
struct private_context *ctx;
const struct voicebus_operations *old;
- void *old_drvdata;
int id;
might_sleep();
ctx = kzalloc(sizeof(struct private_context), GFP_KERNEL);
@@ -121,14 +120,11 @@ static int vpmadt032_load_firmware(struct voicebus *vb)
ret = __vpmadt032_start_load(0, id, &ctx->pvt);
if (ret)
goto error_exit;
- old_drvdata = pci_get_drvdata(vb->pdev);
- pci_set_drvdata(vb->pdev, ctx);
old = vb->ops;
- vb->ops = &loader_operations;
+ vb->ops = &ctx->ops;
if (!wait_for_completion_timeout(&ctx->done, HZ*20))
ret = -EIO;
vb->ops = old;
- pci_set_drvdata(vb->pdev, old_drvdata);
__vpmadt032_cleanup(ctx->pvt);
error_exit:
kfree(ctx);