|
|
1.1 root 1: /*
2: * Trivial echo driver for STREAMS testing.
3: */
4:
5: #define _DDI_DKI 1
6: #define _SYSV4 1
7:
8: #include <common/ccompat.h>
9: #include <sys/stream.h>
10: #include <sys/stropts.h>
11: #include <stddef.h>
12:
13:
14: static struct module_info minfo = {
15: 0x1821, "echo", 0, INFPSZ, 512, 128
16: };
17:
18: static int echoopen __PROTO ((queue_t * q, dev_t * devp, int flag,
19: int sflag, cred_t * credp));
20: static int echoclose __PROTO ((queue_t * q, int flag,
21: cred_t * credp));
22: static void echowput __PROTO ((queue_t * q, mblk_t * mp));
23: static void echowsrv __PROTO ((queue_t * q));
24: static void echorsrv __PROTO ((queue_t * q));
25:
26: static struct qinit rinit = {
27: NULL, echorsrv, echoopen, echoclose, NULL, & minfo, NULL
28: };
29:
30: static struct qinit winit = {
31: echowput, echowsrv, NULL, NULL, NULL, & minfo, NULL
32: };
33:
34: struct streamtab echoinfo = { & rinit, & winit, NULL, NULL };
35:
36: int echodevflag = 0;
37:
38:
39: #if __USE_PROTO__
40: int echoopen (queue_t * q, dev_t * __NOTUSED (devp), int __NOTUSED (flag),
41: int __NOTUSED (sflag), cred_t * __NOTUSED (credp))
42: #else
43: int
44: echoopen (q, devp, flag, sflag, credp)
45: queue_t * q;
46: dev_t * devp;
47: int flag;
48: int sflag;
49: cred_t * credp;
50: #endif
51: {
52: /*
53: * Enable put and service routines for this queue pair.
54: */
55:
56: qprocson (q);
57: return 0;
58: }
59:
60:
61: #if __USE_PROTO__
62: void echowput (queue_t * q, mblk_t * mp)
63: #else
64: void
65: echowput (q, mp)
66: queue_t * q;
67: mblk_t * mp;
68: #endif
69: {
70: switch (mp->b_datap->db_type) {
71:
72: case M_IOCTL:
73: /*
74: * Invalid ioctl (). Setting "ioc_error" causes the
75: * ioctl () call to return that particular errno. By
76: * default, ioctl () will return EINVAL on failure.
77: */
78:
79: mp->b_datap->db_type = M_IOCNAK;
80: qreply (q, mp);
81: break;
82:
83: case M_FLUSH:
84: /*
85: * Canonical driver flush processing.
86: */
87:
88: if ((* mp->b_rptr & FLUSHW) != 0)
89: flushq (q, FLUSHALL);
90:
91: if ((* mp->b_rptr & FLUSHR) != 0)
92: flushq (RD (q), FLUSHALL);
93:
94: * mp->b_rptr &= ~ FLUSHW;
95:
96: if ((* mp->b_rptr & FLUSHR) != 0)
97: qreply (RD (q), mp);
98: else
99: freemsg (mp);
100: break;
101:
102: case M_DATA:
103: case M_PROTO:
104: case M_PCPROTO:
105: putq (q, mp);
106: break;
107:
108: default:
109: /*
110: * Discard unrecognized messages.
111: */
112:
113: freemsg (mp);
114: break;
115: }
116: }
117:
118:
119: #if __USE_PROTO__
120: void echowsrv (queue_t * q)
121: #else
122: void
123: echowsrv (q)
124: queue_t * q;
125: #endif
126: {
127: mblk_t * mp;
128:
129: while ((mp = getq (q)) != NULL) {
130: /*
131: * If the read side becomes full, keep the messages on this
132: * side to exert back-pressure upstream.
133: */
134:
135: if (! pcmsg (mp->b_datap->db_type) && ! canputnext (RD (q))) {
136:
137: putbq (q, mp);
138: break;
139: }
140:
141: putnext (RD (q), mp);
142: }
143: }
144:
145:
146: #if __USE_PROTO__
147: void echorsrv (queue_t * q)
148: #else
149: void
150: echorsrv (q)
151: queue_t * q;
152: #endif
153: {
154: /*
155: * Deal with being back-enabled by flow control by enabling the write
156: * side service procedure to retry sending the messages backed up
157: * there.
158: */
159:
160: qenable (WR (q));
161: }
162:
163:
164: #if __USE_PROTO__
165: int echoclose (queue_t * q, int __NOTUSED (flag), cred_t * __NOTUSED (credp))
166: #else
167: int
168: echoclose (q, flag, credp)
169: queue_t * q;
170: int flag;
171: cred_t * credp;
172: #endif
173: {
174: /*
175: * Disable put and service routines for the queue pair.
176: */
177:
178: qprocsoff (q);
179: return 0;
180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.