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

驱动编程

开发平台:

Visual C++

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Runtime.CompilerServices;
  4. using System.Windows.Forms;
  5. using System.Data;
  6. using Jungo.wdapi_dotnet;
  7. using wdc_err = Jungo.wdapi_dotnet.WD_ERROR_CODES;
  8. using UINT64 = System.UInt64;
  9. using UINT32 = System.UInt32;
  10. using DWORD = System.UInt32;
  11. using WORD = System.UInt16;
  12. using BYTE = System.Byte;
  13. using BOOL = System.Boolean;
  14. using WDC_DEVICE_HANDLE = System.IntPtr;   
  15. using HANDLE = System.IntPtr;
  16. namespace Jungo.plx_lib
  17. {
  18. #region "PLX header definitions" 
  19.     /* PLX configuration registers */
  20.     public enum PLX_CFG_REGS 
  21.     {
  22.         PLX_PMCAPID = 0x40,   /* Power Management Capability ID */    
  23.         PLX_PMNEXT = 0x41,    /* Power Management Next Capability Pointer */
  24.         PLX_PMCAP = 0x42,     /* Power Management Capabilities Register */
  25.         PLX_PMCSR = 0x44,     /* Power Management Control/Status Register */
  26.         PLX_HS_CAPID = 0x48,  /* Hot Swap Capability ID */
  27.         PLX_HS_NEXT = 0x49,   /* Hot Swap Next Capability Pointer */
  28.         PLX_HS_CSR = 0x4A,    /* Hot Swap Control/Status Register */
  29.         PLX_VPD_CAPID = 0x4C, /* PCI Vital Product Data Capability ID */
  30.         PLX_VPD_NEXT = 0x4D,  /* PCI Vital Product Data Next Capability Pointer */
  31.         PLX_VPD_ADDR = 0x4E,  /* PCI Vital Product Data Address */
  32.         PLX_VPD_DATA = 0x50   /* PCI VPD Data */
  33.     };
  34.     public enum PLX_ADDR
  35.     {
  36.         /*if REG_IO_ACCESS is defines, then the access to the device's
  37.          * registers will be done through the device's IO space BAR1 */
  38. #if REG_IO_ACCESS
  39.         PLX_ADDR_REG = PCI_BARS.AD_PCI_BAR1;
  40. #else
  41.         PLX_ADDR_REG = PCI_BARS.AD_PCI_BAR0,
  42. #endif
  43.         PLX_ADDR_REG_IO = PCI_BARS.AD_PCI_BAR1,
  44.         PLX_ADDR_SPACE0 = PCI_BARS.AD_PCI_BAR2,
  45.         PLX_ADDR_SPACE1 = PCI_BARS.AD_PCI_BAR3,
  46.         PLX_ADDR_SPACE2 = PCI_BARS.AD_PCI_BAR4,
  47.         PLX_ADDR_SPACE3 = PCI_BARS.AD_PCI_BAR5,                
  48.     };
  49. #endregion
  50.     /* PLX diagnostics plug-and-play and power management events handler 
  51.      * function type */
  52.     public delegate void USER_EVENT_CALLBACK(ref WD_EVENT pEvent, PLX_Device dev);
  53.     public abstract class PLX_Device
  54.     {
  55.         protected bool m_bIsMaster;
  56.         private WDC_DEVICE m_wdcDevice = new WDC_DEVICE();
  57.         protected MarshalWdcDevice m_wdcDeviceMarshaler;
  58.         private EEPROM m_EEPROM;
  59.         private USER_EVENT_CALLBACK m_userEventHandler;
  60.         private INT_HANDLER m_intHandler;
  61.         private EVENT_HANDLER_DOTNET m_eventHandler;
  62.         protected string m_sDeviceLongDesc;
  63.         protected string m_sDeviceShortDesc;
  64.         protected const DWORD PLX_ADDR_REG = (DWORD)PLX_ADDR.PLX_ADDR_REG; 
  65.         /* Kernel PlugIn driver name (should be no more than 8 characters) */
  66.         private string m_sKP_PLX_DRIVER_NAME;
  67.         /* offsets of some useful registers */
  68.         internal DWORD m_dwINTCSR;
  69.         internal DWORD m_dwCNTRL;
  70.         internal DWORD m_dwPROT_AREA;
  71.         internal DWORD[] m_dwLASBA;
  72. #region " constructors " 
  73.         /* c'tors */
  74.         internal PLX_Device(WD_PCI_SLOT slot):
  75.             this(0, 0, slot, ""){}
  76.         internal PLX_Device(DWORD dwVendorId, DWORD dwDeviceId, WD_PCI_SLOT slot):
  77.             this(dwVendorId, dwDeviceId, slot, ""){} 
  78.         internal PLX_Device(DWORD dwVendorId, DWORD dwDeviceId, WD_PCI_SLOT slot, string sKP_PLX_DRIVER_NAME)
  79.         {
  80.             m_wdcDevice = new WDC_DEVICE();
  81.             m_wdcDevice.id.pciId.dwVendorId = dwVendorId;
  82.             m_wdcDevice.id.pciId.dwDeviceId = dwDeviceId;
  83.             m_wdcDevice.slot.pciSlot = slot;
  84.             m_wdcDeviceMarshaler = new MarshalWdcDevice();
  85.             m_eventHandler = new EVENT_HANDLER_DOTNET(EventHandler);
  86.             m_sKP_PLX_DRIVER_NAME = sKP_PLX_DRIVER_NAME;
  87.             SetDescription();
  88.         }
  89. #endregion
  90. #region " utilities " 
  91.         /*****************
  92.          *  utilities     *
  93.          * ***************/
  94.         /* public methods */
  95.         public static bool IsMasterDevice(ref WD_PCI_SLOT slot)
  96.         {
  97.             WORD wIsMaster = 0;
  98.             DWORD dwStatus = wdc_lib_decl.WDC_PciReadCfgBySlot16(ref slot,
  99.                 (DWORD)PCI_CFG_REG.PCI_CR, ref wIsMaster);
  100.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  101.             {
  102.                 Log.ErrLog("PLX_Device.IsMasterDevice:Failed reading " +
  103.                     "the vendor ID from the configuration registers. " +
  104.                     "(Physical Location: " + slot.dwBus.ToString("X") + ":" +
  105.                     slot.dwSlot.ToString("X") + ":"
  106.                     + slot.dwFunction.ToString("X") +")");
  107.                 return false; 
  108.             }
  109.             if((wIsMaster & (WORD)BITS.BIT2) != 0)
  110.                 return true;
  111.             else
  112.                 return false;
  113.         }
  114.         public bool IsMaster
  115.         {
  116.             get
  117.             {
  118.                 return m_bIsMaster;
  119.             }                        
  120.         }
  121.         public IntPtr Handle
  122.         {
  123.             get
  124.             {
  125.                 return m_wdcDevice.hDev;
  126.             }
  127.             set
  128.             {
  129.                 m_wdcDevice.hDev = value;
  130.             }
  131.         }
  132.         protected WDC_DEVICE wdcDevice
  133.         {
  134.             get
  135.             {
  136.                 return m_wdcDevice;
  137.             }
  138.             set
  139.             {
  140.                 m_wdcDevice = value;
  141.             }
  142.         }
  143.         public WD_PCI_ID id
  144.         {
  145.             get
  146.             {
  147.                 return m_wdcDevice.id.pciId;
  148.             }
  149.             set
  150.             {
  151.                 m_wdcDevice.id.pciId = value;
  152.             }
  153.         }
  154.         public WD_PCI_SLOT slot
  155.         {
  156.             get
  157.             {
  158.                 return m_wdcDevice.slot.pciSlot;
  159.             }
  160.             set
  161.             {
  162.                 m_wdcDevice.slot.pciSlot = value;
  163.             }
  164.         }
  165.         public WDC_ADDR_DESC[] AddrDesc
  166.         {
  167.             get
  168.             {
  169.                 return m_wdcDevice.pAddrDesc;
  170.             }
  171.             set
  172.             {
  173.                 m_wdcDevice.pAddrDesc = value;
  174.             }
  175.         }
  176.         public string[] AddrDescToString(bool bMemOnly)
  177.         {
  178.             int iFirstSpace = (int)(bMemOnly? PLX_ADDR.PLX_ADDR_SPACE0 : 
  179.                 PLX_ADDR.PLX_ADDR_REG);
  180.             string[] sAddr = new string[AddrDesc.Length - iFirstSpace];
  181.             for (int i = iFirstSpace; i<sAddr.Length + iFirstSpace; ++i)
  182.             {
  183.                 sAddr[i - iFirstSpace] = "BAR " +
  184.                     AddrDesc[i].dwAddrSpace.ToString() + 
  185.                     ((AddrDesc[i].fIsMemory)? " Memory " : " I/O ");
  186.                 if (wdc_lib_decl.WDC_AddrSpaceIsActive(Handle, 
  187.                     AddrDesc[i].dwAddrSpace))
  188.                 {
  189.                     WD_ITEMS item =
  190.                         m_wdcDevice.cardReg.Card.Item[AddrDesc[i].dwItemIndex];
  191.                     UINT64 dwAddr = (UINT64)(AddrDesc[i].fIsMemory?
  192.                         item.I.Mem.dwPhysicalAddr : item.I.IO.dwAddr);
  193.                     sAddr[i - iFirstSpace] += dwAddr.ToString("X") + " - " + 
  194.                         (dwAddr + AddrDesc[i].dwBytes - 1).ToString("X") +
  195.                         " (" + AddrDesc[i].dwBytes.ToString("X") + " bytes)";
  196.                 }
  197.                 else
  198.                     sAddr[i - iFirstSpace] += "Inactive address space";
  199.             }
  200.             return sAddr;
  201.         }
  202.         public  string ToString(BOOL bLong)
  203.         {
  204.             return (bLong)? m_sDeviceLongDesc: m_sDeviceShortDesc;
  205.         }
  206.         public EEPROM EEprom
  207.         {
  208.             get
  209.             {
  210.                 return m_EEPROM;
  211.             }
  212.             set
  213.             {
  214.                 m_EEPROM = value;
  215.             }
  216.         }                
  217.         public bool IsMySlot(ref WD_PCI_SLOT slot)
  218.         {
  219.             if(m_wdcDevice.slot.pciSlot.dwBus == slot.dwBus &&
  220.                 m_wdcDevice.slot.pciSlot.dwSlot == slot.dwSlot &&
  221.                 m_wdcDevice.slot.pciSlot.dwFunction == slot.dwFunction)
  222.                 return true;
  223.             return false;
  224.         }
  225.         /** private methods **/
  226.         protected void SetDescription()
  227.         {
  228.             m_sDeviceLongDesc = string.Format("PLX Device: Vendor ID 0x{0:X}, "
  229.                 + "Device ID 0x{1:X}, Physical Location {2:X}:{3:X}:{4:X}", 
  230.                 id.dwVendorId, id.dwDeviceId, slot.dwBus, slot.dwSlot, 
  231.                 slot.dwFunction);
  232.             m_sDeviceShortDesc = string.Format("Device " +
  233.                 "{0:X},{1:X} {2:X}:{3:X}:{4:X}", id.dwVendorId, 
  234.                 id.dwDeviceId, slot.dwBus, slot.dwSlot, slot.dwFunction);
  235.         }
  236.         private bool DeviceValidate()
  237.         {
  238.             DWORD i, dwNumAddrSpaces = m_wdcDevice.dwNumAddrSpaces;
  239.             /* NOTE: You can modify the implementation of this function in 
  240.              * order to verify that the device has the resources you expect to
  241.              * find */
  242.             /* Verify that the device has at least one active address space */
  243.             for (i = 0; i < dwNumAddrSpaces; i++)
  244.             {
  245.                 if (wdc_lib_decl.WDC_AddrSpaceIsActive(Handle, i))
  246.                     return true;
  247.             }
  248.             Log.ErrLog("PLX_Device.DeviceValidate: Device does not have "
  249.                 + "any active memory or I/O address spaces " + "(" +
  250.                 this.ToString(false) + ")" );
  251.             return false;
  252.         }        
  253. #endregion
  254. #region " Device Open/Close " 
  255.         /****************************
  256.          *  Device Open & Close     *
  257.          * **************************/
  258.         /* public methods */
  259.         public virtual DWORD DeviceOpen()
  260.         {
  261.             DWORD dwStatus;
  262.             WD_PCI_CARD_INFO deviceInfo = new WD_PCI_CARD_INFO();
  263.             /* Retrieve the device's resources information */
  264.             deviceInfo.pciSlot = slot;
  265.             dwStatus = wdc_lib_decl.WDC_PciGetDeviceInfo(deviceInfo);
  266.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  267.             {
  268.                 Log.ErrLog("PLX_Device.Open: Failed retrieving the " 
  269.                     + "device's resources information. Error 0x" + 
  270.                     dwStatus.ToString("X") + ": " + utils.Stat2Str(dwStatus) +
  271.                     "(" + this.ToString(false) +")" );
  272.                 return dwStatus;
  273.             }
  274.             /* NOTE: You can modify the device's resources information here, 
  275.              * if necessary (mainly the deviceInfo.Card.Items array or the
  276.              * items number - deviceInfo.Card.dwItems) in order to register
  277.              * only some of the resources or register only a portion of a
  278.              * specific address space, for example. */
  279.             dwStatus = wdc_lib_decl.WDC_PciDeviceOpen(ref m_wdcDevice,
  280.                 deviceInfo, IntPtr.Zero, IntPtr.Zero, "", IntPtr.Zero);
  281.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  282.             {
  283.                 Log.ErrLog("PLX_Device.DeviceOpen: Failed opening a " +
  284.                     "WDC device handle. Error 0x" + dwStatus.ToString("X") +
  285.                     ": " + utils.Stat2Str(dwStatus) + "(" + 
  286.                     this.ToString(false) + ")");
  287.                 goto Error;
  288.             }
  289.             Log.TraceLog("PLX_Device.DeviceOpen: Opened a PLX device " + 
  290.                 this.ToString(false));
  291.             /* Open a Kernel PlugIn handle to the device */
  292.             if(m_sKP_PLX_DRIVER_NAME != "")
  293.             {
  294.                 dwStatus = wdc_lib_decl.WDC_KernelPlugInOpen(m_wdcDevice, m_sKP_PLX_DRIVER_NAME, 
  295.                     ref wdcDevice.hDev);
  296.                 if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  297.                 {
  298.                     Log.ErrLog("PLX_Device.DeviceOpen: Failed opening a " +
  299.                         "Kernel PlugIn handle to the KP driver. Error 0x" + 
  300.                         dwStatus.ToString("X") + ": " + utils.Stat2Str(dwStatus) + "(" + 
  301.                         this.ToString(false) + ")");                                
  302.                 }
  303.                 else
  304.                 {
  305.                     Log.TraceLog("PLX_Device.DeviceOpen: Opened a handle to " +
  306.                         "Kernel PlugIn driver " + m_sKP_PLX_DRIVER_NAME + 
  307.                         this.ToString(false));
  308.                 }
  309.             }
  310.         
  311.             /* Validate device information */
  312.             if (DeviceValidate() != true)
  313.             {
  314.                 dwStatus = (DWORD)wdc_err.WD_NO_RESOURCES_ON_DEVICE;
  315.                 goto Error;
  316.             }
  317.             DeviceInit();
  318.             if(EEPROM.EEPROMIsPresent(Handle, m_dwCNTRL))
  319.             {
  320.                 if(EEPROM.VPD_Validate(Handle, m_dwCNTRL))
  321.                     m_EEPROM = new EEPROM_VPD(Handle, m_dwCNTRL, m_dwPROT_AREA);
  322.                 else
  323.                     switch (m_wdcDevice.id.pciId.dwDeviceId)
  324.                     {
  325.                     case 0x9080:
  326.                         m_EEPROM = new EEPROM_RT(Handle, m_dwCNTRL, 
  327.                             (DWORD)BITS.BIT5);
  328.                         break;
  329.                     case 0x9030:
  330.                     case 0x9050:
  331.                     case 0x9052:
  332.                     case 0x9054:
  333.                     case 0x9056:
  334.                     case 0x9656:
  335.                     default:
  336.                         m_EEPROM = new EEPROM_RT(Handle, m_dwCNTRL,
  337.                             (DWORD)BITS.BIT7);
  338.                         break;
  339.                     }
  340.             }
  341.             return dwStatus;
  342. Error:    
  343.             if (Handle != IntPtr.Zero)
  344.                 DeviceClose();
  345.             return dwStatus;
  346.         }
  347.         public virtual bool DeviceClose()
  348.         {
  349.             DWORD dwStatus;
  350.             if (Handle == IntPtr.Zero)
  351.             {
  352.                 Log.ErrLog("PLX_Device.DeviceClose: Error - NULL " 
  353.                     + "device handle");
  354.                 return false;
  355.             }
  356.             /* unregister events*/
  357.             dwStatus = EventUnregister();
  358.             /* Disable interrupts */
  359.             dwStatus = DisableInterrupts();
  360.             /* Close the device */
  361.             dwStatus = wdc_lib_decl.WDC_PciDeviceClose(Handle);
  362.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  363.             {
  364.                 Log.ErrLog("PLX_Device.DeviceClose: Failed closing a "
  365.                     + "WDC device handle (0x" + Handle.ToInt64().ToString("X") 
  366.                     + ". Error 0x" + dwStatus.ToString("X") + ": " +
  367.                     utils.Stat2Str(dwStatus) + this.ToString(false));
  368.             }
  369.             else
  370.             {
  371.                 Log.TraceLog("PLX_Device.DeviceClose: " +
  372.                     this.ToString(false) + " was closed successfully");
  373.             }
  374.             return ((DWORD)wdc_err.WD_STATUS_SUCCESS == dwStatus);
  375.         }
  376.         /* protected methods */
  377.         protected abstract void DeviceInit(); 
  378.         public void Dispose()
  379.         {
  380.             DeviceClose();
  381.         }
  382. #endregion
  383. #region " Read/Write "
  384.         public DWORD ReadReg8(DWORD dwOffset, ref BYTE bData) 
  385.         {
  386.             return wdc_lib_decl.WDC_ReadAddr8(Handle, PLX_ADDR_REG, dwOffset,
  387.                 ref bData);
  388.         }
  389.         public DWORD ReadReg16(DWORD dwOffset, ref WORD wData) 
  390.         {
  391.             return wdc_lib_decl.WDC_ReadAddr16(Handle, PLX_ADDR_REG, dwOffset,
  392.                 ref wData);
  393.         }
  394.         public DWORD ReadReg32(DWORD dwOffset, ref UINT32 u32Data) 
  395.         {
  396.             return wdc_lib_decl.WDC_ReadAddr32(Handle, PLX_ADDR_REG, dwOffset,
  397.                 ref u32Data);
  398.         }
  399.         public DWORD ReadReg64(DWORD dwOffset, ref UINT64 u64Data) 
  400.         {
  401.             return wdc_lib_decl.WDC_ReadAddr64(Handle, PLX_ADDR_REG, dwOffset,
  402.                 ref u64Data);
  403.         }
  404.         public DWORD WriteReg8(DWORD dwOffset, BYTE bData) 
  405.         {
  406.             return wdc_lib_decl.WDC_WriteAddr8(Handle, PLX_ADDR_REG, dwOffset,
  407.                 bData);
  408.         }
  409.         public DWORD WriteReg16(DWORD dwOffset, WORD wData) 
  410.         {
  411.             return wdc_lib_decl.WDC_WriteAddr16(Handle, PLX_ADDR_REG, dwOffset,
  412.                 wData);
  413.         }
  414.         public DWORD WriteReg32(DWORD dwOffset, UINT32 u32Data) 
  415.         {
  416.             return wdc_lib_decl.WDC_WriteAddr32(Handle, PLX_ADDR_REG, dwOffset,
  417.                 u32Data);
  418.         }
  419.         public DWORD WriteReg64(DWORD dwOffset, UINT64 u64Data) 
  420.         {
  421.             return wdc_lib_decl.WDC_WriteAddr64(Handle, PLX_ADDR_REG, dwOffset,
  422.                 u64Data);
  423.         }
  424.         
  425. #endregion
  426.         
  427. #region " Interrupts "
  428.         /****************************
  429.          *       Interrupts         *
  430.          * **************************/
  431.         /* public methods */
  432.         public bool IsEnabledInt()
  433.         {
  434.             return wdc_lib_decl.WDC_IntIsEnabled(this.Handle);
  435.         }
  436.     public abstract DWORD CreateIntTransCmds(out WD_TRANSFER[] pIntTransCmds,
  437.             out DWORD dwNumCmds);
  438.     public abstract void DisableCardInts();
  439.     protected DWORD EnableInterrupts(INT_HANDLER intHandler, DWORD dwOptions,
  440.         IntPtr pData)
  441.     {
  442.         WD_TRANSFER[] pIntTransCmds = null;
  443.         DWORD dwNumCmds;
  444.         if(intHandler == null)
  445.         {
  446.             Log.ErrLog("PLX_Device.EnableInterrupts: interrupt handler is " +
  447.                 "null (" + this.ToString(false) + ")" ); 
  448.             return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  449.         }
  450.         if(wdc_lib_decl.WDC_IntIsEnabled(Handle))
  451.         {
  452.             Log.ErrLog("PLX_Device.EnableInterrupts: "
  453.                 + "interrupts are already enabled (" +
  454.                 this.ToString(false) + ")" );
  455.             return (DWORD)wdc_err.WD_OPERATION_ALREADY_DONE;
  456.         }
  457.         DWORD dwStatus = CreateIntTransCmds(out pIntTransCmds, out dwNumCmds);
  458.         if (dwStatus != (DWORD)wdc_err.WD_STATUS_SUCCESS)
  459.             return dwStatus;
  460.         m_intHandler = intHandler;
  461.         dwStatus = wdc_lib_decl.WDC_IntEnable(wdcDevice, pIntTransCmds, 
  462.             dwNumCmds, dwOptions, m_intHandler, pData, 
  463.             wdc_defs_macros.WDC_IS_KP(m_wdcDevice));
  464.         if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  465.         {
  466.             Log.ErrLog("PLX_Device.EnableInterrupts: Failed "
  467.                 + "enabling interrupts. Error " + dwStatus.ToString("X") + ": " 
  468.                 + utils.Stat2Str(dwStatus) + "(" + this.ToString(false) + ")");
  469.             m_intHandler = null;
  470.             return dwStatus;
  471.         }
  472.         return dwStatus;            
  473.     }
  474.     public virtual DWORD DisableInterrupts()
  475.     {
  476.         DWORD dwStatus;
  477.         if (!wdc_lib_decl.WDC_IntIsEnabled(this.Handle))
  478.         {
  479.             Log.ErrLog("PLX_Device.DisableInterrupts: interrupts are already disabled... " +
  480.                 "(" + this.ToString(false) + ")" );
  481.             return (DWORD)wdc_err.WD_OPERATION_ALREADY_DONE;
  482.         }
  483.         DisableCardInts();
  484.         dwStatus = wdc_lib_decl.WDC_IntDisable(m_wdcDevice);
  485.         if (dwStatus != (DWORD)wdc_err.WD_STATUS_SUCCESS)
  486.         {
  487.             Log.ErrLog("PLX_Device.DisableInterrupts: Failed to" +
  488.                 "disable interrupts. Error " + dwStatus.ToString("X") 
  489.                 + ": " + utils.Stat2Str(dwStatus) + " (" +
  490.                 this.ToString(false) + ")" );
  491.         }
  492.         else
  493.         {
  494.             Log.TraceLog("PLX_Device.DisableInterrupts: Interrupts are disabled (" +
  495.                 this.ToString(false) + ")");
  496.         }
  497.         return dwStatus;                        
  498.     }
  499. #endregion
  500. #region " Local Bus Read/Write "
  501.         /****************************
  502.          *    Local Bus Read/Write  *
  503.          * **************************/
  504.         /* public methods */
  505.         public DWORD ReadAddrLocalBlock(PLX_ADDR addrSpace,
  506.             DWORD dwLocalAddr, DWORD dwBytes, IntPtr pData, WDC_ADDR_MODE mode,
  507.             WDC_ADDR_RW_OPTIONS options)
  508.         {
  509.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  510.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  511.             return wdc_lib_decl.WDC_ReadAddrBlock(Handle, (DWORD)addrSpace,
  512.                 dwOffset, dwBytes, pData, mode, options);
  513.         }
  514.         public DWORD ReadAddrLocalBlock(PLX_ADDR addrSpace,
  515.             DWORD dwLocalAddr, DWORD dwBytes, UInt64[] pData, 
  516.             WDC_ADDR_MODE mode, WDC_ADDR_RW_OPTIONS options)
  517.         {
  518.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  519.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  520.             return wdc_lib_decl.WDC_ReadAddrBlock(Handle, (DWORD)addrSpace,
  521.                 dwOffset, dwBytes, pData, mode, options);
  522.         }
  523.         public DWORD ReadAddrLocalBlock(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  524.             DWORD dwBytes, DWORD[] pData, WDC_ADDR_MODE mode,
  525.             WDC_ADDR_RW_OPTIONS options)
  526.         {
  527.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  528.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  529.             return wdc_lib_decl.WDC_ReadAddrBlock(Handle, (DWORD)addrSpace,
  530.                 dwOffset, dwBytes, pData, mode, options);
  531.         }
  532.         public DWORD ReadAddrLocalBlock(PLX_ADDR addrSpace,
  533.             DWORD dwLocalAddr, DWORD dwBytes, WORD[] pData, WDC_ADDR_MODE mode,
  534.             WDC_ADDR_RW_OPTIONS options)
  535.         {
  536.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  537.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  538.             return wdc_lib_decl.WDC_ReadAddrBlock(Handle, (DWORD)addrSpace,
  539.                 dwOffset, dwBytes, pData, mode, options);
  540.         }
  541.         public DWORD ReadAddrLocalBlock(PLX_ADDR addrSpace,
  542.             DWORD dwLocalAddr, DWORD dwBytes, byte[] pData, WDC_ADDR_MODE mode,
  543.             WDC_ADDR_RW_OPTIONS options)
  544.         {
  545.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  546.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  547.             return wdc_lib_decl.WDC_ReadAddrBlock(Handle, (DWORD)addrSpace,
  548.                 dwOffset, dwBytes, pData, mode, options);
  549.         }
  550.         public DWORD WriteAddrLocalBlock(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  551.             DWORD dwBytes, IntPtr pData, WDC_ADDR_MODE mode, 
  552.             WDC_ADDR_RW_OPTIONS options)
  553.         {
  554.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  555.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  556.             return wdc_lib_decl.WDC_WriteAddrBlock(Handle, (DWORD)addrSpace,
  557.                 dwOffset, dwBytes, pData, mode, options);
  558.         }
  559.         public DWORD WriteAddrLocalBlock(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  560.             DWORD dwBytes, UInt64[] pData, WDC_ADDR_MODE mode, 
  561.             WDC_ADDR_RW_OPTIONS options)
  562.         {
  563.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  564.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  565.             return wdc_lib_decl.WDC_WriteAddrBlock(Handle, (DWORD)addrSpace,
  566.                 dwOffset, dwBytes, pData, mode, options);
  567.         }
  568.         public DWORD WriteAddrLocalBlock(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  569.             DWORD dwBytes, DWORD[] pData, WDC_ADDR_MODE mode, 
  570.             WDC_ADDR_RW_OPTIONS options)
  571.         {
  572.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  573.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  574.             return wdc_lib_decl.WDC_WriteAddrBlock(Handle, (DWORD)addrSpace,
  575.                 dwOffset, dwBytes, pData, mode, options);
  576.         }
  577.         public DWORD WriteAddrLocalBlock(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  578.             DWORD dwBytes, WORD[] pData, WDC_ADDR_MODE mode,
  579.             WDC_ADDR_RW_OPTIONS options)
  580.         {
  581.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  582.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  583.             return wdc_lib_decl.WDC_WriteAddrBlock(Handle, (DWORD)addrSpace,
  584.                 dwOffset, dwBytes, pData, mode, options);
  585.         }
  586.         public DWORD WriteAddrLocalBlock(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  587.             DWORD dwBytes, byte[] pData, WDC_ADDR_MODE mode, 
  588.             WDC_ADDR_RW_OPTIONS options)
  589.         {
  590.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  591.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  592.             return wdc_lib_decl.WDC_WriteAddrBlock(Handle, (DWORD)addrSpace,
  593.                 dwOffset, dwBytes, pData, mode, options);
  594.         }
  595.         public DWORD ReadAddrLocal8(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  596.             ref byte bData)
  597.         {
  598.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  599.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  600.             return wdc_lib_decl.WDC_ReadAddr8(Handle, (DWORD)addrSpace,
  601.                 dwOffset, ref bData);
  602.         }
  603.         public DWORD WriteAddrLocal8(PLX_ADDR addrSpace,
  604.             DWORD dwLocalAddr, byte bData)
  605.         {
  606.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  607.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  608.             return wdc_lib_decl.WDC_WriteAddr8(Handle, (DWORD)addrSpace, 
  609.                 dwOffset, bData);
  610.         }
  611.         public DWORD ReadAddrLocal16(PLX_ADDR addrSpace, DWORD dwLocalAddr, 
  612.             ref WORD wData)
  613.         {
  614.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  615.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  616.             return wdc_lib_decl.WDC_ReadAddr16(Handle, (DWORD)addrSpace, 
  617.                 dwOffset, ref wData);
  618.         }
  619.         public DWORD WriteAddrLocal16(PLX_ADDR addrSpace,
  620.             DWORD dwLocalAddr, WORD wData)
  621.         {
  622.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  623.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  624.             return wdc_lib_decl.WDC_WriteAddr16(Handle, (DWORD)addrSpace,
  625.                 dwOffset, wData);
  626.         }
  627.         public DWORD ReadAddrLocal32(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  628.             ref uint u32Data)
  629.         {
  630.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  631.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  632.             return wdc_lib_decl.WDC_ReadAddr32(Handle, (DWORD)addrSpace,
  633.                 dwOffset, ref u32Data);
  634.         }
  635.         public DWORD WriteAddrLocal32(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  636.             uint u32Data)
  637.         {
  638.             DWORD dwOffset = MASK_LOCAL( addrSpace) & dwLocalAddr;
  639.             LocalAddrSetMode( addrSpace, dwLocalAddr);
  640.             return wdc_lib_decl.WDC_WriteAddr32(Handle, (DWORD)addrSpace,
  641.                 dwOffset, u32Data);
  642.         }
  643.         public DWORD ReadAddrLocal64(PLX_ADDR addrSpace, DWORD dwLocalAddr, 
  644.             ref ulong u64Data)
  645.         {
  646.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  647.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  648.             return wdc_lib_decl.WDC_ReadAddr64(Handle, (DWORD)addrSpace, 
  649.                 dwOffset, ref u64Data);
  650.         }
  651.         public DWORD WriteAddrLocal64(PLX_ADDR addrSpace, DWORD dwLocalAddr,
  652.             ulong u64Data)
  653.         {
  654.             DWORD dwOffset = MASK_LOCAL(addrSpace) & dwLocalAddr;
  655.             LocalAddrSetMode(addrSpace, dwLocalAddr);
  656.             return wdc_lib_decl.WDC_WriteAddr64(Handle, (DWORD)addrSpace,
  657.                 dwOffset, u64Data);
  658.         }
  659.         /* private methods */
  660.         private DWORD MASK_LOCAL(PLX_ADDR addrSpace)
  661.         {
  662.             return AddrDesc[(int)addrSpace].dwBytes - 1;
  663.         }
  664.         private DWORD LocalAddrSetMode(PLX_ADDR addrSpace, DWORD dwLocalAddr)
  665.         {
  666.             DWORD dwLocalBase = (dwLocalAddr & ~MASK_LOCAL(addrSpace)) | 
  667.                 (DWORD)BITS.BIT0;
  668.             DWORD dwOffset = m_dwLASBA[(DWORD)addrSpace - 2];
  669.             return wdc_lib_decl.WDC_WriteAddr32(Handle, PLX_ADDR_REG,
  670.                 dwOffset, (uint)dwLocalBase);
  671.         }
  672. #endregion
  673. #region " Events "
  674.         /****************************
  675.          *          Events          *
  676.          * **************************/
  677.         /* public methods */
  678.         public bool IsEventRegistered()
  679.         {
  680.             if (Handle == IntPtr.Zero)
  681.                 return false;
  682.             return wdc_lib_decl.WDC_EventIsRegistered(Handle);
  683.         }
  684.         public DWORD EventRegister(USER_EVENT_CALLBACK userEventHandler)
  685.         {
  686.             DWORD dwStatus;
  687.             DWORD dwActions = (DWORD)windrvr_consts.WD_ACTIONS_ALL;
  688.             /* TODO: Modify the above to set up the plug-and-play/power 
  689.              * management events for which you wish to receive notifications.
  690.              dwActions can be set to any combination of the WD_EVENT_ACTION
  691.              flags defined in windrvr.h */
  692.             if(userEventHandler == null)
  693.             {
  694.                 Log.ErrLog("PLX_Device.EventRegister: user callback is "
  695.                     + "null");
  696.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  697.             }
  698.             /* Check if event is already registered */
  699.             if(wdc_lib_decl.WDC_EventIsRegistered(Handle))
  700.             {
  701.                 Log.ErrLog("PLX_Device.EventRegister: Events are already "
  702.                     + "registered ...");
  703.                 return (DWORD)wdc_err.WD_OPERATION_ALREADY_DONE;
  704.             }
  705.             m_userEventHandler = userEventHandler;
  706.             /* Register event */
  707.             dwStatus = wdc_lib_decl.WDC_EventRegister(m_wdcDevice, dwActions,
  708.                 m_eventHandler, Handle, wdc_defs_macros.WDC_IS_KP(m_wdcDevice));
  709.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  710.             {
  711.                 Log.ErrLog("PLX_Device.EventRegister: Failed to register "
  712.                     + "events. Error 0x"
  713.                     + dwStatus.ToString("X") + utils.Stat2Str(dwStatus));
  714.                 m_userEventHandler = null;
  715.             }
  716.             else
  717.             {
  718.                 Log.TraceLog("PLX_Device.EventRegister: events are " +
  719.                     " registered (" + this.ToString(false) +")" );
  720.             }
  721.             return dwStatus;                        
  722.         }
  723.         public DWORD EventUnregister()
  724.         {
  725.             DWORD dwStatus;
  726.             if (!wdc_lib_decl.WDC_EventIsRegistered(Handle))
  727.             {
  728.                 Log.ErrLog("PLX_Device.EventUnregister: No events " +
  729.                     "currently registered ...(" + this.ToString(false) + ")" );
  730.                 return (DWORD)wdc_err.WD_OPERATION_ALREADY_DONE;
  731.             }
  732.             dwStatus = wdc_lib_decl.WDC_EventUnregister(m_wdcDevice);
  733.             if ((DWORD)wdc_err.WD_STATUS_SUCCESS != dwStatus)
  734.                 Log.ErrLog("PLX_Device.EventUnregister: Failed to " +
  735.                     " unregister events. Error 0x" + dwStatus.ToString("X") +
  736.                     ": " + utils.Stat2Str(dwStatus) + "(" +
  737.                     this.ToString(false) + ")");
  738.             else
  739.                 Log.TraceLog("PLX_Device.EventUnregister: Unregistered " +
  740.                     " events (" + this.ToString(false) + ")" );
  741.             return dwStatus;
  742.         }
  743.         /** private methods **/
  744.         /* event callback method */
  745.         private void EventHandler(IntPtr pWdEvent, IntPtr pDev)
  746.         {
  747.             MarshalWdEvent wdEventMarshaler = new MarshalWdEvent();
  748.             WD_EVENT wdEvent = (WD_EVENT)wdEventMarshaler.MarshalNativeToManaged(pWdEvent);
  749.             m_wdcDevice.Event =
  750.                 (WD_EVENT)m_wdcDeviceMarshaler.MarshalDevWdEvent(pDev);
  751.             if(m_userEventHandler != null)
  752.                 m_userEventHandler(ref wdEvent, this); 
  753.         }
  754. #endregion
  755.     }
  756. }