📄 isr.cod
字号:
; 298 :
; 299 : if (statusRegister & 0x10) {
0003d f6 d0 not al
0003f 0f b6 c0 movzx eax, al
00042 74 0a je SHORT $L14869
00044 83 e0 10 and eax, 16 ; 00000010H
00047 0c 40 or al, 64 ; 00000040H
00049 c1 e8 04 shr eax, 4
; 300 :
; 301 : whichPort = 4;
; 302 :
; 303 : } else {
; 304 :
; 305 : whichPort = 5;
; 306 :
; 307 : }
; 308 :
; 309 : } else {
0004c eb 05 jmp SHORT $L14873
$L14869:
; 310 :
; 311 : if (statusRegister & 0x40) {
0004e c1 e8 06 shr eax, 6
00051 0c 06 or al, 6
$L14873:
; 312 :
; 313 : whichPort = 6;
; 314 :
; 315 : } else {
; 316 :
; 317 : whichPort = 7;
; 318 :
; 319 : }
; 320 :
; 321 : }
; 322 :
; 323 : }
; 324 :
; 325 : if (dispatch->Extensions[whichPort]) {
00053 8b 44 86 04 mov eax, DWORD PTR [esi+eax*4+4]
00057 85 c0 test eax, eax
00059 74 af je SHORT $L14856
; 326 :
; 327 : if (SerialISR(
; 328 : InterruptObject,
; 329 : dispatch->Extensions[whichPort]
; 330 : )) {
0005b 50 push eax
0005c ff 75 08 push DWORD PTR _InterruptObject$[ebp]
0005f e8 00 00 00 00 call _SerialISR@8
00064 84 c0 test al, al
00066 74 a2 je SHORT $L14856
; 331 :
; 332 : servicedAnInterrupt = TRUE;
00068 b3 01 mov bl, 1
; 333 :
; 334 : }
; 335 :
; 336 : }
; 337 :
; 338 : }
; 339 :
; 340 : } while (statusRegister);
0006a eb 9e jmp SHORT $L14856
$L15258:
; 341 :
; 342 : return servicedAnInterrupt;
0006c 8a c3 mov al, bl
0006e 5e pop esi
0006f 5b pop ebx
; 343 :
; 344 : }
00070 5d pop ebp
00071 c2 08 00 ret 8
_SerialBitMappedMultiportIsr@8 ENDP
_TEXT ENDS
PUBLIC _SerialProcessLSR@4
PUBLIC _SerialPutChar@8
EXTRN __imp__KeInsertQueueDpc@12:NEAR
EXTRN __imp__WRITE_PORT_UCHAR@8:NEAR
EXTRN __imp__WRITE_PORT_BUFFER_UCHAR@12:NEAR
EXTRN __imp_@InterlockedIncrement@4:NEAR
EXTRN __imp_@InterlockedDecrement@4:NEAR
EXTRN __imp__RtlAssert@16:NEAR
EXTRN _SerialInsertQueueDpc@16:NEAR
EXTRN _SerialDebugLogEntry@20:NEAR
EXTRN _SerialSetRTS@4:NEAR
EXTRN _SerialHandleModemUpdate@8:NEAR
; COMDAT _SerialISR@8
_TEXT SEGMENT
$SG14911 DB 'f:\w2ddk\src\kernel\serial\isr.c', 00H
ORG $+3
$SG14912 DB 'FALSE', 00H
; Function compile flags: /Ogs
_Context$ = 12
_ServicedAnInterrupt$ = 15
_ReceivedChar$14924 = -4
_SerialISR@8 PROC NEAR ; COMDAT
; 377 : {
0002a 55 push ebp
0002b 8b ec mov ebp, esp
0002d 51 push ecx
0002e 53 push ebx
0002f 56 push esi
; 378 :
; 379 : //
; 380 : // Holds the information specific to handling this device.
; 381 : //
; 382 : PSERIAL_DEVICE_EXTENSION Extension = Context;
00030 8b 75 0c mov esi, DWORD PTR _Context$[ebp]
00033 57 push edi
; 383 :
; 384 : //
; 385 : // Holds the contents of the interrupt identification record.
; 386 : // A low bit of zero in this register indicates that there is
; 387 : // an interrupt pending on this device.
; 388 : //
; 389 : UCHAR InterruptIdReg;
; 390 :
; 391 : //
; 392 : // Will hold whether we've serviced any interrupt causes in this
; 393 : // routine.
; 394 : //
; 395 : BOOLEAN ServicedAnInterrupt;
; 396 :
; 397 : UCHAR tempLSR;
; 398 :
; 399 : UNREFERENCED_PARAMETER(InterruptObject);
; 400 :
; 401 : //
; 402 : // Make sure we have an interrupt pending. If we do then
; 403 : // we need to make sure that the device is open. If the
; 404 : // device isn't open or powered down then quiet the device. Note that
; 405 : // if the device isn't opened when we enter this routine
; 406 : // it can't open while we're in it.
; 407 : //
; 408 :
; 409 : InterruptIdReg = READ_INTERRUPT_ID_REG(Extension->Controller);
00034 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
0003a 40 inc eax
0003b 40 inc eax
0003c 50 push eax
0003d ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
; 410 :
; 411 : //
; 412 : // Apply lock so if close happens concurrently we don't miss the DPC
; 413 : // queueing
; 414 : //
; 415 :
; 416 : InterlockedIncrement(&Extension->DpcCount);
00043 8d be 30 06 00
00 lea edi, DWORD PTR [esi+1584]
00049 8a d8 mov bl, al
0004b 8b cf mov ecx, edi
0004d ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedIncrement@4
; 417 : LOGENTRY(LOG_CNT, 'DpI3', 0, Extension->DpcCount, 0);
00053 6a 00 push 0
00055 ff 37 push DWORD PTR [edi]
00057 6a 00 push 0
00059 68 33 49 70 44 push 1148209459 ; 44704933H
0005e 6a 02 push 2
00060 e8 00 00 00 00 call _SerialDebugLogEntry@20
; 418 :
; 419 : if ((InterruptIdReg & SERIAL_IIR_NO_INTERRUPT_PENDING)) {
00065 f6 c3 01 test bl, 1
00068 74 09 je SHORT $L14890
; 420 :
; 421 : ServicedAnInterrupt = FALSE;
0006a 80 65 0f 00 and BYTE PTR _ServicedAnInterrupt$[ebp], 0
; 422 :
; 423 : } else if (!Extension->DeviceIsOpened
0006e e9 e3 05 00 00 jmp $L15291
$L14890:
; 424 : || (Extension->PowerState != PowerDeviceD0)) {
00073 80 be 9d 01 00
00 00 cmp BYTE PTR [esi+413], 0
0007a 0f 84 60 05 00
00 je $L14893
00080 83 be a4 04 00
00 01 cmp DWORD PTR [esi+1188], 1
00087 0f 85 53 05 00
00 jne $L14893
; 489 : } else {
; 490 :
; 491 : ServicedAnInterrupt = TRUE;
0008d c6 45 0f 01 mov BYTE PTR _ServicedAnInterrupt$[ebp], 1
$L15303:
00091 8b 3d 00 00 00
00 mov edi, DWORD PTR __imp__WRITE_PORT_UCHAR@8
; 492 : do {
; 493 :
; 494 : //
; 495 : // We only care about bits that can denote an interrupt.
; 496 : //
; 497 :
; 498 : InterruptIdReg &= SERIAL_IIR_RLS | SERIAL_IIR_RDA |
; 499 : SERIAL_IIR_CTI | SERIAL_IIR_THR |
; 500 : SERIAL_IIR_MS;
00097 83 e3 0e and ebx, 14 ; 0000000eH
; 501 :
; 502 : //
; 503 : // We have an interrupt. We look for interrupt causes
; 504 : // in priority order. The presence of a higher interrupt
; 505 : // will mask out causes of a lower priority. When we service
; 506 : // and quiet a higher priority interrupt we then need to check
; 507 : // the interrupt causes to see if a new interrupt cause is
; 508 : // present.
; 509 : //
; 510 :
; 511 : switch (InterruptIdReg) {
0009a 83 eb 00 sub ebx, 0
0009d 0f 84 6b 01 00
00 je $L15061
000a3 4b dec ebx
000a4 4b dec ebx
000a5 0f 84 bc 01 00
00 je $doTrasmitStuff$14959
000ab 4b dec ebx
000ac 4b dec ebx
000ad 74 17 je SHORT $L14925
000af 4b dec ebx
000b0 4b dec ebx
000b1 74 08 je SHORT $L14922
000b3 83 eb 06 sub ebx, 6
000b6 e9 4b 01 00 00 jmp $L15312
$L14922:
; 512 :
; 513 : case SERIAL_IIR_RLS: {
; 514 :
; 515 : SerialProcessLSR(Extension);
000bb 56 push esi
000bc e8 00 00 00 00 call _SerialProcessLSR@4
; 516 :
; 517 : break;
000c1 e9 50 01 00 00 jmp $L14916
$L14925:
; 518 :
; 519 : }
; 520 :
; 521 : case SERIAL_IIR_RDA:
; 522 : case SERIAL_IIR_CTI:
; 523 :
; 524 : {
; 525 :
; 526 : //
; 527 : // Reading the receive buffer will quiet this interrupt.
; 528 : //
; 529 : // It may also reveal a new interrupt cause.
; 530 : //
; 531 : UCHAR ReceivedChar;
; 532 :
; 533 : do {
; 534 :
; 535 : ReceivedChar =
; 536 : READ_RECEIVE_BUFFER(Extension->Controller);
000c6 ff b6 98 00 00
00 push DWORD PTR [esi+152]
000cc ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
; 537 : Extension->PerfStats.ReceivedCount++;
000d2 ff 86 84 01 00
00 inc DWORD PTR [esi+388]
; 538 : Extension->WmiPerfData.ReceivedCount++;
000d8 ff 86 18 06 00
00 inc DWORD PTR [esi+1560]
000de 8a d8 mov bl, al
; 539 :
; 540 : ReceivedChar &= Extension->ValidDataMask;
000e0 22 9e d9 01 00
00 and bl, BYTE PTR [esi+473]
000e6 88 5d fc mov BYTE PTR _ReceivedChar$14924[ebp], bl
; 541 :
; 542 : if (!ReceivedChar &&
; 543 : (Extension->HandFlow.FlowReplace &
; 544 : SERIAL_NULL_STRIPPING)) {
000e9 75 0d jne SHORT $L14930
000eb f6 86 78 01 00
00 08 test BYTE PTR [esi+376], 8
000f2 0f 85 f5 00 00
00 jne $ReceiveDoLineStatus$14931
$L14930:
; 545 :
; 546 : //
; 547 : // If what we got is a null character
; 548 : // and we're doing null stripping, then
; 549 : // we simply act as if we didn't see it.
; 550 : //
; 551 :
; 552 : goto ReceiveDoLineStatus;
; 553 :
; 554 : }
; 555 :
; 556 : if ((Extension->HandFlow.FlowReplace &
; 557 : SERIAL_AUTO_TRANSMIT) &&
; 558 : ((ReceivedChar ==
; 559 : Extension->SpecialChars.XonChar) ||
; 560 : (ReceivedChar ==
; 561 : Extension->SpecialChars.XoffChar))) {
000f8 8b 86 78 01 00
00 mov eax, DWORD PTR [esi+376]
000fe a8 01 test al, 1
00100 74 68 je SHORT $L14933
00102 3a 9e 70 01 00
00 cmp bl, BYTE PTR [esi+368]
00108 74 08 je SHORT $L14934
0010a 3a 9e 71 01 00
00 cmp bl, BYTE PTR [esi+369]
00110 75 58 jne SHORT $L14933
$L14934:
; 562 :
; 563 : //
; 564 : // No matter what happens this character
; 565 : // will never get seen by the app.
; 566 : //
; 567 :
; 568 : if (ReceivedChar ==
; 569 : Extension->SpecialChars.XoffChar) {
00112 3a 9e 71 01 00
00 cmp bl, BYTE PTR [esi+369]
00118 75 37 jne SHORT $L14935
; 570 :
; 571 : Extension->TXHolding |= SERIAL_TX_XOFF;
0011a 83 8e 1c 01 00
00 08 or DWORD PTR [esi+284], 8
; 572 :
; 573 : if ((Extension->HandFlow.FlowReplace &
; 574 : SERIAL_RTS_MASK) ==
; 575 : SERIAL_TRANSMIT_TOGGLE) {
00121 66 25 c0 00 and ax, 192 ; 000000c0H
00125 3c c0 cmp al, 192 ; 000000c0H
00127 0f 85 c0 00 00
00 jne $ReceiveDoLineStatus$14931
; 576 :
; 577 : SerialInsertQueueDpc(
; 578 : &Extension->StartTimerLowerRTSDpc,
; 579 : NULL,
; 580 : NULL,
; 581 : Extension
; 582 : )?Extension->CountOfTryingToLowerRTS++:0;
0012d 56 push esi
0012e 6a 00 push 0
00130 8d 86 4c 03 00
00 lea eax, DWORD PTR [esi+844]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -