Patch for Microtek ScanMaker X6 (microtek2 backend)

Sebastian Erdmann (serdmann@cs.tu-berlin.de)
Thu, 19 Nov 1998 15:53:49 +0100 (MET)

Hi,

my Microtek Scanmaker X6 exhibits some strange behavior: After
switching it on, colors (or greyscale tones) are "washed out" and
horizontally unbalanced across the image. This occurs when using
SANE 0.74 as well as SANE pre1.00. A simple workaround is to
power-cycle the scanner (while keeping the computer running).

But since the windoze twain drivers can get the scanner to work
without that extra power-cycle, I wasn't satisfied with the
situation and started to look for a better solution. Unfortunately,
the trace information obtained from setting "option dump 4" in
microtek2.conf and setting SANE_DEBUG_MICROTEK2=255 in the
environment didn't show significant differences between the
"colors washed out" case and the normal case. In fact, the only
difference I found turned out to be unrelated to the problem, but
I fixed it anyway to prevent potential problems: The scanner seems
to come up with random values for the NTRACK and NCALIB bits in
the system status. The fix (included in the patch below) was to
explicitly set these bits to zero in sane_start().

But the "colors washed out" problem did still persist.
However, after some experimentation I found out that issuing
a SEND DIAGNOSTIC command (which performs a scanner self test)
fixes the problem. Since this command keeps the scanner busy for
quite some time, I added a flag to the Microtek2_Device struct
so the self test is only performed once in a xscanimage session.

The most natural place for the SEND DIAGNOSTIC command seemed to
be do_dummy_scan(), since this function already handles
quirks of some scanner models.

These changes should only affect ScanMaker 636 (model code 0x97)
and ScanMaker X6 (model code 0x91), both with firmware revision
1.00. For other models, my patch shouldn't make any difference
(the NTRACK and NCALIB bits are just set to their default values).

Below is the patch to the microtek2 backend relative to SANE pre-1.00.

Sebastian

--- microtek2.h-sane-pre1.00
+++ microtek2.h Wed Nov 18 14:49:24 1998
@@ -417,6 +417,13 @@
#define RQS_ASINFO(s) &((s)[18])
#define RQS_ASINFOLENGTH(s) (s)[7] - 11

+
+/* SEND DIAGNOSTIC */
+#define SSD_CMD(d) (d)[0] = 0x1d; (d)[1] = 0x04; (d)[2] = 0x00; \
+ (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00
+#define SSD_CMD_L 6
+
+
/******************************************************************************/
/* enumeration of Option Descriptors */
/******************************************************************************/
@@ -606,6 +613,7 @@

SANE_Int *custom_gamma_table[4]; /* used for the custom gamma */
/* values before a scan starts */
+ SANE_Bool did_self_test; /* self test has been performed */
/* the following two are derived from lut_cap */
int max_lut_size; /* in bytes */
int lut_entry_size; /* word or byte transfer in LUT */
@@ -998,5 +1006,8 @@

static SANE_Status
scsi_wait_for_image(Microtek2_Scanner *);
+
+static SANE_Status
+scsi_send_diagnostic(Microtek2_Device *, int);

#endif
--- microtek2.c-sane-pre1.00
+++ microtek2.c Wed Nov 18 14:41:20 1998
@@ -1158,6 +1158,14 @@
return status;
}

+ status = do_dummy_scan(ms);
+ if ( status != SANE_STATUS_GOOD )
+ {
+ cleanup_scanner(ms);
+ return status;
+ }
+
+ /* toggle the lamp */
if ( ms->scan_source != MS_SOURCE_TMA )
{
md->status.flamp |= MD_FLAMP_ON;
@@ -1168,8 +1176,10 @@
md->status.flamp &= ~MD_FLAMP_ON;
md->status.tlamp |= MD_TLAMP_ON;
}
-
- /* toggle the lamp */
+
+ md->status.ntrack = 0;
+ md->status.ncalib = 0;
+
status = scsi_send_system_status(md, ms->sfd);
if ( status != SANE_STATUS_GOOD )
{
@@ -1177,13 +1187,6 @@
return status;
}

- status = do_dummy_scan(ms);
- if ( status != SANE_STATUS_GOOD )
- {
- cleanup_scanner(ms);
- return status;
- }
-
status = scsi_set_window(ms, 1);
if ( status != SANE_STATUS_GOOD )
{
@@ -1453,6 +1456,7 @@
md->sane.vendor = NULL;
md->sane.model = NULL;
md->sane.type = NULL;
+ md->did_self_test = SANE_FALSE;
md->scan_source = MD_SOURCE_FLATBED;
strncpy(md->name, hdev, PATH_MAX - 1);
++md_num_devices;
@@ -2008,6 +2012,19 @@
DBG(1, "do_dummy_scan: malloc failed\n");
return SANE_STATUS_NO_MEM;
}
+
+ if ( ! md->did_self_test )
+ {
+ status = scsi_send_diagnostic(md, ms->sfd);
+ if ( status != SANE_STATUS_GOOD )
+ {
+ DBG(1, "do_dummy_scan: send_diagnostic '%s'\n",
+ sane_strstatus(status));
+ return status;
+ }
+ md->did_self_test = SANE_TRUE;
+ }
+
ms_dummy->sfd = ms->sfd;
/* scsi_read_image_info() checks the model code, so we need */
/* something like this; all this is ugly */
@@ -5143,5 +5160,44 @@
DBG(1, "scsi_test_unit_ready: cmd '%s'\n", sane_strstatus(status));

sanei_scsi_close(sfd);
+ return status;
+}
+
+/*---------- scsi_send_diagnostic() ------------------------------------------*/
+
+static SANE_Status
+scsi_send_diagnostic(Microtek2_Device *md, int fd)
+{
+ u_int8_t sdiag[SSD_CMD_L];
+ int sfd;
+ SANE_Status status;
+
+
+ DBG(30, "scsi_send_diagnostic: md=%p fd=%d\n", md, fd);
+
+ if ( fd == -1 )
+ {
+ status = sanei_scsi_open(md->name, &sfd, scsi_sense_handler, 0);
+ if ( status != SANE_STATUS_GOOD )
+ {
+ DBG(1, "scsi_send_diagnostic: open '%s'\n",
+ sane_strstatus(status));
+ return status;
+ }
+ }
+ else
+ sfd = fd;
+
+ SSD_CMD(sdiag);
+
+ if ( ms_dump >= 2)
+ dump_area2(sdiag, SSD_CMD_L, "senddiagnostic");
+
+ status = sanei_scsi_cmd(sfd, sdiag, sizeof(sdiag), NULL, 0);
+ if ( status != SANE_STATUS_GOOD )
+ DBG(1, "scsi_send_diagnostic: '%s'\n", sane_strstatus(status));
+
+ if ( fd == -1 )
+ sanei_scsi_close(sfd);
return status;
}

-- 
                                        ___
Sebastian Erdmann                      /
serdmann@cs.tu-berlin.de           ___|__
se@pobox.com                      (_  |
http://pobox.com/~se              __)  \___

--
Source code, list archive, and docs: http://www.mostang.com/sane/
To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com