1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
45:
46: 47: 48: 49:
50:
51: #include "netdrv.h"
52:
53: 54: 55:
56: LOCAL ER ReadWriteReq(NetInf *inf, T_DEVREQ *req)
57: {
58: ER er;
59: W i, cmd, len, dsz;
60: VP mp;
61:
62: #define cmR 0x01
63: #define cmW 0x02
64: #define ckST 0x10
65:
66: static const struct {
67: W dno;
68: UH dsz;
69: UH flg;
70: } DaTab[] = {
71: {0, 0, cmW | ckST },
72: {DN_NETEVENT, sizeof(ID), cmR | cmW },
73: {DN_NETRESET, sizeof(W), cmR | cmW | ckST},
74: {DN_NETADDR, sizeof(NetAddr), cmR | ckST },
75: {DN_NETDEVINFO, sizeof(NetDevInfo), cmR },
76: {DN_NETSTINFO, sizeof(NetStInfo), cmR },
77: {DN_NETCSTINFO, sizeof(NetStInfo), cmR },
78: {DN_NETRXBUF, sizeof(VP), cmW },
79: {DN_NETRXBUFSZ, sizeof(NetRxBufSz), cmR | cmW },
80: {DN_NETMCASTLIST, 0, cmR | cmW | ckST},
81: {DN_NETALLMCAST, 0, cmW | ckST },
82: };
83:
84: #define N_DaTab (sizeof(DaTab) / (sizeof(W) + sizeof(UH) * 2))
85:
86:
87: if ((len = req->size) < 0) {er = E_PAR; goto EEXIT;}
88:
89:
90: er = tk_set_tsp(TSK_SELF, &req->tskspc);
91: if (er < E_OK) goto EEXIT;
92:
93: cmd = (req->cmd == TDC_READ) ? cmR : cmW;
94: mp = req->buf;
95:
96:
97: for (i = 0; i < N_DaTab && req->start != DaTab[i].dno; i++);
98: if (i >= N_DaTab) goto PAR_ERR;
99:
100:
101: if (DaTab[i].flg == 0) {er = E_NOSPT; goto EEXIT;}
102: if ((DaTab[i].flg & cmd) == 0) goto PAR_ERR;
103:
104:
105: if ((DaTab[i].flg & ckST) != 0 && inf->di.stat < E_OK)
106: {er = E_OBJ; goto EEXIT;}
107:
108:
109: if ((dsz = DaTab[i].dsz) != 0 && len < dsz) {
110: er = (len == 0) ? dsz : E_PAR;
111: goto NEXIT;
112: }
113:
114:
115: er = E_OK;
116: switch (req->start) {
117: case 0:
118: if (len <= 0 || len > MAXPKTLEN) er = E_PAR;
119: else {
120: 121: 122:
123: if ((dsz = len) < MINPKTLEN) {
124: UB buf[MINPKTLEN];
125: memcpy(buf, mp, len);
126: memset(&buf[len], 0, MINPKTLEN - len);
127: mp = (VP)buf;
128: len = MINPKTLEN;
129: }
130: er = (*(inf->sendfn))(inf, (UB*)mp, len);
131: }
132: break;
133:
134: case DN_NETEVENT:
135: if (cmd == cmR) *((W*)mp) = inf->mbfid;
136: else inf->mbfid = *((W*)mp);
137: break;
138:
139: case DN_NETRESET:
140: (*(inf->reset))(inf, TRUE);
141: break;
142:
143: case DN_NETADDR:
144: *((NetAddr*)mp) = inf->eaddr;
145: break;
146:
147: case DN_NETDEVINFO:
148: *((NetDevInfo*)mp) = inf->di;
149: break;
150:
151: case DN_NETSTINFO:
152: case DN_NETCSTINFO:
153: if (inf->misc != NULL && inf->di.stat >= E_OK)
154: (*(inf->misc))(inf, 0, DN_NETSTINFO, NULL, 0);
155: *((NetStInfo*)mp) = inf->stinf;
156: if (req->start == DN_NETCSTINFO)
157: memset(&inf->stinf, 0, sizeof(NetStInfo));
158: break;
159:
160: case DN_NETRXBUF:
161:
162: er = SetRxBuf(inf, *((VP*)mp));
163: break;
164:
165: case DN_NETRXBUFSZ:
166: if (cmd == cmR) {
167: *((NetRxBufSz*)mp) = inf->bufsz;
168: } else {
169: NetRxBufSz bsz = *((NetRxBufSz*)mp);
170:
171: bsz.maxsz &= (~3);
172: if (bsz.maxsz > MAXPKTLEN) bsz.maxsz = MAXPKTLEN;
173: if (bsz.minsz < 0 || bsz.minsz >= MINRXBUFSZ ||
174: bsz.maxsz <= bsz.minsz || bsz.maxsz < MINRXBUFSZ)
175: goto PAR_ERR;
176: inf->bufsz = bsz;
177: }
178: break;
179: case DN_NETMCASTLIST:
180: case DN_NETALLMCAST:
181: dsz = er = (inf->mcast == NULL) ? E_NOSPT :
182: (*(inf->mcast))(inf, cmd & cmW,
183: (req->start == DN_NETALLMCAST),
184: mp, len);
185: break;
186: }
187: NEXIT:
188: if (er < E_OK) goto EEXIT;
189:
190: req->asize = dsz;
191: return E_OK;
192:
193: PAR_ERR:
194: er = E_PAR;
195: EEXIT:
196:
197: DBG( if (er != E_BUSY)
198: DP(("Net%c: ReadWrite cmd:%d st:%d sz:%d [%#x]\n", NetUnit(inf),
199: req->cmd, req->start, req->size, er)); );
200:
201: return er;
202: }
203:
204: 205: 206:
207: EXPORT ER OpenProc(ID devid, UINT omode, GDI gdi)
208: {
209: NetInf *inf = GDI_exinf(gdi);
210: ER er = E_OK;
211:
212: if (! inf->exist) {
213: er = E_NOMDA;
214: } else if (inf->opencnt == 0) {
215: SetRxBuf(inf, NULL);
216: if ((er = CardPowerOn(inf, TRUE)) >= E_OK) {
217: if (inf->di.stat >= E_OK)
218: (*(inf->reset))(inf, TRUE);
219: }
220: }
221: if (er >= E_OK) inf->opencnt++;
222: return er;
223: }
224:
225: 226: 227:
228: EXPORT ER CloseProc(ID devid, UINT option, GDI gdi)
229: {
230: NetInf *inf = GDI_exinf(gdi);
231:
232: if (--inf->opencnt <= 0) {
233: inf->opencnt = 0;
234: inf->mbfid = INVALID_ID;
235: if (inf->exist) {
236: if (inf->di.stat >= E_OK && ! inf->poweroff)
237: (*(inf->reset))(inf, FALSE);
238: CardPowerOff(inf, TRUE);
239: }
240: }
241:
242: return E_OK;
243: }
244:
245: 246: 247:
248: EXPORT INT EventProc(INT evttyp, VP evtinf, GDI gdi)
249: {
250: NetInf *inf = GDI_exinf(gdi);
251:
252: switch (evttyp) {
253: case TDV_SUSPEND:
254: if (inf->exist) {
255: if (inf->di.stat >= E_OK && ! inf->poweroff)
256: (*(inf->reset))(inf, FALSE);
257: CardPowerOff(inf, FALSE);
258: }
259: inf->suspended = TRUE;
260: return E_OK;
261:
262: case TDV_RESUME:
263: if (inf->suspended) {
264: if (inf->exist) {
265: CardPowerOn(inf, FALSE);
266: if (inf->di.stat >= E_OK && inf->opencnt > 0)
267: (*(inf->reset))(inf, TRUE);
268: }
269: inf->suspended = FALSE;
270: }
271: return E_OK;
272:
273: case TDV_CARDEVT:
274: return CardEvent(inf, evtinf);
275:
276: default:
277: DP(("Net%c: EventProc evttyp:%d\n", evttyp));
278: return E_PAR;
279: }
280: }
281:
282: 283: 284:
285: EXPORT void AcceptRequest(NetInf *inf)
286: {
287: T_DEVREQ *devReq;
288: ER er;
289:
290:
291: for (;;) {
292:
293: er = GDI_Accept(&devReq, DRP_NORMREQ,
294: (inf->suspended || inf->tmofn == NULL ||
295: inf->tmout <= 0) ? TMO_FEVR : inf->tmout,
296: inf->Gdi);
297:
298: if (er < E_OK) {
299: if (er == E_TMOUT && inf->tmofn != NULL) {
300:
301: (*(inf->tmofn))(inf);
302: } else {
303:
304: DP(("Net%c: GDI_accept [%#x]\n", NetUnit(inf), er));
305:
306: }
307: continue;
308: }
309:
310:
311: er = (inf->exist) ? ReadWriteReq(inf, devReq) : E_NOMDA;
312:
313: DBG( if (er < E_OK && er != E_BUSY)
314: DP(("Net%c: cmd:%d [%#x]\n", NetUnit(inf), devReq->cmd,er)); );
315:
316:
317: devReq->error = er;
318: GDI_Reply(devReq, inf->Gdi);
319: }
320: }
321: