1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13: #include <sys/machine.h>
14: #include <tk/tkernel.h>
15: #include <tstdlib.h>
16:
17: #include "ser.h"
18: #include "../include/dev_def.h"
19: #if DEV_SER_ENABLE
20: 21: 22: 23:
24:
25:
26: 27:
28: #if TK_SUPPORT_MEMLIB
29:
30: LOCAL T_SER_DCB *dev_ser_cb[DEV_SER_UNITNM];
31: #define get_dcb_mem(unit,a) (dev_ser_cb[unit]->a)
32:
33: #else
34:
35: LOCAL T_SER_DCB dev_ser_cb[DEV_SER_UNITNM];
36: #define get_dcb_mem(unit,a) (dev_ser_cb[unit].a)
37:
38: #endif
39:
40:
41: 42: 43: 44:
45: EXPORT BOOL dev_ser_get_snddat(UW unit, UW *data)
46: {
47: T_SER_BUFF *p_buff;
48:
49: p_buff = &get_dcb_mem(unit, snd_buff);
50: if(p_buff->top != p_buff->tail) {
51: *data = p_buff->data[p_buff->tail];
52: if(++p_buff->tail >= DEVCONF_SER_BUFFSIZE) p_buff->tail = 0;
53:
54: if(p_buff->wait_tskid) {
55: tk_wup_tsk( p_buff->wait_tskid);
56: p_buff->wait_tskid = 0;
57: }
58: return TRUE;
59: } else {
60: return FALSE;
61: }
62: }
63:
64: EXPORT void dev_ser_notify_rcv(UW unit, UW data)
65: {
66: T_SER_BUFF *p_buff;
67: INT next;
68:
69: p_buff = &get_dcb_mem( unit, rcv_buff);
70: next = p_buff->top + 1;
71: if(next >= DEVCONF_SER_BUFFSIZE) next = 0;
72: if(next != p_buff->tail) {
73: p_buff->data[p_buff->top] = data;
74: p_buff->top = next;
75: } else {
76: dev_ser_notify_err( unit, DEV_SER_ERR_ROVR);
77: }
78:
79: if(p_buff->wait_tskid) {
80: tk_wup_tsk( p_buff->wait_tskid);
81: p_buff->wait_tskid = 0;
82: }
83:
84: }
85:
86: EXPORT void dev_ser_notify_err(UW unit, UW err)
87: {
88: get_dcb_mem(unit, com_error) |= err;
89: }
90:
91:
92: 93:
94:
95: LOCAL ER set_atr_size(T_DEVREQ *req)
96: {
97: switch(req->start) {
98: case TDN_EVENT:
99: req->asize = sizeof(ID);
100: break;
101: case TDN_SER_MODE:
102: case TDN_SER_SPEED:
103: case TDN_SER_COMERR:
104: req->asize = sizeof(UW);
105: break;
106: case TDN_SER_SNDTMO:
107: case TDN_SER_RCVTMO:
108: req->asize = sizeof(TMO);
109: break;
110: default:
111: return E_PAR;
112: }
113: return E_OK;
114: }
115:
116: LOCAL ER read_atr(T_SER_DCB *p_dcb, T_DEVREQ *req)
117: {
118: UINT imask;
119: ER err;
120:
121: err = set_atr_size(req);
122: if(err != E_OK) return err;
123:
124: if(req->size) {
125: switch(req->start) {
126: case TDN_EVENT:
127: *(ID*)req->buf = p_dcb->evtmbfid;
128: break;
129: case TDN_SER_MODE:
130: *(UW*)req->buf = p_dcb->com_mode;
131: break;
132: case TDN_SER_SPEED:
133: *(UW*)req->buf = p_dcb->com_speed;
134: break;
135: case TDN_SER_SNDTMO:
136: *(TMO*)req->buf = p_dcb->snd_tmo;
137: break;
138: case TDN_SER_RCVTMO:
139: *(TMO*)req->buf = p_dcb->rcv_tmo;
140: break;
141: case TDN_SER_COMERR:
142: DI(imask);
143: *(UW*)req->buf = p_dcb->com_error;
144: p_dcb->com_error = 0;
145: EI(imask);
146: break;
147: case TDN_SER_BREAK:
148:
149: default:
150: err = E_PAR;
151: }
152: }
153: return err;
154: }
155:
156: LOCAL ER write_atr(T_SER_DCB *p_dcb, T_DEVREQ *req)
157: {
158: ER err;
159:
160: err = set_atr_size(req);
161: if(err != E_OK) return err;
162:
163: if(req->size) {
164: switch(req->start) {
165: case TDN_EVENT:
166: p_dcb->evtmbfid = *(ID*)req->buf;
167: break;
168: case TDN_SER_MODE:
169: p_dcb->com_mode = *(UW*)req->buf;
170: err = dev_ser_llctl( p_dcb->unit, LLD_SER_MODE, p_dcb->com_mode);
171: break;
172: case TDN_SER_SPEED:
173: p_dcb->com_speed = *(UW*)req->buf;
174: err = dev_ser_llctl( p_dcb->unit, LLD_SER_SPEED, p_dcb->com_speed);
175: break;
176: case TDN_SER_SNDTMO:
177: p_dcb->snd_tmo = *(TMO*)req->buf;
178: break;
179: case TDN_SER_RCVTMO:
180: p_dcb->rcv_tmo = *(TMO*)req->buf;
181: break;
182: case TDN_SER_BREAK:
183: err = dev_ser_llctl( p_dcb->unit, LLD_SER_BREAK, *(UW*)req->buf);
184: break;
185: default:
186: err = E_PAR;
187: }
188: }
189: return err;
190: }
191:
192:
193: 194:
195:
196: LOCAL ER read_data( T_SER_DCB *p_dcb, T_DEVREQ *req)
197: {
198: T_SER_BUFF *p_buff;
199: UW tail;
200: UB *pd;
201: SZ rsize;
202: ER err;
203:
204: p_buff = &p_dcb->rcv_buff;
205: tail = p_buff->tail;
206: pd = req->buf;
207: rsize = req->size;
208: err = E_OK;
209:
210: if(rsize != 0 ) {
211: while(rsize) {
212: DisableInt(p_dcb->intno_rcv);
213: if(p_buff->top != tail) {
214: *pd++ = p_buff->data[tail++];
215: if(tail >= DEVCONF_SER_BUFFSIZE ) tail = 0;
216: p_buff->tail = tail;
217: EnableInt(p_dcb->intno_rcv, DEVCNF_SER_INTPRI);
218: rsize--;
219: } else {
220: p_buff->wait_tskid = tk_get_tid();
221: EnableInt(p_dcb->intno_rcv, DEVCNF_SER_INTPRI);
222: err = tk_slp_tsk(p_dcb->rcv_tmo);
223: if( err != E_OK) break;
224: }
225: }
226: req->asize = req->size - rsize;
227: } else {
228:
229: rsize = p_buff->top - p_buff->tail;
230:
231: if(rsize < 0) {
232: rsize += DEVCONF_SER_BUFFSIZE;
233: }
234: req->asize = rsize;
235: }
236:
237: return err;
238: }
239:
240: LOCAL ER write_data( T_SER_DCB *p_dcb, T_DEVREQ *req)
241: {
242: T_SER_BUFF *p_buff;
243: UW next;
244: UB *pd;
245: INT ssize;
246: ER err;
247: BOOL s;
248:
249: p_buff = &p_dcb->snd_buff;
250: pd = req->buf;
251: ssize = req->size;
252: err = E_OK;
253:
254: if(ssize != 0) {
255: while(ssize) {
256: next = p_buff->top + 1;
257: if(next >= DEVCONF_SER_BUFFSIZE) next = 0;
258:
259: DisableInt(p_dcb->intno_snd);
260: if(next != p_buff->tail) {
261: s = FALSE;
262: if(p_buff->top == p_buff->tail) {
263: s = (E_OK == dev_ser_llctl( p_dcb->unit, LLD_SER_SEND, *pd));
264: }
265: if(s) {
266: pd++;
267: } else {
268: p_buff->data[p_buff->top] = *pd++;
269: p_buff->top = next;
270: }
271: EnableInt(p_dcb->intno_snd, DEVCNF_SER_INTPRI);
272: ssize--;
273: } else {
274: p_buff->wait_tskid = tk_get_tid();
275: EnableInt(p_dcb->intno_snd, DEVCNF_SER_INTPRI);
276: err = tk_slp_tsk(p_dcb->snd_tmo);
277: if(err != E_OK) break;
278: }
279: }
280: req->asize = req->size - ssize;
281: } else {
282: DisableInt(p_dcb->intno_snd);
283: ssize = p_buff->top - p_buff->tail;
284: EnableInt(p_dcb->intno_snd, DEVCNF_SER_INTPRI);
285: if(ssize < 0) {
286: ssize += DEVCONF_SER_BUFFSIZE;
287: }
288: req->asize = DEVCONF_SER_BUFFSIZE - ssize;
289: }
290:
291: return err;
292: }
293:
294: 295: 296:
297: 298: 299:
300: ER dev_ser_openfn( ID devid, UINT omode, T_MSDI *p_msdi)
301: {
302: T_SER_DCB *p_dcb;
303: ER err;
304:
305: p_dcb = (T_SER_DCB*)p_msdi->dmsdi.exinf;
306:
307:
308: p_dcb->omode = omode;
309: buff_init(&p_dcb->snd_buff);
310: buff_init(&p_dcb->rcv_buff);
311:
312: err = dev_ser_llctl(p_dcb->unit, LLD_SER_START, 0);
313:
314: return err;
315: }
316:
317: 318: 319:
320: ER dev_ser_closefn( ID devid, UINT option, T_MSDI *p_msdi)
321: {
322: T_SER_DCB *p_dcb;
323: ER err;
324:
325: p_dcb = (T_SER_DCB*)(p_msdi->dmsdi.exinf);
326:
327:
328: err = dev_ser_llctl(p_dcb->unit, LLD_SER_STOP, 0);
329:
330: return err;
331: }
332:
333: 334: 335:
336: ER dev_ser_readfn( T_DEVREQ *req, T_MSDI *p_msdi)
337: {
338: T_SER_DCB *p_dcb;
339: ER err;
340:
341: p_dcb = (T_SER_DCB*)(p_msdi->dmsdi.exinf);
342:
343: if(req->start >= 0) {
344: if( p_dcb->omode & TD_READ ) {
345: err = read_data( p_dcb, req);
346: } else {
347: err = E_OACV;
348: }
349: } else {
350: err = read_atr( p_dcb, req);
351: }
352:
353: return err;
354: }
355:
356: 357: 358:
359: ER dev_ser_writefn( T_DEVREQ *req, T_MSDI *p_msdi)
360: {
361: T_SER_DCB *p_dcb;
362: ER err;
363:
364: p_dcb = (T_SER_DCB*)(p_msdi->dmsdi.exinf);
365:
366: if(req->start >= 0) {
367: if( p_dcb->omode & TD_WRITE) {
368: err = write_data( p_dcb, req);
369: } else {
370: err = E_OACV;
371: }
372: } else {
373: err = write_atr( p_dcb, req);
374: }
375:
376: return err;
377: }
378:
379: 380: 381:
382: ER dev_ser_eventfn( INT evttyp, void *evtinf, T_MSDI *p_msdi)
383: {
384: return E_NOSPT;
385: }
386:
387: 388: 389:
390: EXPORT ER dev_init_ser( UW unit )
391: {
392: T_SER_DCB *p_dcb;
393: T_IDEV idev;
394: T_MSDI *p_msdi;
395: T_DMSDI dmsdi;
396: ER err;
397: INT i;
398:
399: if( unit >= DEV_SER_UNITNM) return E_PAR;
400:
401: #if TK_SUPPORT_MEMLIB
402: p_dcb = (T_SER_DCB*)Kmalloc(sizeof(T_SER_DCB));
403: if( p_dcb == NULL) return E_NOMEM;
404: dev_ser_cb[unit] = p_dcb;
405: #else
406: p_dcb = &dev_ser_cb[unit];
407: #endif
408:
409:
410: dmsdi.exinf = p_dcb;
411: dmsdi.drvatr = 0;
412: dmsdi.devatr = TDK_UNDEF;
413: dmsdi.nsub = 0;
414: dmsdi.blksz = 1;
415: dmsdi.openfn = dev_ser_openfn;
416: dmsdi.closefn = dev_ser_closefn;
417: dmsdi.readfn = dev_ser_readfn;
418: dmsdi.writefn = dev_ser_writefn;
419: dmsdi.eventfn = dev_ser_eventfn;
420:
421: knl_strcpy( (char*)dmsdi.devnm, DEVCNF_SER_DEVNAME);
422: i = knl_strlen(DEVCNF_SER_DEVNAME);
423: dmsdi.devnm[i] = (UB)('a' + unit);
424: dmsdi.devnm[i+1] = 0;
425:
426: err = msdi_def_dev( &dmsdi, &idev, &p_msdi);
427: if(err != E_OK) goto err_2;
428:
429: p_dcb->unit = unit;
430: p_dcb->evtmbfid = idev.evtmbfid;
431:
432:
433: err = dev_ser_llinit( p_dcb);
434: if(err != E_OK) goto err_1;
435:
436:
437: p_dcb->com_speed = DEVCNF_SER_SPEED;
438: dev_ser_llctl( unit, LLD_SER_SPEED, DEVCNF_SER_SPEED);
439: p_dcb->com_mode = DEVCNF_SER_MODE;
440: dev_ser_llctl( unit, LLD_SER_MODE, DEVCNF_SER_MODE);
441: p_dcb->snd_tmo = DEVCNF_SER_SND_TMO;
442: p_dcb->rcv_tmo = DEVCNF_SER_RCV_TMO;
443:
444: return E_OK;
445:
446: err_1:
447: msdi_del_dev(p_msdi);
448: err_2:
449: Kfree(p_dcb);
450: return err;
451: }
452:
453: #endif