[sane-devel] FreeBSD and Microtek Scanmaker II

abel deuring a.deuring@satzbau-gmbh.de
Tue, 17 Jun 2003 23:30:44 +0200

Nakal wrote:
> On Tuesday 17 June 2003 00:16, abel deuring wrote:
>>What I meant, was a combination of the log output of the Sane SCVSI
>>library and of the Microtek backend ;)
> This is the output of:
> SANE_DEBUG_SANEI_SCSI=128 scanimage -v -d 'microtek:/dev/scanner' 
> --mode color -y 50 > microtek-on-fbsd48.log 2>&1
> I'm sorry for flooding the mailing list with my logs,

Never mind, a few kilobytes are OK, IMHO.

First a disclaimer for the following stuff: I don't have FreeBSD 
installed, I used it only rarely, and I never wrote software 
specifically for FreeBSD. So I am writing as a "backseat driver" ;)

Looking through the log, it seems to me that something is wrong in 
sanei_scsi.c. From your log file:

[microtek] .stop_scan...
[microtek] SPS:1b  0  0  0  0  0
[sanei_scsi] sanei_scsi_cmd: scsi returned with status 10
[microtek] SENSE!  fd = 0
[microtek] sense = 00 00 00 00.
scanimage: min/max graylevel value = 21/255
[microtek] sane_start...

The "stop scan" command returns an error (the "sanei_scsi" line), and 
all following SCSI commands return errors too.

The interesting point is this: For some the commands we have the line 
"scsi returned with status 10", for other commands we have the line 
"scsi returned with status 16". Since the sense handler is called for 
both status values, I assume that you are using FreeBSD's CAM interface. 
(The other FreeBSD SCSI interface calls the sense handler of the backend 
only for a single status value.)

This is the relevant part of sanei_scsi.c:

    if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
       SANEI_SCSI_Sense_Handler handler;

       DBG (1, "sanei_scsi_cmd: scsi returned with status %d\n",
            (ccb->ccb_h.status & CAM_STATUS_MASK));

       if((ccb->ccb_h.status & CAM_STATUS_MASK)
          return SANE_STATUS_DEVICE_BUSY;

       handler = fd_info[fd].sense_handler;
       if (handler) {
          SANE_Status st = (*handler) (fd,
          return st;
          return SANE_STATUS_IO_ERROR;

Googling quickly for 'freebsd cam.h', I found a version of cam.h at 
and found these definitions for the status values 10 and 16:

10 -> CAM_SEL_TIMEOUT,	/* Target Selection Timeout */
16 -> CAM_AUTOSENSE_FAIL = 0x10,/* Autosense: request sense cmd fail */

(definitions of this kind tend to be stable -- but control is better 
than trust some cases: Martin, can you confirm this for your version of 

OK, many commands fail with a selection time out. Not very surprising 
for a slow scanner with probably somewhat dumb firmware ;) This status 
means that the scanner simply did not accept the SCSI command, so it 
does not make sense to call the sense handler, but the sense handler is 
called anyway. (Fortunately, the CAM system sets the sense data to all 
zero, so that the backend doesn't become completely confused...)

If this happens, sanei_scsi_cmd2 should return SANE_STATUS_DEVICE_BUSY, 
and the backend should retry to issue the command for a few times.

It is perhaps enough to change the following part:

       if((ccb->ccb_h.status & CAM_STATUS_MASK)
          return SANE_STATUS_DEVICE_BUSY;


       if((ccb->ccb_h.status & CAM_STATUS_MASK)
          == CAM_SEL_TIMEOUT)
          return SANE_STATUS_DEVICE_BUSY;

to fix at least some a part of the problem, but the backend will 
probably also need some patches...

Another point: From reading cam.h, I think that the sense handler should 
only be called, if the bit CAM_AUTOSNS_VALID is set in ccb_h.status.

Generally, I have the impression that the FreeBSD/CAM part of 
sanei_scsi.c could need a review. But that should be done by somebody 
who can run Sane under FreeBSD ;)