From: Philippe Gerum <[email protected]> Unlike the I-pipe, Dovetail does not copy the work descriptor but merely hands over the request to the common irq_work() mechanism. We must guarantee that such descriptor lives in a portion of memory which won't go stale until the handler has run, which by design can only happen once the calling out-of-band context unwinds.
Therefore, we have to allocate a request descriptor from the core heap when issuing a request to enable/disable a particular IRQ channel from the in-band stage. Signed-off-by: Philippe Gerum <[email protected]> Signed-off-by: Jan Kiszka <[email protected]> --- kernel/drivers/udd/udd.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index e1a2bc3b0..d263afc72 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -520,6 +520,7 @@ struct irqswitch_work { rtdm_irq_t *irqh; int enabled; rtdm_event_t *done; + struct irqswitch_work *self; /* Revisit: I-pipe requirement */ }; static void lostage_irqswitch_line(struct pipeline_inband_work *inband_work) @@ -538,24 +539,32 @@ static void lostage_irqswitch_line(struct pipeline_inband_work *inband_work) if (rq->done) rtdm_event_signal(rq->done); + + xnfree(rq->self); } static void switch_irq_line(rtdm_irq_t *irqh, int enable, rtdm_event_t *done) { - struct irqswitch_work switchwork = { - .inband_work = PIPELINE_INBAND_WORK_INITIALIZER(switchwork, - lostage_irqswitch_line), - .irqh = irqh, - .enabled = enable, - .done = done, - }; + struct irqswitch_work *rq; + + rq = xnmalloc(sizeof(*rq)); + if (WARN_ON(rq == NULL)) + return; + + rq->inband_work = (struct pipeline_inband_work) + PIPELINE_INBAND_WORK_INITIALIZER(*rq, + lostage_irqswitch_line); + rq->irqh = irqh; + rq->enabled = enable; + rq->done = done; + rq->self = rq; /* Revisit: I-pipe requirement */ /* * Not pretty, but we may not traverse the kernel code for * enabling/disabling IRQ lines from primary mode. Defer this * to the root context. */ - pipeline_post_inband_work(&switchwork); + pipeline_post_inband_work(rq); } /** -- 2.26.2
