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:
parent
5759e5a6a6
commit
8870b8e1fb
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user