home *** CD-ROM | disk | FTP | other *** search
- A FAST PARALLEL PORT DRIVER THAT DOES NOT USE INTERRUPTS
-
- This is the source of a parallel port driver for System V/386, rel. 3.2.
-
- It is different from the standard lp(7) driver because it does only raw
- output (while lp(7) uses the termio(4) line discipline), and it does not use
- interrupts. It assumes that the printer has an internal buffer, so that the
- most efficient style of communication is to pump characters as fast as
- possible until the buffer fills, then sleep for a relatively long period
- when it signals not ready, and try again thereafter.
-
- This implies that no interrupt processing is done, which has the advantages
- of simplicity and low overhead, and, perhaps most importantly, of not using
- one of the scarce interurpt lines of the ISA bus.
-
- OUTLINE OF DESIGN
-
- Output is done entirely in the top half of the driver, and therefore not
- inside a critical region. This could mean that on a very busy system the
- pumping could be interrupted by task switching. This, if important, can be
- easily obviated, by turning the pumping loop into a critical region; if this
- is done it becomes important to limit the number of characters pumped in one
- go, by having two loops, the outer one that runs until busy is signaled, the
- inner one for a fixed number of characters, and put only the inner one in
- the critical region.
-
- A similar driver has been posted by Mike Grenier; this version is completely
- rewritten and uses different logic. In particular the polling waits are
- either very short if busy or interruptible if sleeping.
-
- INSTALLATION
-
- As it stands it is especially designed for a stock System V/386 rel. 3.2
- system, e.g. ESIX, especially inasmuch installation is concerned. It should
- be sufficient to say 'make install' to install it, and then you should say
- 'idconfig' and 'idmkunix' to rebuild the kernel (but first finish reading
- this file). The Makefile will install "pp.h" into "/usr/include/sys", which
- is required.
-
- This driver is so simple that it should port very quickly to other flavours
- of Unix; the only thing that may not be portable is the reference to a kernel
- procedure called 'tenmicrosec()' in pp.c, which does a busy loop of 10
- microseconds. It is fairly easy to roll your own, of course.
-
- CONFIGURATION OF PARAMETERS
-
- This version can be configured in several ways. You can, in file "pp.h",
- define ppSTATICSZ as either zero, in which case a buffer will be stolen from
- the block cache whenever a parallel port is open, or non zero, in which case
- a static buffer will be allocated for each parallel port. The only reason
- for a buffer in this driver is to cut down on procedure invocations to fetch
- characters to transmit from the user space, so even a small buffer will be
- sufficient to amortize the cost of a procedure call (anything upwards of 64
- bytes is probably OK). I recommend using a smallish static buffer (say
- 128-256 bytes), as probably the code that implements cache block stealing
- and restitution is about that size anyhow :-), even if static allocation is
- aesthetically less pleasing (character by character fetching was simpler and
- insignificantly slower, but I will not bother putting it back in). Note that
- there is no interlocking provided for access (as opposed to allocation) to
- the buffer; if two processes try to write to the printer at the same time,
- they will use the same buffer without any synchronization. It is expected
- that higher level synchronization and queueing mechanisms exist.
-
- You can configure, in file "space.c", a number of things; first the
- addresses of the IO ports of the printers you have got. These should not
- need changing at all on an AT compatible 386. At worst, you can
- comment/uncomment those lines that correspond to devices you have/don't
- have. You can also configure the masks and the durations for long term
- (waiting for the printer to be online) pauses and for short term (waiting
- for the interface buffer to become less choked) pauses. You can also
- configure the number of tens of microseconds we are prepared to busy wait
- for the interface to accept the next character before switching to short
- term pausing and waiting for it to reach some low water mark.
-
- In general the mask and pause values given as defaults should work, and the
- pause durations do not matter that much; the max spinning count (busy wait
- loops) parameters is more critical, in that if it is too small the printer
- will be driven very slowly (only a few characters per second), because a
- short pause will be entered on every character. If it is too large some time
- will be wasted when the interface becomes choked before we give up spinning,
- but this is probably not very frequent or important. The default value is
- conservative enough for my printer, but raise it if you are in doubt.
-