xref: /third_party/backends/backend/st400.c (revision 141cc406)
1/*
2vim: ts=4 sw=4 noexpandtab
3 */
4
5/* st400.c - SANE module for Siemens ST400 flatbed scanner
6
7   Copyright (C) 1999-2000 Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
8
9   This file is part of the SANE package.
10
11   This program is free software; you can redistribute it and/or
12   modify it under the terms of the GNU General Public License as
13   published by the Free Software Foundation; either version 2 of the
14   License, or (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful, but
17   WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19   General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
24   As a special exception, the authors of SANE give permission for
25   additional uses of the libraries contained in this release of SANE.
26
27   The exception is that, if you link a SANE library with other files
28   to produce an executable, this does not by itself cause the
29   resulting executable to be covered by the GNU General Public
30   License.  Your use of that executable is in no way restricted on
31   account of linking the SANE library code into it.
32
33   This exception does not, however, invalidate any other reasons why
34   the executable file might be covered by the GNU General Public
35   License.
36
37   *************************************************************************
38
39   This file implements a SANE backend for the Siemens ST400 flatbed scanner.
40
41   Unfortunately, I have no documentation for this scanner.  All I have
42   is an old PC Pascal source and an Amiga C source (derived from the
43   Pascal source).  Both are quite primitive, and so is this backend...
44
45   Version numbers of this backend follow SANE version scheme:  The first
46   number is SANE's major version (i.e. the version of the SANE API that
47   this backend conforms to), the second is the version of this backend.
48   Thus, version 1.2 is the second release of this backend for SANE v1.
49
50   1.0 (08 Mar 1999): First public release, for SANE v1.0.0
51   1.1 (12 Mar 1999): Fixed some stupid bugs (caused crash if accessed via net).
52   1.2 (23 Apr 1999): Oops, got threshold backwards.
53                      Tested with SANE 1.0.1.
54   1.3 (27 Apr 1999): Seems the separate MODE SELECT to switch the light on
55                      is not necessary.  Removed debugging output via syslog,
56                      it was only used to track down a bug in saned.  Some
57					  minor cleanups.  Removed illegal version check (only
58					  frontends should do this).  Made "maxread" and "delay"
59					  config options instead of compile-time #define's.
60					  Added model check via INQUIRY, and related changes.
61   1.4 (29 Jun 1999): New config options to configure scanner models.
62					  See st400.conf for details.  These options are only
63					  for testing, and will be removed someday.
64   1.5 (26 Mar 2000): Check for optnum >= 0.  Fixed some hardcoded paths in
65   					  manpage.  ST400 locks up with reads >64KB - added
66					  maxread entry to model struct.  Tested with SANE 1.0.2.
67   1.6 (08 Apr 2000): Minor cleanups.
68   1.7 (18 Dec 2001): Security fix from Tim Waugh.  Dump inquiry data to
69					  "$HOME/st400.dump" instead of "/tmp/st400.dump".
70*/
71
72#include "../include/sane/config.h"
73
74#include <sys/types.h>
75#include <stdlib.h>
76#include <string.h>
77#include <unistd.h>
78#include <ctype.h>
79#include "../include/sane/sane.h"
80#include "../include/sane/sanei.h"
81#include "../include/sane/sanei_config.h"
82#include "../include/sane/saneopts.h"
83#include "../include/sane/sanei_scsi.h"
84#include "../include/sane/sanei_debug.h"
85#ifndef PATH_MAX
86#	define PATH_MAX	1024
87#endif
88
89#define BACKEND_NAME	st400
90#include "../include/sane/sanei_backend.h"
91
92#include "st400.h"
93
94/* supported scanners */
95static ST400_Model st400_models[] = {
96{ 8, "SIEMENS", 16, "ST 400", 6, 0x200000UL, 65536UL, NULL, "Siemens", "ST400", "flatbed scanner" },
97{ 8, "SIEMENS", 16, "ST 800", 6, 0x200000UL, 65536UL, NULL, "Siemens", "ST800", "flatbed scanner" },	/* to be tested */
98{ 0, "", 0, "", 6, 0x200000UL, 65536UL, NULL, "Unknown", "untested", "flatbed scanner" },	/* matches anything */
99
100	/* must be last */
101	{ 0, NULL, 0, NULL, 0, 0, 0, NULL, NULL, NULL, NULL }
102};
103
104
105static ST400_Device *st400_devices = NULL;
106static unsigned int st400_num_devices = 0;
107static const SANE_Device **st400_device_array = NULL;
108/* The array pointer must stay valid between calls to sane_get_devices().
109 * So we cannot modify or deallocate the array when a new device is attached
110 * - until the next call to sane_get_devices().  The array_valid bit indicates
111 * whether the array is still in sync with the device list or not (if new
112 * devices have been attached in the meantime).
113 */
114static struct {
115	unsigned array_valid: 1;
116} st400_status = { 0 };
117static size_t st400_maxread = 0;
118static size_t st400_light_delay = 0;
119static int st400_dump_data = 0;
120
121/* SCSI commands */
122#define CMD_TEST_UNIT_READY		0x00
123#define CMD_INQUIRY				0x12
124#define CMD_MODE_SELECT			0x15
125#define CMD_RESERVE				0x16
126#define CMD_RELEASE				0x17
127#define CMD_START_STOP			0x1b
128#define CMD_SET_WINDOW			0x24
129#define CMD_READ_CAPACITY		0x25	/* get window settings - unused */
130#define CMD_READ10				0x28
131
132/* prototypes */
133static SANE_Status st400_inquiry( int fd, ST400_Model **modelP );
134static SANE_Status st400_sense_handler( int fd, SANE_Byte *result, void *arg );
135static SANE_Status st400_attach( const char *devname, ST400_Device **devP );
136static SANE_Status st400_attach_one( const char *device );
137static void st400_init_options( ST400_Device *dev );
138static SANE_Status st400_set_window( ST400_Device *dev );
139static SANE_Status st400_wait_ready( int fd );
140static SANE_Status st400_cmd6( int fd, SANE_Byte cmd, SANE_Byte ctrl );
141static SANE_Status st400_read10( int fd, SANE_Byte *buf, size_t *lenP );
142static void st400_reset_options( ST400_Device *dev );
143
144#undef min
145#define min(a, b)		((a) < (b) ? (a) : (b))
146#define maxval(bpp)		((1<<(bpp))-1)
147
148/* Debugging levels */
149#define DERR	0		/* errors */
150#define DINFO	1		/* misc information */
151#define DSENSE	2		/* SCSI sense */
152#define DSCSI	3		/* SCSI commands */
153#define DOPT	4		/* option control */
154#define DVAR	5		/* important variables */
155#define DCODE	6		/* code flow */
156
157
158/*********************************************************************
159 * low-level SCSI functions
160 *********************************************************************/
161
162#define set24(m, x)	do {										\
163	*((SANE_Byte *)(m)+0) = (SANE_Byte)(((x) >> 16) & 0xff);	\
164	*((SANE_Byte *)(m)+1) = (SANE_Byte)(((x) >> 8) & 0xff);		\
165	*((SANE_Byte *)(m)+2) = (SANE_Byte)(((x) >> 0) & 0xff);		\
166} while(0)
167#define set16(m, x)	do {										\
168	*((SANE_Byte *)(m)+0) = (SANE_Byte)(((x) >> 8) & 0xff);		\
169	*((SANE_Byte *)(m)+1) = (SANE_Byte)(((x) >> 0) & 0xff);		\
170} while(0)
171
172
173static int str_at_offset(char *str, size_t offset, unsigned char *data)
174{
175	size_t len;
176
177	len = strlen(str);
178	return !strncmp((char *)&data[offset], str, len);
179}
180
181
182static SANE_Status
183st400_inquiry( int fd, ST400_Model **modelP )
184{
185	struct { SANE_Byte cmd, lun, reserved[2], tr_len, ctrl; } scsi_cmd;
186/*
187	struct {
188		SANE_Byte devtype, devqual, version;
189		SANE_Byte reserved1, additionallength;
190		SANE_Byte reserved2[2], flags;
191		SANE_Byte vendor[8], product[16], release[4];
192		SANE_Byte reserved3[60];
193	} inqdata;
194*/
195	struct { SANE_Byte bytes[96]; } inqdata;
196
197	size_t inqlen;
198	SANE_Status status;
199	ST400_Model *model;
200
201	inqlen = sizeof(inqdata);
202	memset(&scsi_cmd, 0, sizeof(scsi_cmd));
203	scsi_cmd.cmd = CMD_INQUIRY;
204	scsi_cmd.tr_len = inqlen;
205
206	DBG(DSCSI, "SCSI: sending INQUIRY (%lu bytes)\n", (u_long)inqlen);
207	status = sanei_scsi_cmd(fd, &scsi_cmd, sizeof(scsi_cmd), &inqdata, &inqlen);
208	DBG(DSCSI, "SCSI: result=%s (%lu bytes)\n", sane_strstatus(status), (u_long)inqlen);
209	if( status != SANE_STATUS_GOOD )
210		return status;
211
212	if( st400_dump_data ) {
213		const char *home = getenv ("HOME");
214		char basename[] = "st400.dump";
215		char *name;
216		FILE *fp;
217
218		if (home) {
219			name = malloc (strlen (home) + sizeof (basename) + 1);
220			sprintf (name, "%s/%s", home, basename);
221		} else name = basename;
222
223		fp = fopen(name, "ab");
224		if( fp != NULL ) {
225			fwrite(inqdata.bytes, 1, inqlen, fp);
226			fclose(fp);
227		}
228
229		if (name != basename)
230			free (name);
231	}
232
233	if( inqlen != sizeof(inqdata) )
234		return SANE_STATUS_IO_ERROR;
235
236	for( model = st400_models; model->inq_vendor; model++ ) {
237		if( str_at_offset(model->inq_vendor, model->inq_voffset, inqdata.bytes) && str_at_offset(model->inq_model, model->inq_moffset, inqdata.bytes) ) {
238			*modelP = model;
239			DBG(DINFO, "found matching scanner model \"%s %s\" in list\n", model->sane_vendor, model->sane_model);
240			return SANE_STATUS_GOOD;
241		}
242	}
243
244	return SANE_STATUS_UNSUPPORTED;
245}
246
247static SANE_Status
248st400_cmd6( int fd, SANE_Byte cmd, SANE_Byte ctrl )
249{
250	struct { SANE_Byte cmd, lun, reserved[2], tr_len, ctrl; } scsi_cmd;
251	SANE_Status status;
252
253	memset(&scsi_cmd, 0, sizeof(scsi_cmd));
254	scsi_cmd.cmd = cmd;
255	scsi_cmd.ctrl = ctrl;
256
257	DBG(DSCSI, "SCSI: sending cmd6 0x%02x (ctrl=%d)\n", (int)cmd, (int)ctrl);
258	status = sanei_scsi_cmd(fd, &scsi_cmd, sizeof(scsi_cmd), 0, 0);
259	DBG(DSCSI, "SCSI: result=%s\n", sane_strstatus(status));
260
261	return status;
262}
263
264#define st400_test_ready(fd)	st400_cmd6(fd, CMD_TEST_UNIT_READY, 0)
265#define st400_reserve(fd)		st400_cmd6(fd, CMD_RESERVE, 0)
266#define st400_release(fd)		st400_cmd6(fd, CMD_RELEASE, 0)
267#define st400_start_scan(fd)	st400_cmd6(fd, CMD_START_STOP, 0)
268#define st400_light_on(fd)		st400_cmd6(fd, CMD_MODE_SELECT, 0x80)
269#define st400_light_off(fd)		st400_cmd6(fd, CMD_MODE_SELECT, 0)
270
271
272static SANE_Status
273st400_wait_ready( int fd )
274{
275#define SLEEPTIME	100000L		/* 100ms */
276	long max_sleep = 60000000L;	/* 60 seconds */
277	SANE_Status status;
278
279	DBG(DCODE, "st400_wait_ready(%d)\n", fd);
280
281	while(1) {
282		status = st400_test_ready(fd);
283		switch( status ) {
284			case SANE_STATUS_DEVICE_BUSY:
285				if( max_sleep > 0 ) {
286					usleep(SLEEPTIME);	/* retry after 100ms */
287					max_sleep -= SLEEPTIME;
288					break;
289				}
290				/* else fall through */
291			default:
292				DBG(DERR, "st400_wait_ready: failed, error=%s\n", sane_strstatus(status));
293				/* fall through */
294			case SANE_STATUS_GOOD:
295				return status;
296		}
297	}
298	/*NOTREACHED*/
299}
300
301
302static SANE_Status
303st400_set_window( ST400_Device *dev )
304{
305	unsigned short xoff, yoff;
306	SANE_Byte th;
307
308	struct {
309		/* 10byte command */
310		SANE_Byte cmd, lun, reserved1[4], tr_len[3], ctrl;
311
312		/* 40byte window struct */
313		SANE_Byte reserved2[6], wd_len[2], winnr, reserved3;
314		SANE_Byte x_res[2], y_res[2];			/* resolution: 200, 300, 400 */
315		SANE_Byte x_ul[2], y_ul[2];				/* upper left corner */
316		SANE_Byte width[2], height[2];
317		SANE_Byte reserved4, threshold;
318		SANE_Byte reserved5, halftone;			/* ht: 0 or 2 */
319		SANE_Byte bitsperpixel, reserved6[13];	/* bpp: 1 or 8 */
320	} scsi_cmd;
321	/* The PC/Amiga source uses reserved5 to indicate A4/A5 paper size
322	 * (values 4 and 5), but a comment implies that this is only for the
323	 * scanning program and the value is ignored by the scanner.
324	 */
325	SANE_Status status;
326
327	memset(&scsi_cmd, 0, sizeof(scsi_cmd));
328	scsi_cmd.cmd = CMD_SET_WINDOW;
329	set24(scsi_cmd.tr_len, 40);
330	set16(scsi_cmd.wd_len, 32);
331
332	/* These offsets seem to be required to avoid damaging the scanner:
333	 * If a scan with 0/0 as the top left corner is started, the scanner
334	 * seems to try to move the carriage over the bottom end (not a
335	 * pretty sound).
336	 */
337	xoff = (11L * dev->val[OPT_RESOLUTION]) / 100;
338	yoff = 6;
339	th = (double)maxval(dev->model->bits) * SANE_UNFIX(dev->val[OPT_THRESHOLD]) / 100.0;
340
341	scsi_cmd.winnr = 1;
342	set16(scsi_cmd.x_res, (unsigned short)dev->val[OPT_RESOLUTION]);
343	set16(scsi_cmd.y_res, (unsigned short)dev->val[OPT_RESOLUTION]);
344	set16(scsi_cmd.x_ul, dev->x + xoff);
345	set16(scsi_cmd.y_ul, dev->wy + yoff);
346	set16(scsi_cmd.width, dev->w);
347	set16(scsi_cmd.height, dev->wh);
348	scsi_cmd.threshold = th;
349	scsi_cmd.halftone = (dev->val[OPT_DEPTH] == 1) ? 0 : 2;
350	scsi_cmd.bitsperpixel = dev->val[OPT_DEPTH];
351
352	DBG(DSCSI, "SCSI: sending SET_WINDOW (x=%hu y=%hu w=%hu h=%hu wy=%hu wh=%hu th=%d\n", dev->x, dev->y, dev->w, dev->h, dev->wy, dev->wh, (int)th);
353	status = sanei_scsi_cmd(dev->fd, &scsi_cmd, sizeof(scsi_cmd), 0, 0);
354	DBG(DSCSI, "SCSI: result=%s\n", sane_strstatus(status));
355
356	return status;
357}
358
359static SANE_Status
360st400_read10( int fd, SANE_Byte *buf, size_t *lenP )
361{
362	struct { SANE_Byte cmd, lun, res[4], tr_len[3], ctrl; } scsi_cmd;
363	SANE_Status status;
364
365	memset(&scsi_cmd, 0, sizeof(scsi_cmd));
366	scsi_cmd.cmd = CMD_READ10;
367	set24(scsi_cmd.tr_len, *lenP);
368
369	DBG(DSCSI, "SCSI: sending READ10 (%lu bytes)\n", (u_long)(*lenP));
370	status = sanei_scsi_cmd(fd, &scsi_cmd, sizeof(scsi_cmd), buf, lenP);
371	DBG(DSCSI, "SCSI: result=%s (%lu bytes)\n", sane_strstatus(status), (u_long)(*lenP));
372
373	return status;
374}
375
376static SANE_Status
377st400_fill_scanner_buffer( ST400_Device *dev )
378{
379	SANE_Status status;
380
381	DBG(DCODE, "st400_fill_scanner_buffer(%p)\n", (void *) dev);
382
383	if( dev->lines_to_read == 0 )
384		dev->status.eof = 1;
385	if( dev->status.eof )
386		return SANE_STATUS_EOF;
387
388	dev->wh = dev->model->bufsize / dev->params.bytes_per_line;
389	if( dev->wh > dev->lines_to_read )
390		dev->wh = dev->lines_to_read;
391	DBG(DVAR, "dev->wh = %hu\n", dev->wh);
392
393	status = st400_set_window(dev);
394	if( status != SANE_STATUS_GOOD )
395		return status;
396
397	status = st400_start_scan(dev->fd);
398	if( status != SANE_STATUS_GOOD )
399		return status;
400
401	dev->wy += dev->wh;
402	dev->lines_to_read -= dev->wh;
403	dev->bytes_in_scanner = dev->wh * dev->params.bytes_per_line;
404
405	return SANE_STATUS_GOOD;
406}
407
408static SANE_Status
409st400_fill_backend_buffer( ST400_Device *dev )
410{
411	size_t r;
412	SANE_Status status;
413
414	DBG(DCODE, "st400_fill_backend_buffer(%p)\n", (void *) dev);
415
416	if( dev->bytes_in_scanner == 0 ) {
417		status = st400_fill_scanner_buffer(dev);
418		if( status != SANE_STATUS_GOOD )
419			return status;
420	}
421
422	r = min(dev->bufsize, dev->bytes_in_scanner);
423	status = st400_read10(dev->fd, dev->buffer, &r);
424	if( status == SANE_STATUS_GOOD ) {
425		dev->bufp = dev->buffer;
426		dev->bytes_in_buffer = r;
427		dev->bytes_in_scanner -= r;
428
429		if( r == 0 )
430			dev->status.eof = 1;
431	}
432
433	return status;
434}
435
436static SANE_Status
437st400_sense_handler( int fd, SANE_Byte *result, void *arg )
438{
439	/* ST400_Device *dev = arg; */
440	SANE_Status status;
441
442	(void) fd;
443	(void) arg; /* silence compilation warnings */
444
445	switch( result[0] & 0x0f ) {
446		case 0x0:
447			status = SANE_STATUS_GOOD;
448			break;
449		case 0x1:
450			DBG(DSENSE, "SCSI: sense RECOVERED_ERROR\n");
451			status = SANE_STATUS_GOOD;	/* ?? */
452			break;
453		case 0x2:
454			DBG(DSENSE, "SCSI: sense NOT_READY\n");
455			status = SANE_STATUS_DEVICE_BUSY;
456			break;
457		case 0x4:
458			DBG(DSENSE, "SCSI: sense HARDWARE_ERROR\n");
459			status = SANE_STATUS_IO_ERROR;
460			break;
461		case 0x5:
462			DBG(DSENSE, "SCSI: sense ILLEGAL_REQUEST\n");
463			status = SANE_STATUS_IO_ERROR;
464			break;
465		case 0x6:
466			DBG(DSENSE, "SCSI: sense UNIT_ATTENTION\n");
467			status = SANE_STATUS_DEVICE_BUSY;
468			break;
469		case 0xb:
470			DBG(DSENSE, "SCSI: sense ABORTED_COMMAND\n");
471			status = SANE_STATUS_CANCELLED;	/* ?? */
472			break;
473		default:
474			DBG(DSENSE, "SCSI: sense unknown (%d)\n", result[0] & 0x0f);
475			status = SANE_STATUS_IO_ERROR;
476			break;
477	}
478	return status;
479}
480
481
482/*********************************************************************
483 * Sane initializing stuff
484 *********************************************************************/
485
486static SANE_Status
487st400_attach( const char *devname, ST400_Device **devP )
488{
489	ST400_Device *dev;
490	ST400_Model *model;
491	SANE_Status status;
492	int fd;
493
494	DBG(DCODE, "st400_attach(%s, %p)\n", devname, (void *) devP);
495	if( devP )
496		*devP = NULL;
497
498	for( dev = st400_devices; dev != NULL; dev = dev->next ) {
499		if( strcmp(dev->sane.name, devname) == 0 ) {
500			if( devP )
501				*devP = dev;
502			DBG(DCODE, "st400_attach: found device in list\n");
503			return SANE_STATUS_GOOD;
504		}
505	}
506
507	dev = calloc(1, sizeof(*dev));
508	if( !dev )
509		return SANE_STATUS_NO_MEM;
510	DBG(DCODE, "st400_attach: new device struct at %p\n", (void *) dev);
511
512	status = sanei_scsi_open(devname, &fd, st400_sense_handler, dev);
513	if( status == SANE_STATUS_GOOD ) {
514		status = st400_inquiry(fd, &model);
515		if( status == SANE_STATUS_GOOD )
516			status = st400_test_ready(fd);
517		sanei_scsi_close(fd);
518	}
519	if( status != SANE_STATUS_GOOD ) {
520		free(dev);
521		return status;
522	}
523
524	/* initialize device structure */
525	dev->sane.name = strdup(devname);
526	if( !dev->sane.name ) {
527		free(dev);
528		return SANE_STATUS_NO_MEM;
529	}
530	dev->sane.vendor = model->sane_vendor;
531	dev->sane.model = model->sane_model;
532	dev->sane.type = model->sane_type;
533	dev->status.open = 0;
534	dev->status.scanning = 0;
535	dev->status.eof = 0;
536	dev->fd = -1;
537	dev->buffer = NULL;
538	dev->model = model;
539
540	st400_init_options(dev);
541
542	DBG(DCODE, "st400_attach: everything ok, adding device to list\n");
543
544	dev->next = st400_devices;
545	st400_devices = dev;
546	++st400_num_devices;
547	st400_status.array_valid = 0;
548
549	if( devP )
550		*devP = dev;
551	return SANE_STATUS_GOOD;
552}
553
554static SANE_Status
555st400_attach_one( const char *device )
556{
557	DBG(DCODE, "st400_attach_one(%s)\n", device);
558	return st400_attach(device, NULL);
559}
560
561static SANE_Status
562st400_config_get_arg(char **optP, unsigned long *argP, size_t linenum)
563{
564	int n;
565
566	(void) linenum; /* silence compilation warnings */
567
568	if( sscanf(*optP, "%lu%n", argP, &n) == 1 ) {
569		*optP += n;
570		*optP = (char *)sanei_config_skip_whitespace(*optP);
571		return SANE_STATUS_GOOD;
572	}
573	return SANE_STATUS_INVAL;
574}
575
576
577static SANE_Status
578st400_config_get_single_arg(char *opt, unsigned long *argP, size_t linenum)
579{
580	int n;
581
582	if( sscanf(opt, "%lu%n", argP, &n) == 1 ) {
583		opt += n;
584		opt = (char *)sanei_config_skip_whitespace(opt);
585		if( *opt == '\0' )
586			return SANE_STATUS_GOOD;
587		else {
588			DBG(DERR, "extraneous arguments at line %lu: %s\n", (u_long)linenum, opt);
589			return SANE_STATUS_INVAL;
590		}
591	}
592	DBG(DERR, "invalid option argument at line %lu: %s\n", (u_long)linenum, opt);
593	return SANE_STATUS_INVAL;
594}
595
596
597static SANE_Status
598st400_config_do_option(char *opt, size_t linenum)
599{
600	unsigned long arg;
601	SANE_Status status;
602	int i;
603
604	status = SANE_STATUS_GOOD;
605
606	opt = (char *)sanei_config_skip_whitespace(opt);
607	if( strncmp(opt, "maxread", 7) == 0 && isspace(opt[7]) ) {
608		opt += 8;
609		status = st400_config_get_single_arg(opt, &arg, linenum);
610		if( status == SANE_STATUS_GOOD ) {
611			if( arg == 0 )
612				st400_maxread = sanei_scsi_max_request_size;
613			else
614				st400_maxread = (size_t)arg;
615		}
616	}
617	else
618	if( strncmp(opt, "delay", 5) == 0 && isspace(opt[5]) ) {
619		opt += 6;
620		status = st400_config_get_single_arg(opt, &arg, linenum);
621		if( status == SANE_STATUS_GOOD )
622			st400_light_delay = (size_t)arg;
623	}
624	else
625	if( strncmp(opt, "scanner_bufsize", 15) == 0 && isspace(opt[15]) ) {
626		opt += 16;
627		status = st400_config_get_single_arg(opt, &arg, linenum);
628		if( status == SANE_STATUS_GOOD )
629			if( st400_devices )
630				st400_devices->model->bufsize = arg;	/* FIXME: changes bufsize for all scanners of this model! */
631	}
632	else
633	if( strncmp(opt, "scanner_bits", 12) == 0 && isspace(opt[12]) ) {
634		opt += 13;
635		status = st400_config_get_single_arg(opt, &arg, linenum);
636		if( status == SANE_STATUS_GOOD )
637			if( st400_devices )
638				st400_devices->model->bits = arg;	/* FIXME */
639	}
640	else
641	if( strncmp(opt, "scanner_maxread", 15) == 0 && isspace(opt[15]) ) {
642		opt += 16;
643		status = st400_config_get_single_arg(opt, &arg, linenum);
644		if( status == SANE_STATUS_GOOD )
645			if( st400_devices )
646				st400_devices->model->maxread = arg;	/* FIXME */
647	}
648	else
649	if( strncmp(opt, "scanner_resolutions", 19) == 0 && isspace(opt[19]) ) {
650		opt += 20;
651		st400_devices->model->dpi_list = malloc(16 * sizeof(SANE_Int));
652		i = 0;
653		do {
654			status = st400_config_get_arg(&opt, &arg, linenum);
655			if( status == SANE_STATUS_GOOD ) {
656				++i;
657				st400_devices->model->dpi_list[i] = (SANE_Int)arg;
658			}
659		} while( status == SANE_STATUS_GOOD && i < 15 );
660		st400_devices->model->dpi_list[0] = i;
661		DBG(DINFO, "%d entries for resolution\n", i);
662		status = SANE_STATUS_GOOD;
663	}
664	else
665	if( strncmp(opt, "dump_inquiry", 12) == 0 ) {
666		st400_dump_data = 1;
667	}
668	if( st400_devices )
669		st400_reset_options(st400_devices);
670	return status;
671}
672
673SANE_Status
674sane_init( SANE_Int *versionP, SANE_Auth_Callback authorize )
675{
676	FILE *fp;
677	SANE_Status status;
678
679	DBG_INIT();
680	DBG(DCODE, "sane_init: version %s null, authorize %s null\n", (versionP) ? "!=" : "==", (authorize) ? "!=" : "==");
681
682	if( versionP != NULL )
683		*versionP = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
684
685	status = SANE_STATUS_GOOD;
686	if( (fp = sanei_config_open(ST400_CONFIG_FILE)) != NULL ) {
687		char line[PATH_MAX], *str;
688		size_t len, linenum;
689
690		linenum = 0;
691		DBG(DCODE, "sane_init: reading config file\n");
692		while( sanei_config_read(line, sizeof(line), fp) ) {
693			++linenum;
694			str = line;
695			if( str[0] == '#' )
696				continue;	/* ignore comments */
697			str = (char *)sanei_config_skip_whitespace(str);
698			len = strlen(str);
699			if( !len )
700				continue;	/* ignore empty lines */
701			if( strncmp(str, "option", 6) == 0 && isspace(str[6]) ) {
702				DBG(DCODE, "sane_init: config line <%s>\n", line);
703				status = st400_config_do_option(str+7, linenum);
704			}
705			else {
706				DBG(DCODE, "sane_init: attaching device <%s>\n", line);
707				sanei_config_attach_matching_devices(line, st400_attach_one);
708			}
709			if( status != SANE_STATUS_GOOD )
710				break;
711		}
712		DBG(DCODE, "sane_init: closing config file\n");
713		fclose(fp);
714	}
715
716	if( status == SANE_STATUS_GOOD && st400_devices == NULL ) {
717		DBG(DCODE, "sane_init: attaching default device <%s>\n", ST400_DEFAULT_DEVICE);
718		sanei_config_attach_matching_devices(ST400_DEFAULT_DEVICE, st400_attach_one);
719	}
720
721	return status;
722}
723
724void
725sane_exit( void )
726{
727	ST400_Device *dev;
728
729	DBG(DCODE, "sane_exit()\n");
730
731	while( (dev = st400_devices) != NULL ) {
732		st400_devices = dev->next;
733
734		sane_close(dev);
735		free((char *)(dev->sane.name));
736		free(dev);
737	}
738	st400_num_devices = 0;
739	if( st400_device_array ) {
740		DBG(DCODE, "sane_exit: freeing device array\n");
741		free(st400_device_array);
742		st400_device_array = NULL;
743		st400_status.array_valid = 0;
744	}
745}
746
747SANE_Status
748sane_get_devices( const SANE_Device ***devarrayP, SANE_Bool local_only )
749{
750	ST400_Device *dev;
751	unsigned int i;
752
753	DBG(DCODE, "sane_get_devices(%p, %d)\n", (void *) devarrayP, (int)local_only);
754
755	if( !st400_status.array_valid ) {
756		if( st400_device_array ) {
757			DBG(DCODE, "sane_get_devices: freeing old device array\n");
758			free(st400_device_array);
759		}
760		st400_device_array = malloc((st400_num_devices + 1) * sizeof(*st400_device_array));
761		if( !st400_device_array )
762			return SANE_STATUS_NO_MEM;
763		DBG(DCODE, "sane_get_devices: new device array at %p\n", (void *) st400_device_array);
764
765		dev = st400_devices;
766		for( i = 0; i < st400_num_devices; i++ ) {
767			st400_device_array[i] = &dev->sane;
768			dev = dev->next;
769		}
770		st400_device_array[st400_num_devices] = NULL;
771		st400_status.array_valid = 1;
772	}
773	DBG(DCODE, "sane_get_devices: %u entries in device array\n", st400_num_devices);
774	if( devarrayP )
775		*devarrayP = st400_device_array;
776	return SANE_STATUS_GOOD;
777}
778
779
780SANE_Status
781sane_open( SANE_String_Const devicename, SANE_Handle *handleP )
782{
783	ST400_Device *dev;
784	SANE_Status status;
785
786	DBG(DCODE, "sane_open(%s, %p)\n", devicename, (void *) handleP);
787
788	*handleP = NULL;
789	if( devicename && devicename[0] ) {
790		status = st400_attach(devicename, &dev);
791		if( status != SANE_STATUS_GOOD )
792			return status;
793	}
794	else
795		dev = st400_devices;
796
797	if( !dev )
798		return SANE_STATUS_INVAL;
799
800	if( dev->status.open )
801		return SANE_STATUS_DEVICE_BUSY;
802
803	dev->status.open = 1;
804	st400_reset_options(dev);
805	*handleP = (SANE_Handle)dev;
806
807	return SANE_STATUS_GOOD;
808}
809
810
811void
812sane_close( SANE_Handle handle )
813{
814	ST400_Device *dev = handle;
815
816	DBG(DCODE, "sane_close(%p)\n", handle);
817
818	if( dev->status.open ) {
819		sane_cancel(dev);
820		dev->status.open = 0;
821	}
822}
823
824
825/*
826 * options
827 */
828static void
829st400_reset_options( ST400_Device *dev )
830{
831	DBG(DCODE, "st400_reset_options(%p)\n", (void *) dev);
832
833	dev->val[OPT_NUM_OPTS]	= NUM_OPTIONS;
834	dev->val[OPT_RESOLUTION]	= dev->opt[OPT_RESOLUTION].constraint.word_list[1];
835	dev->val[OPT_DEPTH]		= dev->opt[OPT_DEPTH].constraint.word_list[1];
836    dev->val[OPT_THRESHOLD]	= SANE_FIX(50.0);
837	dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
838    dev->val[OPT_TL_X]		= SANE_FIX(0.0);
839	dev->val[OPT_TL_Y]		= SANE_FIX(0.0);
840	dev->val[OPT_BR_X]		= SANE_FIX(0.0);
841	dev->val[OPT_BR_Y]		= SANE_FIX(0.0);
842
843	if( dev->model->dpi_list )
844		dev->opt[OPT_RESOLUTION].constraint.word_list = dev->model->dpi_list;
845}
846
847static void
848st400_init_options( ST400_Device *dev )
849{
850	static const SANE_Int depth_list[] = { 2, 1, 8 };
851	static const SANE_Int dpi_list[] = { 3, 200, 300, 400 };
852	static const SANE_Range thres_range = {
853		SANE_FIX(0.0), SANE_FIX(100.0), SANE_FIX(0.0)
854	};
855	static const SANE_Range x_range = {
856		SANE_FIX(0.0), SANE_FIX(ST400_MAX_X * MM_PER_INCH), SANE_FIX(0.0)
857	};
858	static const SANE_Range y_range = {
859		SANE_FIX(0.0), SANE_FIX(ST400_MAX_Y * MM_PER_INCH), SANE_FIX(0.0)
860	};
861
862	DBG(DCODE, "st400_init_options(%p)\n", (void *)dev);
863
864	dev->opt[OPT_NUM_OPTS].name	= SANE_NAME_NUM_OPTIONS;
865	dev->opt[OPT_NUM_OPTS].title	= SANE_TITLE_NUM_OPTIONS;
866	dev->opt[OPT_NUM_OPTS].desc		= SANE_DESC_NUM_OPTIONS;
867	dev->opt[OPT_NUM_OPTS].type	= SANE_TYPE_INT;
868	dev->opt[OPT_NUM_OPTS].unit	= SANE_UNIT_NONE;
869	dev->opt[OPT_NUM_OPTS].size = sizeof(SANE_Word);
870	dev->opt[OPT_NUM_OPTS].cap	= SANE_CAP_SOFT_DETECT;
871	dev->opt[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE;
872
873	dev->opt[OPT_MODE_GROUP].title= "Scan Mode";
874	dev->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
875
876	dev->opt[OPT_RESOLUTION].name	= SANE_NAME_SCAN_RESOLUTION;
877	dev->opt[OPT_RESOLUTION].title= SANE_TITLE_SCAN_RESOLUTION;
878	dev->opt[OPT_RESOLUTION].desc	= SANE_DESC_SCAN_RESOLUTION;
879	dev->opt[OPT_RESOLUTION].type	= SANE_TYPE_INT;
880	dev->opt[OPT_RESOLUTION].unit	= SANE_UNIT_DPI;
881	dev->opt[OPT_RESOLUTION].size = sizeof(SANE_Word);
882	dev->opt[OPT_RESOLUTION].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
883	dev->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
884	dev->opt[OPT_RESOLUTION].constraint.word_list = dpi_list;
885
886	dev->opt[OPT_DEPTH].name	= SANE_NAME_BIT_DEPTH;
887	dev->opt[OPT_DEPTH].title	= SANE_TITLE_BIT_DEPTH;
888	dev->opt[OPT_DEPTH].desc	= SANE_DESC_BIT_DEPTH;
889	dev->opt[OPT_DEPTH].type	= SANE_TYPE_INT;
890	dev->opt[OPT_DEPTH].unit	= SANE_UNIT_BIT;
891	dev->opt[OPT_DEPTH].size	= sizeof(SANE_Word);
892	dev->opt[OPT_DEPTH].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
893	dev->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
894	dev->opt[OPT_DEPTH].constraint.word_list = depth_list;
895
896	dev->opt[OPT_THRESHOLD].name	= SANE_NAME_THRESHOLD;
897	dev->opt[OPT_THRESHOLD].title	= SANE_TITLE_THRESHOLD;
898	dev->opt[OPT_THRESHOLD].desc	= SANE_DESC_THRESHOLD;
899	dev->opt[OPT_THRESHOLD].type	= SANE_TYPE_FIXED;
900	dev->opt[OPT_THRESHOLD].unit	= SANE_UNIT_PERCENT;
901	dev->opt[OPT_THRESHOLD].size	= sizeof(SANE_Word);
902	dev->opt[OPT_THRESHOLD].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
903	dev->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
904	dev->opt[OPT_THRESHOLD].constraint.range = &thres_range;
905
906	dev->opt[OPT_GEOMETRY_GROUP].title= "Geometry";
907	dev->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
908
909	dev->opt[OPT_TL_X].name	= SANE_NAME_SCAN_TL_X;
910	dev->opt[OPT_TL_X].title	= SANE_TITLE_SCAN_TL_X;
911	dev->opt[OPT_TL_X].desc	= SANE_DESC_SCAN_TL_X;
912	dev->opt[OPT_TL_X].type	= SANE_TYPE_FIXED;
913	dev->opt[OPT_TL_X].unit	= SANE_UNIT_MM;
914	dev->opt[OPT_TL_X].size	= sizeof(SANE_Word);
915	dev->opt[OPT_TL_X].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
916	dev->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
917	dev->opt[OPT_TL_X].constraint.range = &x_range;
918
919	dev->opt[OPT_TL_Y].name	= SANE_NAME_SCAN_TL_Y;
920	dev->opt[OPT_TL_Y].title	= SANE_TITLE_SCAN_TL_Y;
921	dev->opt[OPT_TL_Y].desc	= SANE_DESC_SCAN_TL_Y;
922	dev->opt[OPT_TL_Y].type	= SANE_TYPE_FIXED;
923	dev->opt[OPT_TL_Y].unit	= SANE_UNIT_MM;
924	dev->opt[OPT_TL_Y].size	= sizeof(SANE_Word);
925	dev->opt[OPT_TL_Y].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
926	dev->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
927	dev->opt[OPT_TL_Y].constraint.range = &y_range;
928
929	dev->opt[OPT_BR_X].name	= SANE_NAME_SCAN_BR_X;
930	dev->opt[OPT_BR_X].title	= SANE_TITLE_SCAN_BR_X;
931	dev->opt[OPT_BR_X].desc	= SANE_DESC_SCAN_BR_X;
932	dev->opt[OPT_BR_X].type	= SANE_TYPE_FIXED;
933	dev->opt[OPT_BR_X].unit	= SANE_UNIT_MM;
934	dev->opt[OPT_BR_X].size	= sizeof(SANE_Word);
935	dev->opt[OPT_BR_X].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
936	dev->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
937	dev->opt[OPT_BR_X].constraint.range = &x_range;
938
939	dev->opt[OPT_BR_Y].name	= SANE_NAME_SCAN_BR_Y;
940	dev->opt[OPT_BR_Y].title	= SANE_TITLE_SCAN_BR_Y;
941	dev->opt[OPT_BR_Y].desc	= SANE_DESC_SCAN_BR_Y;
942	dev->opt[OPT_BR_Y].type	= SANE_TYPE_FIXED;
943	dev->opt[OPT_BR_Y].unit	= SANE_UNIT_MM;
944	dev->opt[OPT_BR_Y].size	= sizeof(SANE_Word);
945	dev->opt[OPT_BR_Y].cap	= SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT;
946	dev->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
947	dev->opt[OPT_BR_Y].constraint.range = &y_range;
948
949	st400_reset_options(dev);
950}
951
952const SANE_Option_Descriptor *
953sane_get_option_descriptor( SANE_Handle handle, SANE_Int optnum )
954{
955	ST400_Device *dev = handle;
956
957	DBG(DOPT, "sane_get_option_descriptor(%p, %d)\n", handle, (int)optnum);
958
959	if( dev->status.open && optnum >= 0 && optnum < NUM_OPTIONS )
960		return &dev->opt[optnum];
961
962	return NULL;
963}
964
965SANE_Status
966sane_control_option( SANE_Handle handle, SANE_Int optnum,
967	SANE_Action action, void *valP, SANE_Int *infoP)
968{
969	ST400_Device *dev = handle;
970	SANE_Status status;
971
972	DBG(DCODE, "sane_control_option(%p, %d, %d, %p, %p)\n", (void *) handle, (int)optnum, (int)action, valP, (void *) infoP);
973
974	if( infoP )
975		*infoP = 0;
976
977	if( !dev->status.open )
978		return SANE_STATUS_INVAL;
979	if( dev->status.scanning )
980		return SANE_STATUS_DEVICE_BUSY;
981
982	if( optnum < 0 || optnum >= NUM_OPTIONS )
983		return SANE_STATUS_INVAL;
984
985	switch( action ) {
986		case SANE_ACTION_GET_VALUE:
987
988			DBG(DOPT, "getting option %d (value=%d)\n", (int)optnum, (int)dev->val[optnum]);
989
990			switch( optnum ) {
991				case OPT_NUM_OPTS:
992				case OPT_RESOLUTION:
993				case OPT_DEPTH:
994				case OPT_THRESHOLD:
995				case OPT_TL_X:
996				case OPT_TL_Y:
997				case OPT_BR_X:
998				case OPT_BR_Y:
999					*(SANE_Word *)valP = dev->val[optnum];
1000					break;
1001				default:
1002					return SANE_STATUS_INVAL;
1003			}
1004			break;
1005
1006		case SANE_ACTION_SET_VALUE:
1007			if( !SANE_OPTION_IS_SETTABLE(dev->opt[optnum].cap) )
1008				return SANE_STATUS_INVAL;
1009			status = sanei_constrain_value(&dev->opt[optnum], valP, infoP);
1010			if( status != SANE_STATUS_GOOD )
1011				return status;
1012
1013			DBG(DOPT, "setting option %d to %d\n", (int)optnum, (int)*(SANE_Word *)valP);
1014
1015			switch( optnum ) {
1016				case OPT_DEPTH:
1017					if( *(SANE_Word *)valP != 1 )
1018						dev->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1019					else
1020						dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
1021					if( infoP )
1022						*infoP |= SANE_INFO_RELOAD_OPTIONS;
1023					/* fall through */
1024				case OPT_RESOLUTION:
1025				case OPT_TL_X:
1026				case OPT_TL_Y:
1027				case OPT_BR_X:
1028				case OPT_BR_Y:
1029					if( infoP )
1030						*infoP |= SANE_INFO_RELOAD_PARAMS;
1031					/* fall through */
1032				case OPT_THRESHOLD:
1033					dev->val[optnum] = *(SANE_Word *)valP;
1034					break;
1035				default:
1036					return SANE_STATUS_INVAL;
1037			}
1038			break;
1039
1040		case SANE_ACTION_SET_AUTO:
1041
1042			DBG(DOPT, "automatic option setting\n");
1043
1044			return SANE_STATUS_UNSUPPORTED;
1045
1046		default:
1047			return SANE_STATUS_INVAL;
1048	}
1049	return SANE_STATUS_GOOD;
1050}
1051
1052SANE_Status
1053sane_get_parameters( SANE_Handle handle, SANE_Parameters *paramsP )
1054{
1055	ST400_Device *dev = handle;
1056
1057	DBG(DCODE, "sane_get_parameters(%p, %p)\n", handle, (void *) paramsP);
1058
1059	if( !dev->status.open )
1060		return SANE_STATUS_INVAL;
1061
1062	if( !dev->status.scanning ) {
1063		double width, height, dpi;
1064
1065		dev->params.format = SANE_FRAME_GRAY;
1066		dev->params.last_frame = SANE_TRUE;
1067		dev->params.lines = 0;
1068		dev->params.depth = dev->val[OPT_DEPTH];
1069
1070		width  = SANE_UNFIX(dev->val[OPT_BR_X] - dev->val[OPT_TL_X]);
1071		height = SANE_UNFIX(dev->val[OPT_BR_Y] - dev->val[OPT_TL_Y]);
1072		dpi = dev->val[OPT_RESOLUTION];
1073
1074		/* make best-effort guess at what parameters will look like once
1075		   scanning starts.  */
1076		if( dpi > 0.0  &&  width > 0.0  &&  height > 0.0 ) {
1077			double dots_per_mm = dpi / MM_PER_INCH;
1078
1079			dev->params.pixels_per_line = width * dots_per_mm + 0.5;
1080			dev->params.lines = height * dots_per_mm + 0.5;
1081
1082			if( dev->params.depth == 1 ) {
1083				/* Pad to an even multiple of 8.  This way we can simply
1084				 * copy the bytes from the scanner to the SANE buffer
1085				 * (only need to invert them).
1086				 */
1087				dev->params.pixels_per_line += 7;
1088				dev->params.pixels_per_line &= ~7;
1089
1090				/*dev->params.bytes_per_line = (dev->params.pixels_per_line + 7)/8;*/
1091				dev->params.bytes_per_line = dev->params.pixels_per_line/8;
1092			}
1093			else
1094				dev->params.bytes_per_line = dev->params.pixels_per_line;
1095
1096			dev->x = SANE_UNFIX(dev->val[OPT_TL_X]) * dots_per_mm + 0.5;
1097			dev->y = SANE_UNFIX(dev->val[OPT_TL_Y]) * dots_per_mm + 0.5;
1098			dev->w = dev->params.pixels_per_line;
1099			dev->h = dev->params.lines;
1100
1101			DBG(DVAR, "parameters: bpl=%d, x=%hu, y=%hu, w=%hu, h=%hu\n", (int)dev->params.bytes_per_line, dev->x, dev->y, dev->w, dev->h);
1102		}
1103	}
1104
1105	if( paramsP )
1106		*paramsP = dev->params;
1107	return SANE_STATUS_GOOD;
1108}
1109
1110
1111SANE_Status
1112sane_start( SANE_Handle handle )
1113{
1114	ST400_Device *dev = handle;
1115	SANE_Status status;
1116
1117	DBG(DCODE, "sane_start(%p)\n", handle);
1118
1119	if( !dev->status.open )
1120		return SANE_STATUS_INVAL;
1121	if( dev->status.scanning )
1122		return SANE_STATUS_DEVICE_BUSY;
1123
1124	status = sane_get_parameters(dev, NULL);
1125	if( status != SANE_STATUS_GOOD )
1126		return status;
1127
1128	if( !dev->buffer ) {
1129		if( st400_maxread > 0 )
1130			dev->bufsize = min(st400_maxread, (unsigned int) sanei_scsi_max_request_size);
1131		else
1132		if( dev->model->maxread > 0 )
1133			dev->bufsize = min(dev->model->maxread, (unsigned int) sanei_scsi_max_request_size);
1134		else
1135			dev->bufsize = sanei_scsi_max_request_size;
1136		DBG(DVAR, "allocating %lu bytes buffer\n", (u_long)dev->bufsize);
1137		dev->buffer = malloc(dev->bufsize);
1138		if( !dev->buffer )
1139			return SANE_STATUS_NO_MEM;
1140	}
1141	dev->bufp = dev->buffer;
1142	dev->bytes_in_buffer = 0;
1143
1144	if( dev->fd < 0 ) {
1145		status = sanei_scsi_open(dev->sane.name, &dev->fd, st400_sense_handler, dev);
1146		if( status != SANE_STATUS_GOOD )
1147			goto return_error;
1148	}
1149
1150	dev->status.eof = 0;
1151
1152	status = st400_wait_ready(dev->fd);
1153	if( status != SANE_STATUS_GOOD )
1154		goto close_and_return;
1155
1156	status = st400_reserve(dev->fd);
1157	if( status != SANE_STATUS_GOOD )
1158		goto close_and_return;
1159
1160	if( st400_light_delay > 0 ) {
1161		status = st400_light_on(dev->fd);
1162		if( status != SANE_STATUS_GOOD )
1163			goto release_and_return;
1164		usleep(st400_light_delay * 100000);	/* 1/10 seconds */
1165	}
1166
1167	dev->wy = dev->y;
1168	dev->lines_to_read = dev->h;
1169	dev->bytes_in_scanner = 0;
1170
1171	status = st400_fill_scanner_buffer(dev);
1172	if( status != SANE_STATUS_GOOD )
1173		goto lightoff_and_return;
1174
1175	/* everything ok */
1176	dev->status.scanning = 1;
1177	return SANE_STATUS_GOOD;
1178
1179lightoff_and_return:
1180	if( st400_light_delay )
1181		st400_light_off(dev->fd);
1182release_and_return:
1183	st400_release(dev->fd);
1184close_and_return:
1185	sanei_scsi_close(dev->fd);
1186return_error:
1187	dev->fd = -1;
1188	return status;
1189}
1190
1191void
1192sane_cancel( SANE_Handle handle )
1193{
1194	ST400_Device *dev = handle;
1195
1196	DBG(DCODE, "sane_cancel(%p)\n", handle);
1197
1198	if( dev->status.scanning ) {
1199#if 0
1200		st400_stop_scan(dev->fd);
1201#endif
1202		if( st400_light_delay )
1203			st400_light_off(dev->fd);
1204		st400_release(dev->fd);
1205		sanei_scsi_close(dev->fd);
1206		dev->status.scanning = 0;
1207		dev->fd = -1;
1208	}
1209	if( dev->buffer ) {
1210		free(dev->buffer);
1211		dev->buffer = NULL;
1212	}
1213}
1214
1215
1216SANE_Status
1217sane_read( SANE_Handle handle, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenP )
1218{
1219	ST400_Device *dev = handle;
1220	SANE_Status status;
1221	size_t r, i;
1222	SANE_Byte val;
1223
1224	DBG(DCODE, "sane_read(%p, %p, %d, %p)\n", handle, (void *) buf, (int) maxlen, (void *) lenP);
1225
1226	*lenP = 0;
1227	if( !dev->status.scanning )
1228		return SANE_STATUS_INVAL;
1229	if( dev->status.eof )
1230		return SANE_STATUS_EOF;
1231
1232	status = SANE_STATUS_GOOD;
1233	while( maxlen > 0 ) {
1234		if( dev->bytes_in_buffer == 0 ) {
1235			status = st400_fill_backend_buffer(dev);
1236			if( status == SANE_STATUS_EOF )
1237				return SANE_STATUS_GOOD;
1238			if( status != SANE_STATUS_GOOD ) {
1239				*lenP = 0;
1240				return status;
1241			}
1242		}
1243
1244		r = min((SANE_Int) dev->bytes_in_buffer, maxlen);
1245
1246		if( dev->val[OPT_DEPTH] == 1 || dev->model->bits == 8 ) {
1247			/* This is simple.  We made sure the scanning are is aligned to
1248			 * 8 pixels (see sane_get_parameters()), so we can simply copy
1249			 * the stuff - only need to invert it.
1250			 */
1251			for( i = 0; i < r; i++ )
1252				*buf++ = ~(*dev->bufp++);
1253		}
1254		else {
1255			SANE_Byte mv;
1256
1257			/* The scanner sends bytes with 6bit-values (0..63), where 0 means
1258			 * white.  To convert to 8bit, we invert the values (so 0 means
1259			 * black) and then shift them two bits to the left and replicate
1260			 * the most- significant bits in the lowest two bits of the
1261			 * 8bit-value:
1262			 *     bit-pattern x x 5 4 3 2 1 0  becomes  5 4 3 2 1 0 5 4
1263			 * This is more accurate than simply shifting the values two bits
1264			 * to the left (e.g. 6bit-white 00111111 gets converted to 8bit-
1265			 * white 11111111 instead of almost-white 11111100) and is still
1266			 * reasonably fast.
1267			 */
1268			mv = (SANE_Byte)maxval(dev->model->bits);
1269
1270			/* Note: this works with any bit depth <= 8 */
1271			for( i = 0; i < r; i++ ) {
1272				val = mv - *dev->bufp++;
1273				val <<= (8 - dev->model->bits);
1274				val += (val >> dev->model->bits);
1275				*buf++ = val;
1276			}
1277		}
1278		maxlen -= r;
1279		dev->bytes_in_buffer -= r;
1280		*lenP += r;
1281	}
1282	return status;
1283}
1284
1285
1286/*********************************************************************
1287 * Advanced functions (not supported)
1288 *********************************************************************/
1289
1290SANE_Status
1291sane_set_io_mode( SANE_Handle handle, SANE_Bool nonblock )
1292{
1293	DBG(DCODE, "sane_set_io_mode(%p, %d)\n", handle, (int)nonblock);
1294
1295	if( nonblock == SANE_TRUE )
1296		return SANE_STATUS_UNSUPPORTED;
1297	return SANE_STATUS_GOOD;
1298}
1299
1300SANE_Status
1301sane_get_select_fd( SANE_Handle handle, SANE_Int *fdP )
1302{
1303	DBG(DCODE, "sane_get_select_fd(%p, %p)\n", handle, (void *) fdP);
1304
1305	return SANE_STATUS_UNSUPPORTED;
1306}
1307/* The End */
1308