📄 ulibfs.c
字号:
moved = blockIO( (char *) data + total, queued, FS_WRITBLOK );
// Write the data
traceData( data + total, moved, TRUE); // Trace our output
if ( moved != 0)
spin--; /* No progress, consider timing out */
else {
total += moved;
queued -= moved;
} /* Update our progress */
} /* while(spin && wanted ) */
/*--------------------------------------------------------------------*/
/* Handle buffer overflow which never went away */
/*--------------------------------------------------------------------*/
if ( queued )
{
printmsg(0,"fswrite: Buffer overflow, needed %d bytes",
queued);
return 0;
} /* if ( queued ) */
/*--------------------------------------------------------------------*/
/* Return success to caller */
/*--------------------------------------------------------------------*/
return total;
} /* fswrite */
/*--------------------------------------------------------------------*/
/* f s s e n d b r k */
/* */
/* Send a break to the remote system */
/*--------------------------------------------------------------------*/
void fssendbrk(unsigned int duration)
{
FSBreak( TRUE );
printmsg(4, "fssendbrk: %d", duration);
ddelay( duration * 100 );
FSBreak( FALSE );
} /* fssendbrk */
/*--------------------------------------------------------------------*/
/* f c l o s e l i n e */
/* */
/* Close a FOSSIL controlled port */
/*--------------------------------------------------------------------*/
void fcloseline(void)
{
if (!portActive)
panic();
portActive = FALSE; // Flag port closed for error handler
FSFlushXmit(); // Drop XMIT queue if not empty
FSFlushRecv(); // Drop Recv queue as well
FSDTR( FALSE );
ddelay(500); // Required for V.24
FSClose();
traceStop();
} /* fcloseline */
/*--------------------------------------------------------------------*/
/* F S S e t S p e e d */
/* */
/* Set current speed port; also sets parity and associated */
/* parameters. */
/*--------------------------------------------------------------------*/
void fSIOSpeed(BPS bps)
{
static const long rates[] =
{ 19200, 38400, 300, 600, 1200, 2400, 4800, 9600, -19200 };
short speed = 0; // Actual value used by FOSSIL for speed
short best = 3;
while( (rates[speed] > 0) && (rates[speed] != (long) bps ))
{
if ( (rates[speed] / 100) == ((long) bps / 100) )
best = speed;
speed++;
}
if ( rates[speed] < 0 )
{
printmsg(0,"fSIOSpeed: Invalid modem speed %lu, using %lu",
(unsigned long) bps,
(unsigned long) rates[speed]);
speed = best;
}
printmsg(4,"fSIOSspeed: Changing port speed from %lu BPS to %lu BPS",
(unsigned long) currentBPS,
(unsigned long) rates[speed]);
FSSetSpeed( speed, FS_NO_PARITY, FS_STOPBIT_1, FS_CHARLEN_8);
showModem( FSStatus()); // Report modem status if changed
currentBPS = rates[speed];
} /* fSIOSpeed */
/*--------------------------------------------------------------------*/
/* f f l o w c o n t r o l */
/* */
/* Enable flow control for FOSSIL driven port */
/*--------------------------------------------------------------------*/
void fflowcontrol( boolean flow )
{
printmsg(4,"fflowcontrol: %sabling in-band flow control",
flow ? "en" : "dis");
if ( flow )
FSFlowControl( FS_XONXMIT | FS_XONRECV );
else if ( currentDirect ) // Direct means no flow control
FSFlowControl( FS_NOFLOW );
else
FSFlowControl( FS_CTSRTS );
} /* fflowcontrol */
/*--------------------------------------------------------------------*/
/* f h a n g u p */
/* */
/* Perform hangup via DTR drop on FOSSIL controlled port */
/*--------------------------------------------------------------------*/
void fhangup( void )
{
if (!hangupNeeded)
return;
hangupNeeded = FALSE;
FSFlushXmit(); // Drop XMIT queue if not empty
FSFlushRecv(); // Drop Recv queue as well
FSDTR( FALSE ); /* Hang the phone up */
ddelay(500); /* Really only need 250 milliseconds */
FSDTR( TRUE ); /* Bring the modem back on-line */
ddelay(2000); /* Now wait for the poor thing to recover */
/* two seconds is required by V.24 */
printmsg(3,"fhangup: complete.");
carrierDetect = FALSE; /* No modem connected yet */
} /* fhangup */
/*--------------------------------------------------------------------*/
/* f G e t S p e e d */
/* */
/* Return current port speed */
/*--------------------------------------------------------------------*/
BPS fGetSpeed( void )
{
return currentBPS;
}
/*--------------------------------------------------------------------*/
/* f C D */
/* */
/* Determine if Carrier Detect has dropped */
/*--------------------------------------------------------------------*/
boolean fCD( void )
{
boolean saveCD = carrierDetect;
short status = FSStatus();
showModem( status );
if ( status & FS_STAT_DCD )
carrierDetect = TRUE;
if ((! saveCD) || carrierDetect)
return TRUE;
printmsg(0,"fCD: Lost carrier detect");
return FALSE;
} /* fCD */
/*--------------------------------------------------------------------*/
/* s h o w M o d e m */
/* */
/* Display current modem status */
/*--------------------------------------------------------------------*/
#define mannounce(flag, bits, text ) ((flag & bits) ? text : "" )
static void showModem( const short status )
{
static int old_status = 0xDEAD;
if ( debuglevel < 4 )
return;
if (status == old_status)
return;
printmsg(0, "showModem: %#04x%s%s%s%s%s",
status,
mannounce(FS_STAT_DCD, status, "\tCarrier Detect"),
mannounce(FS_STAT_OVERRUN, status, "\tR-Overrun"),
mannounce(FS_STAT_INQUEUED, status, "\tR-Pending"),
mannounce(FS_STAT_OUTPROOM, status, "\tX-Free"),
mannounce(FS_STAT_OUTPEMPT, status, "\tX-Empty")
);
old_status = status;
} /* showModem */
/*--------------------------------------------------------------------*/
/* g e t D r i v e r I n f o */
/* */
/* Return current FOSSIL driver information */
/*--------------------------------------------------------------------*/
static void getDriverInfo( FS_INFO *fossilData)
{
union REGS regs;
struct SREGS sregs;
regs.h.ah = FS_DRIVINFO; // Get driver information
regs.x.cx = sizeof *fossilData; // Into buffer this long
sregs.es = FP_SEG( fossilData ); // Use segment of buffer
regs.x.di = FP_OFF( fossilData ); // Use offset of buffer
regs.x.dx = portNum; // For this port
int86x( FS_INTERRUPT, ®s, ®s, &sregs);
if ( regs.x.ax != sizeof *fossilData )
{
printmsg(0,"getDriverInfo: Read of FOSSIL information failed, "
" %d bytes returned", regs.x.ax );
panic();
}
} /* getDriverInfo */
/*--------------------------------------------------------------------*/
/* b l o c k I O */
/* */
/* Perform block I/O between memory and the FOSSIL data */
/* queues */
/*--------------------------------------------------------------------*/
static short blockIO( char *buffer, const short len, const char function)
{
union REGS regs;
struct SREGS sregs;
regs.x.dx = portNum; // Perform function against port
regs.h.ah = FS_STATPORT; // First, set up to get status
int86( FS_INTERRUPT, ®s, ®s); // ... get the info ...
showModem ( regs.x.ax ); // ... and report it
regs.h.ah = function; // Input or output function
regs.x.cx = len; // Into buffer this long
sregs.es = FP_SEG( buffer); // Use segment of the buffer
regs.x.di = FP_OFF( buffer ); // Use offset of buffer
int86x( FS_INTERRUPT, ®s, ®s, &sregs);
if ( len > (short) regs.x.ax )
printmsg(4,"blockIO: Buffer %d bytes, only moved %d bytes",
len,
regs.x.ax );
else if ( len < (short) regs.x.ax )
{
printmsg(4,"blockIO: BUFFER (%d bytes) OVERRUN, moved %d bytes",
len,
regs.x.ax );
panic();
}
return (short) regs.x.ax; // Return bytes moved
} /* blockIO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -