Fixed bug in network drivers irq handler.

Updated netdrv.inc and pci.inc 

git-svn-id: svn://kolibrios.org@2935 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-08-25 17:56:09 +00:00
parent c575a498b5
commit 3e0a804c48
12 changed files with 131 additions and 117 deletions

View File

@ -2658,39 +2658,34 @@ int_vortex:
align 4 align 4
int_boomerang: int_boomerang:
DEBUGF 1,"\nIRQ %x Boomerang\n",eax:2 DEBUGF 1,"\nBoomerang int\n"
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
mov esi, BOOMERANG_LIST
mov ecx, [BOOMERANG_DEVICES] mov ecx, [BOOMERANG_DEVICES]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
mov esi, BOOMERANG_LIST
.nextdevice: .nextdevice:
mov ebx, dword[esi] mov ebx, [esi]
set_io 0 set_io 0
set_io REG_INT_STATUS set_io REG_INT_STATUS
in ax, dx in ax, dx
test ax, IntLatch test ax, ax
jnz .got_it jnz .got_it
.continue:
add esi, 4 add esi, 4
test ax , ax
jnz .got_it
dec ecx dec ecx
jnz .nextdevice jnz .nextdevice
.nothing:
.fail:
DEBUGF 1,"Failed!\n"
ret ret
.got_it: .got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, eax DEBUGF 1,"Device: %x Status: %x ", ebx, ax
push ax push ax
; disable all INTS ; disable all INTS
set_io REG_COMMAND set_io REG_COMMAND

View File

@ -831,46 +831,40 @@ transmit:
;; Interrupt handler ;; ;; Interrupt handler ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
align 4 align 4
int_handler: int_handler:
DEBUGF 2,"\nIRQ %x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO DEBUGF 1,"\n%s int\n", my_service
; Find pointer of device wich made IRQ occur ; Find pointer of device wich made IRQ occur
mov esi, device_list
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, dword [esi] mov ebx, [esi]
; Find reason for IRQ
set_io 0 set_io 0
set_io MISR set_io MISR
in ax, dx in ax, dx
out dx, ax ; send it back to ACK out dx, ax ; send it back to ACK
test ax, ax
DEBUGF 2,"MISR=%x\n", eax:4
; Check if we are interessed in some of the reasons
test ax, INT_MASK
jnz .got_it jnz .got_it
.continue:
; If not, try next device
add esi, 4 add esi, 4
dec ecx dec ecx
jnz .nextdevice jnz .nextdevice
.nothing: ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.fail: ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
ret ret
; At this point, test for all possible reasons, and handle accordingly ; At this point, test for all possible reasons, and handle accordingly
.got_it: .got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, ax
push ax push ax
test word [esp], RX_FINISH test word [esp], RX_FINISH

View File

@ -735,34 +735,42 @@ transmit:
; Interrupt handler ; Interrupt handler
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4 align 4
int_handler: int_handler:
DEBUGF 2,"IRQ %x ",eax:2 DEBUGF 1,"\n%s int\n", my_service
; find pointer of device wich made INT occur ; find pointer of device wich made INT occur
mov esi, device_list
mov ecx, [devices] mov ecx, [devices]
.nextdevice: test ecx, ecx
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, [esi] mov ebx, [esi]
set_io 0 set_io 0
set_io P0_ISR set_io P0_ISR
in al, dx in al, dx
test al, al
DEBUGF 2,"isr %x ",eax:2 jnz .got_it
.continue:
test al, ISR_PRX ; packet received ok ?
jnz .rx
add esi, 4 add esi, 4
dec ecx
loop .nextdevice jnz .nextdevice
.nothing:
ret ret
.got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, eax:2
test al, ISR_PRX ; packet received ok ?
jz .no_rx
; looks like we've found a device wich received a packet.. ; looks like we've found a device wich received a packet..
.rx:
stdcall KernelAlloc, ETH_FRAME_LEN ; size doesnt really matter as packet size is smaller then kernel's page size stdcall KernelAlloc, ETH_FRAME_LEN ; size doesnt really matter as packet size is smaller then kernel's page size
test eax, eax test eax, eax
jz .fail_2 jz .fail_2
@ -937,7 +945,10 @@ int_handler:
add esp, 14+8 add esp, 14+8
.fail_2: .fail_2:
DEBUGF 2,"done\n" DEBUGF 2,"done\n"
ret
.no_rx:
ret

View File

@ -739,43 +739,41 @@ transmit:
;; Interrupt handler ;; ;; Interrupt handler ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
align 4 align 4
int_handler: int_handler:
DEBUGF 1,"\nIRQ %x\n", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO DEBUGF 1,"\n%s int\n", my_service
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
mov esi, device_list
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
.nextdevice: mov esi, device_list
mov ebx, dword [esi] .nextdevice:
mov ebx, [esi]
set_io 0 set_io 0
set_io REG_ISR set_io REG_ISR
in ax , dx in ax, dx
out dx , ax ; send it back to ACK out dx, ax ; send it back to ACK
test ax, ax
add esi, 4
test ax , ax
jnz .got_it jnz .got_it
.continue:
add esi, 4
dec ecx dec ecx
jnz .nextdevice jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it: .got_it:
; looks like we've found it! DEBUGF 1,"Device: %x Status: %x ", ebx, ax
; Lets found out why the irq occured then..
;---------------------------------------------------- ;----------------------------------------------------
; Received packet ok? ; Received packet ok?
test ax, ISR_ROK test ax, ISR_ROK
jz @f jz @f
push ax push ax

View File

@ -1113,33 +1113,32 @@ transmit:
align 4 align 4
int_handler: int_handler:
DEBUGF 1,"IRQ %x ",eax:2 DEBUGF 1,"\n%s int\n", my_service
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
mov esi, device_list mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, dword [esi] mov ebx, [esi]
set_io 0 set_io 0
set_io REG_IntrStatus set_io REG_IntrStatus
in ax, dx in ax, dx
test ax, ax test ax, ax
jnz .got_it jnz .got_it
.continue: .continue:
add esi, 4 add esi, 4
dec ecx dec ecx
jnz .nextdevice jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it: .got_it:
DEBUGF 1,"IntrStatus = 0x%x\n",ax
DEBUGF 1,"Device: %x Status: %x ", ebx, ax
cmp ax, 0xFFFF ; if so, hardware is no longer present cmp ax, 0xFFFF ; if so, hardware is no longer present
je .fail je .fail

View File

@ -13,17 +13,25 @@
PCI_HEADER_TYPE = 0x0e ; 8 bit PCI_HEADER_TYPE = 0x0e ; 8 bit
PCI_BASE_ADDRESS_0 = 0x10 ; 32 bit PCI_BASE_ADDRESS_0 = 0x10 ; 32 bit
PCI_BASE_ADDRESS_1 = 0x14 ; 32 bits
PCI_BASE_ADDRESS_2 = 0x18 ; 32 bits
PCI_BASE_ADDRESS_3 = 0x1c ; 32 bits
PCI_BASE_ADDRESS_4 = 0x20 ; 32 bits
PCI_BASE_ADDRESS_5 = 0x24 ; 32 bits PCI_BASE_ADDRESS_5 = 0x24 ; 32 bits
PCI_BASE_ADDRESS_SPACE_IO = 0x01 PCI_BASE_ADDRESS_SPACE_IO = 0x01
PCI_VENDOR_ID = 0x00 ; 16 bit
PCI_BASE_ADDRESS_IO_MASK = 0xFFFFFFFC PCI_BASE_ADDRESS_IO_MASK = 0xFFFFFFFC
PCI_BASE_ADDRESS_MEM_MASK = 0xFFFFFFF0
; PCI programming ; PCI programming
PCI_VENDOR_ID = 0x00 ; 16 bit
PCI_DEVICE_ID = 0x02 ; 16 bits
PCI_REG_COMMAND = 0x4 ; command register PCI_REG_COMMAND = 0x4 ; command register
PCI_REG_STATUS = 0x6 ; status register PCI_REG_STATUS = 0x6 ; status register
PCI_REVISION_ID = 0x08 ; 8 bits
PCI_REG_LATENCY = 0xd ; latency timer register PCI_REG_LATENCY = 0xd ; latency timer register
PCI_REG_CAP_PTR = 0x34 ; capabilities pointer PCI_REG_CAP_PTR = 0x34 ; capabilities pointer
PCI_REG_IRQ = 0x3c
PCI_REG_CAPABILITY_ID = 0x0 ; capapility ID in pm register block PCI_REG_CAPABILITY_ID = 0x0 ; capapility ID in pm register block
PCI_REG_PM_STATUS = 0x4 ; power management status register PCI_REG_PM_STATUS = 0x4 ; power management status register
PCI_REG_PM_CTRL = 0x4 ; power management control register PCI_REG_PM_CTRL = 0x4 ; power management control register
@ -90,7 +98,6 @@ macro find_mmio32 bus, dev, io {
.got: .got:
mov io, eax mov io, eax
} }
macro find_irq bus, dev, irq { macro find_irq bus, dev, irq {
@ -98,7 +105,7 @@ macro find_irq bus, dev, irq {
push eax edx ecx push eax edx ecx
movzx ecx, bus movzx ecx, bus
movzx edx, dev movzx edx, dev
stdcall PciRead8, ecx ,edx ,0x3c ; 0x3c is the offset where irq can be found stdcall PciRead8, ecx, edx, PCI_REG_IRQ
mov irq, al mov irq, al
pop ecx edx eax pop ecx edx eax

View File

@ -1012,40 +1012,33 @@ transmit:
align 4 align 4
int_handler: int_handler:
DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO DEBUGF 1,"\n%s int\n", my_service
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
mov esi, device_list mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, dword [esi] mov ebx, [esi]
set_io 0 set_io 0
set_io CSR5 set_io CSR5
in eax, dx in eax, dx
out dx , eax ; send it back to ACK out dx, eax ; send it back to ACK
and eax, CSR7_DEFAULT ; int mask
test eax, eax test eax, eax
jnz .got_it jnz .got_it
.continue: .continue:
add esi, 4 add esi, 4
dec ecx dec ecx
jnz .nextdevice jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it: .got_it:
DEBUGF 1,"CSR7: %x ", eax DEBUGF 1,"Device: %x CSR5: %x ", ebx, ax
; looks like we've found it!
; Lets found out why the irq occured then..
;---------------------------------- ;----------------------------------
; TX ok? ; TX ok?

View File

@ -682,29 +682,35 @@ transmit:
;; Interrupt handler ;; ;; Interrupt handler ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
align 4 align 4
int_handler: int_handler:
DEBUGF 2,"\nIRQ %x\n", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
DEBUGF 1,"\n%s int\n", my_service
;------------------------------------------- ;-------------------------------------------
; Find pointer of device wich made IRQ occur ; Find pointer of device wich made IRQ occur
mov esi, device_list
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, dword [esi] mov ebx, [esi]
mov edi, [device.mmio_addr] mov edi, [device.mmio_addr]
test edi, edi
jz .nextdevice
;--------------------
; Get interrupt cause
mov eax, [edi + REG_ICR] mov eax, [edi + REG_ICR]
DEBUGF 2,"interrupt cause=%x\n", eax test eax, eax
jnz .got_it
.continue:
add esi, 4
dec ecx
jnz .nextdevice
.nothing:
ret
.got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, eax
;--------- ;---------
; RX done? ; RX done?

View File

@ -1099,35 +1099,33 @@ write_mac:
align 4 align 4
int_handler: int_handler:
DEBUGF 1,"\nIRQ %x\n",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO DEBUGF 1,"\n%s int\n", my_service
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .fail jz .nothing
mov esi, device_list mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, dword [esi] mov ebx, [esi]
set_io 0 set_io 0
set_io ISR set_io ISR
in eax, dx in eax, dx
out dx , eax ; send it back to ACK out dx, eax ; send it back to ACK
; and eax, ; int mask
test eax, eax test eax, eax
jnz .got_it jnz .got_it
.continue: .continue:
add esi, 4 add esi, 4
dec ecx dec ecx
jnz .nextdevice jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it: .got_it:
DEBUGF 1,"Status=%x\n", eax DEBUGF 1,"Device: %x Status: %x ", ebx, ax
test ax, RI ; receive interrupt test ax, RI ; receive interrupt
jz .no_rx jz .no_rx

View File

@ -14,6 +14,7 @@ include 'bus/pci.inc'
PAGESIZE = 4096 PAGESIZE = 4096
PG_SW = 0x003 PG_SW = 0x003
PG_NOCACHE = 0x018
; network driver types ; network driver types

View File

@ -1025,32 +1025,35 @@ transmit:
align 4 align 4
int_handler: int_handler:
; DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO DEBUGF 1,"\n%s int\n", my_service
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
mov esi, device_list
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .abort jz .nothing
mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, dword [esi] mov ebx, [esi]
mov edx, [device.io_addr] ; get IRQ reason
mov edx, [device.io_addr] ; get IRQ reason
push ecx push ecx
xor ecx, ecx ; CSR0 xor ecx, ecx ; CSR0
call [device.access_read_csr] call [device.access_read_csr]
pop ecx pop ecx
test al, al
test al , al
js .got_it js .got_it
.continue:
add esi, 4 add esi, 4
loop .nextdevice dec ecx
jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver
.got_it: .got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, eax:2
;------------------------------------------------------- ;-------------------------------------------------------
; Possible reasons: ; Possible reasons:
; initialization done - ignore ; initialization done - ignore

View File

@ -1042,27 +1042,36 @@ transmit:
; between multiple descriptors you will lose part of the packet ; between multiple descriptors you will lose part of the packet
; ;
;*************************************************************************** ;***************************************************************************
align 4 align 4
int_handler: int_handler:
DEBUGF 1,"\n%s int\n", my_service
; find pointer of device which made IRQ occur ; find pointer of device which made IRQ occur
mov esi, device_list
mov ecx, [devices] mov ecx, [devices]
test ecx, ecx test ecx, ecx
jz .nothing jz .nothing
mov esi, device_list
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
set_io 0 set_io 0
set_io isr set_io isr
in eax, dx ; note that this clears all interrupts in eax, dx ; note that this clears all interrupts
test ax, IE test ax, IE
jnz .got_it jnz .got_it
loop .nextdevice .continue:
add esi, 4
dec ecx
jnz .nextdevice
.nothing: .nothing:
ret ret
.got_it: .got_it:
DEBUGF 1,"IRQ! status=%x\n", ax DEBUGF 1,"Device: %x Status: %x ", ebx, ax
test ax, RxOK test ax, RxOK
jz .no_rx_ jz .no_rx_