📄 profim.c
字号:
//
#ifdef PnP
NTSTATUS GetPnPConfiguration( IN PPROFIM_DEVICE_EXTENSION DeviceExtension)
{
NTSTATUS status = STATUS_SUCCESS;
int i;
int BR;
HANDLE regKeyHandle;
ULONG Data;
NTSTATUS code;
if ( !DeviceExtension )
{
DbgPrint( "ProfiM: GetConfiguration Error - DeviceExtension is NULL!" );
return STATUS_UNSUCCESSFUL;
}
if ( DeviceExtension->magic != PROFIM_MAGIC )
{
DbgPrint( "ProfiM: GetConfiguration Error - Device Extension MAGIC is invalid!" );
return STATUS_UNSUCCESSFUL;
}
//
// Read values from registry
//
code = IoOpenDeviceRegistryKey( DeviceExtension->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_WRITE,
®KeyHandle );
if ( NT_SUCCESS( code ) )
{
/*
if ( GetRegistryDWord ( regKeyHandle, L"Port Address", &Data) )
DeviceExtension->PortAddress = ( PUCHAR ) Data;
else
DeviceExtension->PortAddress = ( PUCHAR ) DEF_PORT_ADDRESS;
if ( GetRegistryDWord ( regKeyHandle, L"IRQ Line", &Data) )
DeviceExtension->IRQLine = ( KIRQL ) Data;
else
DeviceExtension->IRQLine = ( KIRQL ) DEF_IRQ_LINE;
*/
if ( GetRegistryDWord ( regKeyHandle, L"Baud Rate", &Data) )
DeviceExtension->BaudRate = Data;
else
DeviceExtension->BaudRate = DEF_BAUD_RATE;
/*
if ( GetRegistryDWord ( regKeyHandle, L"Buffer Size", &Data) )
DeviceExtension->BufferSize = Data;
else
*/
DeviceExtension->BufferSize = DEF_BUFFER_SIZE;
ZwClose( regKeyHandle );
}
DbgPrint( "ProfiM: GetPnPConfiguration - BufferSize=%d",
DeviceExtension->BufferSize );
if ( DeviceExtension->BufferSize == 0 )
{
DbgPrint( "ProfiM: Error BufferSize can't be null!" );
return STATUS_UNSUCCESSFUL;
}
DbgPrint( "ProfiM: GetConfiguration - BaudRate=%d",
DeviceExtension->BaudRate );
return status;
}
#endif
//***************************************************************************
// Initialize_ProfiM
//
// Description:
// Initializes all data structures and hardware necessary for
// driver execution
//
// Arguments:
// DeviceExtension - Pointer to the device extension.
//
// Return Value:
// NSTATUS
//
NTSTATUS Initialize_ProfiM( IN PPROFIM_DEVICE_EXTENSION DeviceExtension,
int chip_options )
{
UCHAR ch, Divisor;
NTSTATUS status = STATUS_SUCCESS;
if ( !DeviceExtension )
{
DbgPrint( "ProfiM: Initialize Error - DeviceExtension is NULL!" );
return STATUS_UNSUCCESSFUL;
}
if ( DeviceExtension->magic != PROFIM_MAGIC )
{
DbgPrint( "ProfiM: Initialize Error - Device Extension MAGIC is invalid!" );
return STATUS_UNSUCCESSFUL;
}
if ( DeviceExtension->BufferSize < 10 )
{
DbgPrint("ProfiM: Buffer size was too small or null, set to defalt size.\n");
DeviceExtension->BufferSize = DEF_BUFFER_SIZE;
}
DeviceExtension->XmitBuffer = ExAllocatePool( NonPagedPool,
DeviceExtension->BufferSize );
if ( DeviceExtension->XmitBuffer == NULL )
{
RS_DbgPrint( "ProfiM: ExAllocatePool failed for XmitBuffer\n" );
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
//
// Setup buffer pointers and counts
//
/* DeviceExtension->XmitBufferPosition = DeviceExtension->XmitBuffer;
DeviceExtension->XmitBufferEnd = DeviceExtension->XmitBuffer +
(DeviceExtension->BufferSize - 1);
DeviceExtension->XmitBufferCount = 0;*/
DeviceExtension->XmitFirst = 0;
DeviceExtension->XmitLast = 0;
}
DeviceExtension->XmitTypeBuffer = ExAllocatePool( NonPagedPool,
DeviceExtension->BufferSize );
if ( DeviceExtension->XmitTypeBuffer == NULL )
{
RS_DbgPrint( "ProfiM: ExAllocatePool failed for XmitTypeBuffer\n" );
status = STATUS_INSUFFICIENT_RESOURCES;
}
//
// Clear the interrupt/error Count and get current system time
DeviceExtension->InterruptCount = 0;
DeviceExtension->RcvError = 0;
//KeQuerySystemTime (&DeviceExtension->LastQuerySystemTime);
IrpB_Init( &DeviceExtension->IrpB, DeviceExtension );
DeviceExtension->Buffering = FALSE;
DeviceExtension->ContinueBuffering = FALSE;
//*****************************************************************
//
// HARDWARE INITIALIZATION
//
//*****************************************************************
if( (chip_options&~0xff)==0x16954000 )
{
DbgPrint("ProfiM: ********** 16C954 MODE **********\n");
u950pci_init( DeviceExtension, DeviceExtension->port, DeviceExtension->irq,
DeviceExtension->BaudRate, DeviceExtension->ChipOptions );
u950pci_pinit( DeviceExtension );
}
else
{
DbgPrint("ProfiM: **** xx450 compatibility MODE ****\n");
//
// Initialize all of the xx450 register addresses
//
DeviceExtension->ComPort.RBR = DeviceExtension->PortAddress +
RX_REGISTER_8250;
DeviceExtension->ComPort.TBR = DeviceExtension->PortAddress +
TX_REGISTER_8250;
DeviceExtension->ComPort.IER = DeviceExtension->PortAddress + IER_8250;
DeviceExtension->ComPort.IIR = DeviceExtension->PortAddress + IIR_8250;
DeviceExtension->ComPort.LCR = DeviceExtension->PortAddress + LCR_8250;
DeviceExtension->ComPort.MCR = DeviceExtension->PortAddress + MCR_8250;
DeviceExtension->ComPort.LSR = DeviceExtension->PortAddress + LSR_8250;
DeviceExtension->ComPort.MSR = DeviceExtension->PortAddress + MSR_8250;
DeviceExtension->ComPort.BAUD = DeviceExtension->PortAddress +
DIVISOR_REGISTER_8250;
// DbgPrint( "ProfiM: TBR= %x", DeviceExtension->ComPort.TBR );
//
// Determine the UART divisor value
//
switch ( DeviceExtension->BaudRate )
{
case 1200:
Divisor = BAUD_RATE_DIVISOR_1200;
break;
case 2400:
Divisor = BAUD_RATE_DIVISOR_2400;
break;
case 4800:
Divisor = BAUD_RATE_DIVISOR_4800;
break;
case 9600:
Divisor = BAUD_RATE_DIVISOR_9600;
break;
case 19200:
Divisor = BAUD_RATE_DIVISOR_19200;
break;
case 38400:
Divisor = BAUD_RATE_DIVISOR_38400;
break;
case 57600:
Divisor = BAUD_RATE_DIVISOR_57600;
break;
case 115200:
Divisor = BAUD_RATE_DIVISOR_115200;
break;
default:
Divisor = BAUD_RATE_DIVISOR_9600;
break;
}
//
// Set the baud rate to the divisor value.
//
ch = ( ( READ_PORT_UCHAR( DeviceExtension->ComPort.LCR ) ) |
LCR_ENABLE_DIVISOR_LATCH );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.LCR, ch );
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.LCR );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.BAUD, Divisor );
ch = ( ( READ_PORT_UCHAR( DeviceExtension->ComPort.LCR ) ) & LCR_DISABLE_DIVISOR_LATCH );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.LCR, ch );
//
// The data format = 1 start bit, 8 data bits, 1 stop bit, even parity.
//
ch = ( LCR_EIGHT_BITS_PER_WORD | LCR_ONE_STOP_BIT | LCR_EVEN_PARITY );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.LCR, ch );
//
// Enable all UART interrupts on the IBM PC by asserting the GP02 general
// purpose output. Clear all other MCR bits. Activate DTR for convertor use.
//
ch = MCR_ACTIVATE_GP02 | MCR_ACTIVATE_DTR;
WRITE_PORT_UCHAR( DeviceExtension->ComPort.MCR, ch );
//
// Enable Specific Interrupts
//
ch = ( IER_ENABLE_RX_DATA_READY_IRQ |
IER_ENABLE_TX_BE_IRQ |
IER_ENABLE_RX_ERROR_IRQ );
WRITE_PORT_UCHAR( DeviceExtension->ComPort.IER, ch );
// Uvedeni RTS do pocatecniho stavu
//
// Switch to receive
//
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.MCR ) & MCR_DEACTIVATE_RTS;
WRITE_PORT_UCHAR( DeviceExtension->ComPort.MCR, ch );
//
// Read the UART receive register - neprecteny znak muze branit
// prichodu dalsiho preruseni
//
ch = READ_PORT_UCHAR( DeviceExtension->ComPort.RBR );
}
return status;
}
//***************************************************************************
// ProfiM_Write
//
// Description:
// Called by DispatchRoutine in response to a Write request.
//
// Arguments:
// DeviceExtension - The device extension strtucture
// Irp - The Irp associated with this IO
//
// Return Value:
// NTSTATUS
//
/*NTSTATUS ProfiM_Write( IN PPROFIM_DEVICE_EXTENSION DeviceExtension,
IN PIRP Irp )*/
BOOLEAN ProfiM_Write( IN PPROFIM_DEVICE_EXTENSION DeviceExtension )
{
ULONG Length;
UCHAR ch;
int HID;
PIRP Irp;
Irp = DeviceExtension->TempIrp;
if ( !Irp ) {
DbgPrint( "ProfiM: Read Routine Error - Irp is NULL!" );
return FALSE;
}
Length = IoGetCurrentIrpStackLocation( Irp )->Parameters.Write.Length;
//
// jednoznacna identifikace Handle, pres ktery prisel pozadavek
//
if ( IoGetCurrentIrpStackLocation( Irp )->FileObject )
HID = ( int ) IoGetCurrentIrpStackLocation( Irp )->FileObject->FsContext;
else
DbgPrint( "ProfiM: ERROR in Write - IoGetCurrentIrpStackLocation(Irp)->FileObject is NULL." );
Irp->IoStatus.Information = 0L;
//DbgPrint("ProfiM: Delka bloku pozadavku: %dB (spravna delka %dB)\n",Length, sizeof(fdl_rb) );
//
// Check for a zero length write.
//
if ( Length == sizeof( fdl_rb ) )
{
if ( !ReqB_Full( &( DeviceExtension->PB.ReqB ),
( ( fdl_rb * ) Irp->AssociatedIrp.SystemBuffer )->rb2_header.priority ) )
{
PB_DbgPrintL2( "ProfiM: Prijat pozadavek od aplikace (HID=%d).\n", HID );
StoreHIDinRB( ( fdl_rb * ) Irp->AssociatedIrp.SystemBuffer, HID ); // prirazeni HID k pozadavku RB (aby bylo mozne zjistit, ke kteremu otevrenemu Handle patri)
ReqB_Add( &( DeviceExtension->PB.ReqB ),
( fdl_rb * ) Irp->AssociatedIrp.SystemBuffer );
//DbgPrint("ProfiM: Index v low bufferu: %d\n", DeviceExtension->PB.ReqB.LowLast);
//DbgPrint("ProfiM: Index v high bufferu: %d\n", DeviceExtension->PB.ReqB.HighLast);
//
// Set the number of bytes written
//
Irp->IoStatus.Information = Length;
}
else
{
//
// Error - Request Buffer je plny
//
DbgPrint("ProfiM: Request Buffer je plny!" );
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
}
else
{
//
// Error - jedine pripustne datove bloky pro zapis do ovladace jsou fdl_rb
//
DbgPrint("ProfiM: Spatna delka bloku pozadavku: %dB (spravna delka %dB)\n",Length, sizeof(fdl_rb) );
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
//***************************************************************************
// ProfiM_Read
//
// Description:
// Called by DispatchRoutine in response to a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -