* Updated to version 0.13.0

* Added MP160, MP180, MP460, MP510 and MP600
* Fixed a buffer-overflow bug in sane_read()
merge-requests/1/head
Wittawat Yamwong 2007-04-09 20:41:25 +00:00
rodzic d620d407bb
commit 459d5c7e8e
13 zmienionych plików z 246 dodań i 64 usunięć

Wyświetl plik

@ -1,3 +1,10 @@
2007-04-09 Wittawat Yamwong <wittawat@web.de>
* backend/pixma*.[ch] doc/sane-pixma.man doc/descriptions/pixma.desc:
Updated to version 0.13.0
Added MP160, MP180, MP460, MP510 and MP600
Fixed a buffer-overflow bug in sane_read()
2007-04-5 Jochen Eisinger <jochen@penguin-breeder.org>
* README.openbsd, tools/README, tools/openbsd/attach,

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -188,6 +188,7 @@ find_scanners (void)
cleanup_device_list ();
nscanners = pixma_find_scanners ();
PDBG (pixma_dbg (3, "pixma_find_scanners() found %u devices\n", nscanners));
dev_list =
(const SANE_Device **) calloc (nscanners + 1, sizeof (*dev_list));
if (!dev_list)
@ -413,7 +414,7 @@ control_string_option (pixma_sane_t * ss, SANE_Int n, SANE_Action a, void *v,
str = opt->def.s;
/* fall through */
case SANE_ACTION_SET_VALUE:
strncpy (opt->val.s, str, opt->sod.size);
strncpy (opt->val.s, str, opt->sod.size - 1);
*info |= opt->info;
break;
}
@ -798,7 +799,7 @@ reader_thread (void *arg)
sigemptyset (&sigs);
sigaddset (&sigs, SIGPIPE);
pthread_sigmask (SIG_BLOCK, &sigs, NULL);
#endif
#endif /* USE_PTHREAD */
return reader_loop (ss);
}
@ -1223,7 +1224,7 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
{
DECL_CTX;
int sum, n;
SANE_Byte temp[16];
SANE_Byte temp[60];
SANE_Status status;
if (len)
@ -1265,6 +1266,13 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
{
/* skip padding */
n = ss->sp.line_size - ss->byte_pos_in_line;
if (n > (int) sizeof (temp))
{
PDBG (pixma_dbg (3,
"Inefficient skip buffer. Should be %d\n",
n));
n = sizeof (temp);
}
status = read_image (ss, temp, n, &n);
if (n == 0)
break;

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -107,8 +107,8 @@ typedef u_int32_t uint32_t;
/** \name Version of the driver */
/**@{*/
#define PIXMA_VERSION_MAJOR 0
#define PIXMA_VERSION_MINOR 12
#define PIXMA_VERSION_BUILD 2
#define PIXMA_VERSION_MINOR 13
#define PIXMA_VERSION_BUILD 0
/**@}*/
/** \name Error codes */

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -497,7 +497,7 @@ pixma_open (unsigned devnr, pixma_t ** handle)
(2, "pixma_connect() failed %s\n", pixma_strerror (error)));
goto rollback;
}
strncpy (s->id, pixma_get_device_id (devnr), sizeof (s->id));
strncpy (s->id, pixma_get_device_id (devnr), sizeof (s->id) - 1);
s->ops = s->cfg->ops;
s->scanning = 0;
error = s->ops->open (s);

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -174,8 +174,10 @@ read_serial_number (scanner_info_t * si)
if (iSerialNumber != 0)
{
int iSerialNumber = ddesc[16];
/* Read the first language code. Assumed that there is at least one. */
if (get_string_descriptor (usb, 0, 0, 4, unicode) != SANE_STATUS_GOOD)
goto done;
/* Read the serial number string. */
status =
get_string_descriptor (usb, iSerialNumber,
unicode[3] * 256 + unicode[2],
@ -268,6 +270,8 @@ pixma_collect_devices (const struct pixma_config_t *const pixma_devices[])
si = first_scanner;
while (j < nscanners)
{
PDBG (pixma_dbg (3, "pixma_collect_devices() found %s at %s\n",
cfg->name, si->devname));
si->cfg = cfg;
read_serial_number (si);
si = si->next;

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -70,7 +70,12 @@
#define IMAGE_BLOCK_SIZE (512*1024)
#define CMDBUF_SIZE (4096 + 24)
#define DEFAULT_GAMMA 1.0
#define UNKNOWN_PID 0xffff
#define CANON_VID 0x04a9
/* Generation 1 */
#define MP150_PID 0x1709
#define MP170_PID 0x170a
#define MP450_PID 0x170b
@ -80,6 +85,14 @@
#define MP800R_PID 0x170e
#define MP830_PID 0x1713
/* Generation 2 */
#define MP160_PID 0x1714
#define MP180_PID 0x1715 /* FIXME */
#define MP460_PID 0x1716
#define MP510_PID 0x1717
#define MP600_PID 0x1718
/* TODO: #define MP600R_PID 0x1719 */
/* TODO: #define MP810_PID 0x171a */
enum mp150_state_t
{
@ -110,8 +123,9 @@ typedef struct mp150_t
enum mp150_state_t state;
pixma_cmdbuf_t cb;
uint8_t *imgbuf;
uint8_t current_status[12];
uint8_t current_status[16];
unsigned last_block;
int generation;
} mp150_t;
@ -174,8 +188,15 @@ static int
is_calibrated (pixma_t * s)
{
mp150_t *mp = (mp150_t *) s->subdriver;
if (mp->generation == 1)
{
return (mp->current_status[8] == 1);
}
else
{
return (mp->current_status[9] == 1);
}
}
static int
has_paper (pixma_t * s)
@ -250,6 +271,10 @@ select_source (pixma_t * s)
{
data[0] = (s->param->source == PIXMA_SOURCE_ADF) ? 2 : 1;
data[1] = 1;
if (mp->generation == 2)
{
data[5] = 1;
}
}
return pixma_exec (s, &mp->cb);
}
@ -261,6 +286,8 @@ send_gamma_table (pixma_t * s)
const uint8_t *lut = s->param->gamma_table;
uint8_t *data;
if (mp->generation == 1)
{
data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0);
data[0] = (s->param->channels == 3) ? 0x10 : 0x01;
pixma_set_be16 (0x1004, data + 2);
@ -268,20 +295,57 @@ send_gamma_table (pixma_t * s)
memcpy (data + 4, lut, 4096);
else
pixma_fill_gamma_table (DEFAULT_GAMMA, data + 4, 4096);
}
else
{
/* FIXME: Gamma table for 2nd generation: 1024 * uint16_le */
data = pixma_newcmd (&mp->cb, cmd_gamma, 2048 + 8, 0);
data[0] = 0x10;
pixma_set_be16 (0x0804, data + 2);
if (lut)
{
int i;
for (i = 0; i < 1024; i++)
{
int j = (i << 2) + (i >> 8);
data[4 + 2 * i + 0] = lut[j];
data[4 + 2 * i + 1] = lut[j];
}
}
else
{
int i;
pixma_fill_gamma_table (DEFAULT_GAMMA, data + 4, 2048);
for (i = 0; i < 1024; i++)
{
int j = (i << 1) + (i >> 9);
data[4 + 2 * i + 0] = data[4 + j];
data[4 + 2 * i + 1] = data[4 + j];
}
}
}
return pixma_exec (s, &mp->cb);
}
static unsigned
calc_raw_width (const pixma_scan_param_t * param)
calc_raw_width (const mp150_t * mp, const pixma_scan_param_t * param)
{
unsigned raw_width;
/* NOTE: Actually, we can send arbitary width to MP150. Lines returned
are always padded to multiple of 4 or 12 pixels. Is this valid for
other models, too? */
if (param->channels == 1)
if (mp->generation == 2)
{
raw_width = ALIGN (param->w, 32);
}
else if (param->channels == 1)
{
raw_width = ALIGN (param->w, 12);
}
else
{
raw_width = ALIGN (param->w, 4);
}
return raw_width;
}
@ -290,7 +354,7 @@ send_scan_param (pixma_t * s)
{
mp150_t *mp = (mp150_t *) s->subdriver;
uint8_t *data;
unsigned raw_width = calc_raw_width (s->param);
unsigned raw_width = calc_raw_width (mp, s->param);
data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0);
pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x04);
@ -313,13 +377,14 @@ query_status (pixma_t * s)
{
mp150_t *mp = (mp150_t *) s->subdriver;
uint8_t *data;
int error;
int error, status_len;
data = pixma_newcmd (&mp->cb, cmd_status, 0, 12);
status_len = (mp->generation == 1) ? 12 : 16;
data = pixma_newcmd (&mp->cb, cmd_status, 0, status_len);
error = pixma_exec (s, &mp->cb);
if (error >= 0)
{
memcpy (mp->current_status, data, 12);
memcpy (mp->current_status, data, status_len);
PDBG (pixma_dbg (3, "Current status: paper=%u cal=%u lamp=%u busy=%u\n",
data[1], data[8], data[7], data[9]));
}
@ -492,6 +557,7 @@ wait_until_ready (pixma_t * s)
static int
has_ccd_sensor (pixma_t * s)
{
/* TODO: add MP810 */
return (s->cfg->pid == MP800_PID || s->cfg->pid == MP830_PID
|| s->cfg->pid == MP800R_PID);
}
@ -531,8 +597,9 @@ mp150_open (pixma_t * s)
mp->cb.cmd_len_field_ofs = 14;
mp->imgbuf = buf + CMDBUF_SIZE;
mp->generation = (s->cfg->pid >= MP160_PID) ? 2 : 1;
/*query_status(s); */
query_status (s);
handle_interrupt (s, 200);
return 0;
}
@ -551,10 +618,15 @@ mp150_close (pixma_t * s)
static int
mp150_check_param (pixma_t * s, pixma_scan_param_t * sp)
{
UNUSED (s);
mp150_t *mp = (mp150_t *) s->subdriver;
sp->depth = 8; /* MP150 only supports 8 bit per channel. */
sp->line_size = calc_raw_width (sp) * sp->channels;
if (mp->generation == 2)
{
sp->x = ALIGN (sp->x, 32);
sp->y = ALIGN (sp->y, 32);
}
sp->line_size = calc_raw_width (mp, sp) * sp->channels;
return 0;
}
@ -658,8 +730,8 @@ mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
error = wait_until_ready (s);
if (error < 0)
return error;
pixma_sleep (1500000); /* No need to wait, actually, but Window's driver
* waits 1.5 sec. */
pixma_sleep (1000000); /* No need to sleep, actually, but Window's driver
* sleep 1.5 sec. */
mp->state = state_scanning;
mp->last_block = 0;
}
@ -774,7 +846,7 @@ static const pixma_scan_ops_t pixma_mp150_ops = {
#define DEVICE(name, pid, dpi, cap) { \
name, /* name */ \
0x04a9, pid, /* vid pid */ \
CANON_VID, pid, /* vid pid */ \
0, /* iface */ \
&pixma_mp150_ops, /* ops */ \
dpi, 2*(dpi), /* xdpi, ydpi */ \
@ -784,16 +856,32 @@ static const pixma_scan_ops_t pixma_mp150_ops = {
}
const pixma_config_t pixma_mp150_devices[] = {
/* TODO: PIXMA_CAP_CCD & PIXMA_CAP_CIS */
/* Generation 1: CIS */
DEVICE ("Canon PIXMA MP150", MP150_PID, 1200, 0),
DEVICE ("Canon PIXMA MP170", MP170_PID, 1200, 0),
DEVICE ("Canon PIXMA MP450", MP450_PID, 1200, 0),
DEVICE ("Canon PIXMA MP500", MP500_PID, 1200, 0),
DEVICE ("Canon PIXMA MP530", MP530_PID, 1200, PIXMA_CAP_ADF),
/* Generation 1: CCD */
DEVICE ("Canon PIXMA MP800", MP800_PID, 2400,
PIXMA_CAP_TPU | PIXMA_CAP_48BIT),
DEVICE ("Canon PIXMA MP800R", MP800R_PID, 2400,
PIXMA_CAP_TPU | PIXMA_CAP_48BIT),
DEVICE ("Canon PIXMA MP830", MP830_PID, 2400,
PIXMA_CAP_ADFDUP | PIXMA_CAP_48BIT),
/* Generation 2: CIS */
DEVICE ("Canon PIXMA MP160", MP160_PID, 600, 0),
DEVICE ("Canon PIXMA MP180", MP180_PID, 1200, 0),
DEVICE ("Canon PIXMA MP460", MP460_PID, 1200, 0),
DEVICE ("Canon PIXMA MP510", MP510_PID, 1200, 0),
DEVICE ("Canon PIXMA MP600", MP600_PID, 2400, 0),
DEVICE ("Canon PIXMA MP600R", UNKNOWN_PID, 2400, PIXMA_CAP_EXPERIMENT),
/* Generation 2: CCD */
DEVICE ("Canon PIXMA MP810", UNKNOWN_PID, 4800, PIXMA_CAP_EXPERIMENT), /* TPU, 4800x4800DPI */
DEVICE (NULL, 0, 0, 0)
};

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -60,6 +60,8 @@
#define CMDBUF_SIZE 512
#define MP360_PID 0x263c
#define MP370_PID 0x263d
#define MP390_PID 0x263e
#define MP700_PID 0x2630
#define MP730_PID 0x262f
@ -261,6 +263,8 @@ handle_interrupt (pixma_t * s, int timeout)
switch (s->cfg->pid)
{
case MP360_PID:
case MP370_PID:
case MP390_PID:
if (len != 16)
{
PDBG (pixma_dbg
@ -280,7 +284,6 @@ handle_interrupt (pixma_t * s, int timeout)
case MP700_PID:
case MP730_PID:
default:
if (len != 8)
{
PDBG (pixma_dbg
@ -292,6 +295,10 @@ handle_interrupt (pixma_t * s, int timeout)
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;
}
@ -299,7 +306,8 @@ handle_interrupt (pixma_t * s, int timeout)
static int
has_ccd_sensor (pixma_t * s)
{
return (s->cfg->pid == MP360_PID);
return (s->cfg->pid == MP360_PID || s->cfg->pid == MP370_PID
|| s->cfg->pid == MP390_PID);
}
static int
@ -370,6 +378,11 @@ mp730_open (pixma_t * s)
mp->cb.cmd_header_len = 10;
mp->cb.cmd_len_field_ofs = 7;
PDBG (pixma_dbg (3, "Trying to clear the interrupt buffer...\n"));
if (handle_interrupt (s, 200) == 0)
{
PDBG (pixma_dbg (3, " no packets in buffer\n"));
}
return 0;
}
@ -416,6 +429,11 @@ mp730_scan (pixma_t * s)
if (mp->state != state_idle)
return PIXMA_EBUSY;
/* clear interrupt packets buffer */
while (handle_interrupt (s, 0) > 0)
{
}
mp->raw_width = calc_raw_width (s->param);
PDBG (pixma_dbg (3, "raw_width = %u\n", mp->raw_width));
@ -484,8 +502,9 @@ mp730_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
if (block_size == 0)
{
/* no image data at this moment. */
pixma_sleep (100000); /* FIXME: too short, too long? */
}
/*pixma_sleep(100000); *//* FIXME: too short, too long? */
handle_interrupt (s, 100);
/*XXX*/}
}
while (block_size == 0);
@ -595,8 +614,10 @@ static const pixma_scan_ops_t pixma_mp730_ops = {
}
const pixma_config_t pixma_mp730_devices[] = {
/* TODO: check area limits */
DEVICE ("Canon SmartBase MP360", 0x263c, 1200, 636, 868, 0),
DEVICE ("Canon MultiPASS MP700", 0x2630, 1200, 638, 877 /*1035 */ , 0),
DEVICE ("Canon MultiPASS MP730", 0x262f, 1200, 637, 868, PIXMA_CAP_ADF),
DEVICE ("Canon SmartBase MP360", MP360_PID, 1200, 636, 868, 0),
DEVICE ("Canon SmartBase MP370", MP370_PID, 1200, 636, 868, 0),
DEVICE ("Canon SmartBase MP390", MP390_PID, 1200, 636, 868, 0),
DEVICE ("Canon MultiPASS MP700", MP700_PID, 1200, 638, 877 /*1035 */ , 0),
DEVICE ("Canon MultiPASS MP730", MP730_PID, 1200, 637, 868, PIXMA_CAP_ADF),
DEVICE (NULL, 0, 0, 0, 0, 0)
};

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.
@ -524,6 +524,7 @@ mp750_open (pixma_t * s)
mp->cb.cmd_header_len = 10;
mp->cb.cmd_len_field_ofs = 7;
handle_interrupt (s, 200);
workaround_first_command (s);
return 0;
}
@ -566,6 +567,11 @@ mp750_scan (pixma_t * s)
if (mp->state != state_idle)
return PIXMA_EBUSY;
/* clear interrupt packets buffer */
while (handle_interrupt (s, 0) > 0)
{
}
if (s->param->channels == 1)
mp->raw_width = ALIGN (s->param->w, 12);
else

Wyświetl plik

@ -1,6 +1,6 @@
/* SANE - Scanner Access Now Easy.
Copyright (C) 2006 Wittawat Yamwong <wittawat@web.de>
Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
This file is part of the SANE package.

Wyświetl plik

@ -11,12 +11,12 @@
; See doc/descriptions.txt for details.
:backend "pixma" ; name of backend
:version "0.12.2" ; version of backend (or "unmaintained")
:version "0.13.0" ; version of backend (or "unmaintained")
;:new :yes ; Is the backend new to this SANE release?
; :yes or :no
:manpage "sane-pixma" ; name of manpage (if it exists)
:url "http://home.arcor.de/wittawat/pixma/" ; backend's web page
:comment "Devices marked as experimantal are disabled by default. See the manual page for how to enable them."
;:comment "Devices marked as experimantal are disabled by default. See the manual page for how to enable them."
:devicetype :scanner ; start of a list of devices....
; other types: :stillcam, :vidcam,
@ -30,16 +30,20 @@
:usbid "0x04a9" "0x1709"
:status :good
:model "PIXMA MP160"
:interface "USB"
:usbid "0x04a9" "0x1714"
:status :minimal
:model "PIXMA MP170"
:interface "USB"
:usbid "0x04a9" "0x170a"
:status :good
:model "SmartBase MP360"
:model "PIXMA MP180"
:interface "USB"
:usbid "0x04a9" "0x263c"
:status :minimal
:comment "The scanner locks up sometimes."
:usbid "0x04a9" "0x1715"
:status :untested
:model "PIXMA MP450"
:interface "USB"
@ -47,27 +51,35 @@
:status :good
:comment "Scanner makes loud noise at 600 DPI."
:model "PIXMA MP460"
:interface "USB"
:usbid "0x04a9" "0x1716"
:status :untested
:model "PIXMA MP500"
:interface "USB"
:usbid "0x04a9" "0x170c"
:status :good
:model "PIXMA MP510"
:interface "USB"
:usbid "0x04a9" "0x1717"
:status :untested
:model "PIXMA MP530"
:interface "USB"
:usbid "0x04a9" "0x1712"
:status :good
:model "MultiPASS MP700"
:model "PIXMA MP600"
:interface "USB"
:usbid "0x04a9" "0x2630"
:status :basic
:comment "Same model as SmartBase MP700 Photo?"
:model "MultiPASS MP730"
:interface "USB"
:usbid "0x04a9" "0x262f"
:usbid "0x04a9" "0x1718"
:status :minimal
:comment "Do grayscale and ADF work? Same model as SmartBase MP730 Photo?"
;:model "PIXMA MP600R"
;:interface "USB"
;:usbid "0x04a9" "0x1719"
;:status :untested
:model "PIXMA MP750"
:interface "USB"
@ -99,8 +111,43 @@
:status :basic
:comment "No film scan."
;:model "PIXMA MP810"
;:interface "USB"
;:usbid "0x04a9" "0x171a"
;:status :untested
:model "PIXMA MP830"
:interface "USB"
:usbid "0x04a9" "0x1713"
:status :basic
:comment "Sigle-side ADF works but duplex doesn't work yet."
:model "SmartBase MP360"
:interface "USB"
:usbid "0x04a9" "0x263c"
:status :minimal
:comment "The scanner locks up sometimes."
:model "SmartBase MP370"
:interface "USB"
:usbid "0x04a9" "0x263d"
:status :minimal
:comment "The scanner locks up sometimes."
:model "SmartBase MP390"
:interface "USB"
:usbid "0x04a9" "0x263e"
:status :minimal
:comment "The scanner locks up sometimes."
:model "MultiPASS MP700"
:interface "USB"
:usbid "0x04a9" "0x2630"
:status :basic
:comment "Same model as SmartBase MP700 Photo?"
:model "MultiPASS MP730"
:interface "USB"
:usbid "0x04a9" "0x262f"
:status :minimal
:comment "Do grayscale and ADF work? Same model as SmartBase MP730 Photo?"

Wyświetl plik

@ -1,4 +1,4 @@
.TH "sane-pixma" "5" "26 August 2006" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH "sane-pixma" "5" "09 April 2007" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-pixma
.SH NAME
sane-pixma \- SANE backend for Canon PIXMA MP series
@ -17,11 +17,12 @@ PIXMA MP530, PIXMA MP800, PIXMA MP800R, PIXMA MP830,
MultiPASS MP700, PIXMA MP750 (no grayscale)
.RE
.PP
The following models are marked as experimental because they are not well
tested and/or the scanner sometimes hangs and must be switched off and on.
Therefore they are disabled by default. (See PIXMA_EXPERIMENT below)
The following models are not well tested and/or the scanner sometimes hangs
and must be switched off and on.
.PP
.RS
PIXMA MP160, PIXMA MP180, PIXMA MP460, PIXMA MP510, PIXMA MP600
.br
SmartBase MP360, MultiPASS MP730, PIXMA MP760, PIXMA MP780
.RE
.PP