From 3e0a804c4895c4dde87044458690aa70fad54188 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Sat, 25 Aug 2012 17:56:09 +0000 Subject: [PATCH] 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 --- kernel/branches/net/drivers/3c59x.asm | 25 +++++++--------- kernel/branches/net/drivers/R6040.asm | 30 ++++++++----------- kernel/branches/net/drivers/RTL8029.asm | 37 +++++++++++++++--------- kernel/branches/net/drivers/RTL8139.asm | 30 +++++++++---------- kernel/branches/net/drivers/RTL8169.asm | 13 ++++----- kernel/branches/net/drivers/bus/pci.inc | 13 +++++++-- kernel/branches/net/drivers/dec21x4x.asm | 19 ++++-------- kernel/branches/net/drivers/i8254x.asm | 28 +++++++++++------- kernel/branches/net/drivers/mtd80x.asm | 14 ++++----- kernel/branches/net/drivers/netdrv.inc | 1 + kernel/branches/net/drivers/pcnet32.asm | 23 ++++++++------- kernel/branches/net/drivers/sis900.asm | 15 ++++++++-- 12 files changed, 131 insertions(+), 117 deletions(-) diff --git a/kernel/branches/net/drivers/3c59x.asm b/kernel/branches/net/drivers/3c59x.asm index 63225eae24..668642fe19 100644 --- a/kernel/branches/net/drivers/3c59x.asm +++ b/kernel/branches/net/drivers/3c59x.asm @@ -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 diff --git a/kernel/branches/net/drivers/R6040.asm b/kernel/branches/net/drivers/R6040.asm index 11b68d45cf..997e81dce8 100644 --- a/kernel/branches/net/drivers/R6040.asm +++ b/kernel/branches/net/drivers/R6040.asm @@ -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 + out dx, ax ; send it back to ACK + 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 diff --git a/kernel/branches/net/drivers/RTL8029.asm b/kernel/branches/net/drivers/RTL8029.asm index c27fea0e5e..5f3a8b29d9 100644 --- a/kernel/branches/net/drivers/RTL8029.asm +++ b/kernel/branches/net/drivers/RTL8029.asm @@ -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 diff --git a/kernel/branches/net/drivers/RTL8139.asm b/kernel/branches/net/drivers/RTL8139.asm index da65e64e32..f1629aa8d3 100644 --- a/kernel/branches/net/drivers/RTL8139.asm +++ b/kernel/branches/net/drivers/RTL8139.asm @@ -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 diff --git a/kernel/branches/net/drivers/RTL8169.asm b/kernel/branches/net/drivers/RTL8169.asm index 381d0fbae3..06cf3fb2b7 100644 --- a/kernel/branches/net/drivers/RTL8169.asm +++ b/kernel/branches/net/drivers/RTL8169.asm @@ -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 diff --git a/kernel/branches/net/drivers/bus/pci.inc b/kernel/branches/net/drivers/bus/pci.inc index 16afcc3a7f..52e9d3fae8 100644 --- a/kernel/branches/net/drivers/bus/pci.inc +++ b/kernel/branches/net/drivers/bus/pci.inc @@ -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 diff --git a/kernel/branches/net/drivers/dec21x4x.asm b/kernel/branches/net/drivers/dec21x4x.asm index dfc81d2364..13053c5389 100644 --- a/kernel/branches/net/drivers/dec21x4x.asm +++ b/kernel/branches/net/drivers/dec21x4x.asm @@ -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? diff --git a/kernel/branches/net/drivers/i8254x.asm b/kernel/branches/net/drivers/i8254x.asm index b7cea609ed..c07edd148f 100644 --- a/kernel/branches/net/drivers/i8254x.asm +++ b/kernel/branches/net/drivers/i8254x.asm @@ -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? diff --git a/kernel/branches/net/drivers/mtd80x.asm b/kernel/branches/net/drivers/mtd80x.asm index 8a72e400bd..7b48b79b61 100644 --- a/kernel/branches/net/drivers/mtd80x.asm +++ b/kernel/branches/net/drivers/mtd80x.asm @@ -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 diff --git a/kernel/branches/net/drivers/netdrv.inc b/kernel/branches/net/drivers/netdrv.inc index 7f9352056e..3ff801de61 100644 --- a/kernel/branches/net/drivers/netdrv.inc +++ b/kernel/branches/net/drivers/netdrv.inc @@ -14,6 +14,7 @@ include 'bus/pci.inc' PAGESIZE = 4096 PG_SW = 0x003 + PG_NOCACHE = 0x018 ; network driver types diff --git a/kernel/branches/net/drivers/pcnet32.asm b/kernel/branches/net/drivers/pcnet32.asm index 52279a320f..dba10af21b 100644 --- a/kernel/branches/net/drivers/pcnet32.asm +++ b/kernel/branches/net/drivers/pcnet32.asm @@ -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 diff --git a/kernel/branches/net/drivers/sis900.asm b/kernel/branches/net/drivers/sis900.asm index fa92a7cb7d..9786b79acf 100644 --- a/kernel/branches/net/drivers/sis900.asm +++ b/kernel/branches/net/drivers/sis900.asm @@ -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_