Patching you is a dirty job, but somebody's gotta do it... - I mean why some function is not detected by NBI?

(The Answers for the real curious ones...)


Short answer:
NBI code was incorrect as it queried not the base device's address to check if there is any more function besides the 00 one, but queried the device address+function address, so they won't always return what they should [80].

How does it look like in hex?
NetWare 4.x:
The unpacked and 1F enabled NBI.NLM (Version 2.27u)

NBI.NLM|PCIBuildClassCodeTable

 00008F74: 53                  push      ebx
 00008F75: 56                  push      esi
 00008F76: 57                  push      edi
 00008F77: 55                  push      ebp
 00008F78: 83EC20              sub       esp,020 ;" "
 00008F7B: BBE4000000          mov       ebx,0000000E4			;NBI.NLM|pciInfoTable (buffer)
 00008F80: C744240400000000    mov       d,[esp][00004],000000000	;bus ID [0-FF]
 00008F88: C744240800000000    mov       d,[esp][00008],000000000

scanbuses:
 00008F90: 8B442408            mov       eax,[esp][00008]
 00008F94: 0D00000080          or        eax,080000000
 00008F99: C744241400000000    mov       d,[esp][00014],000000000	;devices [0-1F]
 00008FA1: 8944240C            mov       [esp][0000C],eax
 00008FA5: 8A442414            mov       al,[esp][00014]		;devices [0-1F]
 00008FA9: C0E003              shl       al,003
 00008FAC: C7042400000000      mov       d,[esp],000000000
 00008FB3: 88442418            mov       [esp][00018],al		;device number <<3 for "OUT"

scandevices:
 00008FB7: C744241000000000    mov       d,[esp][00010],000000000	;function [0-7]
 00008FBF: 8A442418            mov       al,[esp][00018]
 00008FC3: 8B2C24              mov       ebp,[esp]
 00008FC6: 31FF                xor       edi,edi
 00008FC8: 8844241C            mov       [esp][0001C],al

scanfunction:
 00008FCC: 8B74240C            mov       esi,[esp][0000C]		;80000000 + BUS
 00008FD0: 09EE                or        esi,ebp			;+  device base address
 00008FD2: 09FE                or        esi,edi			;+function base address
 00008FD4: 56                  push      esi
 00008FD5: 68F80C0000          push      000000CF8
 00008FDA: 6A00                push      000
 00008FDC: E8AC94FFFF          call      00000248D			;NBI.NLM|Out32
 00008FE1: 83C40C              add       esp,00C
 00008FE4: 68FC0C0000          push      000000CFC
 00008FE9: 6A00                push      000
 00008FEB: E82393FFFF          call      000002313			;NBI.NLM|In32
 00008FF0: 25FFFF0000          and       eax,00000FFFF
 00008FF5: 83C408              add       esp,008
 00008FF8: 3DFFFF0000          cmp       eax,00000FFFF			;if no device found then jump to:
 00008FFD: 745B                je        00000905A			;------------------------> nextdevice

[foundsomething]
 00008FFF: 8A442404            mov       al,[esp][00004]
 00009003: 8803                mov       [ebx],al
 00009005: 8A442410            mov       al,[esp][00010]		;function [0-7]
 00009009: 2403                and       al,003
 0000900B: 83C303              add       ebx,003
 0000900E: 8A64241C            mov       ah,[esp][0001C]
 00009012: C643FFFF            mov       b,[ebx][-0001],0FF ;" "
 00009016: 08C4                or        ah,al
 00009018: 8863FE              mov       [ebx][-0002],ah
 0000901B: FE05F5030000        inc       b,[0000003F5]			; NumberOfPCISlotsForThisBus
 00009021: 0F848A000000        je        0000090B1			;-------------------------> error
 00009027: 81FBE4030000        cmp       ebx,0000003E4
 0000902D: 0F837E000000        jae       0000090B1			;-------------------------> error (out of pciInfoTable space)
 00009033: 6683CE0C            or        si,00C
 00009037: 56                  push      esi
 00009038: 68F80C0000          push      000000CF8
 0000903D: 6A00                push      000
 0000903F: E84994FFFF          call      00000248D			;NBI.NLM|Out32
 00009044: 83C40C              add       esp,00C
 00009047: 68FE0C0000          push      000000CFE
 0000904C: 6A00                push      000
 0000904E: E8AF92FFFF          call      000002302			;NBI.NLM|In8
 00009053: 83C408              add       esp,008
 00009056: A880                test      al,080 ;"Ç"
 00009058: 753C                jne       000009096  			; ------------------------> nextfunction

nextdevice:
 0000905A: 81042400080000      add       d,[esp],000000800
 00009061: FF442414            inc       d,[esp][00014]			;devices [0-1F]
 00009065: 8044241808          add       b,[esp][00018],008
 0000906A: 837C24141F          cmp       d,[esp][00014],01F		;max devices [1F]
 0000906F: 0F8642FFFFFF        jbe       000008FB7			;-------------------------^ scandevices
 -
 00009075: FF442404            inc       d,[esp][00004]			;bus ID [0-FF]
 00009079: 66FF44240A          inc       w,[esp][0000A]
 0000907E: 817C2404FF000000    cmp       d,[esp][00004],0000000FF	;bus ID [0-FF]
 00009086: 0F8604FFFFFF        jbe       000008F90			;-------------------------^ scanbuses
 -
 0000908C: 31C0                xor       eax,eax
 0000908E: 83C420              add       esp,020 ;" "
 00009091: 5D                  pop       ebp
 00009092: 5F                  pop       edi
 00009093: 5E                  pop       esi
 00009094: 5B                  pop       ebx
 00009095: C3                  retn

nextfunction:
 00009096: 3CFF                cmp       al,0FF ;" "			;if result=FF, then
 00009098: 74C0                je        00000905A			;-------------------------^ nextdevice
 0000909A: FF442410            inc       d,[esp][00010]			;function [0-7]
 0000909E: 81C700010000        add       edi,000000100
 000090A4: 837C241007          cmp       d,[esp][00010],007		;function ID is below 8?
 000090A9: 0F861DFFFFFF        jbe       000008FCC			;-------------------------^ scanfunction
 000090AF: EBA9                jmps      00000905A			;-------------------------^ nextdevice

error:
 000090B1: B801000000          mov       eax,000000001
 000090B6: 83C420              add       esp,020 ;" "
 000090B9: 5D                  pop       ebp
 000090BA: 5F                  pop       edi
 000090BB: 5E                  pop       esi
 000090BC: 5B                  pop       ebx
 000090BD: C3                  retn


External routines:
------------------
Out32:     8B542408            mov       edx,[esp][00008]
           8B44240C            mov       eax,[esp][0000C]
           EF                  out       dx,eax
           C3                  retn

In32:      33C0                xor       eax,eax
           8B542408            mov       edx,[esp][00008]
           ED                  in        eax,dx
           C3                  retn

In8:       33C0                xor       eax,eax
           8B542408            mov       edx,[esp][00008]
           EC                  in        al,dx
           C3                  retn

To let NBI do its job properly, we need to change the following things here:
 00008FF0: 25FFFF0000          and       eax,00000FFFF
 00008FF5: 83C408              add       esp,008
 00008FF8: 3DFFFF0000          cmp       eax,00000FFFF		;if no device found then jump to:
 00008FFD: 745B                je        00000905A		;------------------------> nextdevice

[foundsomething]
 00008FFF: 8A442404            mov       al,[esp][00004]
 00009003: 8803                mov       [ebx],al
 00009005: 8A442410            mov       al,[esp][00010]	;function [0-7]
 00009009: 2403                and       al,003
to:
 00008FF0: 668BF5              mov       si,bp			;we don't need and eax, because...
 00008FF3: 90                  nop
 00008FF4: 90                  nop
 00008FF5: 83C408              add       esp,008
 00008FF8: 663DFFFF            cmp       ax,FFFF		;...we compare lower eax only, full eax resets in next Out32 routines
 00008FFC: 90                  nop
 00008FFD: 745B                je        00000905A

[foundsomething]
 00008FFF: 8A442404            mov       al,[esp][00004]
 00009003: 8803                mov       [ebx],al
 00009005: 8A442410            mov       al,[esp][00010]
 00009009: 2407                and       al,007			;this should be 3 bits, not "3" (that is 7 decimal), but actually,
								;since check is done at 90A4 (cmp d,[esp+10],007), this
								;couldn't be more anyway, so we could as well "NOP" it...
								;Remember next time we want to insert some more patches... :-]

So we need to patch NBI as follows:

POKE.EXE NBI.NLM 36848 668bf59090
(36848: 25FFFF0000 to 668bf59090)
+
POKE.EXE NBI.NLM 36865 663dffff90
(36856: 3DFFFF0000 to 663dffff90)
+
POKE.EXE NBI.NLM 36874 07
(36874: 03 to 07)

And don't forget to patch to allow scanning device 1F too:
POKE.EXE NBI.NLM 36974 1F
(36974: 1E to 1F)

For the lazy ones, patched NBI's are included - for both 3.1x and 4.x - in the ideata.zip package.



BACK to NWUDMA main page