Import 2.3.18pre1
[davej-history.git] / drivers / usb / hp_scanner.c
blobc7a5af555d04481ba21433250d84b7d534332e46
1 /* -*- linux-c -*- */
3 /*
4 * Driver for USB HP Scanners
6 * David E. Nelson (dnelson@jump.net)
7 *
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).
24 * History
25 * 0.1 8/31/1999
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.
33 * */
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>
47 #include "usb.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
55 * it. */
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. */
60 #define OBUF_SIZE 128
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 */
70 char *ibuf;
71 wait_queue_head_t wait_q; /* for timeouts */
74 static struct hpscan_usb_data hpscan;
76 static int
77 open_scanner(struct inode * inode, struct file * file)
79 struct hpscan_usb_data *hps = &hpscan;
81 if (hps->isopen) {
82 return -EBUSY;
84 hps->isopen = 1;
86 init_waitqueue_head(&hps->wait_q);
88 MOD_INC_USE_COUNT;
90 return 0;
93 static int
94 close_scanner(struct inode * inode, struct file * file)
96 struct hpscan_usb_data *hps = &hpscan;
98 hps->isopen = 0;
100 MOD_DEC_USE_COUNT;
102 return 0;
105 static ssize_t
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;
115 int result = 0;
116 int maxretry;
118 do {
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))
124 return -EFAULT;
125 maxretry = 5;
126 while (thistime) {
127 if (!hps->hpscan_dev)
128 return -ENODEV;
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 */
138 if(!maxretry--) {
139 return -ETIME;
141 interruptible_sleep_on_timeout(&hps->wait_q, NAK_TIMEOUT);
142 continue;
143 } else if (!result & partial) {
144 obuf += partial;
145 thistime -= partial;
146 } else
147 break;
149 if (result) {
150 printk("Write Whoops - %x\n", result);
151 return -EIO;
153 bytes_written += copy_size;
154 count -= copy_size;
155 buffer += copy_size;
156 } while ( count > 0 );
158 return bytes_written ? bytes_written : -EIO;
161 static ssize_t
162 read_scanner(struct file * file, char * buffer,
163 size_t count, loff_t *ppos)
165 struct hpscan_usb_data *hps = &hpscan;
167 ssize_t read_count;
169 unsigned long partial;
171 int this_read;
172 int result;
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
176 * of seconds. */
177 int maxretry = 30;
179 char *ibuf = hps->ibuf;
181 read_count = 0;
183 while (count) {
184 if (signal_pending(current)) {
185 return read_count ? read_count : -EINTR;
187 if (!hps->hpscan_dev)
188 return -ENODEV;
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);
195 if (partial) {
196 count = this_read = partial;
197 } else if (result == USB_ST_TIMEOUT || result == 15) {
198 if(!maxretry--) {
199 printk(KERN_DEBUG "read_scanner: maxretry timeout\n");
200 return -ETIME;
202 interruptible_sleep_on_timeout(&hps->wait_q, NAK_TIMEOUT);
203 continue;
204 } else if (result != USB_ST_DATAUNDERRUN) {
205 printk("Read Whoops - result:%u partial:%lu this_read:%u\n", result, partial, this_read);
206 return -EIO;
207 } else {
208 return (0);
211 if (this_read) {
212 if (copy_to_user(buffer, ibuf, this_read))
213 return -EFAULT;
214 count -= this_read;
215 read_count += this_read;
216 buffer += this_read;
219 return read_count;
222 static int
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
230 * soon. */
231 if (dev->descriptor.idVendor != 0x3f0 ) {
232 printk(KERN_INFO "Scanner is not an HP Scanner.\n");
233 return -1;
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");
240 return -1;
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");
247 return -1;
250 hps->present = 1;
251 hps->hpscan_dev = dev;
253 if (!(hps->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) {
254 return -ENOMEM;
257 if (!(hps->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) {
258 return -ENOMEM;
261 return 0;
264 static void
265 disconnect_scanner(struct usb_device *dev)
267 struct hpscan_usb_data *hps = &hpscan;
269 if (hps->isopen) {
270 /* better let it finish - the release will do whats needed */
271 hps->hpscan_dev = NULL;
272 return;
274 kfree(hps->ibuf);
275 kfree(hps->obuf);
277 dev->private = NULL; /* just in case */
278 hps->present = 0;
281 static struct
282 usb_driver scanner_driver = {
283 "usbscanner",
284 probe_scanner,
285 disconnect_scanner,
286 { NULL, NULL }
289 static struct
290 file_operations usb_scanner_fops = {
291 NULL, /* seek */
292 read_scanner,
293 write_scanner,
294 NULL, /* readdir */
295 NULL, /* poll */
296 NULL, /* ioctl */
297 NULL, /* mmap */
298 open_scanner,
299 NULL, /* flush */
300 close_scanner,
301 NULL,
302 NULL, /* fasync */
306 usb_hp_scanner_init(void)
308 int result;
310 if ((result = register_chrdev(USB_SCANNER_MAJOR, "usbscanner", &usb_scanner_fops)) < 0) {
311 printk(KERN_WARNING "hp_scanner: Cannot register device\n");
312 return result;
314 usb_register(&scanner_driver);
315 printk(KERN_DEBUG "USB Scanner support registered.\n");
316 return 0;
320 void
321 usb_hp_scanner_cleanup(void)
323 struct hpscan_usb_data *hps = &hpscan;
325 hps->present = 0;
326 usb_deregister(&scanner_driver);
327 unregister_chrdev(USB_SCANNER_MAJOR, "usbscanner");
330 #ifdef MODULE
333 init_module(void)
335 return usb_hp_scanner_init();
338 void
339 cleanup_module(void)
341 usb_hp_scanner_cleanup();
343 #endif