Subversion Repositories Kolibri OS

Rev

Rev 2935 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1886 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  R6040 driver for KolibriOS                                     ;;
7
;;                                                                 ;;
8
;;  based on R6040.c from linux                                    ;;
9
;;                                                                 ;;
10
;;    Written by Asper (asper.85@mail.ru)                          ;;
11
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
18
format MS COFF
19
 
2852 hidnplayr 20
        API_VERSION             =   0x01000100
21
        DRIVER_VERSION          =   5
1886 hidnplayr 22
 
2852 hidnplayr 23
        MAX_DEVICES             =   16
1886 hidnplayr 24
 
2852 hidnplayr 25
        DEBUG                   =   1
26
        __DEBUG__               =   1
27
        __DEBUG_LEVEL__         =   2
1886 hidnplayr 28
 
2852 hidnplayr 29
        W_MAX_TIMEOUT           =   0x0FFF      ; max time out delay time
1893 hidnplayr 30
 
2852 hidnplayr 31
        TX_TIMEOUT              =   6000        ; Time before concluding the transmitter is hung, in ms
1893 hidnplayr 32
 
2852 hidnplayr 33
        TX_RING_SIZE            =   4           ; RING sizes must be a power of 2
34
        RX_RING_SIZE            =   4
1886 hidnplayr 35
 
2852 hidnplayr 36
        RX_BUF_LEN_IDX          =   3           ; 0==8K, 1==16K, 2==32K, 3==64K
1886 hidnplayr 37
 
1893 hidnplayr 38
; Threshold is bytes transferred to chip before transmission starts.
39
 
2852 hidnplayr 40
        TX_FIFO_THRESH          =   256         ; In bytes, rounded down to 32 byte units.
1893 hidnplayr 41
 
42
; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
43
 
2852 hidnplayr 44
        RX_FIFO_THRESH          =   4           ; Rx buffer level before first PCI xfer.
45
        RX_DMA_BURST            =   4           ; Maximum PCI burst, '4' is 256 bytes
46
        TX_DMA_BURST            =   4
1893 hidnplayr 47
 
48
 
49
 
1886 hidnplayr 50
include 'proc32.inc'
51
include 'imports.inc'
52
include 'fdo.inc'
53
include 'netdrv.inc'
54
 
55
public START
56
public service_proc
57
public version
58
 
1893 hidnplayr 59
; Operational parameters that usually are not changed.
1886 hidnplayr 60
 
2852 hidnplayr 61
PHY1_ADDR       =   1       ;For MAC1
62
PHY2_ADDR       =   3       ;For MAC2
63
PHY_MODE        =   0x3100  ;PHY CHIP Register 0
64
PHY_CAP         =   0x01E1  ;PHY CHIP Register 4
1886 hidnplayr 65
 
66
;**************************************************************************
67
; RDC R6040 Register Definitions
68
;**************************************************************************
2852 hidnplayr 69
MCR0            =   0x00    ;Control register 0
70
MCR1            =   0x01    ;Control register 1
71
MAC_RST         =   0x0001  ;Reset the MAC
72
MBCR            =   0x08    ;Bus control
73
MT_ICR          =   0x0C    ;TX interrupt control
74
MR_ICR          =   0x10    ;RX interrupt control
75
MTPR            =   0x14    ;TX poll command register
76
MR_BSR          =   0x18    ;RX buffer size
77
MR_DCR          =   0x1A    ;RX descriptor control
78
MLSR            =   0x1C    ;Last status
79
MMDIO           =   0x20    ;MDIO control register
80
MDIO_WRITE      =   0x4000  ;MDIO write
81
MDIO_READ       =   0x2000  ;MDIO read
82
MMRD            =   0x24    ;MDIO read data register
83
MMWD            =   0x28    ;MDIO write data register
84
MTD_SA0         =   0x2C    ;TX descriptor start address 0
85
MTD_SA1         =   0x30    ;TX descriptor start address 1
86
MRD_SA0         =   0x34    ;RX descriptor start address 0
87
MRD_SA1         =   0x38    ;RX descriptor start address 1
88
MISR            =   0x3C    ;Status register
89
MIER            =   0x40    ;INT enable register
90
MSK_INT         =   0x0000  ;Mask off interrupts
91
RX_FINISH       =   0x0001  ;RX finished
92
RX_NO_DESC      =   0x0002  ;No RX descriptor available
93
RX_FIFO_FULL    =   0x0004  ;RX FIFO full
94
RX_EARLY        =   0x0008  ;RX early
95
TX_FINISH       =   0x0010  ;TX finished
96
TX_EARLY        =   0x0080  ;TX early
97
EVENT_OVRFL     =   0x0100  ;Event counter overflow
98
LINK_CHANGED    =   0x0200  ;PHY link changed
99
ME_CISR         =   0x44    ;Event counter INT status
100
ME_CIER         =   0x48    ;Event counter INT enable
101
MR_CNT          =   0x50    ;Successfully received packet counter
102
ME_CNT0         =   0x52    ;Event counter 0
103
ME_CNT1         =   0x54    ;Event counter 1
104
ME_CNT2         =   0x56    ;Event counter 2
105
ME_CNT3         =   0x58    ;Event counter 3
106
MT_CNT          =   0x5A    ;Successfully transmit packet counter
107
ME_CNT4         =   0x5C    ;Event counter 4
108
MP_CNT          =   0x5E    ;Pause frame counter register
109
MAR0            =   0x60    ;Hash table 0
110
MAR1            =   0x62    ;Hash table 1
111
MAR2            =   0x64    ;Hash table 2
112
MAR3            =   0x66    ;Hash table 3
113
MID_0L          =   0x68    ;Multicast address MID0 Low
114
MID_0M          =   0x6A    ;Multicast address MID0 Medium
115
MID_0H          =   0x6C    ;Multicast address MID0 High
116
MID_1L          =   0x70    ;MID1 Low
117
MID_1M          =   0x72    ;MID1 Medium
118
MID_1H          =   0x74    ;MID1 High
119
MID_2L          =   0x78    ;MID2 Low
120
MID_2M          =   0x7A    ;MID2 Medium
121
MID_2H          =   0x7C    ;MID2 High
122
MID_3L          =   0x80    ;MID3 Low
123
MID_3M          =   0x82    ;MID3 Medium
124
MID_3H          =   0x84    ;MID3 High
125
PHY_CC          =   0x88    ;PHY status change configuration register
126
PHY_ST          =   0x8A    ;PHY status register
127
MAC_SM          =   0xAC    ;MAC status machine
128
MAC_ID          =   0xBE    ;Identifier register
1893 hidnplayr 129
 
2852 hidnplayr 130
MAX_BUF_SIZE    =   0x600   ;1536
1886 hidnplayr 131
 
2852 hidnplayr 132
MBCR_DEFAULT    =   0x012A  ;MAC Bus Control Register
133
MCAST_MAX       =   3       ;Max number multicast addresses to filter
1886 hidnplayr 134
 
135
;Descriptor status
2852 hidnplayr 136
DSC_OWNER_MAC   =   0x8000  ;MAC is the owner of this descriptor
137
DSC_RX_OK       =   0x4000  ;RX was successfull
138
DSC_RX_ERR      =   0x0800  ;RX PHY error
139
DSC_RX_ERR_DRI  =   0x0400  ;RX dribble packet
140
DSC_RX_ERR_BUF  =   0x0200  ;RX length exceeds buffer size
141
DSC_RX_ERR_LONG =   0x0100  ;RX length > maximum packet length
142
DSC_RX_ERR_RUNT =   0x0080  ;RX packet length < 64 byte
143
DSC_RX_ERR_CRC  =   0x0040  ;RX CRC error
144
DSC_RX_BCAST    =   0x0020  ;RX broadcast (no error)
145
DSC_RX_MCAST    =   0x0010  ;RX multicast (no error)
146
DSC_RX_MCH_HIT  =   0x0008  ;RX multicast hit in hash table (no error)
147
DSC_RX_MIDH_HIT =   0x0004  ;RX MID table hit (no error)
148
DSC_RX_IDX_MID_MASK  =   3  ;RX mask for the index of matched MIDx
1886 hidnplayr 149
 
150
;PHY settings
2852 hidnplayr 151
ICPLUS_PHY_ID   =   0x0243
1886 hidnplayr 152
 
2852 hidnplayr 153
RX_INTS         =   RX_FIFO_FULL or RX_NO_DESC or RX_FINISH
154
TX_INTS         =   TX_FINISH
155
INT_MASK        =   RX_INTS or TX_INTS
1886 hidnplayr 156
 
2852 hidnplayr 157
RX_BUF_LEN      equ (8192 << RX_BUF_LEN_IDX)    ; Size of the in-memory receive ring.
1886 hidnplayr 158
 
2852 hidnplayr 159
IO_SIZE         =   256     ; RDC MAC I/O Size
160
MAX_MAC         =   2       ; MAX RDC MAC
1893 hidnplayr 161
 
162
 
1886 hidnplayr 163
virtual at 0
164
x_head:
2852 hidnplayr 165
  .status         dw ?   ;0-1
166
  .len            dw ?   ;2-3
167
  .buf            dd ?   ;4-7
168
  .ndesc          dd ?   ;8-B
169
  .rev1           dd ?   ;C-F
170
  .vbufp          dd ?   ;10-13
171
  .vndescp        dd ?   ;14-17
172
  .skb_ptr        dd ?   ;18-1B
173
  .rev2           dd ?   ;1C-1F
1886 hidnplayr 174
  .sizeof:
175
end virtual
176
 
177
 
178
virtual at ebx
179
 
2852 hidnplayr 180
        device:
1886 hidnplayr 181
 
2852 hidnplayr 182
        ETH_DEVICE
1886 hidnplayr 183
 
2852 hidnplayr 184
        .io_addr        dd ?
1886 hidnplayr 185
 
2852 hidnplayr 186
        .cur_rx         dw ?
187
        .cur_tx         dw ?
188
        .last_tx        dw ?
189
        .phy_addr       dw ?
190
        .phy_mode       dw ?
191
        .mcr0           dw ?
192
        .mcr1           dw ?
193
        .switch_sig     dw ?
1886 hidnplayr 194
 
2852 hidnplayr 195
        .pci_bus        db ?
196
        .pci_dev        db ?
197
        .irq_line       db ?
1886 hidnplayr 198
 
2852 hidnplayr 199
        rb 1            ; dword alignment
1886 hidnplayr 200
 
2852 hidnplayr 201
        .tx_ring:       rb (((x_head.sizeof*TX_RING_SIZE)+32) and 0xfffffff0)
202
        .rx_ring:       rb (((x_head.sizeof*RX_RING_SIZE)+32) and 0xfffffff0)
1886 hidnplayr 203
 
2852 hidnplayr 204
        .size = $ - device
1886 hidnplayr 205
 
206
end virtual
207
 
208
 
209
 
210
section '.flat' code readable align 16
211
 
212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213
;;                        ;;
214
;; proc START             ;;
215
;;                        ;;
216
;; (standard driver proc) ;;
217
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
218
 
219
align 4
220
proc START stdcall, state:dword
221
 
2852 hidnplayr 222
        cmp [state], 1
223
        jne .exit
1886 hidnplayr 224
 
225
  .entry:
226
 
2852 hidnplayr 227
        DEBUGF  2,"Loading R6040 driver\n"
228
        stdcall RegService, my_service, service_proc
229
        ret
1886 hidnplayr 230
 
231
  .fail:
232
  .exit:
2852 hidnplayr 233
        xor eax, eax
234
        ret
1886 hidnplayr 235
 
236
endp
237
 
238
 
239
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240
;;                        ;;
241
;; proc SERVICE_PROC      ;;
242
;;                        ;;
243
;; (standard driver proc) ;;
244
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245
 
246
align 4
247
proc service_proc stdcall, ioctl:dword
248
 
2852 hidnplayr 249
        mov     edx, [ioctl]
250
        mov     eax, [IOCTL.io_code]
1886 hidnplayr 251
 
252
;------------------------------------------------------
253
 
2852 hidnplayr 254
        cmp     eax, 0 ;SRV_GETVERSION
255
        jne     @F
1886 hidnplayr 256
 
2852 hidnplayr 257
        cmp     [IOCTL.out_size], 4
258
        jl      .fail
259
        mov     eax, [IOCTL.output]
260
        mov     [eax], dword API_VERSION
1886 hidnplayr 261
 
2852 hidnplayr 262
        xor     eax, eax
263
        ret
1886 hidnplayr 264
 
265
;------------------------------------------------------
266
  @@:
2852 hidnplayr 267
        cmp     eax, 1 ;SRV_HOOK
268
        jne     .fail
1886 hidnplayr 269
 
2852 hidnplayr 270
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
271
        jl      .fail
1886 hidnplayr 272
 
2852 hidnplayr 273
        mov     eax, [IOCTL.input]
274
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
275
        jne     .fail                                   ; other types arent supported for this card yet
1886 hidnplayr 276
 
277
; check if the device is already listed
278
 
2852 hidnplayr 279
        mov     esi, device_list
280
        mov     ecx, [devices]
281
        test    ecx, ecx
282
        jz      .firstdevice
1886 hidnplayr 283
 
284
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
2852 hidnplayr 285
        mov     ax , [eax+1]                            ;
1886 hidnplayr 286
  .nextdevice:
2852 hidnplayr 287
        mov     ebx, [esi]
288
        cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
289
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
290
        add     esi, 4
291
        loop    .nextdevice
1886 hidnplayr 292
 
293
 
294
; This device doesnt have its own eth_device structure yet, lets create one
295
  .firstdevice:
2852 hidnplayr 296
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
297
        jge     .fail
1886 hidnplayr 298
 
2852 hidnplayr 299
        allocate_and_clear ebx, device.size, .fail      ; Allocate the buffer for device structure
1886 hidnplayr 300
 
301
; Fill in the direct call addresses into the struct
302
 
2852 hidnplayr 303
        mov     [device.reset], reset
304
        mov     [device.transmit], transmit
305
        mov     [device.get_MAC], read_mac
306
        mov     [device.set_MAC], .fail
307
        mov     [device.unload], unload
308
        mov     [device.name], my_service
1886 hidnplayr 309
 
310
; save the pci bus and device numbers
311
 
2852 hidnplayr 312
        mov     eax, [IOCTL.input]
313
        mov     cl , [eax+1]
314
        mov     [device.pci_bus], cl
315
        mov     cl , [eax+2]
316
        mov     [device.pci_dev], cl
1886 hidnplayr 317
 
318
; Now, it's time to find the base io addres of the PCI device
319
 
2852 hidnplayr 320
        find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
1886 hidnplayr 321
 
322
; We've found the io address, find IRQ now
323
 
2852 hidnplayr 324
        find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
1886 hidnplayr 325
 
2852 hidnplayr 326
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
327
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1886 hidnplayr 328
 
329
; Ok, the eth_device structure is ready, let's probe the device
2852 hidnplayr 330
        cli
1886 hidnplayr 331
 
2852 hidnplayr 332
        call    probe                                                   ; this function will output in eax
333
        test    eax, eax
334
        jnz     .err_sti                                                ; If an error occured, exit
1886 hidnplayr 335
 
2852 hidnplayr 336
        mov     eax, [devices]                                          ; Add the device structure to our device list
337
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
338
        inc     [devices]                                               ;
1886 hidnplayr 339
 
2852 hidnplayr 340
        mov     [device.type], NET_TYPE_ETH
341
        call    NetRegDev
342
        sti
1886 hidnplayr 343
 
2852 hidnplayr 344
        cmp     eax, -1
345
        je      .destroy
1886 hidnplayr 346
 
2852 hidnplayr 347
        ret
1886 hidnplayr 348
 
349
; If the device was already loaded, find the device number and return it in eax
350
 
351
  .find_devicenum:
2852 hidnplayr 352
        DEBUGF  1,"Trying to find device number of already registered device\n"
353
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
354
                                                                        ; into a device number in edi
355
        mov     eax, edi                                                ; Application wants it in eax instead
356
        DEBUGF  1,"Kernel says: %u\n", eax
357
        ret
1886 hidnplayr 358
 
359
; If an error occured, remove all allocated data and exit (returning -1 in eax)
360
 
361
  .destroy:
2852 hidnplayr 362
        ; todo: reset device into virgin state
1886 hidnplayr 363
 
364
  .err_sti:
2852 hidnplayr 365
        sti
1886 hidnplayr 366
 
367
  .err:
2852 hidnplayr 368
        stdcall KernelFree, ebx
1886 hidnplayr 369
 
370
  .fail:
2852 hidnplayr 371
        or      eax, -1
372
        ret
1886 hidnplayr 373
 
374
;------------------------------------------------------
375
endp
376
 
377
 
378
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
379
;;                                                                        ;;
380
;;        Actual Hardware dependent code starts here                      ;;
381
;;                                                                        ;;
382
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
383
 
384
 
1893 hidnplayr 385
macro mdio_write reg, val {
2852 hidnplayr 386
        stdcall phy_read, [device.io_addr], [device.phy_addr], reg
1886 hidnplayr 387
}
388
 
1893 hidnplayr 389
macro mdio_write reg, val {
2852 hidnplayr 390
        stdcall phy_write, [device.io_addr], [devce.phy_addr], reg, val
1886 hidnplayr 391
}
392
 
393
 
394
align 4
395
unload:
2852 hidnplayr 396
        ; TODO: (in this particular order)
397
        ;
398
        ; - Stop the device
399
        ; - Detach int handler
400
        ; - Remove device from local list (RTL8139_LIST)
401
        ; - call unregister function in kernel
402
        ; - Remove all allocated structures and buffers the card used
1886 hidnplayr 403
 
2852 hidnplayr 404
        or      eax,-1
1886 hidnplayr 405
 
406
ret
407
 
408
 
409
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
410
;;
411
;;  probe: enables the device (if it really is RTL8139)
412
;;
413
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
414
 
415
align 4
416
probe:
2852 hidnplayr 417
        DEBUGF  2,"Probing R6040 device\n"
1886 hidnplayr 418
 
2852 hidnplayr 419
        make_bus_master [device.pci_bus], [device.pci_dev]
1886 hidnplayr 420
 
2852 hidnplayr 421
        ; If PHY status change register is still set to zero
422
        ; it means the bootloader didn't initialize it
1886 hidnplayr 423
 
2852 hidnplayr 424
        set_io  0
425
        set_io  PHY_CC
426
        in      ax, dx
427
        test    ax, ax
428
        jnz     @f
429
        mov     ax, 0x9F07
430
        out     dx, ax
1886 hidnplayr 431
     @@:
432
 
2852 hidnplayr 433
        call    read_mac
1886 hidnplayr 434
 
2852 hidnplayr 435
        ; Some bootloaders/BIOSes do not initialize MAC address, warn about that
436
        and     eax, 0xFF
437
        or      eax, dword [device.mac]
438
        test    eax, eax
439
        jnz     @f
440
        DEBUGF  2, "ERROR: MAC address not initialized!\n"
1886 hidnplayr 441
 
442
     @@:
2852 hidnplayr 443
        ; Init RDC private data
444
        mov     [device.mcr0], 0x1002
445
        ;mov     [private.phy_addr], 1 ; Asper: Only one network card is supported now.
446
        mov     [device.switch_sig], 0
1886 hidnplayr 447
 
2852 hidnplayr 448
        ; Check the vendor ID on the PHY, if 0xFFFF assume none attached
449
        stdcall phy_read, 1, 2
450
        cmp     ax, 0xFFFF
451
        jne     @f
452
        DEBUGF  2, "Failed to detect an attached PHY\n" ;, generating random"
453
        mov     eax, -1
454
        ret
1886 hidnplayr 455
     @@:
456
 
2852 hidnplayr 457
        ; Set MAC address
458
        call    init_mac_regs
1886 hidnplayr 459
 
2852 hidnplayr 460
        ; Initialize and alloc RX/TX buffers
461
        call    init_txbufs
462
        call    init_rxbufs
1886 hidnplayr 463
 
2852 hidnplayr 464
        ; Read the PHY ID
465
        mov     [device.phy_mode], 0x8000
466
        stdcall phy_read, 0, 2
467
        mov     [device.switch_sig], ax
468
        cmp     ax, ICPLUS_PHY_ID
469
        jne     @f
470
        stdcall phy_write, 29, 31, 0x175C ; Enable registers
471
        jmp     .phy_readen
1886 hidnplayr 472
      @@:
473
 
2852 hidnplayr 474
        ; PHY Mode Check
475
        movzx   eax, [device.phy_addr]
476
        stdcall phy_write, eax, 4, PHY_CAP
477
        stdcall phy_write, eax, 0, PHY_MODE
1886 hidnplayr 478
 
1893 hidnplayr 479
      if PHY_MODE = 0x3100
2852 hidnplayr 480
        call    phy_mode_chk
481
        mov     [device.phy_mode], ax
482
        jmp     .phy_readen
1893 hidnplayr 483
      end if
1886 hidnplayr 484
 
1893 hidnplayr 485
      if not (PHY_MODE and 0x0100)
2852 hidnplayr 486
        mov     [device.phy_mode], 0
1893 hidnplayr 487
      end if
488
 
1886 hidnplayr 489
      .phy_readen:
490
 
2852 hidnplayr 491
        ; Set duplex mode
492
        mov     ax, [device.phy_mode]
493
        or      [device.mcr0], ax
1886 hidnplayr 494
 
2852 hidnplayr 495
        ; improve performance (by RDC guys)
496
        stdcall phy_read, 30, 17
497
        or      ax, 0x4000
498
        stdcall phy_write, 30, 17, eax
1886 hidnplayr 499
 
2852 hidnplayr 500
        stdcall phy_read, 30, 17
501
        and     ax, not 0x2000
502
        stdcall phy_write, 30, 17, eax
1886 hidnplayr 503
 
2852 hidnplayr 504
        stdcall phy_write, 0, 19, 0x0000
505
        stdcall phy_write, 0, 30, 0x01F0
1886 hidnplayr 506
 
2852 hidnplayr 507
        ; Initialize all Mac registers
508
        call    init_mac_regs
1886 hidnplayr 509
 
510
 
511
 
512
align 4
513
reset:
514
 
2852 hidnplayr 515
        DEBUGF  2,"Resetting R6040\n"
1886 hidnplayr 516
 
2852 hidnplayr 517
        ; Mask off Interrupt
518
        xor     ax, ax
519
        set_io  0
520
        set_io  MIER
521
        out     dx, ax
1886 hidnplayr 522
 
523
 
524
; attach int handler
525
 
2852 hidnplayr 526
        movzx   eax, [device.irq_line]
527
        DEBUGF  2,"Attaching int handler to irq %x\n", eax:1
528
        stdcall AttachIntHandler, eax, int_handler, dword 0
529
        test    eax, eax
530
        jnz     @f
531
        DEBUGF  2,"\nCould not attach int handler!\n"
1886 hidnplayr 532
;        or      eax, -1
533
;        ret
534
       @@:
535
 
536
 
2852 hidnplayr 537
        ;Reset RDC MAC
538
        mov     eax, MAC_RST
539
        set_io  0
540
        set_io  MCR1
541
        out     dx, ax
1886 hidnplayr 542
 
2852 hidnplayr 543
        mov     ecx, 2048 ;limit
1886 hidnplayr 544
  .read:
2852 hidnplayr 545
        in      ax, dx
546
        test    ax, 0x1
547
        jnz      @f
548
        dec     ecx
549
        test    ecx, ecx
550
        jnz     .read
1886 hidnplayr 551
  @@:
2852 hidnplayr 552
        ;Reset internal state machine
553
        mov     ax,  2
554
        set_io  MAC_SM
555
        out     dx, ax
1886 hidnplayr 556
 
2852 hidnplayr 557
        xor     ax, ax
558
        out     dx, ax
1886 hidnplayr 559
 
2852 hidnplayr 560
        mov     esi, 5
561
        stdcall Sleep
1886 hidnplayr 562
 
2852 hidnplayr 563
        ;MAC Bus Control Register
564
        mov     ax, MBCR_DEFAULT
565
        set_io  0
566
        set_io  MBCR
567
        out     dx, ax
1886 hidnplayr 568
 
2852 hidnplayr 569
        ;Buffer Size Register
570
        mov     ax, MAX_BUF_SIZE
571
        set_io  MR_BSR
572
        out     dx, ax
1886 hidnplayr 573
 
2852 hidnplayr 574
        ;Write TX ring start address
575
        lea     eax, [device.tx_ring]
576
        GetRealAddr
577
        set_io  MTD_SA0
578
        out     dx, ax
579
        shr     eax, 16
580
        set_io  MTD_SA1
581
        out     dx, ax
1886 hidnplayr 582
 
2852 hidnplayr 583
        ;Write RX ring start address
584
        lea     eax, [device.rx_ring]
585
        GetRealAddr
586
        set_io  MRD_SA0
587
        out     dx, ax
588
        shr     eax, 16
589
        set_io  MRD_SA1
590
        out     dx, ax
1886 hidnplayr 591
 
2852 hidnplayr 592
        ;Set interrupt waiting time and packet numbers
593
        xor     ax, ax
594
        set_io  MT_ICR
595
        out     dx, ax
1886 hidnplayr 596
 
2852 hidnplayr 597
        ;Enable interrupts
598
        mov     ax, INT_MASK
599
        set_io  MIER
600
        out     dx, ax
1886 hidnplayr 601
 
2852 hidnplayr 602
        ;Enable TX and RX
603
        mov     ax, [device.mcr0]
604
        or      ax, 0x0002
605
        set_io  0
606
        out     dx, ax
1886 hidnplayr 607
 
2852 hidnplayr 608
        ;Let TX poll the descriptors
609
        ;we may got called by tx_timeout which has left
610
        ;some unset tx buffers
611
        xor     ax, ax
612
        inc     ax
613
        set_io  0
614
        set_io  MTPR
615
        out     dx, ax
1886 hidnplayr 616
 
617
; Set the mtu, kernel will be able to send now
2852 hidnplayr 618
        mov     [device.mtu], 1514
1886 hidnplayr 619
 
2852 hidnplayr 620
        DEBUGF  1,"Reset ok\n"
621
        xor     eax, eax
1886 hidnplayr 622
 
2852 hidnplayr 623
        ret
1886 hidnplayr 624
 
625
 
626
 
627
align 4
628
init_txbufs:
629
 
2852 hidnplayr 630
        DEBUGF  1,"Init TxBufs\n"
1886 hidnplayr 631
 
2852 hidnplayr 632
        lea     esi, [device.tx_ring]
633
        lea     eax, [device.tx_ring + x_head.sizeof]
634
        GetRealAddr
635
        mov     ecx, TX_RING_SIZE
1886 hidnplayr 636
 
637
    .next_desc:
2852 hidnplayr 638
        mov     [esi + x_head.ndesc], eax
639
        mov     [esi + x_head.skb_ptr], 0
640
        mov     [esi + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 641
 
2852 hidnplayr 642
        add     eax, x_head.sizeof
643
        add     esi, x_head.sizeof
1886 hidnplayr 644
 
2852 hidnplayr 645
        dec     ecx
646
        jnz     .next_desc
1886 hidnplayr 647
 
2852 hidnplayr 648
        lea     eax, [device.tx_ring]
649
        GetRealAddr
650
        mov     [device.tx_ring + x_head.sizeof*(TX_RING_SIZE - 1) + x_head.ndesc], eax
1886 hidnplayr 651
 
2852 hidnplayr 652
        ret
1886 hidnplayr 653
 
654
 
655
 
656
align 4
657
init_rxbufs:
658
 
2852 hidnplayr 659
        DEBUGF  1,"Init RxBufs\n"
1886 hidnplayr 660
 
2852 hidnplayr 661
        lea     esi, [device.rx_ring]
662
        lea     eax, [device.rx_ring + x_head.sizeof]
663
        GetRealAddr
664
        mov     edx, eax
665
        mov     ecx, RX_RING_SIZE
1886 hidnplayr 666
 
667
    .next_desc:
2852 hidnplayr 668
         mov     [esi + x_head.ndesc], edx
1886 hidnplayr 669
 
2852 hidnplayr 670
        push    esi ecx
671
        stdcall KernelAlloc, MAX_BUF_SIZE
672
        pop     ecx esi
1886 hidnplayr 673
 
2852 hidnplayr 674
        mov     [esi + x_head.skb_ptr], eax
675
        GetRealAddr
676
        mov     [esi + x_head.buf], eax
677
        mov     [esi + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 678
 
2852 hidnplayr 679
        add     edx, x_head.sizeof
680
        add     esi, x_head.sizeof
1886 hidnplayr 681
 
2852 hidnplayr 682
        dec     ecx
683
        jnz     .next_desc
1886 hidnplayr 684
 
2852 hidnplayr 685
        ; complete the ring by linking the last to the first
1886 hidnplayr 686
 
2852 hidnplayr 687
        lea     eax, [device.rx_ring]
688
        GetRealAddr
689
        mov     [device.rx_ring + x_head.sizeof*(RX_RING_SIZE - 1) + x_head.ndesc], eax
1886 hidnplayr 690
 
2852 hidnplayr 691
        ret
1886 hidnplayr 692
 
693
 
694
 
695
align 4
696
phy_mode_chk:
697
 
2852 hidnplayr 698
        DEBUGF  1,"Checking PHY mode\n"
1886 hidnplayr 699
 
2852 hidnplayr 700
        ; PHY Link Status Check
701
        movzx   eax, [device.phy_addr]
702
        stdcall phy_read, eax, 1
703
        test    eax, 0x4
704
        jz      .ret_0x8000
1886 hidnplayr 705
 
2852 hidnplayr 706
        ; PHY Chip Auto-Negotiation Status
707
        movzx   eax, [device.phy_addr]
708
        stdcall phy_read, eax, 1
709
        test    eax, 0x0020
710
        jnz     .auto_nego
1886 hidnplayr 711
 
2852 hidnplayr 712
        ; Force Mode
713
        movzx   eax, [device.phy_addr]
714
        stdcall phy_read, eax, 0
715
        test    eax, 0x100
716
        jnz     .ret_0x8000
1886 hidnplayr 717
 
718
  .auto_nego:
2852 hidnplayr 719
        ; Auto Negotiation Mode
720
        movzx   eax, [device.phy_addr]
721
        stdcall phy_read, eax, 5
722
        mov     ecx, eax
723
        movzx   eax, [device.phy_addr]
724
        stdcall phy_read, eax, 4
725
        and     eax, ecx
726
        test    eax, 0x140
727
        jnz     .ret_0x8000
1886 hidnplayr 728
 
2852 hidnplayr 729
        xor     eax, eax
730
        ret
1886 hidnplayr 731
 
732
  .ret_0x8000:
2852 hidnplayr 733
        mov     eax, 0x8000
734
        ret
1886 hidnplayr 735
 
736
 
737
 
738
 
739
 
740
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
741
;;                                         ;;
742
;; Transmit                                ;;
743
;;                                         ;;
744
;; In: buffer pointer in [esp+4]           ;;
745
;;     size of buffer in [esp+8]           ;;
746
;;     pointer to device structure in ebx  ;;
747
;;                                         ;;
748
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
749
align 4
750
transmit:
2852 hidnplayr 751
        DEBUGF  2,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
752
        mov     eax, [esp+4]
753
        DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
754
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
755
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
756
        [eax+13]:2,[eax+12]:2
1886 hidnplayr 757
 
2852 hidnplayr 758
        cmp     dword [esp+8], 1514
759
        jg      .fail
760
        cmp     dword [esp+8], 60
761
        jl      .fail
1886 hidnplayr 762
 
2852 hidnplayr 763
        movzx   edi, [device.cur_tx]
764
        shl     edi, 5
765
        add     edi, ebx
766
        add     edi, device.tx_ring - ebx
1886 hidnplayr 767
 
2852 hidnplayr 768
        DEBUGF  2,"TX buffer status: 0x%x\n", [edi + x_head.status]:4
1886 hidnplayr 769
 
2852 hidnplayr 770
        test    [edi + x_head.status], DSC_OWNER_MAC    ; check if buffer is available
771
        jnz     .wait_to_send
1886 hidnplayr 772
 
773
  .do_send:
774
 
2852 hidnplayr 775
        DEBUGF  2,"Sending now\n"
1893 hidnplayr 776
 
2852 hidnplayr 777
        mov     eax, [esp+4]
778
        mov     [edi + x_head.skb_ptr], eax
779
        GetRealAddr
780
        mov     [edi + x_head.buf], eax
781
        mov     ecx, [esp+8]
782
        mov     [edi + x_head.len], cx
783
        mov     [edi + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 784
 
2852 hidnplayr 785
        ; Trigger the MAC to check the TX descriptor
786
        mov     ax, 0x01
787
        set_io  0
788
        set_io  MTPR
789
        out     dx, ax
1886 hidnplayr 790
 
2852 hidnplayr 791
        inc     [device.cur_tx]
792
        and     [device.cur_tx], TX_RING_SIZE - 1
793
        xor     eax, eax
1886 hidnplayr 794
 
2865 hidnplayr 795
; Update stats
796
        inc     [device.packets_tx]
797
        mov     eax, [esp+8]
798
        add     dword [device.bytes_tx], eax
799
        adc     dword [device.bytes_tx + 4], 0
800
 
2852 hidnplayr 801
        ret     8
1886 hidnplayr 802
 
803
  .wait_to_send:
804
 
2852 hidnplayr 805
        DEBUGF  2,"Waiting for TX buffer\n"
1886 hidnplayr 806
 
2852 hidnplayr 807
        call    GetTimerTicks           ; returns in eax
808
        lea     edx, [eax + 100]
1893 hidnplayr 809
     .l2:
2852 hidnplayr 810
        test    [edi + x_head.status], DSC_OWNER_MAC
811
        jz      .do_send
812
        mov     esi, 10
813
        call    Sleep
814
        call    GetTimerTicks
815
        cmp     edx, eax
816
        jl      .l2
1893 hidnplayr 817
 
2852 hidnplayr 818
        DEBUGF  1,"Send timeout\n"
819
        xor     eax, eax
820
        dec     eax
1886 hidnplayr 821
  .fail:
2852 hidnplayr 822
        DEBUGF  1,"Send failed\n"
823
        ret     8
1886 hidnplayr 824
 
825
 
826
 
827
 
828
 
829
;;;;;;;;;;;;;;;;;;;;;;;
830
;;                   ;;
831
;; Interrupt handler ;;
832
;;                   ;;
833
;;;;;;;;;;;;;;;;;;;;;;;
2935 hidnplayr 834
 
1886 hidnplayr 835
align 4
836
int_handler:
837
 
2935 hidnplayr 838
        DEBUGF  1,"\n%s int\n", my_service
1886 hidnplayr 839
 
840
; Find pointer of device wich made IRQ occur
841
 
2852 hidnplayr 842
        mov     ecx, [devices]
843
        test    ecx, ecx
2935 hidnplayr 844
        jz      .nothing
845
        mov     esi, device_list
1886 hidnplayr 846
  .nextdevice:
2935 hidnplayr 847
        mov     ebx, [esi]
1886 hidnplayr 848
 
2852 hidnplayr 849
        set_io  0
850
        set_io  MISR
851
        in      ax, dx
2935 hidnplayr 852
        out     dx, ax                  ; send it back to ACK
853
        test    ax, ax
2852 hidnplayr 854
        jnz     .got_it
2935 hidnplayr 855
  .continue:
2852 hidnplayr 856
        add     esi, 4
857
        dec     ecx
858
        jnz     .nextdevice
2935 hidnplayr 859
  .nothing:                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
2852 hidnplayr 860
        ret
1886 hidnplayr 861
 
862
; At this point, test for all possible reasons, and handle accordingly
863
 
864
  .got_it:
2935 hidnplayr 865
 
866
        DEBUGF  1,"Device: %x Status: %x ", ebx, ax
867
 
2852 hidnplayr 868
        push ax
1886 hidnplayr 869
 
2852 hidnplayr 870
        test    word [esp], RX_FINISH
871
        jz      .no_RX
1886 hidnplayr 872
 
2852 hidnplayr 873
        push    ebx
1886 hidnplayr 874
  .more_RX:
2852 hidnplayr 875
        pop     ebx
1886 hidnplayr 876
 
2852 hidnplayr 877
        ; Find the current RX descriptor
1886 hidnplayr 878
 
2852 hidnplayr 879
        movzx   edx, [device.cur_rx]
880
        shl     edx, 5
881
        lea     edx, [device.rx_ring + edx]
1886 hidnplayr 882
 
2852 hidnplayr 883
        ; Check the descriptor status
1886 hidnplayr 884
 
2852 hidnplayr 885
        mov     cx, [edx + x_head.status]
886
        test    cx, DSC_OWNER_MAC
887
        jnz     .no_RX
1886 hidnplayr 888
 
2852 hidnplayr 889
        DEBUGF  2,"packet status=0x%x\n", cx
1886 hidnplayr 890
 
2852 hidnplayr 891
        test    cx, DSC_RX_ERR          ; Global error status set
892
        jnz     .no_RX
1886 hidnplayr 893
 
2852 hidnplayr 894
        ; Packet successfully received
1886 hidnplayr 895
 
2852 hidnplayr 896
        movzx   ecx, [edx + x_head.len]
897
        and     ecx, 0xFFF
898
        sub     ecx, 4                  ; Do not count the CRC
1886 hidnplayr 899
 
2865 hidnplayr 900
; Update stats
901
        add     dword [device.bytes_rx], ecx
902
        adc     dword [device.bytes_rx + 4], 0
903
        inc     dword [device.packets_rx]
904
 
2852 hidnplayr 905
        ; Push packet size and pointer, kernel will need it..
1886 hidnplayr 906
 
2852 hidnplayr 907
        push    ebx
908
        push    .more_RX
1886 hidnplayr 909
 
2852 hidnplayr 910
        push    ecx
911
        push    [edx + x_head.skb_ptr]
1886 hidnplayr 912
 
2852 hidnplayr 913
        DEBUGF  2,"packet ptr=0x%x\n", [edx + x_head.skb_ptr]
1886 hidnplayr 914
 
2852 hidnplayr 915
        ; reset the RX descriptor
1886 hidnplayr 916
 
2852 hidnplayr 917
        push    edx
918
        stdcall KernelAlloc, MAX_BUF_SIZE
919
        pop     edx
920
        mov     [edx + x_head.skb_ptr], eax
921
        GetRealAddr
922
        mov     [edx + x_head.buf], eax
923
        mov     [edx + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 924
 
2852 hidnplayr 925
        ; Use next descriptor next time
1886 hidnplayr 926
 
2852 hidnplayr 927
        inc     [device.cur_rx]
928
        and     [device.cur_rx], RX_RING_SIZE - 1
1886 hidnplayr 929
 
2852 hidnplayr 930
        ; At last, send packet to kernel
1886 hidnplayr 931
 
2981 hidnplayr 932
        jmp     Eth_input
1886 hidnplayr 933
 
1889 hidnplayr 934
 
1886 hidnplayr 935
  .no_RX:
936
 
2852 hidnplayr 937
        test    word [esp], TX_FINISH
938
        jz      .no_TX
1886 hidnplayr 939
 
1889 hidnplayr 940
      .loop_tx:
2852 hidnplayr 941
        movzx   edi, [device.last_tx]
942
        shl     edi, 5
943
        lea     edi, [device.tx_ring + edi]
1886 hidnplayr 944
 
2852 hidnplayr 945
        test    [edi + x_head.status], DSC_OWNER_MAC
946
        jnz     .no_TX
1889 hidnplayr 947
 
2852 hidnplayr 948
        cmp     [edi + x_head.skb_ptr], 0
949
        je      .no_TX
1889 hidnplayr 950
 
2852 hidnplayr 951
        DEBUGF  2,"Freeing buffer 0x%x\n", [edi + x_head.skb_ptr]
1889 hidnplayr 952
 
2852 hidnplayr 953
        push    [edi + x_head.skb_ptr]
954
        mov     [edi + x_head.skb_ptr], 0
955
        call    KernelFree
1889 hidnplayr 956
 
2852 hidnplayr 957
        inc     [device.last_tx]
958
        and     [device.last_tx], TX_RING_SIZE - 1
1893 hidnplayr 959
 
2852 hidnplayr 960
        jmp     .loop_tx
1889 hidnplayr 961
 
962
  .no_TX:
2852 hidnplayr 963
        pop     ax
964
        ret
1886 hidnplayr 965
 
966
 
967
 
968
 
969
align 4
970
init_mac_regs:
971
 
2852 hidnplayr 972
        DEBUGF  2,"initializing MAC regs\n"
1886 hidnplayr 973
 
2852 hidnplayr 974
        ; MAC operation register
975
        mov     ax, 1
976
        set_io  0
977
        set_io  MCR1
978
        out     dx, ax
979
        ; Reset MAC
980
        mov     ax, 2
981
        set_io  MAC_SM
982
        out     dx, ax
983
        ; Reset internal state machine
984
        xor     ax, ax
985
        out     dx, ax
986
        mov     esi, 5
987
        stdcall Sleep
1886 hidnplayr 988
 
2852 hidnplayr 989
        call    read_mac
1886 hidnplayr 990
 
2852 hidnplayr 991
        ret
1886 hidnplayr 992
 
993
 
994
 
995
 
996
; Read a word data from PHY Chip
997
 
998
align 4
999
proc  phy_read stdcall, phy_addr:dword, reg:dword
1000
 
2852 hidnplayr 1001
        DEBUGF  2,"PHY read, addr=0x%x reg=0x%x\n", [phy_addr]:8, [reg]:8
1886 hidnplayr 1002
 
2852 hidnplayr 1003
        mov     eax, [phy_addr]
1004
        shl     eax, 8
1005
        add     eax, [reg]
1006
        add     eax, MDIO_READ
1007
        set_io  0
1008
        set_io  MMDIO
1009
        out     dx, ax
1886 hidnplayr 1010
 
2852 hidnplayr 1011
        ;Wait for the read bit to be cleared.
1012
        mov     ecx, 2048 ;limit
1886 hidnplayr 1013
  .read:
2852 hidnplayr 1014
        in      ax, dx
1015
        test    ax, MDIO_READ
1016
        jz      @f
1017
        dec     ecx
1018
        jnz     .read
1886 hidnplayr 1019
  @@:
1020
 
2852 hidnplayr 1021
        set_io  MMRD
1022
        in      ax, dx
1023
        and     eax, 0xFFFF
1886 hidnplayr 1024
 
2852 hidnplayr 1025
        DEBUGF  2,"PHY read, val=0x%x\n", eax:4
1886 hidnplayr 1026
 
2852 hidnplayr 1027
        ret
1886 hidnplayr 1028
 
1029
endp
1030
 
1031
 
1032
 
1033
 
1034
; Write a word data to PHY Chip
1035
 
1036
align 4
1037
proc  phy_write stdcall, phy_addr:dword, reg:dword, val:dword
1038
 
2852 hidnplayr 1039
        DEBUGF  2,"PHY write, addr=0x%x reg=0x%x val=0x%x\n", [phy_addr]:8, [reg]:8, [val]:8
1886 hidnplayr 1040
 
2852 hidnplayr 1041
        mov     eax, [val]
1042
        set_io  0
1043
        set_io  MMWD
1044
        out     dx, ax
1886 hidnplayr 1045
 
2852 hidnplayr 1046
        ;Write the command to the MDIO bus
1886 hidnplayr 1047
 
2852 hidnplayr 1048
        mov     eax, [phy_addr]
1049
        shl     eax, 8
1050
        add     eax, [reg]
1051
        add     eax, MDIO_WRITE
1052
        set_io  MMDIO
1053
        out     dx, ax
1886 hidnplayr 1054
 
2852 hidnplayr 1055
        ;Wait for the write bit to be cleared.
1056
        mov     ecx, 2048 ;limit
1886 hidnplayr 1057
  .write:
2852 hidnplayr 1058
        in      ax, dx
1059
        test    ax, MDIO_WRITE
1060
        jz      @f
1061
        dec     ecx
1062
        jnz     .write
1886 hidnplayr 1063
  @@:
1064
 
2852 hidnplayr 1065
        DEBUGF  2,"PHY write ok\n"
1886 hidnplayr 1066
 
2852 hidnplayr 1067
        ret
1886 hidnplayr 1068
endp
1069
 
1070
 
1071
 
1072
align 4
1073
read_mac:
1074
 
2852 hidnplayr 1075
        DEBUGF  2,"Reading MAC: "
1886 hidnplayr 1076
 
2852 hidnplayr 1077
        mov     cx, 3
1078
        lea     edi, [device.mac]
1079
        set_io  0
1080
        set_io  MID_0L
1886 hidnplayr 1081
     .mac:
2852 hidnplayr 1082
        in      ax, dx
1083
        stosw
1084
        inc     dx
1085
        inc     dx
1086
        dec     cx
1087
        jnz     .mac
1886 hidnplayr 1088
 
2852 hidnplayr 1089
        DEBUGF  2,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2
1886 hidnplayr 1090
 
2852 hidnplayr 1091
        ret
1886 hidnplayr 1092
 
1093
 
1094
 
1095
 
1096
; End of code
1097
 
1098
section '.data' data readable writable align 16 ; place all uninitialized data place here
2852 hidnplayr 1099
align 4                                         ; Place all initialised data here
1886 hidnplayr 1100
 
2852 hidnplayr 1101
devices         dd 0
1102
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1103
my_service      db 'R6040',0                    ; max 16 chars include zero
1886 hidnplayr 1104
 
2852 hidnplayr 1105
include_debug_strings                           ; All data wich FDO uses will be included here
1886 hidnplayr 1106
 
2852 hidnplayr 1107
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
1886 hidnplayr 1108