diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-04-08 11:01:17 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-04-08 11:01:17 +0100 |
commit | ee29f146c33b704a5e256fe0a36b851d021c1225 (patch) | |
tree | 5d1240a887a0ac9708e8650e73e0b75b95643d94 | |
parent | b766b4774afbaf01a0b2291e4d9add1df953dc11 (diff) | |
download | xen-ee29f146c33b704a5e256fe0a36b851d021c1225.tar.gz xen-ee29f146c33b704a5e256fe0a36b851d021c1225.tar.bz2 xen-ee29f146c33b704a5e256fe0a36b851d021c1225.zip |
Fix remove_pin_at_irq(), introduced with changeset
9586:f84a333d8aa6e1a25e2b73b07610e95007267f6a.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/arch/x86/io_apic.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index ca180d3bf7..97aae7a77d 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -110,7 +110,6 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) static void remove_pin_at_irq(unsigned int irq, int apic, int pin) { struct irq_pin_list *entry, *prev; - int idx; for (entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next]) { if ((entry->apic == apic) && (entry->pin == pin)) @@ -119,18 +118,24 @@ static void remove_pin_at_irq(unsigned int irq, int apic, int pin) BUG(); } - entry->pin = -1; - entry->apic = -1; + entry->pin = entry->apic = -1; - idx = entry - irq_2_pin; - if (idx >= NR_IRQS) { - while (prev->next != idx) + if (entry != &irq_2_pin[irq]) { + /* Removed entry is not at head of list. */ + prev = &irq_2_pin[irq]; + while (&irq_2_pin[prev->next] != entry) prev = &irq_2_pin[prev->next]; prev->next = entry->next; entry->next = irq_2_pin_free_entry; - irq_2_pin_free_entry = idx; - } else { - entry->next = 0; + irq_2_pin_free_entry = entry - irq_2_pin; + } else if (entry->next != 0) { + /* Removed entry is at head of multi-item list. */ + prev = entry; + entry = &irq_2_pin[entry->next]; + *prev = *entry; + entry->pin = entry->apic = -1; + entry->next = irq_2_pin_free_entry; + irq_2_pin_free_entry = entry - irq_2_pin; } } |