Douglas Gilbert wrote:
>
> Erik Inge Bolsø wrote:
> >
> > On Sun, 14 Jan 2001, Douglas Gilbert wrote:
> > >> [snapscan] request_sense
> > >> [snapscan] sense_handler(5, 0xbffff324, 0x8050c90)
> > >> [snapscan] sense_handler: sense key is invalid.
> >
> > The problem was here. The aha152x.c driver filtered out request_sense
> > commands and always returned 0 on them. (At least that's my layman's
> > understanding of the problem.)
> >
> > int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
> > {
> > if(*SCpnt->cmnd == REQUEST_SENSE) {
> > SCpnt->result = 0;
> > done(SCpnt);
> >
> > return SUCCESS;
> > }
> >
> > return aha152x_internal_queue(SCpnt, 0, 0, 0, done);
> > }
> >
> > Removing everything but the "return" line fixed the problem :)
> >
> > Thanks to Marcel Martin for the fix :)
>
> This is interesting. The linux scsi subsystem (as does
> FreeBSD's CAM) implements "autosense" to get its sense
> buffer after a command has failed. This means that when
> a command like "test unit ready" is sent and it returns
> a "check condition" status code then the subsystem will
> automatically issue a "request sense" and give its
> response back as the sense buffer of the original command
> ("test unit ready" in this case).
>
> So SANE backends shouldn't be issuing "request sense"
> commands IMHO. BTW only the first "request sense" gets
> the error response, so sending more of them is useless.
>
> It seems as though a problem that Arnold Schiller has
> sent me is very similar: a SnapScan1236/aha152x
> combination that locks up just after a "request sense"
> is sent to the scanner.
>
> Anyway, the aha152x driver probably shouldn't be reacting
> the way it is.
I think that Jürgen Fischer patched the aha152x driver already.
I must admit that I am the one who insisted that the Snapscans are a
little bit brain damaged, and that it would be preferable to have low
level SCSI driver, which can handle a REQUEST SENSE command from user
space.
This claim was purely based on reading the source files of the Snapscan
backend. At present, I have a borrowed Snapscan 1236 at home, so I
played a little bit with Sane and the scanner.
The main result is, that at least _this_ scanner works probably as
described above by Douglas: The REQUEST SENSE command issued from the
backend does not work as expected.
wait_scanner_ready is one of the functions of the backend using the
REQUEST SENSE command (probably the most important):
static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss)
{
static char me[] = "wait_scanner_ready";
SANE_Status status;
int retries;
DBG (DL_CALL_TRACE, "%s\n", me);
for (retries = 5; retries; retries--)
{
status = test_unit_ready (pss);
if (status == SANE_STATUS_GOOD)
{
status = request_sense (pss);
switch (status)
{
case SANE_STATUS_GOOD:
return status;
case SANE_STATUS_DEVICE_BUSY:
/* first additional sense byte contains time to wait */
{
int delay = pss->asi1 + 1;
DBG (DL_INFO,
"%s: scanner warming up. Waiting %ld
seconds.\n",
me,
(long) delay);
sleep (delay);
}
break;
case SANE_STATUS_IO_ERROR:
/* hardware error; bail */
DBG (DL_MAJOR_ERROR, "%s: hardware error detected.\n",
me);
return status;
default:
DBG (DL_MAJOR_ERROR,
"%s: unhandled request_sense result; trying
again.\n",
me);
break;
}
}
}
return status;
}
So the basic logic is: if TEST UNIT READY fails, return an error; if
TEST UNIT READY succeeds, issue REQUEST SENSE to read the warm up time
(this time is stored at offset 18 in the sense buffer; this value is
copied into pss->asi1 in the function request_sense). If REQUEST SENSE
returns DEVICE BUSY, sleep for pss->asi1 seconds.
With the borrowed 1236, this does not seem to work.
If I run "scanimage -d snapscan:/dev/sg2" immediately after powering up
the scanner, the program bails out without starting a scan. The debug
message "scanner warming up" does not appear. The reason is, that TEST
UNIT READY returns "busy" for at least 10 seconds after power up, so
that the "if (status == SANE_STATUS_GOOD)" section is never run. A few
seconds later, scanimage runs without any errors.
So I tried the following version of wait_scanner_ready:
static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss)
{
static char me[] = "wait_scanner_ready";
SANE_Status status;
int retries;
DBG (DL_CALL_TRACE, "%s\n", me);
for (retries = 20; retries; retries--)
{
status = test_unit_ready(pss);
if (status == SANE_STATUS_DEVICE_BUSY)
{
DBG(DL_INFO, "wait_scanner: sleeping (%i)...\n",
retries);
sleep(1);
}
else
return status;
}
return status;
}
This version of wait_scanner_ready works better than the "official" one:
After powering up the scanner, the "for (retries..." loop is executed 12
or 13 times; later, TEST UNIT READY succeeds immediately. And it avoids
the explicit issueing of REQUEST SENSE.
If have no access to other scanners supported by the Snapscan backend
(and to the 1236 only for a limited time), neither do I have access to
any documentation for these scanner, so I can't tell, if the original
logic of wait_scanner_ready is reasonable for other scanner.
But if the current "official" version of wait_scanner_ready is simply
based on a misunderstanding of the REQUEST SENSE logic in a multitasking
OS (and the fact, that the Snapscan obviously stores the expected warm
up/power up time at offest 18 in the sense buffer, which is difficult to
access, if only 18 or 16 sense buffer bytes are returned), it might be
reasonble, if the Snapscan maintainers improve the current version. This
might not only solve headaches for people using the Snapscan backend
under Linux -- I don't know, how the other OS supported by Sane will
respond to a REQUEST SENSE command issued from usert space.
Abel
PS: Jürgen, sorry for causing perhaps unnecessary work...
-- Source code, list archive, and docs: http://www.mostang.com/sane/ To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com
This archive was generated by hypermail 2b29 : Tue Jan 16 2001 - 08:52:55 PST