[sane-devel] sanei_scsi.c and OpenStep

Oliver Schirrmeister oschirr@abm.de
Wed, 22 May 2002 15:24:54 +0200


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.


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;
      /* 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",

  if (hdr.sr_io_status == SR_IOST_CHKSNV)                              <<--- added
</nofill>       /* call request_sense again but how???*/                           

      return SANE_STATUS_IO_ERROR;

                          <<--- added

  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,

  if (dst_size)
    *dst_size = hdr.sr_dma_xfr;