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>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9554 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Shaun Ruffell 2011-01-03 13:03:49 +00:00
parent 5759e5a6a6
commit 8870b8e1fb

View File

@ -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);