[sane-devel] Reflecta ProScan 7200

Vleeshouwers, J.M. J.M.Vleeshouwers at tue.nl
Sat Jul 30 15:00:29 UTC 2011

Hi Michael,

I agree with you that the scratch removal implementation should be high
on the priority list. I remember having seen outlines of an algorithm,
do you have any need for them?

Five other remarks: on scanner hangs/cancelling, on the model number, on
the READ SETTINGS-command (0xd7), on the status-buye(s) and on PIE/PIE2.

With respect to driver robustness, I did some regular Windows logs.
They don't give any information we did not yet know, except for the SCAN(0)
which I did not encouter in the logs yet. (But you did, apparently.)

This is a typical Cyberview scan run (with a count-down timer alongside):
10:00 switch on, start Cyberview after 10 seconds
 8:42 preview
 7:53 start scan 1800 dpi TIF & let it complete
 7:15 start scan 1800 dpi TIF
 6:00 cancel @ 50% - option abort scan
 5:14 start scan 1800 dpi TIF
 4:56 cancel @ 50% - option abort scan & process
 4:18 ready

Both cancelled scans have an incomplete list of SCSI READs (which follow
COPY and PARAM to transfer the slide data to the host).
After the last READ comes:
a. SCAN (0x1b) with size 0 and with a 03-02-status response
b. REQUEST SENSE (0x03) 70000b0000000006000000000006 =>
   0x0b = ABORTED_COMMAND : 0x0006 = Received ABORT message from initiator
c. RELEASE SCANNER (0xd2) after a 3s wait, repeated for as long as the
   command status is 03-08 (busy)

Your reader process does just this, I assume?

I also rebuilt VirtualBox to allow me to intercept and change USB transfers
sent to the scanner by Cyberview. The first experiments with this seem to
indicate that the Windows driver lacks facilities to recover from a hanging
I intercepted the ff8778e0 sequence (the SCSI-prefix) and changed it to
ff877801. Now Cyberview won't even start. The logs show that the scanner
stops responding at the 2nd byte of the first INQUIRY-command that is sent
to the scanner in the initialisation phase. Trying to start Cyberview
again does not create any additional USB-traffic.
What also hangs the scanner is if a SCSI WRITE-command is not followed by
the exact number of bytes as specified in its size-byte. So I intercepted
the first WRITE (0x0a) - Set Scan Frame (0x13) and set its command size to
4 (should be 8). This hangs Cyberview, at the 7th (!?) data byte of this
WRITE command. The VirtualBox-log indicates that the device seems
to have disappeared (with three exclamation marks):
vusbUrbQueueAsyncRh: pDev=a72dd7c0[a1933c40[proxy 05e3:0145]] rc=ERR_DNR
  a=1 e=0 d=out t=control cb=0x9(9) Ed=00000000 cTds=0 Td0=ffffffff ts=0
  (42385420880532 ns ago) ShortOk
vusbUrbQueueAsyncRh: CTRL: bmRequestType=0x40 (host2dev vendor dev)
  bRequest=0x0c (SYNCH_FRAME) wValue=0x0085 wIndex=0x9588 wLength=0x0001
  NESTED MSG: pDev=a72dd7c0[a1933c40[proxy 05e3:0145]] rc=OK a=1 e=0 d=out
  t=control-part cb=0x1(1) Ed=00001000 cTds=1 Td0=00001080 ts=42385418688669
  (3104645 ns ago) ShortOk
vusbUrbQueueAsyncRh: returns VERR_VUSB_DEVICE_NOT_ATTACHED (queue_urb)
vusbMsgDoTransfer: failed submitting urb! failing it with DNR

Looks like we can't do better than be prepared for a hanging scanner and
if this occurs, exit with an apology and an instruction to switch the scanner
off and on again. Do you know if this can be done without having to restart
SANE? Would be very preferrable...

Maybe we should also try to document the situations in which the scanner
is vulnerable for hanging. The vulnerable situation I observe most
frequently (using my own warm-up routine) is the phase during warm-up when
there is scanning activity. If a READ STATUS command is issued, the scanner
sometimes hangs at the 2nd command byte, as if the SCSI-prefix did not get
Concluding from differences in the scanner noise, it looks as if it pauses
the scanning when servicing the READ STATUS command. (The standard noise is a
continuous rattle for some seconds, but if VirtualBox is busy logging
USB-activity, the noise changes into a series of short rattles and pauses.)
I can imagine that this internal activity switching might be critical.
Maybe we should leave the scanner alone for a longer amount of time once we
detect a sense of "in the process of becoming ready" during the warm-up
phase. There may also be a relationship with the 150ms waits which are
inserted between a TEST UNIT READY and a GET STATUS command (see the logs),
even if a TEST UNIT READY just returns a 0x03-0x00 status.

My experience with libusb_reset_device() is that it only disconnects the
scanner, but there is no subsequent reconnection. You still have to switch
the scanner off and on to get it to work again. (Not sure about if
re-attaching the cable works, probably not.)

With respect to the different scanner models we appear to own: I found a
file CyberViewX.ini in C:\Documents and Settings\Jan\Application Data\
PIE\SF, which on its very last lines says:
  Scanner Model=48
Since 48 = 0x30, it looks like your hunch is probably right. Does your
file say "Scanner Model=54"?

With respect to the 103-bytes of data retrieved by READ SETINGS (0xd2): we
considered the 20 bytes at offset 76 to be fixed, but they are not. Even in
the standard snoops I did, they vary slightly - another puzzle.

I focused a bit more on the status returned after each SCSI-command (1 or 2
bytes), with this conclusion:
Return:    Meaning:
0x00       OK, device is ready to send data
0x01       OK, device is ready to receive data
0x03       Read 2nd status byte:
  0x00       OK, command and data (if any) handled successfully 
  0x02       Not OK, next command should be REQUEST SENSE
  0x08       Not OK, device busy, retry command after pause

Finally, with respect to creating a 2nd PIE-branch. There are in fact three
projects: (1) From a SCSI-persepective we have scanner models which differ
from the ones already implemented in the PIE-backend (no hardware gamma
correction, infrared). That would require an update of the PIE-backend.
(2) If I understand you correctly, the infrared capability is something
that requires updating the SANE standard. I don't know what the implications
are but I should consider this a separate topic. (3) And finally there is
the USB-wrapper (pie_usb.c) which is currently much less scanner independent
as I originally expected it to become.
I think if you are starting to get lost in if-then-else branches, it is
time to start a separate PIE-backend. And since it is highly unlikely there
will ever be SCSI-scanners corresponding to our USB-scanners, integrate
pie_usb.c and call the backend PIEUSB. It will probably result in a much more
maintainable driver.

Enough for today, yours,


More information about the sane-devel mailing list