PLX_TargetDevice.cs
上传用户:huajielb
上传日期:2022-07-29
资源大小:626k
文件大小:9k
源码类别:

驱动编程

开发平台:

Visual C++

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Threading;
  4. using System.Windows.Forms;
  5. using Jungo.wdapi_dotnet;
  6. using wdc_err = Jungo.wdapi_dotnet.WD_ERROR_CODES;
  7. using UINT32 = System.UInt32;
  8. using DWORD = System.UInt32;
  9. using WORD = System.UInt16;
  10. namespace Jungo.plx_lib
  11. {
  12.     /* Run-time registers of PLX target devices (9030, 9050, 9052) */
  13.     public enum PLX_T_REGS 
  14.     {
  15.         /* Local configuration registers */
  16.         PLX_T_LAS0RR = 0x00,      /* Local Addr Space 0 Range */
  17.         PLX_T_LAS1RR = 0x04,      /* Local Addr Space 1 Range */
  18.         PLX_T_LAS2RR = 0x08,      /* Local Addr Space 2 Range */
  19.         PLX_T_LAS3RR = 0x0C,      /* Local Addr Space 3 Range */
  20.         PLX_T_EROMRR = 0x10,      /* Expansion ROM Range */
  21.         PLX_T_LAS0BA = 0x14,      /* Local Addr Space 0 Local BAR (Remap) */
  22.         PLX_T_LAS1BA = 0x18,      /* Local Addr Space 1 Local BAR (Remap) */
  23.         PLX_T_LAS2BA = 0x1C,      /* Local Addr Space 2 Local BAR (Remap) */
  24.         PLX_T_LAS3BA = 0x20,      /* Local Addr Space 3 Local BAR (Remap) */
  25.         PLX_T_EROMBA = 0x24,      /* Expansion ROM Local BAR (Remap) */
  26.         PLX_T_LAS0BRD = 0x28,     /* Local Addr Space 0 Bus Region Descriptors */
  27.         PLX_T_LAS1BRD = 0x2C,     /* Local Addr Space 1 Bus Region Descriptors */
  28.         PLX_T_LAS2BRD = 0x30,     /* Local Addr Space 2 Bus Region Descriptors */
  29.         PLX_T_LAS3BRD = 0x34,     /* Local Addr Space 3 Bus Region Descriptors */
  30.         PLX_T_EROMBRD = 0x38,     /* Expansion ROM Bus Region Descriptors */
  31.         /* Chip select registers */
  32.         PLX_T_CS0BASE = 0x3C,     /* Chip Select 0 Base Address */
  33.         PLX_T_CS1BASE = 0x40,     /* Chip Select 1 Base Address */
  34.         PLX_T_CS2BASE = 0x44,     /* Chip Select 2 Base Address */
  35.         PLX_T_CS3BASE = 0x48,     /* Chip Select 3 Base Address */
  36.         /* Control registers */
  37.         PLX_T_INTCSR = 0x4C,      /* Interrupt Control/Status (16 bit)*/
  38.         PLX_T_PROT_AREA = 0x4E,   /* Serial EEPROM Write-Protected Addr Boundary (16 bit)*/
  39.         PLX_T_CNTRL = 0x50,       /* PCI Target Response; Serial EEPROM; Init Ctr */
  40.         PLX_T_GPIOC = 0x54,       /* General Purpose I/O Control */
  41.         PLX_T_PMDATASEL = 0x70,   /* Hidden 1 Power Management Data Select */
  42.         PLX_T_PMDATASCALE = 0x74  /* Hidden 2 Power Management Data Scale */
  43.     };        
  44.     /* PLX diagnostics interrupt handler function type */
  45.     public delegate void USER_INTERRUPT_TARGET_CALLBACK(PLX_TargetDevice device);
  46.     public class PLX_TargetDevice: PLX_Device
  47.     {
  48.         private USER_INTERRUPT_TARGET_CALLBACK m_userIntHandler;
  49.         private const WORD PLX_TARGET_INT_MASK = (WORD)
  50.                 ( BITS.BIT2  /* LINTi1 Status */ 
  51.                 | BITS.BIT5  /* LINTi2 Status */ 
  52.                 );
  53.         /*constructors*/
  54.         internal protected PLX_TargetDevice(WD_PCI_SLOT slot): this(0, 0, slot, ""){}
  55.         internal protected PLX_TargetDevice(DWORD dwVendorId, DWORD dwDeviceId, 
  56.             WD_PCI_SLOT slot): this(dwVendorId, dwDeviceId, slot, ""){}
  57.         internal protected PLX_TargetDevice(DWORD dwVendorId, DWORD dwDeviceId, 
  58.             WD_PCI_SLOT slot, string sKP_PLX_DRIVER_NAME):
  59.             base(dwVendorId, dwDeviceId, slot, sKP_PLX_DRIVER_NAME)
  60.         {
  61.             m_bIsMaster = false;
  62.             m_dwLASBA = new DWORD[4];
  63.         } 
  64.         protected override void DeviceInit()
  65.         {
  66.             /* NOTE: You can modify the implementation of this function in 
  67.              * order to perform any additional device initialization you
  68.              * require */
  69.             /* Set specific registers infomation */
  70.             m_dwINTCSR = (DWORD)PLX_T_REGS.PLX_T_INTCSR; 
  71.             m_dwCNTRL = (DWORD)PLX_T_REGS.PLX_T_CNTRL;
  72.             m_dwPROT_AREA = (DWORD)PLX_T_REGS.PLX_T_PROT_AREA;
  73.             m_dwLASBA[0] = (DWORD)PLX_T_REGS.PLX_T_LAS0BA;
  74.             m_dwLASBA[1] = (DWORD)PLX_T_REGS.PLX_T_LAS1BA;
  75.             m_dwLASBA[2] = (DWORD)PLX_T_REGS.PLX_T_LAS2BA;
  76.             m_dwLASBA[3] = (DWORD)PLX_T_REGS.PLX_T_LAS3BA;
  77.         }
  78.         public override DWORD CreateIntTransCmds(out WD_TRANSFER[] pIntTransCmds,
  79.                 out DWORD dwNumCmds)
  80.         {
  81.             WDC_ADDR_DESC addrDesc = AddrDesc[PLX_ADDR_REG];
  82.             WORD wINTCSR=0;
  83.             int NUM_TRANS_CMDS_TARGET = 3;
  84.             pIntTransCmds = new WD_TRANSFER[NUM_TRANS_CMDS_TARGET];
  85.             DWORD dwStatus = ReadReg16(m_dwINTCSR, ref wINTCSR);
  86.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  87.             {
  88.                 Log.ErrLog("PLX_TargetDevice.CreateIntTransCmds: Failed reading "
  89.                     + "from the INTCSR register (" + this.ToString(false) + 
  90.                     ")");
  91.                 dwNumCmds = 0;
  92.                 return dwStatus;
  93.             }
  94.             /* Prepare the interrupt transfer commands */
  95.             /* The transfer commands will be executed by WinDriver in the kernel
  96.                for each interrupt that is received */
  97.             byte i = 0;
  98.             byte bIntCsrIndex;
  99.             /* Read status from the INTCSR register */
  100.             pIntTransCmds[i].dwPort = addrDesc.kptAddr + m_dwINTCSR;
  101.             pIntTransCmds[i].cmdTrans = (DWORD)(addrDesc.fIsMemory ? 
  102.                 WD_TRANSFER_CMD.RM_DWORD : WD_TRANSFER_CMD.RP_DWORD);
  103.             bIntCsrIndex = i;
  104.             i++;
  105.             /* Mask interrupt status from the INTCSR register */
  106.             pIntTransCmds[i].cmdTrans = (DWORD)WD_TRANSFER_CMD.CMD_MASK;
  107.             pIntTransCmds[i].Data.Word = PLX_TARGET_INT_MASK;
  108.             i++;
  109.             /* Write to the INTCSR register to clear the interrupt */
  110.             pIntTransCmds[i].dwPort = pIntTransCmds[bIntCsrIndex].dwPort;
  111.             pIntTransCmds[i].cmdTrans = (DWORD)(addrDesc.fIsMemory ?
  112.                 WD_TRANSFER_CMD.WM_WORD : WD_TRANSFER_CMD.WP_WORD);
  113.             pIntTransCmds[i].Data.Word =(WORD)((DWORD)(wINTCSR) & 
  114.                 (DWORD)(~(BITS.BIT8 | BITS.BIT10)));
  115.             i++;
  116.             dwNumCmds = i;
  117.             return dwStatus;
  118.         }
  119.         public DWORD EnableInterrupts(USER_INTERRUPT_TARGET_CALLBACK userIntCb)
  120.         {
  121.             WORD wINTCSR=0;
  122.             
  123.             if(userIntCb == null)
  124.             {
  125.                 Log.TraceLog("PLX_TargetDevice.EnableTargetInterrupts: "
  126.                     + "user callback is invalid");
  127.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  128.             }
  129.             
  130.             m_userIntHandler = userIntCb;
  131.             DWORD dwStatus = base.EnableInterrupts(new INT_HANDLER(IntHandler), 
  132.                 (DWORD)WD_INTERRUPT_OPTIONS.INTERRUPT_CMD_COPY, Handle);
  133.        
  134.             if(dwStatus != (DWORD)wdc_err.WD_STATUS_SUCCESS)
  135.                 goto Error;
  136.             /* Physically enable the interrupts on the board */
  137.             dwStatus = ReadReg16(m_dwINTCSR, ref wINTCSR);
  138.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  139.             {
  140.                 Log.ErrLog("PLX_TargetDevice.EnableInterrupts: Failed reading "
  141.                     + "from the INTCSR register (" + this.ToString(false) + 
  142.                     ")");
  143.                 goto Error;
  144.             }
  145.             dwStatus = WriteReg16(m_dwINTCSR, (WORD)(wINTCSR |
  146.                 (WORD)(BITS.BIT8 | BITS.BIT10)));
  147.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  148.             {
  149.                 Log.ErrLog("PLX_TargetDevice.EnableInterrupts: Faild " +
  150.                     "writing to the INTCSR register to physically enable " +
  151.                     " the interrupts on the board. Error 0x" + 
  152.                     dwStatus.ToString("X") + ": " + utils.Stat2Str(dwStatus)
  153.                     + " (" + this.ToString(false) + ")");
  154.                 goto Error;
  155.             }
  156.             Log.TraceLog("PLX_TargetDevice.EnableInterrupts: enabled interrupts ("
  157.                 + this.ToString(false) + ")");
  158.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  159. Error:
  160.             m_userIntHandler = null;
  161.             return dwStatus;            
  162.         }
  163.         public override void DisableCardInts()
  164.         {
  165.             WORD wINTCSR = 0;
  166.             ReadReg16((DWORD)PLX_T_REGS.PLX_T_INTCSR, ref wINTCSR);
  167.             WriteReg16((DWORD)PLX_T_REGS.PLX_T_INTCSR,
  168.                 (WORD)(wINTCSR & (DWORD)(~(BITS.BIT8 | BITS.BIT10))));
  169.         }
  170.         public void GenerateTargetInterrupt(DWORD addr_space)
  171.         {
  172.             wdc_lib_decl.WDC_WriteAddr16(Handle, addr_space, m_dwINTCSR, 0xc3);
  173.         }
  174.         private void IntHandler(IntPtr pDev)
  175.         {
  176.             wdcDevice.Int =
  177.                 (WD_INTERRUPT)m_wdcDeviceMarshaler.MarshalDevWdInterrupt(pDev);
  178.             /* to obtain the data that was read at interrupt use:
  179.              * WD_TRANSFER[] transCommands;
  180.              * transCommands = (WD_TRANSFER[])m_wdcDeviceMarshaler.MarshalDevpWdTrans(
  181.              *     wdcDevice.Int.Cmd, wdcDevice.Int.dwCmds);
  182.              */
  183.             if(m_userIntHandler != null)
  184.                 m_userIntHandler(this);        
  185.         }
  186.     }
  187. }