Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | /* * Driver for USB Scanners (linux-2.4.18) * * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson * * Brian Beattie <beattie@beattie-home.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. * * 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net> * * */ #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> #include <linux/devfs_fs_kernel.h> // #define DEBUG /* Enable this to support the older ioctl interfaces scanners that * a PV8630 Scanner-On-Chip. The prefered method is the * SCANNER_IOCTL_CTRLMSG ioctl. */ // #define PV8630 #define DRIVER_VERSION "0.4.6" #define DRIVER_DESC "USB Scanner Driver" #include <linux/usb.h> static __s32 vendor=-1, product=-1, read_timeout=0; MODULE_AUTHOR("Brian Beattie, beattie@beattie-home.net"); 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 */ { USB_DEVICE(0x04a5, 0x2060) }, /* Prisa Acerscan 620U & 640U (!)*/ { USB_DEVICE(0x04a5, 0x2040) }, /* Prisa AcerScan 620U (!) */ { USB_DEVICE(0x04a5, 0x20c0) }, /* Prisa AcerScan 1240UT */ { USB_DEVICE(0x04a5, 0x2022) }, /* Vuego Scan Brisa 340U */ { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x1a2a) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x207e) }, /* Prisa 640BU */ { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20c0) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */ { USB_DEVICE(0x04a5, 0x20b0) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x20fe) }, /* Unknown - Oliver Schwartz */ /* Agfa */ { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */ { USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */ { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ { USB_DEVICE(0x06bd, 0x0100) }, /* SnapScan Touch */ { USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */ { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ /* Canon */ { USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */ { USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */ { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ /* Colorado -- See Primax/Colorado below */ /* Epson -- See Seiko/Epson below */ /* Genius */ { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ { USB_DEVICE(0x0458, 0x2008) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2009) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2013) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2015) }, /* Unknown */ { USB_DEVICE(0x0458, 0x2016) }, /* Unknown */ /* Hewlett Packard */ { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ { USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */ { USB_DEVICE(0x03f0, 0x0105) }, /* 4200C */ { USB_DEVICE(0x03f0, 0x0305) }, /* 4300C */ { USB_DEVICE(0x03f0, 0x0705) }, /* 4400C */ { USB_DEVICE(0x03f0, 0x0102) }, /* PhotoSmart S20 */ { USB_DEVICE(0x03f0, 0x0401) }, /* 5200C */ // { USB_DEVICE(0x03f0, 0x0701) }, /* 5300C - NOT SUPPORTED - see http://www.neatech.nl/oss/HP5300C/ */ { USB_DEVICE(0x03f0, 0x0201) }, /* 6200C */ { USB_DEVICE(0x03f0, 0x0601) }, /* 6300C */ { USB_DEVICE(0x03f0, 0x605) }, /* 2200C */ /* iVina */ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ /* Lifetec */ { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ /* Memorex */ { USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */ /* Microtek -- No longer supported - 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(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */ /* Mustek */ { USB_DEVICE(0x055f, 0x0001) }, /* 1200 CU */ { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */ { USB_DEVICE(0x055f, 0x0002) }, /* 600 CU */ { USB_DEVICE(0x055f, 0x0873) }, /* 600 USB */ { USB_DEVICE(0x055f, 0x0003) }, /* 1200 USB */ { USB_DEVICE(0x055f, 0x0006) }, /* 1200 UB */ { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */ { USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */ { USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */ { USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */ { USB_DEVICE(0x05d8, 0x4002) }, /* 1200 CU and 1200 UB Plus */ /* Plustek */ { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */ { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */ { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ { USB_DEVICE(0x0461, 0x0301) }, /* G2E-300 #1 */ { USB_DEVICE(0x0461, 0x0381) }, /* ReadyScan 636i */ { USB_DEVICE(0x0461, 0x0302) }, /* G2-300 #2 */ { USB_DEVICE(0x0461, 0x0382) }, /* G2-600 #2 */ { USB_DEVICE(0x0461, 0x0303) }, /* G2E-300 #2 */ { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */ { USB_DEVICE(0x0461, 0x0340) }, /* Colorado USB 9600 */ // { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 - undetected endpoint */ { USB_DEVICE(0x0461, 0x0341) }, /* Colorado 600u */ { USB_DEVICE(0x0461, 0x0361) }, /* Colorado 1200u */ /* Relisis */ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ /* Seiko/Epson Corp. */ { USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */ { USB_DEVICE(0x04b8, 0x0103) }, /* Perfection 610 */ { USB_DEVICE(0x04b8, 0x0104) }, /* Perfection 1200U and 1200Photo*/ { USB_DEVICE(0x04b8, 0x0106) }, /* Stylus Scan 2500 */ { USB_DEVICE(0x04b8, 0x0107) }, /* Expression 1600 */ { 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(0x04a9, 0x2204) }, /* FB630U */ { 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, 0x011e) }, /* Perfection 1660 Photo */ /* Umax */ { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */ { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */ { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */ { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */ /* Visioneer */ { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0211) }, /* OneTouch 7600 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 */ { } /* 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) minor((X)->i_rdev) - SCN_BASE_MNR #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 */ /* FIXME: These are NOT registered ioctls()'s */ #ifdef PV8630 #define PV8630_IOCTL_INREQUEST 69 #define PV8630_IOCTL_OUTREQUEST 70 #endif /* PV8630 */ /* 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) #ifdef CONFIG_USB_DYNAMIC_MINORS #define SCN_MAX_MNR 256 #define SCN_BASE_MNR 0 #else #define SCN_MAX_MNR 16 /* We're allocated 16 minors */ #define SCN_BASE_MNR 48 /* USB Scanners start at minor 48 */ #endif static DECLARE_MUTEX (scn_mutex); /* Initializes to unlocked */ struct scn_usb_data { struct usb_device *scn_dev; devfs_handle_t devfs; /* devfs device */ 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. */ }; extern devfs_handle_t usb_devfs_handle; static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, /* ... */}; static struct usb_driver scanner_driver; |