--- linux-2.4.20-pfeifer-r1_pre8/Documentation/usb/scanner.txt	2003-05-03 09:26:13.000000000 -0500
+++ linux-2.4.20-pfeifer-r1_pre9/Documentation/usb/scanner.txt	2003-02-28 06:15:24.000000000 -0600
@@ -1,154 +1,114 @@
 Copyright (C) 1999, 2000 David E. Nelson <dnelson@jump.net>
+Updated 2003 by Henning Meier-Geinitz <henning@meier-geinitz.de>
 
-April 26, 2000
-
-CHANGES
-
-- Amended for linux-2.4.12
-- Updated devfs support
-- Amended for linux-2.3.99-pre6-3
-- Appended hp_scan.c to end of this README
-- Removed most references to HP
-- Updated uhci/ohci host controller info
-- Updated support for multiple scanner support
-- Updated supported scanners list
-- Updated usbdevfs info
-- Spellcheck
 
 OVERVIEW
 
-This README addresses issues regarding how to configure the kernel
-to access a USB scanner.  Although the driver was originally conceived
-for USB HP scanners, it's general enough so that it can be used with
-other scanners.  Also, one can now pass the USB Vendor and Product
-ID's using module parameters for unknown scanners.  Refer to the
-document scanner-hp-sane.txt for guidance on how to configure SANE to
-use a USB HP Scanner.
+This README addresses issues regarding how to configure the kernel to access a
+USB scanner.  Although the driver was originally conceived for USB HP
+scanners, it's general enough so that it can be used with most other USB
+scanners.  Also, one can pass the USB Vendor and Product IDs using module
+parameters for unknown scanners.
+
+There are two drivers for SCSI-over-USB scanners: 
+* The "hpusbscsi" module for Hewlett-Packard 53xx series, Hewlett-Packard 7400,
+  Minolta Scan Dual II, Minolta Elite II
+* The "microtek" module for the Microtek Scanmaker X6
+
+In addition to the kernel driver, user-space tools like SANE are necessary to
+actually use the scanner.  SANE ("Scanner Access Now Easy") provides drivers
+for a variety of USB scanners.  See the appropriate SANE man page for details,
+e.g. man sane-usb and man sane-hp (for HP scanners).
+
+NOTE: Just because a product is detected by this driver does not mean that
+applications exist that support the product.  It's in the hopes that this will
+allow developers a means to produce applications that will support the listed
+USB products.
 
 
 ADDITIONAL INFORMATION
 
-http://www.linux-usb.org/
+http://www.linux-usb.org/           (General information, mailing lists, links)
+http://www.mostang.com/sane/        (SANE user-space tools)
+http://www.meier-geinitz.de/kernel/ (USB scanner driver information and patches)
 
 
 REQUIREMENTS
 
-A host with a USB port.  Ideally, either a UHCI (Intel) or OHCI
-(Compaq and others) hardware port should work.  At the time of this
-writing, there are two UHCI drivers and one OHCI.
-
-A Linux kernel with USB support enabled or a backported version to
-linux-2.2.x.  See http://www.linux-usb.org for more information on
-accomplishing this.
-
-'lspci' which is only needed to determine the type of USB hardware
-available/installed in your machine.
-
-CONFIGURATION
-
-Using `lspci -v`, determine the type of USB hardware available/installed.
+A host with a USB port.  Ideally, either a UHCI (Intel), OHCI (Compaq and
+others) or EHCI hardware should work.  
 
-  If you see something like:
+Using "make menuconfig" or your preferred method for configuring the kernel,
+select "Support for USB", "OHCI/UHCI/EHCI" depending on your hardware, "USB
+Scanner support", and "Preliminary USB device filesystem".  Compile and
+install the modules (you may need to execute "depmod -a" to update the module
+dependencies).  If any of the USB sections were compiled into the kernel, a
+reboot is necessary.  NOTE: Updating the boot disk with "lilo" may also be
+required.  Testing was performed only as modules, YMMV.
+
+Up to 16 scanners can be connected/used simultaneously.  If devfs support is
+enabled, see next section.  Otherwise, the device files must be created
+manually if they don't exist yet, either by MAKEDEV or mknod.
+
+MAKEDEV method:
+  cd /dev
+  MAKEDEV usb
+  Check that the device files "/dev/usb/scanner0" - "/dev/usb/scanner15" have
+  been created.
+
+mknod method:
+  mknod /dev/usb/scanner0 c 180 48
+  mknod /dev/usb/scanner1 c 180 49
+                  . 
+                  .
+  mknod /dev/usb/scanner15 c 180 63
 
-    USB Controller: ......
-    Flags: .....
-    I/O ports at ....
-
-  Then you have a UHCI based controller.
-
-  If you see something like:
-
-     USB Controller: .....
-     Flags: ....
-     Memory at .....
-
-  Then you have a OHCI based controller.
-
-Using `make menuconfig` or your preferred method for configuring the
-kernel, select 'Support for USB', 'OHCI/UHCI' depending on your
-hardware (determined from the steps above), 'USB Scanner support', and
-'Preliminary USB device filesystem'.  Compile and install the modules
-(you may need to execute `depmod -a` to update the module
-dependencies). If any of the USB sections were compiled into the
-kernel, a reboot is necessary. NOTE: Updating the boot disk with
-'lilo' may also be required. Testing was performed only as modules,
-YMMV.
-
-Beginning with version 0.4 of the driver, up to 16 scanners can be
-connected/used simultaneously.  For devfs support, see next section.
-If you intend to use more than one scanner at a time w/o devfs support:
-
-   Add a device for the USB scanner:
-	`mknod /dev/usbscanner0 c 180 48`
-	`mknod /dev/usbscanner1 c 180 49`
-                      . 
-                      .
-	`mknod /dev/usbscanner15 c 180 63`
-
-
-If you foresee using only one scanner it is best to:
-	`mknod /dev/usbscanner0 c 180 48`
-	`ln -s /dev/usbscanner0 /dev/usbscanner`
-
-
-Set appropriate permissions for /dev/usbscanner[0-15] (don't forget
+Set appropriate permissions for /dev/usb/scanner[0-15] (don't forget
 about group and world permissions).  Both read and write permissions
-are required for proper operation. For example:
-	`chmod 666 /dev/usbscanner0`
+are required for proper operation.  For example:
+  chmod 666 /dev/usb/scanner0
 
 Load the appropriate modules (if compiled as modules):
 
-  OHCI:
-    modprobe usb-ohci
-    modprobe scanner
-
-  UHCI:
-    modprobe usb-uhci
-    modprobe scanner
+  modprobe usb-ohci (or uhci, usb-uhci, ehci)
+  modprobe scanner
+
 
 DEVFS
 
 The later versions of the Linux kernel (2.4.8'ish) included a dynamic
-device filesystem call 'devfs'.  With devfs, there is no need to
+device filesystem call "devfs".  With devfs, there is no need to
 create the device files as explained above; instead, they are
 dynamically created for you.  For USB Scanner, the device is created
 in /dev/usb/scannerX where X can range from 0 to 15 depending on the
 number of scanners connected to the system.
 
-To see if you have devfs, issue the command `cat /proc/filesytems`.
-If devfs is listed you should be ready to go.  You sould also have a
-process running called 'devfsd'.  In order to make sure, issue the
-command `ps aux | grep '[d]evfsd'`.
-
-If you would like to maintain /dev/usbscanner0 in order to maintain
-compatibility with applications, then add the following to
-/etc/devfsd.conf:
-
-REGISTER ^usb/scanner0$ CFUNCTION GLOBAL symlink usb/scanner0 usbscanner0
-UNREGISTER ^usb/scanner0$ CFUNCTION GLOBAL unlink usbscanner0
+To see if you have devfs, issue the command "cat /proc/filesytems".
+If devfs is listed you should be ready to go.  You should also have a
+process running called "devfsd".  In order to make sure, issue the
+command "ps aux | grep '[d]evfsd'".
 
-Then reset the scanner (reseat the USB connector or power cycle). This
-will create the necessary symlinks in /dev to /dev/usb.
 
 CONCLUSION
 
-That's it.  SANE should now be able to access the device.  
+That's it.  SANE should now be able to access the device.  To make sure the
+device was detected, use "cat /proc/bus/usb/devices".  Your scanner should be
+listed and the line starting with "I:" should look similar to this example:
+
+  I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=usbscanner
+
+The important part is "Driver=usbscanner".  If it reads "Driver=(none)", the
+USB scanner driver didn't recognize the scanner.  Have a look at the MODULE
+PARAMETERS section for what to do in this case.
+
+For more details on the format of "/proc/bus/usb/devices" see
+Documentation/usb/proc_usb_info.txt.
 
-There is a small test program (hp_scan.c -- appended below) that can
-be used to test the scanner device if it's an HP scanner that supports
-SCL (Scanner Control Language).  Known HP scanner that support SCL are
-the 4100, 5200, 6200, the 6300 -- note that the 4200 is *not*
-supported since it does not understand SCL; it's also strongly
-suspected that the 3300 and the PhotoSmart S20 are not SCL compliant.
-Hp_scan.c's purpose is to test the driver without having to
-retrieve/configure SANE.  Hp_scan.c will scan the entire bed and put
-the output into a file called 'out.dat' in the current directory.  The
-data in the file is raw data so it's not very useful for imaging.
 
 MESSAGES
 
 usb_control/bulk_msg: timeout -- On occasions this message will appear
-in '/var/adm/messages', on the console, or both depending on how
+in "/var/adm/messages", on the console, or both depending on how
 your system is configured.  This is a side effect that scanners are
 sometimes very slow at warming up and/or initializing.  In most cases,
 however, only several of these messages should appear and is generally
@@ -165,122 +125,90 @@
 
 probe_scanner: Endpoint determination failed -- This means that the
 driver is unable to detect a supported configuration for means to
-communicate with the scanner.  See also 'probe_scanner: Undetected
-endpoint'.
+communicate with the scanner.  See also "probe_scanner: Undetected
+endpoint".
 
 funky result -- Most of the time the data flow between the computer
 and the scanner goes smoothly.  However, due to whatever reason,
 whether it be solar flares or stray neutrons, sometimes the
 communications don't work as expected.  The driver tries to handle
 most types of errors but not all.  When this message is seen,
-something weird happened.  Please contact the maintaner listed at the
-top of this file.
-
-SUPPORTED SCANNERS
-
-NOTE: Just because a product is listed here does not mean that
-applications exist that support the product.  It's in the hopes that
-this will allow developers a means to produce applications that will
-support the listed USB products.
-
-At the time of this writing, the following scanners were supported by
-scanner.c:
-
- Acer
-	 Prisa Acerscan 620U & 640U (!)
-	 Prisa AcerScan 620U (!)
- Agfa
-	 SnapScan 1212U
-	 Another SnapScan 1212U (?)
-	 SnapScan Touch
- Colorado -- See Primax/Colorado below
- Epson -- See Seiko/Epson below
- Genius
-         ColorPage-Vivid Pro
- Hewlett Packard
-	 3300C
-	 4100C
-	 4200C
-	 PhotoSmart S20
-	 5200C
-	 6200C
-	 6300C
- Microtek
-	 ScanMaker X6 - X6U
-	 Phantom 336CX - C3
-	 Phantom 336CX - C3 #2
-	 Phantom C6
-	 ScanMaker V6USL
-	 ScanMaker V6USL #2
-	 ScanMaker V6UL - SpicyU
- Mustek
-	 1200 CU
- Primax/Colorado
-	 G2-300 #1
-	 G2-600 #1
-	 G2E-300 #1
-	 ReadyScan 636i
-	 G2-300 #2
-	 G2-600 #2
-	 G2E-300 #2
-	 G2E-600
-	 Colorado USB 9600
-	 Colorado USB 19200
-	 Colorado 600u
-	 Colorado 1200u
- Seiko/Epson Corp.
-	 Perfection 636U and 636Photo
-	 Perfection 610
-	 Perfection 1200U and 1200Photo
- Umax
-	 Astra 1220U
-	 Astra 1236U
-	 Astra 2000U
-	 Astra 2200U
- Visioneer
-	 OneTouch 5300
-	 OneTouch 7600 duplicate ID (!)
-	 6100
+something weird happened.  Please contact the mailing list (see
+CONTACT section for details).
 
 
 MODULE PARAMETERS
 
 If you have a device that you wish to experiment with or try using
-this driver with, but the Vendor and Product ID's are not coded in,
+this driver with, but the Vendor and Product IDs are not coded in,
 don't despair.  If the driver was compiled as a module, you can pass
 options to the driver.  Simply add 
 
   options scanner vendor=0x#### product=0x****
 
 to the /etc/modules.conf file replacing the #'s and the *'s with the
-correct ID's.  The ID's can be retrieved from the messages file or
-using `cat /proc/bus/usb/devices`. Note that USB /proc support must be
-enabled during kernel configuration.  If the 'scanner' module is
-already loaded into memory, it must be reloaded for the module
-parameters to take effect.  In essence, `rmmod scanner; modprobe
-scanner` must be performed.
+correct IDs.  The IDs can be retrieved from the messages file or
+using "cat /proc/bus/usb/devices".
 
-**NOTE**: In later kernels (2.3.38+), a new filesystem was introduced,
-usbdevfs.  To mount the filesystem, issue the command (as root):
+If the default timeout is too low, i.e. there are frequent "timeout" messages,
+you may want to increase the timeout manually by using the parameter
+"read_timeout".  The time is given in seconds.  This is an example for
+modules.conf with a timeout of 60 seconds:
+
+  options scanner read_timeout=60
+ 
+If the "scanner" module is already loaded into memory, it must be reloaded for
+the module parameters to take effect.  In essence, "rmmod scanner; modprobe
+scanner" must be performed.
 
-  mount -t usbdevfs /proc/bus/usb /proc/bus/usb
 
-An alternative and more permanent method would be to add
+BUGS
 
-  none  /proc/bus/usb  usbdevfs  defaults  0  0
+Just look at the list of fixes in the source files. 
 
-to /etc/fstab.  This will mount usbdevfs at each reboot.  You can then
-issue `cat /proc/bus/usb/devices` to extract USB device information.
 
+CONTACT
 
-BUGS
+For asking about problems and fixes, use the linux-usb-users mailing list. For
+patches, linux-usb-devel should be used. Information on both lists can be
+found on http://www.linux-usb.org/.
+
+
+CHANGES
+
+- Added information about read_timeout
+- Added more details about /proc/bus/usb/devices
+- Added/updated links
+- Added pointers two "special" scanner drivers
+- Reordering, spell-checking, formatting
+- Used /dev/usb/scanner[0-15] instead of /dev/usbscanner[0-15]
+- Removed some basic USB configuration stuff
+- Added EHCI
+- Removed some more references to HP
+- Amended for linux-2.4.12
+- Updated devfs support
+- Amended for linux-2.3.99-pre6-3
+- Appended hp_scan.c to end of this README
+- Removed most references to HP
+- Updated uhci/ohci host controller info
+- Updated support for multiple scanner support
+- Updated supported scanners list
+- Updated usbdevfs info
+- Spellcheck
 
-Just look at the list of fixes in the source files.  So, if you
-encounter any problems feel free to drop me an email.
 
-David /\/elson
-dnelson@jump.net
-http://www.jump.net/~dnelson
+HP TEST PROGRAM
+
+There is a small test program (hp_scan.c -- appended below) that can
+be used to test the scanner device if it's an HP scanner that supports
+SCL (Scanner Control Language).  Known HP scanner that support SCL are
+the 4100, 5200, 6200, the 6300 -- note that the 4200 is *not*
+supported since it does not understand SCL; it's also strongly
+suspected that the 3300 and the PhotoSmart S20 are not SCL compliant.
+Hp_scan.c's purpose is to test the driver without having to
+retrieve/configure SANE.  Hp_scan.c will scan the entire bed and put
+the output into a file called "out.dat" in the current directory.  The
+data in the file is raw data so it's not very useful for imaging.
 
 --------------- snip -- hp_scan.c -- snip ---------------
 /*
@@ -347,7 +275,7 @@
 		exit (1);
 	}
 	
-	if((fp=open("/dev/usbscanner", O_RDWR)) < 0) {
+	if((fp=open("/dev/usb/scanner0", O_RDWR)) < 0) {
 		perror("Unable to open scanner device");
 		exit (1);
 	}
--- linux-2.4.20-pfeifer-r1_pre8/include/linux/usb_scanner_ioctl.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pfeifer-r1_pre8/include/linux/usb_scanner_ioctl.h	2003-02-28 06:15:40.000000000 -0600
@@ -0,0 +1,9 @@
+/* USB Scanner IOCTLS */
+
+/* read vendor and product IDs from the scanner */
+#define SCANNER_IOCTL_VENDOR _IOR('U', 0x20, int)
+#define SCANNER_IOCTL_PRODUCT _IOR('U', 0x21, int)
+/* send/recv a control message to the scanner */
+#define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, struct usb_ctrlrequest )
+
+
--- linux-2.4.20-pfeifer-r1_pre8/drivers/usb/scanner.c	2003-05-03 09:26:13.000000000 -0500
+++ linux-2.4.20-pfeifer-r1_pre9/drivers/usb/scanner.c	2003-04-16 03:22:32.000000000 -0500
@@ -1,13 +1,16 @@
 /* -*- linux-c -*- */
 
 /* 
- * Driver for USB Scanners (linux-2.4.18)
+ * Driver for USB Scanners (linux-2.4)
  *
  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
+ * Copyright (C) 2002, 2003 Henning Meier-Geinitz
  *
  * Portions may be copyright Brad Keryan and Michael Gee.
  *
- * Brian Beattie <beattie@beattie-home.net>
+ * Previously maintained by Brian Beattie
+ *
+ * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -311,12 +314,55 @@
  *    - Changed maintainership from David E. Nelson to Brian
  *      Beattie <beattie@beattie-home.net>.
  *
+ * 0.4.9  12/19/2002
+ *    - Added vendor/product ids for Nikon, Mustek, Plustek, Genius, Epson,
+ *      Canon, Umax, Hewlett-Packard, Benq, Agfa, Minolta scanners.
+ *      Thanks to Dieter Faulbaum <faulbaum@mail.bessy.de>, Stian Jordet
+ *      <liste@jordet.nu>, "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>,
+ *      "Jaeger, Gerhard" <gerhard@gjaeger.de>, Ira Childress 
+ *      <ichildress@mn.rr.com>, Till Kamppeter <till.kamppeter@gmx.net>,
+ *      Ed Hamrick <EdHamrick@aol.com>, Oliver Schwartz
+ *      <Oliver.Schwartz@gmx.de> and everyone else who sent ids.
+ *    - Some Benq, Genius and Plustek ids are identified now.
+ *    - Don't clutter syslog with "Unable to access minor data" messages.
+ *    - Accept scanners with only one bulk (in) endpoint (thanks to Sergey
+ *      Vlasov <vsu@mivlgu.murom.ru>).
+ *    - Accept devices with more than one interface. Only use interfaces that
+ *      look like belonging to scanners.
+ *    - Use altsetting[0], not altsetting[ifnum].
+ *    - Add locking to ioctl_scanner(). Thanks to Oliver Neukum
+ *      <oliver@neukum.name>.
+ *
+ * 0.4.10  01/07/2003
+ *    - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek 
+ *      and Visioneer scanners. Thanks to William Lam <wklam@triad.rr.com>,
+ *      Till Kamppeter <till.kamppeter@gmx.net> and others for all the ids.
+ *    - Cleaned up list of vendor/product ids.
+ *    - Print information about user-supplied ids only once at startup instead
+ *      of everytime any USB device is plugged in.
+ *    - Removed PV8630 ioctls. Use the standard ioctls instead.
+ *    - Made endpoint detection more generic. Basically, only one bulk-in 
+ *      endpoint is required, everything else is optional.
+ *    - Move the scanner ioctls to usb_scanner_ioctl.h to allow access by archs
+ *      that need it (by Greg KH).
+ *    - New maintainer: Henning Meier-Geinitz.
+ *    - Print ids and device number when a device was detected.
+ *    - Don't print errors when the device is busy.
+ *      
+ * 0.4.11  2003-02-25
+ *    - Added vendor/product ids for Artec, Avision, Brother, Canon, Compaq,
+ *      Fujitsu, Hewlett-Packard, Lexmark, LG Electronics, Medion, Microtek,
+ *      Primax, Prolink,  Plustek, SYSCAN, Trust and UMAX scanners.
+ *
+ * 0.4.12  2003-04-16
+ *    - Fixed endpoint detection. The endpoints were numbered from 1 to n but
+ *      that assumption is not correct in all cases.
+ *
+ *
  * TODO
- *    - Remove the 2/3 endpoint limitation
  *    - Performance
  *    - Select/poll methods
  *    - More testing
- *    - Proper registry/assignment for LM9830 ioctl's
  *    - More general usage ioctl's
  *
  *
@@ -334,7 +380,7 @@
  *    - All the developers that are working on USB SANE backends or other
  *      applications to use USB scanners.
  *    - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie
- *      to be the new USB Scanner maintainer.
+ *      and Henning Meier-Geinitz to be the new USB Scanner maintainer.
  *
  *  Performance:
  *
@@ -343,6 +389,14 @@
  *      24 Bit Color ~ 70 secs - 3.6 Mbit/sec
  *       8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */
 
+/*
+ * For documentation, see Documentation/usb/scanner.txt.
+ * Website: http://www.meier-geinitz.de/kernel/
+ * Please contact the maintainer if your scanner is not detected by this
+ * driver automatically.
+ */
+
+
 /* 
  * Scanner definitions, macros, module info, 
  * debug/ioctl/data_dump enable, and other constants.
@@ -384,8 +438,6 @@
 
 	int err=0;
 
-	MOD_INC_USE_COUNT;
-
 	down(&scn_mutex);
 
 	scn_minor = USB_SCN_MINOR(inode);
@@ -394,8 +446,7 @@
 
 	if (!p_scn_table[scn_minor]) {
 		up(&scn_mutex);
-		MOD_DEC_USE_COUNT;
-		err("open_scanner(%d): Unable to access minor data", scn_minor);
+		dbg("open_scanner(%d): Unable to access minor data", scn_minor);
 		return -ENODEV;
 	}
 
@@ -403,7 +454,7 @@
 
 	dev = scn->scn_dev;
 
-	down(&(scn->sem));	/* Now protect the scn_usb_data structure */ 
+	down(&(scn->sem));	/* Now protect the scn_usb_data structure */
 
 	up(&scn_mutex); /* Now handled by the above */
 
@@ -420,7 +471,7 @@
 	}
 
 	if (scn->isopen) {
-		err("open_scanner(%d): Scanner device is already open", scn_minor);
+		dbg("open_scanner(%d): Scanner device is already open", scn_minor);
 		err = -EBUSY;
 		goto out_error;
 	}
@@ -436,9 +487,6 @@
 
 	up(&(scn->sem)); /* Wake up any possible contending processes */
 
-	if (err)
-		MOD_DEC_USE_COUNT;
-
 	return err;
 }
 
@@ -469,8 +517,6 @@
 	up(&scn_mutex);
 	up(&(scn->sem));
 
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
@@ -496,6 +542,12 @@
 
 	down(&(scn->sem));
 
+	if (!scn->bulk_out_ep) {
+		/* This scanner does not have a bulk-out endpoint */
+		up(&(scn->sem));
+		return -EINVAL;
+	}
+
 	scn_minor = scn->scn_minor;
 
 	obuf = scn->obuf;
@@ -636,7 +688,7 @@
 				goto data_recvd;
 			}
 		}
-		
+
 		if (result == -EPIPE) { /* No hope */
 			if(usb_clear_halt(dev, scn->bulk_in_ep)) {
 				err("read_scanner(%d): Failure to clear endpoint halt condition (%Zd).", scn_minor, ret);
@@ -684,81 +736,23 @@
 ioctl_scanner(struct inode *inode, struct file *file,
 	      unsigned int cmd, unsigned long arg)
 {
+	struct scn_usb_data *scn;
 	struct usb_device *dev;
+	int retval = -ENOTTY;
 
-	kdev_t scn_minor;
-
-	scn_minor = USB_SCN_MINOR(inode);
-
-	if (!p_scn_table[scn_minor]) {
-		err("ioctl_scanner(%d): invalid scn_minor", scn_minor);
-		return -ENODEV;
-	}
+	scn = file->private_data;
+	down(&(scn->sem));
 
-	dev = p_scn_table[scn_minor]->scn_dev;
+	dev = scn->scn_dev;
 
 	switch (cmd)
 	{
 	case SCANNER_IOCTL_VENDOR :
-		return (put_user(dev->descriptor.idVendor, (unsigned int *) arg));
+		retval = (put_user(dev->descriptor.idVendor, (unsigned int *) arg));
+		break;
 	case SCANNER_IOCTL_PRODUCT :
-		return (put_user(dev->descriptor.idProduct, (unsigned int *) arg));
-#ifdef PV8630
-	case PV8630_IOCTL_INREQUEST :
-	{
-		int result;
-
-		struct {
-			__u8  data;
-			__u8  request;
-			__u16 value;
-			__u16 index;
-		} args;
-
-		if (copy_from_user(&args, (void *)arg, sizeof(args)))
-			return -EFAULT;
-
-		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-					 args.request, USB_TYPE_VENDOR|
-					 USB_RECIP_DEVICE|USB_DIR_IN,
-					 args.value, args.index, &args.data,
-					 1, HZ*5);
-
-		dbg("ioctl_scanner(%d): inreq: args.data:%x args.value:%x args.index:%x args.request:%x\n", scn_minor, args.data, args.value, args.index, args.request);
-
-		if (copy_to_user((void *)arg, &args, sizeof(args)))
-			return -EFAULT;
-
-		dbg("ioctl_scanner(%d): inreq: result:%d\n", scn_minor, result);
-
-		return result;
-	}
-	case PV8630_IOCTL_OUTREQUEST :
-	{
-		int result;
-
-		struct {
-			__u8  request;
-			__u16 value;
-			__u16 index;
-		} args;
-
-		if (copy_from_user(&args, (void *)arg, sizeof(args)))
-			return -EFAULT;
-
-		dbg("ioctl_scanner(%d): outreq: args.value:%x args.index:%x args.request:%x\n", scn_minor, args.value, args.index, args.request);
-
-		result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-					 args.request, USB_TYPE_VENDOR|
-					 USB_RECIP_DEVICE|USB_DIR_OUT,
-					 args.value, args.index, NULL,
-					 0, HZ*5);
-
-		dbg("ioctl_scanner(%d): outreq: result:%d\n", scn_minor, result);
-
-		return result;
-	}
-#endif /* PV8630 */
+		retval = (put_user(dev->descriptor.idProduct, (unsigned int *) arg));
+		break;
  	case SCANNER_IOCTL_CTRLMSG:
  	{
  		struct ctrlmsg_ioctl {
@@ -767,19 +761,26 @@
  		} cmsg;
  		int pipe, nb, ret;
  		unsigned char buf[64];
- 
- 		if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg)))
- 			return -EFAULT;
+		retval = 0;
+
+ 		if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg))) {
+ 			retval = -EFAULT;
+			break;
+		}
 
  		nb = cmsg.req.wLength;
 
- 		if (nb > sizeof(buf))
- 			return -EINVAL;
+ 		if (nb > sizeof(buf)) {
+ 			retval = -EINVAL;
+			break;
+		}
 
  		if ((cmsg.req.bRequestType & 0x80) == 0) {
  			pipe = usb_sndctrlpipe(dev, 0);
- 			if (nb > 0 && copy_from_user(buf, cmsg.data, nb))
- 				return -EFAULT;
+ 			if (nb > 0 && copy_from_user(buf, cmsg.data, nb)) {
+ 				retval = -EFAULT;
+				break;
+			}
  		} else {
  			pipe = usb_rcvctrlpipe(dev, 0);
 		}
@@ -791,23 +792,26 @@
  				      buf, nb, HZ);
 
  		if (ret < 0) {
- 			err("ioctl_scanner(%d): control_msg returned %d\n", scn_minor, ret);
- 			return -EIO;
+ 			err("ioctl_scanner: control_msg returned %d\n", ret);
+ 			retval = -EIO;
+			break;
  		}
 
  		if (nb > 0 && (cmsg.req.bRequestType & 0x80) && copy_to_user(cmsg.data, buf, nb))
- 			return -EFAULT;
+ 			retval = -EFAULT;
 
- 		return 0;
+ 		break;
  	}
 	default:
-		return -ENOTTY;
+		break;
 	}
-	return 0;
+	up(&(scn->sem));
+	return retval;
 }
 
 static struct
 file_operations usb_scanner_fops = {
+	owner:		THIS_MODULE,
 	read:		read_scanner,
 	write:		write_scanner,
 	ioctl:		ioctl_scanner,
@@ -832,10 +836,6 @@
 	char have_bulk_in, have_bulk_out, have_intr;
 	char name[10];
 
-	if (vendor != -1 && product != -1) {
-		info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product);
-	}
-
 	dbg("probe_scanner: USB dev address:%p", dev);
 	dbg("probe_scanner: ifnum:%u", ifnum);
 
@@ -886,48 +886,58 @@
 		return NULL;
 	}
 
-	if (dev->config[0].bNumInterfaces != 1) {
-		info("probe_scanner: Only one device interface is supported.");
+	interface = dev->config[0].interface[ifnum].altsetting;
+
+	if (interface[0].bInterfaceClass != USB_CLASS_VENDOR_SPEC &&
+	    interface[0].bInterfaceClass != USB_CLASS_PER_INTERFACE &&
+	    interface[0].bInterfaceClass != SCN_CLASS_SCANJET) {
+		dbg("probe_scanner: This interface doesn't look like a scanner (class=0x%x).", interface[0].bInterfaceClass);
 		return NULL;
 	}
 
-	interface = dev->config[0].interface[ifnum].altsetting;
-	endpoint = interface[ifnum].endpoint;
+	endpoint = interface[0].endpoint;
 
 /*
- * Start checking for two bulk endpoints OR two bulk endpoints *and* one
- * interrupt endpoint. If we have an interrupt endpoint go ahead and
+ * Start checking for bulk and interrupt endpoints. We are only using the first
+ * one of each type of endpoint. If we have an interrupt endpoint go ahead and
  * setup the handler. FIXME: This is a future enhancement...
  */
 
 	dbg("probe_scanner: Number of Endpoints:%d", (int) interface->bNumEndpoints);
 
-	if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) {
-		info("probe_scanner: Only two or three endpoints supported.");
-		return NULL;
-	}
-
 	ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0;
 
 	while (ep_cnt < interface->bNumEndpoints) {
 
-		if (!have_bulk_in && IS_EP_BULK_IN(endpoint[ep_cnt])) {
+		if (IS_EP_BULK_IN(endpoint[ep_cnt])) {
 			ep_cnt++;
-			have_bulk_in = ep_cnt;
+			if (have_bulk_in) {
+				info ("probe_scanner: ignoring additional bulk_in_ep:%d", ep_cnt);
+				continue;
+			}
+			have_bulk_in = endpoint[ep_cnt - 1].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 			dbg("probe_scanner: bulk_in_ep:%d", have_bulk_in);
 			continue;
 		}
 
-		if (!have_bulk_out && IS_EP_BULK_OUT(endpoint[ep_cnt])) {
+		if (IS_EP_BULK_OUT(endpoint[ep_cnt])) {
 			ep_cnt++;
-			have_bulk_out = ep_cnt;
+			if (have_bulk_out) {
+				info ("probe_scanner: ignoring additional bulk_out_ep:%d", ep_cnt);
+				continue;
+			}
+			have_bulk_out = endpoint[ep_cnt - 1].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 			dbg("probe_scanner: bulk_out_ep:%d", have_bulk_out);
 			continue;
 		}
 
-		if (!have_intr && IS_EP_INTR(endpoint[ep_cnt])) {
+		if (IS_EP_INTR(endpoint[ep_cnt])) {
 			ep_cnt++;
-			have_intr = ep_cnt;
+			if (have_intr) {
+				info ("probe_scanner: ignoring additional intr_ep:%d", ep_cnt);
+				continue;
+			}
+			have_intr = endpoint[ep_cnt - 1].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 			dbg("probe_scanner: intr_ep:%d", have_intr);
 			continue;
 		}
@@ -940,22 +950,8 @@
  * Perform a quick check to make sure that everything worked as it
  * should have.
  */
-
-	switch(interface->bNumEndpoints) {
-	case 2:
-		if (!have_bulk_in || !have_bulk_out) {
-			info("probe_scanner: Two bulk endpoints required.");
-			return NULL;
-		}
-		break;
-	case 3:
-		if (!have_bulk_in || !have_bulk_out || !have_intr) {
-			info("probe_scanner: Two bulk endpoints and one interrupt endpoint required.");
-			return NULL;
-		}
-		break;
-	default:
-		info("probe_scanner: Endpoint determination failed --  consult Documentation/usb/scanner.txt");
+	if (!have_bulk_in) {
+		err("probe_scanner: One bulk-in endpoint required.");
 		return NULL;
 	}
 
@@ -1036,7 +1032,6 @@
 		break;
 	case 0x055f:		/* Mustek */
 	case 0x0400:		/* Another Mustek */
-	case 0x0ff5:		/* And yet another Mustek */
 		scn->rd_nak_timeout = HZ * 1;
 	default:
 		scn->rd_nak_timeout = RD_NAK_TIMEOUT;
@@ -1067,6 +1062,8 @@
 	if (scn->devfs == NULL)
 		dbg("scanner%d: device node registration failed", scn_minor);
 
+	info ("USB scanner device (0x%04x/0x%04x) now attached to %s",
+	      dev->descriptor.idVendor, dev->descriptor.idProduct, name);
 	p_scn_table[scn_minor] = scn;
 
 	up(&scn_mutex);
@@ -1125,6 +1122,8 @@
                 return -1;
 
 	info(DRIVER_VERSION ":" DRIVER_DESC);
+	if (vendor != -1 && product != -1)
+		info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product);
 	return 0;
 }
 
--- linux-2.4.20-pfeifer-r1_pre8/drivers/usb/scanner.h	2003-05-03 09:41:24.000000000 -0500
+++ linux-2.4.20-pfeifer-r1_pre9/drivers/usb/scanner.h	2003-04-16 03:09:10.000000000 -0500
@@ -1,9 +1,10 @@
 /*
- * Driver for USB Scanners (linux-2.4.18)
+ * Driver for USB Scanners (linux-2.4)
  *
  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
+ * Previously maintained by Brian Beattie
  *
- * Brian Beattie <beattie@beattie-home.net>
+ * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -21,6 +22,13 @@
  *
  */ 
 
+/*
+ * For documentation, see Documentation/usb/scanner.txt.
+ * Website: http://www.meier-geinitz.de/kernel/
+ * Please contact the maintainer if your scanner is not detected by this
+ * driver automatically.
+ */
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -32,23 +40,18 @@
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/usb_scanner_ioctl.h>
 
 // #define DEBUG
 
-/* Enable this to support the older ioctl interfaces scanners that
- * a PV8630 Scanner-On-Chip.  The prefered method is the
- * SCANNER_IOCTL_CTRLMSG ioctl.
- */
-// #define PV8630 
-
-#define DRIVER_VERSION "0.4.6"
+#define DRIVER_VERSION "0.4.12"
 #define DRIVER_DESC "USB Scanner Driver"
 
 #include <linux/usb.h>
 
 static __s32 vendor=-1, product=-1, read_timeout=0;
 
-MODULE_AUTHOR("Brian Beattie, beattie@beattie-home.net");
+MODULE_AUTHOR("Henning Meier-Geinitz, henning@meier-geinitz.de");
 MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
@@ -67,65 +70,112 @@
 // #define WR_DATA_DUMP /* DEBUG does not have to be defined. */
 
 static struct usb_device_id scanner_device_ids [] = {
-	/* Acer */
-	{ USB_DEVICE(0x04a5, 0x2060) },	/* Prisa Acerscan 620U & 640U (!)*/
-	{ USB_DEVICE(0x04a5, 0x2040) },	/* Prisa AcerScan 620U (!) */
-	{ USB_DEVICE(0x04a5, 0x20c0) },  /* Prisa AcerScan 1240UT */
-	{ USB_DEVICE(0x04a5, 0x2022) },	/* Vuego Scan Brisa 340U */
+	/* Acer (now Benq) */
 	{ USB_DEVICE(0x04a5, 0x1a20) },	/* Unknown - Oliver Schwartz */
-	{ USB_DEVICE(0x04a5, 0x1a2a) },	/* Unknown - Oliver Schwartz */
-	{ USB_DEVICE(0x04a5, 0x207e) },	/* Prisa 640BU */
+	{ USB_DEVICE(0x04a5, 0x1a2a) },	/* Another 620U */
+	{ USB_DEVICE(0x04a5, 0x2022) },	/* 340U */
+	{ USB_DEVICE(0x04a5, 0x2040) },	/* 620U (!) */
+	{ USB_DEVICE(0x04a5, 0x2060) },	/* 620U & 640U (!)*/
+	{ USB_DEVICE(0x04a5, 0x207e) },	/* 640BU */
+	{ USB_DEVICE(0x04a5, 0x20b0) },	/* Benq 4300 */
 	{ USB_DEVICE(0x04a5, 0x20be) },	/* Unknown - Oliver Schwartz */
-	{ USB_DEVICE(0x04a5, 0x20c0) },	/* Unknown - Oliver Schwartz */
+	{ USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */
 	{ USB_DEVICE(0x04a5, 0x20de) },	/* S2W 3300U */
-	{ USB_DEVICE(0x04a5, 0x20b0) },	/* Unknown - Oliver Schwartz */
-	{ USB_DEVICE(0x04a5, 0x20fe) },	/* Unknown - Oliver Schwartz */
+	{ USB_DEVICE(0x04a5, 0x20fc) }, /* Benq 5000 */
+	{ USB_DEVICE(0x04a5, 0x20fe) },	/* Benq 5300 */
 	/* Agfa */
 	{ USB_DEVICE(0x06bd, 0x0001) },	/* SnapScan 1212U */
 	{ USB_DEVICE(0x06bd, 0x0002) },	/* SnapScan 1236U */
-	{ USB_DEVICE(0x06bd, 0x2061) },	/* Another SnapScan 1212U (?)*/
 	{ USB_DEVICE(0x06bd, 0x0100) },	/* SnapScan Touch */
+	{ USB_DEVICE(0x06bd, 0x2061) },	/* Another SnapScan 1212U (?)*/
+	{ USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
+	{ USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/
 	{ USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */
+	{ USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/
 	{ USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */
 	{ USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */
-	{ USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
+	{ USB_DEVICE(0x06bd, 0x20fd) }, /* SnapScan e52*/
+	{ USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/
+	/* Artec */
+	{ USB_DEVICE(0x05d8, 0x4001) },	/* Ultima 2000 */
+	{ USB_DEVICE(0x05d8, 0x4002) }, /* Ultima 2000 (GT6801 based) */
+	{ USB_DEVICE(0x05d8, 0x4003) }, /* E+ 48U */
+	{ USB_DEVICE(0x05d8, 0x4004) }, /* E+ Pro */
+	/* Avision */
+	{ USB_DEVICE(0x0638, 0x0a10) },	/* iVina FB1600 (=Umax Astra 4500) */
+	/* Benq: see Acer */
+	/* Brother */
+	{ USB_DEVICE(0x04f9, 0x010f) },	/* MFC 5100C */
+	{ USB_DEVICE(0x04f9, 0x0111) },	/* MFC 6800 */
 	/* Canon */
+	{ USB_DEVICE(0x04a9, 0x2201) }, /* CanoScan FB320U */
 	{ USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */
 	{ USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */
+	{ USB_DEVICE(0x04a9, 0x2205) }, /* CanoScan FB1210U */
 	{ USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */
 	{ USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */
 	{ USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ 
-	{ USB_DEVICE(0x04a9, 0x220b) }, /* D646U */
+	{ USB_DEVICE(0x04a9, 0x220b) }, /* CanoScan D646U */
+	{ USB_DEVICE(0x04a9, 0x220c) },	/* CanoScan D1250U2 */
+	{ USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */
+	{ USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */
+	{ USB_DEVICE(0x04a9, 0x2213) },	/* LIDE 50 */
+	{ USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */
 	/* Colorado -- See Primax/Colorado below */
+	/* Compaq */
+	{ USB_DEVICE(0x049f, 0x001a) },	/* S4 100 */
+	{ USB_DEVICE(0x049f, 0x0021) },	/* S200 */
 	/* Epson -- See Seiko/Epson below */
+	/* Fujitsu */
+	{ USB_DEVICE(0x04c5, 0x1041) }, /* fi-4220c USB/SCSI info:mza@mu-tec.de */
+	{ USB_DEVICE(0x04c5, 0x1042) }, /* fi-4120c USB/SCSI info:mza@mu-tec.de */
+	{ USB_DEVICE(0x04c5, 0x1029) }, /* fi-4010c USB AVision info:mza@mu-tec.de */
 	/* Genius */
-	{ USB_DEVICE(0x0458, 0x2001) },	/* ColorPage-Vivid Pro */
+	{ USB_DEVICE(0x0458, 0x2001) },	/* ColorPage Vivid Pro */
 	{ USB_DEVICE(0x0458, 0x2007) },	/* ColorPage HR6 V2 */
-	{ USB_DEVICE(0x0458, 0x2008) },	/* Unknown */
-	{ USB_DEVICE(0x0458, 0x2009) },	/* Unknown */
-	{ USB_DEVICE(0x0458, 0x2013) },	/* Unknown */
-	{ USB_DEVICE(0x0458, 0x2015) },	/* Unknown  */
-	{ USB_DEVICE(0x0458, 0x2016) },	/* Unknown  */
+	{ USB_DEVICE(0x0458, 0x2008) }, /* ColorPage HR6 V2 */
+	{ USB_DEVICE(0x0458, 0x2009) }, /* ColorPage HR6A */
+	{ USB_DEVICE(0x0458, 0x2011) }, /* ColorPage Vivid3x */
+	{ USB_DEVICE(0x0458, 0x2013) }, /* ColorPage HR7 */
+	{ USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */
+	{ USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */
 	/* Hewlett Packard */
-	{ USB_DEVICE(0x03f0, 0x0205) },	/* 3300C */
-	{ USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */
-	{ USB_DEVICE(0x03f0, 0x0101) },	/* 4100C */
-	{ USB_DEVICE(0x03f0, 0x0105) },	/* 4200C */
-	{ USB_DEVICE(0x03f0, 0x0305) }, /* 4300C */
+	{ USB_DEVICE(0x03f0, 0x0101) },	/* ScanJet 4100C */
 	{ USB_DEVICE(0x03f0, 0x0102) },	/* PhotoSmart S20 */
-	{ USB_DEVICE(0x03f0, 0x0705) }, /* 4400C */
-	{ USB_DEVICE(0x03f0, 0x0401) },	/* 5200C */
-	//	{ USB_DEVICE(0x03f0, 0x0701) },	/* 5300C - NOT SUPPORTED - see http://www.neatech.nl/oss/HP5300C/ */
-	{ USB_DEVICE(0x03f0, 0x0201) },	/* 6200C */
-	{ USB_DEVICE(0x03f0, 0x0601) },	/* 6300C */
-	{ USB_DEVICE(0x03f0, 0x605) },	/* 2200C */
+	{ USB_DEVICE(0x03f0, 0x0105) },	/* ScanJet 4200C */
+	{ USB_DEVICE(0x03f0, 0x0201) },	/* ScanJet 6200C */
+	{ USB_DEVICE(0x03f0, 0x0205) },	/* ScanJet 3300C */
+	{ USB_DEVICE(0x03f0, 0x0305) }, /* ScanJet 4300C */
+	{ USB_DEVICE(0x03f0, 0x0401) },	/* ScanJet 5200C */
+	{ USB_DEVICE(0x03f0, 0x0405) }, /* ScanJet 3400C */
+	{ USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */
+	{ USB_DEVICE(0x03f0, 0x0601) },	/* ScanJet 6300C */
+	{ USB_DEVICE(0x03f0, 0x0605) },	/* ScanJet 2200C */
+	//	{ USB_DEVICE(0x03f0, 0x0701) },	/* ScanJet 5300C - NOT SUPPORTED - use hpusbscsi driver */
+	{ USB_DEVICE(0x03f0, 0x0705) }, /* ScanJet 4400C */
+	//	{ USB_DEVICE(0x03f0, 0x0801) },	/* ScanJet 7400C - NOT SUPPORTED - use hpusbscsi driver */
+	{ USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */
+	{ USB_DEVICE(0x03F0, 0x1005) },	/* ScanJet 5400C */
+	{ USB_DEVICE(0x03F0, 0x1105) },	/* ScanJet 5470C */
+	{ USB_DEVICE(0x03f0, 0x1305) },	/* Scanjet 4570c */
+	{ USB_DEVICE(0x03f0, 0x2005) },	/* ScanJet 3570c */
+	{ USB_DEVICE(0x03f0, 0x2205) },	/* ScanJet 3500c */
 	/* iVina */
 	{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
-	/* Lifetec */
-	{ USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */
+	/* Lexmark */
+	{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
+	{ USB_DEVICE(0x043d, 0x003d) }, /* X83 */
+	/* LG Electronics */
+	{ USB_DEVICE(0x0461, 0x0364) },	/* Scanworks 600U (repackaged Primax?) */
+	/* Medion */
+	{ USB_DEVICE(0x0461, 0x0377) },	/* MD 5345 - repackaged Primax? */
 	/* Memorex */
 	{ USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */
-	/* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */
+	/* Microtek */
+	{ USB_DEVICE(0x05da, 0x30ce) },	/* ScanMaker 3800 */
+	{ USB_DEVICE(0x05da, 0x30cf) },	/* ScanMaker 4800 */
+	/* The following SCSI-over-USB Microtek devices are supported by the
+	   microtek driver: Enable SCSI and USB Microtek in kernel config */
 	//	{ USB_DEVICE(0x05da, 0x0099) },	/* ScanMaker X6 - X6U */
 	//	{ USB_DEVICE(0x05da, 0x0094) },	/* Phantom 336CX - C3 */
 	//	{ USB_DEVICE(0x05da, 0x00a0) },	/* Phantom 336CX - C3 #2 */
@@ -134,53 +184,74 @@
 	//	{ USB_DEVICE(0x05da, 0x80a3) },	/* ScanMaker V6USL #2 */
 	//	{ USB_DEVICE(0x05da, 0x80ac) },	/* ScanMaker V6UL - SpicyU */
 	/* Minolta */
-	//	{ USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */
+	{ USB_DEVICE(0x0686, 0x400d) }, /* Scan Dual III */
+	/* The following SCSI-over-USB Minolta devices are supported by the
+	   hpusbscsi driver: Enable SCSI and USB hpusbscsi in kernel config */
+	//	{ USB_DEVICE(0x0638, 0x026a) }, /* Minolta Dimage Scan Dual II */
+	//	{ USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */
 	/* Mustek */
-	{ USB_DEVICE(0x055f, 0x0001) },	/* 1200 CU */
-	{ USB_DEVICE(0x0400, 0x1000) },	/* BearPaw 1200 */
-	{ USB_DEVICE(0x055f, 0x0002) },	/* 600 CU */
-	{ USB_DEVICE(0x055f, 0x0873) }, /* 600 USB */
-	{ USB_DEVICE(0x055f, 0x0003) },	/* 1200 USB */
-	{ USB_DEVICE(0x055f, 0x0006) },	/* 1200 UB */
-	{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */
-	{ USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */
-	{ USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */
+	{ USB_DEVICE(0x0400, 0x1000) },	/* BearPaw 1200 (National Semiconductor LM9831) */
+	{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 (National Semiconductor LM9832) */
+	{ USB_DEVICE(0x055f, 0x0001) },	/* ScanExpress 1200 CU */
+	{ USB_DEVICE(0x055f, 0x0002) },	/* ScanExpress 600 CU */
+	{ USB_DEVICE(0x055f, 0x0003) },	/* ScanExpress 1200 USB */
+	{ USB_DEVICE(0x055f, 0x0006) },	/* ScanExpress 1200 UB */
+	{ USB_DEVICE(0x055f, 0x0007) },	/* ScanExpress 1200 USB Plus */
+	{ USB_DEVICE(0x055f, 0x0008) }, /* ScanExpress 1200 CU Plus */
+	{ USB_DEVICE(0x055f, 0x0010) }, /* BearPaw 1200F */
+	{ USB_DEVICE(0x055f, 0x0210) },	/* ScanExpress A3 USB */
 	{ USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */
-	{ USB_DEVICE(0x05d8, 0x4002) }, /* 1200 CU and 1200 UB Plus */
+	{ USB_DEVICE(0x055f, 0x0219) }, /* BearPaw 2400 TA Plus */
+	{ USB_DEVICE(0x055f, 0x021c) }, /* BearPaw 1200 CU Plus */
+	{ USB_DEVICE(0x055f, 0x021d) }, /* Bearpaw 2400 CU Plus */
+	{ USB_DEVICE(0x055f, 0x021e) }, /* BearPaw 1200 TA/CS */
+	{ USB_DEVICE(0x055f, 0x0400) }, /* BearPaw 2400 TA PRO */
+	{ USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */
+	{ USB_DEVICE(0x055f, 0x1000) }, /* BearPaw 4800 TA PRO */
+	//	{ USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus (see Artec) */
+	/* Nikon */
+	{ USB_DEVICE(0x04b0, 0x4000) }, /* Coolscan LS 40 ED */
 	/* Plustek */
-	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */
-	{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */
 	{ USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */
-	{ USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */
+	{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */
-	{ USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */
-	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */
+	{ USB_DEVICE(0x07b3, 0x0400) }, /* OpticPro 1248U */
+	{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U (another one) */
 	/* Primax/Colorado */
 	{ USB_DEVICE(0x0461, 0x0300) },	/* G2-300 #1 */
-	{ USB_DEVICE(0x0461, 0x0380) },	/* G2-600 #1 */
 	{ USB_DEVICE(0x0461, 0x0301) },	/* G2E-300 #1 */
-	{ USB_DEVICE(0x0461, 0x0381) },	/* ReadyScan 636i */
 	{ USB_DEVICE(0x0461, 0x0302) },	/* G2-300 #2 */
-	{ USB_DEVICE(0x0461, 0x0382) },	/* G2-600 #2 */
 	{ USB_DEVICE(0x0461, 0x0303) },	/* G2E-300 #2 */
-	{ USB_DEVICE(0x0461, 0x0383) },	/* G2E-600 */
 	{ USB_DEVICE(0x0461, 0x0340) },	/* Colorado USB 9600 */
-	// { USB_DEVICE(0x0461, 0x0360) },	/* Colorado USB 19200 - undetected endpoint */
 	{ USB_DEVICE(0x0461, 0x0341) },	/* Colorado 600u */
+	{ USB_DEVICE(0x0461, 0x0347) },	/* Primascan Colorado 2600u */
+	{ USB_DEVICE(0x0461, 0x0360) },	/* Colorado USB 19200 */
 	{ USB_DEVICE(0x0461, 0x0361) },	/* Colorado 1200u */
+	{ USB_DEVICE(0x0461, 0x0380) },	/* G2-600 #1 */
+	{ USB_DEVICE(0x0461, 0x0381) },	/* ReadyScan 636i */
+	{ USB_DEVICE(0x0461, 0x0382) },	/* G2-600 #2 */
+	{ USB_DEVICE(0x0461, 0x0383) },	/* G2E-600 */
+	/* Prolink */
+	{ USB_DEVICE(0x06dc, 0x0014) }, /* Winscan Pro 2448U */
 	/* Relisis */
 	// { USB_DEVICE(0x0475, 0x0103) },	/* Episode - undetected endpoint */
 	/* Seiko/Epson Corp. */
 	{ USB_DEVICE(0x04b8, 0x0101) },	/* Perfection 636U and 636Photo */
+	{ USB_DEVICE(0x04b8, 0x0102) }, /* GT-2200 */
 	{ USB_DEVICE(0x04b8, 0x0103) },	/* Perfection 610 */
 	{ USB_DEVICE(0x04b8, 0x0104) },	/* Perfection 1200U and 1200Photo*/
+	{ USB_DEVICE(0x04b8, 0x0105) }, /* StylusScan 2000 */
 	{ USB_DEVICE(0x04b8, 0x0106) },	/* Stylus Scan 2500 */
 	{ USB_DEVICE(0x04b8, 0x0107) },	/* Expression 1600 */
+	{ USB_DEVICE(0x04b8, 0x0109) }, /* Expression 1640XL */
 	{ USB_DEVICE(0x04b8, 0x010a) }, /* Perfection 1640SU and 1640SU Photo */
 	{ USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */
 	{ USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */
@@ -190,19 +261,33 @@
 	{ USB_DEVICE(0x04b8, 0x0112) }, /* Perfection 2450 - GT-9700 for the Japanese mkt */
 	{ USB_DEVICE(0x04b8, 0x0114) }, /* Perfection 660 */
 	{ USB_DEVICE(0x04b8, 0x011b) }, /* Perfection 2400 Photo */
+	{ USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */
+	{ USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */
 	{ USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */
+	{ USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */
+	{ USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */
+	/* SYSCAN */
+	{ USB_DEVICE(0x0a82, 0x4600) }, /* TravelScan 460/464 */
+	/* Trust */
+	{ USB_DEVICE(0x05cb, 0x1483) }, /* CombiScan 19200 */
+	{ USB_DEVICE(0x05d8, 0x4006) }, /* Easy Webscan 19200 (repackaged Artec?) */
 	/* Umax */
+	{ USB_DEVICE(0x05d8, 0x4009) },	/* Astraslim (actually Artec?) */
 	{ USB_DEVICE(0x1606, 0x0010) },	/* Astra 1220U */
 	{ USB_DEVICE(0x1606, 0x0030) },	/* Astra 2000U */
+	{ USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */
 	{ USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */
+	{ USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */  
 	{ USB_DEVICE(0x1606, 0x0230) },	/* Astra 2200U */
 	/* Visioneer */
-	{ USB_DEVICE(0x04a7, 0x0221) },	/* OneTouch 5300 USB */
 	{ USB_DEVICE(0x04a7, 0x0211) },	/* OneTouch 7600 USB */
+	{ USB_DEVICE(0x04a7, 0x0221) },	/* OneTouch 5300 USB */
 	{ USB_DEVICE(0x04a7, 0x0231) },	/* 6100 USB */
 	{ USB_DEVICE(0x04a7, 0x0311) },	/* 6200 EPP/USB */
 	{ USB_DEVICE(0x04a7, 0x0321) },	/* OneTouch 8100 EPP/USB */
 	{ USB_DEVICE(0x04a7, 0x0331) }, /* OneTouch 8600 EPP/USB */
+	{ USB_DEVICE(0x0461, 0x0345) }, /* 6200 (actually Primax?) */
+	{ USB_DEVICE(0x0461, 0x0371) }, /* Onetouch 8920 USB (actually Primax?) */
 	{ }				/* Terminating entry */
 };
 
@@ -229,19 +314,9 @@
 #define RD_EXPIRE 12		/* Number of attempts to wait X seconds */
 
 
-/* FIXME: These are NOT registered ioctls()'s */
-#ifdef PV8630
-#define PV8630_IOCTL_INREQUEST 69
-#define PV8630_IOCTL_OUTREQUEST 70
-#endif /* PV8630 */
-
-
-/* read vendor and product IDs from the scanner */
-#define SCANNER_IOCTL_VENDOR _IOR('U', 0x20, int)
-#define SCANNER_IOCTL_PRODUCT _IOR('U', 0x21, int)
-/* send/recv a control message to the scanner */
-#define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, struct usb_ctrlrequest )
-
+/* USB bInterfaceClass used by Hewlett-Packard ScanJet 3300c and Genius HR6
+   USB - Vivid III */
+#define SCN_CLASS_SCANJET 16
 
 #define SCN_MAX_MNR 16		/* We're allocated 16 minors */
 #define SCN_BASE_MNR 48		/* USB Scanners start at minor 48 */
