Neither of these scanner have an automated slide transport and fail on respective SCSI commands.
- Add flags parameter to control if automatic slide transport is available - Reflect flags in pieusb.conf.in - rename SLIDE_LAMP_ON to SLIDE_INIT it fails on scanners without automatic slide transport, so it has nothing to do with the lamp. - run SLIDE_INIT only FLAG_SLIDE_TRANSPORT is set - pieusb.conf.in: Add Reflecta CrystalScan 3600 --- backend/pieusb.c | 89 ++++++++++++++++++++++++++++------------------- backend/pieusb.conf.in | 15 ++++++-- backend/pieusb.h | 1 + backend/pieusb_scancmd.c | 2 +- backend/pieusb_scancmd.h | 2 +- backend/pieusb_specific.c | 48 ++++++++++++++++++------- backend/pieusb_specific.h | 11 ++++-- 7 files changed, 113 insertions(+), 55 deletions(-) diff --git a/backend/pieusb.c b/backend/pieusb.c index 4b0730403aeb..973088849ca8 100644 --- a/backend/pieusb.c +++ b/backend/pieusb.c @@ -109,6 +109,10 @@ extern void write_tiff_rgbi_header (FILE *fptr, int width, int height, int depth #define DBG_info_scan 11 /* information scanner commands */ #define DBG_info_usb 13 /* information usb level functions */ +/* device flags */ + +#define FLAG_SLIDE_TRANSPORT 0x01 + /* -------------------------------------------------------------------------- * * SUPPORTED DEVICES SPECIFICS @@ -150,7 +154,8 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize char config_line[PATH_MAX]; SANE_Word vendor_id; SANE_Word product_id; - SANE_Word model_number; + SANE_Int model_number; + SANE_Int flags; SANE_Status status; int i; @@ -183,18 +188,22 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize pieusb_supported_usb_device_list[0].vendor = 0x05e3; pieusb_supported_usb_device_list[0].product = 0x0145; pieusb_supported_usb_device_list[0].model = 0x30; + pieusb_supported_usb_device_list[0].flags = 0; /* Reflecta ProScan 7200, model number 0x36 */ pieusb_supported_usb_device_list[1].vendor = 0x05e3; pieusb_supported_usb_device_list[1].product = 0x0145; pieusb_supported_usb_device_list[1].model = 0x36; - /* Reflecta 6000 Multiple Slide Scanner */ + pieusb_supported_usb_device_list[1].flags = 0; + /* Reflecta 6000 Multiple Slide Scanner, model number 0x3a */ pieusb_supported_usb_device_list[2].vendor = 0x05e3; pieusb_supported_usb_device_list[2].product = 0x0142; pieusb_supported_usb_device_list[2].model = 0x3a; + pieusb_supported_usb_device_list[2].flags = FLAG_SLIDE_TRANSPORT; /* end of list */ pieusb_supported_usb_device_list[3].vendor = 0; pieusb_supported_usb_device_list[3].product = 0; pieusb_supported_usb_device_list[3].model = 0; + pieusb_supported_usb_device_list[3].flags = 0; /* Add entries from config file */ fp = sanei_config_open (PIEUSB_CONFIG_FILE); @@ -209,14 +218,14 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize if (strncmp (config_line, "usb ", 4) != 0) continue; /* Parse vendor-id, product-id and model number and add to list */ DBG (DBG_info_sane, "sane_init() config file parsing %s\n", config_line); - status = sanei_pieusb_parse_config_line(config_line, &vendor_id, &product_id, &model_number); + status = sanei_pieusb_parse_config_line(config_line, &vendor_id, &product_id, &model_number, &flags); if (status == SANE_STATUS_GOOD) { - DBG (DBG_info_sane, "sane_init() config file lists device %04x %04x %02x\n",vendor_id, product_id, model_number); - if (!sanei_pieusb_supported_device_list_contains(vendor_id, product_id, model_number)) { - DBG (DBG_info_sane, "sane_init() adding device %04x %04x %02x\n",vendor_id, product_id, model_number); - sanei_pieusb_supported_device_list_add(vendor_id, product_id, model_number); + DBG (DBG_info_sane, "sane_init() config file lists device %04x %04x %02x %02x\n",vendor_id, product_id, model_number, flags); + if (!sanei_pieusb_supported_device_list_contains(vendor_id, product_id, model_number, flags)) { + DBG (DBG_info_sane, "sane_init() adding device %04x %04x %02x %02x\n",vendor_id, product_id, model_number, flags); + sanei_pieusb_supported_device_list_add(vendor_id, product_id, model_number, flags); } else { - DBG (DBG_info_sane, "sane_init() list already contains %04x %04x %02x\n", vendor_id, product_id, model_number); + DBG (DBG_info_sane, "sane_init() list already contains %04x %04x %02x %02x\n", vendor_id, product_id, model_number, flags); } } else { DBG (DBG_info_sane, "sane_init() config file parsing %s: error\n", config_line); @@ -235,8 +244,13 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize pieusb_supported_usb_device.vendor = pieusb_supported_usb_device_list[i].vendor; pieusb_supported_usb_device.product = pieusb_supported_usb_device_list[i].product; pieusb_supported_usb_device.model = pieusb_supported_usb_device_list[i].model; + pieusb_supported_usb_device.flags = pieusb_supported_usb_device_list[i].flags; pieusb_supported_usb_device.device_number = -1; /* No device number (yet) */ - DBG( DBG_info_sane, "sane_init() looking for Reflecta scanner %04x %04x model %02x\n", pieusb_supported_usb_device.vendor, pieusb_supported_usb_device.product, pieusb_supported_usb_device.model); + DBG( DBG_info_sane, "sane_init() looking for scanner %04x %04x model %02x, flags %02x\n", + pieusb_supported_usb_device.vendor, + pieusb_supported_usb_device.product, + pieusb_supported_usb_device.model, + pieusb_supported_usb_device.flags); sanei_usb_find_devices (pieusb_supported_usb_device.vendor, pieusb_supported_usb_device.product, sanei_pieusb_find_device_callback); i++; } @@ -354,6 +368,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle) pieusb_supported_usb_device.vendor = vendor; pieusb_supported_usb_device.product = product; pieusb_supported_usb_device.model = pieusb_supported_usb_device_list[i].model; + pieusb_supported_usb_device.flags = pieusb_supported_usb_device_list[i].flags; pieusb_supported_usb_device.device_number = -1; sanei_usb_find_devices (vendor, product, sanei_pieusb_find_device_callback); if (pieusb_supported_usb_device.device_number == -1) { @@ -994,17 +1009,18 @@ sane_start (SANE_Handle handle) * * ---------------------------------------------------------------------- */ - sanei_pieusb_cmd_17 (scanner->device_number, 1, &status); - if (status.pieusb_status != PIEUSB_STATUS_GOOD) { - DBG (DBG_error, "sane_start(): sanei_pieusb_cmd_17 failed: %d\n", status.pieusb_status); - return SANE_STATUS_IO_ERROR; - } - st = sanei_pieusb_wait_ready (scanner, 0); - if (st != SANE_STATUS_GOOD) { - DBG (DBG_error, "sane_start(): scanner not ready after sanei_pieusb_cmd_17: %d\n", st); - return st; + if (scanner->device->flags & FLAG_SLIDE_TRANSPORT) { + sanei_pieusb_cmd_17 (scanner->device_number, 1, &status); + if (status.pieusb_status != PIEUSB_STATUS_GOOD) { + DBG (DBG_error, "sane_start(): sanei_pieusb_cmd_17 failed: %d\n", status.pieusb_status); + return SANE_STATUS_IO_ERROR; + } + st = sanei_pieusb_wait_ready (scanner, 0); + if (st != SANE_STATUS_GOOD) { + DBG (DBG_error, "sane_start(): scanner not ready after sanei_pieusb_cmd_17: %d\n", st); + return st; + } } - /* ---------------------------------------------------------------------- * * Get & set initial gains and offsets @@ -1039,20 +1055,21 @@ sane_start (SANE_Handle handle) /* ---------------------------------------------------------------------- * - * Lamp on + * Init slide transport * * ---------------------------------------------------------------------- */ - sanei_pieusb_cmd_slide (scanner->device_number, SLIDE_LAMP_ON, &status); - if (status.pieusb_status != PIEUSB_STATUS_GOOD) { - DBG (DBG_error, "sane_start(): sanei_pieusb_cmd_slide failed: %d\n", status.pieusb_status); - return SANE_STATUS_IO_ERROR; - } - st = sanei_pieusb_wait_ready (scanner, 0); - if (st != SANE_STATUS_GOOD) { - DBG (DBG_error, "sane_start: scanner not ready %d\n", st); - return st; + if (scanner->device->flags & FLAG_SLIDE_TRANSPORT) { + sanei_pieusb_cmd_slide (scanner->device_number, SLIDE_INIT, &status); + if (status.pieusb_status != PIEUSB_STATUS_GOOD) { + DBG (DBG_error, "sane_start(): sanei_pieusb_cmd_slide failed: %d\n", status.pieusb_status); + return SANE_STATUS_IO_ERROR; + } + st = sanei_pieusb_wait_ready (scanner, 0); + if (st != SANE_STATUS_GOOD) { + DBG (DBG_error, "sane_start: scanner not ready %d\n", st); + return st; + } } - /* Enter SCAN phase 1 */ DBG (DBG_info_sane, "sane_start(): scan phase 1\n"); @@ -1200,12 +1217,14 @@ sane_start (SANE_Handle handle) * Advance to next slide (except for preview) * * ---------------------------------------------------------------------- */ - if (scanner->val[OPT_ADVANCE_SLIDE].b && !scanner->val[OPT_PREVIEW].b) { - sanei_pieusb_cmd_slide (scanner->device_number, SLIDE_NEXT, &status); - if (status.pieusb_status != PIEUSB_STATUS_GOOD) { - DBG (DBG_error, "sane_start(): sanei_pieusb_cmd_slide failed: %d\n", status.pieusb_status); - } + if (scanner->device->flags & FLAG_SLIDE_TRANSPORT) { + if (scanner->val[OPT_ADVANCE_SLIDE].b && !scanner->val[OPT_PREVIEW].b) { + sanei_pieusb_cmd_slide (scanner->device_number, SLIDE_NEXT, &status); + if (status.pieusb_status != PIEUSB_STATUS_GOOD) { + DBG (DBG_error, "sane_start(): sanei_pieusb_cmd_slide failed: %d\n", status.pieusb_status); + } + } } /* ---------------------------------------------------------------------- diff --git a/backend/pieusb.conf.in b/backend/pieusb.conf.in index ec5ba7ecce5f..1bee8e2d5895 100644 --- a/backend/pieusb.conf.in +++ b/backend/pieusb.conf.in @@ -1,9 +1,18 @@ # pieusb.conf: Configuration file for PIE/Reflecta USB scanner # Read man sane-pieusb for documentation -# Autodetect +# Format +# usb <vendor-id> <device-id> <model-nr> <has-slide-transport> +# +# Autodetect (built-in) # Reflecta 6000 Multiple Slide Scanner -usb 0x05e3 0x0142 +# usb 0x05e3 0x0142 0x3a 0x01 # Reflecta CrystalScan 7200 +# usb 0x05e3 0x0145 0x30 0x00 # Reflecta ProScan 7200 -usb 0x05e3 0x0145 +# usb 0x05e3 0x0145 0x36 0x00 + +# Reflecta ProScan 10T +usb 0x05e3 0x0145 0x47 0x00 +# Reflecta CrystalScan 3600 +usb 0x05e3 0x0145 0x2e 0x00 diff --git a/backend/pieusb.h b/backend/pieusb.h index 10ce106d4e3d..dc4cda78592f 100644 --- a/backend/pieusb.h +++ b/backend/pieusb.h @@ -80,6 +80,7 @@ struct Pieusb_USB_Device_Entry SANE_Word product; /* USB product identifier */ SANE_Word model; /* USB model number */ SANE_Int device_number; /* USB device number if the device is present */ + SANE_Int flags; /* flags */ }; extern struct Pieusb_USB_Device_Entry* pieusb_supported_usb_device_list; diff --git a/backend/pieusb_scancmd.c b/backend/pieusb_scancmd.c index 1fc42b0fbb74..672716f41325 100644 --- a/backend/pieusb_scancmd.c +++ b/backend/pieusb_scancmd.c @@ -212,7 +212,7 @@ sanei_pieusb_cmd_test_unit_ready(SANE_Int device_number, struct Pieusb_Command_S /** * slide action - * @param action SLIDE_NEXT, SLIDE_PREV, SLIDE_LAMP_ON, SLIDE_RELOAD + * @param action SLIDE_NEXT, SLIDE_PREV, SLIDE_INIT, SLIDE_RELOAD * @return Pieusb_Command_Status */ diff --git a/backend/pieusb_scancmd.h b/backend/pieusb_scancmd.h index 0dee64610920..5eefa5521600 100644 --- a/backend/pieusb_scancmd.h +++ b/backend/pieusb_scancmd.h @@ -318,7 +318,7 @@ struct Pieusb_Command_Status { typedef struct Pieusb_Scanner_Properties Pieusb_Scanner_Properties; typedef enum { - SLIDE_NEXT = 0x04, SLIDE_PREV = 0x05, SLIDE_LAMP_ON = 0x10, SLIDE_RELOAD = 0x40 + SLIDE_NEXT = 0x04, SLIDE_PREV = 0x05, SLIDE_INIT = 0x10, SLIDE_RELOAD = 0x40 } slide_action; void sanei_pieusb_cmd_slide(SANE_Int device_number, slide_action action, struct Pieusb_Command_Status *status); diff --git a/backend/pieusb_specific.c b/backend/pieusb_specific.c index 823107530bc4..ce107cf78de8 100644 --- a/backend/pieusb_specific.c +++ b/backend/pieusb_specific.c @@ -292,6 +292,8 @@ sanei_pieusb_find_device_callback (const char *devicename) return SANE_STATUS_INVAL; } + dev->flags = pieusb_supported_usb_device.flags; + /* Found a supported scanner, put it in the definitions list*/ DBG (DBG_info_proc, "sanei_pieusb_find_device_callback: success\n"); dev->next = pieusb_definition_list_head; @@ -996,18 +998,23 @@ sanei_pieusb_init_options (Pieusb_Scanner* scanner) } /** - * Parse line from config file into a vendor id, product id and a model number + * Parse line from config file into a vendor id, product id, model number, and flags * * @param config_line Text to parse * @param vendor_id * @param product_id * @param model_number + * @param flags * @return SANE_STATUS_GOOD, or SANE_STATUS_INVAL in case of a parse error */ SANE_Status -sanei_pieusb_parse_config_line(const char* config_line, SANE_Word* vendor_id, SANE_Word* product_id, SANE_Word* model_number) +sanei_pieusb_parse_config_line(const char* config_line, + SANE_Word* vendor_id, + SANE_Word* product_id, + SANE_Int* model_number, + SANE_Int* flags) { - char *vendor_id_string, *product_id_string, *model_number_string; + char *vendor_id_string, *product_id_string, *model_number_string, *flags_string; if (strncmp (config_line, "usb ", 4) != 0) { return SANE_STATUS_INVAL; @@ -1041,12 +1048,12 @@ sanei_pieusb_parse_config_line(const char* config_line, SANE_Word* vendor_id, SA } else { return SANE_STATUS_INVAL; } - /* Detect product-id */ + /* Detect model number */ config_line = sanei_config_skip_whitespace (config_line); if (*config_line) { config_line = sanei_config_get_string (config_line, &model_number_string); if (model_number_string) { - *model_number = strtol (model_number_string, 0, 0); + *model_number = (SANE_Int) strtol (model_number_string, 0, 0); free (model_number_string); } else { return SANE_STATUS_INVAL; @@ -1055,6 +1062,16 @@ sanei_pieusb_parse_config_line(const char* config_line, SANE_Word* vendor_id, SA } else { return SANE_STATUS_INVAL; } + /* Detect (optional) flags */ + *flags = 0; + config_line = sanei_config_skip_whitespace (config_line); + if (*config_line) { + config_line = sanei_config_get_string (config_line, &flags_string); + if (flags_string) { + *flags = (SANE_Int) strtol (flags_string, 0, 0); + free (flags_string); + } + } return SANE_STATUS_GOOD; } @@ -1064,16 +1081,18 @@ sanei_pieusb_parse_config_line(const char* config_line, SANE_Word* vendor_id, SA * @param vendor_id * @param product_id * @param model_number + * @param flags * @return */ SANE_Bool -sanei_pieusb_supported_device_list_contains(SANE_Word vendor_id, SANE_Word product_id, SANE_Word model_number) +sanei_pieusb_supported_device_list_contains(SANE_Word vendor_id, SANE_Word product_id, SANE_Int model_number, SANE_Int flags) { int i = 0; while (pieusb_supported_usb_device_list[i].vendor != 0) { if (pieusb_supported_usb_device_list[i].vendor == vendor_id && pieusb_supported_usb_device_list[i].product == product_id - && pieusb_supported_usb_device_list[i].model == model_number) { + && pieusb_supported_usb_device_list[i].model == model_number + && pieusb_supported_usb_device_list[i].flags == flags) { return SANE_TRUE; } i++; @@ -1086,10 +1105,11 @@ sanei_pieusb_supported_device_list_contains(SANE_Word vendor_id, SANE_Word produ * @param vendor_id * @param product_id * @param model_number + * @param flags * @return */ SANE_Status -sanei_pieusb_supported_device_list_add(SANE_Word vendor_id, SANE_Word product_id, SANE_Word model_number) +sanei_pieusb_supported_device_list_add(SANE_Word vendor_id, SANE_Word product_id, SANE_Int model_number, SANE_Int flags) { int i = 0, k; struct Pieusb_USB_Device_Entry* dl; @@ -1099,10 +1119,11 @@ sanei_pieusb_supported_device_list_add(SANE_Word vendor_id, SANE_Word product_id } /* i is index of last entry */ for (k=0; k<=i; k++) { - DBG(DBG_info_proc,"sanei_pieusb_supported_device_list_add(): current %03d: %04x %04x %02x\n", i, + DBG(DBG_info_proc,"sanei_pieusb_supported_device_list_add(): current %03d: %04x %04x %02x %02x\n", i, pieusb_supported_usb_device_list[k].vendor, pieusb_supported_usb_device_list[k].product, - pieusb_supported_usb_device_list[k].model); + pieusb_supported_usb_device_list[k].model, + pieusb_supported_usb_device_list[k].flags); } dl = realloc(pieusb_supported_usb_device_list,(i+2)*sizeof(struct Pieusb_USB_Device_Entry)); /* Add one entry to list */ @@ -1114,14 +1135,17 @@ sanei_pieusb_supported_device_list_add(SANE_Word vendor_id, SANE_Word product_id pieusb_supported_usb_device_list[i].vendor = vendor_id; pieusb_supported_usb_device_list[i].product = product_id; pieusb_supported_usb_device_list[i].model = model_number; + pieusb_supported_usb_device_list[i].flags = flags; pieusb_supported_usb_device_list[i+1].vendor = 0; pieusb_supported_usb_device_list[i+1].product = 0; pieusb_supported_usb_device_list[i+1].model = 0; + pieusb_supported_usb_device_list[i+1].flags = 0; for (k=0; k<=i+1; k++) { - DBG(DBG_info_proc,"sanei_pieusb_supported_device_list_add() add: %03d: %04x %04x %02x\n", i, + DBG(DBG_info_proc,"sanei_pieusb_supported_device_list_add() add: %03d: %04x %04x %02x %02x\n", i, pieusb_supported_usb_device_list[k].vendor, pieusb_supported_usb_device_list[k].product, - pieusb_supported_usb_device_list[k].model); + pieusb_supported_usb_device_list[k].model, + pieusb_supported_usb_device_list[k].flags); } return SANE_STATUS_GOOD; } diff --git a/backend/pieusb_specific.h b/backend/pieusb_specific.h index 3928adfa6d65..f51696089d5e 100644 --- a/backend/pieusb_specific.h +++ b/backend/pieusb_specific.h @@ -193,6 +193,7 @@ struct Pieusb_Device_Definition /* USB id's like 0x05e3 0x0145, see pieusb.conf */ SANE_String version; /* INQUIRY productRevision */ SANE_Byte model; /* INQUIRY model */ + SANE_Byte flags; /* pieusb.conf flags */ /* Ranges for various quantities */ SANE_Range dpi_range; @@ -315,7 +316,11 @@ struct Pieusb_Scanner typedef struct Pieusb_Scanner Pieusb_Scanner; -SANE_Status sanei_pieusb_parse_config_line(const char* config_line, SANE_Word* vendor_id, SANE_Word* product_id, SANE_Word* model_number); +SANE_Status sanei_pieusb_parse_config_line(const char* config_line, + SANE_Word* vendor_id, + SANE_Word* product_id, + SANE_Int* model_number, + SANE_Int* flags); /* sub to sane_start() */ SANE_Status sanei_pieusb_post (Pieusb_Scanner *scanner, uint16_t **in_img, int planes); void sanei_pieusb_correct_shading(struct Pieusb_Scanner *scanner, struct Pieusb_Read_Buffer *buffer); @@ -329,8 +334,8 @@ SANE_Status sanei_pieusb_set_frame_from_options(Pieusb_Scanner * scanner); void sanei_pieusb_print_options(struct Pieusb_Scanner *scanner); /* sub to sane_control_option() and sane_start() */ int sanei_pieusb_analyse_options(struct Pieusb_Scanner *scanner); -SANE_Bool sanei_pieusb_supported_device_list_contains(SANE_Word vendor_id, SANE_Word product_id, SANE_Word model_number); -SANE_Status sanei_pieusb_supported_device_list_add(SANE_Word vendor_id, SANE_Word product_id, SANE_Word model_number); +SANE_Bool sanei_pieusb_supported_device_list_contains(SANE_Word vendor_id, SANE_Word product_id, SANE_Int model_number, SANE_Int flags); +SANE_Status sanei_pieusb_supported_device_list_add(SANE_Word vendor_id, SANE_Word product_id, SANE_Int model_number, SANE_Int flags); /* sub to sane_init() and sane_open() */ SANE_Status sanei_pieusb_find_device_callback (const char *devicename); /* sub to sane_open() */ -- 2.12.2 -- SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg) -- sane-devel mailing list: sane-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel Unsubscribe: Send mail with subject "unsubscribe your_password" to sane-devel-requ...@lists.alioth.debian.org