From 8e38974a3e4904df89e5fb6a00803ada4652b800 Mon Sep 17 00:00:00 2001 From: "m. allan noah" Date: Mon, 8 Dec 2008 03:47:35 +0000 Subject: [PATCH] * backend/canon_dr.[ch], backend/canon_dr-cmd.h: backend v8 - rename read/send_counter to read/send_panel - enable control panel during init - add options for all buttons - call TUR twice in wait_scanner(), even if first succeeds - disable rif - enable brightness/contrast/threshold options * doc/descriptions/canon_dr.desc, doc/sane-canon_dr.man: backend v8 --- ChangeLog | 22 +++- backend/canon_dr-cmd.h | 83 ++++++------- backend/canon_dr.c | 208 ++++++++++++++++++++++++++------- backend/canon_dr.h | 45 ++++--- doc/descriptions/canon_dr.desc | 4 +- doc/sane-canon_dr.man | 10 +- 6 files changed, 248 insertions(+), 124 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33f43c53d..6a3c8649c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,21 @@ -2008-12-06 Louis Lagendijk - * replaced getlogin/getenv by getpwuid(geteuid) +2008-12-07 m. allan noah + * backend/canon_dr.[ch], backend/canon_dr-cmd.h: backend v8 + - rename read/send_counter to read/send_panel + - enable control panel during init + - add options for all buttons + - call TUR twice in wait_scanner(), even if first succeeds + - disable rif + - enable brightness/contrast/threshold options + * doc/descriptions/canon_dr.desc, doc/sane-canon_dr.man: backend v8 2008-12-06 Louis Lagendijk - * backend/pixma_bjnp.c pixma_bjnp_private.h - On Ubuntu getlogin() returns NULL. So we noew first try getlogin() - and if that fails, we try getenv("USER") and if that fails we use - a defaul user string + * replaced getlogin/getenv by getpwuid(geteuid) + +2008-12-06 Louis Lagendijk + * backend/pixma_bjnp.c pixma_bjnp_private.h + On Ubuntu getlogin() returns NULL. So we noew first try getlogin() + and if that fails, we try getenv("USER") and if that fails we use + a defaul user string 2008-12-03 Stéphane Voltz * backend/rts8891.c backend/rts8891_low.c: possible fix for diff --git a/backend/canon_dr-cmd.h b/backend/canon_dr-cmd.h index e887d08e7..71c515e86 100644 --- a/backend/canon_dr-cmd.h +++ b/backend/canon_dr-cmd.h @@ -202,28 +202,41 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) #define GET_WINDOW_code 0x25 #define GET_WINDOW_len 0 +/* ==================================================================== */ +/* READ/SEND page codes */ +#define SR_datatype_image 0x00 +#define SR_datatype_lut 0x83 +#define SR_datatype_panel 0x84 +#define SR_datatype_counters 0x8c +#define SR_datatype_endorser 0x90 + /* ==================================================================== */ /* READ */ #define READ_code 0x28 #define READ_len 10 -#define set_R_datatype_code(sb, val) sb[0x02] = val -#define R_datatype_imagedata 0x00 -#define R_datatype_pixelsize 0x80 -#define R_datatype_counter 0x84 -#define set_R_window_id(sb, val) sb[0x05] = val +#define set_R_datatype_code(sb, val) sb[0x02] = val #define set_R_xfer_length(sb, val) putnbyte(sb + 0x06, val, 3) -/*pixelsize*/ -#define R_PSIZE_len 0x18 -#define get_PSIZE_num_x(in) getnbyte(in + 0x00, 4) -#define get_PSIZE_num_y(in) getnbyte(in + 0x04, 4) -#define get_PSIZE_paper_w(in) getnbyte(in + 0x08, 4) -#define get_PSIZE_paper_l(in) getnbyte(in + 0x0C, 4) +/*image needs no macros?*/ -/*counter*/ -#define R_COUNTER_len 0x08 -#define get_R_COUNTER_count(in) getnbyte(in + 0x04, 4) +/*lut unread?*/ + +/*panel*/ +#define R_PANEL_len 0x08 +#define get_R_PANEL_start(in) getbitfield(in, 1, 7) +#define get_R_PANEL_stop(in) getbitfield(in, 1, 6) +#define get_R_PANEL_new_file(in) getbitfield(in+1, 1, 0) +#define get_R_PANEL_count_only(in) getbitfield(in+1, 1, 1) +#define get_R_PANEL_bypass_mode(in) getbitfield(in+1, 1, 2) +#define get_R_PANEL_enable_led(in) getbitfield(in+2, 1, 0) +#define get_R_PANEL_counter(in) getnbyte(in + 0x04, 4) + +/*counters*/ +#define R_COUNTERS_len 0x80 +#define get_R_COUNTERS_scans(in) getnbyte(in + 0x04, 4) + +/*endorser unread?*/ /* ==================================================================== */ /* SEND */ @@ -231,40 +244,18 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) #define SEND_len 10 #define set_S_xfer_datatype(sb, val) sb[0x02] = (unsigned char)val -/*#define S_datatype_imagedatai 0x00 -#define S_datatype_halftone_mask 0x02 -#define S_datatype_gamma_function 0x03*/ -#define S_datatype_lut_data 0x83 -#define S_datatype_counter 0x84 -/*#define S_datatype_jpg_q_table 0x88*/ -#define S_datatype_endorser_data 0x90 -/*#define S_EX_datatype_lut 0x01 -#define S_EX_datatype_shading_data 0xa0 -#define S_user_reg_gamma 0xc0 -#define S_device_internal_info 0x03 -#define set_S_datatype_qual_upper(sb, val) sb[0x04] = (unsigned char)val -#define S_DQ_none 0x00 -#define S_DQ_Rcomp 0x06 -#define S_DQ_Gcomp 0x07 -#define S_DQ_Bcomp 0x08 -#define S_DQ_Reg1 0x01 -#define S_DQ_Reg2 0x02 -#define S_DQ_Reg3 0x03*/ -#define set_S_xfer_id(sb, val) putnbyte(sb + 4, val, 2) -#define set_S_xfer_length(sb, val) putnbyte(sb + 6, val, 3) +#define set_S_xfer_id(sb, val) putnbyte(sb + 4, val, 2) +#define set_S_xfer_length(sb, val) putnbyte(sb + 6, val, 3) /*lut*/ -#define S_lut_header_len 0x0a -#define set_S_lut_order(sb, val) putnbyte(sb + 2, val, 1) -#define S_lut_order_single 0x10 -#define set_S_lut_ssize(sb, val) putnbyte(sb + 4, val, 2) -#define set_S_lut_dsize(sb, val) putnbyte(sb + 6, val, 2) -#define S_lut_data_min_len 256 -#define S_lut_data_max_len 1024 -/*counter*/ -#define S_COUNTER_len 0x08 -#define set_S_COUNTER_count(sb,val) putnbyte(sb + 0x04, val, 4) +/*panel*/ +#define S_PANEL_len 0x08 +#define set_S_PANEL_enable_led(in,val) setbitfield(in+2, 1, 0, val) +#define set_S_PANEL_counter(sb,val) putnbyte(sb + 0x04, val, 4) + +/*counters*/ +/*endorser*/ /* ==================================================================== */ /* OBJECT_POSITION */ @@ -316,8 +307,10 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) /* for DF page */ #define set_SSM_DF_unk1(sb, val) setbitfield(sb+7, 1, 5, val) +#define set_SSM_DF_staple(sb, val) setbitfield(sb+7, 1, 4, val) #define set_SSM_DF_len(sb, val) setbitfield(sb+7, 1, 0, val) #define set_SSM_DF_thick(sb, val) setbitfield(sb+7, 1, 2, val) +#define set_SSM_DF_textdir(sb, val) setbitfield(sb+9, 0xf, 0, val) /* for DUPLEX page */ #define set_SSM_BUFF_duplex(sb, val) sb[0x06] = val diff --git a/backend/canon_dr.c b/backend/canon_dr.c index 6e34175ed..194f50826 100644 --- a/backend/canon_dr.c +++ b/backend/canon_dr.c @@ -102,6 +102,13 @@ - rename buffer option to buffermode to avoid conflict with scanimage - send ssm_do and ssm_df during sane_start - improve sense_handler output + v8 2008-12-07, MAN + - rename read/send_counter to read/send_panel + - enable control panel during init + - add options for all buttons + - call TUR twice in wait_scanner(), even if first succeeds + - disable rif + - enable brightness/contrast/threshold options SANE FLOW DIAGRAM @@ -162,7 +169,7 @@ #include "canon_dr.h" #define DEBUG 1 -#define BUILD 7 +#define BUILD 8 /* values for SANE_DEBUG_CANON_DR env var: - errors 5 @@ -544,6 +551,15 @@ attach_one (const char *device_name, int connType) return ret; } + /* enable/read the buttons */ + ret = init_panel (s); + if (ret != SANE_STATUS_GOOD) { + disconnect_fd(s); + free (s); + DBG (5, "attach_one: model failed\n"); + return ret; + } + /* sets SANE option 'values' to good defaults */ ret = init_user (s); if (ret != SANE_STATUS_GOOD) { @@ -607,6 +623,7 @@ connect_fd (struct scanner *s) else if (s->connection == CONNECTION_USB) { DBG (15, "connect_fd: opening USB device\n"); ret = sanei_usb_open (s->device_name, &(s->fd)); + ret = sanei_usb_clear_halt(s->fd); } else { DBG (15, "connect_fd: opening SCSI device\n"); @@ -880,13 +897,17 @@ init_model (struct scanner *s) s->reverse_by_mode[MODE_COLOR] = 0; s->can_color = 1; - s->has_rif = 1; + s->has_rif = 0; s->has_adf = 1; s->has_duplex = 1; s->has_buffer = 1; s->has_back = 0; s->has_comp_JPEG = 0; + s->brightness_steps = 255; + s->contrast_steps = 255; + s->threshold_steps = 255; + /* convert to 1200dpi units */ s->max_x = s->max_x_basic * 1200 / s->basic_x_res; s->max_y = s->max_y_basic * 1200 / s->basic_y_res; @@ -912,6 +933,24 @@ init_model (struct scanner *s) return SANE_STATUS_GOOD; } +/* + * This function enables the buttons and preloads the current panel values + */ +static SANE_Status +init_panel (struct scanner *s) +{ + SANE_Status ret = SANE_STATUS_GOOD; + + DBG (10, "init_panel: start\n"); + + ret = read_panel(s); + ret = send_panel(s); + + DBG (10, "init_panel: finish\n"); + + return ret; +} + /* * set good default user values. * struct is already initialized to 0. @@ -1710,6 +1749,51 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->constraint_type = SANE_CONSTRAINT_NONE; } + if(option==OPT_START){ + opt->name = "start"; + opt->title = "Start button"; + opt->desc = "Big green button"; + opt->type = SANE_TYPE_BOOL; + opt->unit = SANE_UNIT_NONE; + opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + } + + if(option==OPT_STOP){ + opt->name = "stop"; + opt->title = "Stop button"; + opt->desc = "Little orange button"; + opt->type = SANE_TYPE_BOOL; + opt->unit = SANE_UNIT_NONE; + opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + } + + if(option==OPT_NEWFILE){ + opt->name = "newfile"; + opt->title = "New File button"; + opt->desc = "New File button"; + opt->type = SANE_TYPE_BOOL; + opt->unit = SANE_UNIT_NONE; + opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + } + + if(option==OPT_COUNTONLY){ + opt->name = "countonly"; + opt->title = "Count Only button"; + opt->desc = "Count Only button"; + opt->type = SANE_TYPE_BOOL; + opt->unit = SANE_UNIT_NONE; + opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + } + + if(option==OPT_BYPASSMODE){ + opt->name = "bypassmode"; + opt->title = "Bypass Mode button"; + opt->desc = "Bypass Mode button"; + opt->type = SANE_TYPE_BOOL; + opt->unit = SANE_UNIT_NONE; + opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + } + if(option==OPT_COUNTER){ opt->name = "counter"; opt->title = "Counter"; @@ -1723,7 +1807,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->counter_range.quant=1; if (s->has_counter) - opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; + opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT; else opt->cap = SANE_CAP_INACTIVE; } @@ -1947,8 +2031,35 @@ sane_control_option (SANE_Handle handle, SANE_Int option, return SANE_STATUS_GOOD; /* Sensor Group */ + case OPT_START: + read_panel(s); + *val_p = s->panel_start; + return SANE_STATUS_GOOD; + + case OPT_STOP: + read_panel(s); + *val_p = s->panel_stop; + return SANE_STATUS_GOOD; + + case OPT_NEWFILE: + read_panel(s); + *val_p = s->panel_new_file; + return SANE_STATUS_GOOD; + + case OPT_COUNTONLY: + read_panel(s); + *val_p = s->panel_count_only; + return SANE_STATUS_GOOD; + + case OPT_BYPASSMODE: + read_panel(s); + *val_p = s->panel_bypass_mode; + return SANE_STATUS_GOOD; + case OPT_COUNTER: - return read_counter (s,val_p); + read_panel(s); + *val_p = s->panel_counter; + return SANE_STATUS_GOOD; } } @@ -2188,7 +2299,8 @@ sane_control_option (SANE_Handle handle, SANE_Int option, /* Sensor Group */ case OPT_COUNTER: - return send_counter(s,val_c); + s->panel_counter = val_c; + return send_panel(s); } } /* else */ @@ -2375,65 +2487,73 @@ ssm_do (struct scanner *s) } static SANE_Status -read_counter(struct scanner *s,SANE_Word * val_p) +read_panel(struct scanner *s) { SANE_Status ret=SANE_STATUS_GOOD; unsigned char cmd[READ_len]; size_t cmdLen = READ_len; - unsigned char in[R_COUNTER_len]; - size_t inLen = R_COUNTER_len; + unsigned char in[R_PANEL_len]; + size_t inLen = R_PANEL_len; - DBG (10, "read_counter: start\n"); - - memset(cmd,0,cmdLen); - set_SCSI_opcode(cmd, READ_code); - set_R_datatype_code (cmd, R_datatype_counter); - set_R_xfer_length (cmd, inLen); - - ret = do_cmd ( - s, 1, 0, - cmd, cmdLen, - NULL, 0, - in, &inLen - ); - - if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { - DBG(15, "read_counter: got GOOD/EOF, returning GOOD\n"); - *val_p = get_R_COUNTER_count(in); - ret = SANE_STATUS_GOOD; - } - else { - DBG(5, "read_counter: error, status = %d\n",ret); - *val_p = -1; + DBG (10, "read_panel: start\n"); + + /* only run this once every second */ + if (s->last_panel < time(NULL)) { + + DBG (15, "read_panel: running\n"); + memset(cmd,0,cmdLen); + set_SCSI_opcode(cmd, READ_code); + set_R_datatype_code (cmd, SR_datatype_panel); + set_R_xfer_length (cmd, inLen); + + ret = do_cmd ( + s, 1, 0, + cmd, cmdLen, + NULL, 0, + in, &inLen + ); + + if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { + s->last_panel = time(NULL); + s->panel_start = get_R_PANEL_start(in); + s->panel_stop = get_R_PANEL_stop(in); + s->panel_new_file = get_R_PANEL_new_file(in); + s->panel_count_only = get_R_PANEL_count_only(in); + s->panel_bypass_mode = get_R_PANEL_bypass_mode(in); + s->panel_enable_led = get_R_PANEL_enable_led(in); + s->panel_counter = get_R_PANEL_counter(in); + ret = SANE_STATUS_GOOD; + } } - DBG (10, "read_counter: finish\n"); + DBG (10, "read_panel: finish\n"); return ret; } static SANE_Status -send_counter(struct scanner *s,SANE_Word val) +send_panel(struct scanner *s) { SANE_Status ret=SANE_STATUS_GOOD; unsigned char cmd[SEND_len]; size_t cmdLen = SEND_len; - unsigned char out[S_COUNTER_len]; - size_t outLen = S_COUNTER_len; + unsigned char out[S_PANEL_len]; + size_t outLen = S_PANEL_len; - DBG (10, "send_counter: start\n"); + DBG (10, "send_panel: start\n"); memset(cmd,0,cmdLen); set_SCSI_opcode(cmd, SEND_code); - set_S_xfer_datatype (cmd, S_datatype_counter); + set_S_xfer_datatype (cmd, SR_datatype_panel); set_S_xfer_length (cmd, outLen); memset(out,0,outLen); - set_S_COUNTER_count(out,val); + set_S_PANEL_enable_led(out,1); + set_S_PANEL_counter(out,s->panel_counter); ret = do_cmd ( s, 1, 0, @@ -2442,12 +2562,11 @@ send_counter(struct scanner *s,SANE_Word val) NULL, NULL ); - if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { - DBG(15, "send_counter: got GOOD/EOF, returning GOOD\n"); + if (ret == SANE_STATUS_EOF) { ret = SANE_STATUS_GOOD; } - DBG (10, "send_counter: finish %d\n", ret); + DBG (10, "send_panel: finish %d\n", ret); return ret; } @@ -3174,7 +3293,7 @@ read_from_scanner(struct scanner *s, int side) memset(cmd,0,cmdLen); set_SCSI_opcode(cmd, READ_code); - set_R_datatype_code (cmd, R_datatype_imagedata); + set_R_datatype_code (cmd, SR_datatype_image); set_R_xfer_length (cmd, inLen); @@ -4018,6 +4137,13 @@ wait_scanner(struct scanner *s) NULL, NULL ); + ret = do_cmd ( + s, 0, 1, + cmd, cmdLen, + NULL, 0, + NULL, NULL + ); + if (ret != SANE_STATUS_GOOD) { DBG(5,"WARNING: Brain-dead scanner. Hitting with stick\n"); ret = do_cmd ( diff --git a/backend/canon_dr.h b/backend/canon_dr.h index aa9ab5b6e..9aed14993 100644 --- a/backend/canon_dr.h +++ b/backend/canon_dr.h @@ -1,26 +1,6 @@ #ifndef CANON_DR_H #define CANON_DR_H -#if V_MINOR == 0 -#define SANE_NAME_STANDARD "standard" -#define SANE_TITLE_STANDARD SANE_I18N("Standard") -#define SANE_DESC_STANDARD SANE_I18N("Source, mode and resolution options") -#define SANE_NAME_GEOMETRY "geometry" -#define SANE_TITLE_GEOMETRY SANE_I18N("Geometry") -#define SANE_DESC_GEOMETRY SANE_I18N("Scan area and media size options") -#define SANE_NAME_PAGE_WIDTH "page-width" -#define SANE_TITLE_PAGE_WIDTH SANE_I18N("Page width") -#define SANE_DESC_PAGE_WIDTH \ -SANE_I18N("Specifies the width of the media. Required for automatic " \ -"centering of sheet-fed scans.") -#define SANE_NAME_PAGE_HEIGHT "page-height" -#define SANE_TITLE_PAGE_HEIGHT SANE_I18N("Page height") -#define SANE_DESC_PAGE_HEIGHT \ -SANE_I18N("Specifies the height of the media.") -#define SANE_NAME_ENHANCEMENT "enhancement" -#define SANE_TITLE_ENHANCEMENT SANE_I18N("Enhancement") -#define SANE_DESC_ENHANCEMENT SANE_I18N("Image modification options") -#endif /* * Part of SANE - Scanner Access Now Easy. * Please see opening comment in canon_dr.c @@ -66,6 +46,11 @@ enum scanner_Option /*sensor group*/ OPT_SENSOR_GROUP, + OPT_START, + OPT_STOP, + OPT_NEWFILE, + OPT_COUNTONLY, + OPT_BYPASSMODE, OPT_COUNTER, /* must come last: */ @@ -278,10 +263,21 @@ struct scanner int fds[2]; /* --------------------------------------------------------------------- */ - /* values which used by the command and data sending functions (scsi/usb)*/ - int fd; /* The scanner device file descriptor. */ + /* values used by the command and data sending functions (scsi/usb) */ + int fd; /* The scanner device file descriptor. */ size_t rs_info; + /* --------------------------------------------------------------------- */ + /* values used to hold hardware or control panel status */ + + time_t last_panel; + int panel_start; + int panel_stop; + int panel_new_file; + int panel_count_only; + int panel_bypass_mode; + int panel_enable_led; + int panel_counter; }; #define CONNECTION_SCSI 0 /* SCSI interface */ @@ -403,6 +399,7 @@ static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg); static SANE_Status init_inquire (struct scanner *s); static SANE_Status init_vpd (struct scanner *s); static SANE_Status init_model (struct scanner *s); +static SANE_Status init_panel (struct scanner *s); static SANE_Status init_user (struct scanner *s); static SANE_Status init_options (struct scanner *s); @@ -442,8 +439,8 @@ int get_page_height (struct scanner *s); static SANE_Status set_window (struct scanner *s); -static SANE_Status read_counter(struct scanner *s, SANE_Word *); -static SANE_Status send_counter(struct scanner *s, SANE_Word); +static SANE_Status read_panel(struct scanner *s); +static SANE_Status send_panel(struct scanner *s); static SANE_Status start_scan (struct scanner *s); diff --git a/doc/descriptions/canon_dr.desc b/doc/descriptions/canon_dr.desc index 8f8042091..93d73e8f3 100644 --- a/doc/descriptions/canon_dr.desc +++ b/doc/descriptions/canon_dr.desc @@ -83,13 +83,13 @@ :interface "USB SCSI" :usbid "0x04a9" "0x160b" :status :good -:comment "Simplex, duplex, dropout-color, multifeed detection and JPEG working, imprinter unsupported" +:comment "Simplex, duplex, all resolutions, binary/ht/gray, async mode, dropout-color, multifeed detection, buttons and gray JPEG working, imprinter unsupported" :model "DR-9080C" :interface "USB SCSI" :usbid "0x04a9" "0x1603" :status :good -:comment "Simplex, duplex, dropout-color, multifeed detection and JPEG working, imprinter unsupported" +:comment "Simplex, duplex, all resolutions, binary/ht/gray/color, async mode, dropout-color, multifeed detection, buttons and gray JPEG working, imprinter unsupported, color JPEG broken" :model "DR-X10C" :interface "USB SCSI" diff --git a/doc/sane-canon_dr.man b/doc/sane-canon_dr.man index 312d0c72e..a2789b79f 100644 --- a/doc/sane-canon_dr.man +++ b/doc/sane-canon_dr.man @@ -10,10 +10,10 @@ The library implements a SANE (Scanner Access Now Easy) backend which provides access to some Canon DR-series scanners. -This document describes backend version 3, slated to ship with SANE 1.1.0. +This document describes backend version 8, slated to ship with SANE 1.1.0. .SH SUPPORTED HARDWARE -This version has only been tested with the DR\-9080C and DR\-7580C. Please see +This version has only been tested with the DR\-9080C and DR\-7580. Please see http://www.sane\-project.org/sane\-supported\-devices.html for a more recent list. @@ -56,9 +56,7 @@ coordinates when using ADF and to detect double feed errors. .RE .PP Other options will be available based on the capabilities of the scanner: -machines with IPC or DTC will have additional enhancement options, those -with CMP will have compression options, those with a printer will have a -group of endorser options. +enhancement, compression, buttons and sensors, etc. Use 'scanimage \-\-help' to get a list, but be aware that some options may be settable only when another option has been set, and that advanced options @@ -74,7 +72,7 @@ are identical to the default configuration file shipped with SANE. .PP Scanners can be specified in the configuration file in 4 ways: .PP -"scsi CANON DR" +"scsi CANON" .RS Requests backend to search all scsi busses in the system for a device which reports itself to be a scanner made by 'CANON', with a model name