1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 1997 Andreas Czechanowski and David Mosberger
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 This file implements the Mustek-proprietary SCSI-over-parallel-port
40 interface. */
41
42 #include "../include/sane/config.h"
43
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
47
48 #include <sys/types.h>
49
50 #include "../include/sane/sanei_directio.h"
51
52 #include "../include/sane/sane.h"
53 #include "../include/sane/sanei.h"
54 #include "../include/sane/sanei_ab306.h"
55
56 #if (defined(HAVE_IOPERM) || defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(IO_SUPPORT_MISSING)
57
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <limits.h>
61 #include <signal.h>
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <sys/types.h>
66 #include <sys/wait.h>
67 #include <unistd.h>
68
69 #include "../include/sane/saneopts.h"
70
71 #define BACKEND_NAME sanei_ab306
72 #include "../include/sane/sanei_debug.h"
73
74 #define PORT_DEV "/dev/port"
75 #define AB306_CIO 0x379 /* control i/o port */
76
77 #if defined(__FreeBSD__) || defined(__DragonFly__)
78 static int dev_io_fd = 0;
79 #endif
80
81 typedef struct port
82 {
83 u_long base; /* i/o base address */
84 int port_fd; /* >= 0 when using /dev/port */
85 u_int lstat;
86 u_int in_use : 1, /* port in use? */
87 active : 1; /* port was active at some point */
88 }
89 Port;
90
91 static Port port[] =
92 {
93 {0x26b, -1, 0, 0, 0},
94 {0x2ab, -1, 0, 0, 0},
95 {0x2eb, -1, 0, 0, 0},
96 {0x22b, -1, 0, 0, 0},
97 {0x32b, -1, 0, 0, 0},
98 {0x36b, -1, 0, 0, 0},
99 {0x3ab, -1, 0, 0, 0},
100 {0x3eb, -1, 0, 0, 0}
101 };
102
103 static const SANE_Byte wakeup[] =
104 {
105 0x47, 0x55, 0x54, 0x53, 0x02, 0x01, 0x80
106 };
107
108 static u_char cdb_sizes[8] =
109 {
110 6, 10, 10, 12, 12, 12, 10, 10
111 };
112 #define CDB_SIZE(opcode) cdb_sizes[(((opcode) >> 5) & 7)]
113
114 static void
ab306_outb(Port * p,u_long addr,u_char val)115 ab306_outb (Port *p, u_long addr, u_char val)
116 {
117
118 if (p->port_fd >= 0)
119 {
120 if ((u_long) lseek (p->port_fd, addr, SEEK_SET) != addr)
121 return;
122 if (write (p->port_fd, &val, 1) != 1)
123 return;
124 }
125 else
126 sanei_outb (addr, val);
127 }
128
129 static int
ab306_inb(Port * p,u_long addr)130 ab306_inb (Port *p, u_long addr)
131 {
132 u_char ch;
133
134 if (p->port_fd >= 0)
135 {
136 if ((u_long) lseek (p->port_fd, addr, SEEK_SET) != addr)
137 return -1;
138 if (read (p->port_fd, &ch, 1) != 1)
139 return -1;
140 return ch;
141 }
142 else
143 return sanei_inb (addr);
144 }
145
146 /* Send a single command-byte over the AB306N-interface. */
147 static void
ab306_cout(Port * p,int val)148 ab306_cout (Port *p, int val)
149 {
150 u_long base = p->base;
151
152 while ((ab306_inb (p, base + 1) & 0x80)); /* wait for dir flag */
153 ab306_outb (p, base, val);
154 ab306_outb (p, base + 1, 0xe0);
155 while ((ab306_inb (p, base + 1) & 0x80) == 0); /* wait for ack */
156 ab306_outb (p, base + 1, 0x60);
157 }
158
159 /* Read a single response-byte from the SANEI_AB306N-interface. */
160 static int
ab306_cin(Port * p)161 ab306_cin (Port *p)
162 {
163 u_long base = p->base;
164 u_char val;
165
166 while ((ab306_inb (p, base + 1) & 0x80) == 0); /* wait for dir flag */
167 val = ab306_inb (p, base);
168 ab306_outb (p, base + 1, 0xe0); /* ack received byte */
169 while (ab306_inb (p, base + 1) & 0x80);
170 ab306_outb (p, base + 1, 0x60); /* reset ack */
171 return val;
172 }
173
174 static SANE_Status
ab306_write(Port * p,const void * buf,size_t len)175 ab306_write (Port *p, const void *buf, size_t len)
176 {
177 u_long base = p->base;
178 u_int i;
179 int cksum = 0;
180
181 DBG(3, "ab306_write: waiting for scanner to be ready %02x\n",
182 ab306_inb (p, base + 1));
183 while ((ab306_inb (p, base + 1) & 0x20) == 0);
184 usleep (10000);
185
186 DBG(4, "ab306_write: writing data\n");
187 for (i = 0; i < len; ++i)
188 {
189 ab306_cout (p, ((const u_char *) buf)[i]);
190 cksum += ((const u_char *) buf)[i];
191 }
192
193 DBG(4, "ab306_write: writing checksum\n");
194 ab306_cout (p, -cksum & 0xff);
195
196 DBG(3, "ab306_write: waiting for scanner to be NOT ready %02x\n",
197 ab306_inb (p, base + 1));
198 while ((ab306_inb (p, base + 1) & 0x20) != 0);
199 usleep (10000);
200
201 DBG(4, "ab306_write: reading ack\n");
202 cksum = ab306_cin (p);
203 if (cksum != 0xa5)
204 {
205 DBG(0, "ab306_write: checksum error (%02x!=a5) when sending command!\n",
206 cksum);
207 return SANE_STATUS_IO_ERROR;
208 }
209 return SANE_STATUS_GOOD;
210 }
211
212 /* Abort a running scan by pulling C6 low for a while. */
213 static void
ab306_abort(Port * p)214 ab306_abort (Port *p)
215 {
216 ab306_outb (p, p->base + 1, 0x20);
217 while ((ab306_inb (p, p->base + 1) & 0x80));
218 ab306_outb (p, p->base + 1, 0x60);
219 }
220
221 /* Open the device, <dev> must contain a valid port number (as string)
222 returns port number and I/O method in <*fdp> (not a file
223 descriptor) turns the scanner on setting C5 and C6. */
224 SANE_Status
sanei_ab306_open(const char * dev,int * fdp)225 sanei_ab306_open (const char *dev, int *fdp)
226 {
227 static int first_time = 1;
228 SANE_Status status;
229 u_char byte;
230 u_long base;
231 char *end;
232 int i, j;
233
234 if (first_time)
235 {
236 first_time = 0;
237 DBG_INIT();
238 }
239
240 base = strtol (dev, &end, 0);
241 if (end == dev || *end)
242 {
243 DBG(1, "sanei_ab306_open: `%s' is not a valid port number\n", dev);
244 return SANE_STATUS_INVAL;
245 }
246
247 for (i = 0; i < NELEMS(port); ++i)
248 if (port[i].base == base)
249 break;
250
251 if (i >= NELEMS(port))
252 {
253 DBG(1, "sanei_ab306_open: %lx is not a valid base address\n", base);
254 return SANE_STATUS_INVAL;
255 }
256
257 if (port[i].in_use)
258 {
259 DBG(1, "sanei_ab306_open: port %lx is already in use\n", base);
260 return SANE_STATUS_DEVICE_BUSY;
261 }
262
263 status = sanei_ab306_get_io_privilege (i);
264
265 #if defined(__FreeBSD__) || defined(__DragonFly__)
266 status = sanei_ab306_get_io_privilege (i);
267 if (status != SANE_STATUS_GOOD)
268 return status;
269
270 DBG(1, "sanei_ab306_ioport: using inb/outb access\n");
271 for (j = 0; j < NELEMS(wakeup); ++j)
272 {
273 byte = wakeup[j];
274 if (j == NELEMS(wakeup) - 1)
275 byte |= i;
276 sanei_outb (AB306_CIO, byte);
277 }
278
279 #else /* !defined(__FreeBSD__) */
280 if (sanei_ioperm (AB306_CIO, 1, 1) != 0)
281 {
282 DBG(1, "sanei_ab306_ioport: using /dev/port access\n");
283 if (port[i].port_fd < 0)
284 port[i].port_fd = open (PORT_DEV, O_RDWR);
285 if (port[i].port_fd < 0)
286 return SANE_STATUS_IO_ERROR;
287 for (j = 0; j < NELEMS(wakeup); ++j)
288 {
289 if (lseek (port[i].port_fd, AB306_CIO, SEEK_SET) != AB306_CIO)
290 return SANE_STATUS_IO_ERROR;
291 byte = wakeup[j];
292 if (j == NELEMS(wakeup) - 1)
293 byte |= i;
294 if (write (port[i].port_fd, &byte, 1) != 1)
295 return SANE_STATUS_IO_ERROR;
296 }
297 }
298 else
299 {
300 DBG(1, "sanei_ab306_ioport: using inb/outb access\n");
301 for (j = 0; j < NELEMS(wakeup); ++j)
302 {
303 byte = wakeup[j];
304 if (j == NELEMS(wakeup) - 1)
305 byte |= i;
306 sanei_outb (AB306_CIO, byte);
307 }
308 status = sanei_ab306_get_io_privilege (i);
309 if (status != SANE_STATUS_GOOD)
310 return status;
311 }
312 #endif /* !defined(__FreeBSD__) */
313
314 ab306_outb (port + i, port[i].base + 1, 0x60);
315 port[i].in_use = 1;
316 port[i].active = 1;
317 *fdp = i;
318 return SANE_STATUS_GOOD;
319 }
320
321 void
sanei_ab306_close(int fd)322 sanei_ab306_close (int fd)
323 {
324 Port *p = port + fd;
325
326 if (p->in_use)
327 {
328 if (p->port_fd >= 0)
329 {
330 close (p->port_fd);
331 p->port_fd = -1;
332 }
333 p->in_use = 0;
334 }
335 }
336
337 /* Get I/O permission to the configuration port and the desired
338 operating ports. */
339 SANE_Status
sanei_ab306_get_io_privilege(int fd)340 sanei_ab306_get_io_privilege (int fd)
341 {
342 if (port[fd].port_fd < 0)
343 {
344 #if defined(__FreeBSD__) || defined(__DragonFly__)
345 if (dev_io_fd == 0)
346 dev_io_fd = open ("/dev/io", O_RDONLY);
347 if (dev_io_fd < 0)
348 return SANE_STATUS_IO_ERROR;
349 #else /* !defined(__FreeBSD__) */
350 if (sanei_ioperm (port[fd].base, 3, 1) != 0)
351 return SANE_STATUS_IO_ERROR;
352 #endif /* !defined(__FreeBSD__) */
353 }
354 return SANE_STATUS_GOOD;
355 }
356
357 /* Send a command via the SANEI_AB306N-interface, get response when
358 <dst_size> is > 0. */
359 SANE_Status
sanei_ab306_cmd(int fd,const void * src,size_t src_size,void * dst,size_t * dst_size)360 sanei_ab306_cmd (int fd, const void *src, size_t src_size,
361 void *dst, size_t * dst_size)
362 {
363 Port *p = port + fd;
364 const u_char *cp = src;
365 size_t cdb_size = CDB_SIZE(cp[0]);
366 SANE_Status status;
367 u_char byte;
368
369 /* If this is a READ_SCANNED_DATA command, reset lstat: */
370 switch (cp[0])
371 {
372 case 0x08: /* scsi READ_SCANNED_DATA command */
373 /* Initialize lstat to the current status, because we need bit 4
374 (0x10) as toggle bit for reading lines. */
375 p->lstat = 0x34;
376 break;
377
378 case 0x1b: /* scsi START_STOP command */
379 if (!cp[4])
380 {
381 /* it's a STOP */
382 ab306_abort (p);
383 return SANE_STATUS_GOOD;
384 }
385 break;
386
387 default:
388 break;
389 }
390
391 status = ab306_write (p, src, 6);
392 if (status != SANE_STATUS_GOOD)
393 return status;
394
395 if (src_size > cdb_size)
396 {
397 status = ab306_write (p, cp + cdb_size, src_size - cdb_size);
398 if (status != SANE_STATUS_GOOD)
399 return status;
400 }
401
402 if (dst && *dst_size > 0)
403 {
404 u_int i, cksum = 0;
405
406 DBG(3, "sanei_ab306_cmd: waiting for scanner to be NOT ready %02x\n",
407 ab306_inb (p, p->base + 1));
408 while ((ab306_inb (p, p->base + 1) & 0x20) != 0);
409
410 for (i = 0; i < *dst_size; i++)
411 {
412 byte = ab306_cin (p);
413 cksum += byte;
414 ((u_char *) dst)[i] = byte;
415 }
416 cksum += ab306_cin (p); /* add in checksum */
417
418 if ((cksum & 0xff) != 0)
419 {
420 DBG(0, "sanei_ab306_cmd: checksum error (%2x!=0) when receiving "
421 "after command!\n", cksum);
422 return SANE_STATUS_IO_ERROR;
423 }
424 ab306_cout (p, 0); /* dummy byte (will be discarded) */
425 }
426 return SANE_STATUS_GOOD;
427 }
428
429 /* Read scan-data from the AB306N-device. Read <lines> lines, of which
430 every one has <bpl> bytes. */
431 SANE_Status
sanei_ab306_rdata(int fd,int planes,SANE_Byte * buf,int lines,int bpl)432 sanei_ab306_rdata (int fd, int planes, SANE_Byte * buf, int lines, int bpl)
433 {
434 Port *p = port + fd;
435 int lcnt, pcnt, bcnt, xmax;
436 int nstat;
437
438 DBG(2, "sanei_ab306_rdata: start\n");
439
440 /* lstat should be set by a call to sanei_ab306_init_toggle before ! */
441 while ((ab306_inb (p, p->base + 1) & 0x80) == 0);
442 /* the lines-loop: */
443 for (lcnt = 0; lcnt < lines; ++lcnt)
444 {
445 /* the planes-loop: */
446 for (pcnt = 0; pcnt < planes; ++pcnt)
447 {
448 xmax = bpl / planes;
449 do
450 nstat = ab306_inb (p, p->base + 1);
451 while (((p->lstat ^ nstat) & 0x10) == 0);
452
453 if (p->port_fd >= 0)
454 {
455 /* the pixel-loop: */
456 for (bcnt = 0; bcnt < xmax; bcnt++)
457 {
458 if ((u_long) lseek (p->port_fd, p->base, SEEK_SET) != p->base)
459 return SANE_STATUS_IO_ERROR;
460 if (read (p->port_fd, buf, 1) != 1)
461 return SANE_STATUS_IO_ERROR;
462 ++buf;
463 }
464 }
465 else
466 {
467 /* the pixel-loop: */
468 for (bcnt = 0; bcnt < xmax; bcnt++)
469 {
470 *(u_char *) buf = sanei_inb (p->base);
471 ++buf;
472 }
473 }
474 p->lstat = nstat;
475 }
476 }
477 DBG(2, "sanei_ab306_rdata: done\n");
478 return SANE_STATUS_GOOD;
479 }
480
481 void
sanei_ab306_exit(void)482 sanei_ab306_exit (void)
483 {
484 int i;
485
486 for (i = 0; i < NELEMS(port); ++i)
487 if (port[i].active)
488 {
489 port[i].active = 0;
490 /* power off the scanner: */
491 ab306_outb (port + i, port[i].base + 1, 0x00);
492 }
493 #if defined(__FreeBSD) || defined(__DragonFly__)
494 if (dev_io_fd >0)
495 close (dev_io_fd);
496 #endif /* defined(__FreeBSD__) */
497 }
498
499 SANE_Status
sanei_ab306_test_ready(int fd)500 sanei_ab306_test_ready (int fd)
501 {
502 Port *p = port + fd;
503 u_char byte;
504
505 byte = ab306_inb (p, p->base + 1);
506 if (byte & 0x20)
507 return SANE_STATUS_GOOD;
508
509 return SANE_STATUS_DEVICE_BUSY;
510 }
511
512 #else /* !HAVE_IOPERM */
513
514 SANE_Status
sanei_ab306_open(const char * devname,int * fdp)515 sanei_ab306_open (const char *devname, int *fdp)
516 {
517 *fdp = -1;
518 return SANE_STATUS_INVAL;
519 }
520
521 void
sanei_ab306_close(int fd)522 sanei_ab306_close (int fd)
523 {
524 }
525
526 void
sanei_ab306_exit(void)527 sanei_ab306_exit (void)
528 {
529 }
530
531 SANE_Status
sanei_ab306_get_io_privilege(int fd)532 sanei_ab306_get_io_privilege (int fd)
533 {
534 return SANE_STATUS_INVAL;
535 }
536
537 SANE_Status
sanei_ab306_test_ready(int fd)538 sanei_ab306_test_ready (int fd)
539 {
540 return SANE_STATUS_GOOD; /* non-existent device is always ready... */
541 }
542
543 SANE_Status
sanei_ab306_cmd(int fd,const void * src,size_t src_size,void * dst,size_t * dst_size)544 sanei_ab306_cmd (int fd, const void *src, size_t src_size,
545 void *dst, size_t *dst_size)
546 {
547 return SANE_STATUS_INVAL;
548 }
549
550 SANE_Status
sanei_ab306_rdata(int fd,int planes,SANE_Byte * buf,int lines,int bpl)551 sanei_ab306_rdata (int fd, int planes, SANE_Byte *buf, int lines, int bpl)
552 {
553 return SANE_STATUS_INVAL;
554 }
555
556 #endif /* !HAVE_IOPERM */
557