4 * Driver for USB Scanners (linux-2.4.0test1-ac7)
6 * Copyright (C) 1999, 2000 David E. Nelson
8 * Portions may be copyright Brad Keryan and Michael Gee.
10 * David E. Nelson (dnelson@jump.net)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Originally based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
32 * Developed/tested using linux-2.3.15 with minor ohci.c changes to
33 * support short packes during bulk xfer mode. Some testing was
34 * done with ohci-hcd but the performace was low. Very limited
35 * testing was performed with uhci but I was unable to get it to
36 * work. Initial relase to the linux-usb development effort.
41 * - Device can't be opened unless a scanner is plugged into the USB.
42 * - Finally settled on a reasonable value for the I/O buffer's.
43 * - Cleaned up write_scanner()
44 * - Disabled read/write stats
45 * - A little more code cleanup
50 * - Device registration changed to reflect new device
51 * allocation/registration for linux-2.3.22+.
52 * - Adopted David Brownell's <david-b@pacbell.net> technique for
53 * assigning bulk endpoints.
54 * - Removed unnessesary #include's
55 * - Scanner model now reported via syslog INFO after being detected
57 * - Added user specified vendor:product USB ID's which can be passed
58 * as module parameters.
63 * - Applied patches for linux-2.3.25.
64 * - Error number reporting changed to reflect negative return codes.
69 * - Applied patches for linux-2.3.26 to scanner_init().
70 * - Debug read/write stats now report values as signed decimal.
75 * - Updated the bulk_msg() calls to usb usb_bulk_msg().
76 * - Added a small delay in the write_scanner() method to aid in
77 * avoiding NULL data reads on HP scanners. We'll see how this works.
78 * - Return values from usb_bulk_msg() now ignore positive values for
79 * use with the ohci driver.
80 * - Added conditional debugging instead of commenting/uncommenting
82 * - kfree()'d the pointer after using usb_string() as documented in
84 * - Added usb_set_configuration(). It got lost in version 0.3 -- ack!
85 * - Added the HP 5200C USB Vendor/Product ID's.
90 * - Added Greg K-H's <greg@kroah.com> patch for better handling of
91 * Product/Vendor detection.
92 * - The driver now autoconfigures its endpoints including interrupt
93 * endpoints if one is detected. The concept was originally based
94 * upon David Brownell's method.
95 * - Added some Seiko/Epson ID's. Thanks to Karl Heinz
96 * Kremer <khk@khk.net>.
97 * - Added some preliminary ioctl() calls for the PV8630 which is used
98 * by the HP4200. The ioctl()'s still have to be registered. Thanks
99 * to Adrian Perez Jorge <adrianpj@easynews.com>.
100 * - Moved/migrated stuff to scanner.h
101 * - Removed the usb_set_configuration() since this is handled by
102 * the usb_new_device() routine in usb.c.
103 * - Added the HP 3300C. Thanks to Bruce Tenison.
104 * - Changed user specified vendor/product id so that root hub doesn't
105 * get falsely attached to. Thanks to Greg K-H.
106 * - Added some Mustek ID's. Thanks to Gernot Hoyler
107 * <Dr.Hoyler@t-online.de>.
108 * - Modified the usb_string() reporting. See kfree() comment above.
109 * - Added Umax Astra 2000U. Thanks to Doug Alcorn <doug@lathi.net>.
110 * - Updated the printk()'s to use the info/warn/dbg macros.
111 * - Updated usb_bulk_msg() argument types to fix gcc warnings.
116 * - Removed usb_string() from probe_scanner since the core now does a
117 * good job of reporting what was connnected.
118 * - Finally, simultaneous multiple device attachment!
119 * - Fixed some potential memory freeing issues should memory allocation
120 * fail in probe_scanner();
121 * - Some fixes to disconnect_scanner().
122 * - Added interrupt endpoint support.
123 * - Added Agfa SnapScan Touch. Thanks to Jan Van den Bergh
124 * <jan.vandenbergh@cs.kuleuven.ac.be>.
125 * - Added Umax 1220U ID's. Thanks to Maciek Klimkowski
126 * <mac@nexus.carleton.ca>.
127 * - Fixed bug in write_scanner(). The buffer was not being properly
128 * updated for writes larger than OBUF_SIZE. Thanks to Henrik
129 * Johansson <henrikjo@post.utfors.se> for identifying it.
130 * - Added Microtek X6 ID's. Thanks to Oliver Neukum
131 * <Oliver.Neukum@lrz.uni-muenchen.de>.
136 * - Fixed 'count' bug in read_scanner(). Thanks to Henrik
137 * Johansson <henrikjo@post.utfors.se> for identifying it. Amazing
138 * it has worked this long.
139 * - Fixed '>=' bug in both read/write_scanner methods.
140 * - Cleaned up both read/write_scanner() methods so that they are
141 * a little more readable.
142 * - Added a lot of Microtek ID's. Thanks to Adrian Perez Jorge.
143 * - Adopted the __initcall().
144 * - Added #include <linux/init.h> to scanner.h for __initcall().
145 * - Added one liner in irq_scanner() to keep gcc from complaining
146 * about an unused variable (data) if debugging was disabled
148 * - Increased the timeout parameter in read_scanner() to 120 Secs.
153 * - Added Umax 1236U ID. Thanks to Philipp Baer <ph_baer@npw.net>.
154 * - Added Primax, ReadyScan, Visioneer, Colorado, and Genius ID's.
155 * Thanks to Adrian Perez Jorge <adrianpj@easynews.com>.
156 * - Fixed error number reported for non-existant devices. Thanks to
157 * Spyridon Papadimitriou <Spyridon_Papadimitriou@gs91.sp.cs.cmu.edu>.
158 * - Added Acer Prisascan 620U ID's. Thanks to Joao <joey@knoware.nl>.
159 * - Replaced __initcall() with module_init()/module_exit(). Updates
161 * - Replaced file_operations structure with new syntax. Updates
163 * - Changed #include "usb.h" to #include <linux/usb.h>
164 * - Added #define SCN_IOCTL to exclude development areas
165 * since 2.4.x is about to be released. This mainly affects the
166 * ioctl() stuff. See scanner.h for more details.
167 * - Changed the return value for signal_pending() from -ERESTARTSYS to
173 * - Added Umax Astra 2200 ID. Thanks to Flynn Marquardt
174 * <flynn@isr.uni-stuttgart.de>.
175 * - Added iVina 1200U ID. Thanks to Dyson Lin <dyson@avision.com.tw>.
176 * - Added access time update for the device file courtesy of Paul
177 * Mackerras <paulus@linuxcare.com>. This allows a user space daemon
178 * to turn the lamp off for a Umax 1220U scanner after a prescribed
180 * - Fixed HP S20 ID's. Thanks to Ruud Linders <rlinders@xs4all.nl>.
181 * - Added Acer ScanPrisa 620U ID. Thanks to Oliver
182 * Schwartz <Oliver.Schwartz@gmx.de> via sane-devel mail list.
183 * - Fixed bug in read_scanner for copy_to_user() function. The returned
184 * value should be 'partial' not 'this_read'.
185 * - Fixed bug in read_scanner. 'count' should be decremented
186 * by 'this_read' and not by 'partial'. This resulted in twice as many
187 * calls to read_scanner() for small amounts of data and possibly
188 * unexpected returns of '0'. Thanks to Karl Heinz
189 * Kremer <khk@khk.net> and Alain Knaff <Alain.Knaff@ltnb.lu>
190 * for discovering this.
191 * - Integrated Randy Dunlap's <randy.dunlap@intel.com> patch for a
192 * scanner lookup/ident table. Thanks Randy.
193 * - Documentation updates.
194 * - Added wait queues to read_scanner().
199 * - Fixed HP S20 ID's...again..sigh. Thanks to Ruud
200 * Linders <rlinders@xs4all.nl>.
206 * - Select/poll methods
208 * - Proper registry/assignment for LM9830 ioctl's
213 * - All the folks on the linux-usb list who put up with me. :) This
214 * has been a great learning experience for me.
215 * - To Linus Torvalds for this great OS.
217 * - The folks that forwarded Vendor:Product ID's to me.
218 * - Johannes Erdfelt for the loaning of a USB analyzer for tracking an
219 * issue with HP-4100 and uhci.
220 * - Adolfo Montero for his assistance.
221 * - All the folks who chimed in with reports and suggestions.
222 * - All the developers that are working on USB SANE backends or other
223 * applications to use USB scanners.
227 * System: Pentium 120, 80 MB RAM, OHCI, Linux 2.3.23, HP 4100C USB Scanner
228 * 300 dpi scan of the entire bed
229 * 24 Bit Color ~ 70 secs - 3.6 Mbit/sec
230 * 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec
234 * Scanner definitions, macros, module info,
235 * debug/ioctl/data_dump enable, and other constants.
240 irq_scanner(struct urb
*urb
)
244 * For the meantime, this is just a placeholder until I figure out what
245 * all I want to do with it -- or somebody else for that matter.
248 struct scn_usb_data
*scn
= urb
->context
;
249 unsigned char *data
= &scn
->button
;
250 data
+= 0; /* Keep gcc from complaining about unused var */
256 dbg("irq_scanner(%d): data:%x", scn
->scn_minor
, *data
);
262 open_scanner(struct inode
* inode
, struct file
* file
)
264 struct scn_usb_data
*scn
;
265 struct usb_device
*dev
;
269 scn_minor
= USB_SCN_MINOR(inode
);
271 dbg("open_scanner: scn_minor:%d", scn_minor
);
273 if (!p_scn_table
[scn_minor
]) {
274 err("open_scanner(%d): Unable to access minor data", scn_minor
);
278 scn
= p_scn_table
[scn_minor
];
283 err("open_scanner(%d): Scanner device not present", scn_minor
);
288 err("open_scanner(%d): Scanner is not present", scn_minor
);
293 err("open_scanner(%d): Scanner device is already open", scn_minor
);
297 init_waitqueue_head(&scn
->rd_wait_q
);
301 file
->private_data
= scn
; /* Used by the read and write metheds */
309 close_scanner(struct inode
* inode
, struct file
* file
)
311 struct scn_usb_data
*scn
;
315 scn_minor
= USB_SCN_MINOR (inode
);
317 dbg("close_scanner: scn_minor:%d", scn_minor
);
319 if (!p_scn_table
[scn_minor
]) {
320 err("close_scanner(%d): invalid scn_minor", scn_minor
);
324 scn
= p_scn_table
[scn_minor
];
328 file
->private_data
= NULL
;
336 write_scanner(struct file
* file
, const char * buffer
,
337 size_t count
, loff_t
*ppos
)
339 struct scn_usb_data
*scn
;
340 struct usb_device
*dev
;
342 ssize_t bytes_written
= 0; /* Overall count of bytes written */
347 int this_write
; /* Number of bytes to write */
348 int partial
; /* Number of bytes successfully written */
353 scn
= file
->private_data
;
355 scn_minor
= scn
->scn_minor
;
361 file
->f_dentry
->d_inode
->i_atime
= CURRENT_TIME
;
365 if (signal_pending(current
)) {
370 this_write
= (count
>= OBUF_SIZE
) ? OBUF_SIZE
: count
;
372 if (copy_from_user(scn
->obuf
, buffer
, this_write
)) {
377 result
= usb_bulk_msg(dev
,usb_sndbulkpipe(dev
, scn
->bulk_out_ep
), obuf
, this_write
, &partial
, 60*HZ
);
378 dbg("write stats(%d): result:%d this_write:%d partial:%d", scn_minor
, result
, this_write
, partial
);
380 if (result
== USB_ST_TIMEOUT
) { /* NAK -- shouldn't happen */
381 warn("write_scanner: NAK recieved.");
384 } else if (result
< 0) { /* We should not get any I/O errors */
385 warn("write_scanner(%d): funky result: %d. Please notify the maintainer.", scn_minor
, result
);
392 unsigned char cnt
, cnt_max
;
393 cnt_max
= (partial
> 24) ? 24 : partial
;
394 printk(KERN_DEBUG
"dump(%d): ", scn_minor
);
395 for (cnt
=0; cnt
< cnt_max
; cnt
++) {
396 printk("%X ", obuf
[cnt
]);
401 if (partial
!= this_write
) { /* Unable to write all contents of obuf */
406 if (partial
) { /* Data written */
409 bytes_written
+= partial
;
410 } else { /* No data written */
415 mdelay(5); /* This seems to help with SANE queries */
416 return ret
? ret
: bytes_written
;
420 read_scanner(struct file
* file
, char * buffer
,
421 size_t count
, loff_t
*ppos
)
423 struct scn_usb_data
*scn
;
424 struct usb_device
*dev
;
426 ssize_t bytes_read
; /* Overall count of bytes_read */
431 int partial
; /* Number of bytes successfully read */
432 int this_read
; /* Max number of bytes to read */
434 int rd_expire
= RD_EXPIRE
;
438 scn
= file
->private_data
;
440 scn_minor
= scn
->scn_minor
;
449 file
->f_dentry
->d_inode
->i_atime
= CURRENT_TIME
; /* Update the
455 if (signal_pending(current
)) {
460 this_read
= (count
>= IBUF_SIZE
) ? IBUF_SIZE
: count
;
462 result
= usb_bulk_msg(dev
, usb_rcvbulkpipe(dev
, scn
->bulk_in_ep
), ibuf
, this_read
, &partial
, RD_NAK_TIMEOUT
);
463 dbg("read stats(%d): result:%d this_read:%d partial:%d count:%d", scn_minor
, result
, this_read
, partial
, count
);
466 * Scanners are sometimes inheriently slow since they are mechanical
467 * in nature. USB bulk reads tend to timeout while the scanner is
468 * positioning, resetting, warming up the lamp, etc if the timeout is
469 * set too low. A very long timeout parameter for bulk reads was used
470 * to overcome this limitation, but this sometimes resulted in folks
471 * having to wait for the timeout to expire after pressing Ctrl-C from
472 * an application. The user was sometimes left with the impression
473 * that something had hung or crashed when in fact the USB read was
474 * just waiting on data. So, the below code retains the same long
475 * timeout period, but splits it up into smaller parts so that
476 * Ctrl-C's are acted upon in a reasonable amount of time.
479 if (result
== USB_ST_TIMEOUT
&& !partial
) { /* Timeout
482 if (--rd_expire
<= 0) {
483 warn("read_scanner(%d): excessive NAK's received", scn_minor
);
487 interruptible_sleep_on_timeout(&scn
->rd_wait_q
, RD_NAK_TIMEOUT
);
490 } else if ((result
< 0) && (result
!= USB_ST_DATAUNDERRUN
)) {
491 warn("read_scanner(%d): funky result:%d. Please notify the maintainer.", scn_minor
, (int)result
);
498 unsigned char cnt
, cnt_max
;
499 cnt_max
= (partial
> 24) ? 24 : partial
;
500 printk(KERN_DEBUG
"dump(%d): ", scn_minor
);
501 for (cnt
=0; cnt
< cnt_max
; cnt
++) {
502 printk("%X ", ibuf
[cnt
]);
508 if (partial
) { /* Data returned */
509 if (copy_to_user(buffer
, ibuf
, partial
)) {
513 count
-= this_read
; /* Compensate for short reads */
514 bytes_read
+= partial
; /* Keep tally of what actually was read */
522 return ret
? ret
: bytes_read
;
526 probe_scanner(struct usb_device
*dev
, unsigned int ifnum
)
528 struct scn_usb_data
*scn
;
529 struct usb_interface_descriptor
*interface
;
530 struct usb_endpoint_descriptor
*endpoint
;
537 char valid_device
= 0;
538 char have_bulk_in
, have_bulk_out
, have_intr
;
540 if (vendor
!= -1 && product
!= -1) {
541 info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor
, product
);
544 dbg("probe_scanner: USB dev address:%p", dev
);
545 dbg("probe_scanner: ifnum:%u", ifnum
);
548 * 1. Check Vendor/Product
549 * 2. Determine/Assign Bulk Endpoints
550 * 3. Determine/Assign Intr Endpoint
554 * There doesn't seem to be an imaging class defined in the USB
555 * Spec. (yet). If there is, HP isn't following it and it doesn't
556 * look like anybody else is either. Therefore, we have to test the
557 * Vendor and Product ID's to see what we have. Also, other scanners
558 * may be able to use this driver by specifying both vendor and
559 * product ID's as options to the scanner module in conf.modules.
561 * NOTE: Just because a product is supported here does not mean that
562 * applications exist that support the product. It's in the hopes
563 * that this will allow developers a means to produce applications
564 * that will support USB products.
566 * Until we detect a device which is pleasing, we silently punt.
569 for (ix
= 0; ix
< sizeof (scanner_device_ids
) / sizeof (struct scanner_device
); ix
++) {
570 if ((dev
->descriptor
.idVendor
== scanner_device_ids
[ix
].idVendor
) &&
571 (dev
->descriptor
.idProduct
== scanner_device_ids
[ix
].idProduct
)) {
576 if (dev
->descriptor
.idVendor
== vendor
&& /* User specified */
577 dev
->descriptor
.idProduct
== product
) { /* User specified */
582 return NULL
; /* We didn't find anything pleasing */
585 * After this point we can be a little noisy about what we are trying to
589 if (dev
->descriptor
.bNumConfigurations
!= 1) {
590 info("probe_scanner: Only one device configuration is supported.");
594 if (dev
->config
[0].bNumInterfaces
!= 1) {
595 info("probe_scanner: Only one device interface is supported.");
599 interface
= dev
->config
[0].interface
[ifnum
].altsetting
;
600 endpoint
= interface
[ifnum
].endpoint
;
603 * Start checking for two bulk endpoints OR two bulk endpoints *and* one
604 * interrupt endpoint. If we have an interrupt endpoint go ahead and
605 * setup the handler. FIXME: This is a future enhancement...
608 dbg("probe_scanner: Number of Endpoints:%d", (int) interface
->bNumEndpoints
);
610 if ((interface
->bNumEndpoints
!= 2) && (interface
->bNumEndpoints
!= 3)) {
611 info("probe_scanner: Only two or three endpoints supported.");
615 ep_cnt
= have_bulk_in
= have_bulk_out
= have_intr
= 0;
617 while (ep_cnt
< interface
->bNumEndpoints
) {
619 if (!have_bulk_in
&& IS_EP_BULK_IN(endpoint
[ep_cnt
])) {
621 have_bulk_in
= ep_cnt
;
622 dbg("probe_scanner: bulk_in_ep:%d", have_bulk_in
);
626 if (!have_bulk_out
&& IS_EP_BULK_OUT(endpoint
[ep_cnt
])) {
628 have_bulk_out
= ep_cnt
;
629 dbg("probe_scanner: bulk_out_ep:%d", have_bulk_out
);
633 if (!have_intr
&& IS_EP_INTR(endpoint
[ep_cnt
])) {
636 dbg("probe_scanner: intr_ep:%d", have_intr
);
639 info("probe_scanner: Undetected endpoint. Notify the maintainer.");
640 return NULL
; /* Shouldn't ever get here unless we have something weird */
645 * Perform a quick check to make sure that everything worked as it
649 switch(interface
->bNumEndpoints
) {
651 if (!have_bulk_in
|| !have_bulk_out
) {
652 info("probe_scanner: Two bulk endpoints required.");
657 if (!have_bulk_in
|| !have_bulk_out
|| !have_intr
) {
658 info("probe_scanner: Two bulk endpoints and one interrupt endpoint required.");
663 info("probe_scanner: Endpoint determination failed. Notify the maintainer.");
669 * Determine a minor number and initialize the structure associated
670 * with it. The problem with this is that we are counting on the fact
671 * that the user will sequentially add device nodes for the scanner
674 for (scn_minor
= 0; scn_minor
< SCN_MAX_MNR
; scn_minor
++) {
675 if (!p_scn_table
[scn_minor
])
679 /* Check to make sure that the last slot isn't already taken */
680 if (p_scn_table
[scn_minor
]) {
681 err("probe_scanner: No more minor devices remaining.");
685 dbg("probe_scanner: Allocated minor:%d", scn_minor
);
687 if (!(scn
= kmalloc (sizeof (struct scn_usb_data
), GFP_KERNEL
))) {
688 err("probe_scanner: Out of memory.");
691 memset (scn
, 0, sizeof(struct scn_usb_data
));
692 dbg ("probe_scanner(%d): Address of scn:%p", scn_minor
, scn
);
695 /* Ok, if we detected an interrupt EP, setup a handler for it */
697 dbg("probe_scanner(%d): Configuring IRQ handler for intr EP:%d", scn_minor
, have_intr
);
698 FILL_INT_URB(&scn
->scn_irq
, dev
,
699 usb_rcvintpipe(dev
, have_intr
),
700 &scn
->button
, 1, irq_scanner
, scn
,
701 // endpoint[(int)have_intr].bInterval);
704 if (usb_submit_urb(&scn
->scn_irq
)) {
705 err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor
);
712 /* Ok, now initialize all the relevant values */
713 if (!(scn
->obuf
= (char *)kmalloc(OBUF_SIZE
, GFP_KERNEL
))) {
714 err("probe_scanner(%d): Not enough memory for the output buffer.", scn_minor
);
718 dbg("probe_scanner(%d): obuf address:%p", scn_minor
, scn
->obuf
);
720 if (!(scn
->ibuf
= (char *)kmalloc(IBUF_SIZE
, GFP_KERNEL
))) {
721 err("probe_scanner(%d): Not enough memory for the input buffer.", scn_minor
);
726 dbg("probe_scanner(%d): ibuf address:%p", scn_minor
, scn
->ibuf
);
728 scn
->bulk_in_ep
= have_bulk_in
;
729 scn
->bulk_out_ep
= have_bulk_out
;
730 scn
->intr_ep
= have_intr
;
733 scn
->scn_minor
= scn_minor
;
736 return p_scn_table
[scn_minor
] = scn
;
740 disconnect_scanner(struct usb_device
*dev
, void *ptr
)
742 struct scn_usb_data
*scn
= (struct scn_usb_data
*) ptr
;
745 dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn
->scn_minor
);
746 usb_unlink_urb(&scn
->scn_irq
);
748 usb_driver_release_interface(&scanner_driver
,
749 &scn
->scn_dev
->actconfig
->interface
[scn
->ifnum
]);
754 dbg("disconnect_scanner: De-allocating minor:%d", scn
->scn_minor
);
755 p_scn_table
[scn
->scn_minor
] = NULL
;
761 ioctl_scanner(struct inode
*inode
, struct file
*file
,
762 unsigned int cmd
, unsigned long arg
)
764 struct usb_device
*dev
;
770 scn_minor
= USB_SCN_MINOR(inode
);
772 if (!p_scn_table
[scn_minor
]) {
773 err("ioctl_scanner(%d): invalid scn_minor", scn_minor
);
777 dev
= p_scn_table
[scn_minor
]->scn_dev
;
781 case PV8630_IOCTL_INREQUEST
:
790 if (copy_from_user(&args
, (void *)arg
, sizeof(args
)))
793 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
794 args
.request
, USB_TYPE_VENDOR
|
795 USB_RECIP_DEVICE
|USB_DIR_IN
,
796 args
.value
, args
.index
, &args
.data
,
799 dbg("ioctl_scanner(%d): inreq: args.data:%x args.value:%x args.index:%x args.request:%x\n", scn_minor
, args
.data
, args
.value
, args
.index
, args
.request
);
801 if (copy_to_user((void *)arg
, &args
, sizeof(args
)))
804 dbg("ioctl_scanner(%d): inreq: result:%d\n", scn_minor
, result
);
808 case PV8630_IOCTL_OUTREQUEST
:
816 if (copy_from_user(&args
, (void *)arg
, sizeof(args
)))
819 dbg("ioctl_scanner(%d): outreq: args.value:%x args.index:%x args.request:%x\n", scn_minor
, args
.value
, args
.index
, args
.request
);
821 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
822 args
.request
, USB_TYPE_VENDOR
|
823 USB_RECIP_DEVICE
|USB_DIR_OUT
,
824 args
.value
, args
.index
, NULL
,
827 dbg("ioctl_scanner(%d): outreq: result:%d\n", scn_minor
, result
);
836 #endif /* SCN_IOCTL */
839 file_operations usb_scanner_fops
= {
841 write
: write_scanner
,
843 ioctl
: ioctl_scanner
,
844 #endif /* SCN_IOCTL */
846 release
: close_scanner
,
850 usb_driver scanner_driver
= {
860 usb_scanner_exit(void)
862 usb_deregister(&scanner_driver
);
866 usb_scanner_init (void)
868 if (usb_register(&scanner_driver
) < 0)
871 info("USB Scanner support registered.");
875 module_init(usb_scanner_init
);
876 module_exit(usb_scanner_exit
);