PNP.C
上传用户:lx1888888
上传日期:2007-01-04
资源大小:136k
文件大小:7k
源码类别:

驱动编程

开发平台:

Visual C++

  1. #define WANTVXDWRAPS
  2. #include <basedef.h>
  3. #include <vmm.h>
  4. #include <debug.h>
  5. #include "vxdcall.h"
  6. #include <vxdwraps.h>
  7. #include "intrinsi.h"
  8. #include <configmg.h>
  9. #include <vpicd.h>
  10. #include "wrappers.h"
  11. #ifdef DEBUG
  12. #define DPRINTF0(buf, fmt ) _Sprintf(buf, fmt ); Out_Debug_String( buf )
  13. #define DPRINTF1(buf, fmt, arg1) _Sprintf(buf, fmt, arg1 ); Out_Debug_String( buf )
  14. #define DPRINTF2(buf, fmt, arg1, arg2) _Sprintf(buf, fmt, arg1, arg2 ); Out_Debug_String( buf )
  15. #else
  16. #define DPRINTF0(buf, fmt)
  17. #define DPRINTF1(buf, fmt, arg1)
  18. #define DPRINTF2(buf, fmt, arg1, arg2)
  19. #endif
  20. #define _outpdw( port, val ) _asm mov dx, port 
  21.    _asm mov eax, val 
  22.    _asm out dx, eax 
  23. #define REG_CTRL 0
  24. #define REG_STATUS 1
  25. #define CTRL_START_DEVICE 0x01
  26. #define CTRL_STOP_DEVICE 0x00
  27. typedef struct
  28. {
  29. DWORD Ctrl;
  30. DWORD Status;
  31. } MEMREGS;
  32. typedef struct
  33. {
  34. DWORD MemBase;
  35.    DWORD MemSize;
  36. MEMREGS *pMem;
  37. WORD IoBase;
  38. WORD Irq;
  39.    IRQHANDLE       hndIrq;
  40.    VPICD_IRQ_DESCRIPTOR IrqDescr;
  41. } DEVICE_CONTEXT;
  42. BOOL OnSysDynamicDeviceInit(void);
  43. BOOL OnSysDynamicDeviceExit(void);
  44. CONFIGRET OnPNPNewDevnode(DEVNODE DevNode, DWORD LoadType);
  45. CONFIGRET CM_HANDLER ConfigHandler(CONFIGFUNC cfFuncName, SUBCONFIGFUNC scfSubFuncName, DEVNODE dnToDevNode, DWORD dwRefData, ULONG ulFlags);
  46. CONFIGRET ProcessConfigStart( DEVNODE devnode, DEVICE_CONTEXT *dev );
  47. CONFIGRET ProcessConfigStop( DEVNODE devnode, DEVICE_CONTEXT *dev );
  48. void Print_Assigned_Resources( CMCONFIG *pConfig );
  49. DWORD MyMapPhysToLinear( DWORD phys, DWORD size );
  50. BOOL UnMapPhysToLinear( DWORD lin, DWORD size );
  51. char dbuf[80];
  52. DEVICE_CONTEXT *pDeviceContext;
  53. // functions in asm module
  54. void HwIntProcThunk( void );
  55. BOOL OnSysDynamicDeviceInit()
  56. {
  57. return TRUE;
  58. }
  59. BOOL OnSysDynamicDeviceExit()
  60. {
  61. return TRUE;
  62. }
  63. CONFIGRET OnPNPNewDevnode(DEVNODE DevNode, DWORD LoadType)
  64. {    
  65. CONFIGRET rc;
  66. switch (LoadType) 
  67. {
  68. case DLVXD_LOAD_DEVLOADER:
  69. pDeviceContext = (DEVICE_CONTEXT *)_HeapAllocate( sizeof(DEVICE_CONTEXT), HEAPZEROINIT );
  70. if (!pDeviceContext)
  71. return CR_FAILURE;
  72.                         rc = CM_Register_Device_Driver(DevNode, ConfigHandler, pDeviceContext,
  73.                                                        CM_REGISTER_DEVICE_DRIVER_REMOVABLE |
  74.                                                        CM_REGISTER_DEVICE_DRIVER_DISABLEABLE );
  75. if (rc != CR_SUCCESS)
  76. return rc;
  77. return CR_SUCCESS;
  78. default:
  79. return(CR_DEFAULT);
  80. }
  81. }
  82. #pragma VxD_PAGEABLE_DATA_SEG
  83. #pragma VxD_PAGEABLE_CODE_SEG
  84. CONFIGRET CM_HANDLER ConfigHandler(CONFIGFUNC cfFuncName, SUBCONFIGFUNC scfSubFuncName, DEVNODE dnToDevNode, DWORD dwRefData, ULONG ulFlags)
  85. {
  86. CMCONFIG Config;
  87. DWORD rc;
  88. DEVICE_CONTEXT *dev = (DEVICE_CONTEXT *)dwRefData;
  89. switch (cfFuncName) 
  90. {
  91. case CONFIG_START:
  92. return ProcessConfigStart(dnToDevNode, dev );
  93. case CONFIG_TEST:
  94. return CR_SUCCESS;
  95. case CONFIG_STOP:
  96. return ProcessConfigStop(dnToDevNode, dev );
  97. case CONFIG_REMOVE:
  98. return ProcessConfigStop(dnToDevNode, dev );
  99. default:
  100. return CR_DEFAULT;
  101. }
  102. }
  103. CONFIGRET ProcessConfigStart( DEVNODE devnode, void *p )
  104. {
  105.    DEVICE_CONTEXT *dev = (DEVICE_CONTEXT *)p;
  106.    CONFIGRET rc;
  107.    CMCONFIG  Config;
  108.    MEMREGS *regs;
  109.    WORD     reg;
  110.    IRQHANDLE hndIrq;
  111.    rc = CM_Get_Alloc_Log_Conf(&Config, devnode, CM_GET_ALLOC_LOG_CONF_ALLOC);
  112. if (rc != CR_SUCCESS)
  113. {
  114.       DPRINTF1(dbuf, "CM_Get_Alloc_Log_Conf failed rc=%xn", rc );
  115. return CR_FAILURE;
  116. }
  117. Print_Assigned_Resources(&Config);
  118. if (! ((Config.wNumIRQs == 1) && 
  119.     (Config.wNumIOPorts == 1 || Config.wNumMemWindows == 1))
  120.    )
  121. {
  122.       DPRINTF0(dbuf, "Expected resources not assigned" );
  123. return CR_FAILURE;
  124. }
  125. if (Config.wNumMemWindows)
  126. {
  127. dev->MemBase = Config.dMemBase[0];
  128.       dev->MemSize = Config.dMemLength[0];
  129. dev->pMem = (MEMREGS *)MyMapPhysToLinear( dev->MemBase, Config.dMemLength[0] );
  130. if (!dev->pMem)
  131. {
  132.          DPRINTF0(dbuf, "MyMapPhysToLinear failed" );
  133. return CR_FAILURE;
  134. }
  135. dev->pMem->Ctrl = CTRL_START_DEVICE;
  136. }
  137. else
  138. {
  139. dev->IoBase = Config.wIOPortBase[0];
  140.       reg = dev->IoBase + REG_CTRL;
  141. _outpdw( reg, CTRL_START_DEVICE )
  142. }
  143. dev->IrqDescr.VID_IRQ_Number = Config.bIRQRegisters[0];
  144. dev->IrqDescr.VID_Options = VPICD_OPT_REF_DATA;
  145. dev->IrqDescr.VID_Hw_Int_Ref = dev;
  146. dev->IrqDescr.VID_Hw_Int_Proc = HwIntProcThunk;
  147. hndIrq = VPICD_Virtualize_IRQ( &dev->IrqDescr );
  148. if (!hndIrq)
  149. {
  150.       DPRINTF0(dbuf, "VPICD_Virt failed" );
  151. return CR_FAILURE;
  152. }
  153. return CR_SUCCESS;
  154. }
  155. CONFIGRET ProcessConfigStop( DEVNODE devnode, void *p )
  156. {
  157.    DEVICE_CONTEXT *dev = (DEVICE_CONTEXT *)p; 
  158.    WORD  reg;
  159.   if (dev->pMem)
  160.   {
  161.   dev->pMem->Ctrl = CTRL_STOP_DEVICE;
  162.   UnMapPhysToLinear( (DWORD)dev->pMem, dev->MemSize );
  163.   }
  164.   else if (dev->IoBase)
  165.   {
  166.       reg = dev->IoBase + REG_CTRL;
  167. _outpdw( reg, CTRL_STOP_DEVICE )
  168.   }
  169.   VPICD_Force_Default_Behavior( dev->hndIrq );
  170.   _HeapFree( dev, 0 );
  171.   return CR_SUCCESS;
  172. }
  173. void Print_Assigned_Resources( CMCONFIG *pConfig )
  174. {
  175. int i;
  176. if (pConfig->wNumMemWindows)
  177. {
  178. DPRINTF0(dbuf, "Mem resourcesrn" );
  179. for (i=0; i < pConfig->wNumMemWindows; i++)
  180. {
  181. DPRINTF1(dbuf, "Range #%d: ", pConfig->wNumMemWindows );
  182. DPRINTF2(dbuf, "starts at %x len is %drn", pConfig->dMemBase[i],pConfig->dMemLength[i] );
  183. }   
  184. }
  185. if (pConfig->wNumIOPorts)
  186. {
  187. DPRINTF0(dbuf, "IO resourcesrn" );
  188. for (i=0; i < pConfig->wNumIOPorts; i++)
  189. {
  190. DPRINTF1(dbuf, "Range #%d: ", pConfig->wNumIOPorts );
  191. DPRINTF2(dbuf, "starts at %x len is %drn", pConfig->wIOPortBase[i],pConfig->wIOPortLength[i] );
  192. }
  193. }
  194. if (pConfig->wNumIRQs)
  195. {
  196. DPRINTF0(dbuf, "IRQs: " );
  197. for (i=0; i < pConfig->wNumIRQs; i++)
  198. {
  199. DPRINTF1(dbuf, "%d ", pConfig->bIRQRegisters[i]); 
  200. }
  201. DPRINTF0(dbuf, "rn"); 
  202. }
  203. if (pConfig->wNumDMAs)
  204. {
  205. DPRINTF0(dbuf, "DMA channels:" );
  206. for (i=0; i < pConfig->wNumDMAs; i++)
  207. {
  208. DPRINTF1(dbuf, "%d ", pConfig->bDMALst[i]); 
  209. }
  210. DPRINTF0(dbuf, "rn"); 
  211. }
  212. }
  213. DWORD MyMapPhysToLinear( DWORD phys, DWORD size )
  214. {
  215.    DWORD lin;
  216.    DWORD nPages = size / 4096;
  217.    lin = _PageReserve( PR_SYSTEM, nPages, 0 );
  218.    if (lin == -1)
  219.       return 0;
  220.    if (!_PageCommitPhys( lin >> 12, nPages, phys, PC_INCR | PC_WRITEABLE  ))
  221.     return 0;
  222.    if (!_LinPageLock( lin >> 12, nPages, 0 ))
  223.        return 0;
  224.    return lin;
  225. }
  226. BOOL UnMapPhysToLinear( DWORD lin, DWORD size )
  227. {
  228.    DWORD nPages = size / 4096;
  229.    if (!_LinPageUnlock( lin, nPages, 0 ))
  230.        return 0;
  231.    if (!_PageDecommit( lin, nPages, 0))
  232. return 0;
  233.    if (!_PageFree( (void *)lin, 0 ))
  234.       return 0;
  235.    return 1;
  236. }
  237. BOOL __stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *pRefData)
  238. {
  239.    DEVICE_CONTEXT *dev = (DEVICE_CONTEXT *)pRefData;
  240. return TRUE;
  241. }