From 5fbfc87f37554ccaf3309268ca20595a5412d528 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Fri, 21 Jan 2011 05:32:14 +0000 Subject: 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 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 --- .../vpmadt032_loader/dahdi_vpmadt032_loader.c | 28 ++++++++++------------ 1 file 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); -- cgit v1.2.3