Added support for usb functionality on OS/2 using the usbcalls interface (patch

from Paul Smedley <paul@smedley.info>).
merge-requests/1/head
Henning Geinitz 2005-08-07 14:26:33 +00:00
rodzic 5cd850ee6a
commit 2d224c4a75
5 zmienionych plików z 659 dodań i 30 usunięć

Wyświetl plik

@ -9,5 +9,9 @@
warnings.
* doc/releases.txt: Typo fix.
* config.guess config.sub: Updated from libtool 1.5.18.
* configure configure.in include/sane/config.h.in
sanei/sanei_usb.c: Added support for usb functionality on OS/2
using the usbcalls interface (patch from Paul Smedley
<paul@smedley.info>).
Older entries can be found in ChangeLog-1.0.16.

275
configure vendored
Wyświetl plik

@ -7389,6 +7389,225 @@ fi
if test "${ac_cv_header_usbcalls_h+set}" = set; then
echo "$as_me:$LINENO: checking for usbcalls.h" >&5
echo $ECHO_N "checking for usbcalls.h... $ECHO_C" >&6
if test "${ac_cv_header_usbcalls_h+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: $ac_cv_header_usbcalls_h" >&5
echo "${ECHO_T}$ac_cv_header_usbcalls_h" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking usbcalls.h usability" >&5
echo $ECHO_N "checking usbcalls.h usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <usbcalls.h>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking usbcalls.h presence" >&5
echo $ECHO_N "checking usbcalls.h presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <usbcalls.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: usbcalls.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: usbcalls.h: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: present but cannot be compiled" >&5
echo "$as_me: WARNING: usbcalls.h: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: usbcalls.h: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: see the Autoconf documentation" >&5
echo "$as_me: WARNING: usbcalls.h: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: usbcalls.h: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: usbcalls.h: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: usbcalls.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: usbcalls.h: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------------- ##
## Report this to sane-devel@lists.alioth.debian.org ##
## ------------------------------------------------- ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for usbcalls.h" >&5
echo $ECHO_N "checking for usbcalls.h... $ECHO_C" >&6
if test "${ac_cv_header_usbcalls_h+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_header_usbcalls_h=$ac_header_preproc
fi
echo "$as_me:$LINENO: result: $ac_cv_header_usbcalls_h" >&5
echo "${ECHO_T}$ac_cv_header_usbcalls_h" >&6
fi
if test $ac_cv_header_usbcalls_h = yes; then
echo "$as_me:$LINENO: checking for rsm_open_device in -lusbcalls" >&5
echo $ECHO_N "checking for rsm_open_device in -lusbcalls... $ECHO_C" >&6
if test "${ac_cv_lib_usbcalls_rsm_open_device+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lusbcalls $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char rsm_open_device ();
int
main ()
{
rsm_open_device ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_usbcalls_rsm_open_device=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_usbcalls_rsm_open_device=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_usbcalls_rsm_open_device" >&5
echo "${ECHO_T}$ac_cv_lib_usbcalls_rsm_open_device" >&6
if test $ac_cv_lib_usbcalls_rsm_open_device = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_USBCALLS 1
_ACEOF
LIBS="$LIBS -lusbcalls"
fi
fi
echo "$as_me:$LINENO: checking return type of signal handlers" >&5
echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
if test "${ac_cv_type_signal+set}" = set; then
@ -10781,7 +11000,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 10784 "configure"' > conftest.$ac_ext
echo '#line 11003 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@ -12014,7 +12233,7 @@ fi
# Provide some information about the compiler.
echo "$as_me:12017:" \
echo "$as_me:12236:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@ -13073,11 +13292,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13076: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13295: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:13080: \$? = $ac_status" >&5
echo "$as_me:13299: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -13316,11 +13535,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13319: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13538: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:13323: \$? = $ac_status" >&5
echo "$as_me:13542: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -13376,11 +13595,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13379: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13598: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:13383: \$? = $ac_status" >&5
echo "$as_me:13602: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -15552,7 +15771,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 15555 "configure"
#line 15774 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -15650,7 +15869,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 15653 "configure"
#line 15872 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -17845,11 +18064,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17848: $lt_compile\"" >&5)
(eval echo "\"\$as_me:18067: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:17852: \$? = $ac_status" >&5
echo "$as_me:18071: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -17905,11 +18124,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17908: $lt_compile\"" >&5)
(eval echo "\"\$as_me:18127: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:17912: \$? = $ac_status" >&5
echo "$as_me:18131: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -19259,7 +19478,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 19262 "configure"
#line 19481 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -19357,7 +19576,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 19360 "configure"
#line 19579 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -20194,11 +20413,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:20197: $lt_compile\"" >&5)
(eval echo "\"\$as_me:20416: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:20201: \$? = $ac_status" >&5
echo "$as_me:20420: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -20254,11 +20473,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:20257: $lt_compile\"" >&5)
(eval echo "\"\$as_me:20476: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:20261: \$? = $ac_status" >&5
echo "$as_me:20480: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -22291,11 +22510,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:22294: $lt_compile\"" >&5)
(eval echo "\"\$as_me:22513: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:22298: \$? = $ac_status" >&5
echo "$as_me:22517: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -22534,11 +22753,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:22537: $lt_compile\"" >&5)
(eval echo "\"\$as_me:22756: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:22541: \$? = $ac_status" >&5
echo "$as_me:22760: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -22594,11 +22813,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:22597: $lt_compile\"" >&5)
(eval echo "\"\$as_me:22816: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:22601: \$? = $ac_status" >&5
echo "$as_me:22820: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -24770,7 +24989,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 24773 "configure"
#line 24992 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -24868,7 +25087,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 24871 "configure"
#line 25090 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H

Wyświetl plik

@ -138,6 +138,17 @@ AC_CHECK_HEADER(resmgr.h,[
)
])
AC_CHECK_HEADER(usbcalls.h,[
AC_CHECK_LIB(
usbcalls,
rsm_open_device,[
AC_DEFINE(HAVE_USBCALLS,1,[define if you have the usbcalls library])
LIBS="$LIBS -lusbcalls"
]
)
])
dnl ***********************************************************************
dnl Checks for types and structures
dnl ***********************************************************************

Wyświetl plik

@ -350,6 +350,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* define if you have the usbcalls library */
#undef HAVE_USBCALLS
/* Define to 1 if you have the <usb.h> header file. */
#undef HAVE_USB_H

Wyświetl plik

@ -2,6 +2,7 @@
Copyright (C) 2003 Rene Rebe (sanei_read_int,sanei_set_timeout)
Copyright (C) 2001 - 2003 Henning Meier-Geinitz
Copyright (C) 2001 Frank Zago (sanei_usb_control_msg)
Copyright (C) 2005 Paul Smedley <paul@smedley.info> (OS/2 usbcalls)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
@ -62,6 +63,30 @@
#include <usb.h>
#endif /* HAVE_LIBUSB */
#ifdef HAVE_USBCALLS
#include <usb.h>
#include <os2.h>
#include <usbcalls.h>
#define MAX_RW 64000
static int usbcalls_timeout = 30 * 1000; /* 30 seconds */
USBHANDLE dh;
HEV UsbIrqStartHev;
static
struct usb_descriptor_header *GetNextDescriptor( struct usb_descriptor_header *currHead, UCHAR *lastBytePtr)
{
UCHAR *currBytePtr, *nextBytePtr;
if (!currHead->bLength)
return (NULL);
currBytePtr=(UCHAR *)currHead;
nextBytePtr=currBytePtr+currHead->bLength;
if (nextBytePtr>=lastBytePtr)
return (NULL);
return ((struct usb_descriptor_header*)nextBytePtr);
}
#endif /* HAVE_USBCALLS */
#define BACKEND_NAME sanei_usb
#include "../include/sane/sane.h"
#include "../include/sane/sanei_debug.h"
@ -72,7 +97,9 @@ typedef enum
{
sanei_usb_method_scanner_driver = 0, /* kernel scanner driver
(Linux, BSD) */
sanei_usb_method_libusb
sanei_usb_method_libusb,
sanei_usb_method_usbcalls
}
sanei_usb_access_method_type;
@ -436,6 +463,81 @@ sanei_usb_init (void)
}
}
#endif /* HAVE_LIBUSB */
#ifdef HAVE_USBCALLS
/* Check for devices using OS/2 USBCALLS Interface */
CHAR ucData[2048];
struct usb_device_descriptor *pDevDesc;
struct usb_config_descriptor *pCfgDesc;
struct usb_interface_descriptor *intf;
struct usb_endpoint_descriptor *ep;
struct usb_descriptor_header *pDescHead;
APIRET rc;
ULONG ulNumDev, ulDev, ulBufLen;
ulBufLen = sizeof(ucData);
memset(&ucData,0,sizeof(ucData));
rc = UsbQueryNumberDevices( &ulNumDev);
if(rc==0 && ulNumDev)
{
for (ulDev=1; ulDev<=ulNumDev; ulDev++)
{
rc = UsbQueryDeviceReport( ulDev,
&ulBufLen,
ucData);
pDevDesc = (struct usb_device_descriptor*)ucData;
pCfgDesc = (struct usb_config_descriptor*) (ucData+sizeof(struct usb_device_descriptor));
int interface=0;
SANE_Bool found;
if (!pCfgDesc->bConfigurationValue)
{
DBG (1, "sanei_usb_init: device 0x%04x/0x%04x is not configured\n",
pDevDesc->idVendor, pDevDesc->idProduct);
continue;
}
if (pDevDesc->idVendor == 0 || pDevDesc->idProduct == 0)
{
DBG (5, "sanei_usb_init: device 0x%04x/0x%04x looks like a root hub\n",
pDevDesc->idVendor, pDevDesc->idProduct);
continue;
}
found = SANE_FALSE;
if (pDevDesc->bDeviceClass = USB_CLASS_VENDOR_SPEC)
{
found = SANE_TRUE;
}
if (!found)
{
DBG (5, "sanei_usb_init: device 0x%04x/0x%04x: no suitable interfaces\n",
pDevDesc->idVendor, pDevDesc->idProduct);
continue;
}
snprintf (devname, sizeof (devname), "usbcalls:%d",
ulDev);
devices[dn].devname = strdup (devname);
devices[dn].fd = ulDev; /* store usbcalls device number */
devices[dn].vendor = pDevDesc->idVendor;
devices[dn].product = pDevDesc->idProduct;
devices[dn].method = sanei_usb_method_usbcalls;
devices[dn].open = SANE_FALSE;
devices[dn].interface_nr = interface;
DBG (4, "sanei_usb_init: found usbcalls device (0x%04x/0x%04x) as device number %s\n",
pDevDesc->idVendor, pDevDesc->idProduct,devices[dn].devname);
dn++;
if (dn >= MAX_DEVICES)
return;
}
}
#endif /* HAVE_USBCALLS */
DBG (5, "sanei_usb_init: found %d devices\n", dn);
}
@ -508,13 +610,22 @@ sanei_usb_get_vendor_product (SANE_Int dn, SANE_Word * vendor,
return SANE_STATUS_UNSUPPORTED;
#endif /* HAVE_LIBUSB */
}
else if (devices[dn].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
vendorID = devices[dn].vendor;
productID = devices[dn].product;
#else
DBG (1, "sanei_usb_get_vendor_product: usbcalls support missing\n");
return SANE_STATUS_UNSUPPORTED;
#endif /* HAVE_USBCALLS */
}
else
{
DBG (1, "sanei_usb_get_vendor_product: access method %d not "
"implemented\n", devices[dn].method);
return SANE_STATUS_INVAL;
}
if (vendor)
*vendor = vendorID;
if (product)
@ -880,6 +991,153 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
devname, strerror (errno));
}
}
else if (devices[devcount].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
CHAR ucData[2048];
struct usb_device_descriptor *pDevDesc;
struct usb_config_descriptor *pCfgDesc;
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_descriptor_header *pDescHead;
ULONG ulBufLen;
ulBufLen = sizeof(ucData);
memset(&ucData,0,sizeof(ucData));
int result, num,rc;
int address, direction, transfer_type;
DBG (5, "devname = %s, devcount = %d\n",devices[devcount].devname,devcount);
DBG (5, "USBCalls device number to open = %d\n",devices[devcount].fd);
DBG (5, "USBCalls Vendor/Product to open = 0x%04x/0x%04x\n",
devices[devcount].vendor,devices[devcount].product);
rc = UsbOpen (&dh,
devices[devcount].vendor,
devices[devcount].product,
USB_ANY_PRODUCTVERSION,
USB_OPEN_FIRST_UNUSED);
DBG (1, "sanei_usb_open: UsbOpen rc = %d\n",rc);
if (rc!=0)
{
SANE_Status status = SANE_STATUS_INVAL;
DBG (1, "sanei_usb_open: can't open device `%s': %s\n",
devname, strerror (rc));
return status;
}
rc = UsbQueryDeviceReport( devices[devcount].fd,
&ulBufLen,
ucData);
DBG (1, "sanei_usb_open: UsbQueryDeviceReport rc = %d\n",rc);
pDevDesc = (struct usb_device_descriptor*)ucData;
pCfgDesc = (struct usb_config_descriptor*) (ucData+sizeof(struct usb_device_descriptor));
UCHAR *pCurPtr = (UCHAR*) pCfgDesc;
UCHAR *pEndPtr = pCurPtr+ pCfgDesc->wTotalLength;
pDescHead = (struct usb_descriptor_header *) (pCurPtr+pCfgDesc->bLength);
/* Set the configuration */
if (pDevDesc->bNumConfigurations > 1)
{
DBG (3, "sanei_usb_open: more than one "
"configuration (%d), choosing first config (%d)\n",
pDevDesc->bNumConfigurations,
pCfgDesc->bConfigurationValue);
}
DBG (5, "UsbDeviceSetConfiguration parameters: dh = %p, bConfigurationValue = %d\n",
dh,pCfgDesc->bConfigurationValue);
result = UsbDeviceSetConfiguration (dh,
pCfgDesc->bConfigurationValue);
DBG (1, "sanei_usb_open: UsbDeviceSetConfiguration rc = %d\n",result);
if (result)
{
SANE_Status status = SANE_STATUS_INVAL;
DBG (1, "sanei_usb_open: usbcalls complained on UsbDeviceSetConfiguration, rc= %d\n", result);
status = SANE_STATUS_ACCESS_DENIED;
UsbClose (dh);
return status;
}
/* Now we look for usable endpoints */
for (pDescHead = (struct usb_descriptor_header *) (pCurPtr+pCfgDesc->bLength);
pDescHead;pDescHead = GetNextDescriptor(pDescHead,pEndPtr) )
{
switch(pDescHead->bDescriptorType)
{
case USB_DT_INTERFACE:
interface = (struct usb_interface_descriptor *) pDescHead;
DBG (5, "Found %d endpoints\n",interface->bNumEndpoints);
break;
case USB_DT_ENDPOINT:
endpoint = (struct usb_endpoint_descriptor*)pDescHead;
address = endpoint->bEndpointAddress;
//address = endpoint->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
direction = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
transfer_type = endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
/* save the endpoints we need later */
if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT)
{
DBG (5, "sanei_usb_open: found interupt-%s endpoint (address %2x)\n",
direction ? "in" : "out", address);
if (direction) /* in */
{
if (devices[devcount].int_in_ep)
DBG (3, "sanei_usb_open: we already have a int-in endpoint "
"(address: %d), ignoring the new one\n",
devices[devcount].int_in_ep);
else
devices[devcount].int_in_ep = endpoint->bEndpointAddress;
}
else
if (devices[devcount].int_out_ep)
DBG (3, "sanei_usb_open: we already have a int-out endpoint "
"(address: %d), ignoring the new one\n",
devices[devcount].int_out_ep);
else
devices[devcount].int_out_ep = endpoint->bEndpointAddress;
}
else if (transfer_type == USB_ENDPOINT_TYPE_BULK)
{
DBG (5, "sanei_usb_open: found bulk-%s endpoint (address %2x)\n",
direction ? "in" : "out", address);
if (direction) /* in */
{
if (devices[devcount].bulk_in_ep)
DBG (3, "sanei_usb_open: we already have a bulk-in endpoint "
"(address: %d), ignoring the new one\n",
devices[devcount].bulk_in_ep);
else
devices[devcount].bulk_in_ep = endpoint->bEndpointAddress;
}
else
{
if (devices[devcount].bulk_out_ep)
DBG (3, "sanei_usb_open: we already have a bulk-out endpoint "
"(address: %d), ignoring the new one\n",
devices[devcount].bulk_out_ep);
else
devices[devcount].bulk_out_ep = endpoint->bEndpointAddress;
}
}
/* ignore currently unsupported endpoints */
else {
DBG (5, "sanei_usb_open: ignoring %s-%s endpoint "
"(address: %d)\n",
transfer_type == USB_ENDPOINT_TYPE_CONTROL ? "control" :
transfer_type == USB_ENDPOINT_TYPE_ISOCHRONOUS
? "isochronous" : "interrupt",
direction ? "in" : "out", address);
continue;
}
break;
}
}
#else
DBG (1, "sanei_usb_open: can't open device `%s': "
"usbcalls support missing\n", devname);
return SANE_STATUS_UNSUPPORTED;
#endif /* HAVE_USBCALLS */
}
else
{
DBG (1, "sanei_usb_open: access method %d not implemented\n",
@ -911,6 +1169,16 @@ sanei_usb_close (SANE_Int dn)
}
if (devices[dn].method == sanei_usb_method_scanner_driver)
close (devices[dn].fd);
else if (devices[dn].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
int rc;
rc=UsbClose (dh);
DBG (5,"rc of UsbClose = %d\n",rc);
#else
DBG (1, "sanei_usb_close: usbcalls support missing\n");
#endif
}
else
#ifdef HAVE_LIBUSB
{
@ -986,6 +1254,41 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_LIBUSB */
else if (devices[dn].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
int rc;
while (*size)
{
ULONG ulToRead = (*size>MAX_RW)?MAX_RW:*size;
ULONG ulNum = ulToRead;
DBG (5, "Entered usbcalls UsbBulkRead with dn = %d\n",dn);
DBG (5, "Entered usbcalls UsbBulkRead with dh = %p\n",dh);
DBG (5, "Entered usbcalls UsbBulkRead with bulk_in_ep = 0x%02x\n",devices[dn].bulk_in_ep);
DBG (5, "Entered usbcalls UsbBulkRead with interface_nr = %d\n",devices[dn].interface_nr);
DBG (5, "Entered usbcalls UsbBulkRead with usbcalls_timeout = %d\n",usbcalls_timeout);
if (devices[dn].bulk_in_ep){
rc = UsbBulkRead (dh, devices[dn].bulk_in_ep, devices[dn].interface_nr,
&ulToRead, (char *) buffer, usbcalls_timeout);
DBG (1, "sanei_usb_read_bulk: rc = %d\n",rc);}
else
{
DBG (1, "sanei_usb_read_bulk: can't read without a bulk-in endpoint\n");
return SANE_STATUS_INVAL;
}
if (rc || (ulNum!=ulToRead)) return SANE_STATUS_INVAL;
*size -=ulToRead;
buffer += ulToRead;
read_size += ulToRead;
}
#else /* not HAVE_USBCALLS */
{
DBG (1, "sanei_usb_read_bulk: usbcalls support missing\n");
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_USBCALLS */
}
else
{
DBG (1, "sanei_usb_read_bulk: access method %d not implemented\n",
@ -1062,6 +1365,42 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_LIBUSB */
else if (devices[dn].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
int rc;
DBG (5, "Entered usbcalls UsbBulkWrite with dn = %d\n",dn);
DBG (5, "Entered usbcalls UsbBulkWrite with dh = %p\n",dh);
DBG (5, "Entered usbcalls UsbBulkWrite with bulk_out_ep = 0x%02x\n",devices[dn].bulk_out_ep);
DBG (5, "Entered usbcalls UsbBulkWrite with interface_nr = %d\n",devices[dn].interface_nr);
DBG (5, "Entered usbcalls UsbBulkWrite with usbcalls_timeout = %d\n",usbcalls_timeout);
while (*size)
{
ULONG ulToWrite = (*size>MAX_RW)?MAX_RW:*size;
DBG (5, "size requested to write = %lu, ulToWrite = %lu\n",(unsigned long) *size,ulToWrite);
if (devices[dn].bulk_out_ep){
rc = UsbBulkWrite (dh, devices[dn].bulk_out_ep, devices[dn].interface_nr,
ulToWrite, (char*) buffer, usbcalls_timeout);
DBG (1, "sanei_usb_write_bulk: rc = %d\n",rc);}
else
{
DBG (1, "sanei_usb_write_bulk: can't read without a bulk-out endpoint\n");
return SANE_STATUS_INVAL;
}
if (rc) return SANE_STATUS_INVAL;
*size -=ulToWrite;
buffer += ulToWrite;
write_size += ulToWrite;
DBG (5, "size = %d, write_size = %d\n",*size, write_size);
}
#else /* not HAVE_USBCALLS */
{
DBG (1, "sanei_usb_write_bulk: usbcalls support missing\n");
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_USBCALLS */
}
else
{
DBG (1, "sanei_usb_write_bulk: access method %d not implemented\n",
@ -1172,6 +1511,30 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_LIBUSB */
else if (devices[dn].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
int result;
result = UsbCtrlMessage (dh, rtype, req,
value, index, len, (char *) data,
usbcalls_timeout);
DBG (5, "rc of usb_control_msg = %d\n",result);
if (result < 0)
{
DBG (1, "sanei_usb_control_msg: usbcalls complained: %d\n",result);
return SANE_STATUS_INVAL;
}
if ((rtype & 0x80) && debug_level > 10)
print_buffer (data, len);
return SANE_STATUS_GOOD;
#else /* not HAVE_USBCALLS */
{
DBG (1, "sanei_usb_control_msg: usbcalls support missing\n");
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_USBCALLS */
}
else
{
DBG (1, "sanei_usb_control_msg: access method %d not implemented\n",
@ -1226,6 +1589,35 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_LIBUSB */
else if (devices[dn].method == sanei_usb_method_usbcalls)
{
#ifdef HAVE_USBCALLS
int rc;
USHORT usNumBytes=*size;
DBG (5, "Entered usbcalls UsbBulkWrite with dn = %d\n",dn);
DBG (5, "Entered usbcalls UsbBulkWrite with dh = %p\n",dh);
DBG (5, "Entered usbcalls UsbBulkWrite with int_in_ep = 0x%02x\n",devices[dn].int_in_ep);
DBG (5, "Entered usbcalls UsbBulkWrite with interface_nr = %d\n",devices[dn].interface_nr);
DBG (5, "Entered usbcalls UsbBulkWrite with bytes to read = %u\n",usNumBytes);
if (devices[dn].int_in_ep){
rc = UsbIrqStart (dh,devices[dn].int_in_ep,devices[dn].interface_nr,
usNumBytes, (char *) buffer, (HEV *) UsbIrqStartHev);
DBG (5, "rc of UsbIrqStart = %d\n",rc);
}
else
{
DBG (1, "sanei_usb_read_int: can't read without an int "
"endpoint\n");
return SANE_STATUS_INVAL;
}
if (rc) return SANE_STATUS_INVAL;
read_size += usNumBytes;
#else
DBG (1, "sanei_usb_read_int: usbcalls support missing\n");
return SANE_STATUS_UNSUPPORTED;
#endif /* HAVE_USBCALLS */
}
else
{
DBG (1, "sanei_usb_read_int: access method %d not implemented\n",