From a64323c2965f181dbd7edeba7feb39e496c34b2a Mon Sep 17 00:00:00 2001 From: CleverMouse Date: Wed, 30 Dec 2015 15:48:01 +0000 Subject: [PATCH] always install IDE interrupt handler git-svn-id: svn://kolibrios.org@6015 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/hd_drv.inc | 103 +++++++++++++------------------ kernel/trunk/core/irq.inc | 2 + kernel/trunk/detect/init_ata.inc | 20 +++--- kernel/trunk/kernel.asm | 2 - 4 files changed, 56 insertions(+), 71 deletions(-) diff --git a/kernel/trunk/blkdev/hd_drv.inc b/kernel/trunk/blkdev/hd_drv.inc index e9e4d77449..a84dc437e3 100644 --- a/kernel/trunk/blkdev/hd_drv.inc +++ b/kernel/trunk/blkdev/hd_drv.inc @@ -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 diff --git a/kernel/trunk/core/irq.inc b/kernel/trunk/core/irq.inc index 7fe6a349d0..a70bccbc20 100644 --- a/kernel/trunk/core/irq.inc +++ b/kernel/trunk/core/irq.inc @@ -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: diff --git a/kernel/trunk/detect/init_ata.inc b/kernel/trunk/detect/init_ata.inc index 66e7e44cc5..4f98329ffa 100644 --- a/kernel/trunk/detect/init_ata.inc +++ b/kernel/trunk/detect/init_ata.inc @@ -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 ;-------------------------------------- diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 98d2e967bb..672849759d 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -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