[sane-devel] Problem with empty sense buffer in sanei_scsi (linux+hpusbscsi+vuescan)?

Douglas Gilbert dgilbert@interlog.com
Sun, 14 Oct 2001 21:37:55 -0400


Jose Paulo Moitinho de Almeida wrote:
> 
> On Thursday 04 October 2001 21:01, abel deuring wrote:
> > Jose Paulo Moitinho de Almeida wrote:
> > > Hello
> > >
> >.....
> >
> > Jose, it seems that you uncovered a serious problem in sanei_scsi.c --
> > but I'm afraid that a proper fix isn't that easy:
> >
> > 1. sanei_scsi.c passes the sense buffer to a callback function
> > (parameter sense_handler in sanei_scsi_open[_extended]) So a fix would
> > require patches to all backends that implement a sense handler.
> >
> > 2. As mentioned above, older versions of the Linux SG driver do not
> > return the length of the sense buffer. So, even if you would start to
> > patch sanei_scsi.c, the sense handlers would need to be aware that no
> > length information is available.
> >
> > 3. The patch needs to be applied to the implementations of
> > sanei_scsi_cmd resp. sanei_scsi_req_enter/sanei_scsi_req_wait for all
> > the operating systems supported by Sane.
> >
> > An easier way might perhaps be to return some "obviously invalid data"
> > like a string of 0 or 0xff in the case that the SG driver or its
> > counterparts for other OS do not return a valid sense buffer. (BTW, does
> > Byte 0 of the sense buffer contain the value 0xf0 or 0x70? If not, this
> > could be used to determine, if a valid sense buffer is available.)
> >
> 
> I now have the log, using the original sg driver, which is attached and
> states:
> 
> a) "sanei_scsi_open: using new SG header structure";
> 
> b) "sense buffer: 68 22 42 08 ff ff ff ff 00 00 00 00 00 00 00 00"
> 
> After reading Abel's message, rereading the code and looking at the log I
> think it is safe to say that the problem is here:
> 
>      if (   ((req->sgdata.sg3.hdr.info & SG_INFO_CHECK) != 0)
>              || (req->sgdata.sg3.hdr.sb_len_wr > 0 &&
>               ((req->sgdata.sg3.sense_buffer[0] & 0x7f) != 0)))
> 
> I don't have the scanner here, but from the log I had when tracing the
> problem, while in drivers/scsi/sg.c, sg_new_read, I dumped the following info:
> 
> masked_status 8 driver_status 0

Paulo,
The problem starts here, a masked_status of 8 corresponds
to a SCSI status of INTERMEDIATE. This implies the command
sent to the scanner had the link bit set in the control
field which is the last byte in every command descriptor
block. Perhaps the SANE backend driver wanted to invoke
linked commands, more likely, it is a mistake by the
backend driver. Anyway that SCSI status does not 
trigger auto-sense and therefore has no sense buffer 
associated with it. The lack of sense buffer is indicated 
by the sb_len_wr == 0.

> sense 0 0 0 0 0 0 0 0
> len=0 sbp 68 22 42 8 ff ff ff ff
> sb_len_wr 0

As expected.
 
> using the following piece of code
> 
>     printk(KERN_INFO "masked_status %x driver_status %x\n",
>           hp->masked_status, hp->driver_status);
>     printk(KERN_INFO "sense %x %x %x %x %x %x %x %x\n", srp->sense_b[0],
>           srp->sense_b[1], srp->sense_b[2], srp->sense_b[3],
>           srp->sense_b[4], srp->sense_b[5], srp->sense_b[6], srp->sense_b[7]);
>         if ((CHECK_CONDITION & hp->masked_status) ||
>             (DRIVER_SENSE & hp->driver_status)) {
>             int sb_len = sizeof(dummy_cmdp->sr_sense_buffer);
>             sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
>             len = 8 + (int)srp->sense_b[7]; /* Additional sense length field*/
>             len = (len > sb_len) ? sb_len : len;
>             if ((err = verify_area(VERIFY_WRITE, hp->sbp, len)))
>                 goto err_out;
>             __copy_to_user(hp->sbp, srp->sense_b, len);
>             hp->sb_len_wr = len;
>         }
>     }
>     printk(KERN_INFO "len=%d sbp %x %x %x %x %x %x %x %x\n", hp->sb_len_wr,
>                 hp->sbp[0], hp->sbp[1], hp->sbp[2],
>                 hp->sbp[3], hp->sbp[4], hp->sbp[5], hp->sbp[6], hp->sbp[7]);
>     printk(KERN_INFO "sb_len_wr %x\n", hp->sb_len_wr);
>     if (hp->masked_status || hp->host_status || hp->driver_status)
>           hp->info |= SG_INFO_CHECK;
> 
> So hrd.info ands with SG_INFO_CHECK and the sense buffer is sent to the
> handler.

As the last 2 lines of code indicate, SG_INFO_CHECK is
set whenever any of those statuses are non-zero.  

> This dump lead me to the conclusion that the error was downstream, but
> perhaps I am wrong.

Perhaps you could look upstream and see if that link
bit on the SCSI command is being set for a good reason.
 
> Should sg.c be modified, so that when SG_INFO_CHECK is set, the
> initialisation of the sense_buffer is done?

I have just put some more words in the sg documentation
(soon to be at: http://www.torque.net/sg/p/sg_v3_ho.html )
to emphasize that SG_INFO_CHECK does not always imply that
there will be a sense buffer.
 
> The possibility that there may be a problem somewhere else should not be
> excluded either. I am using a driver which is "fresh from the oven".

Hmm.
 
> PS: Most probably I will not be able to read my email until next Monday.
> Sorry for being so long, but didn't want to forget anything.

I have been away for the last week and so haven't
been able to respond before now.

--------------------------------------------------------------

abel deuring <adeuring@gmx.net> wrote:
> Maybe, but I think that older versions of the SG driver 
> do not return the length of sense data read from a device. 
> (Douglas, can you confirm this?)

Abel,
Yes, that is correct. To get around this, apps like cdrecord
and paranoia would pre-fill the sense buffer with zeroes and
then look for a change when the command completed.


Doug Gilbert