forked from KolibriOS/kolibrios
always install IDE interrupt handler
git-svn-id: svn://kolibrios.org@6015 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
ad9aec7af3
commit
a64323c296
@ -504,81 +504,66 @@ align 4
|
||||
IDE_irq_14_handler:
|
||||
IDE_irq_15_handler:
|
||||
IDE_common_irq_handler:
|
||||
; Most of the time, we are here because we have requested
|
||||
; a DMA transfer for the corresponding drive.
|
||||
; However,
|
||||
; a) we can be here because IDE IRQ is shared with some other device,
|
||||
; that device has actually raised IRQ,
|
||||
; it has nothing to do with IDE;
|
||||
; b) we can be here because IDE controller just does not want
|
||||
; to be silent and reacts to something even though
|
||||
; we have, in theory, disabled IRQs.
|
||||
; If the interrupt corresponds to our current request,
|
||||
; remove the interrupt request and raise the event for the waiting code.
|
||||
; In the case a), just return zero - not our interrupt.
|
||||
; In the case b), remove the interrupt request and hope for the best.
|
||||
; DEBUGF 1, 'K : IDE_irq_handler %x\n', [IDE_common_irq_param]:2
|
||||
cmp [IDE_common_irq_param], 0
|
||||
jz .exit
|
||||
pushfd
|
||||
cli
|
||||
pushad
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov ecx, [esp+4]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
cmp [IDE_common_irq_param], 14
|
||||
jz @f
|
||||
add dx, 8
|
||||
@@:
|
||||
add edx, 2 ; Bus Master IDE Status register
|
||||
in al, dx
|
||||
test al, 4
|
||||
jz @f
|
||||
mov [IDE_common_irq_param], 0
|
||||
jnz .interrupt_from_primary
|
||||
add edx, 8
|
||||
in al, dx
|
||||
test al, 4
|
||||
jnz .interrupt_from_secondary
|
||||
.exit_notour:
|
||||
xor eax, eax ; not our interrupt
|
||||
ret
|
||||
.interrupt_from_primary:
|
||||
out dx, al ; clear Interrupt bit
|
||||
sub edx, 2
|
||||
xor eax, eax
|
||||
out dx, al ; clear Bus Master IDE Command register
|
||||
mov edx, [hdbase]
|
||||
mov dx, [ecx+IDE_DATA.BAR0_val]
|
||||
add edx, 7
|
||||
in al, dx ; read status register
|
||||
in al, dx ; read status register
|
||||
cmp [IDE_common_irq_param], 14
|
||||
jz .raise
|
||||
.exit_our:
|
||||
mov al, 1
|
||||
ret
|
||||
.interrupt_from_secondary:
|
||||
out dx, al ; clear Interrupt bit
|
||||
sub edx, 2
|
||||
xor eax, eax
|
||||
out dx, al ; clear Bus Master IDE Command register
|
||||
mov dx, [ecx+IDE_DATA.BAR2_val]
|
||||
add edx, 7
|
||||
in al, dx ; read status register
|
||||
cmp [IDE_common_irq_param], 15
|
||||
jnz .exit_our
|
||||
.raise:
|
||||
cmp ecx, [IDE_controller_pointer]
|
||||
jnz .exit_our
|
||||
pushad
|
||||
mov eax, [eventPointer]
|
||||
mov ebx, [eventID]
|
||||
xor edx, edx
|
||||
xor esi, esi
|
||||
call raise_event
|
||||
popad
|
||||
popfd
|
||||
mov al, 1 ; remove the interrupt request
|
||||
ret
|
||||
@@:
|
||||
popad
|
||||
popfd
|
||||
.exit:
|
||||
xor eax, eax ; not our interrupt
|
||||
ret
|
||||
;-----------------------------------------------------------------
|
||||
proc clear_pci_ide_interrupts
|
||||
mov esi, pcidev_list
|
||||
align 4
|
||||
.loop:
|
||||
mov esi, [esi+PCIDEV.fd]
|
||||
cmp esi, pcidev_list
|
||||
jz .done
|
||||
|
||||
; cmp [esi+PCIDEV.class], 0x01018F
|
||||
mov eax, [esi+PCIDEV.class]
|
||||
shr eax, 4
|
||||
cmp eax, 0x01018
|
||||
jnz .loop
|
||||
|
||||
mov ah, [esi+PCIDEV.bus]
|
||||
mov al, 2
|
||||
mov bh, [esi+PCIDEV.devfn]
|
||||
mov bl, 0x20
|
||||
call pci_read_reg
|
||||
|
||||
and eax, 0FFFCh
|
||||
mov edx, eax
|
||||
add edx, 2
|
||||
in al, dx
|
||||
DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al
|
||||
out dx, al
|
||||
in al, dx
|
||||
DEBUGF 1,'-> %x; ',al
|
||||
add edx, 8
|
||||
in al, dx
|
||||
DEBUGF 1,'port[%x] = %x ',dx,al
|
||||
out dx, al
|
||||
in al, dx
|
||||
DEBUGF 1,'-> %x\n',al
|
||||
jmp .loop
|
||||
.done:
|
||||
ret
|
||||
endp
|
||||
|
@ -203,6 +203,8 @@ align 16
|
||||
; 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.
|
||||
cmp ebp, 1
|
||||
jz .fail
|
||||
push ebp
|
||||
xor ebp, ebp
|
||||
.try_other_irqs:
|
||||
|
@ -378,9 +378,11 @@ Init_IDE_ATA_controller_2:
|
||||
je .end_set_interrupts
|
||||
|
||||
push ecx
|
||||
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0
|
||||
stdcall attach_int_handler, 14, IDE_irq_14_handler, ecx
|
||||
pop ecx
|
||||
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax
|
||||
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0
|
||||
push ecx
|
||||
stdcall attach_int_handler, 15, IDE_irq_15_handler, ecx
|
||||
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax
|
||||
pop ecx
|
||||
|
||||
@ -400,20 +402,18 @@ Init_IDE_ATA_controller_2:
|
||||
; the IDE controller 01018f. For this reason, the interrupt handler
|
||||
; does not need to be installed if both channel IDE controller
|
||||
; running in PIO mode.
|
||||
|
||||
; ...unfortunately, PCI interrupt can be shared with other devices
|
||||
; which could enable it without consulting IDE code.
|
||||
; So install the handler anyways and try to process
|
||||
; even those interrupts which we are not expecting.
|
||||
cmp [ecx+IDE_DATA.RegsBaseAddres], 0
|
||||
je .end_set_interrupts
|
||||
|
||||
cmp [ecx+IDE_DATA.dma_hdd_channel_1], 0
|
||||
jne @f
|
||||
|
||||
cmp [ecx+IDE_DATA.dma_hdd_channel_2], 0
|
||||
je .end_set_interrupts
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov ax, [ecx+IDE_DATA.Interrupt]
|
||||
movzx eax, al
|
||||
push ecx
|
||||
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
|
||||
stdcall attach_int_handler, eax, IDE_common_irq_handler, ecx
|
||||
pop ecx
|
||||
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [ecx+IDE_DATA.Interrupt]:1, eax
|
||||
;--------------------------------------
|
||||
|
@ -996,8 +996,6 @@ end if
|
||||
; mov esi, boot_devices
|
||||
; call boot_log
|
||||
|
||||
call clear_pci_ide_interrupts
|
||||
|
||||
include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||
|
||||
stdcall load_pe_driver, szVidintel, 0
|
||||
|
Loading…
Reference in New Issue
Block a user