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
Henning Geinitz 2004-10-04 18:29:37 +00:00
rodzic 3359ae8b0a
commit 85b457a282
4 zmienionych plików z 253 dodań i 29 usunięć

Wyświetl plik

@ -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> 2004-10-04 Peter Kirchgessner <peter@kirchgessner.net>
* backend/hp.h backend/hp.c backend/hp-scl.c: * backend/hp.h backend/hp.c backend/hp-scl.c:

Wyświetl plik

@ -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 .IX sane-find-scanner
.SH NAME .SH NAME
sane-find-scanner \- find SCSI and USB scanners and their device files 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 [ \-q ]
.RB [ \-p ] .RB [ \-p ]
.RB [ \-f ] .RB [ \-f ]
.RB [ \-F
.IR filename ]
.RI [ devname ] .RI [ devname ]
.SH DESCRIPTION .SH DESCRIPTION
@ -83,6 +85,14 @@ useful if
.B sane-find-scanner .B sane-find-scanner
is wrong in determing the device type. is wrong in determing the device type.
.TP 8 .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 .B devname
Test device file "devname". No other devices are checked if devname is given. Test device file "devname". No other devices are checked if devname is given.
.SH EXAMPLE .SH EXAMPLE
@ -120,6 +130,5 @@ NetBSD, OpenBSD, and HP-UX.
.SH BUGS .SH BUGS
No support for most parallel port scanners yet. No support for most parallel port scanners yet.
.br .br
Detection of USB chipsets is limited to GrandTech 6801 and 6816, Mustek chips Detection of USB chipsets is limited to a few chipsets.
and National Semiconductor lm983x chips.

Wyświetl plik

@ -27,19 +27,20 @@
#include "../include/sane/config.h" #include "../include/sane/config.h"
#include "../include/sane/sane.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
static int verbose = 0; static int verbose = 0;
static SANE_Bool no_chipset_access;
#define TIMEOUT 1000 #define TIMEOUT 1000
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB
#include <usb.h> #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 static int
@ -47,6 +48,9 @@ prepare_interface (struct usb_device *dev, usb_dev_handle ** handle)
{ {
int result; int result;
if (no_chipset_access)
return 0;
*handle = usb_open (dev); *handle = usb_open (dev);
if (*handle == 0) if (*handle == 0)
{ {
@ -860,20 +864,17 @@ check_ma1509 (struct usb_device *dev)
|| (dev->config[0].interface[0].altsetting[0].endpoint[0]. || (dev->config[0].interface[0].altsetting[0].endpoint[0].
bmAttributes != 0x02) bmAttributes != 0x02)
|| (dev->config[0].interface[0].altsetting[0].endpoint[0]. || (dev->config[0].interface[0].altsetting[0].endpoint[0].
wMaxPacketSize != 0x40) wMaxPacketSize != 0x40))
|| (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
0xff))
{ {
if (verbose > 2) if (verbose > 2)
printf printf
(" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " (" 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]. dev->config[0].interface[0].altsetting[0].endpoint[0].
bEndpointAddress, bEndpointAddress,
dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
dev->config[0].interface[0].altsetting[0].endpoint[0]. dev->config[0].interface[0].altsetting[0].endpoint[0].
wMaxPacketSize, wMaxPacketSize);
dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
return 0; return 0;
} }
if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. 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]. || (dev->config[0].interface[0].altsetting[0].endpoint[1].
bmAttributes != 0x02) bmAttributes != 0x02)
|| (dev->config[0].interface[0].altsetting[0].endpoint[1]. || (dev->config[0].interface[0].altsetting[0].endpoint[1].
wMaxPacketSize != 0x08) wMaxPacketSize != 0x08))
|| (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
0x00))
{ {
if (verbose > 2) if (verbose > 2)
printf printf
(" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " (" 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]. dev->config[0].interface[0].altsetting[0].endpoint[1].
bEndpointAddress, bEndpointAddress,
dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
dev->config[0].interface[0].altsetting[0].endpoint[1]. dev->config[0].interface[0].altsetting[0].endpoint[1].
wMaxPacketSize, wMaxPacketSize);
dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
return 0; return 0;
} }
if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
@ -1780,8 +1778,8 @@ check_gl841 (struct usb_device *dev)
bmAttributes != 0x03) bmAttributes != 0x03)
|| (dev->config[0].interface[0].altsetting[0].endpoint[2]. || (dev->config[0].interface[0].altsetting[0].endpoint[2].
wMaxPacketSize != 0x1) wMaxPacketSize != 0x1)
|| (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != || ((dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8)
8)) && (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 16)))
{ {
if (verbose > 2) if (verbose > 2)
printf printf
@ -2009,11 +2007,12 @@ check_icm532b (struct usb_device *dev)
/* ====================================== end of icm532b ==================*/ /* ====================================== end of icm532b ==================*/
char * 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; char *chip_name = 0;
verbose = verbosity; verbose = verbosity;
no_chipset_access = from_file;
if (verbose > 2) if (verbose > 2)
printf ("\n<trying to find out which USB chip is used>\n"); printf ("\n<trying to find out which USB chip is used>\n");

Wyświetl plik

@ -36,15 +36,16 @@
#include <ddk/ntddscsi.h> #include <ddk/ntddscsi.h>
#endif #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.h"
#include "../include/sane/sanei_scsi.h" #include "../include/sane/sanei_scsi.h"
#include "../include/sane/sanei_usb.h" #include "../include/sane/sanei_usb.h"
#include "../include/sane/sanei_pa4s2.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 #ifndef PATH_MAX
# define PATH_MAX 1024 # define PATH_MAX 1024
@ -92,6 +93,8 @@ usage (char *msg)
fprintf (stderr, "\t-f: force opening devname as SCSI even if it looks " fprintf (stderr, "\t-f: force opening devname as SCSI even if it looks "
"like USB\n"); "like USB\n");
fprintf (stderr, "\t-p: enable scannig for parallel port devices\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) if (msg)
fprintf (stderr, "\t%s\n", msg); fprintf (stderr, "\t%s\n", msg);
} }
@ -433,7 +436,7 @@ get_libusb_product (struct usb_device *dev)
} }
static void static void
check_libusb_device (struct usb_device *dev) check_libusb_device (struct usb_device *dev, SANE_Bool from_file)
{ {
int is_scanner = 0; int is_scanner = 0;
char *vendor = get_libusb_vendor (dev); char *vendor = get_libusb_vendor (dev);
@ -610,7 +613,7 @@ check_libusb_device (struct usb_device *dev)
if (is_scanner > 0) 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); printf ("found USB scanner (vendor=0x%04x", dev->descriptor.idVendor);
if (vendor) if (vendor)
@ -620,6 +623,9 @@ check_libusb_device (struct usb_device *dev)
printf (" [%s]", product); printf (" [%s]", product);
if (chipset) if (chipset)
printf (", chip=%s", chipset); printf (", chip=%s", chipset);
if (from_file)
printf (")\n");
else
printf (") at libusb:%s:%s\n", dev->bus->dirname, dev->filename); printf (") at libusb:%s:%s\n", dev->bus->dirname, dev->filename);
libusb_device_found = SANE_TRUE; libusb_device_found = SANE_TRUE;
@ -882,7 +888,205 @@ check_mustek_pp_device (void)
" # man-page for setup instructions.\n"); " # man-page for setup instructions.\n");
return (found > 0 || scsi > 0); 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 int
@ -924,6 +1128,10 @@ main (int argc, char **argv)
enable_pp_checks = SANE_TRUE; enable_pp_checks = SANE_TRUE;
break; break;
case 'F':
parse_file ((char *) (*(++ap)));
exit (0);
default: default:
printf ("unknown option: -%c, try -h for help\n", (*ap)[1]); printf ("unknown option: -%c, try -h for help\n", (*ap)[1]);
exit (0); exit (0);
@ -1301,7 +1509,7 @@ main (int argc, char **argv)
{ {
for (dev = bus->devices; dev; dev = dev->next) for (dev = bus->devices; dev; dev = dev->next)
{ {
check_libusb_device (dev); check_libusb_device (dev, SANE_FALSE);
} /* for (dev) */ } /* for (dev) */
} /* for (bus) */ } /* for (bus) */
} /* if (usb_dev_list == ap) */ } /* if (usb_dev_list == ap) */