GS4500 scanner driver (and lookalikes) V1.0

This code was written using the slim manual supplied with my scanner,
and a lot of port probing to figure out what was happening.  As a
consequence, I can't be sure that what I'm doing is the right way to
do it, but it works.  If you find any problems or have any suggestions,
don't hestitate to let me know.  I'd particularly like to hear from
users who add support for other scanners.

Do what you like with the code, but please acknowledge me as the
author if you redistribute it.

Installing:
  1. Patch the kernel (pl13) with:
	(cd /usr/src/linux/kernel/chr_drv ; patch -p0) < kernel.patch
     If you are not running pl13, you will have to patch by hand (it's
     easy to do).
  2. Copy scanner.c into the kernel tree:
	cp scanner.c /usr/src/linux/kernel/chr_drv
  3. Create the scanner device:
	mknod /dev/scanner c 30 0
  6. Compile testscan.c:
	cc -o testscan testscan.c
  7. Rebuild kernel & reboot.
  8. Start X, do `testscan | xv -'.

The `30' in step 5 is the major device # I'm using for the scanner.  If
you already have a device using this number, pick one of your own, and
change SCANNER_MAJOR in scanner.c.  I tried doing as the FAQ says and
using a major > 128, but MAX_CHRDRV is set to 32 in pl9, and looking
through the allocated major #'s, 30 appeared to be unused.

Only the GS4500 is supported at the moment, since that's all I've got.
scanner_init() uses a table of probe routines to determine which
scanner is attached, so if any other scanners are supported it should
be fairly simple to include them.

Because the scanner uses DMA, but no IRQ, the kernel must busy wait on
the terminal count in the DMA chip to determine when a scanline has
been read.  This can be a major performance hit, since the kernel can't
do anything until the number of bytes requested by read() have been
extracted from the scanner.  What the code does is do a schedule()
while waiting for the terminal count.  While this allows other tasks to
be run, it can lead to data dropouts if something that takes a long
time gets run (eg, disk sync).  If the integrity of your scanned data
takes precedence over the rest of the system, comment out the "else
schedule()" lines from scanner.c.

Cheers,
Rick.
