00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sys/types.h>
00023 #include <sys/sched.h>
00024 #include <sys/kernel.h>
00025 #include <sys/proxy.h>
00026 #include <sys/psinfo.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <errno.h>
00030 #include <signal.h>
00031
00032 #include <sys/_devdrvr.h>
00033
00034 extern int far Kick ( struct output_buffer far * obuf );
00035 extern int far Stty ( struct termios far * tios );
00036 extern int far Ctrl ( union ioctl_entry far * ioc );
00037
00038 extern int sys_msg( void * );
00039
00040 union _private_msg {
00041 msg_t type;
00042 msg_t status;
00043 char filer[100];
00044 } msg;
00045
00046 int idle = 1;
00047 int more = 0;
00048
00049 pid_t out_proxy;
00050 pid_t in_proxy;
00051 pid_t proxy;
00052
00053 unsigned isize = 2048;
00054 unsigned osize = 2048;
00055 unsigned csize = 256;
00056
00057 #define MAX_DEVICES 1
00058
00059 struct driver_ctrl drv_ctrl;
00060 struct device_ctrl ctrl[MAX_DEVICES];
00061
00062 int dev_handle;
00063 int num_devices = 1;
00064
00065 unsigned driver_options = 0;
00066
00067 char* prefix = "Board";
00068
00069 int main(int argc, char* argv[] ) {
00070 unsigned c;
00071 int i;
00072 pid_t pid;
00073 int t;
00074 int nbytes;
00075
00076 extern void terminate();
00077
00078 setscheduler(0, SCHED_FIFO, 15);
00079
00080
00081
00082
00083
00084 for( i = _SIGMIN; i <= _SIGMAX; ++i)
00085 if ( i != SIGTERM)
00086 signal( i, SIG_IGN );
00087
00088 signal( SIGTERM, &terminate );
00089
00090
00091
00092
00093 while( ( c=getopt(argc,argv,"C:I:O:N:n:") ) != -1 ) {
00094 switch (c) {
00095 case 'C':
00096 csize = strtol(optarg,NULL,0);
00097 break;
00098 case 'I':
00099 isize = strtol(optarg,NULL,0);
00100 break;
00101
00102 case 'O':
00103 osize = strtol(optarg,NULL,0);
00104 break;
00105
00106 case 'N':
00107 prefix = optarg;
00108 break;
00109
00110 case 'n':
00111 num_devices = strtol(optarg,NULL,0);
00112 if (num_devices > MAX_DEVICES)
00113 num_devices = MAX_DEVICES;
00114 break;
00115
00116 }
00117 }
00118
00119
00120
00121
00122
00123 if ( ( dev_handle = dev_drvr_register( "custom", prefix, num_devices,
00124 &Kick, &Stty, &Ctrl, &drv_ctrl, driver_options )
00125 ) == -1 ) {
00126 exit ( ENFILE );
00127 }
00128
00129
00130
00131
00132
00133 for( i = 0; i < num_devices; i++ ) {
00134 ctrl[i].isize = isize;
00135 ctrl[i].osize = osize;
00136 ctrl[i].csize = csize;
00137 }
00138
00139 if ( dev_drvr_mount( dev_handle, drv_ctrl.base_tty,
00140 num_devices, &ctrl[0] ) )
00141 {
00142 dev_drvr_shutdown( dev_handle );
00143 exit(ENOMEM);
00144 }
00145
00146 out_proxy = qnx_proxy_attach(0, 0, 0, -1);
00147 in_proxy = qnx_proxy_attach(0, 0, 0, -1);
00148
00149 #ifndef DEBUGMODE
00150
00151
00152
00153
00154
00155
00156 close(0);
00157 close(1);
00158 close(2);
00159 #endif
00160
00161
00162
00163
00164 qnx_pflags( _PPF_SERVER, _PPF_SERVER, 0, 0 );
00165
00166
00167
00168
00169
00170
00171 for( i = 0; i < num_devices; i++ )
00172 {
00173
00174 struct output_buffer far * obuf;
00175 struct termios far * tios;
00176
00177 obuf = ctrl[i].obuf;
00178 obuf->mode |= OUTPUT_XNL;
00179
00180 tios = ctrl[i].termios;
00181
00182 tios->c_ispeed = tios->c_ospeed = 9600;
00183
00184 tios->c_cflag = (CREAD);
00185 tios->c_oflag = (OPOST);
00186 tios->c_iflag = (ICRNL|IXON|BRKINT);
00187 tios->c_lflag = (ICANON|ISIG|ECHO|ECHOE|ECHOK|IEXTEN);
00188
00189 tios->c_cc[VEOF] = 0x04;
00190 tios->c_cc[VEOL] = 0x00;
00191 tios->c_cc[VERASE] = 0x7F;
00192 tios->c_cc[VINTR] = 0x03;
00193 tios->c_cc[VKILL] = 0x18;
00194 tios->c_cc[VQUIT] = 0x00;
00195 tios->c_cc[VSUSP] = 0x00;
00196 tios->c_cc[VSTART] = 0x11;
00197 tios->c_cc[VSTOP] = 0x13;
00198
00199 tios->c_cc[VMIN] = 0x01;
00200 tios->c_cc[VTIME] = 0x00;
00201 }
00202
00203
00204
00205
00206
00207 init_driver();
00208
00209
00210
00211
00212
00213 for(i = 0; i < num_devices; i++) {
00214 if ( dev_drvr_arm(ctrl[i].tty) )
00215 {
00216 dev_drvr_shutdown( dev_handle );
00217 exit(ENODEV);
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226 for(;;) {
00227
00228 pid = Receive( 0, &msg, sizeof(msg) );
00229
00230 if ( pid == out_proxy )
00231 {
00232 idle = 1;
00233
00234
00235
00236
00237
00238 flush_output();
00239 continue;
00240 }
00241
00242 if ( pid == in_proxy )
00243 {
00244
00245
00246
00247
00248
00249
00250
00251 input_ready();
00252 continue;
00253 }
00254
00255
00256
00257
00258
00259 t = msg.type;
00260 msg.status = ENOSYS;
00261 nbytes = sizeof(msg.status);
00262
00263 switch(t) {
00264
00265 case 0:
00266 nbytes = sys_msg(&msg);
00267 break;
00268
00269 default:
00270 break;
00271 }
00272
00273 if (nbytes) {
00274 Reply(pid, &msg, nbytes);
00275 }
00276
00277 continue;
00278
00279 }
00280 }
00281
00282
00283 void terminate( int signal ) {
00284 if (signal) {
00285
00286
00287
00288
00289 dev_drvr_shutdown( dev_handle );
00290
00291
00292
00293
00294
00295
00296 exit_driver();
00297 }
00298
00299 exit(0);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308 int input_ready() {
00309 pid_t proxy;
00310 int i;
00311 int n;
00312 char buf[100];
00313
00314 proxy = 0;
00315
00316
00317
00318
00319
00320 for( i = 0; i < num_devices; ++i ) {
00321 while( (n = get_data(i, &buf[0], sizeof(buf))) > 0 ) {
00322 if(drv_ctrl.ttim_offset != 0)
00323 {
00324
00325
00326
00327
00328 pid_t (far *ttimcall) (int tty, int len, char far *data, unsigned ds);
00329 ttimcall = MK_FP( FP_SEG(drv_ctrl.tti), drv_ctrl.ttim_offset );
00330 proxy |= (*ttimcall) (ctrl[i].tty, n, &buf[0], drv_ctrl.tti_ds);
00331 } else {
00332
00333
00334
00335
00336 int j;
00337 for(j = 0; j < n; ++j)
00338 proxy |= (*drv_ctrl.tti) (buf[j], ctrl[i].tty, drv_ctrl.tti_ds);
00339 }
00340 }
00341 }
00342
00343
00344
00345
00346 if(proxy)
00347 Trigger(proxy);
00348
00349 return(0);
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 flush_output() {
00362 struct output_buffer far *obuf;
00363 char far * tail;
00364 char far * end;
00365 char far * begin;
00366 int i;
00367 int n;
00368 int size;
00369 int nothing;
00370 int unit;
00371 int expand_newlines;
00372
00373 for(;;) {
00374
00375
00376
00377 nothing = 0;
00378 more = 0;
00379 for(unit = 0; unit < num_devices; ++unit) {
00380
00381 obuf = ctrl[unit].obuf;
00382
00383
00384
00385
00386
00387 if(obuf->mode & OUTPUT_HFLOW_OFF) {
00388 obuf->mode &= ~OUTPUT_HFLOW_OFF;
00389 drop_hw(unit);
00390 }
00391
00392 if(obuf->mode & OUTPUT_HFLOW_ON) {
00393 obuf->mode &= ~OUTPUT_HFLOW_ON;
00394 raise_hw(unit);
00395 }
00396
00397 if(obuf->mode & OUTPUT_XOFF) {
00398 obuf->mode &= ~OUTPUT_XOFF;
00399
00400
00401
00402 put_data(unit, (char far *) "\023", 1, 0);
00403 }
00404
00405 if(obuf->mode & OUTPUT_XON) {
00406 obuf->mode &= ~OUTPUT_XON;
00407
00408
00409
00410 put_data(unit, (char far *) "\021", 1, 0);
00411 }
00412
00413
00414
00415
00416
00417 _disable();
00418 if(obuf->size == 0 ||
00419 (obuf->mode & (OUTPUT_STOPPED|OUTPUT_STOPPED_HW)) != 0) {
00420 _enable();
00421 ++nothing;
00422 continue;
00423 }
00424 _enable();
00425
00426 if(obuf->discard) {
00427
00428
00429
00430 n = obuf->discard;
00431 _disable();
00432 obuf->discard -= n;
00433 obuf->size -= n;
00434 _enable();
00435 i = &obuf->buffer[obuf->length] - obuf->tail;
00436 if(i > n)
00437 obuf->tail += n;
00438 else
00439 obuf->tail = &obuf->buffer[n-i];
00440 }
00441
00442
00443
00444
00445
00446 tail = obuf->tail;
00447 end = &obuf->buffer[obuf->length];
00448 begin = &obuf->buffer[0];
00449 size = obuf->size;
00450
00451 expand_newlines = obuf->mode & OUTPUT_XNL;
00452
00453
00454
00455
00456 i = end - tail;
00457 if(i >= size) {
00458 n = put_data(unit, tail, size, expand_newlines);
00459 }
00460 else {
00461 n = put_data(unit, tail, i, expand_newlines);
00462 n += put_data(unit, begin, size - i, expand_newlines);
00463 }
00464
00465
00466
00467
00468
00469
00470 _disable();
00471
00472 if(i > n)
00473 obuf->tail = tail + n;
00474 else
00475 obuf->tail = begin + (n-i);
00476 obuf->size -= n;
00477
00478
00479
00480
00481 if(obuf->discard > n)
00482 obuf->discard -= n;
00483 else
00484 obuf->discard = 0;
00485
00486 _enable();
00487
00488
00489
00490
00491
00492 _disable();
00493 if(obuf->size < obuf->bcount) {
00494 obuf->bcount = 0;
00495 obuf->action |= ACT_OUTPUT_READY;
00496 _enable();
00497 Trigger(drv_ctrl.hw_pid);
00498 }
00499 else
00500 _enable();
00501 }
00502
00503
00504
00505 _disable();
00506 if(nothing >= num_devices && more == 0) {
00507 idle = 1;
00508 _enable();
00509 return;
00510 }
00511 else
00512 _enable();
00513 }
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 int init_driver()
00528 {
00529 #ifdef DEBUGMODE
00530 old_mode = dev_mode( 0, 0, _DEV_MODES);
00531 dev_arm( 0, in_proxy, _DEV_EVENT_RXRDY );
00532 #else
00533
00534 #endif
00535 return(0);
00536 }
00537
00538
00539
00540 int exit_driver()
00541 {
00542 #ifdef DEBUGMODE
00543 dev_mode( 0, old_mode, _DEV_MODES);
00544 #else
00545
00546 #endif
00547 return(0);
00548 }
00549
00550
00551
00552 get_data(int unit, char *buf, int nbytes)
00553 {
00554
00555
00556
00557
00558 int n = 0;
00559
00560 unit = unit;
00561
00562 #ifdef DEBUGMODE
00563 n = dev_read(0, buf, nbytes, 0, 0, 0, 0, 0);
00564 dev_arm( 0, in_proxy, _DEV_EVENT_RXRDY );
00565 #else
00566
00567 #endif
00568
00569 return(n);
00570 }
00571
00572
00573
00574 put_data(int unit, char far *buf, int nbytes, int expand_newlines)
00575 {
00576
00577
00578
00579
00580 #ifdef DEBUGMODE
00581 int i;
00582 char c;
00583
00584 unit = unit;
00585
00586 for(i = 0; i < nbytes; ++i) {
00587 c = *buf++;
00588 if(expand_newlines && c == '\n')
00589 write(1, "\r", 1);
00590 write(1, &c, 1);
00591 }
00592 #else
00593
00594 #endif
00595 return(nbytes);
00596 }
00597
00598
00599
00600 void drop_hw(int unit) {
00601
00602
00603
00604 unit = unit;
00605 #ifndef DEBUGMODE
00606
00607 #endif
00608 }
00609
00610
00611
00612 void raise_hw(int unit) {
00613
00614
00615
00616 unit = unit;
00617 #ifndef DEBUGMODE
00618
00619 #endif
00620 }
00621
00622
00623 #if 0
00624
00625
00626
00627
00628
00629 #include "../_devdrvr.h"
00630 #include <sys/trace.h>
00631 #include <sys/tracecod.h>
00632
00633
00634
00635
00636
00637 #pragma off (check_stack);
00638
00639 pid_t async_int(int irq) {
00640 extern pid_t (far *tti)(int, int, unsigned);
00641 extern unsigned tti_ds;
00642 pid_t status = 0;
00643 unsigned char *data;
00644 int nbytes = 0;
00645 int irq_type = 0;
00646 unsigned short c;
00647 unsigned iobase = 0;
00648
00649 switch(irq_type) {
00650
00651 case 0:
00652
00653
00654
00655 while(nbytes--) {
00656 c = (unsigned short) *data++;
00657 status |= (*tti) (c, dev->tty, tti_ds);
00658 }
00659 break;
00660
00661 case 1:
00662 status |= (*tti) (*data | RCV_PARITY, dev->tty, tti_ds);
00663 Trace1( (long)_TRACE_DEV_SER_PARITY, _TRACE_TRANSIENT, iobase );
00664 break;
00665
00666 case 2:
00667 status |= (*tti) (*data | RCV_FRAME, dev->tty, tti_ds);
00668 Trace1( (long)_TRACE_DEV_SER_FRAME, _TRACE_TRANSIENT, iobase );
00669 break;
00670
00671 case 3:
00672 status |= (*tti) (*data | RCV_OVERRUN, dev->tty, tti_ds);
00673 Trace1( (long)_TRACE_DEV_SER_OVERRUN, _TRACE_TRANSIENT, iobase );
00674 break;
00675
00676 case 4:
00677 status |= (*tti) (*data | RCV_BREAK, dev->tty, tti_ds);
00678 break;
00679
00680 case 5:
00681 status |= (*tti) (RCV_CARRIER, dev->tty, tti_ds);
00682 Trace1( _TRACE_DEV_SER_CARRIER, _TRACE_EXPECTED, dev->iobase );
00683 break;
00684
00685 case 6:
00686 status |= (*tti) (RCV_HNGUP, dev->tty, tti_ds);
00687 Trace1( _TRACE_DEV_SER_HUP, _TRACE_EXPECTED, dev->iobase );
00688 break;
00689
00690 case 7:
00691 status |= (*tti) (RCV_HW_ON, dev->tty, tti_ds);
00692 break;
00693
00694 case 8:
00695 status |= (*tti) (RCV_HW_OFF, dev->tty, tti_ds);
00696 break;
00697 }
00698
00699 return(status);
00700 }
00701
00702 #pragma on (check_stack);
00703
00704 #endif