Hi,

Here's a patch against 2.4.13-pre5 that updates the USB scanner driver.
The patch is by David Nelson.

thanks,

greg k-h
(temporary USB maintainer)



diff --minimal -Nru a/Documentation/usb/scanner.txt b/Documentation/usb/scanner.txt
--- a/Documentation/usb/scanner.txt     Fri Oct 19 16:11:09 2001
+++ b/Documentation/usb/scanner.txt     Fri Oct 19 16:11:09 2001
@@ -1,9 +1,11 @@
-Copyright (C) 1999, 2000 David E. Nelson
+Copyright (C) 1999, 2000 David E. Nelson <[EMAIL PROTECTED]>
 
 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
@@ -35,11 +37,9 @@
 (Compaq and others) hardware port should work.  At the time of this
 writing, there are two UHCI drivers and one OHCI.
 
-A Linux development kernel (2.3.x) 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.
-
-A Linux kernel with USB Scanner support enabled.
+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.
@@ -75,15 +75,15 @@
 YMMV.
 
 Beginning with version 0.4 of the driver, up to 16 scanners can be
-connected/used simultaneously.  If you intend to use more than
-one scanner at a time:
+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/usb/scanner15 180 63`
+       `mknod /dev/usbscanner15 180 63`
 
 
 If you foresee using only one scanner it is best to:
@@ -106,6 +106,32 @@
     modprobe usb-uhci
     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
+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
+
+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.  
 
 There is a small test program (hp_scan.c -- appended below) that can
@@ -121,15 +147,34 @@
 
 MESSAGES
 
-On occasions the message 'usb_control/bulk_msg: timeout' or something
-similar will appear in '/var/adm/messages' or 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 considered to be normal.  If you see
-a message of the type 'excessive NAK's received' then this should
-be considered abnormal and generally indicates that the USB system is
-unable to communicate with the scanner for some particular reason.
+usb_control/bulk_msg: timeout -- On occasions this message will appear
+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
+considered to be normal.  
+
+excessive NAK's received -- This message should be considered abnormal
+and generally indicates that the USB system is unable to communicate
+with the scanner for some particular reason.
+
+probe_scanner: Undetected endpoint -- The USB Scanner driver is fairly
+general when it comes to communicating to scanners.  Unfortunately,
+some vendors have designed their scanners in one way or another that
+this driver doesn't account for.
+
+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'.
+
+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
 
diff --minimal -Nru a/drivers/usb/scanner.c b/drivers/usb/scanner.c
--- a/drivers/usb/scanner.c     Fri Oct 19 16:11:09 2001
+++ b/drivers/usb/scanner.c     Fri Oct 19 16:11:09 2001
@@ -1,9 +1,9 @@
 /* -*- linux-c -*- */
 
 /* 
- * Driver for USB Scanners (linux-2.4.0)
+ * Driver for USB Scanners (linux-2.4.12)
  *
- * Copyright (C) 1999, 2000 David E. Nelson
+ * Copyright (C) 1999, 2000, 2001 David E. Nelson
  *
  * Portions may be copyright Brad Keryan and Michael Gee.
  *
@@ -226,13 +226,59 @@
  *      read_timeout.  Thanks to Mark W. Webb <[EMAIL PROTECTED]> for
  *      reporting this bug.
  *    - Added Epson Perfection 1640SU and 1640SU Photo.  Thanks to
- *      Jean-Luc <[EMAIL PROTECTED]>.
- *
- * 0.4.6 08/16/2001 Yves Duret <[EMAIL PROTECTED]>
- *    - added devfs support (from printer.c)
+ *      Jean-Luc <[EMAIL PROTECTED]> and Manuel
+ *      Pelayo <[EMAIL PROTECTED]>. Reported to work fine by Manuel.
  *
- *  TODO
+ * 0.4.6  9/27/2001
+ *    - Added IOCTL's to report back scanner USB ID's.  Thanks to
+ *      Karl Heinz <[EMAIL PROTECTED]>
+ *    - Added Umax Astra 2100U ID's.  Thanks to Ron
+ *      Wellsted <[EMAIL PROTECTED]>.
+ *      and Manuel Pelayo <[EMAIL PROTECTED]>.
+ *    - Added HP 3400 ID's. Thanks to Harald Hannelius <[EMAIL PROTECTED]>
+ *      and Bertrik Sikken <[EMAIL PROTECTED]>.  Reported to work at
+ *      htpp://home.zonnet.nl/bertrik/hp3300c/hp3300c.htm.
+ *    - Added Minolta Dimage Scan Dual II ID's.  Thanks to Jose Paulo
+ *      Moitinho de Almeida <[EMAIL PROTECTED]>
+ *    - Confirmed addition for SnapScan E20.  Thanks to Steffen H�bner
+ *      <[EMAIL PROTECTED]>.
+ *    - Added Lifetec LT9385 ID's.  Thanks to Van Bruwaene Kris
+ *      <[EMAIL PROTECTED]>
+ *    - Added Agfa SnapScan e26 ID's.  Reported to work with SANE
+ *      1.0.5.  Thanks to Falk Sauer <[EMAIL PROTECTED]>.
+ *    - Added HP 4300 ID's.  Thanks to Stefan Schlosser
+ *      <[EMAIL PROTECTED]>.
+ *    - Added Relisis Episode ID's.  Thanks to Manfred
+ *      Morgner <[EMAIL PROTECTED]>.
+ *    - Added many Acer ID's. Thanks to Oliver
+ *      Schwartz <[EMAIL PROTECTED]>.
+ *    - Added Snapscan e40 ID's.  Thanks to Oliver
+ *      Schwartz <[EMAIL PROTECTED]>.
+ *    - Thanks to Oliver Neukum <[EMAIL PROTECTED]>
+ *      for helping with races.
+ *    - Added Epson Perfection 1650 ID's. Thanks to Karl Heinz
+ *      Kremer <[EMAIL PROTECTED]>.
+ *    - Added Epson Perfection 2450 ID's (aka GT-9700 for the Japanese
+ *      market).  Thanks to Karl Heinz Kremer <[EMAIL PROTECTED]>.
+ *    - Added Mustek 600 USB ID's.  Thanks to Marcus
+ *      Alanen <[EMAIL PROTECTED]>.
+ *    - Added Acer ScanPrisa 1240UT ID's.  Thanks to Morgan
+ *      Collins <[EMAIL PROTECTED]>.
+ *    - Incorporated devfs patches!! Thanks to Tom Rini
+ *      <[EMAIL PROTECTED]>, Pavel Roskin <[EMAIL PROTECTED]>,
+ *      Greg KH <[EMAIL PROTECTED]>, Yves Duret <[EMAIL PROTECTED]>,
+ *      Flavio Stanchina <[EMAIL PROTECTED]>.
+ *    - Removed Minolta ScanImage II.  This scanner uses USB SCSI.  Thanks
+ *      to Oliver Neukum <[EMAIL PROTECTED]> for pointing
+ *      this out.
+ *    - Added additional SMP locking.  Thanks to David Brownell and 
+ *      Oliver Neukum for their help.
+ *    - Added version reporting - reports for both module load and modinfo
+ *    - Started path to hopefully straighten/clean out ioctl()'s.
+ *    - Users are now notified to consult the Documentation/usb/scanner.txt
+ *      for common error messages rather than the maintainer.
  *
+ * TODO
  *    - Performance
  *    - Select/poll methods
  *    - More testing
@@ -266,7 +312,6 @@
  */ 
 #include "scanner.h"
 
-
 static void
 irq_scanner(struct urb *urb)
 {
@@ -276,19 +321,23 @@
  * all I want to do with it -- or somebody else for that matter.
  */
 
-       struct scn_usb_data *scn = urb->context;
-       unsigned char *data = &scn->button;
+       struct scn_usb_data *scn;
+       unsigned char *data;
+       scn = urb->context;
+       down(&(scn->sem));
+       data = &scn->button;
        data += 0;              /* Keep gcc from complaining about unused var */
 
        if (urb->status) {
+               up(&(scn->sem));
                return;
        }
 
        dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data);
+       up(&(scn->sem));
        return;
 }
 
-
 static int
 open_scanner(struct inode * inode, struct file * file)
 {
@@ -299,22 +348,28 @@
 
        int err=0;
 
-       lock_kernel();
+       MOD_INC_USE_COUNT;
+
+       down(&scn_mutex);
 
        scn_minor = USB_SCN_MINOR(inode);
 
        dbg("open_scanner: scn_minor:%d", scn_minor);
 
        if (!p_scn_table[scn_minor]) {
+               up(&scn_mutex);
                err("open_scanner(%d): Unable to access minor data", scn_minor);
-               err = -ENODEV;
-               goto out_error;
+               return -ENODEV;
        }
 
        scn = p_scn_table[scn_minor];
 
        dev = scn->scn_dev;
 
+       down(&(scn->sem));      /* Now protect the scn_usb_data structure */ 
+
+       up(&scn_mutex); /* Now handled by the above */
+
        if (!dev) {
                err("open_scanner(%d): Scanner device not present", scn_minor);
                err = -ENODEV;
@@ -337,13 +392,15 @@
 
        scn->isopen = 1;
 
-       file->private_data = scn; /* Used by the read and write metheds */
+       file->private_data = scn; /* Used by the read and write methods */
 
-       MOD_INC_USE_COUNT;
 
 out_error:
 
-       unlock_kernel();
+       up(&(scn->sem)); /* Wake up any possible contending processes */
+
+       if (err)
+               MOD_DEC_USE_COUNT;
 
        return err;
 }
@@ -364,12 +421,17 @@
                return -ENODEV;
        }
 
-       scn = p_scn_table[scn_minor];
+       down(&scn_mutex);
 
+       scn = p_scn_table[scn_minor];
+       down(&(scn->sem));
        scn->isopen = 0;
 
        file->private_data = NULL;
 
+       up(&scn_mutex);
+       up(&(scn->sem));
+
        MOD_DEC_USE_COUNT;
 
        return 0;
@@ -395,6 +457,8 @@
 
        scn = file->private_data;
 
+       down(&(scn->sem));
+
        scn_minor = scn->scn_minor;
 
        obuf = scn->obuf;
@@ -403,12 +467,10 @@
 
        file->f_dentry->d_inode->i_atime = CURRENT_TIME;
 
-       down(&(scn->gen_lock));
-
        while (count > 0) {
 
                if (signal_pending(current)) {
-                       ret = -EINTR;
+                       ret = -ERESTARTSYS;
                        break;
                }
 
@@ -427,7 +489,7 @@
                        ret = result;
                        break;
                } else if (result < 0) { /* We should not get any I/O errors */
-                       warn("write_scanner(%d): funky result: %d. Please notify the 
maintainer.", scn_minor, result);
+                       warn("write_scanner(%d): funky result: %d. Consult 
+Documentataion/usb/scanner.txt.", scn_minor, result);
                        ret = -EIO;
                        break;
                }
@@ -457,7 +519,7 @@
                        break;
                }
        }
-       up(&(scn->gen_lock));
+       up(&(scn->sem));
        mdelay(5);              /* This seems to help with SANE queries */
        return ret ? ret : bytes_written;
 }
@@ -483,6 +545,8 @@
 
        scn = file->private_data;
 
+       down(&(scn->sem));
+
        scn_minor = scn->scn_minor;
 
        ibuf = scn->ibuf;
@@ -496,11 +560,9 @@
                                                             atime of
                                                             the device
                                                             node */
-       down(&(scn->gen_lock));
-
        while (count > 0) {
                if (signal_pending(current)) {
-                       ret = -EINTR;
+                       ret = -ERESTARTSYS;
                        break;
                }
 
@@ -545,7 +607,7 @@
                        ret = result;
                        break;
                } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) {
-                       warn("read_scanner(%d): funky result:%d. Please notify the 
maintainer.", scn_minor, (int)result);
+                       warn("read_scanner(%d): funky result:%d. Consult 
+Documentation/usb/scanner.txt.", scn_minor, (int)result);
                        ret = -EIO;
                        break;
                }
@@ -577,20 +639,16 @@
                        break;
                }
        }
-       up(&(scn->gen_lock));
-
+       up(&(scn->sem));
        return ret ? ret : bytes_read;
 }
 
-#ifdef SCN_IOCTL
 static int
 ioctl_scanner(struct inode *inode, struct file *file,
              unsigned int cmd, unsigned long arg)
 {
        struct usb_device *dev;
 
-       int result;
-
        kdev_t scn_minor;
 
        scn_minor = USB_SCN_MINOR(inode);
@@ -604,12 +662,15 @@
 
        switch (cmd)
        {
-       case IOCTL_SCANNER_VENDOR :
+       case SCANNER_IOCTL_VENDOR :
                return (put_user(dev->descriptor.idVendor, (unsigned int *) arg));
-       case IOCTL_SCANNER_PRODUCT :
+       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;
@@ -637,6 +698,8 @@
        }
        case PV8630_IOCTL_OUTREQUEST :
        {
+               int result;
+
                struct {
                        __u8  request;
                        __u16 value;
@@ -658,20 +721,59 @@
 
                return result;
        }
+#endif /* PV8630 */
+       case SCANNER_IOCTL_CTRLMSG:
+       {
+               struct ctrlmsg_ioctl {
+                       devrequest      req;
+                       void            *data;
+               } cmsg;
+               int pipe, nb, ret;
+               unsigned char buf[64];
+ 
+               if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg)))
+                       return -EFAULT;
+
+               nb = le16_to_cpup(&cmsg.req.length);
+
+               if (nb > sizeof(buf))
+                       return -EINVAL;
+
+               if ((cmsg.req.requesttype & 0x80) == 0) {
+                       pipe = usb_sndctrlpipe(dev, 0);
+                       if (nb > 0 && copy_from_user(buf, cmsg.data, nb))
+                               return -EFAULT;
+               } else {
+                       pipe = usb_rcvctrlpipe(dev, 0);
+               }
+
+               ret = usb_control_msg(dev, pipe, cmsg.req.request,
+                                     cmsg.req.requesttype,
+                                     le16_to_cpup(&cmsg.req.value),
+                                     le16_to_cpup(&cmsg.req.index),
+                                     buf, nb, HZ);
+
+               if (ret < 0) {
+                       err("ioctl_scanner(%d): control_msg returned %d\n", scn_minor, 
+ret);
+                       return -EIO;
+               }
+
+               if (nb > 0 && (cmsg.req.requesttype & 0x80) && copy_to_user(cmsg.data, 
+buf, nb))
+                       return -EFAULT;
+
+               return 0;
+       }
        default:
                return -ENOTTY;
        }
        return 0;
 }
-#endif /* SCN_IOCTL */
 
 static struct
 file_operations usb_scanner_fops = {
        read:           read_scanner,
        write:          write_scanner,
-#ifdef SCN_IOCTL
        ioctl:          ioctl_scanner,
-#endif /* SCN_IOCTL */
        open:           open_scanner,
        release:        close_scanner,
 };
@@ -691,6 +793,7 @@
 
        char valid_device = 0;
        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);
@@ -791,7 +894,7 @@
                        dbg("probe_scanner: intr_ep:%d", have_intr);
                        continue;
                }
-               info("probe_scanner: Undetected endpoint. Notify the maintainer.");
+               info("probe_scanner: Undetected endpoint -- consult 
+Documentation/usb/scanner.txt.");
                return NULL;    /* Shouldn't ever get here unless we have something 
weird */
        }
 
@@ -815,7 +918,7 @@
                }
                break;
        default:
-               info("probe_scanner: Endpoint determination failed.  Notify the 
maintainer.");
+               info("probe_scanner: Endpoint determination failed --  consult 
+Documentation/usb/scanner.txt");
                return NULL;
        }
 
@@ -825,6 +928,8 @@
  * with it.  The problem with this is that we are counting on the fact
  * that the user will sequentially add device nodes for the scanner
  * devices.  */
+       
+       down(&scn_mutex);
 
        for (scn_minor = 0; scn_minor < SCN_MAX_MNR; scn_minor++) {
                if (!p_scn_table[scn_minor])
@@ -844,8 +949,10 @@
                return NULL;
        }
        memset (scn, 0, sizeof(struct scn_usb_data));
-       dbg ("probe_scanner(%d): Address of scn:%p", scn_minor, scn);
 
+       init_MUTEX(&(scn->sem)); /* Initializes to unlocked */
+
+       dbg ("probe_scanner(%d): Address of scn:%p", scn_minor, scn);
 
 /* Ok, if we detected an interrupt EP, setup a handler for it */
        if (have_intr) {
@@ -859,6 +966,7 @@
                if (usb_submit_urb(&scn->scn_irq)) {
                        err("probe_scanner(%d): Unable to allocate INT URB.", 
scn_minor);
                        kfree(scn);
+                       up(&scn_mutex);
                        return NULL;
                }
        }
@@ -868,6 +976,7 @@
        if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) {
                err("probe_scanner(%d): Not enough memory for the output buffer.", 
scn_minor);
                kfree(scn);
+               up(&scn_mutex);
                return NULL;
        }
        dbg("probe_scanner(%d): obuf address:%p", scn_minor, scn->obuf);
@@ -876,6 +985,7 @@
                err("probe_scanner(%d): Not enough memory for the input buffer.", 
scn_minor);
                kfree(scn->obuf);
                kfree(scn);
+               up(&scn_mutex);
                return NULL;
        }
        dbg("probe_scanner(%d): ibuf address:%p", scn_minor, scn->ibuf);
@@ -908,15 +1018,17 @@
        scn->scn_minor = scn_minor;
        scn->isopen = 0;
 
-       init_MUTEX(&(scn->gen_lock));
-
-       /* if we have devfs, create with perms=660 */
-       scn->devfs = devfs_register(usb_devfs_handle, "scanner",
-                                     DEVFS_FL_DEFAULT, USB_MAJOR,
-                                     SCN_BASE_MNR + scn_minor,
-                                     S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
-                                     S_IWGRP, &usb_scanner_fops, NULL);
+       sprintf(name, "scanner%d", scn->scn_minor);
+       
+       scn->devfs = devfs_register(usb_devfs_handle, name,
+                                   DEVFS_FL_DEFAULT, USB_MAJOR,
+                                   SCN_BASE_MNR + scn->scn_minor,
+                                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
+                                   S_IWGRP | S_IROTH | S_IWOTH, &usb_scanner_fops, 
+NULL);
+       if (scn->devfs == NULL)
+               dbg("scanner%d: device node registration failed", scn_minor);
 
+       up(&scn_mutex);
 
        return p_scn_table[scn_minor] = scn;
 }
@@ -926,6 +1038,9 @@
 {
        struct scn_usb_data *scn = (struct scn_usb_data *) ptr;
 
+       down (&scn_mutex);
+       down (&(scn->sem));
+
        if(scn->intr_ep) {
                dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor);
                usb_unlink_urb(&scn->scn_irq);
@@ -933,17 +1048,17 @@
         usb_driver_release_interface(&scanner_driver,
                 &scn->scn_dev->actconfig->interface[scn->ifnum]);
 
-       devfs_unregister (scn->devfs);
-
        kfree(scn->ibuf);
        kfree(scn->obuf);
 
        dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
+       devfs_unregister(scn->devfs);
        p_scn_table[scn->scn_minor] = NULL;
+       up (&(scn->sem));
        kfree (scn);
+       up (&scn_mutex);
 }
 
-
 static struct
 usb_driver scanner_driver = {
        name:           "usbscanner",
@@ -968,7 +1083,7 @@
         if (usb_register(&scanner_driver) < 0)
                 return -1;
 
-       info("USB Scanner support registered.");
+       info(DRIVER_VERSION ":" DRIVER_DESC);
        return 0;
 }
 
diff --minimal -Nru a/drivers/usb/scanner.h b/drivers/usb/scanner.h
--- a/drivers/usb/scanner.h     Fri Oct 19 16:11:09 2001
+++ b/drivers/usb/scanner.h     Fri Oct 19 16:11:09 2001
@@ -1,12 +1,10 @@
 /*
- * Driver for USB Scanners (linux-2.4.0)
+ * Driver for USB Scanners (linux-2.4.12)
  *
- * Copyright (C) 1999, 2000 David E. Nelson
+ * Copyright (C) 1999, 2000, 2001 David E. Nelson
  *
  * David E. Nelson ([EMAIL PROTECTED])
  *
- * 08/16/2001 added devfs support Yves Duret <[EMAIL PROTECTED]>
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
@@ -37,12 +35,21 @@
 
 // #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_DESC "USB Scanner Driver"
+
 #include <linux/usb.h>
 
 static __s32 vendor=-1, product=-1, read_timeout=0;
 
 MODULE_AUTHOR("David E. Nelson, [EMAIL PROTECTED], http://www.jump.net/~dnelson";);
-MODULE_DESCRIPTION("USB Scanner Driver");
+MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(vendor, "i");
@@ -55,10 +62,6 @@
 MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds");
 
 
-/* Enable to activate the ioctl interface.  This is mainly meant for */
-/* development purposes until an ioctl number is officially registered */
-#define SCN_IOCTL
-
 /* WARNING: These DATA_DUMP's can produce a lot of data. Caveat Emptor. */
 // #define RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */
 // #define WR_DATA_DUMP /* DEBUG does not have to be defined. */
@@ -69,26 +72,42 @@
        { USB_DEVICE(0x04a5, 0x2040) }, /* Prisa AcerScan 620U (!) */
        { USB_DEVICE(0x04a5, 0x20c0) },  /* Prisa AcerScan 1240UT */
        { USB_DEVICE(0x04a5, 0x2022) }, /* Vuego Scan Brisa 340U */
+       { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */
+       { USB_DEVICE(0x04a5, 0x1a2a) }, /* Unknown - Oliver Schwartz */
+       { USB_DEVICE(0x04a5, 0x207e) }, /* Prisa 640BU */
+       { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */
+       { USB_DEVICE(0x04a5, 0x20c0) }, /* Unknown - Oliver Schwartz */
+       { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */
+       { USB_DEVICE(0x04a5, 0x20b0) }, /* Unknown - Oliver Schwartz */
+       { USB_DEVICE(0x04a5, 0x20fe) }, /* Unknown - Oliver Schwartz */
        /* 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, 0x2091) }, /* SnapScan e20 */
+       { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */
+       { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
        /* Colorado -- See Primax/Colorado below */
        /* Epson -- See Seiko/Epson below */
        /* Genius */
        { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */
        /* 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, 0x0102) }, /* PhotoSmart S20 */
        { 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 */
        /* iVina */
-       { USB_DEVICE(0x0638, 0x0268) },     /* 1200U */
+       { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
+       /* Lifetec */
+       { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */
        /* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel 
config */
        //      { USB_DEVICE(0x05da, 0x0099) }, /* ScanMaker X6 - X6U */
        //      { USB_DEVICE(0x05da, 0x0094) }, /* Phantom 336CX - C3 */
@@ -97,10 +116,13 @@
        //      { USB_DEVICE(0x05da, 0x00a3) }, /* ScanMaker V6USL */
        //      { USB_DEVICE(0x05da, 0x80a3) }, /* ScanMaker V6USL #2 */
        //      { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */
+       /* Minolta */
+       //      { USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */
        /* 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 */
@@ -116,9 +138,11 @@
        { 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 */
+       // { USB_DEVICE(0x0461, 0x0360) },      /* Colorado USB 19200 - undetected 
+endpoint */
        { USB_DEVICE(0x0461, 0x0341) }, /* Colorado 600u */
        { USB_DEVICE(0x0461, 0x0361) }, /* Colorado 1200u */
+       /* Relisis */
+       // { USB_DEVICE(0x0475, 0x0103) },      /* Episode - undetected endpoint */
        /* Seiko/Epson Corp. */
        { USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */
        { USB_DEVICE(0x04b8, 0x0103) }, /* Perfection 610 */
@@ -129,9 +153,12 @@
        { USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */
        { USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */
        { USB_DEVICE(0x04b8, 0x010e) }, /* Expression 1680 */
+       { USB_DEVICE(0x04b8, 0x0110) }, /* Perfection 1650 */
+       { USB_DEVICE(0x04b8, 0x0112) }, /* Perfection 2450 - GT-9700 for the Japanese 
+mkt */
        /* Umax */
        { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */
        { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */
+       { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */
        { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */
        /* Visioneer */
        { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */
@@ -167,16 +194,24 @@
 
 
 /* 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, devrequest )
 
-/* read vendor and product IDs */
-#define IOCTL_SCANNER_VENDOR _IOR('u', 0xa0, int)
-#define IOCTL_SCANNER_PRODUCT _IOR('u', 0xa1, int)
 
 #define SCN_MAX_MNR 16         /* We're allocated 16 minors */
 #define SCN_BASE_MNR 48                /* USB Scanners start at minor 48 */
 
+static DECLARE_MUTEX (scn_mutex); /* Initializes to unlocked */
+
 struct scn_usb_data {
        struct usb_device *scn_dev;
        devfs_handle_t devfs;   /* devfs device */
@@ -189,12 +224,12 @@
        char *obuf, *ibuf;      /* transfer buffers */
        char bulk_in_ep, bulk_out_ep, intr_ep; /* Endpoint assignments */
        wait_queue_head_t rd_wait_q; /* read timeouts */
-       struct semaphore gen_lock; /* lock to prevent concurrent reads or writes */
+       struct semaphore sem; /* lock to prevent concurrent reads or writes */
        unsigned int rd_nak_timeout; /* Seconds to wait before read() timeout. */
 };
 
+extern devfs_handle_t usb_devfs_handle;
+
 static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, /* ... */};
 
 static struct usb_driver scanner_driver;
-
-extern devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to