ChangeSet 1.1500.8.21, 2004/02/04 17:06:57-08:00, greg@kroah.com [PATCH] USB: remove scanner driver files. drivers/usb/image/scanner.c | 1216 -------------------------------------------- drivers/usb/image/scanner.h | 387 -------------- 2 files changed, 1603 deletions(-) diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c --- a/drivers/usb/image/scanner.c Mon Feb 9 14:38:51 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1216 +0,0 @@ -/* -*- linux-c -*- */ - -/* - * Driver for USB Scanners (linux-2.6) - * - * 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. - * - * Previously maintained by Brian Beattie - * - * Current maintainer: Henning Meier-Geinitz - * - * 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 - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Originally based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). - * - * History - * - * 0.1 8/31/1999 - * - * Developed/tested using linux-2.3.15 with minor ohci.c changes to - * support short packets during bulk xfer mode. Some testing was - * done with ohci-hcd but the performance was low. Very limited - * testing was performed with uhci but I was unable to get it to - * work. Initial relase to the linux-usb development effort. - * - * - * 0.2 10/16/1999 - * - * - Device can't be opened unless a scanner is plugged into the USB. - * - Finally settled on a reasonable value for the I/O buffer's. - * - Cleaned up write_scanner() - * - Disabled read/write stats - * - A little more code cleanup - * - * - * 0.3 10/18/1999 - * - * - Device registration changed to reflect new device - * allocation/registration for linux-2.3.22+. - * - Adopted David Brownell's technique for - * assigning bulk endpoints. - * - Removed unnecessary #include's - * - Scanner model now reported via syslog INFO after being detected - * *and* configured. - * - Added user specified vendor:product USB ID's which can be passed - * as module parameters. - * - * - * 0.3.1 - * - * - Applied patches for linux-2.3.25. - * - Error number reporting changed to reflect negative return codes. - * - * - * 0.3.2 - * - * - Applied patches for linux-2.3.26 to scanner_init(). - * - Debug read/write stats now report values as signed decimal. - * - * - * 0.3.3 - * - * - Updated the bulk_msg() calls to usb usb_bulk_msg(). - * - Added a small delay in the write_scanner() method to aid in - * avoiding NULL data reads on HP scanners. We'll see how this works. - * - Return values from usb_bulk_msg() now ignore positive values for - * use with the ohci driver. - * - Added conditional debugging instead of commenting/uncommenting - * all over the place. - * - kfree()'d the pointer after using usb_string() as documented in - * linux-usb-api.txt. - * - Added usb_set_configuration(). It got lost in version 0.3 -- ack! - * - Added the HP 5200C USB Vendor/Product ID's. - * - * - * 0.3.4 1/23/2000 - * - * - Added Greg K-H's patch for better handling of - * Product/Vendor detection. - * - The driver now autoconfigures its endpoints including interrupt - * endpoints if one is detected. The concept was originally based - * upon David Brownell's method. - * - Added some Seiko/Epson ID's. Thanks to Karl Heinz - * Kremer . - * - Added some preliminary ioctl() calls for the PV8630 which is used - * by the HP4200. The ioctl()'s still have to be registered. Thanks - * to Adrian Perez Jorge . - * - Moved/migrated stuff to scanner.h - * - Removed the usb_set_configuration() since this is handled by - * the usb_new_device() routine in usb.c. - * - Added the HP 3300C. Thanks to Bruce Tenison. - * - Changed user specified vendor/product id so that root hub doesn't - * get falsely attached to. Thanks to Greg K-H. - * - Added some Mustek ID's. Thanks to Gernot Hoyler - * . - * - Modified the usb_string() reporting. See kfree() comment above. - * - Added Umax Astra 2000U. Thanks to Doug Alcorn . - * - Updated the printk()'s to use the info/warn/dbg macros. - * - Updated usb_bulk_msg() argument types to fix gcc warnings. - * - * - * 0.4 2/4/2000 - * - * - Removed usb_string() from probe_scanner since the core now does a - * good job of reporting what was connnected. - * - Finally, simultaneous multiple device attachment! - * - Fixed some potential memory freeing issues should memory allocation - * fail in probe_scanner(); - * - Some fixes to disconnect_scanner(). - * - Added interrupt endpoint support. - * - Added Agfa SnapScan Touch. Thanks to Jan Van den Bergh - * . - * - Added Umax 1220U ID's. Thanks to Maciek Klimkowski - * . - * - Fixed bug in write_scanner(). The buffer was not being properly - * updated for writes larger than OBUF_SIZE. Thanks to Henrik - * Johansson for identifying it. - * - Added Microtek X6 ID's. Thanks to Oliver Neukum - * . - * - * - * 0.4.1 2/15/2000 - * - * - Fixed 'count' bug in read_scanner(). Thanks to Henrik - * Johansson for identifying it. Amazing - * it has worked this long. - * - Fixed '>=' bug in both read/write_scanner methods. - * - Cleaned up both read/write_scanner() methods so that they are - * a little more readable. - * - Added a lot of Microtek ID's. Thanks to Adrian Perez Jorge. - * - Adopted the __initcall(). - * - Added #include to scanner.h for __initcall(). - * - Added one liner in irq_scanner() to keep gcc from complaining - * about an unused variable (data) if debugging was disabled - * in scanner.c. - * - Increased the timeout parameter in read_scanner() to 120 Secs. - * - * - * 0.4.2 3/23/2000 - * - * - Added Umax 1236U ID. Thanks to Philipp Baer . - * - Added Primax, ReadyScan, Visioneer, Colorado, and Genius ID's. - * Thanks to Adrian Perez Jorge . - * - Fixed error number reported for non-existant devices. Thanks to - * Spyridon Papadimitriou . - * - Added Acer Prisascan 620U ID's. Thanks to Joao . - * - Replaced __initcall() with module_init()/module_exit(). Updates - * from patch-2.3.48. - * - Replaced file_operations structure with new syntax. Updates - * from patch-2.3.49. - * - Changed #include "usb.h" to #include - * - Added #define SCN_IOCTL to exclude development areas - * since 2.4.x is about to be released. This mainly affects the - * ioctl() stuff. See scanner.h for more details. - * - Changed the return value for signal_pending() from -ERESTARTSYS to - * -EINTR. - * - * - * 0.4.3 4/30/2000 - * - * - Added Umax Astra 2200 ID. Thanks to Flynn Marquardt - * . - * - Added iVina 1200U ID. Thanks to Dyson Lin . - * - Added access time update for the device file courtesy of Paul - * Mackerras . This allows a user space daemon - * to turn the lamp off for a Umax 1220U scanner after a prescribed - * time. - * - Fixed HP S20 ID's. Thanks to Ruud Linders . - * - Added Acer ScanPrisa 620U ID. Thanks to Oliver - * Schwartz via sane-devel mail list. - * - Fixed bug in read_scanner for copy_to_user() function. The returned - * value should be 'partial' not 'this_read'. - * - Fixed bug in read_scanner. 'count' should be decremented - * by 'this_read' and not by 'partial'. This resulted in twice as many - * calls to read_scanner() for small amounts of data and possibly - * unexpected returns of '0'. Thanks to Karl Heinz - * Kremer and Alain Knaff - * for discovering this. - * - Integrated Randy Dunlap's patch for a - * scanner lookup/ident table. Thanks Randy. - * - Documentation updates. - * - Added wait queues to read_scanner(). - * - * - * 0.4.3.1 - * - * - Fixed HP S20 ID's...again..sigh. Thanks to Ruud - * Linders . - * - * 0.4.4 - * - Added addtional Mustek ID's (BearPaw 1200, 600 CU, 1200 USB, - * and 1200 UB. Thanks to Henning Meier-Geinitz . - * - Added the Vuego Scan Brisa 340U ID's. Apparently this scanner is - * marketed by Acer Peripherals as a cheap 300 dpi model. Thanks to - * David Gundersen . - * - Added the Epson Expression1600 ID's. Thanks to Karl Heinz - * Kremer . - * - * 0.4.5 2/28/2001 - * - Added Mustek ID's (BearPaw 2400, 1200 CU Plus, BearPaw 1200F). - * Thanks to Henning Meier-Geinitz . - * - Added read_timeout module parameter to override RD_NAK_TIMEOUT - * when read()'ing from devices. - * - Stalled pipes are now checked and cleared with - * usb_clear_halt() for the read_scanner() function. This should - * address the "funky result: -32" error messages. - * - Removed Microtek scanner ID's. Microtek scanners are now - * supported via the drivers/usb/microtek.c driver. - * - Added scanner specific read timeout's. - * - Return status errors are NEGATIVE!!! This should address the - * "funky result: -110" error messages. - * - Replaced USB_ST_TIMEOUT with ETIMEDOUT. - * - rd_nak was still defined in MODULE_PARM. It's been updated with - * read_timeout. Thanks to Mark W. Webb for - * reporting this bug. - * - Added Epson Perfection 1640SU and 1640SU Photo. Thanks to - * Jean-Luc and Manuel - * Pelayo . Reported to work fine by Manuel. - * - * 0.4.6 9/27/2001 - * - Added IOCTL's to report back scanner USB ID's. Thanks to - * Karl Heinz - * - Added Umax Astra 2100U ID's. Thanks to Ron - * Wellsted . - * and Manuel Pelayo . - * - Added HP 3400 ID's. Thanks to Harald Hannelius - * and Bertrik Sikken . 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 - * - Confirmed addition for SnapScan E20. Thanks to Steffen Hübner - * . - * - Added Lifetec LT9385 ID's. Thanks to Van Bruwaene Kris - * - * - Added Agfa SnapScan e26 ID's. Reported to work with SANE - * 1.0.5. Thanks to Falk Sauer . - * - Added HP 4300 ID's. Thanks to Stefan Schlosser - * . - * - Added Relisis Episode ID's. Thanks to Manfred - * Morgner . - * - Added many Acer ID's. Thanks to Oliver - * Schwartz . - * - Added Snapscan e40 ID's. Thanks to Oliver - * Schwartz . - * - Thanks to Oliver Neukum - * for helping with races. - * - Added Epson Perfection 1650 ID's. Thanks to Karl Heinz - * Kremer . - * - Added Epson Perfection 2450 ID's (aka GT-9700 for the Japanese - * market). Thanks to Karl Heinz Kremer . - * - Added Mustek 600 USB ID's. Thanks to Marcus - * Alanen . - * - Added Acer ScanPrisa 1240UT ID's. Thanks to Morgan - * Collins . - * - Incorporated devfs patches!! Thanks to Tom Rini - * , Pavel Roskin , - * Greg KH , Yves Duret , - * Flavio Stanchina . - * - Removed Minolta ScanImage II. This scanner uses USB SCSI. Thanks - * to Oliver Neukum 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. - * - * 0.4.7 11/28/2001 - * - Fixed typo in Documentation/usb/scanner.txt. Thanks to - * Karel for pointing it out. - * - Added ID's for a Memorex 6136u. Thanks to Álvaro Gaspar de - * Valenzuela" . - * - Added ID's for Agfa e25. Thanks to Heinrich - * Rust . Also reported to work with - * Linux and SANE (?). - * - Added Canon FB620U, D646U, and 1220U ID's. Thanks to Paul - * Rensing . For more info - * on Linux support for these models, contact - * salvestrini@users.sourceforge.net. - * - Added Plustek OpticPro UT12, OpticPro U24, KYE/Genius - * ColorPage-HR6 V2 ID's in addition to many "Unknown" models - * under those vendors. Thanks to - * Jaeger, Gerhard" . These scanner are - * apparently based upon the LM983x IC's. - * - Applied Frank's patch that addressed some locking and module - * referencing counts. Thanks to both - * Frank Zago and - * Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. - * - * 0.4.8 5/30/2002 - * - Added Mustek BearPaw 2400 TA. Thanks to Sergey - * Vlasov . - * - Added Mustek 1200UB Plus and Mustek BearPaw 1200 CU ID's. These use - * the Grandtech GT-6801 chip. Thanks to Henning - * Meier-Geinitz . - * - Increased Epson timeout to 60 secs as requested from - * Karl Heinz Kremer . - * - Changed maintainership from David E. Nelson to Brian - * Beattie . - * - * 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 , Stian Jordet - * , "Yann E. MORIN" , - * "Jaeger, Gerhard" , Ira Childress - * , Till Kamppeter , - * Ed Hamrick , Oliver Schwartz - * and everyone else who sent ids. - * - Some Benq, Genius and Plustek ids are identified now. - * - Accept scanners with only one bulk (in) endpoint (thanks to Sergey - * Vlasov ). - * - Accept devices with more than one interface. Only use interfaces that - * look like belonging to scanners. - * - Fix compilation error when debugging is enabled. - * - Add locking to ioctl_scanner(). Thanks to Oliver Neukum - * . - * - * 0.4.10 01/07/2003 - * - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek - * and Visioneer scanners. Thanks to William Lam , - * Till Kamppeter 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 every time 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. - * - 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. - * - Fixed generation of devfs names if dynamic minors are disabled. - * - Used kobject reference counting to free the scn struct when the device - * is closed and disconnected. Avoids crashes when writing to a - * disconnected device. (Thanks to Greg KH). - * - * 0.4.12 2003-04-11 - * - Fixed endpoint detection. The endpoints were numbered from 1 to n but - * that assumption is not correct in all cases. - * - * 0.4.13 2003-05-30 - * - Added vendor/product ids for Genius, Hewlett-Packard, Microtek, - * Mustek, Pacific Image Electronics, Plustek, and Visioneer scanners. - * Fixed names of some other scanners. - * - * 0.4.14 2003-07-15 - * - Fixed race between open and probe (Oliver Neukum). - * - Added vendor/product ids for Avision, Canon, HP, Microtek and Relisys scanners. - * - Clean up irq urb when not enough memory is available. - * - * 0.4.15 2003-09-22 - * - Use static declarations for usb_scanner_init/usb_scanner_exit - * (Daniele Bellucci). - * - Report back return codes of usb_register and usb_usbmit_urb instead of -1 or - * -ENONMEM (Daniele Bellucci). - * - Balancing usb_register_dev/usb_deregister_dev in probe_scanner when a fail - * condition occours (Daniele Bellucci). - * - Added vendor/product ids for Canon, HP, Microtek, Mustek, Siemens, UMAX, and - * Visioneer scanners. - * - Added test for USB_CLASS_CDC_DATA which is used by some fingerprint scanners. - * - * 0.4.16 2003-11-04 - * - Added vendor/product ids for Epson, Genius, Microtek, Plustek, Reflecta, and - * Visioneer scanners. Removed ids for HP PSC devices as these are supported by - * the hpoj userspace driver. - * - * TODO - * - Performance - * - Select/poll methods - * - More testing - * - More general usage ioctl's - * - * - * Thanks to: - * - * - All the folks on the linux-usb list who put up with me. :) This - * has been a great learning experience for me. - * - To Linus Torvalds for this great OS. - * - The GNU folks. - * - The folks that forwarded Vendor:Product ID's to me. - * - Johannes Erdfelt for the loaning of a USB analyzer for tracking an - * issue with HP-4100 and uhci. - * - Adolfo Montero for his assistance. - * - All the folks who chimed in with reports and suggestions. - * - All the developers that are working on USB SANE backends or other - * applications to use USB scanners. - * - Thanks to Greg KH for setting up Brian Beattie - * and Henning Meier-Geinitz to be the new USB Scanner maintainer. - * - * Performance: - * - * System: Pentium 120, 80 MB RAM, OHCI, Linux 2.3.23, HP 4100C USB Scanner - * 300 dpi scan of the entire bed - * 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. - */ - - -#include - -/* - * Scanner definitions, macros, module info, - * debug/ioctl/data_dump enable, and other constants. - */ -#include "scanner.h" - -static void -irq_scanner(struct urb *urb, struct pt_regs *regs) -{ - -/* - * For the meantime, this is just a placeholder until I figure out what - * all I want to do with it -- or somebody else for that matter. - */ - - struct scn_usb_data *scn; - unsigned char *data; - int status; - - scn = urb->context; - - data = &scn->button; - data += 0; /* Keep gcc from complaining about unused var */ - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - return; - } - - dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data); - - status = usb_submit_urb (urb, GFP_ATOMIC); - if (status) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, status); -} - -static int -open_scanner(struct inode * inode, struct file * file) -{ - struct scn_usb_data *scn; - struct usb_device *dev; - struct usb_interface *intf; - - int scn_minor; - - int err=0; - - down(&scn_mutex); - - scn_minor = USB_SCN_MINOR(inode); - - dbg("open_scanner: scn_minor:%d", scn_minor); - - intf = usb_find_interface(&scanner_driver, scn_minor); - if (!intf) { - up(&scn_mutex); - err("open_scanner(%d): Unable to access minor data", scn_minor); - return -ENODEV; - } - scn = usb_get_intfdata(intf); - kobject_get(&scn->kobj); - - 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; - goto out_error; - } - - if (!scn->present) { - err("open_scanner(%d): Scanner is not present", scn_minor); - err = -ENODEV; - goto out_error; - } - - if (scn->isopen) { - dbg("open_scanner(%d): Scanner device is already open", scn_minor); - err = -EBUSY; - goto out_error; - } - - init_waitqueue_head(&scn->rd_wait_q); - - scn->isopen = 1; - - file->private_data = scn; /* Used by the read and write methods */ - - -out_error: - - up(&(scn->sem)); /* Wake up any possible contending processes */ - - return err; -} - -static int -close_scanner(struct inode * inode, struct file * file) -{ - struct scn_usb_data *scn = file->private_data; - - int scn_minor; - - scn_minor = USB_SCN_MINOR (inode); - - dbg("close_scanner: scn_minor:%d", scn_minor); - - down(&scn_mutex); - down(&(scn->sem)); - - scn->isopen = 0; - - file->private_data = NULL; - - up(&scn_mutex); - up(&(scn->sem)); - - kobject_put(&scn->kobj); - - return 0; -} - -static ssize_t -write_scanner(struct file * file, const char * buffer, - size_t count, loff_t *ppos) -{ - struct scn_usb_data *scn; - struct usb_device *dev; - - ssize_t bytes_written = 0; /* Overall count of bytes written */ - ssize_t ret = 0; - - int scn_minor; - - int this_write; /* Number of bytes to write */ - int partial; /* Number of bytes successfully written */ - int result = 0; - - char *obuf; - - scn = file->private_data; - - 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; - - dev = scn->scn_dev; - - file->f_dentry->d_inode->i_atime = CURRENT_TIME; - - while (count > 0) { - - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - this_write = (count >= OBUF_SIZE) ? OBUF_SIZE : count; - - if (copy_from_user(scn->obuf, buffer, this_write)) { - ret = -EFAULT; - break; - } - - result = usb_bulk_msg(dev,usb_sndbulkpipe(dev, scn->bulk_out_ep), obuf, this_write, &partial, 60*HZ); - dbg("write stats(%d): result:%d this_write:%d partial:%d", scn_minor, result, this_write, partial); - - if (result == -ETIMEDOUT) { /* NAK -- shouldn't happen */ - warn("write_scanner: NAK received."); - ret = result; - break; - } else if (result < 0) { /* We should not get any I/O errors */ - warn("write_scanner(%d): funky result: %d. Consult Documentataion/usb/scanner.txt.", scn_minor, result); - ret = -EIO; - break; - } - -#ifdef WR_DATA_DUMP - if (partial) { - unsigned char cnt, cnt_max; - cnt_max = (partial > 24) ? 24 : partial; - printk(KERN_DEBUG "dump(%d): ", scn_minor); - for (cnt=0; cnt < cnt_max; cnt++) { - printk("%X ", obuf[cnt]); - } - printk("\n"); - } -#endif - if (partial != this_write) { /* Unable to write all contents of obuf */ - ret = -EIO; - break; - } - - if (partial) { /* Data written */ - buffer += partial; - count -= partial; - bytes_written += partial; - } else { /* No data written */ - ret = 0; - break; - } - } - up(&(scn->sem)); - mdelay(5); /* This seems to help with SANE queries */ - return ret ? ret : bytes_written; -} - -static ssize_t -read_scanner(struct file * file, char * buffer, - size_t count, loff_t *ppos) -{ - struct scn_usb_data *scn; - struct usb_device *dev; - - ssize_t bytes_read; /* Overall count of bytes_read */ - ssize_t ret; - - int scn_minor; - int partial; /* Number of bytes successfully read */ - int this_read; /* Max number of bytes to read */ - int result; - int rd_expire = RD_EXPIRE; - - char *ibuf; - - scn = file->private_data; - - down(&(scn->sem)); - - scn_minor = scn->scn_minor; - - ibuf = scn->ibuf; - - dev = scn->scn_dev; - - bytes_read = 0; - ret = 0; - - file->f_dentry->d_inode->i_atime = CURRENT_TIME; /* Update the - atime of - the device - node */ - while (count > 0) { - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; - - result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, scn->bulk_in_ep), ibuf, this_read, &partial, scn->rd_nak_timeout); - dbg("read stats(%d): result:%d this_read:%d partial:%d count:%d", scn_minor, result, this_read, partial, count); - -/* - * Scanners are sometimes inheriently slow since they are mechanical - * in nature. USB bulk reads tend to timeout while the scanner is - * positioning, resetting, warming up the lamp, etc if the timeout is - * set too low. A very long timeout parameter for bulk reads was used - * to overcome this limitation, but this sometimes resulted in folks - * having to wait for the timeout to expire after pressing Ctrl-C from - * an application. The user was sometimes left with the impression - * that something had hung or crashed when in fact the USB read was - * just waiting on data. So, the below code retains the same long - * timeout period, but splits it up into smaller parts so that - * Ctrl-C's are acted upon in a reasonable amount of time. - */ - - if (result == -ETIMEDOUT) { /* NAK */ - if (!partial) { /* No data */ - if (--rd_expire <= 0) { /* Give it up */ - warn("read_scanner(%d): excessive NAK's received", scn_minor); - ret = result; - break; - } else { /* Keep trying to read data */ - interruptible_sleep_on_timeout(&scn->rd_wait_q, scn->rd_nak_timeout); - continue; - } - } else { /* Timeout w/ some data */ - 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); - } - ret = result; - break; - } else if ((result < 0) && (result != -EREMOTEIO)) { - warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result); - ret = -EIO; - break; - } - - data_recvd: - -#ifdef RD_DATA_DUMP - if (partial) { - unsigned char cnt, cnt_max; - cnt_max = (partial > 24) ? 24 : partial; - printk(KERN_DEBUG "dump(%d): ", scn_minor); - for (cnt=0; cnt < cnt_max; cnt++) { - printk("%X ", ibuf[cnt]); - } - printk("\n"); - } -#endif - - if (partial) { /* Data returned */ - if (copy_to_user(buffer, ibuf, partial)) { - ret = -EFAULT; - break; - } - count -= this_read; /* Compensate for short reads */ - bytes_read += partial; /* Keep tally of what actually was read */ - buffer += partial; - } else { - ret = 0; - break; - } - } - up(&(scn->sem)); - return ret ? ret : bytes_read; -} - -static int -ioctl_scanner(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct usb_device *dev; - struct scn_usb_data *scn = file->private_data; - int retval = -ENOTTY; - int scn_minor; - - scn_minor = USB_SCN_MINOR(inode); - down(&(scn->sem)); - - dev = scn->scn_dev; - - switch (cmd) - { - case SCANNER_IOCTL_VENDOR : - retval = (put_user(dev->descriptor.idVendor, (unsigned int *) arg)); - break; - case SCANNER_IOCTL_PRODUCT : - retval = (put_user(dev->descriptor.idProduct, (unsigned int *) arg)); - break; - case SCANNER_IOCTL_CTRLMSG: - { - struct ctrlmsg_ioctl { - struct usb_ctrlrequest req; - void *data; - } cmsg; - int pipe, nb, ret; - unsigned char buf[64]; - retval = 0; - - if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg))) { - retval = -EFAULT; - break; - } - - nb = cmsg.req.wLength; - - 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)) { - retval = -EFAULT; - break; - } - } else { - pipe = usb_rcvctrlpipe(dev, 0); - } - - ret = usb_control_msg(dev, pipe, cmsg.req.bRequest, - cmsg.req.bRequestType, - cmsg.req.wValue, - cmsg.req.wIndex, - buf, nb, HZ); - - if (ret < 0) { - err("ioctl_scanner(%d): control_msg returned %d\n", scn_minor, ret); - retval = -EIO; - break; - } - - if (nb > 0 && (cmsg.req.bRequestType & 0x80) && copy_to_user(cmsg.data, buf, nb)) - retval = -EFAULT; - - break; - } - default: - break; - } - up(&(scn->sem)); - return retval; -} - -static void destroy_scanner (struct kobject *kobj) -{ - struct scn_usb_data *scn; - - dbg ("%s", __FUNCTION__); - - scn = to_scanner(kobj); - - down (&scn_mutex); - down (&(scn->sem)); - - usb_driver_release_interface(&scanner_driver, - scn->scn_dev->actconfig->interface[scn->ifnum]); - - kfree(scn->ibuf); - kfree(scn->obuf); - - usb_free_urb(scn->scn_irq); - usb_put_dev(scn->scn_dev); - up (&(scn->sem)); - kfree (scn); - up (&scn_mutex); -} - -static struct kobj_type scanner_kobj_type = { - .release = destroy_scanner, -}; - -static struct -file_operations usb_scanner_fops = { - .owner = THIS_MODULE, - .read = read_scanner, - .write = write_scanner, - .ioctl = ioctl_scanner, - .open = open_scanner, - .release = close_scanner, -}; - -static struct usb_class_driver scanner_class = { - .name = "usb/scanner%d", - .fops = &usb_scanner_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, - .minor_base = SCN_BASE_MNR, -}; - -static int -probe_scanner(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev (intf); - struct scn_usb_data *scn; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - - int ep_cnt; - int ix; - int retval; - - char valid_device = 0; - char have_bulk_in, have_bulk_out, have_intr; - char name[14]; - - dbg("probe_scanner: USB dev address:%p", dev); - -/* - * 1. Check Vendor/Product - * 2. Determine/Assign Bulk Endpoints - * 3. Determine/Assign Intr Endpoint - */ - -/* - * There doesn't seem to be an imaging class defined in the USB - * Spec. (yet). If there is, HP isn't following it and it doesn't - * look like anybody else is either. Therefore, we have to test the - * Vendor and Product ID's to see what we have. Also, other scanners - * may be able to use this driver by specifying both vendor and - * product ID's as options to the scanner module in conf.modules. - * - * NOTE: Just because a product is supported 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 USB products. - * - * Until we detect a device which is pleasing, we silently punt. - */ - - for (ix = 0; ix < sizeof (scanner_device_ids) / sizeof (struct usb_device_id); ix++) { - if ((dev->descriptor.idVendor == scanner_device_ids [ix].idVendor) && - (dev->descriptor.idProduct == scanner_device_ids [ix].idProduct)) { - valid_device = 1; - break; - } - } - if (dev->descriptor.idVendor == vendor && /* User specified */ - dev->descriptor.idProduct == product) { /* User specified */ - valid_device = 1; - } - - if (!valid_device) - return -ENODEV; /* We didn't find anything pleasing */ - -/* - * After this point we can be a little noisy about what we are trying to - * configure. - */ - - if (dev->descriptor.bNumConfigurations != 1) { - info("probe_scanner: Only one device configuration is supported."); - return -ENODEV; - } - - interface = intf->altsetting; - - if (interface[0].desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC && - interface[0].desc.bInterfaceClass != USB_CLASS_PER_INTERFACE && - interface[0].desc.bInterfaceClass != USB_CLASS_CDC_DATA && - interface[0].desc.bInterfaceClass != SCN_CLASS_SCANJET) { - dbg("probe_scanner: This interface doesn't look like a scanner (class=0x%x).", interface[0].desc.bInterfaceClass); - return -ENODEV; - } - -/* - * 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->desc.bNumEndpoints); - - ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0; - - while (ep_cnt < interface->desc.bNumEndpoints) { - endpoint = &interface->endpoint[ep_cnt].desc; - - if (IS_EP_BULK_IN(endpoint)) { - ep_cnt++; - if (have_bulk_in) { - info ("probe_scanner: ignoring additional bulk_in_ep:%d", ep_cnt); - continue; - } - have_bulk_in = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - dbg("probe_scanner: bulk_in_ep:%d", have_bulk_in); - continue; - } - - if (IS_EP_BULK_OUT(endpoint)) { - ep_cnt++; - if (have_bulk_out) { - info ("probe_scanner: ignoring additional bulk_out_ep:%d", ep_cnt); - continue; - } - have_bulk_out = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - dbg("probe_scanner: bulk_out_ep:%d", have_bulk_out); - continue; - } - - if (IS_EP_INTR(endpoint)) { - ep_cnt++; - if (have_intr) { - info ("probe_scanner: ignoring additional intr_ep:%d", ep_cnt); - continue; - } - have_intr = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - dbg("probe_scanner: intr_ep:%d", have_intr); - continue; - } - info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt."); - return -EIO; /* Shouldn't ever get here unless we have something weird */ - } - - -/* - * Perform a quick check to make sure that everything worked as it - * should have. - */ - - if (!have_bulk_in) { - err("probe_scanner: One bulk-in endpoint required."); - return -EIO; - } - -/* - * Determine a minor number and initialize the structure associated - * 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); - - retval = usb_register_dev(intf, &scanner_class); - if (retval) { - err ("Not able to get a minor for this device."); - up(&scn_mutex); - return -ENOMEM; - } - - dbg("probe_scanner: Allocated minor:%d", intf->minor); - - if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) { - err("probe_scanner: Out of memory."); - up(&scn_mutex); - return -ENOMEM; - } - memset (scn, 0, sizeof(struct scn_usb_data)); - kobject_init(&scn->kobj); - scn->kobj.ktype = &scanner_kobj_type; - - scn->scn_irq = usb_alloc_urb(0, GFP_KERNEL); - if (!scn->scn_irq) { - usb_deregister_dev(intf, &scanner_class); - kfree(scn); - up(&scn_mutex); - return -ENOMEM; - } - - init_MUTEX(&(scn->sem)); /* Initializes to unlocked */ - - dbg ("probe_scanner(%d): Address of scn:%p", intf->minor, scn); - -/* Ok, if we detected an interrupt EP, setup a handler for it */ - if (have_intr) { - dbg("probe_scanner(%d): Configuring IRQ handler for intr EP:%d", intf->minor, have_intr); - usb_fill_int_urb(scn->scn_irq, dev, - usb_rcvintpipe(dev, have_intr), - &scn->button, 1, irq_scanner, scn, - // endpoint[(int)have_intr].bInterval); - 250); - - retval = usb_submit_urb(scn->scn_irq, GFP_KERNEL); - if (retval) { - err("probe_scanner(%d): Unable to allocate INT URB.", intf->minor); - usb_deregister_dev(intf, &scanner_class); - kfree(scn); - up(&scn_mutex); - return retval; - } - } - - -/* Ok, now initialize all the relevant values */ - if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { - err("probe_scanner(%d): Not enough memory for the output buffer.", intf->minor); - if (have_intr) - usb_unlink_urb(scn->scn_irq); - usb_free_urb(scn->scn_irq); - usb_deregister_dev(intf, &scanner_class); - kfree(scn); - up(&scn_mutex); - return -ENOMEM; - } - dbg("probe_scanner(%d): obuf address:%p", intf->minor, scn->obuf); - - if (!(scn->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { - err("probe_scanner(%d): Not enough memory for the input buffer.", intf->minor); - if (have_intr) - usb_unlink_urb(scn->scn_irq); - usb_free_urb(scn->scn_irq); - usb_deregister_dev(intf, &scanner_class); - kfree(scn->obuf); - kfree(scn); - up(&scn_mutex); - return -ENOMEM; - } - dbg("probe_scanner(%d): ibuf address:%p", intf->minor, scn->ibuf); - - - switch (dev->descriptor.idVendor) { /* Scanner specific read timeout parameters */ - case 0x04b8: /* Seiko/Epson */ - scn->rd_nak_timeout = HZ * 60; - break; - case 0x055f: /* Mustek */ - case 0x0400: /* Another Mustek */ - scn->rd_nak_timeout = HZ * 1; - default: - scn->rd_nak_timeout = RD_NAK_TIMEOUT; - } - - - if (read_timeout > 0) { /* User specified read timeout overrides everything */ - info("probe_scanner: User specified USB read timeout - %d", read_timeout); - scn->rd_nak_timeout = read_timeout; - } - - - usb_get_dev(dev); - scn->bulk_in_ep = have_bulk_in; - scn->bulk_out_ep = have_bulk_out; - scn->intr_ep = have_intr; - scn->present = 1; - scn->scn_dev = dev; - scn->scn_minor = intf->minor; - scn->isopen = 0; - - snprintf(name, sizeof(name), scanner_class.name, - intf->minor - scanner_class.minor_base); - - info ("USB scanner device (0x%04x/0x%04x) now attached to %s", - dev->descriptor.idVendor, dev->descriptor.idProduct, name); - - usb_set_intfdata(intf, scn); - up(&scn_mutex); - - return 0; -} - -static void -disconnect_scanner(struct usb_interface *intf) -{ - struct scn_usb_data *scn = usb_get_intfdata(intf); - - /* disable open() */ - dbg("%s: De-allocating minor:%d", __FUNCTION__, scn->scn_minor); - usb_deregister_dev(intf, &scanner_class); - - usb_set_intfdata(intf, NULL); - if(scn->intr_ep) { - dbg("%s(%d): Unlinking IRQ URB", __FUNCTION__, scn->scn_minor); - usb_unlink_urb(scn->scn_irq); - } - - if (scn) - kobject_put(&scn->kobj); -} - -/* we want to look at all devices, as the vendor/product id can change - * depending on the command line argument */ -static struct usb_device_id ids[] = { - {.driver_info = 42}, - {} -}; - -static struct -usb_driver scanner_driver = { - .owner = THIS_MODULE, - .name = "usbscanner", - .probe = probe_scanner, - .disconnect = disconnect_scanner, - .id_table = ids, -}; - -static void __exit -usb_scanner_exit(void) -{ - usb_deregister(&scanner_driver); -} - -static int __init -usb_scanner_init (void) -{ - int retval; - retval = usb_register(&scanner_driver); - if (retval) - goto out; - - info(DRIVER_VERSION ":" DRIVER_DESC); - if (vendor != -1 && product != -1) - info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product); - out: - return retval; -} - -module_init(usb_scanner_init); -module_exit(usb_scanner_exit); diff -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h --- a/drivers/usb/image/scanner.h Mon Feb 9 14:38:51 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,387 +0,0 @@ -/* - * Driver for USB Scanners (linux-2.6) - * - * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson - * Previously maintained by Brian Beattie - * - * Current maintainer: Henning Meier-Geinitz - * - * 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 - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// #define DEBUG - -#define DRIVER_VERSION "0.4.16" -#define DRIVER_DESC "USB Scanner Driver" - -#include - -static __s32 vendor=-1, product=-1, read_timeout=0; - -MODULE_AUTHOR("Henning Meier-Geinitz, henning@meier-geinitz.de"); -MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -MODULE_PARM(vendor, "i"); -MODULE_PARM_DESC(vendor, "User specified USB idVendor"); - -MODULE_PARM(product, "i"); -MODULE_PARM_DESC(product, "User specified USB idProduct"); - -MODULE_PARM(read_timeout, "i"); -MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds"); - - -/* 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. */ - -static struct usb_device_id scanner_device_ids [] = { - /* Acer (now Benq) */ - { USB_DEVICE(0x04a5, 0x1a20) }, /* Prisa 310U */ - { 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) }, /* 1240UT, 1240U */ - { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */ - { 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, 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, 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, 0x0268) }, /* iVina 1200U */ - { USB_DEVICE(0x0638, 0x0a10) }, /* iVina FB1600 (=Umax Astra 4500) */ - { USB_DEVICE(0x0638, 0x0a20) }, /* iVina FB1800 (=Umax Astra 4700) */ - /* 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, 0x220a) }, /* CanoScan D2400UF */ - { 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, 0x220f) }, /* CanoScan 8000F */ - { USB_DEVICE(0x04a9, 0x2210) }, /* CanoScan 9900F */ - { USB_DEVICE(0x04a9, 0x2212) }, /* CanoScan 5000F */ - { USB_DEVICE(0x04a9, 0x2213) }, /* LIDE 50 */ - { USB_DEVICE(0x04a9, 0x2215) }, /* CanoScan 3000 */ - { 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, 0x2007) }, /* ColorPage HR6 V2 */ - { 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 */ - { USB_DEVICE(0x0458, 0x2018) }, /* ColorPage HR7X */ - { USB_DEVICE(0x0458, 0x201b) }, /* Colorpage Vivid 4x */ - /* Hewlett Packard */ - /* IMPORTANT: Hewlett-Packard multi-function peripherals (OfficeJet, - Printer/Scanner/Copier (PSC), LaserJet, or PhotoSmart printer) - should not be added to this table because they are accessed by a - userspace driver (hpoj) */ - { USB_DEVICE(0x03f0, 0x0101) }, /* ScanJet 4100C */ - { USB_DEVICE(0x03f0, 0x0102) }, /* PhotoSmart S20 */ - { 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, 0x0805) }, /* ScanJet 4470c */ - { USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */ - { USB_DEVICE(0x03f0, 0x0a01) }, /* ScanJet 2400c */ - { USB_DEVICE(0x03F0, 0x1005) }, /* ScanJet 5400C */ - { USB_DEVICE(0x03F0, 0x1105) }, /* ScanJet 5470C */ - { USB_DEVICE(0x03f0, 0x1205) }, /* ScanJet 5550C */ - { USB_DEVICE(0x03f0, 0x1305) }, /* Scanjet 4570c */ - // { USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 - NOT SUPPORTED - use hpoj userspace driver */ - { USB_DEVICE(0x03f0, 0x2005) }, /* ScanJet 3570c */ - { USB_DEVICE(0x03f0, 0x2205) }, /* ScanJet 3500c */ - // { USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210 - NOT SUPPORTED - use hpoj userspace driver */ - /* 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 */ - { USB_DEVICE(0x05da, 0x20a7) }, /* ScanMaker 5600 */ - { USB_DEVICE(0x05da, 0x20c9) }, /* ScanMaker 6700 */ - { USB_DEVICE(0x05da, 0x30ce) }, /* ScanMaker 3800 */ - { USB_DEVICE(0x05da, 0x30cf) }, /* ScanMaker 4800 */ - { USB_DEVICE(0x05da, 0x30d4) }, /* ScanMaker 3830 + 3840 */ - { USB_DEVICE(0x05da, 0x30d8) }, /* ScanMaker 5900 */ - { USB_DEVICE(0x04a7, 0x0224) }, /* Scanport 3000 (actually Visioneer?)*/ - /* 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 */ - // { USB_DEVICE(0x05da, 0x009a) }, /* Phantom C6 */ - // { USB_DEVICE(0x05da, 0x00a3) }, /* ScanMaker V6USL */ - // { USB_DEVICE(0x05da, 0x80a3) }, /* ScanMaker V6USL #2 */ - // { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */ - /* Minolta */ - { 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(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(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, 0x0401) }, /* P 3600 A3 Pro */ - { USB_DEVICE(0x055f, 0x0409) }, /* BearPaw 2448TA 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 */ - /* Pacific Image Electronics */ - { USB_DEVICE(0x05e3, 0x0120) }, /* PrimeFilm 1800u */ - /* Plustek */ - { USB_DEVICE(0x07b3, 0x0001) }, /* 1212U */ - { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */ - { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */ - { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0013) }, /* UT12 */ - { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */ - { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */ - { USB_DEVICE(0x07b3, 0x0400) }, /* OpticPro 1248U */ - { USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U (another one) */ - { USB_DEVICE(0x07b3, 0x0403) }, /* U16B */ - { USB_DEVICE(0x07b3, 0x0413) }, /* OpticSlim 1200 */ - /* Primax/Colorado */ - { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ - { USB_DEVICE(0x0461, 0x0301) }, /* G2E-300 #1 */ - { USB_DEVICE(0x0461, 0x0302) }, /* G2-300 #2 */ - { USB_DEVICE(0x0461, 0x0303) }, /* G2E-300 #2 */ - { USB_DEVICE(0x0461, 0x0340) }, /* Colorado USB 9600 */ - { 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 */ - /* Reflecta */ - { USB_DEVICE(0x05e3, 0x0120) }, /* iScan 1800 */ - /* Relisis */ - // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ - { USB_DEVICE(0x0475, 0x0210) }, /* Scorpio Ultra 3 */ - /* 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 */ - { USB_DEVICE(0x04b8, 0x010e) }, /* Expression 1680 */ - { USB_DEVICE(0x04b8, 0x010f) }, /* Perfection 1250U */ - { USB_DEVICE(0x04b8, 0x0110) }, /* Perfection 1650 */ - { 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, 0x011f) }, /* Perfection 1670 */ - { USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */ - { USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */ - /* Siemens */ - { USB_DEVICE(0x0681, 0x0005) }, /* ID Mouse Professional */ - { USB_DEVICE(0x0681, 0x0010) }, /* Cherry FingerTIP ID Board - Sensor */ - /* 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, 0x0070) }, /* Astra 4400 */ - { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */ - { USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */ - { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */ - /* Visioneer */ - { USB_DEVICE(0x04a7, 0x0211) }, /* OneTouch 7600 USB */ - { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ - { USB_DEVICE(0x04a7, 0x0224) }, /* OneTouch 4800 USB */ - { USB_DEVICE(0x04a7, 0x0226) }, /* OneTouch 5800 USB */ - { USB_DEVICE(0x04a7, 0x0229) }, /* OneTouch 7100 USB */ - { USB_DEVICE(0x04a7, 0x022c) }, /* OneTouch 9020 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 */ -}; - -MODULE_DEVICE_TABLE (usb, scanner_device_ids); - -#define IS_EP_BULK(ep) ((ep)->bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0) -#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep)->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) -#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep)->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) -#define IS_EP_INTR(ep) ((ep)->bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0) - -#define USB_SCN_MINOR(X) iminor(X) - -#ifdef DEBUG -#define SCN_DEBUG(X) X -#else -#define SCN_DEBUG(X) -#endif - -#define IBUF_SIZE 32768 -#define OBUF_SIZE 4096 - -/* read_scanner timeouts -- RD_NAK_TIMEOUT * RD_EXPIRE = Number of seconds */ -#define RD_NAK_TIMEOUT (10*HZ) /* Default number of X seconds to wait */ -#define RD_EXPIRE 12 /* Number of attempts to wait X seconds */ - - -/* 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_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; - struct urb *scn_irq; - unsigned int ifnum; /* Interface number of the USB device */ - int scn_minor; /* Scanner minor - used in disconnect() */ - unsigned char button; /* Front panel buffer */ - char isopen; /* Not zero if the device is open */ - char present; /* Not zero if device is present */ - 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 sem; /* lock to prevent concurrent reads or writes */ - unsigned int rd_nak_timeout; /* Seconds to wait before read() timeout. */ - struct kobject kobj; /* Handles our reference counting */ -}; -#define to_scanner(d) container_of(d, struct scn_usb_data, kobj) - -static struct usb_driver scanner_driver;