home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 4 Drivers
/
04-Drivers.zip
/
594p.zip
/
PROGINFO
/
SPEW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-21
|
11KB
|
440 lines
/*
* Spew
*
* USAGE: spew dev [startdevno enddevno]
*
* Copyright (c) DigiBoard, Inc. 1990
* --Dave Updegraff
*
* To compile: CL /Od /MT spew.c (MSC 6.0)
*/
#define INCL_DOS
#include <os2.h>
#include <malloc.h>
#define VERSION "1.00"
#define BUFFER_SIZE 256
#define STACKSIZE 0x2000
#define MAXDEVICES 16
// These are the IBM defined FIFO bits in the DCB-flag3 (fbTimeout)
// that are not in the MicroSoft 'bsedev.h' definitions for the DCB.
#define EXT_HARDWARE_DISABLE 0x08
#define EXT_HARDWARE_ENABLE 0x10
#define EXT_HARDWARE_AUTO 0x18
#define EXT_HARDWARE_RX1 0x00
#define EXT_HARDWARE_RX4 0x20
#define EXT_HARDWARE_RX8 0x40
#define EXT_HARDWARE_RX14 0x60
#define EXT_HARDWARE_TX1 0x00
#define EXT_HARDWARE_TX16 0x80
char Devname[10], *Dev , *Bp;
char Buffer[BUFFER_SIZE+1];
LONG Speed, Basespeed, Output, Sem;
HFILE handles[MAXDEVICES];
USHORT result, type, attrib, SizeK = 0;
SHORT End, Start;
long time ();
void spew_data();
void loop_data();
void busy_work ();
unsigned Devno;
DCBINFO DCB_setting;
unsigned Commerr, Tracking, Loopback, Signals;
long Rounds, sem_count;
main ( argc, argv )
int argc;
char *argv[];
{
int left, err, j, tid, i , devno;
char *Stack, wait;
TID ThreadID;
long speed, output;
MODEMSTATUS M_sigs;
// If insufficient arguments or '?', just give a USAGE message
if ( argc < 2 )
{
printf ("DigiBoard serial port test program SPEW version %s\n",VERSION);
printf ("USAGE: spew device_name [-[ln]] [starno,endno] \n");
printf (" -l : No LOOPBACK test -- Transmit only\n");
printf (" -c : No CPU utilization information\n");
printf (" -s : No modem SIGNAL testing\n");
printf (" eg. spew -l com31\n");
printf ("MODEM signal test, then Tx-only throughput on COM31 w/CPU statistics\n");
printf (" eg. spew -cs com 8,12\n");
printf ("LOOPBACK test on COM8,COM9,..COM12\n");
exit (0);
}
// Parse out the args
Dev = NULL;
Start = End = -1;
// by default do it all
Tracking = Loopback = Signals = 1;
while ( argc-- > 1)
{
if ( isdigit (*argv[argc] ) )
{
sscanf (argv[argc],"%d,%d", &Start, &End );
if ( (End - Start ) >= MAXDEVICES )
{
printf ("Too many devices. Maximum = %d\n", MAXDEVICES);
exit (1);
}
continue;
}
if ( *argv[argc] == '-' )
{
for (i=1; isalpha (*(argv[argc] + i)); i++)
{
switch (*(argv[argc]+i))
{
case 'c':
Tracking = 0;
break;
case 's':
Signals = 0;
break;
case 'l':
Loopback = 0;
break;
default:
printf ("unknown argument <%s>\n", argv[argc] );
exit (1);
}
}
continue;
}
if ( Dev == NULL )
{
Dev = argv[argc];
continue;
}
printf ("Too many arguments.\n <%s>\n", argv[argc]);
printf ("USAGE: spew device_name [starno,endno] \n");
exit (1);
}
Speed = Basespeed = Output = 0L;
// All the IO threads pend on this which is not released 'till I'm ready.
DosSemSet( &Sem );
for ( i = Start, devno = 0; i <= End; i++,devno++ )
{
if ( i == -1 ) // Singe device only
{
strcpy ( Devname, Dev );
i = End+1;
}
else
sprintf ( Devname, "%s%d", Dev, i );
// Open the device{s}:
if ( DosOpen ( Devname,
&handles[devno],
&result,
0L,
FILE_NORMAL,
FILE_OPEN,
(OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE),
0L ) )
{
printf ("Failed to open device <%s>\n", Devname );
exit (1);
}
// Options for setting up the DCB. Set them to whatever you like. I just
// turn off FLOWCONTROL and enable such FIFO'ing as there may be..
if (DosDevIOCtl( &DCB_setting,
0L,
ASYNC_GETDCBINFO,
IOCTL_ASYNC,
handles[devno]))
return -1;
// If we're gonna test modem signals, need to take handshaking off
// I wanna test the modem signal connectors so first
// clear any flowcontrol that might be in effect for RTS, DTR
if ( Signals )
{
DCB_setting.fbCtlHndShake &= ~(MODE_DTR_HANDSHAKE);
DCB_setting.fbFlowReplace &= ~(MODE_RTS_HANDSHAKE);
if ( DosDevIOCtl( 0L,
&DCB_setting,
ASYNC_SETDCBINFO,
IOCTL_ASYNC,
handles[devno]))
return -1;
// Current settings
printf ("<%s> : Initial conditions:\n", Devname);
show_modem(&handles[devno]);
// Raise DTR and RTS - this should have the effect of having DTR, DCD, DSR up
printf ("\nRaising DTR and RTS has effect of: \n");
M_sigs.fbModemOn = DTR_ON | RTS_ON ;
M_sigs.fbModemOff = 0xff;
DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
IOCTL_ASYNC,handles[devno]);
DosSleep ( 100 );
show_modem(&handles[devno]);
// Drop DTR
printf ("\nDropping DTR and Raising RTS has effect of: \n");
M_sigs.fbModemOn = RTS_ON ;
M_sigs.fbModemOff = DTR_OFF;
DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
IOCTL_ASYNC,handles[devno]);
DosSleep ( 100 );
show_modem(&handles[devno]);
// Drop RTS
printf ("\nRaising DTR and Dropping RTS has effect of: \n");
M_sigs.fbModemOn = DTR_ON ;
M_sigs.fbModemOff = RTS_OFF;
DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
IOCTL_ASYNC,handles[devno]);
DosSleep ( 100 );
show_modem(&handles[devno]);
// Drop them both. Note BIZZARRE way of doing this!!
printf ("\nDropping both DTR and RTS has effect of:\n");
M_sigs.fbModemOn = 0;
M_sigs.fbModemOff = DTR_OFF & RTS_OFF ;
DosDevIOCtl(&err,&M_sigs,ASYNC_SETMODEMCTRL,
IOCTL_ASYNC,handles[devno]);
DosSleep ( 100 );
show_modem(&handles[devno]);
// end of modem signal testing..
}
// If going to do Loopback,set HW flow
if ( Loopback )
{
DCB_setting.fbCtlHndShake = MODE_CTS_HANDSHAKE | MODE_DTR_CONTROL;
DCB_setting.fbFlowReplace &= ~(MODE_RTS_HANDSHAKE|MODE_RTS_CONTROL);
DCB_setting.fbFlowReplace |= MODE_RTS_HANDSHAKE;
}
else
{
DCB_setting.fbCtlHndShake &=
~(MODE_CTS_HANDSHAKE | MODE_DSR_HANDSHAKE);
}
// make sure the FIFO is active if we have one.
if ( DCB_setting.fbTimeout & EXT_HARDWARE_AUTO )
DCB_setting.fbTimeout |= EXT_HARDWARE_ENABLE;
// force READs to wait longer, attempt to fulfill the whole request
DCB_setting.fbTimeout |= MODE_READ_TIMEOUT;
// Set the timeouts to < our wakeup increment(5 secs)
DCB_setting.usReadTimeout = 950; // = 9.5 sec
DCB_setting.usWriteTimeout = 950; // = 9.5 sec
if (DosDevIOCtl( 0L,
&DCB_setting,
ASYNC_SETDCBINFO,
IOCTL_ASYNC,
handles[devno]))
return -1;
// Spawn off the data spewing.
if ( Loopback )
_beginthread( loop_data, NULL, STACKSIZE, &handles[devno] );
else
_beginthread( spew_data, NULL, STACKSIZE, &handles[devno] );
}
// and the busywork thread if we want to track ourselves
if ( Tracking )
_beginthread( busy_work, NULL, STACKSIZE, NULL ) ;
if ( Tracking )
{
printf ("10 seconds while baseline CPU availability calculated..\n");
// After waiting for 10 seconds, we have a guess as to machine MIPs
DosEnterCritSec();
Speed = 0;
DosExitCritSec();
DosSleep (10000);
DosEnterCritSec();
Basespeed = Speed;
DosExitCritSec();
printf ("Basespeed=%ld, %d devices....\n", Basespeed, devno);
}
else
DosSleep(100); // pause 1/10 sec
// Let the spewing begin!
DosSemClear( &Sem );
DosEnterCritSec();
Speed = Output = 0;
DosExitCritSec();
while ( 1 )
{
DosSleep(10000);
DosEnterCritSec();
speed = Speed;
output = Output;
Speed = Output = 0;
DosExitCritSec();
// Lets not fool ourselves that this will never happen...
if ( speed > Basespeed )
Basespeed = speed;
if ( Tracking )
printf ("CPU: %ld%%, %ld bytes/sec/channel (%d channels). ",
((Basespeed - speed)*100)/Basespeed,
((output*BUFFER_SIZE)/(devno*10)),
devno);
else
printf ("%ld bytes/sec/channel (%d channels).",
((output*BUFFER_SIZE)/(devno*10)),
devno);
if ( Loopback )
printf (" -Full duplex-\r");
else
printf (" -Transmit only-\r");
}
exit (0);
}
// unverified pure transmit
void spew_data (HFILE *fp)
{
USHORT bytes ;
// Wait for the main thread to release us
if ( DosSemWait(&Sem, SEM_INDEFINITE_WAIT) )
return ;
// crank it out
while ( 1 )
{
if ( DosWrite (*fp, Buffer, BUFFER_SIZE, &bytes) )
{
printf ("Failed to write!! \n");
DosExit (EXIT_PROCESS, 1);
}
Output++;
}
}
// Tx and Rx, token check of first & last bytes
void loop_data (HFILE *fp)
{
USHORT bytes, request, gotback, jnk ;
unsigned char *rbuf;
LONG slem ;
if (( rbuf = malloc ( BUFFER_SIZE )) == NULL )
{
printf ("Failed to malloc space in spawned thread\n");
return;
}
// markers;
Buffer[0] = 'X';
Buffer[BUFFER_SIZE/2] = 'Y';
Buffer[BUFFER_SIZE-1] = 'Z';
// Wait for the main thread to release us
if ( DosSemWait(&Sem, SEM_INDEFINITE_WAIT) )
return ;
// Make the writes Asy then pend on the read.
while ( 1 )
{
DosWriteAsync (*fp, &slem, &jnk, Buffer, BUFFER_SIZE, &bytes) ;
// make sure that these values are initially wrong so Read will overwrite
*rbuf = *(rbuf + BUFFER_SIZE - 1) = '\0';
for ( gotback=0, memset(rbuf, 0, BUFFER_SIZE), request = BUFFER_SIZE;
gotback < BUFFER_SIZE;
gotback += bytes, request = BUFFER_SIZE - gotback
)
if ( DosRead (*fp, rbuf+gotback, request, &bytes) || bytes == 0)
{
printf ("Failed to READ!! \n");
DosExit (EXIT_PROCESS, 1);
}
// token checks of first, middle, and last bytes
if ( *rbuf == Buffer[0] &&
*(rbuf+BUFFER_SIZE/2) == Buffer[BUFFER_SIZE/2] &&
*(rbuf+BUFFER_SIZE-1) == Buffer[BUFFER_SIZE-1] )
Output++;
else
printf ("Lost Data on Round %d\n", Output );
}
}
void busy_work ()
{
unsigned char far *there;
int i,j;
// `nice` myself
DosSetPrty (PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, 0);
if (( there = (unsigned char far *)malloc ( 0x200 ))== NULL )
{
printf ("Failed to malloc a scratch space\n");
exit (1);
}
// this is NOT a 'stone of any kind and you MUST disable ALL optimizations
// if this busy work is to pretend to be busy
while ( 1 )
{
for (i=0; i < 0x200; i++ )
*(there+i) = 0xff;
for (i=0; i < 0x200; i++ )
*(there+i) /= 0x11;
Speed++;
}
}
show_modem (HFILE *fp)
{
unsigned char min, mout;
DosDevIOCtl(&mout,0L,ASYNC_GETMODEMOUTPUT, IOCTL_ASYNC, *fp);
DosDevIOCtl(&min, 0L,ASYNC_GETMODEMINPUT, IOCTL_ASYNC, *fp);
printf ("Modem OUTPUT signals : DTR=%d, RTS=%d\n",
((mout & DTR_ON)>0),((mout & RTS_ON)>0));
printf ("Modem INPUT signals: CTS=%d, DSR_ON=%d, RI_ON=%d, DCD_ON=%d\n",
((min & CTS_ON)>0),((min & DSR_ON)>0),
((min & RI_ON)>0),((min & DCD_ON)>0) );
printf ("..press ENTER..");
getchar();
}