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

📄 driverpn.c

📁 profibus-dp主站源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  // 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,
                                  &regKeyHandle );
  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 + -