Added sane USB interface.

Henning Meier-Geinitz <henning@meier-geinitz.de>
DEVEL_2_0_BRANCH-1
Henning Geinitz 2001-08-11 13:12:39 +00:00
rodzic 06261c437d
commit 3c7567cb2b
4 zmienionych plików z 354 dodań i 3 usunięć

Wyświetl plik

@ -39,7 +39,7 @@ SECT5 = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 \
sane-tamarack.5 sane-ricoh.5 sane-avision.5 sane-plustek.5 \
sane-st400.5 sane-mustek_pp.5 sane-dc210.5 sane-v4l.5 \
sane-snapscan.5 sane-canon.5 sane-coolscan.5 sane-bh.5 sane-dc240.5 \
sane-umax_pp.5 sane-sm3600.5
sane-umax_pp.5 sane-sm3600.5 sane-usb.5
SECT7 = sane.7
MANPAGES = $(SECT1) $(SECT5) $(SECT7)
READMES = README AUTHORS COPYING ChangeLog LEVEL2 LICENSE NEWS PROBLEMS \

98
doc/sane-usb.man 100644
Wyświetl plik

@ -0,0 +1,98 @@
.TH sane-scsi 5 "11 Aug 2001"
.IX sane-usb
.SH NAME
sane-usb - USB configuration tips for SANE
.SH DESCRIPTION
This manual page contains tips and tricks on how to access scanners
with a USB interface.
.SH GENERAL INFO
Sane-backends currently use three methods of communicating with USB scanners:
.TP 2
-
Using libusb (a library for usb access). This is used by the sm3600 backend
currently.
.TP
-
Access through sanei_usb, the SANE USB interface. Used by the mustek_usb
backend.
.TP
-
Direct access to the USB device files to access kernel scanner drivers
.PP
This manual page describes the access of USB scanners over the sanei_usb
interface. For point 1 and three of this list have a look at the backend's
manual page for details.
.PP
Currently USB access is only tested for Linux. It may work on FreeBSD but it's
not tested.
.PP
For scanners with a USB interface, it may be necessary to edit the
appropriate backend configuration file before using SANE for the first time.
For most systems, the configuration file should list the name of the USB
device file that the scanner is connected to (e.g., under Linux,
.B /dev/usb/scanner0
or
.B /dev/usbscanner0
is such a USB device). Do
.I not
create a symlink from
.B /dev/scanner
to the USB device because this link is used by the SCSI backends. The scanner
may be confused if it receives SCSI commands. For a detailed description of
each backend's configuration file, please refer to the relevant backend manual
page (e.g. sane-mustek_usb Mustek USB scanners).
.PP
For Linux, there is an alternate way of specifying scanner devices. This
alternate allows to identify scanners by the USB vendor and product numbers.
The syntax for specifying a scanner in this way is:
.PP
.RS
usb
.I VENDOR PRODUCT
.RE
.PP
where
.I VENDOR
is the USB vendor id, and
.I PRODUCT
is the USB product id of the scanner. Both ids are non-negative integer
numbers in decimal or hexadecimal format. The correct values for these fields
can be found by looking at the output of the command "cat
/proc/bus/usb/devices/". This is an example of a config file line:
.PP
.RS
usb 0x055f 0x0006
.RE
.PP
would have the effect that all USB devices in the system with a vendor id of
0x55f and a product id of 0x0006 would be probed and recognized by the
backend. The same config line in decimal format looks like this:
.PP
.RS
usb 0x055f 0x0006
.RE
.PP
When using a USB scanner, ensure that the access permission for the
USB device is set appropriately. We recommend to add a group
"scanner" to /etc/group which contains all users that should have
access to the scanner. The permission of the device should then be
set to allow group read and write access. For example, if the scanner
is at USB device
.BR /dev/usb/scanner0 ,
then the following two commands would set the permission correctly:
.PP
.RS
$ chgrp scanner /dev/usb/scanner0
.br
$ chmod 660 /dev/usb/scanner0
.SH ENVIRONMENT
.TP
.B SANE_DEBUG_SANEI_USB
If the library was compiled with debug support enabled, this
environment variable controls the debug level for the USB I/O
subsystem. E.g., a value of 128 requests all debug output to be
printed. Smaller levels reduce verbosity.
.SH "SEE ALSO"
sane(7), sane\-find\-scanner(1), sane\-"backendname"(5), sane-scsi(5)
.SH AUTHOR
Henning Meier-Geinitz. Some parts were copied from the sane-scsi manual page.

Wyświetl plik

@ -45,13 +45,13 @@ LIBSANEI_OBJS = sanei_ab306.o sanei_constrain_value.o sanei_init_debug.o \
sanei_net.o sanei_wire.o sanei_codec_ascii.o sanei_codec_bin.o \
sanei_save_values.o sanei_load_values.o \
sanei_scsi.o sanei_config.o sanei_config2.o sanei_pio.o sanei_pa4s2.o \
sanei_auth.o
sanei_auth.o sanei_usb.o
LIBSANEI_LTOBJS = sanei_ab306.lo sanei_constrain_value.lo sanei_init_debug.lo \
sanei_net.lo sanei_wire.lo sanei_codec_ascii.lo sanei_codec_bin.lo \
sanei_save_values.lo sanei_load_values.lo \
sanei_scsi.lo sanei_config.lo sanei_config2.lo sanei_pio.lo \
sanei_pa4s2.lo sanei_auth.lo
sanei_pa4s2.lo sanei_auth.lo sanei_usb.lo
TARGETS = libsanei.a
TESTPROGRAMS = test_wire

253
sanei/sanei_usb.c 100644
Wyświetl plik

@ -0,0 +1,253 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2001 Henning Meier-Geinitz
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; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
This file provides a generic (?) USB interface. */
#include "../include/sane/config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdio.h>
#define BACKEND_NAME sanei_usb
#include "../include/sane/sane.h"
#include "../include/sane/sanei_debug.h"
#include "../include/sane/sanei_usb.h"
void
sanei_usb_init (void)
{
DBG_INIT();
}
SANE_Status
sanei_usb_get_vendor_product (SANE_Int fd, SANE_Word * vendor,
SANE_Word * product)
{
SANE_Word vendorID, productID;
#if defined (__linux__)
#define IOCTL_SCANNER_VENDOR _IOR('u', 0xa0, int)
#define IOCTL_SCANNER_PRODUCT _IOR('u', 0xa1, int)
/* read the vendor and product IDs via the IOCTLs */
if (ioctl (fd, IOCTL_SCANNER_VENDOR , &vendorID) == -1)
{
DBG (3, "sanei_usb_get_vendor_product: ioctl (vendor) of fd %d failed: "
"%s\n", fd, strerror (errno));
/* just set the vendor ID to 0 */
vendorID = 0;
}
if (ioctl (fd, IOCTL_SCANNER_PRODUCT , &productID) == -1)
{
DBG (3, "sanei_usb_get_vendor_product: ioctl (product) of ds %d failed: "
"%s\n", fd, strerror (errno));
/* just set the product ID to 0 */
productID = 0;
}
if (vendor)
*vendor = vendorID;
if (product)
*product = productID;
#else /* not defined (__linux__) */
vendorID = 0;
productID = 0;
#endif /* not defined (__linux__) */
if (!vendorID || !productID)
{
DBG (3, "sanei_usb_get_vendor_product: fd %d: couldn't get "
"vendor+product ids. ioctl unsupported?\n", fd);
return SANE_STATUS_UNSUPPORTED;
}
else
{
DBG (3, "sanei_usb_get_vendor_product: fd %d: vendorID: 0x%x, "
"productID: 0x%x\n", fd, vendorID, productID);
return SANE_STATUS_GOOD;
}
}
static void
check_vendor_product (SANE_String_Const devname, SANE_Word vendor,
SANE_Word product,
SANE_Status (*attach) (SANE_String_Const dev))
{
SANE_Status status;
SANE_Word devvendor, devproduct;
SANE_Int fd;
status = sanei_usb_open (devname, &fd);
if (status != SANE_STATUS_GOOD)
return;
status = sanei_usb_get_vendor_product (fd, &devvendor, &devproduct);
sanei_usb_close (fd);
if (status == SANE_STATUS_GOOD)
{
if (devvendor == vendor && devproduct == product)
{
if (attach)
attach (devname);
}
}
return;
}
SANE_Status
sanei_usb_find_devices (SANE_Int vendor, SANE_Int product,
SANE_Status (*attach) (SANE_String_Const dev))
{
SANE_String *prefix;
SANE_String prefixlist[] = {"/dev/usbscanner",
"/dev/usb/scanner",
0};
SANE_Char devname[30];
int devcount;
#define SANEI_USB_MAX_DEVICES 16
DBG (3, "sanei_usb_find_devices: vendor=0x%x, product=0x%x, attach=%p\n",
vendor, product, attach);
for (prefix = prefixlist; *prefix; prefix++)
{
check_vendor_product (*prefix, vendor, product, attach);
for (devcount = 0; devcount < SANEI_USB_MAX_DEVICES;
devcount++)
{
snprintf (devname, sizeof (devname), "%s%d", *prefix,
devcount);
check_vendor_product (devname, vendor, product, attach);
}
}
return SANE_STATUS_GOOD;
}
SANE_Status
sanei_usb_open (SANE_String_Const devname, SANE_Int *fd)
{
if (!fd)
{
DBG (1, "sanei_usb_open: fd == NULL\n", fd);
return SANE_STATUS_INVAL;
}
*fd = open (devname, O_RDWR);
if (*fd < 0)
{
SANE_Status status = SANE_STATUS_INVAL;
DBG (1, "sanei_usb_open: open failed: %s\n", strerror (errno));
if (errno == EACCES)
status = SANE_STATUS_ACCESS_DENIED;
return status;
}
DBG (5, "sanei_usb_open: fd %d opened\n", *fd);
return SANE_STATUS_GOOD;
}
void
sanei_usb_close (SANE_Int fd)
{
DBG (5, "sanei_usb_close: closing fd %d\n", fd);
close (fd);
return;
}
SANE_Status
sanei_usb_read_bulk (SANE_Int fd, SANE_Byte * buffer, size_t *size)
{
ssize_t read_size;
if (!size)
{
DBG (1, "sanei_usb_read_bulk: size == NULL\n");
return SANE_STATUS_INVAL;
}
read_size = read (fd, buffer, *size);
if (read_size < 0)
{
DBG (1, "sanei_usb_read_bulk: read failed: %s\n", strerror (errno));
*size = 0;
return SANE_STATUS_IO_ERROR;
}
if (read_size == 0)
{
DBG (3, "sanei_usb_read_bulk: read returned EOF\n");
*size = 0;
return SANE_STATUS_EOF;
}
DBG (5, "sanei_usb_read_bulk: wanted %lu bytes, got %l bytes\n",
*size, read_size);
*size = read_size;
return SANE_STATUS_GOOD;
}
SANE_Status
sanei_usb_write_bulk (SANE_Int fd, SANE_Byte * buffer, size_t *size)
{
ssize_t write_size;
if (!size)
{
DBG (1, "sanei_usb_write_bulk: size == NULL\n");
return SANE_STATUS_INVAL;
}
write_size = write (fd, buffer, *size);
if (write_size < 0)
{
DBG (1, "sanei_usb_write_bulk: write failed: %s\n", strerror (errno));
*size = 0;
return SANE_STATUS_IO_ERROR;
}
DBG (5, "sanei_usb_read_write: wanted %lu bytes, wrote %l bytes\n",
*size, write_size);
*size = write_size;
return SANE_STATUS_GOOD;
}