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>
* 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
.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.

Wyświetl plik

@ -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");

Wyświetl plik

@ -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) */