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

View File

@ -831,46 +831,40 @@ transmit:
;; Interrupt handler ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;
align 4
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
mov esi, device_list
mov ecx, [devices]
test ecx, ecx
jz .fail
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, dword [esi]
; Find reason for IRQ
mov ebx, [esi]
set_io 0
set_io MISR
in ax, dx
out dx, ax ; send it back to ACK
DEBUGF 2,"MISR=%x\n", eax:4
; Check if we are interessed in some of the reasons
test ax, INT_MASK
test ax, ax
jnz .got_it
; If not, try next device
.continue:
add esi, 4
dec ecx
jnz .nextdevice
.fail: ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.nothing: ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
ret
; At this point, test for all possible reasons, and handle accordingly
.got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, ax
push ax
test word [esp], RX_FINISH

View File

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

View File

@ -739,43 +739,41 @@ transmit:
;; Interrupt handler ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;
align 4
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
mov esi, device_list
mov ecx, [devices]
test ecx, ecx
jz .fail
.nextdevice:
mov ebx, dword [esi]
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, [esi]
set_io 0
set_io REG_ISR
in ax , dx
out dx , ax ; send it back to ACK
add esi, 4
test ax , ax
in ax, dx
out dx, ax ; send it back to ACK
test ax, ax
jnz .got_it
.continue:
add esi, 4
dec ecx
jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it:
; looks like we've found it!
; Lets found out why the irq occured then..
DEBUGF 1,"Device: %x Status: %x ", ebx, ax
;----------------------------------------------------
; Received packet ok?
test ax, ISR_ROK
jz @f
push ax

View File

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

View File

@ -13,17 +13,25 @@
PCI_HEADER_TYPE = 0x0e ; 8 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_SPACE_IO = 0x01
PCI_VENDOR_ID = 0x00 ; 16 bit
PCI_BASE_ADDRESS_IO_MASK = 0xFFFFFFFC
PCI_BASE_ADDRESS_MEM_MASK = 0xFFFFFFF0
; PCI programming
PCI_VENDOR_ID = 0x00 ; 16 bit
PCI_DEVICE_ID = 0x02 ; 16 bits
PCI_REG_COMMAND = 0x4 ; command register
PCI_REG_STATUS = 0x6 ; status register
PCI_REVISION_ID = 0x08 ; 8 bits
PCI_REG_LATENCY = 0xd ; latency timer register
PCI_REG_CAP_PTR = 0x34 ; capabilities pointer
PCI_REG_IRQ = 0x3c
PCI_REG_CAPABILITY_ID = 0x0 ; capapility ID in pm register block
PCI_REG_PM_STATUS = 0x4 ; power management status register
PCI_REG_PM_CTRL = 0x4 ; power management control register
@ -90,7 +98,6 @@ macro find_mmio32 bus, dev, io {
.got:
mov io, eax
}
macro find_irq bus, dev, irq {
@ -98,7 +105,7 @@ macro find_irq bus, dev, irq {
push eax edx ecx
movzx ecx, bus
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
pop ecx edx eax

View File

@ -1012,40 +1012,33 @@ transmit:
align 4
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
mov ecx, [devices]
test ecx, ecx
jz .fail
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, dword [esi]
mov ebx, [esi]
set_io 0
set_io CSR5
in eax, dx
out dx , eax ; send it back to ACK
and eax, CSR7_DEFAULT ; int mask
out dx, eax ; send it back to ACK
test eax, eax
jnz .got_it
.continue:
add esi, 4
dec ecx
jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it:
DEBUGF 1,"CSR7: %x ", eax
; looks like we've found it!
; Lets found out why the irq occured then..
DEBUGF 1,"Device: %x CSR5: %x ", ebx, ax
;----------------------------------
; TX ok?

View File

@ -682,29 +682,35 @@ transmit:
;; Interrupt handler ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;
align 4
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
mov esi, device_list
mov ecx, [devices]
test ecx, ecx
jz .fail
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, dword [esi]
mov ebx, [esi]
mov edi, [device.mmio_addr]
test edi, edi
jz .nextdevice
;--------------------
; Get interrupt cause
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?

View File

@ -1099,35 +1099,33 @@ write_mac:
align 4
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
mov ecx, [devices]
test ecx, ecx
jz .fail
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, dword [esi]
mov ebx, [esi]
set_io 0
set_io ISR
in eax, dx
out dx , eax ; send it back to ACK
; and eax, ; int mask
out dx, eax ; send it back to ACK
test eax, eax
jnz .got_it
.continue:
add esi, 4
dec ecx
jnz .nextdevice
.nothing:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it:
DEBUGF 1,"Status=%x\n", eax
DEBUGF 1,"Device: %x Status: %x ", ebx, ax
test ax, RI ; receive interrupt
jz .no_rx

View File

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

View File

@ -1025,32 +1025,35 @@ transmit:
align 4
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
mov esi, device_list
mov ecx, [devices]
test ecx, ecx
jz .abort
jz .nothing
mov esi, device_list
.nextdevice:
mov ebx, dword [esi]
mov edx, [device.io_addr] ; get IRQ reason
mov ebx, [esi]
mov edx, [device.io_addr] ; get IRQ reason
push ecx
xor ecx, ecx ; CSR0
call [device.access_read_csr]
pop ecx
test al , al
test al, al
js .got_it
.continue:
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
.got_it:
DEBUGF 1,"Device: %x Status: %x ", ebx, eax:2
;-------------------------------------------------------
; Possible reasons:
; initialization done - ignore

View File

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