4 * Driver for USB HP Scanners
6 * David E. Nelson (dnelson@jump.net)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
27 * Developed/tested using linux-2.3.15 with minor ohci.c changes to
28 * support short packes during bulk xfer mode. Some testing was
29 * done with ohci-hcd but the performace was low. Very limited
30 * testing was performed with uhci but I was unable to get it to
31 * work. Initial relase to the linux-usb development effort.
35 #include <linux/module.h>
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/signal.h>
39 #include <linux/errno.h>
40 #include <linux/miscdevice.h>
41 #include <linux/random.h>
42 #include <linux/poll.h>
43 #include <linux/init.h>
44 #include <linux/malloc.h>
45 #include <linux/spinlock.h>
49 /* stall/wait timeout for scanner */
50 #define NAK_TIMEOUT (HZ)
52 /* For some reason, an IBUF_SIZE of 8192 causes REALLY big problems
53 * with linux-2.3.15. Anything more than 4k seems to not have an
54 * effect on increasing performance. Anything smaller than 4k hurts
56 #define IBUF_SIZE 4096
58 /* This is a scanner, so not much data is sent to it. The largest
59 * stuff may be some kind of maps and stuff but that's kinda rare. */
62 #define USB_SCANNER_MAJOR 16
64 struct hpscan_usb_data
{
65 struct usb_device
*hpscan_dev
; /* init: probe_scanner */
66 __u8 isopen
; /* nz if open */
68 __u8 present
; /* Device is present on the bus */
69 char *obuf
; /* transfer buffers */
71 wait_queue_head_t wait_q
; /* for timeouts */
74 static struct hpscan_usb_data hpscan
;
77 open_scanner(struct inode
* inode
, struct file
* file
)
79 struct hpscan_usb_data
*hps
= &hpscan
;
86 init_waitqueue_head(&hps
->wait_q
);
94 close_scanner(struct inode
* inode
, struct file
* file
)
96 struct hpscan_usb_data
*hps
= &hpscan
;
106 write_scanner(struct file
* file
, const char * buffer
,
107 size_t count
, loff_t
*ppos
)
109 struct hpscan_usb_data
*hps
= &hpscan
;
111 unsigned long copy_size
;
112 unsigned long bytes_written
= 0;
113 unsigned long partial
;
119 unsigned long thistime
;
120 char *obuf
= hps
->obuf
;
122 thistime
= copy_size
= (count
> OBUF_SIZE
) ? OBUF_SIZE
: count
;
123 if (copy_from_user(hps
->obuf
, buffer
, copy_size
))
127 if (!hps
->hpscan_dev
)
129 if (signal_pending(current
)) {
130 return bytes_written
? bytes_written
: -EINTR
;
133 result
= hps
->hpscan_dev
->bus
->op
->bulk_msg(hps
->hpscan_dev
,usb_sndbulkpipe(hps
->hpscan_dev
, 2), obuf
, thistime
, &partial
);
135 //printk(KERN_DEBUG "write stats: result:%d thistime:%lu partial:%lu\n", result, thistime, partial);
137 if (result
== USB_ST_TIMEOUT
) { /* NAK - so hold for a while */
141 interruptible_sleep_on_timeout(&hps
->wait_q
, NAK_TIMEOUT
);
143 } else if (!result
& partial
) {
150 printk("Write Whoops - %x\n", result
);
153 bytes_written
+= copy_size
;
156 } while ( count
> 0 );
158 return bytes_written
? bytes_written
: -EIO
;
162 read_scanner(struct file
* file
, char * buffer
,
163 size_t count
, loff_t
*ppos
)
165 struct hpscan_usb_data
*hps
= &hpscan
;
169 unsigned long partial
;
174 /* Wait for the scanner to get it's act together. This may involve
175 * resetting the head, warming up the lamp, etc. maxretry is number
179 char *ibuf
= hps
->ibuf
;
184 if (signal_pending(current
)) {
185 return read_count
? read_count
: -EINTR
;
187 if (!hps
->hpscan_dev
)
189 this_read
= (count
> IBUF_SIZE
) ? IBUF_SIZE
: count
;
191 result
= hps
->hpscan_dev
->bus
->op
->bulk_msg(hps
->hpscan_dev
, usb_rcvbulkpipe(hps
->hpscan_dev
, 1), ibuf
, this_read
, &partial
);
193 printk(KERN_DEBUG
"read stats: result:%d this_read:%u partial:%lu\n", result
, this_read
, partial
);
196 count
= this_read
= partial
;
197 } else if (result
== USB_ST_TIMEOUT
|| result
== 15) {
199 printk(KERN_DEBUG
"read_scanner: maxretry timeout\n");
202 interruptible_sleep_on_timeout(&hps
->wait_q
, NAK_TIMEOUT
);
204 } else if (result
!= USB_ST_DATAUNDERRUN
) {
205 printk("Read Whoops - result:%u partial:%lu this_read:%u\n", result
, partial
, this_read
);
212 if (copy_to_user(buffer
, ibuf
, this_read
))
215 read_count
+= this_read
;
223 probe_scanner(struct usb_device
*dev
)
225 struct hpscan_usb_data
*hps
= &hpscan
;
228 * Don't bother using an HP 4200C since it does NOT understand
229 * SCL and HP isn't going to be releasing the specs any time
231 if (dev
->descriptor
.idVendor
!= 0x3f0 ) {
232 printk(KERN_INFO
"Scanner is not an HP Scanner.\n");
236 if (dev
->descriptor
.idProduct
!= 0x101 && /* HP 4100C */
237 dev
->descriptor
.idProduct
!= 0x202 && /* HP 5100C */
238 dev
->descriptor
.idProduct
!= 0x601) { /* HP 6300C */
239 printk(KERN_INFO
"Scanner model not supported/tested.\n");
243 printk(KERN_DEBUG
"USB Scanner found at address %d\n", dev
->devnum
);
245 if (usb_set_configuration(dev
, dev
->config
[0].bConfigurationValue
)) {
246 printk(KERN_DEBUG
"Failed to set configuration\n");
251 hps
->hpscan_dev
= dev
;
253 if (!(hps
->obuf
= (char *)kmalloc(OBUF_SIZE
, GFP_KERNEL
))) {
257 if (!(hps
->ibuf
= (char *)kmalloc(IBUF_SIZE
, GFP_KERNEL
))) {
265 disconnect_scanner(struct usb_device
*dev
)
267 struct hpscan_usb_data
*hps
= &hpscan
;
270 /* better let it finish - the release will do whats needed */
271 hps
->hpscan_dev
= NULL
;
277 dev
->private = NULL
; /* just in case */
282 usb_driver scanner_driver
= {
290 file_operations usb_scanner_fops
= {
306 usb_hp_scanner_init(void)
310 if ((result
= register_chrdev(USB_SCANNER_MAJOR
, "usbscanner", &usb_scanner_fops
)) < 0) {
311 printk(KERN_WARNING
"hp_scanner: Cannot register device\n");
314 usb_register(&scanner_driver
);
315 printk(KERN_DEBUG
"USB Scanner support registered.\n");
321 usb_hp_scanner_cleanup(void)
323 struct hpscan_usb_data
*hps
= &hpscan
;
326 usb_deregister(&scanner_driver
);
327 unregister_chrdev(USB_SCANNER_MAJOR
, "usbscanner");
335 return usb_hp_scanner_init();
341 usb_hp_scanner_cleanup();