kopia lustrzana https://gitlab.com/sane-project/backends
sane-find-scanner can now load USB descriptors from /proc/bus/usb/devices dumps
(e.g. from the unsupported scanner web pages). Minor modifications to some of the chipset tests.merge-requests/1/head
rodzic
3359ae8b0a
commit
85b457a282
|
@ -1,3 +1,11 @@
|
|||
2004-10-03 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
|
||||
* doc/sane-find-scanner.man tools/check-usb-chip.c
|
||||
tools/sane-find-scanner.c: sane-find-scanner can now load USB
|
||||
descriptors from /proc/bus/usb/devices dumps (e.g. from the
|
||||
unsupported scanner web pages). Minor modifications to some of
|
||||
the chipset tests.
|
||||
|
||||
2004-10-04 Peter Kirchgessner <peter@kirchgessner.net>
|
||||
|
||||
* backend/hp.h backend/hp.c backend/hp-scl.c:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH sane-find-scanner 1 "18 Jul 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.TH sane-find-scanner 1 "4 Oct 2004" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.IX sane-find-scanner
|
||||
.SH NAME
|
||||
sane-find-scanner \- find SCSI and USB scanners and their device files
|
||||
|
@ -9,6 +9,8 @@ sane-find-scanner \- find SCSI and USB scanners and their device files
|
|||
.RB [ \-q ]
|
||||
.RB [ \-p ]
|
||||
.RB [ \-f ]
|
||||
.RB [ \-F
|
||||
.IR filename ]
|
||||
.RI [ devname ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
@ -83,6 +85,14 @@ useful if
|
|||
.B sane-find-scanner
|
||||
is wrong in determing the device type.
|
||||
.TP 8
|
||||
.B \-F filename
|
||||
filename is a file that contains USB descriptors in the format of
|
||||
/proc/bus/usb/devices as used by Linux.
|
||||
.B sane-find-scanner
|
||||
tries to identify the chipset(s) of all USB scanners found in such a file. This
|
||||
option is useful for developers when the output of "cat /proc/bus/usb/devices"
|
||||
is avaliable but the scanner itsself isn't.
|
||||
.TP 8
|
||||
.B devname
|
||||
Test device file "devname". No other devices are checked if devname is given.
|
||||
.SH EXAMPLE
|
||||
|
@ -120,6 +130,5 @@ NetBSD, OpenBSD, and HP-UX.
|
|||
.SH BUGS
|
||||
No support for most parallel port scanners yet.
|
||||
.br
|
||||
Detection of USB chipsets is limited to GrandTech 6801 and 6816, Mustek chips
|
||||
and National Semiconductor lm983x chips.
|
||||
Detection of USB chipsets is limited to a few chipsets.
|
||||
|
||||
|
|
|
@ -27,19 +27,20 @@
|
|||
|
||||
|
||||
#include "../include/sane/config.h"
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
static SANE_Bool no_chipset_access;
|
||||
#define TIMEOUT 1000
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#include <usb.h>
|
||||
|
||||
extern char *check_usb_chip (struct usb_device *dev, int verbosity);
|
||||
extern char *check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file);
|
||||
|
||||
|
||||
static int
|
||||
|
@ -47,6 +48,9 @@ prepare_interface (struct usb_device *dev, usb_dev_handle ** handle)
|
|||
{
|
||||
int result;
|
||||
|
||||
if (no_chipset_access)
|
||||
return 0;
|
||||
|
||||
*handle = usb_open (dev);
|
||||
if (*handle == 0)
|
||||
{
|
||||
|
@ -860,20 +864,17 @@ check_ma1509 (struct usb_device *dev)
|
|||
|| (dev->config[0].interface[0].altsetting[0].endpoint[0].
|
||||
bmAttributes != 0x02)
|
||||
|| (dev->config[0].interface[0].altsetting[0].endpoint[0].
|
||||
wMaxPacketSize != 0x40)
|
||||
|| (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
|
||||
0xff))
|
||||
wMaxPacketSize != 0x40))
|
||||
{
|
||||
if (verbose > 2)
|
||||
printf
|
||||
(" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
|
||||
"wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
|
||||
"wMaxPacketSize = 0x%x)\n",
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[0].
|
||||
bEndpointAddress,
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[0].
|
||||
wMaxPacketSize,
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
|
||||
wMaxPacketSize);
|
||||
return 0;
|
||||
}
|
||||
if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
|
||||
|
@ -881,20 +882,17 @@ check_ma1509 (struct usb_device *dev)
|
|||
|| (dev->config[0].interface[0].altsetting[0].endpoint[1].
|
||||
bmAttributes != 0x02)
|
||||
|| (dev->config[0].interface[0].altsetting[0].endpoint[1].
|
||||
wMaxPacketSize != 0x08)
|
||||
|| (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
|
||||
0x00))
|
||||
wMaxPacketSize != 0x08))
|
||||
{
|
||||
if (verbose > 2)
|
||||
printf
|
||||
(" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
|
||||
"wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
|
||||
"wMaxPacketSize = 0x%x)\n",
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[1].
|
||||
bEndpointAddress,
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[1].
|
||||
wMaxPacketSize,
|
||||
dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
|
||||
wMaxPacketSize);
|
||||
return 0;
|
||||
}
|
||||
if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
|
||||
|
@ -1780,8 +1778,8 @@ check_gl841 (struct usb_device *dev)
|
|||
bmAttributes != 0x03)
|
||||
|| (dev->config[0].interface[0].altsetting[0].endpoint[2].
|
||||
wMaxPacketSize != 0x1)
|
||||
|| (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
|
||||
8))
|
||||
|| ((dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8)
|
||||
&& (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 16)))
|
||||
{
|
||||
if (verbose > 2)
|
||||
printf
|
||||
|
@ -2009,11 +2007,12 @@ check_icm532b (struct usb_device *dev)
|
|||
/* ====================================== end of icm532b ==================*/
|
||||
|
||||
char *
|
||||
check_usb_chip (struct usb_device *dev, int verbosity)
|
||||
check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file)
|
||||
{
|
||||
char *chip_name = 0;
|
||||
|
||||
verbose = verbosity;
|
||||
no_chipset_access = from_file;
|
||||
|
||||
if (verbose > 2)
|
||||
printf ("\n<trying to find out which USB chip is used>\n");
|
||||
|
|
|
@ -36,15 +36,16 @@
|
|||
#include <ddk/ntddscsi.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#include "usb.h"
|
||||
extern char * check_usb_chip (struct usb_device *dev, int verbosity);
|
||||
#endif
|
||||
|
||||
#include "../include/sane/sanei.h"
|
||||
#include "../include/sane/sanei_scsi.h"
|
||||
#include "../include/sane/sanei_usb.h"
|
||||
#include "../include/sane/sanei_pa4s2.h"
|
||||
#include "../include/sane/sanei_config.h"
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#include "usb.h"
|
||||
extern char * check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file);
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
|
@ -92,6 +93,8 @@ usage (char *msg)
|
|||
fprintf (stderr, "\t-f: force opening devname as SCSI even if it looks "
|
||||
"like USB\n");
|
||||
fprintf (stderr, "\t-p: enable scannig for parallel port devices\n");
|
||||
fprintf (stderr, "\t-F file: try to detect chipset from given "
|
||||
"/proc/bus/usb/devices file\n");
|
||||
if (msg)
|
||||
fprintf (stderr, "\t%s\n", msg);
|
||||
}
|
||||
|
@ -433,7 +436,7 @@ get_libusb_product (struct usb_device *dev)
|
|||
}
|
||||
|
||||
static void
|
||||
check_libusb_device (struct usb_device *dev)
|
||||
check_libusb_device (struct usb_device *dev, SANE_Bool from_file)
|
||||
{
|
||||
int is_scanner = 0;
|
||||
char *vendor = get_libusb_vendor (dev);
|
||||
|
@ -610,7 +613,7 @@ check_libusb_device (struct usb_device *dev)
|
|||
|
||||
if (is_scanner > 0)
|
||||
{
|
||||
char * chipset = check_usb_chip (dev, verbose);
|
||||
char * chipset = check_usb_chip (dev, verbose, from_file);
|
||||
|
||||
printf ("found USB scanner (vendor=0x%04x", dev->descriptor.idVendor);
|
||||
if (vendor)
|
||||
|
@ -620,7 +623,10 @@ check_libusb_device (struct usb_device *dev)
|
|||
printf (" [%s]", product);
|
||||
if (chipset)
|
||||
printf (", chip=%s", chipset);
|
||||
printf (") at libusb:%s:%s\n", dev->bus->dirname, dev->filename);
|
||||
if (from_file)
|
||||
printf (")\n");
|
||||
else
|
||||
printf (") at libusb:%s:%s\n", dev->bus->dirname, dev->filename);
|
||||
|
||||
libusb_device_found = SANE_TRUE;
|
||||
device_found = SANE_TRUE;
|
||||
|
@ -882,7 +888,205 @@ check_mustek_pp_device (void)
|
|||
" # man-page for setup instructions.\n");
|
||||
|
||||
return (found > 0 || scsi > 0);
|
||||
}
|
||||
|
||||
static SANE_Bool
|
||||
parse_num (char* search, const char* line, int base, long int * number)
|
||||
{
|
||||
char* start_number;
|
||||
|
||||
start_number = strstr (line, search);
|
||||
if (start_number == NULL)
|
||||
return SANE_FALSE;
|
||||
start_number += strlen (search);
|
||||
|
||||
*number = strtol (start_number, NULL, base);
|
||||
if (verbose > 2)
|
||||
printf ("Found %s%ld\n", search, *number);
|
||||
return SANE_TRUE;
|
||||
}
|
||||
|
||||
static SANE_Bool
|
||||
parse_bcd (char* search, const char* line, long int * number)
|
||||
{
|
||||
char* start_number;
|
||||
char* end_number;
|
||||
int first_part;
|
||||
int second_part;
|
||||
|
||||
start_number = strstr (line, search);
|
||||
if (start_number == NULL)
|
||||
return SANE_FALSE;
|
||||
start_number += strlen (search);
|
||||
|
||||
first_part = strtol (start_number, &end_number, 10);
|
||||
start_number = end_number + 1; /* skip colon */
|
||||
second_part = strtol (start_number, NULL, 10);
|
||||
*number = ((first_part / 10) << 12) + ((first_part % 10) << 8)
|
||||
+ ((second_part / 10) << 4) + (second_part % 10);
|
||||
if (verbose > 2)
|
||||
printf ("Found %s%ld\n", search, *number);
|
||||
return SANE_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_file (char *filename)
|
||||
{
|
||||
FILE * parsefile;
|
||||
char line [PATH_MAX], *token;
|
||||
const char * p;
|
||||
struct usb_device *dev = 0;
|
||||
long int number = 0;
|
||||
int current_config = 1;
|
||||
int current_if = -1;
|
||||
int current_as = -1;
|
||||
int current_ep = -1;
|
||||
|
||||
if (verbose > 1)
|
||||
printf ("trying to open %s\n", filename);
|
||||
parsefile = fopen (filename, "r");
|
||||
|
||||
if (parsefile == NULL)
|
||||
{
|
||||
if (verbose > 0)
|
||||
printf ("opening %s failed: %s\n", filename, strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while (sanei_config_read (line, PATH_MAX, parsefile))
|
||||
{
|
||||
if (verbose > 2)
|
||||
printf ("parsing line: `%s'\n", line);
|
||||
p = sanei_config_get_string (line, &token);
|
||||
if (!token || !p || token[0] == '\0')
|
||||
continue;
|
||||
if (token[1] != ':')
|
||||
{
|
||||
if (verbose > 2)
|
||||
printf ("missing `:'?\n");
|
||||
continue;
|
||||
}
|
||||
switch (token[0])
|
||||
{
|
||||
case 'T':
|
||||
if (dev)
|
||||
check_libusb_device (dev, SANE_TRUE);
|
||||
dev = calloc (1, sizeof (struct usb_device));
|
||||
dev->bus = calloc (1, sizeof (struct usb_bus));
|
||||
current_config = 1;
|
||||
current_if = -1;
|
||||
current_as = -1;
|
||||
current_ep = -1;
|
||||
break;
|
||||
case 'D':
|
||||
if (parse_bcd ("Ver=", line, &number))
|
||||
dev->descriptor.bcdUSB = number;
|
||||
if (parse_num ("Cls=", line, 16, &number))
|
||||
dev->descriptor.bDeviceClass = number;
|
||||
if (parse_num ("Sub=", line, 16, &number))
|
||||
dev->descriptor.bDeviceSubClass = number;
|
||||
if (parse_num ("Prot=", line, 16, &number))
|
||||
dev->descriptor.bDeviceProtocol = number;
|
||||
if (parse_num ("MxPS=", line, 10, &number))
|
||||
dev->descriptor.bMaxPacketSize0 = number;
|
||||
if (parse_num ("#Cfgs=", line, 10, &number))
|
||||
dev->descriptor.bNumConfigurations = number;
|
||||
dev->config = calloc (number, sizeof (struct usb_config_descriptor));
|
||||
break;
|
||||
case 'P':
|
||||
if (parse_num ("Vendor=", line, 16, &number))
|
||||
dev->descriptor.idVendor = number;
|
||||
if (parse_num ("ProdID=", line, 16, &number))
|
||||
dev->descriptor.idProduct = number;
|
||||
if (parse_bcd ("Rev=", line, &number))
|
||||
dev->descriptor.bcdDevice = number;
|
||||
break;
|
||||
case 'C':
|
||||
current_if = -1;
|
||||
current_as = -1;
|
||||
current_ep = -1;
|
||||
if (parse_num ("Cfg#=", line, 10, &number))
|
||||
{
|
||||
current_config = number - 1;
|
||||
dev->config[current_config].bConfigurationValue = number;
|
||||
}
|
||||
if (parse_num ("Ifs=", line, 10, &number))
|
||||
dev->config[current_config].bNumInterfaces = number;
|
||||
dev->config[current_config].interface
|
||||
= calloc (number, sizeof (struct usb_interface));
|
||||
if (parse_num ("Atr=", line, 16, &number))
|
||||
dev->config[current_config].bmAttributes = number;
|
||||
if (parse_num ("MxPwr=", line, 10, &number))
|
||||
dev->config[current_config].MaxPower = number / 2;
|
||||
break;
|
||||
case 'I':
|
||||
current_ep = -1;
|
||||
if (parse_num ("If#=", line, 10, &number))
|
||||
{
|
||||
if (current_if != number)
|
||||
{
|
||||
current_if = number;
|
||||
current_as = -1;
|
||||
dev->config[current_config].interface[current_if].altsetting
|
||||
= calloc (20, sizeof (struct usb_interface_descriptor));
|
||||
/* Can't read number of altsettings */
|
||||
dev->config[current_config].interface[current_if].num_altsetting = 1;
|
||||
}
|
||||
else
|
||||
dev->config[current_config].interface[current_if].num_altsetting++;
|
||||
}
|
||||
if (parse_num ("Alt=", line, 10, &number))
|
||||
{
|
||||
current_as = number;
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceNumber
|
||||
= current_if;
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].bAlternateSetting
|
||||
= current_as;
|
||||
}
|
||||
if (parse_num ("#EPs=", line, 10, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].bNumEndpoints
|
||||
= number;
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].endpoint
|
||||
= calloc (number, sizeof (struct usb_endpoint_descriptor));
|
||||
if (parse_num ("Cls=", line, 16, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceClass
|
||||
= number;
|
||||
if (parse_num ("Sub=", line, 16, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceSubClass
|
||||
= number;
|
||||
if (parse_num ("Prot=", line, 16, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceProtocol
|
||||
= number;
|
||||
break;
|
||||
case 'E':
|
||||
current_ep++;
|
||||
if (parse_num ("Ad=", line, 16, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as]
|
||||
.endpoint[current_ep].bEndpointAddress = number;
|
||||
if (parse_num ("Atr=", line, 16, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as]
|
||||
.endpoint[current_ep].bmAttributes = number;
|
||||
if (parse_num ("MxPS=", line, 10, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as]
|
||||
.endpoint[current_ep].wMaxPacketSize = number;
|
||||
if (parse_num ("Ivl=", line, 10, &number))
|
||||
dev->config[current_config].interface[current_if].altsetting[current_as]
|
||||
.endpoint[current_ep].bInterval = number;
|
||||
break;
|
||||
case 'S':
|
||||
case 'B':
|
||||
continue;
|
||||
default:
|
||||
if (verbose > 1)
|
||||
printf ("ignoring unknown line identifier: %c\n", token[0]);
|
||||
continue;
|
||||
}
|
||||
free (token);
|
||||
}
|
||||
if (dev)
|
||||
check_libusb_device (dev, SANE_TRUE);
|
||||
fclose (parsefile);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -924,6 +1128,10 @@ main (int argc, char **argv)
|
|||
enable_pp_checks = SANE_TRUE;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
parse_file ((char *) (*(++ap)));
|
||||
exit (0);
|
||||
|
||||
default:
|
||||
printf ("unknown option: -%c, try -h for help\n", (*ap)[1]);
|
||||
exit (0);
|
||||
|
@ -1301,7 +1509,7 @@ main (int argc, char **argv)
|
|||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
{
|
||||
check_libusb_device (dev);
|
||||
check_libusb_device (dev, SANE_FALSE);
|
||||
} /* for (dev) */
|
||||
} /* for (bus) */
|
||||
} /* if (usb_dev_list == ap) */
|
||||
|
|
Ładowanie…
Reference in New Issue