mirror of
https://github.com/apache/nuttx.git
synced 2026-09-21 21:47:28 +08:00
sched/irq: Preserve all handlers when extending IRQ chains.
Allocate the new handler node independently of the initial chain conversion so handlers beyond the second are appended instead of silently dropped. Delay vector conversion until both required nodes are available to avoid leaving a partially constructed chain on allocation failure. Assisted-by: OpenAI Codex Signed-off-by: yushuailong <yyyusl@qq.com>
This commit is contained in:
+32
-29
@@ -158,46 +158,48 @@ int irqchain_attach(int ndx, xcpt_t isr, FAR void *arg)
|
||||
flags = spin_lock_irqsave(&g_irqchainlock);
|
||||
if (isr != irq_unexpected_isr)
|
||||
{
|
||||
if (g_irqvector[ndx].handler != irqchain_dispatch)
|
||||
node = (FAR struct irqchain_s *)
|
||||
sq_remfirst(&g_irqchainfreelist);
|
||||
if (node == NULL)
|
||||
{
|
||||
if (sq_count(&g_irqchainfreelist) < 2u)
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->handler = isr;
|
||||
node->arg = arg;
|
||||
node->next = NULL;
|
||||
|
||||
if (g_irqvector[ndx].handler != irqchain_dispatch)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = (FAR struct irqchain_s *)
|
||||
curr = (FAR struct irqchain_s *)
|
||||
sq_remfirst(&g_irqchainfreelist);
|
||||
DEBUGASSERT(node != NULL);
|
||||
|
||||
node->handler = g_irqvector[ndx].handler;
|
||||
node->arg = g_irqvector[ndx].arg;
|
||||
node->next = NULL;
|
||||
|
||||
g_irqvector[ndx].handler = irqchain_dispatch;
|
||||
g_irqvector[ndx].arg = node;
|
||||
|
||||
node = (FAR struct irqchain_s *)
|
||||
sq_remfirst(&g_irqchainfreelist);
|
||||
if (node == NULL)
|
||||
if (curr == NULL)
|
||||
{
|
||||
sq_addfirst((FAR struct sq_entry_s *)node,
|
||||
&g_irqchainfreelist);
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->handler = isr;
|
||||
node->arg = arg;
|
||||
node->next = NULL;
|
||||
curr->handler = g_irqvector[ndx].handler;
|
||||
curr->arg = g_irqvector[ndx].arg;
|
||||
curr->next = node;
|
||||
|
||||
curr = g_irqvector[ndx].arg;
|
||||
while (curr->next != NULL)
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
curr->next = node;
|
||||
g_irqvector[ndx].handler = irqchain_dispatch;
|
||||
g_irqvector[ndx].arg = curr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curr = g_irqvector[ndx].arg;
|
||||
while (curr->next != NULL)
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
curr->next = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -217,6 +219,7 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg)
|
||||
FAR struct irqchain_s *curr;
|
||||
FAR struct irqchain_s *first;
|
||||
int ndx = IRQ_TO_NDX(irq);
|
||||
|
||||
if (ndx < 0)
|
||||
{
|
||||
ret = ndx;
|
||||
|
||||
Reference in New Issue
Block a user