home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 4 Drivers / 04-Drivers.zip / 594p.zip / PROGINFO / SPEW.C < prev    next >
C/C++ Source or Header  |  1993-06-21  |  11KB  |  440 lines

  1. /*
  2.  * Spew
  3.  *
  4.  * USAGE: spew dev [startdevno enddevno]
  5.  *
  6.  * Copyright (c) DigiBoard, Inc. 1990
  7.  * --Dave Updegraff
  8.  * 
  9.  * To compile: CL /Od /MT spew.c (MSC 6.0)
  10.  */
  11. #define INCL_DOS
  12. #include <os2.h>
  13. #include <malloc.h>
  14.  
  15. #define VERSION    "1.00"
  16. #define BUFFER_SIZE    256
  17. #define STACKSIZE     0x2000
  18. #define MAXDEVICES    16
  19.  
  20. // These are the IBM defined FIFO bits in the DCB-flag3 (fbTimeout)
  21. // that are not in the MicroSoft 'bsedev.h' definitions for the DCB.
  22. #define    EXT_HARDWARE_DISABLE    0x08
  23. #define    EXT_HARDWARE_ENABLE        0x10
  24. #define    EXT_HARDWARE_AUTO        0x18
  25.  
  26. #define    EXT_HARDWARE_RX1        0x00
  27. #define    EXT_HARDWARE_RX4        0x20
  28. #define    EXT_HARDWARE_RX8        0x40
  29. #define    EXT_HARDWARE_RX14        0x60
  30.  
  31. #define    EXT_HARDWARE_TX1        0x00
  32. #define    EXT_HARDWARE_TX16        0x80
  33.  
  34. char        Devname[10], *Dev , *Bp;
  35. char        Buffer[BUFFER_SIZE+1];
  36. LONG        Speed, Basespeed, Output, Sem;
  37. HFILE         handles[MAXDEVICES];
  38. USHORT        result, type, attrib, SizeK = 0;
  39. SHORT        End, Start;
  40. long        time ();
  41.  
  42.  
  43. void spew_data();
  44. void loop_data();
  45. void busy_work ();
  46.  
  47. unsigned Devno;
  48.  
  49. DCBINFO        DCB_setting;
  50. unsigned     Commerr, Tracking, Loopback, Signals;
  51. long        Rounds, sem_count;
  52.  
  53. main ( argc, argv )
  54. int argc;
  55. char *argv[];
  56. {
  57. int    left, err, j, tid, i , devno;
  58. char    *Stack, wait;
  59. TID    ThreadID;
  60. long    speed, output;
  61. MODEMSTATUS M_sigs;
  62.  
  63.  
  64. // If insufficient arguments or '?', just give a USAGE message
  65.     if ( argc < 2 )
  66.     {
  67.         printf ("DigiBoard serial port test program SPEW version %s\n",VERSION);
  68.         printf ("USAGE: spew device_name [-[ln]]  [starno,endno] \n");
  69.         printf ("       -l : No LOOPBACK test -- Transmit only\n");
  70.         printf ("       -c : No CPU utilization information\n");
  71.         printf ("       -s : No modem SIGNAL testing\n");
  72.         printf ("  eg.   spew -l com31\n");
  73.         printf ("MODEM signal test, then Tx-only throughput on COM31 w/CPU statistics\n");
  74.         printf ("  eg.   spew -cs com 8,12\n");
  75.         printf ("LOOPBACK test on COM8,COM9,..COM12\n");
  76.         exit (0);
  77.     }
  78.  
  79. // Parse out the args
  80.  
  81.     Dev = NULL;
  82.     Start = End = -1;
  83. // by default do it all
  84.     Tracking = Loopback = Signals = 1;
  85.     while ( argc-- > 1)
  86.     {
  87.         if ( isdigit (*argv[argc] ) )
  88.         {
  89.             sscanf (argv[argc],"%d,%d", &Start, &End );
  90.             if ( (End - Start ) >= MAXDEVICES )
  91.             {
  92.                 printf ("Too many devices.  Maximum = %d\n", MAXDEVICES);
  93.                 exit (1);
  94.             }
  95.             continue;
  96.         }
  97.         if ( *argv[argc] == '-' )
  98.         {
  99.             for (i=1; isalpha (*(argv[argc] + i)); i++)
  100.             {
  101.                 switch (*(argv[argc]+i))
  102.                 {
  103.                     case 'c':
  104.                         Tracking = 0;
  105.                         break;
  106.                     case 's':
  107.                         Signals = 0;
  108.                         break;
  109.                     case 'l':
  110.                         Loopback = 0;
  111.                         break;
  112.                     default:
  113.                         printf ("unknown argument <%s>\n", argv[argc] );
  114.                         exit (1);
  115.                 }
  116.             }
  117.             continue;
  118.         }
  119.         if ( Dev == NULL )
  120.         {
  121.             Dev = argv[argc];
  122.             continue;
  123.         }
  124.         printf ("Too many arguments.\n <%s>\n", argv[argc]);
  125.         printf ("USAGE: spew device_name [starno,endno] \n");
  126.         exit (1);
  127.     }
  128.  
  129.     Speed = Basespeed = Output = 0L;
  130.  
  131. // All the IO threads pend on this which is not released 'till I'm ready.
  132.     DosSemSet( &Sem );
  133.  
  134.  
  135.     for ( i = Start, devno = 0; i <= End; i++,devno++ )
  136.     {
  137.         if ( i == -1 )        // Singe device only
  138.         {
  139.             strcpy ( Devname, Dev );
  140.             i = End+1;
  141.         }
  142.         else
  143.             sprintf ( Devname, "%s%d", Dev, i );
  144. // Open the device{s}:
  145.         if ( DosOpen (     Devname,
  146.                         &handles[devno],
  147.                         &result,
  148.                         0L,
  149.                         FILE_NORMAL,
  150.                         FILE_OPEN,
  151.                         (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE), 
  152.                         0L ) )
  153.             {
  154.                 printf ("Failed to open device <%s>\n", Devname );
  155.                 exit (1);
  156.             }
  157.  
  158. // Options for setting up the DCB.  Set them to whatever you like.  I just
  159. // turn off FLOWCONTROL and enable such FIFO'ing as there may be..
  160.  
  161.         if (DosDevIOCtl(     &DCB_setting,
  162.                             0L,
  163.                             ASYNC_GETDCBINFO,
  164.                             IOCTL_ASYNC,
  165.                             handles[devno]))
  166.             return -1;
  167.  
  168. // If we're gonna test modem signals, need to take handshaking off
  169. // I wanna test the modem signal connectors so first
  170. // clear any flowcontrol that might be in effect for RTS, DTR
  171.  
  172.         if ( Signals )
  173.         {
  174.             DCB_setting.fbCtlHndShake &= ~(MODE_DTR_HANDSHAKE);
  175.             DCB_setting.fbFlowReplace &= ~(MODE_RTS_HANDSHAKE);
  176.             if ( DosDevIOCtl(     0L,
  177.                                 &DCB_setting,
  178.                                 ASYNC_SETDCBINFO,
  179.                                 IOCTL_ASYNC,
  180.                                 handles[devno]))
  181.                     return -1;
  182. // Current settings 
  183.         
  184.             printf ("<%s> : Initial conditions:\n", Devname);
  185.             show_modem(&handles[devno]);
  186.  
  187. // Raise DTR and RTS - this should have the effect of having DTR, DCD, DSR up
  188.             printf ("\nRaising DTR and RTS has effect of: \n");
  189.             M_sigs.fbModemOn = DTR_ON | RTS_ON ;
  190.             M_sigs.fbModemOff = 0xff;
  191.             DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
  192.                                     IOCTL_ASYNC,handles[devno]);
  193.             DosSleep ( 100 );
  194.             show_modem(&handles[devno]);
  195.  
  196. // Drop DTR 
  197.             printf ("\nDropping DTR and Raising RTS has effect of: \n");
  198.             M_sigs.fbModemOn = RTS_ON ;
  199.             M_sigs.fbModemOff = DTR_OFF;
  200.             DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
  201.                                     IOCTL_ASYNC,handles[devno]);
  202.             DosSleep ( 100 );
  203.             show_modem(&handles[devno]);
  204.  
  205. // Drop RTS 
  206.             printf ("\nRaising DTR and Dropping RTS has effect of: \n");
  207.             M_sigs.fbModemOn = DTR_ON ;
  208.             M_sigs.fbModemOff = RTS_OFF;
  209.             DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
  210.                                     IOCTL_ASYNC,handles[devno]);
  211.             DosSleep ( 100 );
  212.             show_modem(&handles[devno]);
  213.  
  214. // Drop them both.  Note BIZZARRE way of doing this!!
  215.             printf ("\nDropping both DTR and RTS has effect of:\n");
  216.             M_sigs.fbModemOn = 0;
  217.             M_sigs.fbModemOff = DTR_OFF & RTS_OFF ;
  218.             DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
  219.                                     IOCTL_ASYNC,handles[devno]);
  220.             DosSleep ( 100 );
  221.             show_modem(&handles[devno]);
  222. // end of modem signal testing..
  223.         }
  224.  
  225. // If going to do Loopback,set HW flow
  226.  
  227.         if ( Loopback )
  228.         {
  229.             DCB_setting.fbCtlHndShake =    MODE_CTS_HANDSHAKE | MODE_DTR_CONTROL;
  230.             DCB_setting.fbFlowReplace &= ~(MODE_RTS_HANDSHAKE|MODE_RTS_CONTROL);
  231.             DCB_setting.fbFlowReplace |= MODE_RTS_HANDSHAKE;
  232.         }
  233.         else
  234.         {
  235.             DCB_setting.fbCtlHndShake &=
  236.                             ~(MODE_CTS_HANDSHAKE | MODE_DSR_HANDSHAKE);
  237.         }
  238.  
  239. // make sure the FIFO is active if we have one.
  240.         if ( DCB_setting.fbTimeout & EXT_HARDWARE_AUTO )
  241.             DCB_setting.fbTimeout  |= EXT_HARDWARE_ENABLE;
  242.  
  243. // force READs to wait longer, attempt to fulfill the whole request
  244.         DCB_setting.fbTimeout |= MODE_READ_TIMEOUT;
  245.  
  246. // Set the timeouts to < our wakeup increment(5 secs)
  247.         DCB_setting.usReadTimeout = 950;    // = 9.5 sec
  248.         DCB_setting.usWriteTimeout = 950;    // = 9.5 sec
  249.  
  250.         if (DosDevIOCtl(    0L,
  251.                             &DCB_setting,
  252.                             ASYNC_SETDCBINFO,
  253.                             IOCTL_ASYNC,
  254.                             handles[devno]))
  255.             return -1;
  256.  
  257.  
  258. // Spawn off the data spewing.  
  259.         if ( Loopback )
  260.             _beginthread( loop_data, NULL, STACKSIZE, &handles[devno] );    
  261.         else
  262.             _beginthread( spew_data, NULL, STACKSIZE, &handles[devno] );    
  263.     }
  264. // and the busywork thread if we want to track ourselves
  265.     if ( Tracking )
  266.         _beginthread( busy_work, NULL, STACKSIZE, NULL ) ;
  267.  
  268.  
  269.     if ( Tracking )
  270.     {
  271.         printf ("10 seconds while baseline CPU availability calculated..\n");
  272.  
  273. // After waiting for 10 seconds, we have a guess as to machine MIPs
  274.         DosEnterCritSec();
  275.         Speed = 0;
  276.         DosExitCritSec();
  277.         DosSleep (10000);
  278.         DosEnterCritSec();
  279.         Basespeed = Speed;
  280.         DosExitCritSec();
  281.  
  282.         printf ("Basespeed=%ld, %d devices....\n", Basespeed, devno);
  283.     }
  284.     else
  285.         DosSleep(100);    // pause 1/10 sec
  286.  
  287. // Let the spewing begin!
  288.     DosSemClear( &Sem );
  289.  
  290.     DosEnterCritSec();
  291.     Speed = Output = 0;
  292.     DosExitCritSec();
  293.     while ( 1 )
  294.     {
  295.         DosSleep(10000);
  296.         DosEnterCritSec();
  297.         speed = Speed;
  298.         output = Output;
  299.         Speed = Output = 0;
  300.         DosExitCritSec();
  301.         
  302. // Lets not fool ourselves that this will never happen...
  303.         if ( speed > Basespeed )
  304.             Basespeed = speed;
  305.  
  306.         if ( Tracking )
  307.             printf ("CPU: %ld%%, %ld bytes/sec/channel (%d channels). ",
  308.                 ((Basespeed - speed)*100)/Basespeed,
  309.                 ((output*BUFFER_SIZE)/(devno*10)), 
  310.                 devno);
  311.         else
  312.             printf ("%ld bytes/sec/channel (%d channels).",
  313.                 ((output*BUFFER_SIZE)/(devno*10)), 
  314.                 devno);
  315.  
  316.         if ( Loopback )
  317.             printf (" -Full duplex-\r");
  318.         else
  319.             printf (" -Transmit only-\r");
  320.     }
  321.  
  322.     exit (0);
  323. }
  324.  
  325. // unverified pure transmit
  326. void spew_data (HFILE *fp)
  327. {
  328. USHORT bytes ;
  329.  
  330. // Wait for the main thread to release us
  331.     if  ( DosSemWait(&Sem, SEM_INDEFINITE_WAIT) )
  332.         return ;
  333. // crank it out 
  334.     while ( 1 )
  335.     {
  336.         if (  DosWrite (*fp, Buffer, BUFFER_SIZE, &bytes) )
  337.         {
  338.             printf ("Failed to write!! \n");
  339.             DosExit (EXIT_PROCESS, 1);
  340.         }
  341.         Output++;
  342.     }
  343. }
  344.  
  345. // Tx and Rx, token check of first & last bytes 
  346. void loop_data (HFILE *fp)
  347. {
  348. USHORT bytes, request, gotback, jnk ;
  349. unsigned char *rbuf;
  350. LONG    slem ;
  351.  
  352.     if (( rbuf = malloc ( BUFFER_SIZE )) == NULL )
  353.     {
  354.         printf ("Failed to malloc space in spawned thread\n");
  355.         return;
  356.     }
  357.  
  358. // markers; 
  359.     Buffer[0] = 'X';
  360.     Buffer[BUFFER_SIZE/2] = 'Y';
  361.     Buffer[BUFFER_SIZE-1] = 'Z';
  362.  
  363. // Wait for the main thread to release us
  364.     if  ( DosSemWait(&Sem, SEM_INDEFINITE_WAIT) )
  365.         return ;
  366.  
  367. // Make the writes Asy then pend on the read.
  368.     while ( 1 )
  369.     {
  370.         DosWriteAsync (*fp, &slem, &jnk, Buffer, BUFFER_SIZE, &bytes) ;
  371.  
  372. // make sure that these values are initially wrong so Read will overwrite
  373.         *rbuf = *(rbuf + BUFFER_SIZE - 1) = '\0';
  374.  
  375.         for (    gotback=0, memset(rbuf, 0, BUFFER_SIZE), request = BUFFER_SIZE; 
  376.                 gotback < BUFFER_SIZE;
  377.                 gotback += bytes, request = BUFFER_SIZE - gotback 
  378.             )
  379.             if ( DosRead (*fp, rbuf+gotback, request, &bytes) || bytes == 0)
  380.             {
  381.                 printf ("Failed to READ!! \n");
  382.                 DosExit (EXIT_PROCESS, 1);
  383.             }
  384.  
  385. // token checks of first, middle, and last bytes
  386.         if (    *rbuf == Buffer[0] && 
  387.                 *(rbuf+BUFFER_SIZE/2) == Buffer[BUFFER_SIZE/2] &&
  388.                 *(rbuf+BUFFER_SIZE-1) == Buffer[BUFFER_SIZE-1] )
  389.             Output++;
  390.         else
  391.             printf ("Lost Data on Round %d\n", Output );
  392.  
  393.     }
  394. }
  395.  
  396. void busy_work ()
  397. {
  398. unsigned char far    *there;
  399. int                i,j;
  400.  
  401. // `nice` myself
  402.  
  403.     DosSetPrty (PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, 0);
  404.  
  405.     if (( there = (unsigned char far *)malloc ( 0x200 ))== NULL )
  406.     {
  407.         printf ("Failed to malloc a scratch space\n");
  408.         exit (1);
  409.     }
  410.  
  411.  
  412. // this is NOT a 'stone of any kind and you MUST disable ALL optimizations
  413. // if this busy work is to pretend to be busy
  414.     while ( 1 )
  415.     {
  416.         for (i=0; i < 0x200; i++ )
  417.             *(there+i) = 0xff;
  418.         for (i=0; i < 0x200; i++ )
  419.             *(there+i) /= 0x11;
  420.     Speed++;
  421.     }
  422. }
  423.  
  424.  
  425. show_modem (HFILE *fp)
  426. {
  427. unsigned char min, mout;
  428.  
  429.     DosDevIOCtl(&mout,0L,ASYNC_GETMODEMOUTPUT, IOCTL_ASYNC, *fp);
  430.     DosDevIOCtl(&min, 0L,ASYNC_GETMODEMINPUT,  IOCTL_ASYNC, *fp);
  431.  
  432.     printf ("Modem OUTPUT signals : DTR=%d, RTS=%d\n",
  433.             ((mout & DTR_ON)>0),((mout & RTS_ON)>0));
  434.     printf ("Modem INPUT signals: CTS=%d, DSR_ON=%d, RI_ON=%d, DCD_ON=%d\n",
  435.             ((min & CTS_ON)>0),((min & DSR_ON)>0),
  436.             ((min & RI_ON)>0),((min & DCD_ON)>0) );
  437.     printf ("..press ENTER..");
  438.     getchar();
  439. }
  440.