/* check-usb-chip.c -- Find out what USB scanner chipset is used Copyright (C) 2003-2005 Henning Meier-Geinitz Copyright (C) 2003 Gerhard Jäger for LM983x tests Copyright (C) 2003 Gerard Klaver for ICM532B tests 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. */ #include "../include/sane/config.h" #include "../include/sane/sane.h" #include #include #include static int verbose = 0; static SANE_Bool no_chipset_access; #define TIMEOUT 1000 #ifdef HAVE_LIBUSB #include extern char *check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file); static int prepare_interface (struct usb_device *dev, usb_dev_handle ** handle) { int result; if (no_chipset_access) return 0; *handle = usb_open (dev); if (*handle == 0) { if (verbose > 1) printf (" Couldn't open device: %s\n", usb_strerror ()); return 0; } result = usb_set_configuration (*handle, dev->config[0].bConfigurationValue); if (result < 0) { if (verbose > 1) printf (" Couldn't set configuration: %s\n", usb_strerror ()); usb_close (*handle); return 0; } result = usb_claim_interface (*handle, 0); if (result < 0) { if (verbose > 1) printf (" Couldn't claim interface: %s\n", usb_strerror ()); usb_close (*handle); return 0; } return 1; } static void finish_interface (usb_dev_handle * handle) { usb_release_interface (handle, 0); usb_close (handle); } /* Check for Grandtech GT-6801 */ static char * check_gt6801 (struct usb_device *dev) { char req[64]; usb_dev_handle *handle; int result; if (verbose > 2) printf (" checking for GT-6801 ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { if (verbose > 2) printf (" this is not a GT-6801 (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a GT-6801 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a GT-6801 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a GT-6801 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 1) { if (verbose > 2) printf (" this is not a GT-6801 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a GT-6801 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } /* Now we send a control message */ result = prepare_interface (dev, &handle); if (!result) return "GT-6801?"; memset (req, 0, 64); req[0] = 0x2e; /* get identification information */ req[1] = 0x01; result = usb_control_msg (handle, 0x40, 0x01, 0x2010, 0x3f40, req, 64, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't send write control message (%s)\n", strerror (errno)); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0xc0, 0x01, 0x2011, 0x3f00, req, 64, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't send read control message (%s)\n", strerror (errno)); finish_interface (handle); return 0; } if (req[0] != 0 || (req[1] != 0x2e && req[1] != 0)) { if (verbose > 2) printf (" Unexpected result from control message (%0x/%0x)\n", req[0], req[1]); finish_interface (handle); return 0; } finish_interface (handle); return "GT-6801"; } /* Check for Grandtech GT-6816 */ static char * check_gt6816 (struct usb_device *dev) { char req[64]; usb_dev_handle *handle; int result; int i; if (verbose > 2) printf (" checking for GT-6816 ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != USB_CLASS_VENDOR_SPEC)) { if (verbose > 2) printf (" this is not a GT-6816 (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a GT-6816 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0x00) { if (verbose > 2) printf (" this is not a GT-6816 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0x00) { if (verbose > 2) printf (" this is not a GT-6816 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } if (dev->config[0].bNumInterfaces != 0x01) { if (verbose > 2) printf (" this is not a GT-6816 (bNumInterfaces = 0x%x)\n", dev->config[0].bNumInterfaces); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 2) { if (verbose > 2) printf (" this is not a GT-6816 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a GT-6816 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a GT-6816 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } /* Now we send a control message */ result = prepare_interface (dev, &handle); if (!result) return "GT-6816?"; memset (req, 0, 64); for (i = 0; i < 8; i++) { req[8 * i + 0] = 0x73; /* check firmware */ req[8 * i + 1] = 0x01; } result = usb_control_msg (handle, 0x40, 0x04, 0x2012, 0x3f40, req, 64, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't send write control message (%s)\n", strerror (errno)); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0xc0, 0x01, 0x2013, 0x3f00, req, 64, TIMEOUT); if (result <= 0) { /* Before firmware upload, 64 bytes are returned. Some libusb implementations/operating systems can't seem to cope with short packets. */ result = usb_control_msg (handle, 0xc0, 0x01, 0x2013, 0x3f00, req, 8, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't send read control message (%s)\n", strerror (errno)); finish_interface (handle); return 0; } } if (req[0] != 0) { if (verbose > 2) printf (" Unexpected result from control message (%0x/%0x)\n", req[0], req[1]); finish_interface (handle); return 0; } finish_interface (handle); return "GT-6816"; } /* Check for Grandtech GT-8911 */ static char * check_gt8911 (struct usb_device *dev) { char req[64]; usb_dev_handle *handle; int result; if (verbose > 2) printf (" checking for GT-8911 ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != USB_CLASS_VENDOR_SPEC)) { if (verbose > 2) printf (" this is not a GT-8911 (check 1, bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a GT-8911 (check 2, bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0x00) { if (verbose > 2) printf (" this is not a GT-8911 (check 3, bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0x00) { if (verbose > 2) printf (" this is not a GT-8911 (check 4, bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 2) { if (verbose > 2) printf (" this is not a GT-8911 (check 5, bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } /* Check first endpoint descriptor block */ if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a GT-8911 (check 6, bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a GT-8911 (check 7, bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if (dev->config[0].bNumInterfaces < 2) { if (verbose > 2) printf (" this is not a GT-8911 (check 8, bNumInterfaces = %d)\n", dev->config[0].bNumInterfaces); return 0; } if (dev->config[0].interface[1].num_altsetting < 3) { if (verbose > 2) printf (" this is not a GT-8911 (check 9, num_altsetting = %d)\n", dev->config[0].interface[1].num_altsetting); return 0; } /* Check fourth endpoint descriptor block */ if ((dev->config[0].interface[1].altsetting[2].endpoint[0]. bEndpointAddress != 0x83) || (dev->config[0].interface[1].altsetting[2].endpoint[0]. bmAttributes != 0x01) || (dev->config[0].interface[1].altsetting[2].endpoint[0]. wMaxPacketSize != 0x01d0) || (dev->config[0].interface[1].altsetting[2].endpoint[0].bInterval != 0x01)) { if (verbose > 2) printf (" this is not a GT-8911 (check 10, bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[1].altsetting[2].endpoint[0]. bEndpointAddress, dev->config[0].interface[1].altsetting[2].endpoint[0].bmAttributes, dev->config[0].interface[1].altsetting[2].endpoint[0]. wMaxPacketSize, dev->config[0].interface[1].altsetting[2].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[1].altsetting[2].endpoint[1]. bEndpointAddress != 0x04) || (dev->config[0].interface[1].altsetting[2].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[1].altsetting[2].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[1].altsetting[2].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a GT-8911 (check 11, bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[1].altsetting[2].endpoint[1]. bEndpointAddress, dev->config[0].interface[1].altsetting[2].endpoint[1].bmAttributes, dev->config[0].interface[1].altsetting[2].endpoint[1]. wMaxPacketSize, dev->config[0].interface[1].altsetting[2].endpoint[1].bInterval); return 0; } /* Now we send a control message */ result = prepare_interface (dev, &handle); if (!result) return "GT-8911?"; memset (req, 0, 8); req[0] = 0x55; req[1] = 0x66; result = usb_control_msg (handle, 0xc0, 0x10, 0x41, 0x0000, req, 64, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" this is not a GT-8911 (check 12, couldn't send read control message (%s))\n", strerror (errno)); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0xc0, 0x10, 0x05, 0x0000, req, 64, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" this is not a GT-8911 (check 13, couldn't send read control message (%s)\n", strerror (errno)); finish_interface (handle); return 0; } /* tested on model hardware version 0xffffffc0, firmware version 0x10)) */ if (verbose > 2) printf (" Check 14, control message (hardware version %0x / firmware version %0x)\n", req[0], req[1]); finish_interface (handle); return "GT-8911"; } /* Check for Mustek MA-1017 */ static char * check_ma1017 (struct usb_device *dev) { char req[2]; usb_dev_handle *handle; int result; char res; if (verbose > 2) printf (" checking for MA-1017 ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != USB_CLASS_PER_INTERFACE)) { if (verbose > 2) printf (" this is not a MA-1017 (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x100) { if (verbose > 2) printf (" this is not a MA-1017 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0x00) { if (verbose > 2) printf (" this is not a MA-1017 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0x00) { if (verbose > 2) printf (" this is not a MA-1017 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a MA-1017 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a MA-1017 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x82) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a MA-1017 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0x01)) { if (verbose > 2) printf (" this is not a MA-1017 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } /* read a register value */ result = prepare_interface (dev, &handle); if (!result) return "MA-1017?"; req[0] = 0x00; req[1] = 0x02 | 0x20; result = usb_bulk_write (handle, 0x01, req, 2, 1000); if (result <= 0) { if (verbose > 2) printf (" this is not a MA-1017 (Error during bulk write)\n"); finish_interface (handle); return 0; } result = usb_bulk_read (handle, 0x82, &res, 1, 1000); if (result <= 0) { if (verbose > 2) printf (" this is not a MA-1017 (Error during bulk read)\n"); finish_interface (handle); return 0; } /* Read one byte again to work around a bug in the MA-1017 chipset that appears when an odd number of bytes is read or written. */ result = usb_bulk_write (handle, 0x01, req, 2, 1000); result = usb_bulk_read (handle, 0x82, &res, 1, 1000); finish_interface (handle); return "MA-1017"; } /* Check for Mustek MA-1015 */ static char * check_ma1015 (struct usb_device *dev) { char req[8]; usb_dev_handle *handle; int result; unsigned char res; if (verbose > 2) printf (" checking for MA-1015 ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { if (verbose > 2) printf (" this is not a MA-1015 (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x100) { if (verbose > 2) printf (" this is not a MA-1015 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a MA-1015 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a MA-1015 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 2) { if (verbose > 2) printf (" this is not a MA-1015 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a MA-1015 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x08) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a MA-1015 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } /* Now we read register 0 to find out if this is really a MA-1015 */ result = prepare_interface (dev, &handle); if (!result) return 0; memset (req, 0, 8); req[0] = 33; req[1] = 0x00; result = usb_bulk_write (handle, 0x02, req, 8, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" this is not a MA-1015 (Error during bulk write)\n"); finish_interface (handle); return 0; } result = usb_bulk_read (handle, 0x81, (char *) &res, 1, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" this is not a MA-1015 (Error during bulk read)\n"); finish_interface (handle); return 0; } if (res != 0xa5) { if (verbose > 2) printf (" this is not a MA-1015 (got 0x%x, expected 0xa5)\n", res); finish_interface (handle); return 0; } finish_interface (handle); return "MA-1015"; } /* Check for Mustek MA-1509 */ static char * check_ma1509 (struct usb_device *dev) { char req[8]; char inquiry[0x60]; usb_dev_handle *handle; int result; if (verbose > 2) printf (" checking for MA-1509 ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { if (verbose > 2) printf (" this is not a MA-1509 (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a MA-1509 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a MA-1509 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a MA-1509 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a MA-1509 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40)) { if (verbose > 2) printf (" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x08)) { if (verbose > 2) printf (" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x08) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0x10)) { if (verbose > 2) printf (" this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } /* This is a SCSI-over-USB chip, we'll read the inquiry */ result = prepare_interface (dev, &handle); if (!result) return "MA-1509?"; memset (req, 0, 8); req[0] = 0x12; req[1] = 1; req[6] = 0x60; result = usb_bulk_write (handle, 0x02, req, 8, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" this is not a MA-1509 (Error during bulk write)\n"); finish_interface (handle); return 0; } memset (inquiry, 0, 0x60); result = usb_bulk_read (handle, 0x81, (char *) inquiry, 0x60, TIMEOUT); if (result != 0x60) { if (verbose > 2) printf (" this is not a MA-1509 (Error during bulk read: %d)\n", result); finish_interface (handle); return 0; } if ((inquiry[0] & 0x1f) != 0x06) { if (verbose > 2) printf (" this is not a MA-1509 (inquiry [0] = %d)\n", inquiry[0]); finish_interface (handle); return 0; } if (strncmp (inquiry + 8, "SCANNER ", 8) != 0) { inquiry[16] = 0; if (verbose > 2) printf (" this is not a MA-1509 (vendor=%s)\n", inquiry + 8); finish_interface (handle); return 0; } inquiry[36] = 0; if (verbose > 2) printf (" MA-1509 version %s\n", inquiry + 32); finish_interface (handle); return "MA-1509"; } /********** the lm983x section **********/ static int lm983x_wb (usb_dev_handle * handle, unsigned char reg, unsigned char val) { unsigned char buf[5]; int result; buf[0] = 0; buf[1] = reg; buf[2] = 0; buf[3] = 1; buf[4] = val; result = usb_bulk_write (handle, 3, (char *) buf, 5, TIMEOUT); if (result != 5) return 0; return 1; } static int lm983x_rb (usb_dev_handle * handle, unsigned char reg, unsigned char *val) { unsigned char buf[5]; int result; buf[0] = 1; buf[1] = reg; buf[2] = 0; buf[3] = 1; result = usb_bulk_write (handle, 3, (char *) buf, 4, TIMEOUT); if (result != 4) return 0; result = usb_bulk_read (handle, 2, (char *) val, 1, TIMEOUT); if (result != 1) return 0; return 1; } static char * check_merlin (struct usb_device *dev) { unsigned char val; int result; usb_dev_handle *handle; if (verbose > 2) printf (" checking for LM983[1,2,3] ...\n"); /* Check device descriptor */ if (((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) && (dev->descriptor.bDeviceClass != 0)) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != USB_CLASS_VENDOR_SPEC)) { if (verbose > 2) printf (" this is not a LM983x (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if ((dev->descriptor.bcdUSB != 0x110) && (dev->descriptor.bcdUSB != 0x101) && (dev->descriptor.bcdUSB != 0x100)) { if (verbose > 2) printf (" this is not a LM983x (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0x00) { if (verbose > 2) printf (" this is not a LM983x (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if ((dev->descriptor.bDeviceProtocol != 0) && (dev->descriptor.bDeviceProtocol != 0xff)) { if (verbose > 2) printf (" this is not a LM983x (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a LM983x (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x1) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x10)) { if (verbose > 2) printf (" this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x82) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) /* Currently disabled as we have some problems in detection here ! */ /*|| (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0) */ ) { if (verbose > 2) printf (" this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x40) /* Currently disabled as we have some problems in detection here ! */ /* || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0) */ ) { if (verbose > 2) printf (" this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } result = prepare_interface (dev, &handle); if (!result) return "LM983x?"; result = lm983x_wb (handle, 0x07, 0x00); if (1 == result) result = lm983x_wb (handle, 0x08, 0x02); if (1 == result) result = lm983x_rb (handle, 0x07, &val); if (1 == result) result = lm983x_rb (handle, 0x08, &val); if (1 == result) result = lm983x_rb (handle, 0x69, &val); if (0 == result) { if (verbose > 2) printf (" Couldn't access LM983x registers.\n"); finish_interface (handle); return 0; } finish_interface (handle); switch (val) { case 4: return "LM9832/3"; break; case 3: return "LM9831"; break; case 2: return "LM9830"; break; default: return "LM983x?"; break; } } /********** the gl646 section **********/ static int gl646_write_reg (usb_dev_handle * handle, unsigned char reg, unsigned char val) { int result; result = usb_control_msg (handle, 0x00, 0x00, 0x83, 0x00, (char *) ®, 0x01, TIMEOUT); if (result < 0) return 0; result = usb_control_msg (handle, 0x00, 0x00, 0x85, 0x00, (char *) &val, 0x01, TIMEOUT); if (result < 0) return 0; return 1; } static int gl646_read_reg (usb_dev_handle * handle, unsigned char reg, unsigned char *val) { int result; result = usb_control_msg (handle, 0x00, 0x00, 0x83, 0x00, (char *) ®, 0x01, TIMEOUT); if (result < 0) return 0; result = usb_control_msg (handle, 0x80, 0x00, 0x84, 0x00, (char *) val, 0x01, TIMEOUT); if (result < 0) return 0; return 1; } static char * check_gl646 (struct usb_device *dev) { unsigned char val; int result; usb_dev_handle *handle; if (verbose > 2) printf (" checking for GL646 ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 0x10)) { if (verbose > 2) printf (" this is not a GL646 (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a GL646 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0x00) { if (verbose > 2) printf (" this is not a GL646 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0) { if (verbose > 2) printf (" this is not a GL646 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a GL646 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x0)) { if (verbose > 2) printf (" this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0)) { if (verbose > 2) printf (" this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x1) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8)) { if (verbose > 2) printf (" this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } result = prepare_interface (dev, &handle); if (!result) return "GL646?"; result = gl646_write_reg (handle, 0x38, 0x15); if (!result) { if (verbose > 2) printf (" this is not a GL646 (writing register failed)\n"); finish_interface (handle); return 0; } result = gl646_read_reg (handle, 0x4e, &val); if (!result) { if (verbose > 2) printf (" this is not a GL646 (reading register failed)\n"); finish_interface (handle); return 0; } if (val != 0x15) { if (verbose > 2) printf (" this is not a GL646 (reg 0x4e != reg 0x38)\n"); finish_interface (handle); return 0; } finish_interface (handle); return "GL646"; } /* Same as check_gl646, except that sanity check are different. */ static char * check_gl646_hp (struct usb_device *dev) { unsigned char val; int result; usb_dev_handle *handle; if (verbose > 2) printf (" checking for GL646_HP ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != 0xff) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 0xff)) { if (verbose > 2) printf (" this is not a GL646_HP (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a GL646_HP (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a GL646_HP (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a GL646_HP (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a GL646_HP (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x0)) { if (verbose > 2) printf (" this is not a GL646_HP (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0)) { if (verbose > 2) printf (" this is not a GL646_HP (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x1) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8)) { if (verbose > 2) printf (" this is not a GL646_HP (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } result = prepare_interface (dev, &handle); if (!result) return "GL646_HP?"; result = gl646_write_reg (handle, 0x38, 0x15); if (!result) { if (verbose > 2) printf (" this is not a GL646_HP (writing register failed)\n"); finish_interface (handle); return 0; } result = gl646_read_reg (handle, 0x4e, &val); if (!result) { if (verbose > 2) printf (" this is not a GL646_HP (reading register failed)\n"); finish_interface (handle); return 0; } if (val != 0x15) { if (verbose > 2) printf (" this is not a GL646_HP (reg 0x4e != reg 0x38)\n"); finish_interface (handle); return 0; } finish_interface (handle); return "GL646_HP"; } /* check for the combination of gl660 and gl646 */ static char * check_gl660_gl646 (struct usb_device *dev) { unsigned char val; int result; usb_dev_handle *handle; if (verbose > 2) printf (" checking for GL660+GL646 ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != USB_CLASS_PER_INTERFACE)) { if (verbose > 2) printf (" this is not a GL660+GL646 (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x200) { if (verbose > 2) printf (" this is not a GL660+GL646 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a GL660+GL646 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a GL660+GL646 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a GL660+GL646 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || ((dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) && (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x0)) { if (verbose > 2) printf (" this is not a GL660+GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || ((dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) && (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0)) { if (verbose > 2) printf (" this is not a GL660+GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || ((dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x1) && (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8)) { if (verbose > 2) printf (" this is not a GL660+GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } result = prepare_interface (dev, &handle); if (!result) return "GL660+GL646?"; result = gl646_write_reg (handle, 0x38, 0x15); if (!result) { if (verbose > 2) printf (" this is not a GL660+GL646 (writing register failed)\n"); finish_interface (handle); return 0; } result = gl646_read_reg (handle, 0x4e, &val); if (!result) { if (verbose > 2) printf (" this is not a GL660+GL646 (reading register failed)\n"); finish_interface (handle); return 0; } if (val != 0x15) { if (verbose > 2) printf (" this is not a GL660+GL646 (reg 0x4e != reg 0x38)\n"); finish_interface (handle); return 0; } finish_interface (handle); return "GL660+GL646"; } /********** the gl841 section **********/ static char * check_gl841 (struct usb_device *dev) { unsigned char val; int result; usb_dev_handle *handle; if (verbose > 2) printf (" checking for GL841 ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != USB_CLASS_VENDOR_SPEC)) { if (verbose > 2) printf (" this is not a GL841 (bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x200) { if (verbose > 2) printf (" this is not a GL841 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a GL841 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a GL841 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a GL841 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || ((dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) && (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x0)) { if (verbose > 2) printf (" this is not a GL841 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || ((dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) && (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0)) { if (verbose > 2) printf (" this is not a GL841 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x1) || ((dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8) && (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 16))) { if (verbose > 2) printf (" this is not a GL841 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } result = prepare_interface (dev, &handle); if (!result) return "GL841?"; result = gl646_write_reg (handle, 0x38, 0x15); if (!result) { if (verbose > 2) printf (" this is not a GL841 (writing register failed)\n"); finish_interface (handle); return 0; } result = gl646_read_reg (handle, 0x38, &val); if (!result) { if (verbose > 2) printf (" this is not a GL841 (reading register failed)\n"); finish_interface (handle); return 0; } if (val != 0x15) { if (verbose > 2) printf (" this is not a GL841 (reg 0x38 != 0x15)\n"); finish_interface (handle); return 0; } finish_interface (handle); return "GL841"; } /********** the icm532b section version 0.2 **********/ /* no write and read test registers yet */ static char * check_icm532b (struct usb_device *dev) { int result; usb_dev_handle *handle; if (verbose > 2) printf (" checking for ICM532B ...\n"); /* Check device descriptor */ if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 0xff)) { if (verbose > 2) printf (" this is not a ICM532B (check 1, bDeviceClass = %d, bInterfaceClass = %d)\n", dev->descriptor.bDeviceClass, dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a ICM532B (check 2, bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0xff) { if (verbose > 2) printf (" this is not a ICM532B (check 3, bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0xff) { if (verbose > 2) printf (" this is not a ICM532B (check 4, bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 0x01) { if (verbose > 2) printf (" this is not a ICM532B (check 5, bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } /* Check bEndpointAddress */ if (dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) { if (verbose > 2) printf (" this is not a ICM532B (check 6, bEndpointAddress = %d)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress); return 0; } /* Check bmAttributes */ if (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x01) { if (verbose > 2) printf (" this is not a ICM532B (check 7, bEndpointAddress = %d)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes); return 0; } if ((dev->config[0].interface[0].altsetting[0].bAlternateSetting != 0x00) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x00)) { if (verbose > 2) printf (" this is not a ICM532B (check 8, bAlternateSetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[0].bAlternateSetting, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[1].bAlternateSetting != 0x01) || (dev->config[0].interface[0].altsetting[1].endpoint[0]. wMaxPacketSize != 0x100)) { if (verbose > 2) printf (" this is not a ICM532B (check 9, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[1].bAlternateSetting, dev->config[0].interface[0].altsetting[1].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[2].bAlternateSetting != 0x02) || (dev->config[0].interface[0].altsetting[2].endpoint[0]. wMaxPacketSize != 0x180)) { if (verbose > 2) printf (" this is not a ICM532B (check 10, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[2].bAlternateSetting, dev->config[0].interface[0].altsetting[2].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[3].bAlternateSetting != 0x03) || (dev->config[0].interface[0].altsetting[3].endpoint[0]. wMaxPacketSize != 0x200)) { if (verbose > 2) printf (" this is not a ICM532B (check 11, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[3].bAlternateSetting, dev->config[0].interface[0].altsetting[3].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[4].bAlternateSetting != 0x04) || (dev->config[0].interface[0].altsetting[4].endpoint[0]. wMaxPacketSize != 0x280)) { if (verbose > 2) printf (" this is not a ICM532B (check 12, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[4].bAlternateSetting, dev->config[0].interface[0].altsetting[4].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[5].bAlternateSetting != 0x05) || (dev->config[0].interface[0].altsetting[5].endpoint[0]. wMaxPacketSize != 0x300)) { if (verbose > 2) printf (" this is not a ICM532B (check 13, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[5].bAlternateSetting, dev->config[0].interface[0].altsetting[5].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[6].bAlternateSetting != 0x06) || (dev->config[0].interface[0].altsetting[6].endpoint[0]. wMaxPacketSize != 0x380)) { if (verbose > 2) printf (" this is not a ICM532B (check 14, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[6].bAlternateSetting, dev->config[0].interface[0].altsetting[6].endpoint[0]. wMaxPacketSize); return 0; } if ((dev->config[0].interface[0].altsetting[7].bAlternateSetting != 0x07) || (dev->config[0].interface[0].altsetting[7].endpoint[0]. wMaxPacketSize != 0x3ff)) { if (verbose > 2) printf (" this is not a ICM532B (check 15, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n", dev->config[0].interface[0].altsetting[7].bAlternateSetting, dev->config[0].interface[0].altsetting[7].endpoint[0]. wMaxPacketSize); return 0; } result = prepare_interface (dev, &handle); if (!result) return "ICM532B?"; finish_interface (handle); return "ICM532B"; } /* ====================================== end of icm532b ==================*/ /* Check for the combination of a PowerVision PV8630 (USB->parport bridge) and National Semiconductor LM9830 */ static char * check_pv8630_lm9830 (struct usb_device *dev) { usb_dev_handle *handle; int result; char data; if (verbose > 2) printf (" checking for PV8630/LM9830 ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x100) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0x00) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0x00) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } /* Endpoint 0 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } /* Endpoint 1 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x82) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } /* Endpoint 2 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0x01)) { if (verbose > 2) printf (" this is not a PV8630/LM9830 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } /* Now we write/read a register (red offset) */ result = prepare_interface (dev, &handle); if (!result) return "PV8630/LM9830?"; result = usb_control_msg (handle, 0x40, 0x01, 0x38, 0x01, NULL, 0, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't send write register number (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0x40, 0x01, 0x0f, 0x00, NULL, 0, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't send register data (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0x40, 0x01, 0x38, 0x01, NULL, 0, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't send read register number (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0xc0, 0x00, 0, 0x00, &data, 1, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't read register data (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } if (data != 0x0f) { if (verbose > 2) printf (" Data read != data written (%d/%d)\n", data, 0x0f); finish_interface (handle); return 0; } finish_interface (handle); return "PV8630/LM9830"; } /* Check for Toshiba M011 */ static char * check_m011 (struct usb_device *dev) { usb_dev_handle *handle; int result; char data; if (verbose > 2) printf (" checking for M011 ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { if (verbose > 2) printf (" this is not a M011 (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x100) { if (verbose > 2) printf (" this is not a M011 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != USB_CLASS_VENDOR_SPEC) { if (verbose > 2) printf (" this is not a M011 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != USB_CLASS_VENDOR_SPEC) { if (verbose > 2) printf (" this is not a M011 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 1) { if (verbose > 2) printf (" this is not a M011 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } /* Endpoint 0 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x82) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a M011 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } /* Now we write/read a register (red offset) */ result = prepare_interface (dev, &handle); if (!result) return "M011?"; data = 0x63; result = usb_control_msg (handle, 0x40, 0x08, 0x34, 0x00, &data, 1, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't write register (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } data = 0; result = usb_control_msg (handle, 0xc0, 0x00, 0x34, 0x00, &data, 1, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't read register (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } if (data != 0x63) { if (verbose > 2) printf (" Data read != data written (%d/%d)\n", data, 0x63); finish_interface (handle); return 0; } finish_interface (handle); return "M011"; } /* Check for Realtek rts8858c */ static int rts88xx_read_reg (usb_dev_handle * handle, unsigned char *req, unsigned char *res, int size) { int result; result = usb_bulk_write (handle, 0x02, (char *)req, 0x04, TIMEOUT); if (result < 0) return 0; result = usb_bulk_read (handle, 0x81, (char *)res, size, TIMEOUT); if (result < 0) return 0; return 1; } static char * check_rts8858c (struct usb_device *dev) { unsigned char req[4]; unsigned char res[10]; usb_dev_handle *handle; int result; if (verbose > 2) printf (" checking for rts8858c ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != 0) { if (verbose > 2) printf (" this is not a rts8858c (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x110) { if (verbose > 2) printf (" this is not a rts8858c (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0) { if (verbose > 2) printf (" this is not a rts8858c (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0) { if (verbose > 2) printf (" this is not a rts8858c (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a rts8858c (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a rts8858c (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x08) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a rts8858c (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0xFA)) { if (verbose > 2) printf (" this is not a rts8858c (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } /* Now we read 10 registers */ result = prepare_interface (dev, &handle); if (!result) return "rts8858c?"; memset (req, 0, 4); req[0] = 0x80; /* get registers 0x12-0x1c */ req[1] = 0x12; req[2] = 0x00; req[3] = 0x0a; result = rts88xx_read_reg(handle,req,res,req[3]); if (result <= 0) { if (verbose > 2) printf (" Couldn't read registers\n"); finish_interface (handle); return 0; } if (res[1] != 0x03 || res[2] != 0x00) { if (verbose > 2) printf (" Unexpected result from register reading (0x%0x/0x%0x)\n", res[1], res[2]); finish_interface (handle); return 0; } finish_interface (handle); return "rts8858c"; } /* end of rts8858 detection */ /* Check for Service & Quality SQ113 */ static char * check_sq113 (struct usb_device *dev) { usb_dev_handle *handle; int result; unsigned char data; unsigned char buffer[4]; if (verbose > 2) printf (" checking for SQ113 ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != 0) { if (verbose > 2) printf (" this is not a SQ113 (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x200) { if (verbose > 2) printf (" this is not a SQ113 (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0) { if (verbose > 2) printf (" this is not a SQ113 (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0) { if (verbose > 2) printf (" this is not a SQ113 (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check interface */ if (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 255) { if (verbose > 2) printf (" this is not a SQ113 (bInterfaceClass = %d)\n", dev->config[0].interface[0].altsetting[0].bInterfaceClass); return 0; } if (dev->config[0].interface[0].altsetting[0].bInterfaceSubClass != 255) { if (verbose > 2) printf (" this is not a SQ113 (bInterfaceSubClass = %d)\n", dev->config[0].interface[0].altsetting[0].bInterfaceSubClass); return 0; } if (dev->config[0].interface[0].altsetting[0].bInterfaceProtocol != 255) { if (verbose > 2) printf (" this is not a SQ113 (bInterfaceProtocol = %d)\n", dev->config[0].interface[0].altsetting[0].bInterfaceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a SQ113 (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } /* Endpoint 0 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || ((dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x40) && (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a SQ113 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } /* Endpoint 1 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x82) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || ((dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x40) && (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x200)) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a SQ113 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } /* Endpoint 2 */ if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x1) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0x03)) { if (verbose > 2) printf (" this is not a SQ113 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } /* Now we read the status register */ result = prepare_interface (dev, &handle); if (!result) return "SQ113?"; buffer [0] = 0x5f; buffer [1] = 0x00; buffer [2] = 0x5f; buffer [3] = 0x00; result = usb_control_msg (handle, 0x40, 0x01, 0xb0, 0, (char *) buffer, 4, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't set bank (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } data = 0x00; buffer [0] = 0x8b; buffer [1] = data; buffer [2] = 0x8b; buffer [3] = data; result = usb_control_msg (handle, 0x40, 0x01, 0xb0, 0, (char *) buffer, 4, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't write register (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } buffer [0] = 0x8b; buffer [1] = 0x8b; buffer [2] = 0x8b; buffer [3] = 0x8b; result = usb_control_msg (handle, 0x40, 0x01, 0x04, 0x8b, (char *) buffer, 4, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't set read register address (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } result = usb_control_msg (handle, 0xc0, 0x01, 0x07, 0, (char *) buffer, 4, TIMEOUT); if (result < 0) { if (verbose > 2) printf (" Couldn't read register (%s)\n", usb_strerror ()); finish_interface (handle); return 0; } if ((buffer[0] & 0x10) != 0x10) { if (verbose > 2) printf (" Sensor not home? (0x%02x)\n", buffer[0]); finish_interface (handle); return 0; } finish_interface (handle); return "SQ113"; } /* Check for Realtek RTS8822L-01H chipset*/ static char * check_rts8822l01h (struct usb_device *dev) { char data[2]; usb_dev_handle *handle; int result; if (verbose > 2) printf (" checking for RTS8822L-01H ...\n"); /* Check device descriptor */ if (dev->descriptor.bDeviceClass != 0) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bDeviceClass = %d)\n", dev->descriptor.bDeviceClass); return 0; } if (dev->descriptor.bcdUSB != 0x200) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bcdUSB = 0x%x)\n", dev->descriptor.bcdUSB); return 0; } if (dev->descriptor.bDeviceSubClass != 0) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bDeviceSubClass = 0x%x)\n", dev->descriptor.bDeviceSubClass); return 0; } if (dev->descriptor.bDeviceProtocol != 0) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bDeviceProtocol = 0x%x)\n", dev->descriptor.bDeviceProtocol); return 0; } /* Check endpoints */ if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bNumEndpoints = %d)\n", dev->config[0].interface[0].altsetting[0].bNumEndpoints); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress != 0x81) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize != 0x200) || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[0]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[0]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. bmAttributes != 0x02) || (dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize != 0x200) || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0x00)) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[1]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[1]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); return 0; } if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress != 0x83) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. bmAttributes != 0x03) || (dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize != 0x01) || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0x0c)) { if (verbose > 2) printf (" this is not a RTS8822L-01H (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", dev->config[0].interface[0].altsetting[0].endpoint[2]. bEndpointAddress, dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, dev->config[0].interface[0].altsetting[0].endpoint[2]. wMaxPacketSize, dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); return 0; } /* Now we read 1 register */ result = prepare_interface (dev, &handle); if (!result) return "rts8822L-01H?"; memset (data, 0, 2); result = usb_control_msg(handle, 0xc0, 0x04, 0xfe11, 0x100, data, 0x02, TIMEOUT); if (result <= 0) { if (verbose > 2) printf (" Couldn't send read control message (%s)\n", strerror (errno)); finish_interface (handle); return 0; } if ((data[0] & 0x01) != 0x01) { if (verbose > 2) printf (" Unexpected result from register 0xfe11 : 0x%0x%0x\n", data[1], data[0]); finish_interface (handle); return 0; } finish_interface (handle); return "RTS8822L-01H"; } /* end of RTS8822L-01H detection */ char * check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file) { char *chip_name = 0; verbose = verbosity; no_chipset_access = from_file; if (verbose > 2) printf ("\n\n"); chip_name = check_gt6801 (dev); if (!chip_name) chip_name = check_gt6816 (dev); if (!chip_name) chip_name = check_gt8911 (dev); if (!chip_name) chip_name = check_ma1017 (dev); if (!chip_name) chip_name = check_ma1015 (dev); if (!chip_name) chip_name = check_ma1509 (dev); if (!chip_name) chip_name = check_merlin (dev); if (!chip_name) chip_name = check_gl646 (dev); if (!chip_name) chip_name = check_gl646_hp (dev); if (!chip_name) chip_name = check_gl660_gl646 (dev); if (!chip_name) chip_name = check_gl841 (dev); if (!chip_name) chip_name = check_icm532b (dev); if (!chip_name) chip_name = check_pv8630_lm9830 (dev); if (!chip_name) chip_name = check_m011 (dev); if (!chip_name) chip_name = check_rts8822l01h (dev); if (!chip_name) chip_name = check_rts8858c (dev); if (!chip_name) chip_name = check_sq113 (dev); if (verbose > 2) { if (chip_name) printf ("\n\n", chip_name, PACKAGE_STRING); else printf ("\n\n", PACKAGE_STRING); } return chip_name; } #endif /* HAVE_LIBUSB */