forked from KolibriOS/kolibrios
workaround for handlers registered with wrong IRQ
git-svn-id: svn://kolibrios.org@3505 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
f3b083075c
commit
9bae783f11
@ -66,8 +66,7 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
|
|||||||
test edx, edx
|
test edx, edx
|
||||||
jz .err
|
jz .err
|
||||||
|
|
||||||
pushfd
|
spin_lock_irqsave IrqsList
|
||||||
cli
|
|
||||||
|
|
||||||
;allocate handler
|
;allocate handler
|
||||||
|
|
||||||
@ -84,13 +83,14 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
|
|||||||
mov eax, [user_data]
|
mov eax, [user_data]
|
||||||
mov [ecx+IRQH.handler], edx
|
mov [ecx+IRQH.handler], edx
|
||||||
mov [ecx+IRQH.data], eax
|
mov [ecx+IRQH.data], eax
|
||||||
|
and [ecx+IRQH.num_ints], 0
|
||||||
|
|
||||||
lea edx, [irqh_tab+ebx*8]
|
lea edx, [irqh_tab+ebx*8]
|
||||||
list_add_tail ecx, edx ;clobber eax
|
list_add_tail ecx, edx ;clobber eax
|
||||||
stdcall enable_irq, ebx
|
stdcall enable_irq, ebx
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
popfd
|
spin_unlock_irqrestore IrqsList
|
||||||
.err:
|
.err:
|
||||||
pop ebx
|
pop ebx
|
||||||
mov eax, [.irqh]
|
mov eax, [.irqh]
|
||||||
@ -144,7 +144,7 @@ purge irq_serv_h
|
|||||||
|
|
||||||
align 16
|
align 16
|
||||||
.main:
|
.main:
|
||||||
save_ring3_context
|
save_ring3_context
|
||||||
|
|
||||||
mov ebp, [esp + 32]
|
mov ebp, [esp + 32]
|
||||||
mov bx, app_data;os_data
|
mov bx, app_data;os_data
|
||||||
@ -188,7 +188,7 @@ align 16
|
|||||||
|
|
||||||
push [ebx+IRQH.data]
|
push [ebx+IRQH.data]
|
||||||
call [ebx+IRQH.handler]
|
call [ebx+IRQH.handler]
|
||||||
add esp, 4
|
pop ecx
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
@ -197,6 +197,7 @@ align 16
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz .next
|
jz .next
|
||||||
|
|
||||||
|
inc [ebx+IRQH.num_ints]
|
||||||
btr [irq_active_set], ebp
|
btr [irq_active_set], ebp
|
||||||
jmp .next
|
jmp .next
|
||||||
|
|
||||||
@ -204,6 +205,42 @@ align 16
|
|||||||
btr [irq_active_set], ebp
|
btr [irq_active_set], ebp
|
||||||
jnc .exit
|
jnc .exit
|
||||||
|
|
||||||
|
; There is at least one configuration with one device which generates IRQ
|
||||||
|
; that is not the same as it should be according to PCI config space.
|
||||||
|
; For that device, the handler is registered at wrong IRQ.
|
||||||
|
; As a workaround, when nobody acknowledges the generated IRQ,
|
||||||
|
; try to ask all other registered handlers; if some handler acknowledges
|
||||||
|
; the IRQ this time, relink it to the current IRQ list.
|
||||||
|
; To make this more reliable, for every handler keep number of times
|
||||||
|
; that it has acknowledged an IRQ, and assume that handlers with at least one
|
||||||
|
; acknowledged IRQ are registered properly.
|
||||||
|
; Note: this still isn't 100% correct, because two IRQs can fire simultaneously,
|
||||||
|
; the better way would be to find the correct IRQ, but I don't know how to do
|
||||||
|
; this in that case.
|
||||||
|
push ebp
|
||||||
|
xor ebp, ebp
|
||||||
|
.try_other_irqs:
|
||||||
|
cmp ebp, [esp]
|
||||||
|
jz .try_next_irq
|
||||||
|
lea esi, [irqh_tab+ebp*8]
|
||||||
|
mov ebx, esi
|
||||||
|
.try_next_handler:
|
||||||
|
mov ebx, [ebx+IRQH.list.next]
|
||||||
|
cmp ebx, esi
|
||||||
|
je .try_next_irq
|
||||||
|
cmp [ebx+IRQH.num_ints], 0
|
||||||
|
jne .try_next_irq
|
||||||
|
push [ebx+IRQH.data]
|
||||||
|
call [ebx+IRQH.handler]
|
||||||
|
pop ecx
|
||||||
|
test eax, eax
|
||||||
|
jnz .found_in_wrong_list
|
||||||
|
.try_next_irq:
|
||||||
|
inc ebp
|
||||||
|
cmp ebp, 16
|
||||||
|
jb .try_other_irqs
|
||||||
|
pop ebp
|
||||||
|
|
||||||
inc [irq_failed+ebp*4]
|
inc [irq_failed+ebp*4]
|
||||||
.exit:
|
.exit:
|
||||||
mov [check_idle_semaphore], 5
|
mov [check_idle_semaphore], 5
|
||||||
@ -211,10 +248,21 @@ align 16
|
|||||||
mov ecx, ebp
|
mov ecx, ebp
|
||||||
call irq_eoi
|
call irq_eoi
|
||||||
|
|
||||||
restore_ring3_context
|
restore_ring3_context
|
||||||
add esp, 4
|
add esp, 4
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
.found_in_wrong_list:
|
||||||
|
DEBUGF 1,'K : warning: relinking handler from IRQ%d to IRQ%d\n',\
|
||||||
|
ebp, [esp]
|
||||||
|
spin_lock_irqsave IrqsList
|
||||||
|
list_del ebx
|
||||||
|
pop ebp
|
||||||
|
lea edx, [irqh_tab+ebp*8]
|
||||||
|
list_add_tail ebx, edx
|
||||||
|
spin_unlock_irqrestore IrqsList
|
||||||
|
jmp .exit
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
irqD:
|
irqD:
|
||||||
push eax
|
push eax
|
||||||
|
Loading…
Reference in New Issue
Block a user