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; }
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; }
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; }