[sane-devel] sanei_scsi.c and OpenStep
Oliver Schirrmeister
oschirr@abm.de
Wed, 22 May 2002 15:24:54 +0200
<nofill>Hi,
there is a bug in function sanei_scsi_cmd2() for OPENSTEP.
1. sr_cdb_length is not set in the scsi_req struct.
It works most times without setting the length but in some cases
this leads to a strange behaviour.
2. The status of the scsi-call by ioctl can be SR_IOST_CHKSNV. This
is the same as SR_IOST_CHKSV but sr_esense is invalid. You should
call request_sense but I don't know how. You could return SANE_STATUS_IO_ERROR
what is not correct but better than returning SANE_STATUS_GOOD.
Here is my changed version. It works fine in my environment. Could somebody apply
these changes to the cvs, please.
Oliver
sanei_scsi_cmd2 (int fd,
const void *cmd, size_t cmd_size,
const void *src, size_t src_size,
void *dst, size_t * dst_size)
{
struct scsi_req hdr;
/* xxx obsolete size_t cdb_size;
cdb_size = CDB_SIZE (*(u_char *) src);
*/
memset (&hdr, 0, sizeof (hdr));
memcpy (&hdr.sr_cdb, cmd, cmd_size);
hdr.sr_cdb_length=cmd_size; <<- added
if (dst_size && *dst_size)
{
/* xxx obsolete assert (cdb_size == src_size);
*/
hdr.sr_dma_dir = SR_DMA_RD;
hdr.sr_addr = dst;
hdr.sr_dma_max = *dst_size;
}
else
{
/* xxx obsolete assert (cdb_size <<= src_size);
*/
hdr.sr_dma_dir = SR_DMA_WR;
hdr.sr_addr = (char *) src;
hdr.sr_dma_max = src_size;
}
hdr.sr_ioto = SANE_SCSICMD_TIMEOUT; /* I/O timeout in seconds */
if (ioctl (fd, SGIOCREQ, &hdr) == -1)
{
DBG (1, "sanei_scsi_cmd: ioctl(SGIOCREQ) failed: %s\n",
strerror (errno));
return SANE_STATUS_IO_ERROR;
}
if (hdr.sr_io_status != 1)
DBG (1, "sanei_scsi_cmd: SGIOCREQ completed with sr_io_status=%d\n",
hdr.sr_io_status);
if (hdr.sr_io_status == SR_IOST_CHKSNV) <<--- added
{
</nofill> /* call request_sense again but how???*/
...
return SANE_STATUS_IO_ERROR;
}
<<--- added
<nofill>
if (hdr.sr_scsi_status == SR_IOST_CHKSV && fd_info[fd].sense_handler)
return (*fd_info[fd].sense_handler) (fd, (u_char *) & hdr.sr_esense,
fd_info[fd].sense_handler_arg);
if (dst_size)
*dst_size = hdr.sr_dma_xfr;
return SANE_STATUS_GOOD;
}
</nofill>