patch-2.3.35 linux/drivers/usb/hp_scanner.c

Next file: linux/drivers/usb/hub.c
Previous file: linux/drivers/usb/audio.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.34/linux/drivers/usb/hp_scanner.c linux/drivers/usb/hp_scanner.c
@@ -1,333 +0,0 @@
-/* -*- linux-c -*- */
-
-/* 
- * Driver for USB HP Scanners
- *
- * David E. Nelson (dnelson@jump.net)
- * 
- * 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.
- *
- * 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 packes during bulk xfer mode.  Some testing was
- *    done with ohci-hcd but the performace 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.
- *
- * */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-#include <linux/spinlock.h>
-
-#include "usb.h"
-
-/* stall/wait timeout for scanner */
-#define NAK_TIMEOUT (HZ)
-
-/* For some reason, an IBUF_SIZE of 8192 causes REALLY big problems
- * with linux-2.3.15.  Anything more than 4k seems to not have an
- * effect on increasing performance. Anything smaller than 4k hurts
- * it.  */
-#define IBUF_SIZE 4096
-
-/* This is a scanner, so not much data is sent to it.  The largest
- * stuff may be some kind of maps and stuff but that's kinda rare.  */
-#define OBUF_SIZE 128
-
-struct hpscan_usb_data {
-	struct usb_device 	*hpscan_dev;            /* init: probe_scanner */
-	__u8			isopen;			/* nz if open */
-
-	__u8                    present;                /* Device is present on the bus */
-	char			*obuf;			/* transfer buffers */
-	char			*ibuf;		
-	wait_queue_head_t	wait_q;			/* for timeouts */
-};
-
-static struct hpscan_usb_data hpscan;
-
-static int
-open_scanner(struct inode * inode, struct file * file)
-{
-	struct hpscan_usb_data *hps = &hpscan;
-
-	if (hps->isopen) {
-		return -EBUSY;
-	}
-	hps->isopen = 1;
-
-	init_waitqueue_head(&hps->wait_q);
-
-	MOD_INC_USE_COUNT;
-
-	return 0;
-}
-
-static int
-close_scanner(struct inode * inode, struct file * file)
-{
-	struct hpscan_usb_data *hps = &hpscan;
-
-	hps->isopen = 0;
-
-	MOD_DEC_USE_COUNT;
-
-	return 0;
-}
-
-static ssize_t
-write_scanner(struct file * file, const char * buffer,
-              size_t count, loff_t *ppos)
-{
-	struct hpscan_usb_data *hps = &hpscan;
-
-	unsigned long copy_size;
-	unsigned long bytes_written = 0;
-	unsigned long partial;
-
-	int result = 0;
-	int maxretry;
-	
-	do {
-		unsigned long thistime;
-		char *obuf = hps->obuf;
-
-		thistime = copy_size = (count > OBUF_SIZE) ?  OBUF_SIZE : count;
-		if (copy_from_user(hps->obuf, buffer, copy_size))
-			return -EFAULT;
-		maxretry = 5;
-		while (thistime) {
-			if (!hps->hpscan_dev)
-				return -ENODEV;
-			if (signal_pending(current)) {
-				return bytes_written ? bytes_written : -EINTR;
-			}
-
-			result = usb_bulk_msg(hps->hpscan_dev,usb_sndbulkpipe(hps->hpscan_dev, 2), obuf, thistime, &partial, HZ*10);
-			
-			//printk(KERN_DEBUG "write stats: result:%d thistime:%lu partial:%lu\n", result, thistime, partial);
-
-			if (result == USB_ST_TIMEOUT) {	/* NAK - so hold for a while */
-				if(!maxretry--) {
-					return -ETIME;
-				}
-				interruptible_sleep_on_timeout(&hps->wait_q, NAK_TIMEOUT);
-				continue;
-			} else if (!result & partial) {
-				obuf += partial;
-				thistime -= partial;
-			} else
-				break;
-		};
-		if (result) {
-			printk("Write Whoops - %x\n", result);
-			return -EIO;
-		}
-		bytes_written += copy_size;
-		count -= copy_size;
-		buffer += copy_size;
-	} while ( count > 0 );
-	
-	return bytes_written ? bytes_written : -EIO;
-}
-
-static ssize_t
-read_scanner(struct file * file, char * buffer,
-             size_t count, loff_t *ppos)
-{
-	struct hpscan_usb_data *hps = &hpscan;
-
-	ssize_t read_count;
-
-	unsigned long partial;
-
-	int this_read;
-	int result;
-
-/* Wait for the scanner to get it's act together.  This may involve
- * resetting the head, warming up the lamp, etc.  maxretry is number
- * of seconds.  */
-	int maxretry = 30; 
-
-	char *ibuf = hps->ibuf;
-
-	read_count = 0;
-
-	while (count) {
-		if (signal_pending(current)) {
-			return read_count ? read_count : -EINTR;
-		}
-		if (!hps->hpscan_dev)
-			return -ENODEV;
-		this_read = (count > IBUF_SIZE) ? IBUF_SIZE : count;
-		
-		result = usb_bulk_msg(hps->hpscan_dev, usb_rcvbulkpipe(hps->hpscan_dev, 1), ibuf, this_read, &partial, HZ*10);
-
-		printk(KERN_DEBUG "read stats: result:%d this_read:%u partial:%lu\n", result, this_read, partial);
-		
-		if (partial) {
-			count = this_read = partial;
-		} else if (result == USB_ST_TIMEOUT || result == 15) { 	/* FIXME: 15 ??? */
-			if(!maxretry--) {
-				printk(KERN_DEBUG "read_scanner: maxretry timeout\n");
-				return -ETIME;
-			}
-			interruptible_sleep_on_timeout(&hps->wait_q, NAK_TIMEOUT);
-			continue;
-		} else if (result != USB_ST_DATAUNDERRUN) {
-			printk("Read Whoops - result:%u partial:%lu this_read:%u\n", result, partial, this_read);
-			return -EIO;
-		} else {
-			return (0);
-		}
-		
-		if (this_read) {
-			if (copy_to_user(buffer, ibuf, this_read))
-				return -EFAULT;
-			count -= this_read;
-			read_count += this_read;
-			buffer += this_read;
-		}
-	}
-	return read_count;
-}
-
-static void *
-probe_scanner(struct usb_device *dev, unsigned int ifnum)
-{
-	struct hpscan_usb_data *hps = &hpscan;
-
-	/*
-	 * Don't bother using an HP 4200C since it does NOT understand
-	 * SCL and HP isn't going to be releasing the specs any time
-	 * soon.  */
-	if (dev->descriptor.idVendor != 0x3f0 ) {
-		printk(KERN_INFO "Scanner is not an HP Scanner.\n");
-		return NULL;
-	}
-
-	if (dev->descriptor.idProduct != 0x101 && /* HP 4100C */
-	    dev->descriptor.idProduct != 0x202 && /* HP 5100C */
-            dev->descriptor.idProduct != 0x601) { /* HP 6300C */
-		printk(KERN_INFO "Scanner model not supported/tested.\n");
-		return NULL;
-	}
-	
-	printk(KERN_DEBUG "USB Scanner found at address %d\n", dev->devnum);
-	
-	hps->present = 1;
-	hps->hpscan_dev = dev;
-
-	if (!(hps->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) {
-		return NULL;
-	}
-
-	if (!(hps->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) {
-		return NULL;
-	}
-  
-	return hps;
-}
-
-static void
-disconnect_scanner(struct usb_device *dev, void *ptr)
-{
-	struct hpscan_usb_data *hps = (struct hpscan_usb_data *) ptr;
-
-	if (hps->isopen) {
-		/* better let it finish - the release will do whats needed */
-		hps->hpscan_dev = NULL;
-		return;
-	}
-	kfree(hps->ibuf);
-	kfree(hps->obuf);
-
-	hps->present = 0;
-}
-
-static struct
-file_operations usb_scanner_fops = {
-	NULL,		/* seek */
-	read_scanner,
-	write_scanner,
-	NULL,		/* readdir */
-	NULL,		/* poll */
-	NULL,    	/* ioctl */
-	NULL,		/* mmap */
-	open_scanner,
-	NULL,		/* flush */
-	close_scanner,
-	NULL,         
-	NULL,         /* fasync */
-};
-
-static struct
-usb_driver scanner_driver = {
-	"usbscanner",
-	probe_scanner,
-	disconnect_scanner,
-	{ NULL, NULL },
-	&usb_scanner_fops,
-	48
-};
-
-int
-usb_hp_scanner_init(void)
-{
-	if (usb_register(&scanner_driver) < 0)
-		return -1;
-
-	printk(KERN_DEBUG "USB Scanner support registered.\n");
-	return 0;
-}
-
-
-void
-usb_hp_scanner_cleanup(void)
-{
-	struct hpscan_usb_data *hps = &hpscan;
-
-	hps->present = 0;
-	usb_deregister(&scanner_driver);
-}
-
-#ifdef MODULE
-
-int
-init_module(void)
-{
-	return usb_hp_scanner_init();
-}
-
-void
-cleanup_module(void)
-{
-	usb_hp_scanner_cleanup();
-}
-#endif
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)