#include "insignia.h"
#include "host_def.h"
#ifdef PRINTER
/*
* VPC-XT Revision 1.0
*
* Title: Parallel Printer Port Emulation
*
* Description: Emulates the IBM || Printer card as used in the original
* IBM XT, which is itself a H/W emulation of an Intel 8255.
*
* Author: Henry Nash
*
* Notes: None
*
* Mods:
* <chrisP 11Sep91>
* Allow transition to NOTBUSY in the OUTA state as well as the READY
* state. i.e. at the leading edge of the ACK pulse after just one
* INB (STATUS) rather than two. Our printer port emulation relies on
* these INB's to toggle the ACK line and set NOTBUSY true again. So
* the port could be left in the BUSY condition at the end of an app's
* print job (which can confuse the next print request). NOTE we could
* still have a problem if the PC app bypasses the BIOS and is too lazy
* to do even one INB(STATUS) after the last print byte.
*/
/* for NTVDM port -- williamh
* There are such things called Dongles which many software companies have
* used for copy protection. Each software comes with its dedicated Dongle
* that records necessary indentification inforamtion. It is required
* to plug the device onto the parallel port in order to run the software
* correctly. The device has an outlet which can be connectted to parallel
* port printer so the the user doesn't sacrifice his parallel port when
* the device in plugged on the original connector.
* There are several Dongle vendors and each one of them provides their
* propietary library or driver for the applications to link to. These
* drivers know how to read/WRITE the Dongle to verify a legitmate copy.
* Since it has to maintain compatiblility with standard PC parallel port,
* the devices are designed in a way that it can be programmed without
* disturbing ordinary parallel port operation. To do this, it usually does
* this:
* (1) Turn off strobe.
* (2) output data pattern to data port
* (3) delay a little bit(looping in instructions) and then go to (2)
* until the chunk of data has been sent. NOTE THAT THE STROBE LINE
* IS NEVER "strobe"
* (4). Read status port and by interpreting the line differently,
* the driver decodes any id information it is looking for.
*
* In order to support these devices, we have to do these:
* (1). We can not fake printer status. We have to get the real
* status line states.
* (2). we have to output data to the printer without waiting the data
* to be qualified(strobing).
* (3). We must be smart enough to detect the application is done with
* its Dongle things and wants everything goes back to normal.
* We must adjust ourselves under this circumestances.
* (4). Down level printer driver must provide function that we can call
* to control the port directly.
* (5). Printer h/w interrupt is not allowed to be enabled under this
* circumstance --and how can we make sure of that?????
*
*/
#ifdef SCCSID
static char SccsID[] = "@(#)printer.c 1.19 11/14/94 Copyright Insignia Solutions Ltd.";
#endif
#ifdef SEGMENTATION
/*
* The following #include specifies the code segment into which this
* module will by placed by the MPW C compiler on the Mac II running
* MultiFinder.
*/
#include "SOFTPC_PRINTER.seg"
#endif
/*
* O/S include files.
*/
#include <stdio.h>
#include TypesH
#include TimeH
#ifdef SYSTEMV
#ifdef STINGER
#include <sys/termio.h>
#endif
#endif
/*
* SoftPC include files
*/
#include "xt.h"
#include CpuH
#include "sas.h"
#include "ios.h"
#include "bios.h"
#include "printer.h"
#include "error.h"
#include "config.h"
#include "host_lpt.h"
#include "ica.h"
#include "quick_ev.h"
#include "debug.h"
#ifndef PROD
#include "trace.h"
#endif
/*
* ============================================================================
* Global data
* ============================================================================
*/
/*
* ============================================================================
* Static data and defines
* ============================================================================
*/
#define PRINTER_BIT_MASK 0x3 /* bits decoded from address bus */
#define CONTROL_REG_MASK 0xE0; /* unused bits drift to HIGH */
#define STATUS_REG_MASK 0x07; /* unused bits drift to HIGH */
#define DATA_OFFSET 0 /* ouput register */
#define STATUS_OFFSET 1 /* status register */
#define CONTROL_OFFSET 2 /* control register */
#ifdef ERROR
#undef ERROR
#endif
static half_word output_reg[NUM_PARALLEL_PORTS];
static half_word control_reg[NUM_PARALLEL_PORTS];
#define NOTBUSY 0x80
#define ACK 0x40
#define PEND 0x20
#define SELECT 0x10
#define ERROR 0x08
static half_word status_reg[NUM_PARALLEL_PORTS];
#define IRQ 0x10
#define SELECT_IN 0x08
#define INIT_P 0x04
#define AUTO_FEED 0x02
#define STROBE 0x01
LOCAL IU8 retryErrorCount = 0; /* num status inb before clearing ERROR */
static int state[NUM_PARALLEL_PORTS]; /* state control variable */
/*
* set up arrays of all port addresses
*/
static io_addr port_start[] = {LPT1_PORT_START,LPT2_PORT_START,LPT3_PORT_START};
static io_addr port_end[] = {LPT1_PORT_END, LPT2_PORT_END, LPT3_PORT_END};
static int port_no[] = {LPT1_PORT_START & LPT_MASK, LPT2_PORT_START & LPT_MASK,
LPT3_PORT_START & LPT_MASK };
static half_word lpt_adapter[] = {LPT1_ADAPTER, LPT2_ADAPTER, LPT3_ADAPTER};
static sys_addr port_address[] = {LPT1_PORT_ADDRESS, LPT2_PORT_ADDRESS, LPT3_PORT_ADDRESS};
static sys_addr timeout_address[] = {LPT1_TIMEOUT_ADDRESS, LPT2_TIMEOUT_ADDRESS, LPT3_TIMEOUT_ADDRESS};
static q_ev_handle handle_for_out_event[NUM_PARALLEL_PORTS];
static q_ev_handle handle_for_outa_event[NUM_PARALLEL_PORTS];
#if defined(NTVDM) && defined(MONITOR)
/* sudeepb 24-Jan-1993 for printing performance for x86 */
sys_addr lp16BitPrtBuf;
sys_addr lp16BitPrtId;
sys_addr lp16BitPrtCount;
sys_addr lp16BitPrtBusy;
#endif
#define STATE_READY 0
#define STATE_OUT 1
#define STATE_OUTA 2
#if defined(NTVDM)
#define STATE_DATA 3
#define STATE_DONGLE 4
#endif
/*
* State transitions:
*
* +-> STATE_READY
* | |
* | | ........ write char to output_reg, print on low-high strobe
* | V set NOTBUSY to false
* | STATE_OUT
* | |
* | | ........ (read status) set ACK low
* | V
* | STATE_OUTA
* | |
* | | ........ (read status) set ACK high
* +-----+
*
* Caveat: if the control register interrupt request bit is set,
* we assume that the application isn't interested in getting the
* ACKs and just wants to know when the printer state changes back
* to NOTBUSY. I'm not sure to want extent you can get away with
* this: however, applications using the BIOS printer services
* should be OK.
*/
#ifdef PS_FLUSHING
LOCAL IBOOL psFlushEnabled[NUM_PARALLEL_PORTS]; /* TRUE if PostScript flushing
is enabled */
#endif /* PS_FLUSHING */
/*
* ============================================================================
* Internal functions & macros
* ============================================================================
*/
#define set_low(val, bit) val &= ~bit
#define set_high(val, bit) val |= bit
#define low_high(val1, val2, bit) (!(val1 & bit) && (val2 & bit))
#define high_low(val1, val2, bit) ((val1 & bit) && !(val2 & bit))
#define toggled(val1, val2, bit) ((val1 & bit) != (val2 & bit))
#define negate(val, bit) val ^= bit
/*
* Defines and variables to handle tables stored in 16-bit code for NT
* monitors.
*/
#if defined(NTVDM) && defined(MONITOR)
static BOOL intel_setup = FALSE;
static sys_addr status_addr;
static sys_addr control_addr;
static sys_addr state_addr;
#define get_status(adap) (sas_hw_at_no_check(status_addr+(adap)))
#define set_status(adap,val) (sas_store_no_check(status_addr+(adap),(val)))
#define get_control(adap) (sas_hw_at_no_check(control_addr+(adap)))
#define set_control(adap,val) (sas_store_no_check(control_addr+(adap),(val)))
#define get_state(adap) (sas_hw_at_no_check(state_addr+(adap)))
#define set_state(adap,val) (sas_store_no_check(state_addr+(adap),(val)))
#else /* NTVDM && MONITOR */
#define get_status(adap) (status_reg[adapter])
#define set_status(adap,val) (status_reg[adapter] = (val))
#define get_control(adap) (control_reg[adapter])
#define set_control(adap,val) (control_reg[adapter] = (val))
#define get_state(adap) (state[adapter])
#define set_state(adap,val) (state[adapter] = (val))
#endif /* NTVDM && MONITOR */
static void printer_inb IPT2(io_addr, port, half_word *, value);
static void printer_outb IPT2(io_addr, port, half_word, value);
static void notbusy_check IPT1(int,adapter);
/*
* ============================================================================
* External functions
* ============================================================================
*/
void printer_post IFN1(int,adapter)
{
/*
* Set up BIOS data area.
*/
sas_storew(port_address[adapter],(word)port_start[adapter]);
sas_store(timeout_address[adapter], (half_word)0x14 ); /* timeout */
}
#if defined(NTVDM) && defined(MONITOR)
static void lpr_state_outa_event IFN1(long,adapter)
{
set_status(adapter, get_status(adapter) | ACK);
set_state(adapter, STATE_READY);
}
static void lpr_state_out_event IFN1(long,adapter)
{
set_status(adapter, get_status(adapter) & ~ACK);
set_state(adapter, STATE_OUTA);
handle_for_outa_event[adapter]=add_q_event_t(lpr_state_outa_event,HOST_PRINTER_DELAY,adapter);
}
#else /* NTVDM && MONITOR */
static void lpr_state_outa_event IFN1(long,adapter)
{
set_high(status_reg[adapter],ACK);
state[adapter]=STATE_READY;
}
static void lpr_state_out_event IFN1(long,adapter)
{
set_low(status_reg[adapter], ACK);
state[adapter]=STATE_OUTA;
handle_for_outa_event[adapter]=add_q_event_t(lpr_state_outa_event,HOST_PRINTER_DELAY,adapter);
}
#endif /* NTVDM && MONITOR */
static void printer_inb IFN2(io_addr,port, half_word *,value)
{
int adapter, i;
note_trace1(PRINTER_VERBOSE,"inb from printer port %#x ",port);
/*
** Scan the ports to find out which one is used. NB the
** port must be valid one because we only used io_define_inb()
** for the valid ports
*/
for(i=0; i < NUM_PARALLEL_PORTS; i++)
if((port & LPT_MASK) == port_no[i])
break;
adapter = i % NUM_PARALLEL_PORTS;
port = port & PRINTER_BIT_MASK; /* clear unused bits */
switch(port)
{
case DATA_OFFSET:
*value = output_reg[adapter];
break;
case STATUS_OFFSET:
switch(get_state(adapter))
{
#if defined(NTVDM)
case STATE_DONGLE:
/* read directly from the port for Dongle */
*value = host_read_printer_status_port(adapter);
set_status(adapter, *value);
break;
case STATE_DATA:
#endif
case STATE_READY:
notbusy_check(adapter);
*value = get_status(adapter) | STATUS_REG_MASK;
/* Clear ERROR as it will be set if we fail on the print. */
/* Clear after two inbs as DOS seems to require this. */
if (retryErrorCount > 0)
retryErrorCount--;
else
set_status(adapter, get_status(adapter) | ERROR);
break;
case STATE_OUT:
*value = get_status(adapter) | STATUS_REG_MASK;
#ifndef DELAYED_INTS
delete_q_event(handle_for_out_event[adapter]);
lpr_state_out_event(adapter);
#else
set_low(status_reg[adapter], ACK);
state[adapter] = STATE_OUTA;
#endif /* DELAYED INTS */
break;
case STATE_OUTA:
notbusy_check(adapter); /* <chrisP 11Sep91> */
*value = get_status(adapter) | STATUS_REG_MASK;
#ifndef DELAYED_INTS
delete_q_event(handle_for_outa_event[adapter]);
lpr_state_outa_event(adapter);
#else
set_high(status_reg[adapter], ACK);
state[adapter] = STATE_READY;
#endif
break;
default:
note_trace1(PRINTER_VERBOSE,
"<pinb() - unknown state %x>",
get_state(adapter));
break;
}
break;
case CONTROL_OFFSET:
*value = get_control(adapter) | CONTROL_REG_MASK;
negate(*value, STROBE);
negate(*value, AUTO_FEED);
negate(*value, SELECT_IN);
break;
}
note_trace3(PRINTER_VERBOSE, "<pinb() %x, ret %x, state %x>",
port, *value, get_state(adapter));
}
static void printer_outb IFN2(io_addr,port, half_word,value)
{
int adapter, i;
half_word old_control;
#ifdef PC_CONFIG
char variable_text[MAXPATHLEN];
int softpcerr;
int severity;
softpcerr = 0;
severity = 0;
#endif
note_trace2(PRINTER_VERBOSE,"outb to printer port %#x with value %#x",
port, value);
/*
** Scan the ports to find out which one is used. NB the
** port must be valid one because we only used io_define_inb()
** for the valid ports
*/
for(i=0; i < NUM_PARALLEL_PORTS; i++)
if((port & LPT_MASK) == port_no[i])
break;
adapter = i % NUM_PARALLEL_PORTS;
note_trace3(PRINTER_VERBOSE, "<poutb() %x, val %x, state %x>",
port, value, get_state(adapter));
port = port & PRINTER_BIT_MASK; /* clear unused bits */
switch(get_state(adapter))
{
#if defined(NTVDM)
case STATE_DONGLE:
if (port == DATA_OFFSET) {
output_reg[adapter] = value;
host_print_byte(adapter, value);
break;
}
// fall through
case STATE_DATA:
if (port == DATA_OFFSET) {
if (host_set_lpt_direct_access(adapter, TRUE)) {
host_print_byte(adapter, output_reg[adapter]);
host_print_byte(adapter, value);
set_state(adapter, STATE_DONGLE);
/* Write char to internal buffer */
output_reg[adapter] = value;
}
else {
/* unable to open the lpt for direct access,
mark the device busy */
#if !defined(MONITOR)
set_low(status_reg[adapter], NOTBUSY);
#else /* NTVDM && !MONITOR */
set_status(adapter, 0x7F);
#endif
}
break;
}
// fall through
#endif
case STATE_OUT:
case STATE_OUTA:
case STATE_READY:
switch(port)
{
case DATA_OFFSET:
#if defined(NTVDM)
set_state(adapter, STATE_DATA);
#endif
/* Write char to internal buffer */
output_reg[adapter] = value;
break;
case STATUS_OFFSET:
/* Not possible */
break;
case CONTROL_OFFSET:
/* Write control bits */
old_control = get_control(adapter); /* Save old value to see what's changed */
set_control(adapter, value);
if (low_high(old_control, value, INIT_P))
#ifdef PC_CONFIG
/* this was a call to host_print_doc - <chrisP 28Aug91> */
host_reset_print(&softpcerr, &severity);
if (softpcerr != 0)
host_error(softpcerr, severity, variable_text);
#else
/* this was a call to host_print_doc - <chrisP 28Aug91> */
host_reset_print(adapter);
#endif
if (toggled(old_control, value, AUTO_FEED))
host_print_auto_feed(adapter,
((value & AUTO_FEED) != 0));
if (low_high(old_control, value, STROBE))
{
#if defined(NTVDM)
if (get_state(adapter) == STATE_DONGLE) {
host_set_lpt_direct_access(adapter, FALSE);
/* pass through to print out the last byte
* which we have sent it out the data port
* while we are in DONGLE state.
*/
set_state(adapter, STATE_READY);
}
#endif
#ifdef PS_FLUSHING
/*
* If PostScript flushing is enabled for this
* port then we flush on a Ctrl-D
*/
if ( psFlushEnabled[adapter] &&
output_reg[adapter] == 0x04 /* ^D */ ) {
host_print_doc(adapter);
} else {
#endif /* PS_FLUSHING */
/*
* Send the stored internal buffer to
* the printer
*/
if(host_print_byte(adapter,output_reg[adapter]) == FALSE)
{
set_status(adapter, get_status(adapter) & ~ERROR); /* active Low */
/* NTVDM had here(?): set_status(adapter, ACK|PEND|SELECT|ERROR); */
/* two status inbs before we clear ERROR */
retryErrorCount = 2;
}
else
{
/* clear ERROR condition */
set_status(adapter, get_status(adapter) | ERROR);
#if defined(NTVDM) && !defined(MONITOR)
set_low(status_reg[adapter], NOTBUSY);
#else /* NTVDM && !MONITOR */
set_status(adapter,
get_status(adapter) & ~NOTBUSY);
#endif /* NTVDM && !MONITOR */
set_state(adapter, STATE_OUT);
#ifndef DELAYED_INTS
handle_for_out_event[adapter]=add_q_event_t(lpr_state_out_event,HOST_PRINTER_DELAY,adapter);
#endif /* DELAYED_INTS */
}
#ifdef PS_FLUSHING
}
#endif /* PS_FLUSHING */
}
else if (high_low(old_control, value, STROBE)
&& get_state(adapter) == STATE_OUT)
{
if (value & IRQ)
{
/*
* Application is using
* interrupts, so we can't
* rely on INBs being
* used to check the
* printer status.
*/
set_state(adapter, STATE_READY);
notbusy_check(adapter);
}
}
#if defined(NTVDM)
else if (low_high(old_control, value, IRQ) &&
get_state(adapter) == STATE_DONGLE) {
host_set_lpt_direct_access(adapter, FALSE);
set_state(adapter, STATE_READY);
}
#endif
#ifndef PROD
if (old_control & IRQ)
note_trace1(PRINTER_VERBOSE, "Warning: LPT%d is being interrupt driven\n",
number_for_adapter(adapter));
#endif
break;
}
break;
default:
note_trace1(PRINTER_VERBOSE, "<poutb() - unknown state %x>",
get_state(adapter));
break;
}
}
void printer_status_changed IFN1(int,adapter)
{
note_trace1(PRINTER_VERBOSE, "<printer_status_changed() adapter %d>",
adapter);
/* check whether the printer has just changed state to NOTBUSY */
notbusy_check(adapter);
}
/*
* ============================================================================
* Internal functions
* ============================================================================
*/
static void notbusy_check IFN1(int,adapter)
{
/*
* This function is used to detect when the printer
* state transition to NOTBUSY occurs.
*
* If the parallel port is being polled, the port
* emulation will stop this transition occurring
* until the application has detected the ACK
* pulse. notbusy_check() is then called each time the
* port status is read using the INB; when the host
* says the printer is HOST_LPT_BUSY, the port status
* returns to the NOTBUSY state.
*
* If the parallel port is interrupt driven, we cannot
* rely on the application using the INB: so we first
* check the host printer status immediately after
* outputting the character. If the host printer isn't
* HOST_LPT_BUSY, then we interrupt immediately;
* otherwise, we rely on the printer_status_changed()
* call to notify us of when HOST_LPT_BUSY is cleared.
*/
/* <chrisP 11Sep91> allow not busy at leading edge of ack pulse too */
if ( (get_state(adapter) == STATE_READY ||
#if defined(NTVDM)
get_state(adapter) == STATE_DATA ||
#endif
get_state(adapter) == STATE_OUTA)
&& !(get_status(adapter) & NOTBUSY)
&& !(host_lpt_status(adapter) & HOST_LPT_BUSY))
{
#if defined(NTVDM) && !defined(MONITOR)
set_high(status_reg[adapter], NOTBUSY);
#else /* NTVDM && !MONITOR */
set_status(adapter, get_status(adapter) | NOTBUSY);
#endif /* NTVDM && !MONITOR */
#ifndef PROD
if (io_verbose & PRINTER_VERBOSE)
fprintf(trace_file, "<printer notbusy_check() - adapter %d changed to NOTBUSY>\n", adapter);
#endif
if (get_control(adapter) & IRQ)
{
ica_hw_interrupt(0, CPU_PRINTER_INT, 1);
}
}
}
#ifdef SEGMENTATION
/*
* The following #include specifies the code segment into which this
* module will by placed by the MPW C compiler on the Mac II running
* MultiFinder.
*/
#include "SOFTPC_INIT.seg"
#endif
/*
** Initialise the printer port required.
*/
void printer_init IFN1(int,adapter)
{
io_addr i;
io_define_inb( lpt_adapter[adapter], printer_inb );
io_define_outb( lpt_adapter[adapter], printer_outb );
for(i = port_start[adapter]; i < port_end[adapter]; i++)
io_connect_port(i,lpt_adapter[adapter],IO_READ_WRITE);
#if defined(NTVDM) && defined(MONITOR)
/*
* If we know the addresses of the 16-bit variables write directly
* to them, otherwise save the value until we do.
*/
if (intel_setup)
{
set_status(adapter, 0xDF);
set_control(adapter, 0xEC);
}
else
#endif /* NTVDM && MONITOR */
{
control_reg[adapter] = 0xEC;
status_reg[adapter] = 0xDF;
}
output_reg[adapter] = 0xAA;
/*
* The call to host_print_doc has been removed since it is
* sensible to distinguish between a hard flush (on ctl-alt-del)
* or menu reset and a soft flush under user control or at end
* of PC application. The calls to host_lpt_close() followed
* by host_lpt_open() should already cause a flush to occur,
* so no functionality is lost. The first time printer_init is
* called host_lpt_close() is not called, but this cannot
* matter since host_print_doc() can only be a no-op.
*/
/* host_print_doc(adapter); */
host_print_auto_feed(adapter, FALSE);
#if defined(NTVDM) && defined(MONITOR)
if (intel_setup)
set_state(adapter, STATE_READY);
else
#endif /* NTVDM && MONITOR */
state[adapter] = STATE_READY;
} /* end of printer_init() */
#if defined(NTVDM) && defined(MONITOR)
/*
** Store 16-bit address of status table and fill it with current values.
*/
#ifdef ANSI
void printer_setup_table(sys_addr table_addr)
#else /* ANSI */
void printer_setup_table(table_addr)
sys_addr table_addr;
#endif /* ANSI */
{
int i;
sys_addr lp16BufSize;
unsigned int cbBuf;
word lptBasePortAddr[NUM_PARALLEL_PORTS];
if (!intel_setup)
{
/*
* Store the addresses of the tables resident in 16-bit code. These
* are:
* status register (NUM_PARALLEL_PORTS bytes)
* state register (NUM_PARALLEL_PORTS bytes)
* control register (NUM_PARALLEL_PORTS bytes)
* host_lpt_status (NUM_PARALLEL_PORTS bytes)
*
* Then transfer any values which have already been set up into the
* variables. This is in case printer_init has been called prior to
* this function.
*/
status_addr = table_addr;
state_addr = table_addr + NUM_PARALLEL_PORTS;
control_addr = table_addr + 2 * NUM_PARALLEL_PORTS;
for (i = 0; i < NUM_PARALLEL_PORTS; i++)
{
set_status(i, status_reg[i]);
set_state(i, state[i]);
set_control(i, control_reg[i]);
lptBasePortAddr[i] = port_start[i];
}
/* Let host know where host_lpt_status is stored in 16-bit code. */
host_printer_setup_table(table_addr, NUM_PARALLEL_PORTS, lptBasePortAddr);
/* sudeepb 24-Jan-1993 for printing performance for x86 */
lp16BufSize = table_addr + 4 * NUM_PARALLEL_PORTS;
cbBuf = (sas_w_at_no_check(lp16BufSize));
lp16BitPrtBuf = table_addr + (4 * NUM_PARALLEL_PORTS) + 2;
lp16BitPrtId = lp16BitPrtBuf + cbBuf;
lp16BitPrtCount = lp16BitPrtId + 1;
lp16BitPrtBusy = lp16BitPrtCount + 2;
intel_setup = TRUE;
}
}
#endif /* NTVDM && MONITOR */
#endif
#ifdef NTVDM
void printer_is_being_closed(int adapter)
{
#if defined(MONITOR)
set_state(adapter, STATE_READY);
#else
state[adapter] = STATE_READY;
#endif
}
#endif
#ifdef PS_FLUSHING
/*(
=========================== printer_psflush_change ============================
PURPOSE:
Handle change of PostScript flush configuration option for a printer
port.
INPUT:
hostID - Configuration item I.D.
apply - TRUE if change to be applied
OUTPUT:
None
ALGORITHM:
If PostScript flushing is being enabled then;
set the PostScript flush enable flag for the port;
disable autoflush for the port;
else;
reset the PostScript flush enable flag for the port;
enable autoflush for the port;
===============================================================================
)*/
GLOBAL void printer_psflush_change IFN2(
IU8, hostID,
IBOOL, apply
) {
IS32 adapter = hostID - C_LPT1_PSFLUSH;
assert1(adapter < NUM_PARALLEL_PORTS,"Bad hostID %d",hostID);
if ( apply )
if ( psFlushEnabled[adapter] = (IBOOL)config_inquire(hostID,NULL) )
host_lpt_disable_autoflush(adapter);
else
host_lpt_enable_autoflush(adapter);
}
#endif /* PS_FLUSHING */