Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
586 serge 2
;;                                                              ;;
1602 art_zh 3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;                                                              ;;
586 serge 7
;;  PCI32.INC                                                   ;;
8
;;                                                              ;;
9
;;  32 bit PCI driver code                                      ;;
10
;;                                                              ;;
11
;;  Version 0.3  April 9, 2007                                  ;;
12
;;  Version 0.2  December 21st, 2002                            ;;
13
;;                                                              ;;
14
;;  Author: Victor Prodan, victorprodan@yahoo.com               ;;
15
;;          Mihailov Ilia, ghost.nsk@gmail.com                  ;;
16
;;    Credits:                                                  ;;
17
;;          Ralf Brown                                          ;;
18
;;          Mike Hibbett, mikeh@oceanfree.net                   ;;
19
;;                                                              ;;
20
;;  See file COPYING for details                                ;;
21
;;                                                              ;;
431 serge 22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 ha 23
 
750 victor 24
$Revision: 1602 $
1 ha 25
 
26
;***************************************************************************
27
;   Function
28
;      pci_api:
29
;
30
;   Description
31
;       entry point for system PCI calls
32
;***************************************************************************
1370 art_zh 33
;mmio_pci_addr	equ  0x400		 ; set actual PCI address here to activate user-MMIO
1 ha 34
 
1591 lrz 35
iglobal
36
align 4
37
f62call:
1602 art_zh 38
	dd	pci_fn_0
39
	dd	pci_fn_1
40
	dd	pci_fn_2
41
	dd	pci_service_not_supported	;3
1591 lrz 42
	dd	pci_read_reg		;4 byte
43
	dd	pci_read_reg            ;5 word
44
	dd	pci_read_reg            ;6 dword
1602 art_zh 45
	dd	pci_service_not_supported   ;7
1591 lrz 46
	dd	pci_write_reg           ;8 byte
47
	dd	pci_write_reg           ;9 word
48
	dd	pci_write_reg           ;10 dword
49
if defined mmio_pci_addr
50
	dd	pci_mmio_init		;11
51
	dd	pci_mmio_map		;12
52
	dd	pci_mmio_unmap		;13
53
end if
1602 art_zh 54
 
1591 lrz 55
endg
1370 art_zh 56
 
1602 art_zh 57
align 4
1591 lrz 58
 
1 ha 59
pci_api:
1348 art_zh 60
	cmp  [pci_access_enabled],1
1602 art_zh 61
	jne  pci_service_not_supported
1 ha 62
 
1602 art_zh 63
;cross
64
	mov	eax,ebx
65
	mov	ebx,ecx
66
	mov	ecx,edx
67
;;;;;;;;;;;;;;;;;;;
68
 
1591 lrz 69
if defined mmio_pci_addr
70
        cmp eax, 13
1602 art_zh 71
        jb pci_service_not_supported
1591 lrz 72
else
73
        cmp eax, 10
1602 art_zh 74
        jb pci_service_not_supported
75
end if
76
 
77
        call 	dword [f62call+eax*4]
1591 lrz 78
        mov	dword [esp+32],eax
79
        ret
1602 art_zh 80
;; ============================================
1591 lrz 81
 
1602 art_zh 82
pci_fn_0:
83
; PCI function 0: get pci version (AH.AL)
84
	movzx eax,word [BOOT_VAR+0x9022]
1348 art_zh 85
	ret
1 ha 86
 
1602 art_zh 87
pci_fn_1:
88
; PCI function 1: get last bus in AL
89
	mov al,[BOOT_VAR+0x9021]
1348 art_zh 90
	ret
1 ha 91
 
1602 art_zh 92
pci_fn_2:
93
; PCI function 2: get pci access mechanism
94
	mov al,[BOOT_VAR+0x9020]
1348 art_zh 95
	ret
1 ha 96
 
1602 art_zh 97
pci_service_not_supported:
98
	or eax,-1
1348 art_zh 99
	ret
1 ha 100
 
101
;***************************************************************************
102
;   Function
103
;      pci_make_config_cmd
104
;
105
;   Description
106
;       creates a command dword  for use with the PCI bus
1602 art_zh 107
;       bus # in ah
108
;       device+func in bh (dddddfff)
109
;       register in bl
1 ha 110
;
1602 art_zh 111
;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
1 ha 112
;***************************************************************************
113
 
114
align 4
115
 
116
pci_make_config_cmd:
1602 art_zh 117
    shl     eax,8	   ; move bus to bits 16-23
118
    mov     ax,bx	   ; combine all
119
    and     eax,0xffffff
120
    or	    eax,0x80000000
1 ha 121
    ret
122
 
123
;***************************************************************************
124
;   Function
125
;      pci_read_reg:
126
;
127
;   Description
128
;       read a register from the PCI config space into EAX/AX/AL
1602 art_zh 129
;       IN: ah=bus,device+func=bh,register address=bl
130
;           number of bytes to read (1,2,4) coded into AL, bits 0-1
586 serge 131
;           (0 - byte, 1 - word, 2 - dword)
1 ha 132
;***************************************************************************
133
 
134
align 4
135
 
136
pci_read_reg:
1348 art_zh 137
	cmp	byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
138
	je	pci_read_reg_2
1 ha 139
 
1348 art_zh 140
		; mechanism 1
1602 art_zh 141
	push	esi   ; save register size into ESI
142
	mov	esi,eax
1348 art_zh 143
	and	esi,3
1 ha 144
 
1348 art_zh 145
	call	pci_make_config_cmd
1602 art_zh 146
	mov	ebx,eax
1348 art_zh 147
		; get current state
148
	mov	dx,0xcf8
149
	in	eax, dx
150
	push	eax
151
		; set up addressing to config data
152
	mov	eax,ebx
153
	and	al,0xfc ; make address dword-aligned
154
	out	dx,eax
155
		; get requested DWORD of config data
156
	mov	dl,0xfc
157
	and	bl,3
158
	or	dl,bl	 ; add to port address first 2 bits of register address
1 ha 159
 
1602 art_zh 160
	or	esi,esi
161
	jz	pci_read_byte1
162
	cmp	esi,1
163
	jz	pci_read_word1
164
	cmp	esi,2
165
	jz	pci_read_dword1
166
	jmp	pci_fin_read1
1 ha 167
 
1602 art_zh 168
pci_read_byte1:
1348 art_zh 169
	in	al,dx
1602 art_zh 170
	jmp pci_fin_read1
171
pci_read_word1:
1348 art_zh 172
	in	ax,dx
1602 art_zh 173
	jmp pci_fin_read1
174
pci_read_dword1:
1348 art_zh 175
	in	eax,dx
1602 art_zh 176
	jmp	pci_fin_read1
177
pci_fin_read1:
1348 art_zh 178
		; restore configuration control
179
	xchg	eax,[esp]
180
	mov	dx,0xcf8
181
	out	dx,eax
1 ha 182
 
1348 art_zh 183
	pop	eax
1602 art_zh 184
	pop	esi
1348 art_zh 185
	ret
1 ha 186
pci_read_reg_2:
187
 
1602 art_zh 188
	test	bh,128	;mech#2 only supports 16 devices per bus
189
	jnz	pci_read_reg_err
1 ha 190
 
1602 art_zh 191
	push esi   ; save register size into ESI
192
	mov esi,eax
1348 art_zh 193
	and esi,3
1 ha 194
 
1602 art_zh 195
	push	eax
1348 art_zh 196
		;store current state of config space
197
	mov	dx,0xcf8
198
	in	al,dx
199
	mov	ah,al
200
	mov	dl,0xfa
201
	in	al,dx
1 ha 202
 
1348 art_zh 203
	xchg	eax,[esp]
204
		; out 0xcfa,bus
205
	mov	al,ah
206
	out	dx,al
207
		; out 0xcf8,0x80
208
	mov	dl,0xf8
209
	mov	al,0x80
210
	out	dx,al
211
		; compute addr
1602 art_zh 212
	shr	bh,3 ; func is ignored in mechanism 2
213
	or	bh,0xc0
214
	mov	dx,bx
1 ha 215
 
1602 art_zh 216
	or	esi,esi
217
	jz	pci_read_byte2
218
	cmp	esi,1
219
	jz	pci_read_word2
220
	cmp	esi,2
221
	jz	pci_read_dword2
222
	jmp	pci_fin_read2
1 ha 223
 
1602 art_zh 224
pci_read_byte2:
1348 art_zh 225
	in	al,dx
1602 art_zh 226
	jmp pci_fin_read2
227
pci_read_word2:
1348 art_zh 228
	in	ax,dx
1602 art_zh 229
	jmp pci_fin_read2
230
pci_read_dword2:
1348 art_zh 231
	in	eax,dx
1 ha 232
;       jmp pci_fin_read2
1602 art_zh 233
pci_fin_read2:
1 ha 234
 
1348 art_zh 235
		; restore configuration space
236
	xchg	eax,[esp]
237
	mov	dx,0xcfa
238
	out	dx,al
239
	mov	dl,0xf8
240
	mov	al,ah
241
	out	dx,al
1 ha 242
 
1348 art_zh 243
	pop	eax
1602 art_zh 244
	pop	esi
1348 art_zh 245
	ret
1 ha 246
 
1602 art_zh 247
pci_read_reg_err:
248
	xor	eax,eax
249
	dec	eax
250
	ret
1 ha 251
 
252
 
253
;***************************************************************************
254
;   Function
255
;      pci_write_reg:
256
;
257
;   Description
258
;       write a register from ECX/CX/CL into the PCI config space
1602 art_zh 259
;       IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
260
;           value to write in ecx
261
;           number of bytes to write (1,2,4) coded into AL, bits 0-1
586 serge 262
;           (0 - byte, 1 - word, 2 - dword)
1 ha 263
;***************************************************************************
264
 
265
align 4
266
 
267
pci_write_reg:
1348 art_zh 268
	cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
269
	je pci_write_reg_2
1 ha 270
 
1348 art_zh 271
		; mechanism 1
1602 art_zh 272
	push	esi   ; save register size into ESI
273
	mov	esi,eax
274
	and	esi,3
1 ha 275
 
1348 art_zh 276
	call	pci_make_config_cmd
1602 art_zh 277
	mov	ebx,eax
1348 art_zh 278
		; get current state into ecx
279
	mov	dx,0xcf8
280
	in	eax, dx
281
	push	eax
282
		; set up addressing to config data
283
	mov	eax,ebx
284
	and	al,0xfc ; make address dword-aligned
285
	out	dx,eax
286
		; write DWORD of config data
287
	mov	dl,0xfc
288
	and	bl,3
289
	or	dl,bl
290
	mov	eax,ecx
1 ha 291
 
1602 art_zh 292
	or	esi,esi
293
	jz	pci_write_byte1
294
	cmp	esi,1
295
	jz	pci_write_word1
296
	cmp	esi,2
297
	jz	pci_write_dword1
298
	jmp	pci_fin_write1
299
 
300
pci_write_byte1:
1348 art_zh 301
	out	dx,al
1602 art_zh 302
	jmp pci_fin_write1
303
pci_write_word1:
1348 art_zh 304
	out	dx,ax
1602 art_zh 305
	jmp pci_fin_write1
306
pci_write_dword1:
1348 art_zh 307
	out	dx,eax
1602 art_zh 308
	jmp	pci_fin_write1
309
pci_fin_write1:
1 ha 310
 
1348 art_zh 311
		; restore configuration control
312
	pop	eax
313
	mov	dl,0xf8
314
	out	dx,eax
1 ha 315
 
1348 art_zh 316
	xor	eax,eax
1602 art_zh 317
	pop	esi
318
 
1348 art_zh 319
	ret
1 ha 320
pci_write_reg_2:
321
 
1602 art_zh 322
	test	bh,128	;mech#2 only supports 16 devices per bus
323
	jnz	pci_write_reg_err
1 ha 324
 
325
 
1602 art_zh 326
	push esi   ; save register size into ESI
1348 art_zh 327
	mov esi,eax
1602 art_zh 328
	and esi,3
1 ha 329
 
1348 art_zh 330
	push	eax
331
		;store current state of config space
332
	mov	dx,0xcf8
333
	in	al,dx
334
	mov	ah,al
335
	mov	dl,0xfa
336
	in	al,dx
337
	xchg	eax,[esp]
338
		; out 0xcfa,bus
339
	mov	al,ah
340
	out	dx,al
341
		; out 0xcf8,0x80
342
	mov	dl,0xf8
343
	mov	al,0x80
344
	out	dx,al
345
		; compute addr
346
	shr	bh,3 ; func is ignored in mechanism 2
347
	or	bh,0xc0
348
	mov	dx,bx
349
		; write register
350
	mov	eax,ecx
1 ha 351
 
1602 art_zh 352
	or	esi,esi
353
	jz	pci_write_byte2
354
	cmp	esi,1
355
	jz	pci_write_word2
356
	cmp	esi,2
357
	jz	pci_write_dword2
358
	jmp	pci_fin_write2
359
 
360
pci_write_byte2:
1348 art_zh 361
	out	dx,al
1602 art_zh 362
	jmp pci_fin_write2
363
pci_write_word2:
1348 art_zh 364
	out	dx,ax
1602 art_zh 365
	jmp pci_fin_write2
366
pci_write_dword2:
1348 art_zh 367
	out	dx,eax
1602 art_zh 368
	jmp	pci_fin_write2
369
pci_fin_write2:
1348 art_zh 370
		; restore configuration space
371
	pop	eax
372
	mov	dx,0xcfa
373
	out	dx,al
374
	mov	dl,0xf8
375
	mov	al,ah
376
	out	dx,al
1 ha 377
 
1348 art_zh 378
	xor	eax,eax
1602 art_zh 379
	pop	esi
1348 art_zh 380
	ret
1 ha 381
 
1602 art_zh 382
pci_write_reg_err:
383
	xor	eax,eax
384
	dec	eax
385
	ret
586 serge 386
 
1370 art_zh 387
if defined mmio_pci_addr	; must be set above
1348 art_zh 388
;***************************************************************************
389
;   Function
1370 art_zh 390
;      pci_mmio_init
1348 art_zh 391
;
392
;   Description
1602 art_zh 393
;       IN:  bx = device's PCI bus address (bbbbbbbbdddddfff)
1358 art_zh 394
;   Returns  eax = user heap space available (bytes)
1348 art_zh 395
;   Error codes
396
;       eax = -1 : PCI user access blocked,
397
;       eax = -2 : device not registered for uMMIO service
398
;       eax = -3 : user heap initialization failure
399
;***************************************************************************
400
pci_mmio_init:
1602 art_zh 401
    cmp     bx, mmio_pci_addr
1348 art_zh 402
    jz	    @f
403
    mov     eax,-2
404
    ret
405
@@:
406
    call    init_heap	   ; (if not initialized yet)
407
    or	    eax,eax
408
    jz	    @f
409
    ret
410
@@:
411
    mov     eax,-3
412
    ret
413
 
414
 
415
;***************************************************************************
416
;   Function
1370 art_zh 417
;      pci_mmio_map
1348 art_zh 418
;
419
;   Description
420
;       maps a block of PCI memory to user-accessible linear address
421
;
422
;       WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only!
423
;       The target device address should be set in kernel var mmio_pci_addr
424
;
1602 art_zh 425
;       IN:  ah = BAR#;
426
;       IN: ebx = block size (bytes);
427
;       IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
1348 art_zh 428
;
429
;   Returns eax = MMIO block's linear address in the userspace (if no error)
430
;
431
;
432
;   Error codes
433
;       eax = -1 : user access to PCI blocked,
434
;       eax = -2 : an invalid BAR register referred
435
;       eax = -3 : no i/o space on that BAR
436
;       eax = -4 : a port i/o BAR register referred
437
;       eax = -5 : dynamic userspace allocation problem
438
;***************************************************************************
439
 
440
pci_mmio_map:
441
    and     edx,0x0ffff
1602 art_zh 442
    cmp     ah,6
1353 art_zh 443
    jc     .bar_0_5
444
    jz     .bar_rom
1348 art_zh 445
    mov     eax,-2
446
    ret
1353 art_zh 447
.bar_rom:
448
    mov    ah, 8	; bar6 = Expansion ROM base address
449
.bar_0_5:
1348 art_zh 450
    push    ecx
1602 art_zh 451
    add     ebx, 4095
452
    and     ebx,-4096
453
    push    ebx
454
    mov     bl, ah	; bl = BAR# (0..5), however bl=8 for BAR6
455
    shl     bl, 1
456
    shl     bl, 1
457
    add     bl, 0x10	; now bl = BAR offset in PCI config. space
1354 diamond 458
    mov     ax, mmio_pci_addr
1602 art_zh 459
    mov     bh, al	; bh = dddddfff
460
    mov     al, 2	; al : DW to read
461
    call    pci_read_reg
1348 art_zh 462
    or	    eax, eax
463
    jnz     @f
464
    mov     eax,-3	; empty I/O space
465
    jmp     mmio_ret_fail
466
@@:
467
    test    eax, 1
468
    jz	    @f
469
    mov     eax,-4	; damned ports (not MMIO space)
470
    jmp     mmio_ret_fail
471
@@:
1602 art_zh 472
    pop     ecx 	; ecx = block size, bytes (expanded to whole page)
1348 art_zh 473
    mov     ebx, ecx	; user_alloc destroys eax, ecx, edx, but saves ebx
1602 art_zh 474
    and     eax, 0xFFFFFFF0
1462 art_zh 475
    push    eax 	      ; store MMIO physical address + keep 2DWords in the stack
1348 art_zh 476
    stdcall user_alloc, ecx
1602 art_zh 477
    or	    eax, eax
1348 art_zh 478
    jnz     mmio_map_over
479
    mov     eax,-5	; problem with page allocation
480
 
481
mmio_ret_fail:
482
    pop     ecx
483
    pop     edx
484
    ret
485
 
486
mmio_map_over:
487
    mov     ecx, ebx	; ecx = size (bytes, expanded to whole page)
488
    shr     ecx, 12	; ecx = number of pages
489
    mov     ebx, eax	; ebx = linear address
1602 art_zh 490
    pop     eax 	; eax = MMIO start
491
    pop     edx 	; edx = MMIO shift (pages)
1348 art_zh 492
    shl     edx, 12	; edx = MMIO shift (bytes)
493
    add     eax, edx	; eax = uMMIO physical address
1602 art_zh 494
    or	    eax, PG_SHARED
495
    or	    eax, PG_UW
496
    or	    eax, PG_NOCACHE
1348 art_zh 497
    mov     edi, ebx
498
    call    commit_pages
499
    mov     eax, edi
500
    ret
501
 
502
;***************************************************************************
503
;   Function
1370 art_zh 504
;      pci_mmio_unmap_page
1348 art_zh 505
;
506
;   Description
507
;       unmaps the linear space previously tied to a PCI memory block
508
;
509
;       IN: ebx = linear address of space previously allocated by pci_mmio_map
510
;       returns eax = 1 if successfully unmapped
511
;
512
;   Error codes
513
;       eax = -1 if no user PCI access allowed,
514
;       eax =  0 if unmapping failed
515
;***************************************************************************
516
 
517
pci_mmio_unmap:
1602 art_zh 518
    stdcall user_free, ebx
1348 art_zh 519
    ret
520
 
1354 diamond 521
end if
1348 art_zh 522
 
586 serge 523
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1375 Lrz 524
uglobal
525
align 4
586 serge 526
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
527
pci_emu_dat:	times	30*10 db 0
1375 Lrz 528
endg
586 serge 529
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
530
align 4
531
sys_pcibios:
594 diamond 532
	cmp	[pci_access_enabled], 1
1348 art_zh 533
	jne	.unsupported_func
534
	cmp	[pci_bios_entry], 0
594 diamond 535
	jz	.emulate_bios
586 serge 536
 
1348 art_zh 537
	push	ds
538
	mov	ax, pci_data_sel
539
	mov	ds, ax
540
	mov	eax, ebp
541
	mov	ah, 0B1h
542
	call	pword [cs:pci_bios_entry]
543
	pop	ds
586 serge 544
 
545
	jmp	.return
546
	;-=-=-=-=-=-=-=-=
547
.emulate_bios:
548
	cmp	ebp, 1			; PCI_FUNCTION_ID
549
	jnz	.not_PCI_BIOS_PRESENT
550
	mov	edx, 'PCI '
1348 art_zh 551
	mov	al, [OS_BASE+0x2F0000 + 0x9020]
552
	mov	bx, [OS_BASE+0x2F0000 + 0x9022]
553
	mov	cl, [OS_BASE+0x2F0000 + 0x9021]
554
	xor	ah, ah
594 diamond 555
	jmp	.return_abcd
586 serge 556
 
557
.not_PCI_BIOS_PRESENT:
558
	cmp	ebp, 2			; FIND_PCI_DEVICE
559
	jne	.not_FIND_PCI_DEVICE
594 diamond 560
	mov	ebx, pci_emu_dat
561
..nxt:	cmp	[ebx], dx
586 serge 562
	jne	..no
594 diamond 563
	cmp	[ebx + 2], cx
586 serge 564
	jne	..no
594 diamond 565
	dec	si
586 serge 566
	jns	..no
594 diamond 567
	mov	bx, [ebx + 4]
1348 art_zh 568
	xor	ah, ah
594 diamond 569
	jmp	.return_ab
570
..no:	cmp	word[ebx], 0
586 serge 571
	je	..dev_not_found
594 diamond 572
	add	ebx, 10
586 serge 573
	jmp	..nxt
574
..dev_not_found:
575
	mov	ah, 0x86		; DEVICE_NOT_FOUND
594 diamond 576
	jmp	.return_a
586 serge 577
 
578
.not_FIND_PCI_DEVICE:
579
	cmp	ebp, 3			; FIND_PCI_CLASS_CODE
580
	jne	.not_FIND_PCI_CLASS_CODE
581
	mov	esi, pci_emu_dat
594 diamond 582
	shl	ecx, 8
1348 art_zh 583
..nxt2: cmp	[esi], ecx
586 serge 584
	jne	..no2
585
	mov	bx, [esi]
1348 art_zh 586
	xor	ah, ah
594 diamond 587
	jmp	.return_ab
586 serge 588
..no2:	cmp	dword[esi], 0
594 diamond 589
	je	..dev_not_found
586 serge 590
	add	esi, 10
591
	jmp	..nxt2
592
 
593
.not_FIND_PCI_CLASS_CODE:
594
	cmp	ebp, 8			; READ_CONFIG_*
595
	jb	.not_READ_CONFIG
596
	cmp	ebp, 0x0A
597
	ja	.not_READ_CONFIG
1602 art_zh 598
	mov	eax, ebp
599
	mov	ah, bh
600
	mov	edx, edi
601
	mov	bh, bl
602
	mov	bl, dl
603
	call	pci_read_reg
604
	mov	ecx, eax
586 serge 605
	xor	ah, ah			; SUCCESSFUL
594 diamond 606
	jmp	.return_abc
586 serge 607
.not_READ_CONFIG:
608
	cmp	ebp, 0x0B		; WRITE_CONFIG_*
609
	jb	.not_WRITE_CONFIG
610
	cmp	ebp, 0x0D
611
	ja	.not_WRITE_CONFIG
1348 art_zh 612
	lea	eax, [ebp+1]
1602 art_zh 613
	mov	ah, bh
614
	mov	edx, edi
615
	mov	bh, bl
616
	mov	bl, dl
586 serge 617
	call	pci_write_reg
618
	xor	ah, ah			; SUCCESSFUL
594 diamond 619
	jmp	.return_abc
586 serge 620
.not_WRITE_CONFIG:
621
.unsupported_func:
622
	mov	ah, 0x81		; FUNC_NOT_SUPPORTED
1375 Lrz 623
.return:mov	dword[esp + 4 ], edi
624
	mov	dword[esp + 8], esi
594 diamond 625
.return_abcd:
1375 Lrz 626
	mov	dword[esp + 24], edx
594 diamond 627
.return_abc:
1375 Lrz 628
	mov	dword[esp + 28], ecx
594 diamond 629
.return_ab:
1375 Lrz 630
	mov	dword[esp + 20], ebx
594 diamond 631
.return_a:
1375 Lrz 632
	mov	dword[esp + 32], eax
586 serge 633
	ret