📄 driverpn.c
字号:
// Ensure the base address starts as NULL
//
///DevExt->AmccBaseRegisterAddress = NULL;
DevExt->port = 0;
DevExt->irq = 0;
// Try to find chip category from
// IoGetDeviceProperty(DeviceObject,DeviceProperty,BufferLength,PropertyBuffer,ResultLength);
// subfunctions DevicePropertyHardwareID and DevicePropertyLegacyBusType
// ProfiM: HWID : PCI\VEN_1415&DEV_950A&SUBSYS_00001415&REV_00
// ProfiM: HWID : PCI\VEN_1415&DEV_950A&SUBSYS_00001415
// ProfiM: HWID : PCI\VEN_1415&DEV_950A&CC_070006
// ProfiM: HWID : PCI\VEN_1415&DEV_950A&CC_0700
dpHWID_len = 0;
code = IoGetDeviceProperty( DevExt->PhysicalDeviceObject,
DevicePropertyHardwareID,
0,
NULL,
&dpHWID_len );
if ( dpHWID_len )
{
dpHWID = ExAllocatePool( PagedPool, dpHWID_len );
if ( dpHWID == NULL )
return STATUS_INSUFFICIENT_RESOURCES;
code = IoGetDeviceProperty( DevExt->PhysicalDeviceObject,
DevicePropertyHardwareID,
dpHWID_len,
dpHWID,
&dpHWID_len );
if ( !NT_SUCCESS( code ) )
{
#if PnP_DBG
DbgPrint( "ProfiM PnP: IoGetDeviceProperty failed with error 0x%x", code );
#endif
ExFreePool( dpHWID );
return( code );
}
pwc = dpHWID;
while ( *pwc )
{
#if PnP_DBG
PB_DbgPrintL3( "ProfiM PnP: HWID : %ws\n", pwc );
#endif
while ( *pwc )
pwc++;
pwc++;
}
DevExt->PiKRON = FALSE;
if(FindPciHWID(dpHWID,&device_id))
{
ChipOptions=device_id->driver_data;
//#if PnP_DBG
PB_DbgPrintL3("ProfiM PnP: ChipOptions %08X\n", ChipOptions);
//#endif
if (device_id->vendor==0x1760 && device_id->device==0x8004)
DevExt->PiKRON = TRUE; // specialni typ karty pro firmu PiKRON
}
ExFreePool( dpHWID );
}
DevExt->ChipOptions = ChipOptions;
/*
//
// Read values from registry
//
code = IoOpenDeviceRegistryKey( DevExt->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_WRITE,
®KeyHandle );
if ( NT_SUCCESS( code ) )
{
if ( GetRegistryDWord ( regKeyHandle, L"Baud Rate", &Data) )
DevExt->BaudRate = Data;
else
DevExt->BaudRate = DEF_BAUD_RATE;
// if ( GetRegistryDWord ( regKeyHandle, L"Buffer Size", &Data) )
// DevExt->BufferSize = Data;
// else
DevExt->BufferSize = DEF_BUFFER_SIZE;
if ( DevExt->BufferSize < 10 ) DevExt->BufferSize=10;
DbgPrint("ProfiM PnP: Parametry z registru BaduRate=%d BufferSize=%d", DevExt->BaudRate, DevExt->BufferSize);
ZwClose( regKeyHandle );
}
*/
//
// Walk through the partial resource descriptors to find the
// hardware resources that have been allocated to us
//
// We need one range of port addresses (0x08 bytes long) and
// and interrupt resource.
//
for ( index = 0,
prd = &prl->PartialDescriptors[index],
prdTranslated = &prlTranslated->PartialDescriptors[index];
index < prl->Count && NT_SUCCESS( code );
index++, prd++, prdTranslated++ )
{
switch ( prd->Type )
{
case CmResourceTypePort:
//
// Newer AMCC Demo Boards have more than just one BAR
// programmed in the PCI configuration ROM. We want
// the FIRST BAR, which is the base address of the
// device itself. So, we ignore any ports reported to
// us after the first one.
//
///if (DevExt->AmccBaseRegisterAddress) {
if ( DevExt->port )
{
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Ignoring additional port resource ...\n" );
if ( prdTranslated->Type == CmResourceTypePort )
{
PB_DbgPrintL1( "ProfiM PnP: (Translated port 0x%0x)\n",
prdTranslated->u.Port.Start.LowPart );
}
else
{
PB_DbgPrintL1( "ProfiM PnP: (Translated memory 0x%0x)\n",
prdTranslated->u.Memory.Start );
}
#endif
break;
}
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Configuring port resource ...\n" );
#endif
//
// Should only get ONE port resources
//
///ASSERT(DevExt->AmccBaseRegisterAddress == NULL);
//
// Our port space on this card is 0x40 bytes longs
//
///ASSERT(prd->u.Memory.Length == 0x40);
//
// Do the device ports appear in port I/O space or
// in memory space on this machine.
//
if ( prdTranslated->Type == CmResourceTypePort )
{
//
// The port is in port space on this machine. Just
// store away the address
//
///DevExt->MappedPorts = FALSE;
///DevExt->AmccBaseRegisterAddress =
/// (PVOID) prdTranslated->u.Port.Start.LowPart;
DevExt->port = prdTranslated->u.Port.Start.LowPart;
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Translated resource is a port at 0x%0x\n",
DevExt->port );
#endif
}
else
{
ASSERT( prdTranslated->Type == CmResourceTypeMemory );
//
// The port is in memory space on this machine. We
// need to map some virtual addresses over the physical
// address provided us, and remember to do an UNMAP
// if/when we have to return the resources.
//
DevExt->MappedPorts = TRUE;
///DevExt->AmccBaseRegisterAddress =
DevExt->port = ( ULONG )
MmMapIoSpace( prdTranslated->u.Memory.Start,
DEF_PORT_RANGE, /*prdTranslated->u.Memory.Length,*/
MmNonCached );
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Translated resource is MEMORY at 0x%0x\n",
DevExt->port );
#endif
}
break;
case CmResourceTypeInterrupt:
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Configuring Interrupt resource ...\n" );
#endif
//
// Be sure we get only ONE interrupt resource
//
ASSERT( DevExt->irq == 0 );
//
// Again, assume that the translated and raw resources
// are in the same order and number
//
ASSERT( CmResourceTypeInterrupt == prdTranslated->Type );
///DevExt->InterruptLevel = (UCHAR)prdTranslated->u.Interrupt.Level;
///DevExt->InterruptVector = prdTranslated->u.Interrupt.Vector;
///DevExt->InterruptAffinity = prdTranslated->u.Interrupt.Affinity;
DevExt->Irql = ( UCHAR ) prdTranslated->u.Interrupt.Level;
DevExt->irq = prdTranslated->u.Interrupt.Vector;
DevExt->InterruptAffinity = prdTranslated->u.Interrupt.Affinity;
if ( prdTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED )
{
DevExt->InterruptMode = Latched;
//DbgPrint("Profim PnP: ERROR InterruptMode = Latched??? - LevelSensitive EXPECTED!");
}
else
{
DevExt->InterruptMode = LevelSensitive;
}
//
// Because this is a PCI device, we KNOW it must be
// a LevelSensitive Interrupt
//
///ASSERT(DevExt->InterruptMode == LevelSensitive);
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Interrupt level: 0x%0x, Vector: 0x%0x, Affinity: 0x%0x\n",
DevExt->Irql,
DevExt->irq,
DevExt->InterruptAffinity );
#endif
break;
default:
#if PnP_DBG
PB_DbgPrintL1( "ProfiM PnP: Unhandled Resource -- CmResourceType received 0x%x\n",
prd->Type );
#endif
break;
}
}
//
// We NEED the interrupt info AND one port
//
if ( !DevExt->irq || !DevExt->port )
{
DbgPrint( "ProfiM PnP: Port (0x%0lX) or Irq (%d) undefined\n",
DevExt->port,
DevExt->irq );
return STATUS_UNSUCCESSFUL;
}
//
// Register our DPCforISR routine. This is the routine which will
// be used to complete our interrupt processing.
//
///IoInitializeDpcRequest(DevExt->DeviceObject, DpcForIsr);
/*
//**
KeInitializeDpc(&DevExt->bottom_dpc,ProfiM_bottom_dpc,DevExt);
KeInitializeDpc(&DevExt->wd_timer_dpc,ProfiM_wd_dpc,DevExt);
KeInitializeTimer(&DevExt->wd_timer);
*/
// Increase spinlock level
//** if(uL_SpinLock_Irql<DevExt->Irql)
//** uL_SpinLock_Irql=DevExt->Irql;
//** PB_DbgPrintL1("ProfiM PnP: spin lock irql=%d\n",uL_SpinLock_Irql);
DevExt->PortAddress = (PUCHAR) DevExt->port;
DevExt->IRQLine = (KIRQL) DevExt->irq;
KeInitializeDpc(&DevExt->CompleteDPC, ProfiM_CompleteDPC, DevExt);
KeInitializeSpinLock( &(DevExt->InterruptSpinLock) );
//
// Connect to interrupt from the device. After this call,
// interrupts from the device will result in calls to our ProfiM HandleInterrupt
// function.
//
code = IoConnectInterrupt( &DevExt->InterruptObject,
ProfiM_Isr, // ServiceRoutine
DevExt->DeviceObject, // ServiceContext
&(DevExt->InterruptSpinLock), // SpinLock
DevExt->irq, // Vector
DevExt->Irql, // Irql
DevExt->Irql, // SynchronizeIrql
DevExt->InterruptMode, // InterruptMode
TRUE, // ShareVector
DevExt->InterruptAffinity, // ProcessorEnableMask
FALSE ); // FloatingSave
DevExt->InterruptRunning = FALSE; /*DEBUG*/
DevExt->SecondInterrupt = FALSE; /*DEBUG*/
if ( !NT_SUCCESS( code ) )
{
DbgPrint( "ProfiM PnP: IoConnectInterrupt failed with error 0x%x", code );
//
// We're outa here
//
return( code );
}
DbgPrint( "ProfiM PnP: Pouzivane prostredky Port= (0x%0lX) and Irq= (%d)\n",
DevExt->port,
DevExt->irq );
//
// Now we are ready to start ProfiM communication.
//
///ResetAdapter(DevExt->DeviceObject, FALSE);
/*
//**
DevExt->baud_val=(int)ProfiMBaudrate;
DevExt->my_adr=(int)ProfiMMyAddress;
if(DevExt->State==STATE_NEVER_STARTED) {
#if PnP_DBG
DbgPrint("ProfiM PnP: StartDevice: Calling ul_drv_init_ext\n");
#endif
code = ul_drv_init_ext(DevExt, DevExt->port, DevExt->irq,
(int)ProfiMBaudrate, ChipOptions,
0x10000, (int)ProfiMMyAddress);
}else{
#if PnP_DBG
DbgPrint("ProfiM PnP: StartDevice: Calling ul_drv_new_start\n");
#endif
ul_drv_new_init_state(DevExt,(int)ProfiMMyAddress);
if(ul_drv_new_start(DevExt,0x10000)<0)
code = STATUS_INSUFFICIENT_RESOURCES;
else
code = STATUS_SUCCESS;
}
if(!NT_SUCCESS(code)) {
#if PnP_DBG
DbgPrint("ProfiM PnP: StartDevice: Start of hardware failed\n");
#endif
IoDisconnectInterrupt(DevExt->InterruptObject);
DevExt->InterruptObject = NULL;
ul_drv_done_ext(DevExt);
}
*/
PB_DbgPrintL1( "ProfiM PnP: ********* A muzeme jet *************\n" );
//
// Setup the Dpc for ISR routine
//
IoInitializeDpcRequest( DevExt->DeviceObject, ProfiM_Dpc_Routine );
//KeInitializeDpc(&DevExt->bottom_dpc,ProfiM_bottom_dpc,DevExt);
/// Nastaveni priznaku vysilani
DevExt->Sending = FALSE;
// priznak k vymazani vsech casovacich znaku ze zacatku vysilaci fronty
DevExt->FlushTCH = FALSE;
// umozni rozbeh ovladace nez se aktivuje hlidaci rutina watchdogu
DevExt->WatchDogTrigger = 0;
// pocitadlo instanci Handlu pripojenych na ovladac
DevExt->HIDCounter = 1;
#ifdef PISA_IO
DevExt->ModemInterruptState = MI_Disabled;
#endif
DevExt->PB.PhysicalDeviceObject = DevExt->PhysicalDeviceObject;
//
// Initialize the device (enable IRQ's, hit the hardware)
//
Initialize_ProfiM( DevExt, ChipOptions );
RS_DbgPrint( "ProfiM PnP: All initialized!\n" );
PB_DbgPrintL1( "ProfiM PnP: ACR_RX=%x ACR_TX=%x ",
U950PCI_RX_ACR( DevExt ),U950PCI_TX_ACR( DevExt ) );
PB_DbgPrintL1( "ProfiM PnP: MCR_RX=%x MCR_TX=%x ",
U950PCI_RX_MCR( DevExt ),U950PCI_TX_MCR( DevExt ) );
PB_Init( &( DevExt->PB ), DevExt, &PB_RegistryPath );
code = STATUS_SUCCESS;
return code;
}
///////////////////////////////////////////////////////////////////////////////
//
// CanStopDevice
//
// This routine determines if the device cab be safely stopped. In
// our case we'll assume you can always stop the device. A device
// might not be able to be stopped, for example, if it doesn't have
// a queue for incoming requests or if it was notified that it is
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -