[sane-devel] Improvement for USB scanners: IOCTL to query vendorID/productID in kernel

Karl Heinz Kremer khk@khk.net
Thu, 26 Jul 2001 22:32:46 -0400

Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Finally... It took me quite some time to get this patch into
the kernel. Starting with 2.4.8-pre1 the USB scanner driver
in the Linux kernel has two IOCTs to query the vendor ID and
the product ID for a given device file. This allows a backend
to first check if a device file belongs to a scanner that is
supported by the backend.=20

Currently we do have a problem with backends sending commands
to /dev/usb/scannerX without any knowledge about the scanner
that might be attached. In a lot of cases this will hang the
scanner or the USB bus, so it's a bad thing. With these new
IOCTLs we can finally test first and send commands only after
the backend has verified that the scanner can actually deal
with them.

To use the new feature you have to add the following code
to your backend:

#define IOCTL_SCANNER_VENDOR _IOR('u', 0xa0, int)
#define IOCTL_SCANNER_PRODUCT _IOR('u', 0xa1, int)

#define SANE_EPSON_VENDOR_ID (0x4b8)
#define PRODUCT_PERFECTION_636 (0x101)
#define PRODUCT_PERFECTION_610 (0x103)
#define PRODUCT_PERFECTION_640 (0x10c)
#define PRODUCT_PERFECTION_1200 (0x104)
#define PRODUCT_PERFECTION_1240 (0x10b)
#define PRODUCT_STYLUS_SCAN_2500 (0x106)
#define PRODUCT_PERFECTION_1640 (0x10a)
#define PRODUCT_EXPRESSION_1600 (0x107)
#define PRODUCT_EXPRESSION_1680 (0x10e)

                unsigned int vendorID, productID;
                SANE_Bool do_check;

		/* s->fd is the file descriptor for the device file */

                /* read the vendor and product IDs via the IOCTLs */
                if (ioctl(s->fd, IOCTL_SCANNER_VENDOR , &vendorID) =3D=3D -=
                        /* just set the vendor ID to 0 */
                        vendorID =3D 0;
                if (ioctl(s->fd, IOCTL_SCANNER_PRODUCT , &productID) =3D=3D=
                        /* just set the product ID to 0 */
                        productID =3D 0;
                do_check =3D (getenv("SANE_EPSON_NO_IOCTL") =3D=3D NULL);
                if (do_check && (vendorID !=3D 0) && (productID !=3D 0))
                        /* see if the device is actually an EPSON scanner */
                        if (vendorID !=3D SANE_EPSON_VENDOR_ID)
                                DBG(0, "The device at %s is not an EPSON sc=
anner (vendor id=3D0x%x)\n",
                                        dev_name, vendorID);
                                return SANE_STATUS_INVAL;
                        /* see if we support the scanner */
                        if (productID !=3D PRODUCT_PERFECTION_636 &&
                            productID !=3D PRODUCT_PERFECTION_610 &&
                            productID !=3D PRODUCT_PERFECTION_640 &&
                            productID !=3D PRODUCT_PERFECTION_1200 &&
                            productID !=3D PRODUCT_PERFECTION_1240 &&
                            productID !=3D PRODUCT_STYLUS_SCAN_2500 &&
                            productID !=3D PRODUCT_PERFECTION_1640 &&
                            productID !=3D PRODUCT_EXPRESSION_1600 &&
                            productID !=3D PRODUCT_EXPRESSION_1680)

                                DBG(0, "The device at %s is not a supported=
 EPSON scanner (product id=3D0x%x)\n",
                                        dev_name, productID);
                                return SANE_STATUS_INVAL;

=2E.. this of course only works if your backend accesses EPSON scanners :-)=
 - replace the actual
IDs with something that makes sense for your backend.=20

Karl Heinz

Karl Heinz Kremer                                  khk@khk.net
PGP Key at http://www.freecolormanagement.com/download/khk.asc
EPSON Sane Backend:         http://www.freecolormanagement.com

Content-Type: application/pgp-signature
Content-Disposition: inline

Version: PGP 6.5.8