Пример #1
0
/**
 * Waits for data being available while optionally polling motor. There is a timeout
 * to prevent scanner waiting forever non coming data.
 */
SANE_Status
sanei_rts88xx_wait_data (SANE_Int devnum, SANE_Bool busy, SANE_Word * count)
{
  SANE_Status status;
  SANE_Byte control;

  /* poll the available byte count until not 0 */
  while (SANE_TRUE)
    {
      status = sanei_rts88xx_data_count (devnum, count);
      if (*count != 0)
        {
          DBG (DBG_io, "sanei_rts88xx_wait_data: %d bytes available\n",
               *count);
          return SANE_STATUS_GOOD;
        }

      /* check that the scanner is busy scanning */
      if (busy)
        {
          sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
          if ((control & 0x08) == 0 && (*count == 0))
            {
              DBG (DBG_error,
                   "sanei_rts88xx_wait_data: scanner stopped being busy before data are available\n");
              return SANE_STATUS_IO_ERROR;
            }
        }
    }

  /* we hit timeout */
  return SANE_STATUS_IO_ERROR;
}
Пример #2
0
/* reads data from scanner.
 * First we wait for some data to be available and then loop reading
 * from scanner until the required amount is reached.
 * We handle non blocking I/O by returning immediatly (with SANE_STATUS_BUSY)
 * if there is no data available from scanner. But once read is started,
 * all the required amount is read. Once wait for data succeeded, we still poll
 * for data in order no to read it too fast, but we don' take care of non blocking
 * mode since we cope with it on first data wait.
 */
static SANE_Status
read_data (struct Rts8891_Session *session, SANE_Byte * dest, SANE_Int length)
{
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Int count, read, len, dummy;
  struct Rts8891_Device *dev = session->dev;
  static FILE *raw = NULL;	/* for debugging purpose we need it static */
  SANE_Byte control = 0x08;
  unsigned char buffer[RTS88XX_MAX_XFER_SIZE];

  DBG (DBG_proc, "read_data: start\n");
  DBG (DBG_proc, "read_data: requiring %d bytes\n", length);

  /* wait for data being available and handle non blocking mode */
  /* only when data reading hasn't produce any data yet */
  if (dev->read == 0)
    {
      do
	{
	  status = sanei_rts88xx_data_count (dev->devnum, &count);
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (DBG_error, "read_data: failed to wait for data\n");
	      return status;
	    }
	  if (count == 0)
	    {
	      sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	      if ((control & 0x08) == 0 && (count == 0))
		{
		  DBG (DBG_error,
		       "read_data: scanner stopped being busy before data are available\n");
		  return SANE_STATUS_IO_ERROR;
		}
	    }

	  /* in case there is no data, we return BUSY since this mean    */
	  /* that scanning head hasn't reach is position and data hasn't */
	  /* come yet */
	  if (session->non_blocking && count == 0)
	    {

	      dev->regs[LAMP_REG] = 0x8d;
	      sanei_rts88xx_write_reg (dev->devnum, LAMP_REG,
				       &(dev->regs[LAMP_REG]));
	      DBG (DBG_io, "read_data: no data vailable\n");
	      DBG (DBG_proc, "read_data: end\n");
	      return SANE_STATUS_DEVICE_BUSY;
	    }
	}
      while (count == 0);
    }
  else
    {				/* start of read for a new block */
      status = sanei_rts88xx_data_count (dev->devnum, &count);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "read_data: failed to wait for data\n");
	  return status;
	}
      if (count == 0)
	{
	  sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	  if ((control & 0x08) == 0 && (count == 0))
	    {
	      DBG (DBG_error,
		   "read_data: scanner stopped being busy before data are available\n");
	      return SANE_STATUS_IO_ERROR;
	    }
	}
    }

  /* fill scanned data buffer */
  read = 0;

  /* now loop reading data until we have the amount requested */
  /* we also take care of not reading too much data           */
  while (read < length && dev->read < dev->to_read
	 && ((control & 0x08) == 0x08))
    {
      /* used to sync */
      if (dev->read == 0)
	{
	  status = sanei_rts88xx_data_count (dev->devnum, &dummy);
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (DBG_error, "read_data: failed to read data count\n");
	      return status;
	    }
	}

      /* if there is data to read, read it */
      if (count > 0)
	{
	  len = count;

	  if (len > RTS88XX_MAX_XFER_SIZE)
	    {
	      len = RTS88XX_MAX_XFER_SIZE;
	    }

	  /* we only read even size blocks of data */
	  if (len & 1)
	    {
	      DBG (DBG_io, "read_data: round to next even number\n");
	      len++;
	    }

	  if (len > length - read)
	    {
	      len = length - read;
	    }

	  status = sanei_rts88xx_read_data (dev->devnum, &len, dest + read);
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (DBG_error, "read_data: failed to read from scanner\n");
	      return status;
	    }

	  /* raw data tracing */
	  if (DBG_LEVEL >= DBG_io2)
	    {
	      /* open a new file only when no data scanned */
	      if (dev->read == 0)
		{
		  raw = fopen ("raw_data.pnm", "wb");
		  if (raw != NULL)
		    {
		      /* PNM header */
		      fprintf (raw, "P%c\n%d %d\n255\n",
			       session->params.format ==
			       SANE_FRAME_RGB
			       || session->emulated_gray ==
			       SANE_TRUE ? '6' : '5', dev->pixels,
			       dev->lines);
		    }
		}
	      if (raw != NULL)
		{
		  fwrite (dest + read, 1, len, raw);
		}
	    }

	  /* move pointer and counter */
	  read += len;
	  dev->read += len;
	  DBG (DBG_io2, "read_data: %d/%d\n", dev->read, dev->to_read);
	}

      /* in fast scan mode, read data count
       * in slow scan, head moves by the amount of data read */
      status = sanei_rts88xx_data_count (dev->devnum, &count);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "read_data: failed to read data count\n");
	  return status;
	}

      /* if no data, check if still scanning */
      if (count == 0 && dev->read < dev->to_read)
	{
	  sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	  if ((control & 0x08) == 0x00)
	    {
	      DBG (DBG_error,
		   "read_data: scanner stopped being busy before data are available\n");
	      return SANE_STATUS_IO_ERROR;
	    }
	}
    }

  /* end of physical reads */
  if (dev->read >= dev->to_read)
    {
      /* check there is no more data in case of a bug */
      sanei_rts88xx_data_count (dev->devnum, &count);
      if (count > 0)
	{
	  DBG (DBG_warn,
	       "read_data: %d bytes are still available from scanner\n",
	       count);

	  /* flush left-over data */
	  while (count > 0)
	    {
	      len = count;
	      if (len > RTS88XX_MAX_XFER_SIZE)
		{
		  len = RTS88XX_MAX_XFER_SIZE;
		}

	      /* we only read even size blocks of data */
	      if (len & 1)
		{
		  len++;
		}
	      sanei_rts88xx_read_data (dev->devnum, &len, buffer);
	      sanei_rts88xx_data_count (dev->devnum, &count);
	    }
	}

      /* wait for motor to stop at the end of the scan */
      do
	{
	  sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	}
      while ((control & 0x08) != 0);

      /* close log file if needed */
      if (DBG_LEVEL >= DBG_io2)
	{
	  if (raw != NULL)
	    {
	      fclose (raw);
	      raw = NULL;
	    }
	}
    }

  DBG (DBG_io, "read_data: read %d bytes from scanner\n", length);
  DBG (DBG_proc, "read_data: end\n");
  return status;
}
Пример #3
0
/*
 * Does a simple scan based on the given register set, returning data in a
 * preallocated buffer of the claimed size.
 * sanei_rts88xx_data_count cannot be made reliable, when the announced data
 * amount is read, it may no be ready, leading to errors. To work around
 * it, we read data count one more time before reading.
 */
static SANE_Status
rts8891_simple_scan (SANE_Int devnum, SANE_Byte * regs, int regcount,
		     SANE_Int format, SANE_Word total, unsigned char *image)
{
  SANE_Word count, read, len, dummy;
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Byte control;

  rts8891_write_all (devnum, regs, regcount);
  rts8891_commit (devnum, format);

  read = 0;
  count = 0;
  while (count == 0)
    {
      status = sanei_rts88xx_data_count (devnum, &count);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "simple_scan: failed to wait for data\n");
	  return status;
	}
      if (count == 0)
	{
	  status = sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
	  if (((control & 0x08) == 0) || (status != SANE_STATUS_GOOD))
	    {
	      DBG (DBG_error, "simple_scan: failed to wait for data\n");
	      return SANE_STATUS_IO_ERROR;
	    }
	}
    }

  /* data reading */
  read = 0;
  while ((read < total) && (count != 0 || (control & 0x08) == 0x08))
    {
      /* sync ? */
      status = sanei_rts88xx_data_count (devnum, &dummy);

      /* read */
      if (count > 0)
	{
	  len = count;
	  /* read even size unless last chunk */
	  if ((len & 1) && (read + len < total))
	    {
	      len++;
	    }
	  if (len > RTS88XX_MAX_XFER_SIZE)
	    {
	      len = RTS88XX_MAX_XFER_SIZE;
	    }
	  if (len > 0)
	    {
	      status = sanei_rts88xx_read_data (devnum, &len, image + read);
	      if (status != SANE_STATUS_GOOD)
		{
		  DBG (DBG_error,
		       "simple_scan: failed to read from scanner\n");
		  return status;
		}
	      read += len;
	    }
	}

      /* don't try to read data count if we have enough data */
      if (read < total)
	{
	  status = sanei_rts88xx_data_count (devnum, &count);
	}
      else
	{
	  count = 0;
	}
      if (count == 0)
	{
	  sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
	}
    }

  /* sanity check */
  if (read < total)
    {
      DBG (DBG_io2, "simple_scan: ERROR, %d bytes missing ... \n",
	   total - read);
    }

  /* wait for the motor to stop */
  do
    {
      sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
    }
  while ((control & 0x08) == 0x08);

  return status;
}