📄 profim.c
字号:
#ifndef PISA_IO
//
// Schedule the DPC
//
//RS_DbgPrint ("ISR TX TIMING_CHAR DPC Scheduled\n");
IoRequestDpc( DeviceObject, DeviceObject->CurrentIrp, NULL );
#endif
#ifdef PISA_IO
//
// povoleni preruseni od signalu modemu v DPC
//
if ( DeviceExtension->ModemInterruptState == MI_Disabled )
{
DeviceExtension->MIEnabledTime = GetCurrentTicks();
IoRequestDpc( DeviceObject, DeviceObject->CurrentIrp, NULL );
}
#endif
}
break;
}
//
// Get the current system time
//
//KeQuerySystemTime (&DeviceExtension->LastQuerySystemTime);
break;
//*********************************************************************
// MODEM INTERRUPT
//*********************************************************************
case IIR_MODEM_STATUS_IRQ_PENDING:
// 4th priority interrupt
//RS_DbgPrint ("ProfiM: ISR Modem Status!\n");
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.MSR );
#ifdef PISA_IO
//DbgPrint("Modem ISR - casovy rozdil=%d", (int)(GetCurrentTicks() - DeviceExtension->MIEnabledTime));
if ( ( GetCurrentTicks() - DeviceExtension->MIEnabledTime ) >=
DeviceExtension->PB.Tbit3x )
{
if ( DeviceExtension->ModemInterruptState == MI_Enabled )
IoRequestDpc( DeviceObject, DeviceObject->CurrentIrp, NULL );
}
#endif
break;
default:
break;
}
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.IIR ); // Read the IIR again for the next loop
}
} // 8250 END
//*******************************************************
//
// Return TRUE to signify this was our interrupt and we serviced it.
//
return TRUE;
}
//***************************************************************************
// ProfiM_Dpc_Routine
//
// Description:
// This DPC for ISR is issued by ProfiM_Isr to complete Transmit processing
// by setting the XmitDone event.
//
// Arguments:
// Dpc - not used
// DeviceObject - Pointer to the Device object
// Irp - not used
// Context - not used
//
// Return Value:
// none
//
VOID ProfiM_Dpc_Routine( IN PKDPC Dpc,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context )
{
PPROFIM_DEVICE_EXTENSION DeviceExtension;
UCHAR ch;
if ( !DeviceObject )
{
DbgPrint( "ProfiM: DPC Error - DeviceObject is NULL!" );
return;
}
DeviceExtension = DeviceObject->DeviceExtension;
if ( !DeviceExtension )
{
DbgPrint( "ProfiM: DPC Error - DeviceExtension is NULL!" );
return;
}
if ( DeviceExtension->magic != PROFIM_MAGIC )
{
DbgPrint( "ProfiM: DPC Error - Device Extension MAGIC is invalid!" );
return;
}
#ifdef PISA_IO
if ( DeviceExtension->ModemInterruptState == MI_Disabled )
{
// povoleni preruseni od signalu modemu
//RS_DbgPrint ("ProfiM: povoleni preruseni od modemu\n");
DeviceExtension->ModemInterruptState = MI_Enabled;
ch = ( IER_ENABLE_MODEM_STATUS_IRQ |
IER_ENABLE_RX_DATA_READY_IRQ |
IER_ENABLE_TX_BE_IRQ |
IER_ENABLE_RX_ERROR_IRQ );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.IER, ch );
return;
}
if ( DeviceExtension->ModemInterruptState == MI_Enabled )
{
// zakazani preruseni od modemu
//RS_DbgPrint ("ProfiM: zakazani preruseni od modemu\n");
ch = ( IER_ENABLE_RX_DATA_READY_IRQ |
IER_ENABLE_TX_BE_IRQ |
IER_ENABLE_RX_ERROR_IRQ );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.IER, ch );
DeviceExtension->ModemInterruptState = MI_JustDisabled;
// pokracujeme dale overenim, zda-li je opravdu cely znak vyslan
}
#endif
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// Wait for the entire character to be sent out the UART.
// No waitting if PISA_IO is used (macro PISA_IO defined).
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.LSR );
while ( ( ch & LSR_TX_BOTH_EMPTY ) != LSR_TX_BOTH_EMPTY )
{
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.LSR );
}
if ( DeviceExtension->ActualType == TIMING_CHAR )
PB_TimeTick( &( DeviceExtension->PB ) );
// if ( DeviceExtension->ActualType==SYN_CHAR ) RS_DbgPrint ("DPC - SYN_CHAR - cely znak vyslan... \n");
if ( AllSent( DeviceExtension ) )
{
DeviceExtension->Sending = FALSE;
}
else
{
Jam_First_Out( DeviceExtension );
}
DeviceExtension->FlushTCH = FALSE;
return;
}
//***************************************************************************
//
// DPC routine for completing IRPs
//
//***************************************************************************
VOID ProfiM_CompleteDPC( IN PKDPC Dpc, IN PVOID DeferredContext,
IN PVOID SystemArgument1, IN PVOID SystemArgument2 )
{
PPROFIM_DEVICE_EXTENSION DeviceExtension;
DeviceExtension = SystemArgument1;
if ( !DeviceExtension )
{
DbgPrint( "ProfiM: CompleteDPC Error - DeviceExtension is NULL!" );
return;
}
if ( DeviceExtension->magic != PROFIM_MAGIC )
{
DbgPrint( "ProfiM: CompleteDPC Error - Device Extension MAGIC is invalid!" );
return;
}
//KeSynchronizeExecution( DeviceExtension->InterruptObject,
// ProfiM_CompleteDPC_Synch, DeviceExtension );
ProfiM_CompleteDPC_Synch( DeviceExtension );
}
//***************************************************************************
BOOLEAN ProfiM_CompleteDPC_Synch( IN PPROFIM_DEVICE_EXTENSION DeviceExtension )
{
PTResultBuffer ResB;
int First;
ULONG Length = sizeof( fdl_rb );
fdl_rb * rb;
int HID;
PIRP Irp;
ULONG IrpBuffLength = 0;
PIO_STACK_LOCATION irpStack;
int i;
if ( !DeviceExtension ) {
DbgPrint( "ProfiM: CompleteDPC_Synch Error - DeviceExtension is NULL!" );
return FALSE;
}
ResB = &( DeviceExtension->PB.ResB );
First = ResB->First;
if (First<0 || First>=RS_BUFFER_SIZE) {
DbgPrint( "ProfiM: CompleteDPC_Synch Error - index First out of range!" );
return FALSE;
}
while ( ResB->Last != First )
{
rb = &( ResB->Buffer[First] );
HID = ReadHIDfromRB( rb );
Irp = IrpB_GetFirstIrp( & DeviceExtension->IrpB, HID );
if ( Irp )
{
IrpB_DeleteFirstIrp( & DeviceExtension->IrpB, HID );
irpStack = IoGetCurrentIrpStackLocation( Irp );
if ( irpStack )
IrpBuffLength = irpStack -> Parameters.DeviceIoControl.OutputBufferLength;
if ( Irp->AssociatedIrp.SystemBuffer && IrpBuffLength >= Length )
RtlMoveMemory( Irp->AssociatedIrp.SystemBuffer, rb, Length );
else
DbgPrint("ProfiM: CompleteDPC Error SystemBuffer size if only %dB !!!", IrpBuffLength);
Irp->IoStatus.Information = Length; // Set the number of bytes actually read
if (Irp->IoStatus.Status != STATUS_PENDING) {
DbgPrint("ProfiM: IRP for completion is not PENDING!");
return FALSE;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
ResB_DeleteByHID( &( DeviceExtension->PB.ResB ), HID );
IoCompleteRequest( Irp, IO_NO_INCREMENT );
PB_DbgPrintL2( "ProfiM: PENDING pozadavek IRP=%u pro HID=%d completed...",
( int ) Irp,
HID );
}
else
{
First++;
if ( First >= RS_BUFFER_SIZE )
First = 0;
}
}
return TRUE;
}
//***************************************************************************
//
//
// Routine Description:
//
// Process the IRPs sent to this device.
//
// Arguments:
//
// DeviceObject - pointer to a device object
//
// Irp - pointer to an I/O Request Packet
//
// Return Value:
//
//
NTSTATUS DispatchRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PIO_STACK_LOCATION irpStack;
PPROFIM_DEVICE_EXTENSION deviceExtension;
PVOID ioBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG ioControlCode;
NTSTATUS ntStatus;
int MID;
PIRP DelIrp;
KIRQL OldIrql;
//LARGE_INTEGER CurrentSystemTime;
//LARGE_INTEGER ElapsedTime;
if ( !Irp )
{
DbgPrint( "ProfiM: DispatchRoutine Error - Irp is NULL!" );
return STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation( Irp );
if ( !irpStack )
{
DbgPrint( "ProfiM: DispatchRoutine Error - irpStack is NULL!" );
return STATUS_UNSUCCESSFUL;
}
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
if ( !deviceExtension )
{
DbgPrint( "ProfiM: DispatchRoutine Error - DeviceExtension is NULL!" );
return STATUS_UNSUCCESSFUL;
}
if ( deviceExtension->magic != PROFIM_MAGIC )
{
DbgPrint( "ProfiM: DispatchRoutine Error - Device Extension MAGIC is invalid!" );
return STATUS_UNSUCCESSFUL;
}
deviceExtension->CompleteIrp = TRUE;
//
// Get the pointer to the input/output buffer and it's length
//
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch ( irpStack->MajorFunction )
{
case IRP_MJ_CREATE:
{
DbgPrint( "ProfiM: IRP_MJ_CREATE (HID=%d)\n",
deviceExtension->HIDCounter );
if ( irpStack->FileObject ) // FileObject nemusi byt vzdy platny (napriklad u PnP dotazu v inicializaci)
{
if ( irpStack->FileObject->FsContext )
DbgPrint( "ProfiM: ERROR - FsContext already in use.\n" );
//
// Prirazeni identifikacniho cislo oteviranemu Handle. FsContext
// je urcen pro obecne pouziti ovladacem.
//
else
irpStack->FileObject->FsContext = ( void * )
deviceExtension->HIDCounter;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -