Hi Mitsuru,
> I tried to write the Calibration function as follows.
> Are they correct ?
They are in general correct -- but they _might_ be one problem: The
command code 0xc1, 0xc2 and so on are "vendor specific", meaning that
they are not part of the SCSI standard. And here, the function
sanei_scsi_cmd has a serious problem: The SCSI command itself and data
is placed into _one_ buffer. The SCSI command consists of the first 6,
10 or 12 bytes of the buffer; the remaining part of the of the buffer is
the data to be sent to the scanner. On the way "down to the SCSI bus",
these two parts - command block and data block - must be separated. For
most operating systems, this is done in sanei_scsi.c, function
sanei_scsi_cmd; for older versions of the Linux SG driver, it is done by
the SG driver.
The problem is in any case, that either the SG driver or sanei_scsi_cmd
must "guess" the command length. This works fine for well standardized
commands, but the guess was wrong for the "set adf mode" command (0xd4)
and the "get scan mode" command (0xd5) for Canon scanners. For the old
SG driver, Manuel Panea suggested a patch to the SG driver, but of
course that did not help for other operatiing systems. Therefore, I
introduced the function sanei_scsi_cmd2 (and sanei_scsi_req_enter2 --
but this funtion is not used in the Canon backend), which allows to use
separate buffers for the command and the data, and which allows to
declare explicitly the command length.
Therefore, if your functions return only some error, you should consider
to use sanei_scsi_cmd2. Below are the suggsted modifications, assuming
that all SCSI commands you are using are 6 byte commands.
The function sanei_scsi_cmd2 has the following parameters:
sanei_scsi_cmd2(fd, const void* cmd, size_t cmd_size,
const void* src, size_t src_size,
void* dst, size_t* dst_size)
fd is the file descriptor
cmd points to the SCSI command block (6 or 10 or 12 bytes)
cmd_size gives the command length (6 or 10 or 12)
src points to a data block to be sent to the scanner
src_size gives the length of the data block to be sent
dst points to a buffer that will store the data returned by the scanner
dst_size gives on entry to the function the epected size of the data
returned by the scanner; on return it contains the number of
bytes actually returned.
A SCSI command can either send data to the device or it can receive data
from the device. Thus, it should not happen that both dst and src are
non-zero. Practically:
src dst result
0 0 no data transfer
non-zero 0 send data to the scanner
0 non-zero receive data from the scanner
non-zero non-zero forbidden
> for canon-scsi.c
(that's the correct place, I think)
> ===================================================================
> static SANE_Status
> reset_scanner (int fd)
> {
> static u_char cmd[10];
> int status;
> DBG (31, ">> reset_scanner\n");
>
> memset (cmd, 0, sizeof (cmd));
> cmd[0] = 0xc1;
> status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
status = sanei_scsi_cmd2(fd, cmd, sizeof (cmd), 0, 0, 0, 0);
Perhaps you need to try the function above with "static u_char cmd[6];"
or with "static u_char cmd[12];" Or you can try
status = sanei_scsi_cmd2(fd, cmd, 6, 0, 0, 0, 0);
>
> DBG (31, "<< reset_scanner\n");
> return (status);
> }
>
> static SANE_Status
> execute_calibration (int fd)
> {
> static u_char cmd[6 + 2];
> int status;
> DBG (31, ">> execute_calibration\n");
> memset (cmd, 0, sizeof (cmd));
> cmd[0] = 0xc2;
> cmd[4] = 2;
> status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
> DBG (31, "<< execute_calibration\n");
> return (status);
> }
With sanei_scsi_cmd2, this function might be:
static SANE_Status
execute_calibration (int fd)
{
static u_char cmd[6]; /* or 10 or 12... */
u_char data[2];
int status;
DBG (31, ">> execute_calibration\n");
memset (cmd, 0, sizeof (cmd));
memset (data, 0, sizeof (data));
cmd[0] = 0xc2;
cmd[4] = 2;
status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), data, sizeof(data),
0, 0);
DBG (31, "<< execute_calibration\n");
return (status);
}
>
> static SANE_Status
> get_calibration_status (int fd, void *buf, size_t *buf_size)
> {
> static u_char cmd[6]; /* or 10 or 12 */
> int status;
> DBG (31, ">> get_calibration_status\n");
> memset (cmd, 0, sizeof (cmd));
> cmd[0] = 0xc3;
> cmd[4] = 2;
> status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
Try
status = sanei_scsi_cmd2(fd, cmd, sizeof (cmd), 0, 0, buf,
buf_size);
> DBG (31, "<< get_calibration_status\n");
> return (status);
> }
>
> static SANE_Status
> get_switch_status (int fd, void *buf, size_t *buf_size)
> {
> static u_char cmd[6]; /* or 10 or 12 ?? */
> int status;
> DBG (31, ">> get_switch_status\n");
> memset (cmd, 0, sizeof (cmd));
> cmd[0] = 0xc4;
> cmd[4] = 2;
> status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
Try
status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), 0, 0, buf,
buf_size);
> DBG (31, "<< get_switch_status\n");
> return (status);
> }
The call to the calibration functions should happen in sane_start, I
think. The idea of calibration is to compensate changing illumination
conditions. Especially after switching on the scanner, the lamp needs
some time to heat up into a "stable" state. Before the lamp stabilizes,
the spectral distribution of the emitted light may change. Thus, it is
probably best to do the calibration immediately before a scan starts.
> ===================================================================
>
> for canon.c or canon-sane.c
> ===================================================================
> status = reset_scanner(s->fd);
> if (status != SANE_STATUS_GOOD)
> {
> DBG (1, "attach: RESET SCANNER failed\n");
> sanei_scsi_close (s->fd);
> s->fd = -1;
> }
>
> status = execute_calibration(s->fd);
> if (status != SANE_STATUS_GOOD)
> {
> DBG (1, "attach: EXECUTE CALIBRATION failed\n");
> sanei_scsi_close (s->fd);
> s->fd = -1;
> }
>
> DBG (3, "sane_start: sending GET CALIBRATION STATUS\n");
> memset (ebuf, 0, sizeof (ebuf));
> buf_size = sizeof (ebuf);
> status = get_calibration_status (s->fd, ebuf, &buf_size);
> if (status != SANE_STATUS_GOOD)
> {
> DBG (1, "sane_start: GET CALIBRATION STATUS failed\n");
> sanei_scsi_close (s->fd);
> return (SANE_STATUS_INVAL);
> }
>
> DBG (3, "sane_start: sending GET SWITCH STATUS\n");
> memset (ebuf, 0, sizeof (ebuf));
> buf_size = sizeof (ebuf);
> status = get_switch_status (s->fd, ebuf, &buf_size);
> if (status != SANE_STATUS_GOOD)
> {
> DBG (1, "sane_start: GET SWITCH STATUS failed\n");
> sanei_scsi_close (s->fd);
> return (SANE_STATUS_INVAL);
> }
bye
Abel
-- 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 : Fri Dec 08 2000 - 11:58:44 PST