⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbios.c

📁 如题:POLAR LPC23XX-EK_DEMO software_Keil
💻 C
📖 第 1 页 / 共 3 页
字号:

	stack = IoGetNextIrpStackLocation(Irp);
	stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
	stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
	stack->Parameters.Others.Argument1 = urb;

	// This IRP might have been cancelled the last time it was used, in which case
	// the cancel flag will still be on. Clear it to prevent USBD from thinking that it's
	// been cancelled again! A better way to do this would be to call IoReuseIrp,
	// but that function is not declared in WDM.H.

	Irp->Cancel = FALSE;

//	UsbCom_IncrementIoCount(Extension->DeviceObject); //henry
//	DbgPrint("Exit StartWriteUrb()\n");

	return IoCallDriver(Extension->TopOfStackDeviceObject, Irp);
}							// StartInterruptUrb


NTSTATUS
OnWriteInterrupt(
	PDEVICE_OBJECT junk,
	PIRP Irp,
	PDEVICE_EXTENSION Extension
	)
{							// OnInterrupt
    PURB Urb;
	KIRQL oldirql;
//	KeAcquireSpinLock(&Extension->polllock, &oldirql);
	Extension->writepending = FALSE;		// allow another write to be started
//	PVOID powercontext = Extension->powercontext;
//	Extension->powercontext = NULL;
//	KeReleaseSpinLock(&Extension->polllock, oldirql);

	// If the poll completed successfully, do whatever it is we do when we
	// get an interrupt (in this sample, that's answering an IOCTL) and
	// reissue the read. We're trying to have a read outstanding on the
	// interrupt pipe all the time except when power is off.

    Urb = Extension->WritingUrb;

    DbgPrint("WriteInterrupt_Routine: DO=%08x Irp=%08x TransferLength=%d, Urb Status=%x, Irp Status = %x\n",
        Extension->DeviceObject,
        Irp,
        Urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
        Urb->UrbHeader.Status, 
        Irp->IoStatus.Status);


	if (NT_SUCCESS(Irp->IoStatus.Status)) {		// device signalled an interrupt

//		if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
//			TransferData(Extension, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
		TransmitData(Extension);
//		DbgPrint("Submitting the next read URB\n");
		// Unless we're in the middle of a power-off sequence, reissue the
		// polling IRP. Normally, SaveContext would have tried to cancel the
		// IRP, and we won't get to this statement because STATUS_CANCELLED
		// will fail the NT_SUCCESS test. We don't have any guarantee that the
		// IRP will actually complete with STATUS_CANCELLED, though. Hence this test.
		
//		if (!powercontext)
//			StartReadUrb(Extension); // issue next polling request
	}						// device signalled an interrupt
#if DBG	
	else {
		DbgPrint(" - Write polling IRP %X failed - %X (USBD status %X)\n",
			Irp, Irp->IoStatus.Status, URB_STATUS(Extension->WritingUrb));
	}
#endif

//	UsbCom_DecrementIoCount(Extension->DeviceObject); //henry

	// If we cancelled the poll during a power-down sequence, notify our
	// power management code that it can continue.
/*
	if (powercontext)
		GenericSaveRestoreComplete(powercontext);

	IoReleaseRemoveLock(&Extension->RemoveLock, Irp); // balances acquisition in StartInterruptUrb
*/
	return STATUS_MORE_PROCESSING_REQUIRED;
}							// OnInterrupt


VOID
TransmitData(
	IN PDEVICE_EXTENSION Extension
	)
{

    Extension->HoldingEmpty = TRUE;

    if (Extension->WriteLength ||
        Extension->TransmitImmediate ||
        Extension->SendXoffChar ||
        Extension->SendXonChar) {

        //
        // Even though all of the characters being
        // sent haven't all been sent, this variable
        // will be checked when the transmit queue is
        // empty.  If it is still true and there is a
        // wait on the transmit queue being empty then
        // we know we finished transmitting all characters
        // following the initiation of the wait since
        // the code that initiates the wait will set
        // this variable to false.
        //
        // One reason it could be false is that
        // the writes were cancelled before they
        // actually started, or that the writes
        // failed due to timeouts.  This variable
        // basically says a character was written
        // by the isr at some point following the
        // initiation of the wait.
        //

        Extension->EmptiedTransmit = TRUE;

        //
        // If we have output flow control based on
        // the modem status lines, then we have to do
        // all the modem work before we output each
        // character. (Otherwise we might miss a
        // status line change.)
        //

        if (Extension->HandFlow.ControlHandShake &
            SERIAL_OUT_HANDSHAKEMASK) {

            SerialHandleModemUpdate(
                Extension,
                TRUE
                );

        }

        //
        // We can only send the xon character if
        // the only reason we are holding is because
        // of the xoff.  (Hardware flow control or
        // sending break preclude putting a new character
        // on the wire.)
        //

        if (Extension->SendXonChar &&
            !(Extension->TXHolding & ~SERIAL_TX_XOFF)) {

            if ((Extension->HandFlow.FlowReplace &
                 SERIAL_RTS_MASK) ==
                 SERIAL_TRANSMIT_TOGGLE) {

                //
                // We have to raise if we're sending
                // this character.
                //

                SerialSetRTS(Extension);

                Extension->PerfStats.TransmittedCount++;
                Extension->WmiPerfData.TransmittedCount++;
/*                WRITE_TRANSMIT_HOLDING(
                    Extension->Controller,
                    Extension->SpecialChars.XonChar
                    );
*/

                SerialInsertQueueDpc(
                    &Extension->StartTimerLowerRTSDpc,
                    NULL,
                    NULL,
                    Extension
                    )?Extension->CountOfTryingToLowerRTS++:0;


            } else {

                Extension->PerfStats.TransmittedCount++;
                Extension->WmiPerfData.TransmittedCount++;
/*                WRITE_TRANSMIT_HOLDING(
                    Extension->Controller,
                    Extension->SpecialChars.XonChar
                    );
*/
            }


            Extension->SendXonChar = FALSE;
            Extension->HoldingEmpty = FALSE;

            //
            // If we send an xon, by definition we
            // can't be holding by Xoff.
            //

            Extension->TXHolding &= ~SERIAL_TX_XOFF;

            //
            // If we are sending an xon char then
            // by definition we can't be "holding"
            // up reception by Xoff.
            //

            Extension->RXHolding &= ~SERIAL_RX_XOFF;

        } else if (Extension->SendXoffChar &&
              !Extension->TXHolding) {

            if ((Extension->HandFlow.FlowReplace &
                 SERIAL_RTS_MASK) ==
                 SERIAL_TRANSMIT_TOGGLE) {

                //
                // We have to raise if we're sending
                // this character.
                //

                SerialSetRTS(Extension);

                Extension->PerfStats.TransmittedCount++;
                Extension->WmiPerfData.TransmittedCount++;
/*                WRITE_TRANSMIT_HOLDING(
                    Extension->Controller,
                    Extension->SpecialChars.XoffChar
                    );
*/

                SerialInsertQueueDpc(
                    &Extension->StartTimerLowerRTSDpc,
                    NULL,
                    NULL,
                    Extension
                    )?Extension->CountOfTryingToLowerRTS++:0;

            } else {

                Extension->PerfStats.TransmittedCount++;
                Extension->WmiPerfData.TransmittedCount++;
/*                WRITE_TRANSMIT_HOLDING(
                    Extension->Controller,
                    Extension->SpecialChars.XoffChar
                    );
*/
            }

            //
            // We can't be sending an Xoff character
            // if the transmission is already held
            // up because of Xoff.  Therefore, if we
            // are holding then we can't send the char.
            //

            //
            // If the application has set xoff continue
            // mode then we don't actually stop sending
            // characters if we send an xoff to the other
            // side.
            //

            if (!(Extension->HandFlow.FlowReplace &
                  SERIAL_XOFF_CONTINUE)) {

                Extension->TXHolding |= SERIAL_TX_XOFF;

                if ((Extension->HandFlow.FlowReplace &
                     SERIAL_RTS_MASK) ==
                     SERIAL_TRANSMIT_TOGGLE) {

                    SerialInsertQueueDpc(
                        &Extension->StartTimerLowerRTSDpc,
                        NULL,
                        NULL,
                        Extension
                        )?Extension->CountOfTryingToLowerRTS++:0;

                }

            }

            Extension->SendXoffChar = FALSE;
            Extension->HoldingEmpty = FALSE;

        //
        // Even if transmission is being held
        // up, we should still transmit an immediate
        // character if all that is holding us
        // up is xon/xoff (OS/2 rules).
        //

        } else if (Extension->TransmitImmediate &&
            (!Extension->TXHolding ||
             (Extension->TXHolding == SERIAL_TX_XOFF)
            )) {

            Extension->TransmitImmediate = FALSE;

            if ((Extension->HandFlow.FlowReplace &
                 SERIAL_RTS_MASK) ==
                 SERIAL_TRANSMIT_TOGGLE) {

                //
                // We have to raise if we're sending
                // this character.
                //

                SerialSetRTS(Extension);

                Extension->PerfStats.TransmittedCount++;
                Extension->WmiPerfData.TransmittedCount++;
/*                WRITE_TRANSMIT_HOLDING(
                    Extension->Controller,
                    Extension->ImmediateChar
                    );
*/

                SerialInsertQueueDpc(
                    &Extension->StartTimerLowerRTSDpc,
                    NULL,
                    NULL,
                    Extension
                    )?Extension->CountOfTryingToLowerRTS++:0;

            } else {

                Extension->PerfStats.TransmittedCount++;
                Extension->WmiPerfData.TransmittedCount++;

/*                WRITE_TRANSMIT_HOLDING(
                    Extension->Controller,
                    Extension->ImmediateChar
                    );
*/
            }

            Extension->HoldingEmpty = FALSE;

            SerialInsertQueueDpc(
                &Extension->CompleteImmediateDpc,
                NULL,
                NULL,
                Extension
                );

        } else if (!Extension->TXHolding) {

            ULONG amountToWrite;
/*
            if (Extension->FifoPresent) {

                amountToWrite = (Extension->TxFifoAmount <
                                 Extension->WriteLength)?
                                Extension->TxFifoAmount:
                                Extension->WriteLength;

            } else {

                amountToWrite = 1;

            }
*/
                amountToWrite = (OutPipeMaxSize <
                                 Extension->WriteLength)?
                                OutPipeMaxSize:
                                Extension->WriteLength;

			Extension->WriteSize = amountToWrite;	// Pass this information to StartWriteUrb.

            if ((Extension->HandFlow.FlowReplace &
                 SERIAL_RTS_MASK) ==
                 SERIAL_TRANSMIT_TOGGLE) {

                //
                // We have to raise if we're sending
                // this character.
                //

                SerialSetRTS(Extension);

                if (amountToWrite == 1) {

                    Extension->PerfStats.TransmittedCount++;
                    Extension->WmiPerfData.TransmittedCount++;
/*
                    WRITE_TRANSMIT_HOLDING(
                        Extension->Controller,
                        *(Extension->WriteCurrentChar)
                        );
*/
					StartWriteUrb(Extension);

                } else {

                    Extension->PerfStats.TransmittedCount +=
                        amountToWrite;
                    Extension->WmiPerfData.TransmittedCount +=
                       amountToWrite;
/*
                    WRITE_TRANSMIT_FIFO_HOLDING(
                        Extension->Controller,
                        Extension->WriteCurrentChar,
                        amountToWrite
                        );
*/
					StartWriteUrb(Extension);

                }

                SerialInsertQueueDpc(
                    &Extension->StartTimerLowerRTSDpc,
                    NULL,
                    NULL,
                    Extension
                    )?Extension->CountOfTryingToLowerRTS++:0;

            } else {

                if (amountToWrite == 1) {

                    Extension->PerfStats.TransmittedCount++;
                    Extension->WmiPerfData.TransmittedCount++;
/*
                    WRITE_TRANSMIT_HOLDING(
                        Extension->Controller,
                        *(Extension->WriteCurrentChar)
                        );
*/
					StartWriteUrb(Extension);

                } else {

                    Extension->PerfStats.TransmittedCount +=
                        amountToWrite;
                    Extension->WmiPerfData.TransmittedCount +=
                        amountToWrite;
/*
                    WRITE_TRANSMIT_FIFO_HOLDING(
                        Extension->Controller,
                        Extension->WriteCurrentChar,
                        amountToWrite
                        );
*/
					StartWriteUrb(Extension);

                }

            }

            Extension->HoldingEmpty = FALSE;
            Extension->WriteCurrentChar += amountToWrite;
            Extension->WriteLength -= amountToWrite;
/*
            if (!Extension->WriteLength) {

                PIO_STACK_LOCATION IrpSp;
                //
                // No More characters left.  This
                // write is complete.  Take care
                // when updating the information field,
                // we could have an xoff counter masquerading
                // as a write irp.
                //

                IrpSp = IoGetCurrentIrpStackLocation(
                            Extension->CurrentWriteIrp
                            );

                Extension->CurrentWriteIrp->
                    IoStatus.Information =
                    (IrpSp->MajorFunction == IRP_MJ_WRITE)?
                        (IrpSp->Parameters.Write.Length):
                        (1);

                SerialInsertQueueDpc(
                    &Extension->CompleteWriteDpc,
                    NULL,
                    NULL,
                    Extension
                    );

            }
*/
        }

    } else if (!Extension->WriteLength) {

        PIO_STACK_LOCATION IrpSp;
        //
        // No More characters left.  This
        // write is complete.  Take care
        // when updating the information field,
        // we could have an xoff counter masquerading
        // as a write irp.
        //

        IrpSp = IoGetCurrentIrpStackLocation(
                    Extension->CurrentWriteIrp
                    );

        Extension->CurrentWriteIrp->
            IoStatus.Information =
            (IrpSp->MajorFunction == IRP_MJ_WRITE)?
                (IrpSp->Parameters.Write.Length):
                (1);

        SerialInsertQueueDpc(
            &Extension->CompleteWriteDpc,
            NULL,
            NULL,
            Extension
            );

    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -