1 /* SANE - Scanner Access Now Easy.
2 
3    Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de>
4    Copyright (C) 2007-2008 Nicolas Martin, <nicols-guest at alioth dot debian dot org>
5    Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
6 
7    This file is part of the SANE package.
8 
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 
22    As a special exception, the authors of SANE give permission for
23    additional uses of the libraries contained in this release of SANE.
24 
25    The exception is that, if you link a SANE library with other files
26    to produce an executable, this does not by itself cause the
27    resulting executable to be covered by the GNU General Public
28    License.  Your use of that executable is in no way restricted on
29    account of linking the SANE library code into it.
30 
31    This exception does not, however, invalidate any other reasons why
32    the executable file might be covered by the GNU General Public
33    License.
34 
35    If you submit changes to SANE to the maintainers to be included in
36    a subsequent release, you agree by submitting the changes that
37    those changes may be distributed with this exception intact.
38 
39    If you write modifications of your own for SANE, it is your choice
40    whether to permit this exception to apply to your modifications.
41    If you do not wish that, delete this exception notice.
42  */
43 #include "../include/sane/config.h"
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h>		/* localtime(C90) */
49 
50 #include "pixma_rename.h"
51 #include "pixma_common.h"
52 #include "pixma_io.h"
53 
54 
55 #ifdef __GNUC__
56 # define UNUSED(v) (void) v
57 #else
58 # define UNUSED(v)
59 #endif
60 
61 #define IMAGE_BLOCK_SIZE (0xc000)
62 #define CMDBUF_SIZE 512
63 
64 #define MP10_PID 0x261f
65 
66 #define MP730_PID 0x262f
67 #define MP700_PID 0x2630
68 
69 #define MP5_PID 0x2635          /* untested */
70 
71 #define MP360_PID 0x263c
72 #define MP370_PID 0x263d
73 #define MP390_PID 0x263e
74 #define MP375R_PID 0x263f       /* untested */
75 
76 #define MP740_PID 0x264c	/* Untested */
77 #define MP710_PID 0x264d
78 
79 #define MF5630_PID 0x264e	/* Untested */
80 #define MF5650_PID 0x264f
81 #define MF5730_PID 0x265d	/* Untested */
82 #define MF5750_PID 0x265e	/* Untested */
83 #define MF5770_PID 0x265f
84 #define MF3110_PID 0x2660
85 
86 #define IR1020_PID 0x26e6
87 
88 enum mp730_state_t
89 {
90   state_idle,
91   state_warmup,
92   state_scanning,
93   state_transfering,
94   state_finished
95 };
96 
97 enum mp730_cmd_t
98 {
99   cmd_start_session = 0xdb20,
100   cmd_select_source = 0xdd20,
101   cmd_gamma         = 0xee20,
102   cmd_scan_param    = 0xde20,
103   cmd_status        = 0xf320,
104   cmd_abort_session = 0xef20,
105   cmd_time          = 0xeb80,
106   cmd_read_image    = 0xd420,
107   cmd_error_info    = 0xff20,
108 
109   cmd_activate      = 0xcf60,
110   cmd_calibrate     = 0xe920
111 };
112 
113 typedef struct mp730_t
114 {
115   enum mp730_state_t state;
116   pixma_cmdbuf_t cb;
117   unsigned raw_width;
118   uint8_t current_status[12];
119 
120   uint8_t *buf, *imgbuf, *lbuf;
121   unsigned imgbuf_len;
122 
123   unsigned last_block:1;
124 } mp730_t;
125 
126 
127 static void mp730_finish_scan (pixma_t * s);
128 
129 static int
has_paper(pixma_t * s)130 has_paper (pixma_t * s)
131 {
132   mp730_t *mp = (mp730_t *) s->subdriver;
133   return (mp->current_status[1] == 0);
134 }
135 
136 static void
drain_bulk_in(pixma_t * s)137 drain_bulk_in (pixma_t * s)
138 {
139   mp730_t *mp = (mp730_t *) s->subdriver;
140   while (pixma_read (s->io, mp->imgbuf, IMAGE_BLOCK_SIZE) >= 0);
141 }
142 
143 static int
abort_session(pixma_t * s)144 abort_session (pixma_t * s)
145 {
146   mp730_t *mp = (mp730_t *) s->subdriver;
147   return pixma_exec_short_cmd (s, &mp->cb, cmd_abort_session);
148 }
149 
150 static int
query_status(pixma_t * s)151 query_status (pixma_t * s)
152 {
153   mp730_t *mp = (mp730_t *) s->subdriver;
154   uint8_t *data;
155   int error;
156 
157   data = pixma_newcmd (&mp->cb, cmd_status, 0, 12);
158   error = pixma_exec (s, &mp->cb);
159   if (error >= 0)
160     {
161       memcpy (mp->current_status, data, 12);
162       PDBG (pixma_dbg (3, "Current status: paper=%u cal=%u lamp=%u\n",
163 		       data[1], data[8], data[7]));
164     }
165   return error;
166 }
167 
168 static int
activate(pixma_t * s, uint8_t x)169 activate (pixma_t * s, uint8_t x)
170 {
171   mp730_t *mp = (mp730_t *) s->subdriver;
172   uint8_t *data = pixma_newcmd (&mp->cb, cmd_activate, 10, 0);
173   data[0] = 1;
174   data[3] = x;
175   return pixma_exec (s, &mp->cb);
176 }
177 
178 static int
start_session(pixma_t * s)179 start_session (pixma_t * s)
180 {
181   mp730_t *mp = (mp730_t *) s->subdriver;
182   return pixma_exec_short_cmd (s, &mp->cb, cmd_start_session);
183 }
184 
185 static int
select_source(pixma_t * s)186 select_source (pixma_t * s)
187 {
188   mp730_t *mp = (mp730_t *) s->subdriver;
189   uint8_t *data = pixma_newcmd (&mp->cb, cmd_select_source, 10, 0);
190   switch (s->param->source)
191     {
192     case PIXMA_SOURCE_ADF:
193       data[0] = 2;
194       break;
195 
196     case PIXMA_SOURCE_ADFDUP:
197       data[0] = 2;
198       data[5] = 3;
199       break;
200 
201     default:
202       data[0] = 1;
203       break;
204     }
205   return pixma_exec (s, &mp->cb);
206 }
207 
208 static int
send_scan_param(pixma_t * s)209 send_scan_param (pixma_t * s)
210 {
211   mp730_t *mp = (mp730_t *) s->subdriver;
212   uint8_t *data;
213 
214   data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x2e, 0);
215   pixma_set_be16 (s->param->xdpi | 0x1000, data + 0x04);
216   pixma_set_be16 (s->param->ydpi | 0x1000, data + 0x06);
217   pixma_set_be32 (s->param->x, data + 0x08);
218   pixma_set_be32 (s->param->y, data + 0x0c);
219   pixma_set_be32 (mp->raw_width, data + 0x10);
220   pixma_set_be32 (s->param->h, data + 0x14);
221 
222   if (s->param->channels == 1)
223     {
224       if (s->param->depth == 1)
225         data[0x18] = 0x01;
226       else
227         data[0x18] = 0x04;
228     }
229   else
230     data[0x18] = 0x08;
231 
232   data[0x19] = s->param->channels * s->param->depth;  /* bits per pixel, for lineart should be 0x01 */
233   data[0x1e] = (s->param->depth == 1) ? 0x80 : 0x00;  /* modify for lineart: 0x80 NEW */
234   data[0x1f] = (s->param->depth == 1) ? 0x80 : 0x7f;  /* modify for lineart: 0x80 */
235   data[0x20] = (s->param->depth == 1) ? 0x01 : 0xff;  /* modify for lineart: 0x01 */
236   data[0x23] = 0x81;
237 
238   return pixma_exec (s, &mp->cb);
239 }
240 
241 static int
calibrate(pixma_t * s)242 calibrate (pixma_t * s)
243 {
244   mp730_t *mp = (mp730_t *) s->subdriver;
245   return pixma_exec_short_cmd (s, &mp->cb, cmd_calibrate);
246 }
247 
248 static int
read_image_block(pixma_t * s, uint8_t * header, uint8_t * data)249 read_image_block (pixma_t * s, uint8_t * header, uint8_t * data)
250 {
251   static const uint8_t cmd[10] =	/* 0xd420 cmd */
252   { 0xd4, 0x20, 0, 0, 0, 0, 0, IMAGE_BLOCK_SIZE / 256, 4, 0 };
253   mp730_t *mp = (mp730_t *) s->subdriver;
254   const int hlen = 2 + 4;
255   int error, datalen;
256 
257   mp->state = state_transfering;
258   mp->cb.reslen =
259     pixma_cmd_transaction (s, cmd, sizeof (cmd), mp->cb.buf, 512);
260   datalen = mp->cb.reslen;
261   if (datalen < 0)
262     return datalen;
263 
264   memcpy (header, mp->cb.buf, hlen);
265   if (datalen >= hlen)
266     {
267       datalen -= hlen;
268       memcpy (data, mp->cb.buf + hlen, datalen);
269       data += datalen;
270       if (mp->cb.reslen == 512)
271 	{
272 	  error = pixma_read (s->io, data, IMAGE_BLOCK_SIZE - 512 + hlen);
273 	  if (error < 0)
274 	    return error;
275 	  datalen += error;
276 	}
277     }
278 
279   mp->state = state_scanning;
280   mp->cb.expected_reslen = 0;
281   error = pixma_check_result (&mp->cb);
282   if (error < 0)
283     return error;
284   if (mp->cb.reslen < hlen)
285     return PIXMA_EPROTO;
286   return datalen;
287 }
288 
289 static int
send_time(pixma_t * s)290 send_time (pixma_t * s)
291 {
292   /* Why does a scanner need a time? */
293   time_t now;
294   struct tm *t;
295   uint8_t *data;
296   mp730_t *mp = (mp730_t *) s->subdriver;
297 
298   data = pixma_newcmd (&mp->cb, cmd_time, 20, 0);
299   pixma_get_time (&now, NULL);
300   t = localtime (&now);
301   strftime ((char *) data, 16, "%y/%m/%d %H:%M", t);
302   PDBG (pixma_dbg (3, "Sending time: '%s'\n", (char *) data));
303   return pixma_exec (s, &mp->cb);
304 }
305 
306 static int
handle_interrupt(pixma_t * s, int timeout)307 handle_interrupt (pixma_t * s, int timeout)
308 {
309   uint8_t buf[16];
310   int len;
311 
312   len = pixma_wait_interrupt (s->io, buf, sizeof (buf), timeout);
313   if (len == PIXMA_ETIMEDOUT)
314     return 0;
315   if (len < 0)
316     return len;
317   switch (s->cfg->pid)
318     {
319     case MP360_PID:
320     case MP370_PID:
321     case MP375R_PID:
322     case MP390_PID:
323     case MF5630_PID:
324     case MF5650_PID:
325     case MF5730_PID:
326     case MF5750_PID:
327     case MF5770_PID:
328     case MF3110_PID:
329     case IR1020_PID:
330       if (len != 16)
331 	{
332 	  PDBG (pixma_dbg
333 		(1, "WARNING:unexpected interrupt packet length %d\n", len));
334 	  return PIXMA_EPROTO;
335 	}
336       if (buf[12] & 0x40)
337 	query_status (s);
338       if (buf[10] & 0x40)
339 	send_time (s);
340       /* FIXME: following is unverified! */
341       if (buf[15] & 1)
342 	s->events = PIXMA_EV_BUTTON2;	/* b/w scan */
343       if (buf[15] & 2)
344 	s->events = PIXMA_EV_BUTTON1;	/* color scan */
345       break;
346 
347     case MP5_PID:
348     case MP10_PID:
349     case MP700_PID:
350     case MP730_PID:
351     case MP710_PID:
352     case MP740_PID:
353       if (len != 8)
354 	{
355 	  PDBG (pixma_dbg
356 		(1, "WARNING:unexpected interrupt packet length %d\n", len));
357 	  return PIXMA_EPROTO;
358 	}
359       if (buf[7] & 0x10)
360 	s->events = PIXMA_EV_BUTTON1;
361       if (buf[5] & 8)
362 	send_time (s);
363       break;
364 
365     default:
366       PDBG (pixma_dbg (1, "WARNING:unknown interrupt, please report!\n"));
367       PDBG (pixma_hexdump (1, buf, len));
368     }
369   return 1;
370 }
371 
372 static int
has_ccd_sensor(pixma_t * s)373 has_ccd_sensor (pixma_t * s)
374 {
375   return (s->cfg->pid == MP360_PID ||
376           s->cfg->pid == MP370_PID ||
377           s->cfg->pid == MP375R_PID ||
378           s->cfg->pid == MP390_PID ||
379           s->cfg->pid == MF5630_PID ||
380           s->cfg->pid == MF5650_PID ||
381           s->cfg->pid == MF5730_PID ||
382           s->cfg->pid == MF5750_PID ||
383           s->cfg->pid == MF5770_PID);
384 }
385 
386 static int
read_error_info(pixma_t * s, void *buf, unsigned size)387 read_error_info (pixma_t * s, void *buf, unsigned size)
388 {
389   unsigned len = 16;
390   mp730_t *mp = (mp730_t *) s->subdriver;
391   uint8_t *data;
392   int error;
393 
394   data = pixma_newcmd (&mp->cb, cmd_error_info, 0, len);
395   error = pixma_exec (s, &mp->cb);
396   if (error < 0)
397     return error;
398   if (buf && len < size)
399     {
400       size = len;
401       /* NOTE: I've absolutely no idea what the returned data mean. */
402       memcpy (buf, data, size);
403       error = len;
404     }
405   return error;
406 }
407 
408 static int
step1(pixma_t * s)409 step1 (pixma_t * s)
410 {
411   int error;
412 
413   error = query_status (s);
414   if (error < 0)
415     return error;
416   if ((s->param->source == PIXMA_SOURCE_ADF
417        || s->param->source == PIXMA_SOURCE_ADFDUP)
418       && !has_paper (s))
419     return PIXMA_ENO_PAPER;
420   if (has_ccd_sensor (s))
421     {
422       switch (s->cfg->pid)
423         {
424           case MF5630_PID:
425           case MF5650_PID:
426           case MF5730_PID:
427           case MF5750_PID:
428           case MF5770_PID:
429           /* MF57x0: Wait 10 sec before starting for 1st page only */
430             if (s->param->adf_pageid == 0)
431 	      {
432                 int tmo = 10;  /* like Windows driver, 10 sec CCD calibration ? */
433                 while (--tmo >= 0)
434                   {
435                     error = handle_interrupt (s, 1000);
436                     if (s->cancel)
437                       return PIXMA_ECANCELED;
438                     if (error != PIXMA_ECANCELED && error < 0)
439                       return error;
440                     PDBG (pixma_dbg (2, "CCD Calibration ends in %d sec.\n", tmo));
441                   }
442               }
443             break;
444 
445           default:
446             break;
447         }
448 
449       activate (s, 0);
450       error = calibrate (s);
451 
452       switch (s->cfg->pid)
453         {
454           case MF5630_PID:
455           case MF5650_PID:
456           case MF5730_PID:
457           case MF5750_PID:
458           case MF5770_PID:
459           /* MF57x0: calibration returns PIXMA_STATUS_FAILED */
460             if (error == PIXMA_ECANCELED)
461               error = read_error_info (s, NULL, 0);
462             break;
463 
464           default:
465             break;
466         }
467 
468       // ignore result from calibrate()
469       // don't interrupt @ PIXMA_STATUS_BUSY
470       error = 0;
471     }
472   if (error >= 0)
473     error = activate (s, 0);
474   if (error >= 0)
475     error = activate (s, 4);
476   return error;
477 }
478 
479 static void
pack_rgb(const uint8_t * src, unsigned nlines, unsigned w, uint8_t * dst)480 pack_rgb (const uint8_t * src, unsigned nlines, unsigned w, uint8_t * dst)
481 {
482   unsigned w2, stride;
483 
484   w2 = 2 * w;
485   stride = 3 * w;
486   for (; nlines != 0; nlines--)
487     {
488       unsigned x;
489       for (x = 0; x != w; x++)
490 	{
491 	  *dst++ = src[x + 0];
492 	  *dst++ = src[x + w];
493 	  *dst++ = src[x + w2];
494 	}
495       src += stride;
496     }
497 }
498 
499 static int
mp730_open(pixma_t * s)500 mp730_open (pixma_t * s)
501 {
502   mp730_t *mp;
503   uint8_t *buf;
504 
505   mp = (mp730_t *) calloc (1, sizeof (*mp));
506   if (!mp)
507     return PIXMA_ENOMEM;
508 
509   buf = (uint8_t *) malloc (CMDBUF_SIZE);
510   if (!buf)
511     {
512       free (mp);
513       return PIXMA_ENOMEM;
514     }
515 
516   s->subdriver = mp;
517   mp->state = state_idle;
518 
519   mp->cb.buf = buf;
520   mp->cb.size = CMDBUF_SIZE;
521   mp->cb.res_header_len = 2;
522   mp->cb.cmd_header_len = 10;
523   mp->cb.cmd_len_field_ofs = 7;
524 
525   PDBG (pixma_dbg (3, "Trying to clear the interrupt buffer...\n"));
526   if (handle_interrupt (s, 200) == 0)
527     {
528       PDBG (pixma_dbg (3, "  no packets in buffer\n"));
529     }
530   return 0;
531 }
532 
533 static void
mp730_close(pixma_t * s)534 mp730_close (pixma_t * s)
535 {
536   mp730_t *mp = (mp730_t *) s->subdriver;
537 
538   mp730_finish_scan (s);
539   free (mp->cb.buf);
540   free (mp->buf);
541   free (mp);
542   s->subdriver = NULL;
543 }
544 
545 static unsigned
calc_raw_width(pixma_t * s, const pixma_scan_param_t * sp)546 calc_raw_width (pixma_t * s, const pixma_scan_param_t * sp)
547 {
548   unsigned raw_width;
549   /* FIXME: Does MP730 need the alignment? */
550   /*  TODO test: MP710/740 */
551   if (sp->channels == 1)
552     {
553       if (sp->depth == 8)   /* grayscale  */
554         {
555           if (s->cfg->pid == MP5_PID   ||
556               s->cfg->pid == MP10_PID  ||
557               s->cfg->pid == MP700_PID ||
558               s->cfg->pid == MP730_PID ||
559               s->cfg->pid == MP360_PID ||
560               s->cfg->pid == MP370_PID ||
561               s->cfg->pid == MP375R_PID ||
562               s->cfg->pid == MP390_PID ||
563 	      s->cfg->pid == IR1020_PID)
564             raw_width = ALIGN_SUP (sp->w, 4);
565           else
566             raw_width = ALIGN_SUP (sp->w, 12);
567         }
568       else   /* depth = 1 : LINEART */
569         raw_width = ALIGN_SUP (sp->w, 16);
570     }
571   else
572     raw_width = ALIGN_SUP (sp->w, 4);
573   return raw_width;
574 }
575 
576 static int
mp730_check_param(pixma_t * s, pixma_scan_param_t * sp)577 mp730_check_param (pixma_t * s, pixma_scan_param_t * sp)
578 {
579   uint8_t k = 1;
580 
581   /* check if channels is 3, or if depth is 1 then channels also 1 else set depth to 8 */
582   if ((sp->channels==3) || !(sp->channels==1 && sp->depth==1))
583     {
584       sp->depth=8;
585     }
586   /* for MP5, MP10, MP360/370, MP700/730 in grayscale & lineart modes, max scan res is 600 dpi */
587   if (s->cfg->pid == MP5_PID   ||
588       s->cfg->pid == MP10_PID  ||
589       s->cfg->pid == MP700_PID ||
590       s->cfg->pid == MP730_PID ||
591       s->cfg->pid == MP360_PID ||
592       s->cfg->pid == MP370_PID ||
593       s->cfg->pid == MP375R_PID ||
594       s->cfg->pid == MP390_PID)
595     {
596       if (sp->channels == 1)
597           k = sp->xdpi / MIN (sp->xdpi, 600);
598     }
599 
600   sp->x /= k;
601   sp->y /= k;
602   sp->h /= k;
603   sp->xdpi /= k;
604   sp->ydpi = sp->xdpi;
605 
606   sp->w = calc_raw_width (s, sp);
607   sp->w /= k;
608   sp->line_size = (calc_raw_width (s, sp) * sp->channels * sp->depth) / 8;
609 
610   return 0;
611 }
612 
613 static int
mp730_scan(pixma_t * s)614 mp730_scan (pixma_t * s)
615 {
616   int error, n;
617   mp730_t *mp = (mp730_t *) s->subdriver;
618   uint8_t *buf;
619 
620   if (mp->state != state_idle)
621     return PIXMA_EBUSY;
622 
623   /* clear interrupt packets buffer */
624   while (handle_interrupt (s, 0) > 0)
625     {
626     }
627 
628   mp->raw_width = calc_raw_width (s, s->param);
629   PDBG (pixma_dbg (3, "raw_width = %u\n", mp->raw_width));
630 
631   n = IMAGE_BLOCK_SIZE / s->param->line_size + 1;
632   buf = (uint8_t *) malloc ((n + 1) * s->param->line_size + IMAGE_BLOCK_SIZE);
633   if (!buf)
634     return PIXMA_ENOMEM;
635   mp->buf = buf;
636   mp->lbuf = buf;
637   mp->imgbuf = buf + n * s->param->line_size;
638   mp->imgbuf_len = 0;
639 
640   error = step1 (s);
641   if (error >= 0)
642     error = start_session (s);
643   if (error >= 0)
644     mp->state = state_scanning;
645   if (error >= 0)
646     error = select_source (s);
647   if (error >= 0)
648     error = send_scan_param (s);
649   if (error < 0)
650     {
651       mp730_finish_scan (s);
652       return error;
653     }
654   mp->last_block = 0;
655   return 0;
656 }
657 
658 static int
mp730_fill_buffer(pixma_t * s, pixma_imagebuf_t * ib)659 mp730_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
660 {
661   int error, n;
662   mp730_t *mp = (mp730_t *) s->subdriver;
663   unsigned block_size, bytes_received;
664   uint8_t header[16];
665 
666   do
667     {
668       do
669 	{
670 	  if (s->cancel)
671 	    return PIXMA_ECANCELED;
672 	  if (mp->last_block)           /* end of image */
673 	      return 0;
674 
675 	  error = read_image_block (s, header, mp->imgbuf + mp->imgbuf_len);
676 	  if (error < 0)
677 	    return error;
678 
679 	  bytes_received = error;
680 	  block_size = pixma_get_be16 (header + 4);
681 	  mp->last_block = ((header[2] & 0x28) == 0x28);
682 	  if (mp->last_block)
683 	    {    /* end of image */
684 	      mp->state = state_finished;
685 	    }
686 	  if ((header[2] & ~0x38) != 0)
687 	    {
688 	      PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n"));
689 	      PDBG (pixma_hexdump (1, header, 16));
690 	    }
691 	  PASSERT (bytes_received == block_size);
692 
693 	  if (block_size == 0)
694 	    {
695 	      /* no image data at this moment. */
696 	      /*pixma_sleep(100000); *//* FIXME: too short, too long? */
697 	      handle_interrupt (s, 100);
698             }
699 	}
700       while (block_size == 0);
701 
702       /* TODO: simplify! */
703       mp->imgbuf_len += bytes_received;
704       n = mp->imgbuf_len / s->param->line_size;
705       /* n = number of full lines (rows) we have in the buffer. */
706       if (n != 0)
707 	{
708 	  if (s->param->channels != 1    &&
709 	      s->cfg->pid != MF5630_PID  &&
710 	      s->cfg->pid != MF5650_PID  &&
711 	      s->cfg->pid != MF5730_PID  &&
712 	      s->cfg->pid != MF5750_PID  &&
713 	      s->cfg->pid != MF5770_PID  &&
714 	      s->cfg->pid != MF3110_PID  &&
715 	      s->cfg->pid != IR1020_PID)
716 	    {
717 	      /* color, and not an MF57x0 nor MF3110 */
718 	      pack_rgb (mp->imgbuf, n, mp->raw_width, mp->lbuf);
719 	    }
720 	  else
721              /* grayscale/lineart or MF57x0 or MF3110 */
722              memcpy (mp->lbuf, mp->imgbuf, n * s->param->line_size);
723 
724 	  block_size = n * s->param->line_size;
725 	  mp->imgbuf_len -= block_size;
726 	  memcpy (mp->imgbuf, mp->imgbuf + block_size, mp->imgbuf_len);
727 	}
728     }
729   while (n == 0);
730 
731   ib->rptr = mp->lbuf;
732   ib->rend = mp->lbuf + block_size;
733   return ib->rend - ib->rptr;
734 }
735 
736 static void
mp730_finish_scan(pixma_t * s)737 mp730_finish_scan (pixma_t * s)
738 {
739   int error, aborted = 0;
740   mp730_t *mp = (mp730_t *) s->subdriver;
741 
742   switch (mp->state)
743     {
744     case state_transfering:
745       drain_bulk_in (s);
746       /* fall through */
747     case state_scanning:
748     case state_warmup:
749       aborted = 1;
750       error = abort_session (s);
751       if (error < 0)
752 	PDBG (pixma_dbg
753 	      (1, "WARNING:abort_session() failed %s\n",
754 	       pixma_strerror (error)));
755       /* fall through */
756     case state_finished:
757       query_status (s);
758       query_status (s);
759       activate (s, 0);
760 
761       // MF57x0 devices don't require abort_session() after the last page
762       if (!aborted &&
763           (s->param->source == PIXMA_SOURCE_ADF ||
764            s->param->source == PIXMA_SOURCE_ADFDUP) &&
765            has_paper (s) &&
766            (s->cfg->pid == MF5630_PID ||
767             s->cfg->pid == MF5650_PID ||
768             s->cfg->pid == MF5730_PID ||
769             s->cfg->pid == MF5750_PID ||
770             s->cfg->pid == MF5770_PID ||
771             s->cfg->pid == IR1020_PID))
772       {
773         error = abort_session (s);
774         if (error < 0)
775           PDBG (pixma_dbg
776                 (1, "WARNING:abort_session() failed %s\n",
777                  pixma_strerror (error)));
778       }
779 
780       mp->buf = mp->lbuf = mp->imgbuf = NULL;
781       mp->state = state_idle;
782       /* fall through */
783     case state_idle:
784       break;
785     }
786 }
787 
788 static void
mp730_wait_event(pixma_t * s, int timeout)789 mp730_wait_event (pixma_t * s, int timeout)
790 {
791   /* FIXME: timeout is not correct. See usbGetCompleteUrbNoIntr() for
792    * instance. */
793   while (s->events == 0 && handle_interrupt (s, timeout) > 0)
794     {
795     }
796 }
797 
798 static int
mp730_get_status(pixma_t * s, pixma_device_status_t * status)799 mp730_get_status (pixma_t * s, pixma_device_status_t * status)
800 {
801   int error;
802 
803   error = query_status (s);
804   if (error < 0)
805     return error;
806   status->hardware = PIXMA_HARDWARE_OK;
807   status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
808   return 0;
809 }
810 
811 
812 static const pixma_scan_ops_t pixma_mp730_ops = {
813   mp730_open,
814   mp730_close,
815   mp730_scan,
816   mp730_fill_buffer,
817   mp730_finish_scan,
818   mp730_wait_event,
819   mp730_check_param,
820   mp730_get_status
821 };
822 
823 /* TODO: implement adftpu_min_dpi & adftpu_max_dpi for grayscale & lineart */
824 #define DEVICE(name, model, pid, dpi, w, h, cap) {           \
825               name,              /* name */           \
826               model,             /* model */		      \
827               0x04a9, pid,       /* vid pid */	      \
828               1,                 /* iface */		      \
829               &pixma_mp730_ops,  /* ops */            \
830               0, 0,              /* min_xdpi & min_xdpi_16 not used in this subdriver */ \
831               dpi, dpi,          /* xdpi, ydpi */	    \
832               0, 0,              /* adftpu_min_dpi & adftpu_max_dpi not used in this subdriver */ \
833               0, 0,              /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */  \
834               w, h,              /* width, height */	\
835         PIXMA_CAP_GRAY|PIXMA_CAP_EVENTS|cap           \
836 }
837 const pixma_config_t pixma_mp730_devices[] = {
838 /* TODO: check area limits */
839   DEVICE ("PIXUS MP5/SmartBase MPC190/imageCLASS MPC190","MP5", MP5_PID, 600, 636, 868, PIXMA_CAP_LINEART),/* color scan can do 600x1200 */
840   DEVICE ("PIXUS MP10/SmartBase MPC200/imageCLASS MPC200","MP10", MP10_PID, 600, 636, 868, PIXMA_CAP_LINEART),/* color scan can do 600x1200 */
841   DEVICE ("PIXMA MP360", "MP360", MP360_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
842   DEVICE ("PIXMA MP370", "MP370", MP370_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
843   DEVICE ("PIXMA MP375R", "MP375R", MP375R_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
844   DEVICE ("PIXMA MP390", "MP390", MP390_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
845   DEVICE ("PIXMA MP700", "MP700", MP700_PID, 1200, 638, 877 /*1035 */ , PIXMA_CAP_LINEART),
846   DEVICE ("PIXMA MP710", "MP710", MP710_PID, 1200, 637, 868, PIXMA_CAP_LINEART),
847   DEVICE ("PIXMA MP730", "MP730", MP730_PID, 1200, 637, 868, PIXMA_CAP_ADF | PIXMA_CAP_LINEART),
848   DEVICE ("PIXMA MP740", "MP740", MP740_PID, 1200, 637, 868, PIXMA_CAP_ADF | PIXMA_CAP_LINEART),
849 
850   DEVICE ("Canon imageCLASS MF5630", "MF5630", MF5630_PID, 1200, 636, 868, PIXMA_CAP_ADF),
851   DEVICE ("Canon laserBase MF5650", "MF5650", MF5650_PID, 1200, 636, 868, PIXMA_CAP_ADF),
852   DEVICE ("Canon imageCLASS MF5730", "MF5730", MF5730_PID, 1200, 636, 868, PIXMA_CAP_ADF),
853   DEVICE ("Canon imageCLASS MF5750", "MF5750", MF5750_PID, 1200, 636, 868, PIXMA_CAP_ADF),
854   DEVICE ("Canon imageCLASS MF5770", "MF5770", MF5770_PID, 1200, 636, 868, PIXMA_CAP_ADF),
855   DEVICE ("Canon imageCLASS MF3110", "MF3110", MF3110_PID, 600, 636, 868, 0),
856 
857   DEVICE ("Canon iR 1020/1024/1025", "iR1020", IR1020_PID, 600, 636, 868, PIXMA_CAP_ADFDUP),
858 
859   DEVICE (NULL, NULL, 0, 0, 0, 0, 0)
860 };
861