diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2022-02-01 15:26:02 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2022-02-01 15:26:02 +0100 |
commit | 5de81480e84023d91763d89e4523de88df42c194 (patch) | |
tree | cb83e4c8216cf0e8bcaa17a6f2cb64cf4d7f469a /backend/canon_dr.c | |
parent | 97e55bdc5cdf59304af739e65f416320bcbcf599 (diff) | |
parent | 8e5d399808d2270ae9d56c96560a021e594d18a4 (diff) |
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'backend/canon_dr.c')
-rw-r--r-- | backend/canon_dr.c | 203 |
1 files changed, 137 insertions, 66 deletions
diff --git a/backend/canon_dr.c b/backend/canon_dr.c index de7ed7e..95799e7 100644 --- a/backend/canon_dr.c +++ b/backend/canon_dr.c @@ -3,7 +3,7 @@ This file is part of the SANE package, and implements a SANE backend for various Canon DR-series scanners. - Copyright (C) 2008-2020 m. allan noah + Copyright (C) 2008-2021 m. allan noah Yabarana Corp. www.yabarana.com provided significant funding EvriChart, Inc. www.evrichart.com provided funding and loaned equipment @@ -346,6 +346,15 @@ - add new gray and color interlacing options for DR-C120 - initial support for DR-C120 and C130 - enable fine calibration for P-208 (per @sashacmc in !546) + v61 2021-02-13, MAN + - treat DR-P208 like P-208 (#356) + - treat DR-P215 like P-215 (#356) + - adjust wait_scanner to try one TUR with a long timeout (#142) + v62 2021-02-13, MAN + - allow config file to set inq and vpd lengths for DR-M1060 (#263) + - rewrite do_cmd() timeout handling + - remove long timeout TUR from v61 (did not help) + - allow config file to set initial tur timeout for DR-X10C (#142) SANE FLOW DIAGRAM @@ -384,6 +393,7 @@ #include <math.h> /*tan*/ #include <unistd.h> /*usleep*/ #include <sys/time.h> /*gettimeofday*/ +#include <stdlib.h> /*strtol*/ #include "../include/sane/sanei_backend.h" #include "../include/sane/sanei_scsi.h" @@ -396,7 +406,7 @@ #include "canon_dr.h" #define DEBUG 1 -#define BUILD 60 +#define BUILD 62 /* values for SANE_DEBUG_CANON_DR env var: - errors 5 @@ -448,6 +458,10 @@ static int global_extra_status; static int global_extra_status_default = 0; static int global_duplex_offset; static int global_duplex_offset_default = 0; +static int global_inquiry_length; +static int global_vpd_length; +static int global_tur_timeout; +static int global_tur_timeout_default = USB_PACKET_TIMEOUT/60; /* half second */ static char global_vendor_name[9]; static char global_model_name[17]; static char global_version_name[5]; @@ -486,10 +500,10 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) DBG (10, "sane_init: start\n"); if (version_code) - *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD); + *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); DBG (5, "sane_init: canon_dr backend %d.%d.%d, from %s\n", - SANE_CURRENT_MAJOR, V_MINOR, BUILD, PACKAGE_STRING); + SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); DBG (10, "sane_init: finish\n"); @@ -675,6 +689,84 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) global_duplex_offset = buf; } + /* INQUIRY_LENGTH: <= 0x30 */ + else if (!strncmp (lp, "inquiry-length", 14) && isspace (lp[14])) { + + int buf; + lp += 14; + lp = sanei_config_skip_whitespace (lp); + buf = (int) strtol (lp,NULL,16); + + if (buf > INQUIRY_std_max_len) { + DBG (5, "sane_get_devices: config option \"inquiry-length\" " + "(%#04x) is > %#04x, ignoring!\n", buf, INQUIRY_std_max_len); + continue; + } + + if (buf < 0) { + DBG (5, "sane_get_devices: config option \"inquiry-length\" " + "(%#04x) is < 0, ignoring!\n", buf); + continue; + } + + DBG (15, "sane_get_devices: setting \"inquiry-length\" to %#04x\n", + buf); + + global_inquiry_length = buf; + } + + /* VPD_LENGTH: <= 0x30 */ + else if (!strncmp (lp, "vpd-length", 10) && isspace (lp[10])) { + + int buf; + lp += 10; + lp = sanei_config_skip_whitespace (lp); + buf = (int) strtol (lp,NULL,16); + + if (buf > INQUIRY_vpd_max_len) { + DBG (5, "sane_get_devices: config option \"vpd-length\" " + "(%#04x) is > %#04x, ignoring!\n", buf, INQUIRY_vpd_max_len); + continue; + } + + if (buf < 0) { + DBG (5, "sane_get_devices: config option \"vpd-length\" " + "(%#04x) is < 0, ignoring!\n", buf); + continue; + } + + DBG (15, "sane_get_devices: setting \"vpd-length\" to %#04x\n", + buf); + + global_vpd_length = buf; + } + + /* TUR_TIMEOUT <= 60000 */ + else if (!strncmp (lp, "tur-timeout", 11) && isspace (lp[11])) { + + int buf; + lp += 11; + lp = sanei_config_skip_whitespace (lp); + buf = atoi (lp); + + if (buf > 60000) { + DBG (5, "sane_get_devices: config option \"tur-timeout\" " + "(%d) is > 60000, ignoring!\n", buf); + continue; + } + + if (buf < 0) { + DBG (5, "sane_get_devices: config option \"tur-timeout\" " + "(%d) is < 0, ignoring!\n", buf); + continue; + } + + DBG (15, "sane_get_devices: setting \"tur-timeout\" to %d\n", + buf); + + global_tur_timeout = buf; + } + /* VENDOR: we ingest up to 8 bytes */ else if (!strncmp (lp, "vendor-name", 11) && isspace (lp[11])) { @@ -841,6 +933,9 @@ attach_one (const char *device_name, int connType) s->padded_read = global_padded_read; s->extra_status = global_extra_status; s->duplex_offset = global_duplex_offset; + s->inquiry_length = global_inquiry_length; + s->vpd_length = global_vpd_length; + s->tur_timeout = global_tur_timeout; /* copy the device name */ strcpy (s->device_name, device_name); @@ -1017,8 +1112,8 @@ init_inquire (struct scanner *s) unsigned char cmd[INQUIRY_len]; size_t cmdLen = INQUIRY_len; - unsigned char in[INQUIRY_std_len]; - size_t inLen = INQUIRY_std_len; + unsigned char in[INQUIRY_std_max_len]; + size_t inLen = s->inquiry_length; DBG (10, "init_inquire: start\n"); @@ -1099,8 +1194,8 @@ init_vpd (struct scanner *s) unsigned char cmd[INQUIRY_len]; size_t cmdLen = INQUIRY_len; - unsigned char in[INQUIRY_vpd_len]; - size_t inLen = INQUIRY_vpd_len; + unsigned char in[INQUIRY_vpd_max_len]; + size_t inLen = s->vpd_length; DBG (10, "init_vpd: start\n"); @@ -1491,7 +1586,8 @@ init_model (struct scanner *s) s->has_card = 1; } - else if (strstr (s->model_name, "P-208")) { + else if (strstr (s->model_name, "P-208") + || strstr (s->model_name,"DR-P208")){ s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB; s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB; s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG; @@ -1508,7 +1604,8 @@ init_model (struct scanner *s) s->can_read_sensors = 1; } - else if (strstr (s->model_name, "P-215")) { + else if (strstr (s->model_name, "P-215") + || strstr (s->model_name,"DR-P215")){ s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_rRgGbB; s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB; s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_gG; @@ -7079,6 +7176,9 @@ default_globals(void) global_padded_read = global_padded_read_default; global_extra_status = global_extra_status_default; global_duplex_offset = global_duplex_offset_default; + global_inquiry_length = INQUIRY_std_typ_len; + global_vpd_length = INQUIRY_vpd_typ_len; + global_tur_timeout = global_tur_timeout_default; global_vendor_name[0] = 0; global_model_name[0] = 0; global_version_name[0] = 0; @@ -7332,21 +7432,21 @@ sense_handler (int fd, unsigned char * sensed_data, void *arg) * take a bunch of pointers, send commands to scanner */ static SANE_Status -do_cmd(struct scanner *s, int runRS, int shortTime, +do_cmd(struct scanner *s, int runRS, int timeout, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen ) { if (s->connection == CONNECTION_SCSI) { - return do_scsi_cmd(s, runRS, shortTime, + return do_scsi_cmd(s, runRS, timeout, cmdBuff, cmdLen, outBuff, outLen, inBuff, inLen ); } if (s->connection == CONNECTION_USB) { - return do_usb_cmd(s, runRS, shortTime, + return do_usb_cmd(s, runRS, timeout, cmdBuff, cmdLen, outBuff, outLen, inBuff, inLen @@ -7356,7 +7456,7 @@ do_cmd(struct scanner *s, int runRS, int shortTime, } static SANE_Status -do_scsi_cmd(struct scanner *s, int runRS, int shortTime, +do_scsi_cmd(struct scanner *s, int runRS, int timeout, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen @@ -7366,7 +7466,7 @@ do_scsi_cmd(struct scanner *s, int runRS, int shortTime, /*shut up compiler*/ runRS=runRS; - shortTime=shortTime; + timeout=timeout; DBG(10, "do_scsi_cmd: start\n"); @@ -7404,7 +7504,7 @@ do_scsi_cmd(struct scanner *s, int runRS, int shortTime, } static SANE_Status -do_usb_cmd(struct scanner *s, int runRS, int shortTime, +do_usb_cmd(struct scanner *s, int runRS, int timeout, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen @@ -7414,21 +7514,19 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, size_t cmdLength = 0; size_t cmdActual = 0; unsigned char * cmdBuffer = NULL; - int cmdTimeout = 0; size_t outOffset = 0; size_t outLength = 0; size_t outActual = 0; unsigned char * outBuffer = NULL; - int outTimeout = 0; size_t inOffset = 0; size_t inLength = 0; size_t inActual = 0; unsigned char * inBuffer = NULL; - int inTimeout = 0; size_t extraLength = 0; + int actTimeout = timeout ? timeout : USB_PACKET_TIMEOUT; int ret = 0; int ret2 = 0; @@ -7438,18 +7536,15 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, DBG (10, "do_usb_cmd: start %lu %lu\n", (long unsigned int)timer.tv_sec, (long unsigned int)timer.tv_usec); + /* change timeout */ + sanei_usb_set_timeout(actTimeout); + /****************************************************************/ /* the command stage */ { cmdOffset = USB_HEADER_LEN; cmdLength = cmdOffset+USB_COMMAND_LEN; cmdActual = cmdLength; - cmdTimeout = USB_COMMAND_TIME; - - /* change timeout */ - if(shortTime) - cmdTimeout/=60; - sanei_usb_set_timeout(cmdTimeout); /* build buffer */ cmdBuffer = calloc(cmdLength,1); @@ -7465,7 +7560,7 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, memcpy(cmdBuffer+cmdOffset,cmdBuff,cmdLen); /* write the command out */ - DBG(25, "cmd: writing %d bytes, timeout %d\n", (int)cmdLength, cmdTimeout); + DBG(25, "cmd: writing %d bytes, timeout %d\n", (int)cmdLength, actTimeout); hexdump(30, "cmd: >>", cmdBuffer, cmdLength); ret = sanei_usb_write_bulk(s->fd, cmdBuffer, &cmdActual); DBG(25, "cmd: wrote %d bytes, retVal %d\n", (int)cmdActual, ret); @@ -7488,7 +7583,7 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, /* this is like the regular status block, with an additional */ /* length component at the end */ if(s->extra_status){ - ret2 = do_usb_status(s,runRS,shortTime,&extraLength); + ret2 = do_usb_status(s,runRS,timeout,&extraLength); /* bail out on bad RS status */ if(ret2){ @@ -7504,12 +7599,6 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, outOffset = USB_HEADER_LEN; outLength = outOffset+outLen; outActual = outLength; - outTimeout = USB_DATA_TIME; - - /* change timeout */ - if(shortTime) - outTimeout/=60; - sanei_usb_set_timeout(outTimeout); /* build outBuffer */ outBuffer = calloc(outLength,1); @@ -7525,7 +7614,7 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, memcpy(outBuffer+outOffset,outBuff,outLen); /* write the command out */ - DBG(25, "out: writing %d bytes, timeout %d\n", (int)outLength, outTimeout); + DBG(25, "out: writing %d bytes, timeout %d\n", (int)outLength, actTimeout); hexdump(30, "out: >>", outBuffer, outLength); ret = sanei_usb_write_bulk(s->fd, outBuffer, &outActual); DBG(25, "out: wrote %d bytes, retVal %d\n", (int)outActual, ret); @@ -7563,13 +7652,6 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, /*blast caller's copy in case we error out*/ *inLen = 0; - inTimeout = USB_DATA_TIME; - - /* change timeout */ - if(shortTime) - inTimeout/=60; - sanei_usb_set_timeout(inTimeout); - /* build inBuffer */ inBuffer = calloc(inActual,1); if(!inBuffer){ @@ -7577,7 +7659,7 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, return SANE_STATUS_NO_MEM; } - DBG(25, "in: reading %d bytes, timeout %d\n", (int)inActual, inTimeout); + DBG(25, "in: reading %d bytes, timeout %d\n", (int)inActual, actTimeout); ret = sanei_usb_read_bulk(s->fd, inBuffer, &inActual); DBG(25, "in: read %d bytes, retval %d\n", (int)inActual, ret); hexdump(31, "in: <<", inBuffer, inActual); @@ -7603,7 +7685,7 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, /****************************************************************/ /* the normal status stage */ - ret2 = do_usb_status(s,runRS,shortTime,&extraLength); + ret2 = do_usb_status(s,runRS,timeout,&extraLength); /* if status said EOF, adjust input with remainder count */ if(ret2 == SANE_STATUS_EOF && inBuffer){ @@ -7651,7 +7733,7 @@ do_usb_cmd(struct scanner *s, int runRS, int shortTime, } static SANE_Status -do_usb_status(struct scanner *s, int runRS, int shortTime, size_t * extraLength) +do_usb_status(struct scanner *s, int runRS, int timeout, size_t * extraLength) { #define EXTRA_READ_len 4 @@ -7661,7 +7743,8 @@ do_usb_status(struct scanner *s, int runRS, int shortTime, size_t * extraLength) size_t statLength = 0; size_t statActual = 0; unsigned char * statBuffer = NULL; - int statTimeout = 0; + + int actTimeout = timeout ? timeout : USB_PACKET_TIMEOUT; int ret = 0; @@ -7675,12 +7758,9 @@ do_usb_status(struct scanner *s, int runRS, int shortTime, size_t * extraLength) statLength += EXTRA_READ_len; statActual = statLength; - statTimeout = USB_STATUS_TIME; /* change timeout */ - if(shortTime) - statTimeout/=60; - sanei_usb_set_timeout(statTimeout); + sanei_usb_set_timeout(timeout ? timeout : USB_PACKET_TIMEOUT); /* build statBuffer */ statBuffer = calloc(statLength,1); @@ -7689,7 +7769,7 @@ do_usb_status(struct scanner *s, int runRS, int shortTime, size_t * extraLength) return SANE_STATUS_NO_MEM; } - DBG(25, "stat: reading %d bytes, timeout %d\n", (int)statLength, statTimeout); + DBG(25, "stat: reading %d bytes, timeout %d\n", (int)statLength, actTimeout); ret = sanei_usb_read_bulk(s->fd, statBuffer, &statActual); DBG(25, "stat: read %d bytes, retval %d\n", (int)statActual, ret); hexdump(30, "stat: <<", statBuffer, statActual); @@ -7754,7 +7834,7 @@ do_usb_clear(struct scanner *s, int clear, int runRS) DBG(25,"rs sub call >>\n"); ret2 = do_cmd( - s,0,0, + s, 0, 0, rs_cmd, rs_cmdLen, NULL,0, rs_in, &rs_inLen @@ -7796,7 +7876,7 @@ wait_scanner(struct scanner *s) set_SCSI_opcode(cmd,TEST_UNIT_READY_code); ret = do_cmd ( - s, 0, 1, + s, 0, s->tur_timeout, cmd, cmdLen, NULL, 0, NULL, NULL @@ -7805,7 +7885,7 @@ wait_scanner(struct scanner *s) if (ret != SANE_STATUS_GOOD) { DBG(5,"WARNING: Brain-dead scanner. Hitting with stick.\n"); ret = do_cmd ( - s, 0, 1, + s, 0, s->tur_timeout, cmd, cmdLen, NULL, 0, NULL, NULL @@ -7814,7 +7894,7 @@ wait_scanner(struct scanner *s) if (ret != SANE_STATUS_GOOD) { DBG(5,"WARNING: Brain-dead scanner. Hitting with stick again.\n"); ret = do_cmd ( - s, 0, 1, + s, 0, s->tur_timeout, cmd, cmdLen, NULL, 0, NULL, NULL @@ -7823,18 +7903,9 @@ wait_scanner(struct scanner *s) // some scanners (such as DR-F120) are OK but will not respond to commands // when in sleep mode. By checking the sense it wakes them up. if (ret != SANE_STATUS_GOOD) { - DBG(5,"WARNING: Brain-dead scanner. Hitting with request sense.\n"); - ret = do_cmd ( - s, 1, 1, - cmd, cmdLen, - NULL, 0, - NULL, NULL - ); - } - if (ret != SANE_STATUS_GOOD) { - DBG(5,"WARNING: Brain-dead scanner. Hitting with stick a third time.\n"); + DBG(5,"WARNING: Brain-dead scanner. Hitting with stick and request sense.\n"); ret = do_cmd ( - s, 0, 1, + s, 1, s->tur_timeout, cmd, cmdLen, NULL, 0, NULL, NULL @@ -7843,7 +7914,7 @@ wait_scanner(struct scanner *s) if (ret != SANE_STATUS_GOOD) { DBG(5,"WARNING: Brain-dead scanner. Hitting with stick a fourth time.\n"); ret = do_cmd ( - s, 0, 1, + s, 0, s->tur_timeout, cmd, cmdLen, NULL, 0, NULL, NULL |