kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			Added sane USB interface.
Henning Meier-Geinitz <henning@meier-geinitz.de>DEVEL_2_0_BRANCH-1
							rodzic
							
								
									06261c437d
								
							
						
					
					
						commit
						3c7567cb2b
					
				| 
						 | 
				
			
			@ -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 \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue