diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/check-usb-chip.c | 210 | ||||
-rwxr-xr-x | tools/epson2usb.pl | 63 | ||||
-rw-r--r-- | tools/sane-desc.c | 9 | ||||
-rw-r--r-- | tools/sane-find-scanner.c | 2 |
4 files changed, 279 insertions, 5 deletions
diff --git a/tools/check-usb-chip.c b/tools/check-usb-chip.c index 68b8f79..e851855 100644 --- a/tools/check-usb-chip.c +++ b/tools/check-usb-chip.c @@ -4063,6 +4063,213 @@ check_genesys (libusb_device_handle * handle, return "GL646_HP"; } +/********** the lm983x section **********/ + +static int +lm983x_wb (libusb_device_handle *handle, unsigned char reg, unsigned char val) +{ + unsigned char buf[5]; + int written; + int result; + + buf[0] = 0; + buf[1] = reg; + buf[2] = 0; + buf[3] = 1; + buf[4] = val; + + result = libusb_bulk_transfer(handle, 0x03, buf, 5, &written, TIMEOUT); + if (result < 0) + return 0; + + if (written != 5) + return 0; + + return 1; +} + +static int +lm983x_rb (libusb_device_handle *handle, unsigned char reg, unsigned char *val) +{ + unsigned char buf[5]; + int result; + int tfx; + + buf[0] = 1; + buf[1] = reg; + buf[2] = 0; + buf[3] = 1; + + result = libusb_bulk_transfer(handle, 0x03, buf, 4, &tfx, TIMEOUT); + if (result < 0) + return 0; + + if (tfx != 4) + return 0; + + result = libusb_bulk_transfer(handle, 0x82, val, 1, &tfx, TIMEOUT); + if (result < 0) + return 0; + + if (tfx != 1) + return 0; + + return 1; +} + +/** @brief check for known LM983x chip (aka Merlin) + * + * Try to check if the scanner uses a LM983x ASIC. + * + * @param dev libusb device + * @param hdl libusb opened handle + * @param config0 configuration 0 from get config _descriptor + * @return a string with ASIC name, or NULL if not recognized + */ +static char * +check_merlin(libusb_device_handle * handle, + struct libusb_device_descriptor desc, + struct libusb_config_descriptor *config0) +{ + unsigned char val; + int result; + + if (verbose > 2) + printf (" checking for LM983[1,2,3] ...\n"); + + /* Check device descriptor */ + if (((desc.bDeviceClass != LIBUSB_CLASS_VENDOR_SPEC) + && (desc.bDeviceClass != 0)) + || (config0->interface[0].altsetting[0].bInterfaceClass != + LIBUSB_CLASS_VENDOR_SPEC)) + { + if (verbose > 2) + printf + (" this is not a LM983x (bDeviceClass = %d, bInterfaceClass = %d)\n", + desc.bDeviceClass, + config0->interface[0].altsetting[0].bInterfaceClass); + return 0; + } + if ((desc.bcdUSB != 0x110) + && (desc.bcdUSB != 0x101) + && (desc.bcdUSB != 0x100)) + { + if (verbose > 2) + printf (" this is not a LM983x (bcdUSB = 0x%x)\n", desc.bcdUSB); + return 0; + } + if (desc.bDeviceSubClass != 0x00) + { + if (verbose > 2) + printf (" this is not a LM983x (bDeviceSubClass = 0x%x)\n", + desc.bDeviceSubClass); + return 0; + } + if ((desc.bDeviceProtocol != 0) && + (desc.bDeviceProtocol != 0xff)) + { + if (verbose > 2) + printf (" this is not a LM983x (bDeviceProtocol = 0x%x)\n", + desc.bDeviceProtocol); + return 0; + } + + /* Check endpoints */ + if (config0->interface[0].altsetting[0].bNumEndpoints != 3) + { + if (verbose > 2) + printf (" this is not a LM983x (bNumEndpoints = %d)\n", + config0->interface[0].altsetting[0].bNumEndpoints); + return 0; + } + + if ((config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress != 0x81) + || (config0->interface[0].altsetting[0].endpoint[0].bmAttributes != 0x03) + || (config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize != 0x1) + || (config0->interface[0].altsetting[0].endpoint[0].bInterval != 0x10)) + { + if (verbose > 2) + printf + (" this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " + "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", + config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress, + config0->interface[0].altsetting[0].endpoint[0].bmAttributes, + config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize, + config0->interface[0].altsetting[0].endpoint[0].bInterval); + return 0; + } + + if ((config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress != 0x82) + || (config0->interface[0].altsetting[0].endpoint[1].bmAttributes != 0x02) + || (config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize != 0x40) + /* Currently disabled as we have some problems in detection here ! */ + /*|| (config0->interface[0].altsetting[0].endpoint[1].bInterval != 0) */ + ) + { + if (verbose > 2) + printf + (" this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " + "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", + config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress, + config0->interface[0].altsetting[0].endpoint[1].bmAttributes, + config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize, + config0->interface[0].altsetting[0].endpoint[1].bInterval); + return 0; + } + + if ((config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress != 0x03) + || (config0->interface[0].altsetting[0].endpoint[2].bmAttributes != 0x02) + || (config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize != 0x40) + /* Currently disabled as we have some problems in detection here ! */ + /* || (config0->interface[0].altsetting[0].endpoint[2].bInterval != 0) */ + ) + { + if (verbose > 2) + printf + (" this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " + "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", + config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress, + config0->interface[0].altsetting[0].endpoint[2].bmAttributes, + config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize, + config0->interface[0].altsetting[0].endpoint[2].bInterval); + return 0; + } + + result = lm983x_wb (handle, 0x07, 0x00); + if (1 == result) + result = lm983x_wb (handle, 0x08, 0x02); + if (1 == result) + result = lm983x_rb (handle, 0x07, &val); + if (1 == result) + result = lm983x_rb (handle, 0x08, &val); + if (1 == result) + result = lm983x_rb (handle, 0x69, &val); + + if (0 == result) + { + if (verbose > 2) + printf (" Couldn't access LM983x registers.\n"); + return 0; + } + + switch (val) + { + case 4: + return "LM9832/3"; + break; + case 3: + return "LM9831"; + break; + case 2: + return "LM9830"; + break; + default: + return "LM983x?"; + break; + } +} + + char * check_usb_chip (int verbosity, struct libusb_device_descriptor desc, @@ -4102,6 +4309,9 @@ check_usb_chip (int verbosity, /* now USB is opened and set up, actual chip detection */ if (!chip_name) + chip_name = check_merlin (hdl, desc, config0); + + if (!chip_name) chip_name = check_gt6801 (hdl, desc, config0); if (!chip_name) diff --git a/tools/epson2usb.pl b/tools/epson2usb.pl new file mode 100755 index 0000000..afd6ebd --- /dev/null +++ b/tools/epson2usb.pl @@ -0,0 +1,63 @@ +#!/usr/bin/perl -w + +# Creates an USB device list from the description file +# +# epson2usb.pl doc/descriptions/epson2.desc +# +# Copyright (C) 2010 Tower Technologies +# Author: Alessandro Zummo <a.zummo@towertech.it> +# +# This file is part of the SANE package. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, version 2. + +use strict; +use warnings; + + my %ids; + my @models; + my $i = 0; + + while (<>) { + + my $flip = /^:model/ ... /^$/; + + $models[$i]{$1} = $2 + if /^:(\w+)\s+(.+)/; + + $i++ + if $flip =~ /E0$/; + } + + foreach my $m (@models) { + + next unless defined $m->{'usbid'}; + next if $m->{'status'} eq ':unsupported'; + +# print $m->{'model'} , "\n"; +# print "-", $m->{'usbid'} , "-\n"; + + next unless $m->{'usbid'} =~ /"0x04b8"\s+"(0x[[:xdigit:]]+)"/; + + my $id = $1; + +# print $id, "\n"; + + $id =~ s/0x0/0x/; + + $m->{'model'} =~ s/;.+$//; + $m->{'model'} =~ s/\"//g; + $m->{'model'} =~ s/\s+$//; + + push(@{$ids{$id}}, $m->{'model'}); + } + + foreach (sort keys %ids) { + print ' ', $_, ', /* '; + print join(', ', @{$ids{$_}}); + print " */\n"; + } + + diff --git a/tools/sane-desc.c b/tools/sane-desc.c index 3cc4407..c8b50ad 100644 --- a/tools/sane-desc.c +++ b/tools/sane-desc.c @@ -3568,7 +3568,8 @@ print_udev (void) printf ("\nLABEL=\"libsane_usb_rules_end\"\n\n"); - printf ("SUBSYSTEMS!=\"scsi\", GOTO=\"libsane_scsi_rules_end\"\n\n"); + printf ("SUBSYSTEMS==\"scsi\", GOTO=\"libsane_scsi_rules_begin\"\n"); + printf ("GOTO=\"libsane_scsi_rules_end\"\n\n"); printf ("LABEL=\"libsane_scsi_rules_begin\"\n"); printf ("# Generic: SCSI device type 6 indicates a scanner\n"); @@ -3695,7 +3696,9 @@ print_udevhwdb (void) printf("# The following rule will disable USB autosuspend for the device\n"); printf("ENV{DEVTYPE}==\"usb_device\", ENV{libsane_matched}==\"yes\", TEST==\"power/control\", ATTR{power/control}=\"on\"\n\n"); - printf ("SUBSYSTEMS!=\"scsi\", GOTO=\"libsane_rules_end\"\n"); + printf ("SUBSYSTEMS==\"scsi\", GOTO=\"libsane_scsi_rules_begin\"\n"); + printf ("GOTO=\"libsane_rules_end\"\n\n"); + printf ("LABEL=\"libsane_scsi_rules_begin\"\n"); printf ("KERNEL!=\"sg[0-9]*\", GOTO=\"libsane_rules_end\"\n\n"); printf ("# Generic: SCSI device type 6 indicates a scanner\n"); @@ -3827,7 +3830,7 @@ print_hwdb (void) for(j = 0; j < 4; j++) { vendor_id[j] = toupper(vendor_id[j]); - product_id[j] = toupper(vendor_id[j]); + product_id[j] = toupper(product_id[j]); } printf ("usb:v%sp%s*\n libsane_matched=yes\n\n", diff --git a/tools/sane-find-scanner.c b/tools/sane-find-scanner.c index dbfd0da..ae0e116 100644 --- a/tools/sane-find-scanner.c +++ b/tools/sane-find-scanner.c @@ -757,8 +757,6 @@ sfs_libusb_strerror (int errcode) default: return "Unknown libusb-1.0 error code"; } - - return "Unknown libusb-1.0 error code"; } static char * |