Subject: Re: kern/26117
To: None <tron@netbsd.org>
From: Dieter <netbsd@sopwith.solgatos.com>
List: netbsd-bugs
Date: 09/08/2005 08:19:14
In message <20050908085235.A893463B877@narn.netbsd.org>, tron@netbsd.org writes:
> Synopsis: Sane needs to identify the make/model of scanner.
> 
> State-Changed-From-To: open->analyzed
> State-Changed-By: tron@netbsd.org
> State-Changed-When: Thu, 08 Sep 2005 08:52:34 +0000
> State-Changed-Why:
> Adding the suggested ioctl() has no effect on the behaviour of
> "sane-backends" which doesn't contain any code to use it.

Chicken and egg.  sane-backends doesn't have code to use the NetBSD
ioctl, because NetBSD doesn't have the ioctl yet.

Here is what I had in sane-backends-1.0.14 to use the ioctl.
I've only taken a quick glance at 1.0.16, they added code for BEOS,
but didn't add the code for NetBSD, or the warning for OSes they
don't have support for.

Warning: This isn't cleaned up.  Ignore the debugging stuff.  :-)



*** sanei/sanei_usb.c	2004/06/16 18:44:05	1.1
--- sanei/sanei_usb.c	2004/06/23 23:02:41
***************
*** 58,77 ****
--- 58,83 ----
  #ifdef HAVE_LIBUSB
  #include <usb.h>
  #endif /* HAVE_LIBUSB */
  
  #define BACKEND_NAME	sanei_usb
  #include "../include/sane/sane.h"
  #include "../include/sane/sanei_debug.h"
  #include "../include/sane/sanei_usb.h"
  #include "../include/sane/sanei_config.h"
  
+ #ifdef __NetBSD__
+ #include <dev/usb/usb.h>
+ /* #include <dev/usb/usbhid.h>  */  /* got a redefine */
+ #include <sys/ioctl.h>
+ #endif
+ 
  typedef enum
  {
    sanei_usb_method_scanner_driver = 0,	/* kernel scanner driver 
  					   (Linux, BSD) */
    sanei_usb_method_libusb
  }
  sanei_usb_access_method_type;
  
  typedef struct
  {
***************
*** 187,208 ****
        if (ioctl (fd, SCANNER_IOCTL_VENDOR_OLD, vendorID) == -1)
  	DBG (3, "kernel_get_vendor_product: ioctl (vendor) "
  	     "of device %d failed: %s\n", fd, strerror (errno));
      }
    if (ioctl (fd, SCANNER_IOCTL_PRODUCT, productID) == -1)
      {
        if (ioctl (fd, SCANNER_IOCTL_PRODUCT_OLD, productID) == -1)
  	DBG (3, "sanei_usb_get_vendor_product: ioctl (product) "
  	     "of device %d failed: %s\n", fd, strerror (errno));
      }
! #endif /* defined (__linux__) */
        /* put more os-dependant stuff ... */
  }
  
  void
  sanei_usb_init (void)
  {
    SANE_String *prefix;
    SANE_String prefixlist[] = {
  #if defined(__linux__)
      "/dev/", "usbscanner",
      "/dev/usb/", "scanner",
--- 193,245 ----
        if (ioctl (fd, SCANNER_IOCTL_VENDOR_OLD, vendorID) == -1)
  	DBG (3, "kernel_get_vendor_product: ioctl (vendor) "
  	     "of device %d failed: %s\n", fd, strerror (errno));
      }
    if (ioctl (fd, SCANNER_IOCTL_PRODUCT, productID) == -1)
      {
        if (ioctl (fd, SCANNER_IOCTL_PRODUCT_OLD, productID) == -1)
  	DBG (3, "sanei_usb_get_vendor_product: ioctl (product) "
  	     "of device %d failed: %s\n", fd, strerror (errno));
      }
!   /* end of defined (__linux__) */
! #elif defined (__NetBSD__)
!   {
! #if 1  /* Needs ioctl added to NetBSD */
! 
!     /* DBG output not showing up ? */
! 
!     struct usb_device_info struct_usb_device_info;
!     if (ioctl (fd, USB_GET_DEVICEINFO, &struct_usb_device_info) == -1)
!       {
! 	DBG (1, "kernel_get_vendor_product: ioctl (usb_deviceinfo, for vendor & product IDs) "
! 	     "of device %d failed: %s\n", fd, strerror (errno));
! 	perror("NetBSD uscanner ioctl(usb_deviceinfo) failed");
!       }
!     else
!       {
! 	*vendorID  = (int) struct_usb_device_info.udi_vendorNo;
! 	*productID = (int) struct_usb_device_info.udi_productNo;
! 	DBG (2, "NetBSD uscanner ioctl says: vendorID = 0x%04x  productID = 0x%04x\n", *vendorID, *productID);
! 	fprintf(stderr, "NetBSD uscanner ioctl says: vendorID = 0x%04x  productID = 0x%04x\n", *vendorID, *productID);
!       }
! #endif
! #ifdef HARD_CODE_NETBSD_EPSON_2400
! #warning temp hack for NetBSD to add vendorID productID Epson 2400
!     DBG (1, "NetBSD vendorID productID hardcoded hack\n");
!     *vendorID  = 0x04b8 ; /* Seiko Epson */
!     *productID = 0x011b ; /* Perfection 2400 scanner */
! #endif HARD_CODE_NETBSD_EPSON_2400
!   }
! #else
        /* put more os-dependant stuff ... */
+ #warning "You need to add support for your OS"
+ #endif 
  }
  
  void
  sanei_usb_init (void)
  {
    SANE_String *prefix;
    SANE_String prefixlist[] = {
  #if defined(__linux__)
      "/dev/", "usbscanner",
      "/dev/usb/", "scanner",
***************
*** 948,968 ****
        if (ioctl (devices[dn].fd, SCANNER_IOCTL_CTRLMSG, &c) < 0)
  	{
  	  DBG (5, "sanei_usb_control_msg: SCANNER_IOCTL_CTRLMSG error - %s\n",
  	       strerror (errno));
  	  return SANE_STATUS_IO_ERROR;
  	}
        if ((rtype & 0x80) && debug_level > 10)
  	print_buffer (data, len);
        return SANE_STATUS_GOOD;
  #else /* not __linux__ */
!       DBG (5, "sanei_usb_control_msg: not supported on this OS\n");
        return SANE_STATUS_UNSUPPORTED;
  #endif /* not __linux__ */
      }
    else if (devices[dn].method == sanei_usb_method_libusb)
  #ifdef HAVE_LIBUSB
      {
        int result;
  
        result = usb_control_msg (devices[dn].libusb_handle, rtype, req,
  				value, index, (char *) data, len,
--- 985,1006 ----
        if (ioctl (devices[dn].fd, SCANNER_IOCTL_CTRLMSG, &c) < 0)
  	{
  	  DBG (5, "sanei_usb_control_msg: SCANNER_IOCTL_CTRLMSG error - %s\n",
  	       strerror (errno));
  	  return SANE_STATUS_IO_ERROR;
  	}
        if ((rtype & 0x80) && debug_level > 10)
  	print_buffer (data, len);
        return SANE_STATUS_GOOD;
  #else /* not __linux__ */
! #warning "sanei_usb_control_msg: not supported on this OS"
!       DBG (1, "sanei_usb_control_msg: not supported on this OS\n");
        return SANE_STATUS_UNSUPPORTED;
  #endif /* not __linux__ */
      }
    else if (devices[dn].method == sanei_usb_method_libusb)
  #ifdef HAVE_LIBUSB
      {
        int result;
  
        result = usb_control_msg (devices[dn].libusb_handle, rtype, req,
  				value, index, (char *) data, len,