Example #1
0
static int
handle_interrupt (pixma_t * s, int timeout)
{
  uint8_t buf[16];
  int len;

  len = pixma_wait_interrupt (s->io, buf, sizeof (buf), timeout);
  if (len == PIXMA_ETIMEDOUT)
    return 0;
  if (len < 0)
    return len;
  switch (s->cfg->pid)
    {
    case MP360_PID:
    case MP370_PID:
    case MP375R_PID:
    case MP390_PID:
    case MF5730_PID:
    case MF5750_PID:
    case MF5770_PID:
    case MF3110_PID:
    case IR1020_PID:
      if (len != 16)
	{
	  PDBG (pixma_dbg
		(1, "WARNING:unexpected interrupt packet length %d\n", len));
	  return PIXMA_EPROTO;
	}
      if (buf[12] & 0x40)
	query_status (s);
      if (buf[10] & 0x40)
	send_time (s);
      /* FIXME: following is unverified! */
      if (buf[15] & 1)
	s->events = PIXMA_EV_BUTTON2;	/* b/w scan */
      if (buf[15] & 2)
	s->events = PIXMA_EV_BUTTON1;	/* color scan */
      break;

    case MP700_PID:
    case MP730_PID:
    case MP710_PID:
    case MP740_PID:
      if (len != 8)
	{
	  PDBG (pixma_dbg
		(1, "WARNING:unexpected interrupt packet length %d\n", len));
	  return PIXMA_EPROTO;
	}
      if (buf[7] & 0x10)
	s->events = PIXMA_EV_BUTTON1;
      if (buf[5] & 8)
	send_time (s);
      break;

    default:
      PDBG (pixma_dbg (1, "WARNING:unknown interrupt, please report!\n"));
      PDBG (pixma_hexdump (1, buf, len));
    }
  return 1;
}
Example #2
0
static int
mp730_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
{
  int error, n;
  mp730_t *mp = (mp730_t *) s->subdriver;
  unsigned block_size, bytes_received;
  uint8_t header[16];

  do
    {
      do
	{
	  if (s->cancel)
	    return PIXMA_ECANCELED;
	  if (mp->last_block)           /* end of image */
	      return 0;

	  error = read_image_block (s, header, mp->imgbuf + mp->imgbuf_len);
	  if (error < 0)
	    return error;

	  bytes_received = error;
	  block_size = pixma_get_be16 (header + 4);
	  mp->last_block = ((header[2] & 0x28) == 0x28);
	  if (mp->last_block)
	    {    /* end of image */
	      mp->state = state_finished;
	    }
	  if ((header[2] & ~0x38) != 0)
	    {
	      PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n"));
	      PDBG (pixma_hexdump (1, header, 16));
	    }
	  PASSERT (bytes_received == block_size);

	  if (block_size == 0)
	    {
	      /* no image data at this moment. */
	      /*pixma_sleep(100000); *//* FIXME: too short, too long? */
	      handle_interrupt (s, 100);
            }
	}
      while (block_size == 0);

      /* TODO: simplify! */
      mp->imgbuf_len += bytes_received;
      n = mp->imgbuf_len / s->param->line_size;
      /* n = number of full lines (rows) we have in the buffer. */
      if (n != 0)
	{
	  if (s->param->channels != 1    &&
	      s->cfg->pid != MF5730_PID  &&
	      s->cfg->pid != MF5750_PID  &&
	      s->cfg->pid != MF5770_PID  &&
	      s->cfg->pid != MF3110_PID  &&
	      s->cfg->pid != IR1020_PID)
	    {
	      /* color, and not an MF57x0 nor MF3110 */
	      pack_rgb (mp->imgbuf, n, mp->raw_width, mp->lbuf);
	    }
	  else
             /* grayscale/lineart or MF57x0 or MF3110 */
             memcpy (mp->lbuf, mp->imgbuf, n * s->param->line_size);

	  block_size = n * s->param->line_size;
	  mp->imgbuf_len -= block_size;
	  memcpy (mp->imgbuf, mp->imgbuf + block_size, mp->imgbuf_len);
	}
    }
  while (n == 0);

  ib->rptr = mp->lbuf;
  ib->rend = mp->lbuf + block_size;
  return ib->rend - ib->rptr;
}
Example #3
0
static int
iclass_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
{
  int error, n;
  iclass_t *mf = (iclass_t *) s->subdriver;
  unsigned block_size, lines_size, first_block_size;
  uint8_t info;

/*
 * 1. send a block request cmd (d4 20 00... 04 00 06)
 * 2. examine the response for block size and/or end-of-scan flag
 * 3. read the block one chunk at a time
 * 4. repeat until have enough to process >=1 lines
 */
  do
    {
      do
        {
          if (s->cancel)
            return PIXMA_ECANCELED;
          if (mf->last_block)
            {
              /* end of image */
              mf->state = state_finished;
              return 0;
            }

          first_block_size = 0;
          error = request_image_block (s, 4, &info, &block_size, 
                          mf->blkptr + mf->blk_len, &first_block_size);
          /* add current block to remainder of previous */
          mf->blk_len += first_block_size;
          if (error < 0)
            {
              /* NOTE: seen in traffic logs but don't know the meaning. */
              read_error_info (s, NULL, 0);
              if (error == PIXMA_ECANCELED)
                return error;
            }

          /* info: 0x28 = end; 0x38 = end + ADF empty */
          mf->last_block = info & 0x38;
          if ((info & ~0x38) != 0)
            {
              PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n"));
              PDBG (pixma_hexdump (1, &info, 1));
            }

          if (block_size == 0)
            {
              /* no image data at this moment. */
              /*pixma_sleep(100000); *//* FIXME: too short, too long? */
              handle_interrupt (s, 100);
            }
        }
      while (block_size == 0 && first_block_size == 0);

      error = read_image_block (s, mf->blkptr + mf->blk_len, block_size);
      block_size = error;
      if (error < 0)
        return error;

      /* add current block to remainder of previous */
      mf->blk_len += block_size;
      /* n = number of full lines (rows) we have in the buffer. */
      n = mf->blk_len / s->param->line_size;
      if (n != 0)
        {
          if (s->param->channels != 1 &&
                  s->cfg->pid != MF3010_PID &&
                  s->cfg->pid != MF4410_PID &&
                  s->cfg->pid != MF4770_PID &&
	          s->cfg->pid != MF4550_PID &&
	          s->cfg->pid != MF4600_PID &&
	          s->cfg->pid != MF6500_PID &&
	          s->cfg->pid != MF8030_PID)
            {
              /* color and not MF46xx or MF65xx */
              pack_rgb (mf->blkptr, n, mf->raw_width, mf->lineptr);
            }
          else
            {
              /* grayscale */
              memcpy (mf->lineptr, mf->blkptr, n * s->param->line_size);
            }
          lines_size = n * s->param->line_size;
          /* cull remainder and shift left */
          mf->blk_len -= lines_size;
          memcpy (mf->blkptr, mf->blkptr + lines_size, mf->blk_len);
        }
    }
  while (n == 0);

  /* output full lines, keep partial lines for next block */
  ib->rptr = mf->lineptr;
  ib->rend = mf->lineptr + lines_size;
  return ib->rend - ib->rptr;
}