1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18: 19: 20:
21:
22: #include "line_drv.h"
23: #include <sys/sysinfo.h>
24:
25: 26: 27:
28: LOCAL ER ns16450_in(LINE_INFO *li, UB *buf, W len, W *alen, W tmout);
29: LOCAL ER ns16450_out(LINE_INFO *li, UB *buf, W len, W *alen, W tmout);
30: LOCAL ER ns16450_ctl(LINE_INFO *li, W kind, UW *arg);
31: LOCAL void ns16450_up(LINE_INFO *li);
32: LOCAL void ns16450_down(LINE_INFO *li);
33:
34: EXPORT SC_FUNC ScFuncNS16450 = {
35: ns16450_in, ns16450_out, ns16450_ctl, ns16450_up, ns16450_down,
36: };
37:
38: 39: 40:
41: #include "ns16450.h"
42: #include "ns16450sys.h"
43:
44:
45: #define _CLOCK UART_CLK
46:
47:
48: #define _IOADR(n) (scdefs->c.iobase + (n) * scdefs->c.iostep)
49:
50: 51: 52:
53: Inline void clr_screg( W port, UB m )
54: {
55: OutB(port, InB(port) & ~m);
56: }
57: Inline void set_screg( W port, UB m )
58: {
59: OutB(port, InB(port) | m);
60: }
61: Inline void set_screg2( W port, UB m, UB v )
62: {
63: OutB(port, (InB(port) & ~m) | v);
64: }
65:
66: 67: 68:
69: #define ON_RTS set_screg(SC_MCTL, MC_RTS|MC_OUT2)
70: #define OFF_RTS set_screg2(SC_MCTL, MC_RTS, MC_OUT2)
71: #define ON_BREAK set_screg(SC_LCTL, LC_SBRK)
72: #define OFF_BREAK clr_screg(SC_LCTL, LC_SBRK)
73:
74: 75: 76:
77:
78: #define ENB_RXINT(li) OutB(SC_INTE, (li->enbint == 0) ? \
79: 0x00 : (IM_LSTS|IM_RCV|IM_MSTS))
80: #define ENB_TXRXINT(li) OutB(SC_INTE, (li->enbint == 0) ? \
81: 0x00 : (IM_LSTS|IM_SND|IM_RCV|IM_MSTS))
82: #define DIS_TXRXINT(li) OutB(SC_INTE, 0x00)
83:
84: 85: 86:
87: LOCAL ER line_ctl( LINE_INFO *li, UW cmd )
88: {
89: SC_DEFS *scdefs = &li->scdefs;
90: UW line;
91: ER err = E_OK;
92:
93: line = cmd & (MC_RTS|MC_DTR);
94:
95: switch ( cmd & 0xfffffffc ) {
96: case RSCTL_ON:
97: set_screg(SC_MCTL, line | MC_OUT2);
98: break;
99: case RSCTL_OFF:
100: set_screg2(SC_MCTL, line, MC_OUT2);
101: break;
102: case RSCTL_SET:
103: set_screg2(SC_MCTL, MC_RTS|MC_DTR, line | MC_OUT2);
104: break;
105: default:
106: err = E_PAR;
107: }
108: return err;
109: }
110:
111: 112: 113:
114: LOCAL ER init_sio( LINE_INFO *li, RsMode mode )
115: {
116: SC_DEFS *scdefs = &li->scdefs;
117: UH divcnt;
118: UB lctl, fctl, mctl;
119: W i;
120: ER err = E_OK;
121:
122:
123: if ( mode.parity == 3
124: || mode.stopbits == 3
125: || mode.baud < 50 || mode.baud > SC_LINE_SPEED(1) ) return E_PAR;
126:
127:
128: divcnt = SC_LINE_SPEED(mode.baud);
129:
130:
131: lctl = 0x00;
132: if ( mode.datalen == 0 ) {
133:
134: if ( mode.stopbits == 2 ) return E_NOSPT;
135: if ( mode.stopbits == 1 ) lctl |= LC_STOP;
136: } else {
137:
138: if ( mode.stopbits == 1 ) return E_NOSPT;
139: if ( mode.stopbits == 2 ) lctl |= LC_STOP;
140: lctl |= mode.datalen;
141: }
142: switch ( mode.parity ) {
143: case 1: lctl |= LC_OddParity; break;
144: case 2: lctl |= LC_EvenParity; break;
145: }
146:
147:
148: fctl = FC_FIFO;
149: fctl |= ( mode.baud < 9600 )? FC_TL01: FC_TL08;
150:
151:
152: mctl = ( li->suspend == 0 )? MC_RTS|MC_DTR|MC_OUT2: MC_OUT2;
153:
154:
155: li->enbint = 0;
156: DIS_TXRXINT(li);
157:
158:
159: for ( i = 0; i < FIFO_SIZE; ++i ) {
160: if ( (InB(SC_LSTS) & LS_TSRE) != 0 ) break;
161: tk_dly_tsk(100);
162: }
163:
164:
165: OutB(SC_LCTL, 0x00);
166: InB(SC_LSTS);
167: InB(SC_INTS);
168: InB(SC_MSTS);
169:
170:
171: for ( i = 0; i < FIFO_SIZE; ++i ) {
172: InB(SC_DATA);
173: }
174:
175: if ( fctl != 0 ) {
176:
177: OutB(SC_FCTL, fctl);
178: if ( (InB(SC_INTS) & IS_FIFO) == 0 ) {
179: fctl = 0;
180: }
181: }
182: scdefs->fctl = fctl;
183:
184:
185: if ( fctl == 0 && mode.baud > 19200 ) err = E_NOSPT;
186:
187:
188: if ( li->flowsts.rsoff ) mctl &= ~MC_RTS;
189:
190:
191: OutB(SC_LCTL, LC_DLAB);
192: OutB(SC_DIVH, divcnt >> 8);
193: OutB(SC_DIVL, divcnt & 0xff);
194: OutB(SC_LCTL, lctl);
195: OutB(SC_FCTL, (fctl == 0) ? 0 : (fctl|FC_TXCLR|FC_RXCLR));
196:
197: li->msts = InB(SC_MSTS);
198:
199: OutB(SC_MCTL, mctl);
200:
201: if ( err == E_OK && li->suspend == 0 ) {
202: li->enbint = 1;
203: ENB_RXINT(li);
204: }
205:
206: return err;
207: }
208:
209: 210: 211:
212: EXPORT void sio_inthdr( UINT dintno )
213: {
214: LINE_INFO *li;
215: SC_DEFS *scdefs;
216: UB lsts, fctl, c;
217: UW ptr, nptr;
218: W i, n, cnt;
219:
220:
221: for (li = &LineInfo[0], i = nPorts; ; li++) {
222: if (--i < 0) return;
223: if (li->scdefs.c.intvec == dintno) {
224: if (li->scdefs.fn != &ScFuncNS16450) return;
225: break;
226: }
227: }
228: scdefs = &li->scdefs;
229: fctl = scdefs->fctl;
230:
231:
232:
233: while( (InB(SC_INTS) & IS_PEND) == 0 ) {
234:
235: 236: 237:
238:
239: for ( cnt = 0; cnt < FIFO_SIZE; cnt++ ) {
240: lsts = InB(SC_LSTS);
241:
242: if ( (lsts & LS_RxERR) != 0 ) {
243: UB s;
244:
245:
246: s = lsts & LS_RxERR;
247: li->lsts |= s;
248: li->lstshist |= s;
249:
250:
251: if ( li->in_wptr == li->in_rptr ) {
252: tk_set_flg(li->flg, FLG_IN_NORM);
253: }
254:
255: if ( fctl != 0 && (lsts & LS_OERR) != 0 ) {
256: 257:
258: OutB(SC_FCTL, fctl|FC_RXCLR);
259: }
260:
261:
262: InB(SC_DATA);
263: continue;
264: }
265:
266: if ( (lsts & LS_DRDY) == 0 ) break;
267:
268:
269:
270: c = InB(SC_DATA);
271:
272:
273: if ( li->extfn != NULL ) {
274: if ( (*li->extfn)(li->extpar, c) ) continue;
275: }
276:
277:
278: if ( li->flow.sxflow ) {
279: if ( c == XOFF ) {
280: li->flow.rcvxoff = 1;
281: continue;
282: }
283: if ( c == XON
284: || (li->flow.rcvxoff && li->flow.xonany) ) {
285: li->flow.rcvxoff = 0;
286: continue;
287: }
288: }
289:
290: 291:
292: ptr = li->in_wptr;
293: nptr = PTRMASK(li, ptr + 1);
294: if ( nptr == li->in_rptr ) {
295: li->lsts |= LS_RXOV;
296: li->lstshist |= LS_RXOV;
297: continue;
298: }
299:
300:
301: li->in_buf[ptr] = c;
302: li->in_wptr = nptr;
303:
304:
305: if ( ptr == li->in_rptr ) tk_set_flg(li->flg, FLG_IN_NORM);
306:
307:
308: if ( (li->flow.rsflow || li->flow.rxflow)
309: && IN_BUF_REMAIN(li) < XOFF_MARGIN ) {
310:
311: if ( li->flow.rsflow && li->flowsts.rsoff == 0 ) {
312: li->flowsts.rsoff = 1;
313: OFF_RTS;
314: }
315:
316: if ( li->flow.rxflow && li->flowsts.sndxoff == 0 ) {
317: li->flowsts.sndxoff = 1;
318: li->flowsts.reqchar = XOFF;
319: }
320: }
321: }
322:
323:
324: li->msts = InB(SC_MSTS);
325:
326: if ( (lsts & LS_THRE) != 0
327: && li->flow.rcvxoff == 0
328: && (li->flow.csflow == 0 || (li->msts & MS_CS) != 0)
329: ) {
330: cnt = n = li->ou_wptr - li->ou_rptr;
331:
332: if ( li->flowsts.reqchar != 0 ) n++;
333: if ( fctl != 0 ) {
334: if ( n > FIFO_SIZE ) n = FIFO_SIZE;
335:
336: } else {
337: if ( n > 1 ) n = 1;
338: }
339:
340: if ( n > 0 ) {
341: if ( li->flowsts.reqchar != 0 ) {
342:
343: OutB(SC_DATA, li->flowsts.reqchar);
344: li->flowsts.reqchar = 0;
345: n--;
346: }
347: cnt -= n;
348:
349: ENB_TXRXINT(li);
350:
351:
352: while ( --n >= 0 ) {
353: OutB(SC_DATA, li->ou_buf[
354: OU_PTRMASK(li, li->ou_rptr++)]);
355: }
356: } else {
357:
358: ENB_RXINT(li);
359: }
360:
361: if (cnt < li->ou_cnt) {
362: tk_set_flg(li->flg, FLG_OU_NORM);
363: li->ou_cnt = 0;
364: }
365: } else {
366: 367:
368: if ((lsts & LS_THRE) != 0) ENB_RXINT(li);
369: }
370: }
371:
372:
373: end_inthdr(scdefs);
374: }
375:
376: 377: 378:
379: LOCAL ER setHwConf( LINE_INFO *li, RsHwConf_16450 *conf,
380: RsMode mode, BOOL startup )
381: {
382: SC_DEFS *scdefs = &li->scdefs;
383: ER err;
384:
385:
386: if ( scdefs->c.iostep > 0 ) {
387:
388: li->enbint = 0;
389: DIS_TXRXINT(li);
390:
391:
392: delete_inthdr(scdefs, sio_inthdr);
393: }
394:
395:
396: scdefs->c = *conf;
397: li->mode = mode;
398:
399: if ( scdefs->c.iostep > 0 ) {
400:
401:
402: li->enbint = 0;
403: DIS_TXRXINT(li);
404:
405:
406: err = regist_inthdr(scdefs, sio_inthdr);
407: if (err < E_OK) return err;
408:
409:
410: err = init_sio(li, mode);
411: if ( err < E_OK ) {
412:
413: li->mode = scdefs->mode;
414: err = init_sio(li, li->mode);
415: if ( err < E_OK ) return err;
416: }
417:
418: }
419:
420: return E_OK;
421: }
422:
423: 424: 425:
426: LOCAL RsStat make_line_stat( LINE_INFO *li, UB lsts )
427: {
428: RsStat stat;
429: static RsStat stat0 = {0};
430:
431: stat = stat0;
432: if ( (lsts & LS_RXOV) != 0 ) stat.BE = 1;
433: if ( (lsts & LS_FERR) != 0 ) stat.FE = 1;
434: if ( (lsts & LS_OERR) != 0 ) stat.OE = 1;
435: if ( (lsts & LS_PERR) != 0 ) stat.PE = 1;
436: stat.XF = li->flow.rcvxoff;
437: if ( (lsts & LS_BINT) != 0 ) stat.BD = 1;
438: if ( (li->msts & MS_DR) != 0 ) stat.DR = 1;
439: if ( (li->msts & MS_CD) != 0 ) stat.CD = 1;
440: if ( (li->msts & MS_CS) != 0 ) stat.CS = 1;
441: if ( (li->msts & MS_RI) != 0 ) stat.CI = 1;
442: return stat;
443: }
444:
445: 446: 447: 448: 449: 450: 451:
452: LOCAL BOOL send_1st_char( LINE_INFO *li, W c )
453: {
454: SC_DEFS *scdefs = &li->scdefs;
455: UB lsts, s;
456: W n;
457:
458:
459: if ( li->flow.rcvxoff != 0 ) return FALSE;
460:
461:
462: lsts = InB(SC_LSTS);
463: li->msts = InB(SC_MSTS);
464:
465:
466: if ( (s = lsts & LS_RxERR) != 0 ) {
467: li->lsts |= s;
468: li->lstshist |= s;
469: }
470:
471:
472: if ( (lsts & LS_THRE) == 0
473: || (li->flow.csflow != 0 && (li->msts & MS_CS) == 0) ) return FALSE;
474:
475: if ( c < 0 ) {
476: n = li->ou_wptr - li->ou_rptr;
477: if ( n <= 0 ) return FALSE;
478: if ( scdefs->fctl != 0 ) {
479:
480: if ( n > FIFO_SIZE ) n = FIFO_SIZE;
481:
482: } else {
483: n = 1;
484: }
485: c = li->ou_buf[OU_PTRMASK(li, li->ou_rptr++)];
486: } else {
487: n = 1;
488: }
489:
490:
491: ENB_TXRXINT(li);
492: OutB(SC_DATA, c);
493: while ( --n > 0 )
494: OutB(SC_DATA, li->ou_buf[OU_PTRMASK(li, li->ou_rptr++)]);
495: return TRUE;
496: }
497:
498: 499: 500:
501: LOCAL WRTN recv_one_char( LINE_INFO *li, W tmout )
502: {
503: SC_DEFS *scdefs = &li->scdefs;
504: UB c;
505: UINT flgptn;
506: UW imask;
507: ER er;
508:
509:
510: while ( li->in_wptr == li->in_rptr ) {
511:
512: if ( tmout == 0 ) return RTN_NONE;
513:
514:
515: er = tk_wai_flg(li->flg, FLG_IN_WAIPTN,
516: TWF_ORW | TWF_BITCLR, &flgptn, tmout);
517: if ( er == E_TMOUT ) return RTN_TMOUT;
518: if ( er < E_OK || (flgptn & FLG_IN_ABORT) ) return RTN_ABORT;
519: if ( li->lsts != 0 ) return RTN_ERR;
520: }
521:
522:
523: c = li->in_buf[li->in_rptr];
524: li->in_rptr = PTRMASK(li, li->in_rptr + 1);
525:
526:
527: if ( (li->flowsts.rsoff || li->flowsts.sndxoff)
528: && IN_BUF_REMAIN(li) > XON_MARGIN ) {
529: 530:
531: if ( li->flowsts.rsoff ) {
532:
533: DI(imask);
534: ON_RTS;
535: li->flowsts.rsoff = 0;
536: EI(imask);
537: }
538: if ( li->flowsts.sndxoff ) {
539:
540: DI(imask);
541: if ( !send_1st_char(li, XON) ) {
542: li->flowsts.reqchar = XON;
543:
544: }
545: li->flowsts.sndxoff = 0;
546: EI(imask);
547: }
548: }
549:
550: return c;
551: }
552:
553: 554: 555:
556: LOCAL ER ns16450_in( LINE_INFO *li, UB *buf, W len, W *alen, W tmout )
557: {
558: SC_DEFS *scdefs = &li->scdefs;
559: W c;
560: UW rsz = 0;
561: RsErr err;
562:
563: if ( scdefs->c.iostep <= 0 ) return E_NOMDA;
564:
565:
566: 567:
568: if (tmout == 0 && li->in_wptr == li->in_rptr) {
569: err.w = E_BUSY;
570: goto EEXIT;
571: }
572:
573:
574: if ( consMLock(&li->lock, IN_LOCK) < E_OK ) {
575: err.s = make_line_stat(li, 0);
576: err.c.ErrorClass = MERCD(E_IO);
577: err.c.Aborted = 1;
578: goto EEXIT;
579: }
580:
581: err.w = E_OK;
582:
583: if ( len <= 0 ) {
584:
585: rsz = IN_BUF_SIZE(li);
586: } else {
587: li->lsts = 0;
588:
589:
590: for ( rsz = 0; rsz < len; rsz++ ) {
591:
592: c = recv_one_char(li, tmout);
593: if ( c < RTN_OK ) {
594: if ( c == RTN_NONE ) {
595: err.w = ( rsz > 0 )? E_OK: E_BUSY;
596: } else {
597: err.s = make_line_stat(li, li->lsts);
598: err.c.ErrorClass = MERCD(E_IO);
599: if ( c == RTN_TMOUT ) err.c.Timout = 1;
600: if ( c == RTN_ABORT ) err.c.Aborted= 1;
601: }
602: break;
603: }
604: buf[rsz] = c;
605: }
606: }
607:
608:
609: tk_clr_flg(li->flg, ~(FLG_IN_ABORT | FLG_OU_ABORT));
610:
611:
612: consMUnlock(&li->lock, IN_LOCK);
613:
614: EEXIT:
615:
616: *alen = rsz;
617: return err.w;
618: }
619:
620: 621: 622:
623: LOCAL ER ns16450_out( LINE_INFO *li, UB *buf, W len, W *alen, W tmout )
624: {
625: SC_DEFS *scdefs = &li->scdefs;
626: RsErr err;
627: W sz, n;
628: RTN r;
629: UW wptr, ptr, imask;
630: UINT flgptn;
631: ER er;
632:
633: if ( scdefs->c.iostep <= 0 ) return E_NOMDA;
634:
635:
636: *alen = 0;
637:
638:
639: if ( consMLock(&li->lock, OU_LOCK) < E_OK ) {
640: err.s = make_line_stat(li, 0);
641: err.c.ErrorClass = MERCD(E_IO);
642: err.c.Aborted = 1;
643: goto EEXIT;
644: }
645:
646: err.w = E_OK;
647:
648: 649: 650: 651: 652: 653: 654:
655:
656: for (wptr = li->ou_wptr; len > 0; ) {
657:
658:
659: sz = li->ou_rptr + OUBUFSZ - li->ou_wptr;
660: if (sz > len) sz = len;
661: n = OUBUFSZ - (ptr = OU_PTRMASK(li, li->ou_wptr));
662: if (n > sz) n = sz;
663: if (n > 0) MEMCPY(&li->ou_buf[ptr], buf, n);
664: if (sz > n) MEMCPY(&li->ou_buf[0], &buf[n], sz - n);
665: buf += sz;
666: len -= sz;
667:
668: DI(imask);
669: if (len <= 0) {
670: 671: 672:
673: n = 1;
674: if (tmout == 0) n = 0;
675:
676:
677: } else {
678: 679: 680:
681: if ((n = OUBUFSZ - len) < 20) n = 20;
682: }
683: li->ou_cnt = n;
684: li->ou_wptr += sz;
685:
686: 687:
688: if ((InB(SC_INTE) & IM_SND) == 0) send_1st_char(li, -1);
689:
690: EI(imask);
691:
692:
693: for (r = RTN_OK; li->ou_cnt != 0; ) {
694: ptr = li->ou_rptr;
695: er = tk_wai_flg(li->flg, FLG_OU_WAIPTN,
696: TWF_ORW | TWF_BITCLR, &flgptn, tmout);
697: if ( er == E_TMOUT ) {
698: 699: 700:
701: if ( ptr == li->ou_rptr ) {
702: r = RTN_TMOUT;
703: break;
704: }
705: } else if ( er < E_OK || (flgptn & FLG_OU_ABORT) ) {
706: r = RTN_ABORT;
707: break;
708: }
709: }
710: if ( r < RTN_OK ) {
711: err.s = make_line_stat(li, 0);
712: err.c.ErrorClass = MERCD(E_IO);
713: if ( r == RTN_TMOUT ) err.c.Timout = 1;
714: if ( r == RTN_ABORT ) err.c.Aborted = 1;
715: DI(imask);
716: li->ou_wptr = li->ou_rptr;
717: EI(imask);
718: break;
719: }
720: }
721:
722: *alen = li->ou_wptr - wptr;
723: li->ou_cnt = 0;
724:
725:
726: tk_clr_flg(li->flg, ~(FLG_IN_ABORT | FLG_OU_ABORT));
727:
728:
729: consMUnlock(&li->lock, OU_LOCK);
730:
731: EEXIT:
732:
733: return err.w;
734: }
735:
736: 737: 738:
739: LOCAL ER ns16450_ctl( LINE_INFO *li, W kind, UW *arg )
740: {
741: SC_DEFS *scdefs = &li->scdefs;
742: ER err = E_OK;
743: UW imask;
744: W n;
745:
746: if ( !(kind == DN_RS16450 || kind == -DN_RS16450)
747: && scdefs->c.iostep <= 0 ) return E_NOMDA;
748:
749:
750:
751:
752: switch ( kind ) {
753: case RS_ABORT:
754: tk_set_flg(li->flg, FLG_IN_ABORT | FLG_OU_ABORT);
755: break;
756:
757: case RS_SUSPEND:
758: case RS_RESUME:
759: 760:
761: if ( !(isDebugPort(li) && _isDebugMode()) ) {
762: if (kind == RS_RESUME) sio_susres(li, 1);
763:
764:
765: li->suspend = (kind == RS_SUSPEND) ? 1 : 0;
766: err = setHwConf(li, &li->scdefs.c, li->mode, FALSE);
767:
768: if (kind == RS_SUSPEND) sio_susres(li, 0);
769: }
770: break;
771:
772: case DN_RSMODE:
773: err = init_sio(li, *(RsMode*)arg);
774: if ( err == E_OK ) {
775:
776: DI(imask);
777: li->in_rptr = li->in_wptr = 0;
778: li->ou_rptr = li->ou_wptr = 0;
779: li->ou_cnt = li->ou_len = 0;
780: li->flow = li->scdefs.flow;
781: li->flowsts = li->scdefs.flowsts;
782: li->lsts = li->lstshist = 0;
783: li->mode = *(RsMode*)arg;
784: EI(imask);
785: }
786: break;
787:
788: case -DN_RSMODE:
789: *(RsMode*)arg = li->mode;
790: break;
791:
792: case DN_RSFLOW:
793: li->flow = *(RsFlow*)arg;
794: break;
795:
796: case -DN_RSFLOW:
797: *(RsFlow*)arg = li->flow;
798: break;
799:
800: case -DN_RSSTAT:
801: *(RsStat*)arg = make_line_stat(li, li->lstshist);
802: li->lstshist = 0;
803: break;
804:
805: case DN_RSBREAK:
806: if ( (n = *arg) > 0 ) {
807: DI(imask); ON_BREAK; EI(imask);
808: tk_dly_tsk(n);
809: DI(imask); OFF_BREAK; EI(imask);
810: }
811: break;
812:
813: case RS_RCVBUFSZ:
814: if ( (n = *arg) < MIN_INBUFSZ ) {
815: err = E_PAR;
816: break;
817: }
818: if ( n != li->in_bufsz ) {
819: UB *new, *old;
820: new = Malloc(n);
821: if ( new != NULL ) {
822: DI(imask);
823: old = li->in_buf;
824: li->in_buf = new;
825: li->in_rptr = li->in_wptr = 0;
826: li->in_bufsz = n;
827: EI(imask);
828: Free(old);
829: } else {
830: err = E_NOMEM;
831: }
832: }
833: break;
834:
835: case -RS_RCVBUFSZ:
836: *arg = li->in_bufsz;
837: break;
838:
839: case RS_LINECTL:
840: err = line_ctl(li, *arg);
841: break;
842:
843: case RS_EXTFUNC:
844: if ( li->extfn != NULL && (FUNCP)arg[0] != NULL ) {
845: err = E_OBJ;
846: } else {
847: DI(imask);
848: li->extfn = (FUNCP)arg[0];
849: li->extpar = arg[1];
850: EI(imask);
851: }
852: break;
853:
854: case DN_RS16450:
855: err = setHwConf(li, (RsHwConf_16450*)arg, li->mode, FALSE);
856: break;
857:
858: case -DN_RS16450:
859: *(RsHwConf_16450*)arg = scdefs->c;
860: break;
861:
862: default:
863: err = E_PAR;
864: }
865:
866: return err;
867: }
868:
869: 870: 871:
872: LOCAL void ns16450_down( LINE_INFO *li )
873: {
874: SC_DEFS *scdefs = &li->scdefs;
875:
876: if ( scdefs->c.iostep > 0 ) {
877: li->enbint = 0;
878: DIS_TXRXINT(li);
879: OutB(SC_MCTL, 0x00);
880: }
881: }
882:
883: 884: 885:
886: LOCAL void ns16450_up( LINE_INFO *li )
887: {
888: li->suspend = 0;
889: li->flow = li->scdefs.flow;
890: setHwConf(li, &li->scdefs.c, li->scdefs.mode, TRUE);
891: }