PAGE 58,132 ;****************************************************************************** ; ; (C) Copyright MICROSOFT CORP. 1992-1995 ; ; Title: SERINIT.ASM ; ; Version: 1.0 ; ; Date: 08/16/93 ; ; Author: Sandeeps ; ;============================================================================== ; Change log: ; ;****************************************************************************** .386p .xlist include VMM.INC include OPTTEST.INC include VCOMM.INC include DEBUG.INC include INTERNAL.INC include INS8250.INC include CONFIGMG.INC .list VxD_Pageable_Code_Seg EXTRN _PortOpen:NEAR VxD_Pageable_Code_Ends VxD_Locked_Code_Seg EXTRN GetModemStatus_Hook:NEAR EXTRN EscapeCommFunction_Hook:NEAR VxD_Locked_Code_Ends VxD_Pageable_Data_Seg EXTRN PortInfoHandle:DWORD EXTRN Serial_Functions:BYTE EXTRN SysVMHandle:DWORD EXTRN BaseAddr:DWORD IRQInfoHandle dd 0 xx dd 0 mm db "BPQVC Known %x",0 CommControl db 'Settings',0 Settings dd ? prd_Temp dd ? ;*** ; ; SettingsInfo: struct to read from registry per COM port ; SettingsInfo STRUC COMFifoOn db ? ; Q: How to deal with FIFO ? COMTxFifoSize db ? ; Q: How to deal with Xmit FIFO ? COMDSROn db ? ; Q: Should we force DSR on ? COMRxTrigger db ? ; Q: two bit combo for the trigger SettingsInfo ENDS .errnz SIZE SettingsInfo - 4 VxD_Pageable_Data_Ends VxD_Locked_Data_Seg EXTRN pGetModemStatus_PrevHook:DWORD EXTRN pEscapeCommFunction_PrevHook:DWORD VxD_Locked_Data_Ends VxD_ICODE_Seg ;****************************************************************************** ; ; Serial_Device_Init ; ; Description: ; On snowball, this gets called at Device_Init time ; On Chicago, it gets called at Sys_Dynamic_Device_Init ; time. If registers itself as a port driver with VCOMM ; and loads if it can find the port(s) being configured. ; On Snowball, it looks at BDA and add all ports while ; on Chicago, it configures only the given port. ; ; Entry: ; None. ; Exit: ; if port(s) could be configured then NC ; else CY ; ; Uses: All ; ;****************************************************************************** BeginProc Serial_Device_Init,PUBLIC SaveReg mov BaseAddr, offset32 Serial_Device_Init Debug_Printf "BPQVC Serial Device Init %x ", RestoreReg cmp [SysVMHandle],0 jne NDI_Load_Done VMMCall Get_Sys_VM_Handle mov [SysVMHandle],ebx ; save SaveReg Debug_Printf "BPQVC Serial Device Init VM Handle %x", RestoreReg VxDCall VCOMM_Get_Version ; Q: VCOMM present ? jc NDI_NoLoad ; N: fail to load. ; GetVxDServiceOrdinal eax, _VCOMM_EscapeCommFunction ; mov esi, OFFSET32 EscapeCommFunction_Hook ; points to the hook procedure to install ; VMMCall Hook_Device_Service ; jc not_installed ; carry flag set if error ; mov [pEscapeCommFunction_PrevHook], esi ; Debug_Printf "BPQVC EscCOM FunctHook Installed" ; jmp @f ;not_installed: ; Debug_Printf "BPQVC Hook Not Installed" ;@@: ; GetVxDServiceOrdinal eax, _VCOMM_GetModemStatus ; mov esi, OFFSET32 GetModemStatus_Hook ; points to the hook procedure to install ; VMMCall Hook_Device_Service ; jc not_installed2 ; carry flag set if error ; mov [pGetModemStatus_PrevHook], esi ; Debug_Printf "BPQVC GetModemStatus Hook Installed" ; jmp @f ;not_installed2: ; Debug_Printf "BPQVC GetModemStatusHook Not Installed" ;@@: mov eax,LF_Alloc_Error mov ecx,SIZE PortInformation ; Create per port list. VMMCall List_Create jc NDI_NoLoad mov [PortInfoHandle],esi xor eax,eax mov ecx,SIZE IRQStruc ; Create per irq list. VMMCall List_Create jc NDI_NoLoad mov [IRQInfoHandle],esi SaveReg Debug_Printf "BPQVC Serial Device Init PortInfoHandle is %x", RestoreReg VxDCall _VCOMM_Register_Port_Driver, SaveReg Debug_Printf "BPQVC Serial Device loaded" RestoreReg clc ret NDI_Load_Done: SaveReg Debug_Printf "BPQVC Serial Device already loaded" RestoreReg clc ret NDI_NoLoad: SaveReg Debug_Printf "BPQVC Serial Device not loaded" RestoreReg stc ret EndProc Serial_Device_Init VxD_ICODE_Ends VxD_Pageable_Code_Seg ;****************************************************************************** ; ; void S_DriverControl(DWORD fCode, DWORD DevNode, DWORD DCRefData,...) ; ; Description: ; ; Called by VCOMM to perform various actions. ; ; Entry: ; fCode = code of function to perform ; DevNode -> devnode in plug and play scheme ; DCRefData = reference data to refer to while calling VCOMM back. ; ; Exit: ; None ; Uses: ; C style ;============================================================================== BeginProc S_DriverControl, CCALL, esp, PUBLIC ArgVar fCode,DWORD ArgVar DevNode,DWORD ArgVar DCRefData,DWORD EnterProc mov eax,fCode or eax,eax .errnz DC_Initialize jz _InitFunction TRAP LeaveProc return EndProc S_DriverControl ;****************************************************************************** ; ; void InitFunction(DWORD fCode, DWORD DevNode, DWORD DCRefData, ; DWORD AllocBase,DWORD AllocIrq, char *oldname); ; ; Description: ; ; Called by VCOMM to initialize a port. ; ; Entry: ; fCode = code of function to perform ; DevNode -> devnode in plug and play scheme ; DCRefData = reference data to refer to while calling VCOMM back. ; AllocBase = allocated base ; AllocIrq = allocated irq ; oldname -> name of port. ; ; Exit: ; None ; Uses: ; C style ;============================================================================== BeginProc InitFunction,CCALL,esp,PUBLIC ArgVar fCode,DWORD ArgVar DevNode,DWORD ArgVar DCRefData,DWORD ArgVar AllocBase,DWORD ArgVar AllocIrq,DWORD ArgVar oldname,DWORD EnterProc SaveReg Debug_Printf "BPQVC SerialInitFunction %s %x %x %x", RestoreReg SaveReg ; cmp AllocIrq, 0 ; je IF_Done ; ; We use the following algorithm: ; 1) Look in the list of ports known to us so far for the base ; address. ; 2) If we know the base address, return without adding the ; port. ; 3) If we don't know the base address, allocate a list, attach it, ; fill it with values and return. ; SaveReg Debug_Printf "BPQVC SerialInitFunction PortInfoHaNDLE %x", RestoreReg mov esi,[PortInfoHandle] VMMCall List_Get_First jz IF_NewPort mov ecx,AllocBase IF_CheckIfknownBase: SaveReg mov ecx,[eax.Port] mov xx,ecx Debug_Printf "Found %x", RestoreReg cmp [eax.Port],ecx ; Q: Do we know about the port? je IF_Done ; Y: VMMCall List_Get_Next jnz IF_CheckIfKnownBase IF_NewPort: SaveReg Debug_Printf "BPQVC New Port %x", RestoreReg VMMCall List_Allocate ; allocate space jc IF_Done VMMCall List_Attach ; attach it mov edi,eax ; EDI -> PortInfo mov ebx,eax ; save ptr xor eax,eax mov ecx,(SIZE PortInformation)/4 .errnz (SIZE PortInformation and 3) rep stosd ; zero it out mov DWORD PTR [ebx._PortData.PDLength],(10Ah SHL 16) OR SIZE _PortData mov [ebx._PortData.PDFunctions], OFFSET32 Serial_Functions mov [ebx._PortData.PDNumFunctions],(SIZE _PortFunctions)/4 mov WORD PTR [ebx.ComDCB.XonChar],01311h ; CTRL+S CTRL+Q dec [ebx.RecvTrigger] ; will become -1. mov [ebx.RxFifoTrigger],ACE_TRIG08 mov [ebx.TxFifoTrigger],16 ; blast 16 bytes. lea esi,Settings ; comm settings mov DWORD PTR [esi], 2 OR (16 SHL 8) OR (ACE_TRIG08 SHL 24) ; (Fifo, TxFifo, no DSR, 8byte Rxfifo) mov prd_Temp,SIZE SettingsInfo ; size of entry VxDCall _CONFIGMG_Read_Registry_Value,< \ DevNode, 0, OFFSET32 CommControl, REG_BINARY, \ esi, OFFSET32 prd_Temp, CM_REGISTRY_HARDWARE> test eax,eax ; Q: success ? jnz IF_Defaults_OK mov cl,[esi.COMRxTrigger] ; save RXFIFO trigger bits. mov [ebx.RxFifoTrigger],cl cmp [esi.COMDSROn],0 ; Q: Force DSR ? jz IF_NoForceDsr ; N: SetFlag [ebx.EFlags],fUseDSR IF_NoForceDsr: cmp [esi.COMFifoOn],1 ja IF_FifoDefault_OK jb IF_NoFifo ; force it OFF if = 0 SetFlag [ebx.EFlags],fFIFOchkd ; force it ON if = 1 jmp IF_FifoDefault_OK IF_NoFifo: SetFlag [ebx.EFlags], ; force OFF IF_FifoDefault_OK: cmp [esi.COMTxFifoSize],1 ; Q: Turn off TxFifo ? jbe IF_TurnFifoOff ; Y: mov cl,[esi.COMTxFifoSize] ; get fifo trigger size mov [ebx.TxFifoTrigger],cl ; save it. jmp IF_Defaults_OK IF_TurnFifoOff: SetFlag [ebx.EFlags], fNoTxFifo ; Y: IF_Defaults_OK: mov ecx,AllocIrq mov [ebx.IRQn],cl ; save mov ecx,AllocBase mov [ebx.Port],ecx ; save mov edi,oldname ; EDI -> name of port SaveReg Debug_Printf "BPQVC Adding %s Handle %x Base %x", RestoreReg mov esi,edi ; ESI -> name of port xor eax,eax xor ecx,ecx dec ecx ; ECX = -1. repne scasb ; search for 0 neg ecx dec ecx ; ECX = strlen(oldname) SaveReg Debug_Printf "BPQVC Name Len %d", RestoreReg SaveReg VMMCall _HeapAllocate, mov edi,eax ; EDI -> buffer to copy name to RestoreReg or eax,eax jz IF_DeallocAndQuit mov [ebx.MyName],eax ; save my name rep movsb ; copy the name SaveReg Debug_Printf "BPQVC Calling Add_Port %s ", RestoreReg VxDCall _VCOMM_Add_Port, VxDCall _VCOMM_Get_Contention_Handler, mov [ebx.ContentionHnd],eax test eax,eax ; Q:Contention handler present? jz IF_Done ; N: get out VxDCall _VCOMM_Map_Name_To_Resource, mov [ebx.ContentionRes],eax jmp IF_Done IF_DeallocAndQuit: call DeAllocData ; EXPECTS EBX->PortInformation IF_Done: RestoreReg LeaveProc return EndProc InitFunction ;****** ; ; DeAllocData ; ; Description: ; Deallocs the IRQStruc associated with the PortInformation ; if VirtCnt is 0, also deallocs the PortInformation struct ; Entry: ; EBX = PortInformation ; Exit: ; None ; Uses: ; C style ; BeginProc DeAllocData,PUBLIC SaveReg mov esi,[IRQInfoHandle] mov eax,[ebx.MyIRQStruc] or eax,eax ; Q: Is MyIrqStruc alloc'ed ? jz DAD_NoIrqStrucToDealloc ; N: cmp [eax.VirtCnt],0 ; Q: Is virtualize count == 0? jnz DAD_NoIrqStrucToDealloc ; N: VMMCall List_Remove VMMCall List_Deallocate DAD_NoIrqStrucToDealloc: cmp [ebx.MyName],0 je DAD_NoNameToDealloc VMMCall _HeapFree,<[ebx.MyName],0> DAD_NoNameToDealloc: mov esi,[PortInfoHandle] mov eax,ebx VMMCall List_Remove VMMCall List_Deallocate RestoreReg ret EndProc DeAllocData ;****** ; ; Serial_Dynamic_Device_Exit ; ; Description: ; Deallocs all IRQStruc and PortInformation ; ; Entry: ; None ; ; Exit: ; None ; Uses: ; C style ; BeginProc Serial_Dynamic_Device_Exit,PUBLIC ; ; Deallocate all data ; SaveReg Debug_Printf "BPQVC Serial Device Exit" RestoreReg SaveReg xor esi, esi xchg esi,[IRQInfoHandle] ; esi-> IRQInfo List or esi, esi jz SDE_DoneFreeIRQList VMMCall List_Destroy SDE_DoneFreeIRQList: xor esi, esi xchg esi,[PortInfoHandle] ; esi-> PortInfo List or esi, esi jz SDE_DoneFreePortInfoList SDE_RemovePortInfoLoop: VMMCall List_Remove_First jz SDE_DoneRemovePortInfoList cmp [eax.MyName],0 je SDE_DoneFreeMyName VMMCall _HeapFree,<[eax.MyName],0> SDE_DoneFreeMyName: jmp SDE_RemovePortInfoLoop SDE_DoneRemovePortInfoList: VMMCall List_Destroy SDE_DoneFreePortInfoList: RestoreReg ret EndProc Serial_Dynamic_Device_Exit VxD_Pageable_Code_Ends end