|
|
1.1 root 1: /*
2: * Com_VDD.c - Windows NT serial port Virtual Device Driver
3: *
4: * This module handles the init/exit of the VDD.
5: *
6: * copyright 1992 by Microsoft Corporation
7: *
8: * revision history:
9: * 24-Dec-1992 John Morgan: written
10: *
11: */
12:
13: #include "com_vdd.h"
14: #include "pc_com.h"
15: #include "nt_com.h"
16:
17: #include <vddsvc.h>
18:
19: /*
20: *
21: * VDDInitialize
22: *
23: * Arguments:
24: * DllHandle - Identifies this VDD
25: * Reason - Attach or Detach
26: * Context - Not Used
27: *
28: * Return Value:
29: * TRUE: SUCCESS
30: * FALSE: FAILURE
31: *
32: */
33: BOOL VDDInitialize(
34: IN PVOID DllHandle,
35: IN ULONG Reason,
36: IN PCONTEXT Context OPTIONAL
37: )
38: {
39: VDD_IO_PORTRANGE PortDefs[NUM_SERIAL_PORTS] = {
40: {0x3F8, 0x3FF},
41: {0x2F8, 0x2FF},
42: {0x3E8, 0x3EF},
43: {0x2E8, 0x2EF}
44: };
45:
46: VDD_IO_HANDLERS PortHandlers[NUM_SERIAL_PORTS] = {
47: {com_inb, NULL, NULL, NULL, com_outb, NULL, NULL, NULL},
48: {com_inb, NULL, NULL, NULL, com_outb, NULL, NULL, NULL},
49: {com_inb, NULL, NULL, NULL, com_outb, NULL, NULL, NULL},
50: {com_inb, NULL, NULL, NULL, com_outb, NULL, NULL, NULL}
51: };
52:
53: switch ( Reason ) {
54:
55: case DLL_PROCESS_ATTACH:
56: host_com_init();
57:
58: // Attach inb & outb functions to correct ports
59: VDDInstallIOHook(DllHandle, 4, PortDefs, PortHandlers);
60:
61: break;
62:
63: case DLL_PROCESS_DETACH:
64: // Free comm ports
65: VDDDeInstallIOHook(DllHandle, 4, PortDefs);
66:
67: host_com_exit();
68:
69: break;
70:
71: default:
72: break;
73: }
74:
75: return TRUE;
76: }
77:
78:
79: /*
80: *
81: * VDDTerminateVDM
82: *
83: */
84: VOID VDDTerminateVDM( VOID )
85: {
86: return;
87: }
88:
89:
90: /*
91: *
92: * VDDInit
93: *
94: */
95: VOID VDDInit( VOID )
96: {
97:
98: // Called from the BOP manager. If VDDInitialize has done all the
99: // checking and resources alloaction, just return success.
100:
101: setCF( 0 );
102:
103: return;
104: }
105:
106:
107: /*
108: *
109: * VDDDispatch
110: *
111: * Arguments:
112: * Client (DX) = Address / command code
113: * This is essentially an extended port number. The
114: * lowest hex digit identifies a function, while the
115: * upper two digits identify the port base address.
116: * Command 0 is send buffer. It writes CX
117: * characters from the buffer at DS:SI.
118: * Command 1 is read buffer. It reads up to
119: * CX characters into the buffer at ES:DI. CX is
120: * returned as the number of characters read.
121: * Command 7 is set baud rate. It sets the baud
122: * rate as passed in CX.
123: * Commands 8-F access the virtual UART registers.
124: * CX indicates how the register is to be changed.
125: * CH indicates which bits to clear in the register,
126: * while CL indicates which bits to complement. If
127: * CX = 0 the register is read but not written. If
128: * CH = 0xFF the value in CL is written to the register.
129: * In all other cases the register is both read and
130: * written to. CL is always set to the value written
131: * to the register if any, or the value read if not.
132: * Note that 0 is always THR/RBR and 1 is IER.
133: * Use command 7 to change the baud rate.
134: *
135: * Client (CX) = Port Data or Buffer Size
136: * Client (DS:SI) = Read Message Buffer
137: * Client (ES:DI) = Send Message Buffer
138: *
139: * Return Value:
140: * Client Carry Clear: SUCCESS
141: * Client Carry Set: FAILURE
142: *
143: */
144: VOID VDDDispatch( VOID )
145: {
146: USHORT PortCommand;
147: PCHAR Buffer;
148: tAdapter adapter;
149: USHORT PassCX;
150: BYTE temp;
151:
152: setCF( 0 ); // Assume success
153:
154: PortCommand = getDX();
155: adapter = adapter_for_port( (PortCommand & ~0xF) | 8 );
156:
157: if (adapter < 0 || adapter >= NUM_SERIAL_PORTS) {
158: setCF( 1 ); // ERROR: unknown serial port
159: }
160: else {
161: PassCX = getCX(); // all commands us CX
162: switch (PortCommand & 0xF) {
163: case 0: // Write buffer
164: Buffer = (PCHAR) GetVDMPointer((ULONG)(getDS()<<16|getSI()),PassCX,FALSE);
165: break;
166: case 1: // Read buffer
167: Buffer = (PCHAR) GetVDMPointer((ULONG)(getES()<<16|getDI()),PassCX,FALSE);
168: break;
169: case 7: // Set baud rate
170: break;
171: case 8: // THR & RBR
172: case 9: // IED
173: case 10: // IIR
174: case 11: // LCR
175: case 12: // MCR
176: case 13: // LSR
177: case 14: // MSR
178: case 15: // SCR
179: if (PassCX == 0)
180: {
181: com_inb( PortCommand, &temp );
182: // do not write to port
183: setCL( temp );
184: }
185: else if (PassCX & 0xFF00 == 0xFF00)
186: {
187: // do not read from port
188: com_outb( PortCommand, (BYTE) PassCX );
189: }
190: else
191: {
192: com_inb( PortCommand, &temp );
193: temp = (BYTE)((temp & ~(PassCX >> 8)) ^ PassCX);
194: com_outb( PortCommand, temp );
195: setCL( temp );
196: }
197: break;
198: default: // unknown command
199: break;
200: }
201: }
202:
203: return;
204: }
205:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.