Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
dd94d4eb
Commit
dd94d4eb
authored
Feb 04, 2004
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] USB: remove scanner driver files.
parent
cf3d97bf
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
1603 deletions
+0
-1603
drivers/usb/image/scanner.c
drivers/usb/image/scanner.c
+0
-1216
drivers/usb/image/scanner.h
drivers/usb/image/scanner.h
+0
-387
No files found.
drivers/usb/image/scanner.c
deleted
100644 → 0
View file @
cf3d97bf
/* -*- 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 <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
* 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 <david-b@pacbell.net> 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 <greg@kroah.com> 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 <khk@khk.net>.
* - 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 <adrianpj@easynews.com>.
* - 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
* <Dr.Hoyler@t-online.de>.
* - Modified the usb_string() reporting. See kfree() comment above.
* - Added Umax Astra 2000U. Thanks to Doug Alcorn <doug@lathi.net>.
* - 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
* <jan.vandenbergh@cs.kuleuven.ac.be>.
* - Added Umax 1220U ID's. Thanks to Maciek Klimkowski
* <mac@nexus.carleton.ca>.
* - Fixed bug in write_scanner(). The buffer was not being properly
* updated for writes larger than OBUF_SIZE. Thanks to Henrik
* Johansson <henrikjo@post.utfors.se> for identifying it.
* - Added Microtek X6 ID's. Thanks to Oliver Neukum
* <Oliver.Neukum@lrz.uni-muenchen.de>.
*
*
* 0.4.1 2/15/2000
*
* - Fixed 'count' bug in read_scanner(). Thanks to Henrik
* Johansson <henrikjo@post.utfors.se> 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 <linux/init.h> 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 <ph_baer@npw.net>.
* - Added Primax, ReadyScan, Visioneer, Colorado, and Genius ID's.
* Thanks to Adrian Perez Jorge <adrianpj@easynews.com>.
* - Fixed error number reported for non-existant devices. Thanks to
* Spyridon Papadimitriou <Spyridon_Papadimitriou@gs91.sp.cs.cmu.edu>.
* - Added Acer Prisascan 620U ID's. Thanks to Joao <joey@knoware.nl>.
* - 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 <linux/usb.h>
* - 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
* <flynn@isr.uni-stuttgart.de>.
* - Added iVina 1200U ID. Thanks to Dyson Lin <dyson@avision.com.tw>.
* - Added access time update for the device file courtesy of Paul
* Mackerras <paulus@samba.org>. 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 <rlinders@xs4all.nl>.
* - Added Acer ScanPrisa 620U ID. Thanks to Oliver
* Schwartz <Oliver.Schwartz@gmx.de> 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 <khk@khk.net> and Alain Knaff <Alain.Knaff@ltnb.lu>
* for discovering this.
* - Integrated Randy Dunlap's <randy.dunlap@intel.com> 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 <rlinders@xs4all.nl>.
*
* 0.4.4
* - Added addtional Mustek ID's (BearPaw 1200, 600 CU, 1200 USB,
* and 1200 UB. Thanks to Henning Meier-Geinitz <henningmg@gmx.de>.
* - 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 <gundersd@paradise.net.nz>.
* - Added the Epson Expression1600 ID's. Thanks to Karl Heinz
* Kremer <khk@khk.net>.
*
* 0.4.5 2/28/2001
* - Added Mustek ID's (BearPaw 2400, 1200 CU Plus, BearPaw 1200F).
* Thanks to Henning Meier-Geinitz <henningmg@gmx.de>.
* - 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 <markwebb@adelphia.net> for
* reporting this bug.
* - Added Epson Perfection 1640SU and 1640SU Photo. Thanks to
* Jean-Luc <f5ibh@db0bm.ampr.org> and Manuel
* Pelayo <Manuel.Pelayo@sesips.org>. 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 <khk@lynx.phpwebhosting.com>
* - Added Umax Astra 2100U ID's. Thanks to Ron
* Wellsted <ron@wellsted.org.uk>.
* and Manuel Pelayo <Manuel.Pelayo@sesips.org>.
* - Added HP 3400 ID's. Thanks to Harald Hannelius <harald@iki.fi>
* and Bertrik Sikken <bertrik@zonnet.nl>. 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 <moitinho@civil.ist.utl.pt>
* - Confirmed addition for SnapScan E20. Thanks to Steffen Hübner
* <hueb_s@gmx.de>.
* - Added Lifetec LT9385 ID's. Thanks to Van Bruwaene Kris
* <krvbr@yahoo.co.uk>
* - Added Agfa SnapScan e26 ID's. Reported to work with SANE
* 1.0.5. Thanks to Falk Sauer <falk@mgnkatze.franken.de>.
* - Added HP 4300 ID's. Thanks to Stefan Schlosser
* <castla@grmmbl.org>.
* - Added Relisis Episode ID's. Thanks to Manfred
* Morgner <odb-devel@gmx.net>.
* - Added many Acer ID's. Thanks to Oliver
* Schwartz <Oliver.Schwartz@gmx.de>.
* - Added Snapscan e40 ID's. Thanks to Oliver
* Schwartz <Oliver.Schwartz@gmx.de>.
* - Thanks to Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>
* for helping with races.
* - Added Epson Perfection 1650 ID's. Thanks to Karl Heinz
* Kremer <khk@khk.net>.
* - Added Epson Perfection 2450 ID's (aka GT-9700 for the Japanese
* market). Thanks to Karl Heinz Kremer <khk@khk.net>.
* - Added Mustek 600 USB ID's. Thanks to Marcus
* Alanen <maalanen@ra.abo.fi>.
* - Added Acer ScanPrisa 1240UT ID's. Thanks to Morgan
* Collins <sirmorcant@morcant.org>.
* - Incorporated devfs patches!! Thanks to Tom Rini
* <trini@kernel.crashing.org>, Pavel Roskin <proski@gnu.org>,
* Greg KH <greg@kroah.com>, Yves Duret <yduret@mandrakesoft.com>,
* Flavio Stanchina <flavio.stanchina@tin.it>.
* - Removed Minolta ScanImage II. This scanner uses USB SCSI. Thanks
* to Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> 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 <karel.vervaeke@pandora.be> for pointing it out.
* - Added ID's for a Memorex 6136u. Thanks to Álvaro Gaspar de
* Valenzuela" <agaspard@utsi.edu>.
* - Added ID's for Agfa e25. Thanks to Heinrich
* Rust <Heinrich.Rust@gmx.de>. Also reported to work with
* Linux and SANE (?).
* - Added Canon FB620U, D646U, and 1220U ID's. Thanks to Paul
* Rensing <Paul_Rensing@StanfordAlumni.org>. 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" <g.jaeger@earthling.net>. 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 <fzago@greshamstorage.com> 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 <vsu@mivlgu.murom.ru>.
* - Added Mustek 1200UB Plus and Mustek BearPaw 1200 CU ID's. These use
* the Grandtech GT-6801 chip. Thanks to Henning
* Meier-Geinitz <henning@meier-geinitz.de>.
* - Increased Epson timeout to 60 secs as requested from
* Karl Heinz Kremer <khk@khk.net>.
* - 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.
* - 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.
* - Fix compilation error when debugging is enabled.
* - 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 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 <greg@kroah.com> 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 <asm/byteorder.h>
/*
* 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
);
drivers/usb/image/scanner.h
deleted
100644 → 0
View file @
cf3d97bf
/*
* 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 <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
* 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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/ioctl.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
// #define DEBUG
#define DRIVER_VERSION "0.4.16"
#define DRIVER_DESC "USB Scanner Driver"
#include <linux/usb.h>
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
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment