• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    check-usb-chip.c -- Find out what USB scanner chipset is used
3 
4    Copyright (C) 2003-2005 Henning Meier-Geinitz <henning@meier-geinitz.de>
5    Copyright (C) 2003 Gerhard Jaeger <gerhard@gjaeger.de>
6                       for LM983x tests
7    Copyright (C) 2003 Gerard Klaver <gerard at gkall dot hobby dot nl>
8                       for ICM532B tests
9 
10    This file is part of the SANE package.
11 
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of the
15    License, or (at your option) any later version.
16 
17    This program is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <https://www.gnu.org/licenses/>.
24 */
25 
26 
27 #include "../include/sane/config.h"
28 
29 #ifdef HAVE_LIBUSB_LEGACY
30 
31 #include "../include/sane/sane.h"
32 #include <stdio.h>
33 #include <string.h>
34 #include <errno.h>
35 
36 #ifdef HAVE_LUSB0_USB_H
37 #include <lusb0_usb.h>
38 #else
39 #include <usb.h>
40 #endif
41 
42 #include "../include/_stdint.h"
43 
44 static int verbose = 0;
45 static SANE_Bool no_chipset_access;
46 #define TIMEOUT 1000
47 
48 extern char *check_usb_chip (struct usb_device *dev, int verbosity,
49 			     SANE_Bool from_file);
50 
51 static int
prepare_interface(struct usb_device * dev,usb_dev_handle ** handle)52 prepare_interface (struct usb_device *dev, usb_dev_handle ** handle)
53 {
54   int result;
55 
56   if (no_chipset_access)
57     return 0;
58 
59   *handle = usb_open (dev);
60   if (*handle == 0)
61     {
62       if (verbose > 1)
63 	printf ("    Couldn't open device: %s\n", usb_strerror ());
64       return 0;
65     }
66 
67   result =
68     usb_set_configuration (*handle, dev->config[0].bConfigurationValue);
69   if (result < 0)
70     {
71       if (verbose > 1)
72 	printf ("  Couldn't set configuration: %s\n", usb_strerror ());
73       usb_close (*handle);
74       return 0;
75     }
76 
77   result = usb_claim_interface (*handle, 0);
78   if (result < 0)
79     {
80       if (verbose > 1)
81 	printf ("    Couldn't claim interface: %s\n", usb_strerror ());
82       usb_close (*handle);
83       return 0;
84     }
85   return 1;
86 }
87 
88 static void
finish_interface(usb_dev_handle * handle)89 finish_interface (usb_dev_handle * handle)
90 {
91   usb_release_interface (handle, 0);
92   usb_close (handle);
93 }
94 
95 /* Check for Grandtech GT-6801 */
96 static char *
check_gt6801(struct usb_device * dev)97 check_gt6801 (struct usb_device *dev)
98 {
99   char req[64];
100   usb_dev_handle *handle;
101   int result;
102 
103   if (verbose > 2)
104     printf ("    checking for GT-6801 ...\n");
105 
106   /* Check device descriptor */
107   if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
108     {
109       if (verbose > 2)
110 	printf ("    this is not a GT-6801 (bDeviceClass = %d)\n",
111 		dev->descriptor.bDeviceClass);
112       return 0;
113     }
114   if (dev->descriptor.bcdUSB != 0x110)
115     {
116       if (verbose > 2)
117 	printf ("    this is not a GT-6801 (bcdUSB = 0x%x)\n",
118 		dev->descriptor.bcdUSB);
119       return 0;
120     }
121   if (dev->descriptor.bDeviceSubClass != 0xff)
122     {
123       if (verbose > 2)
124 	printf ("    this is not a GT-6801 (bDeviceSubClass = 0x%x)\n",
125 		dev->descriptor.bDeviceSubClass);
126       return 0;
127     }
128   if (dev->descriptor.bDeviceProtocol != 0xff)
129     {
130       if (verbose > 2)
131 	printf ("    this is not a GT-6801 (bDeviceProtocol = 0x%x)\n",
132 		dev->descriptor.bDeviceProtocol);
133       return 0;
134     }
135 
136   /* Check endpoints */
137   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 1)
138     {
139       if (verbose > 2)
140 	printf ("    this is not a GT-6801 (bNumEndpoints = %d)\n",
141 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
142       return 0;
143     }
144   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
145        bEndpointAddress != 0x81)
146       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
147 	  bmAttributes != 0x02)
148       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
149 	  wMaxPacketSize != 0x40)
150       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
151 	  0x00))
152     {
153       if (verbose > 2)
154 	printf
155 	  ("    this is not a GT-6801 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
156 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
157 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
158 	   bEndpointAddress,
159 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
160 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
161 	   wMaxPacketSize,
162 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
163       return 0;
164     }
165 
166   /* Now we send a control message */
167   result = prepare_interface (dev, &handle);
168   if (!result)
169     return "GT-6801?";
170 
171   memset (req, 0, 64);
172   req[0] = 0x2e;		/* get identification information */
173   req[1] = 0x01;
174 
175   result =
176     usb_control_msg (handle, 0x40, 0x01, 0x2010, 0x3f40, req, 64, TIMEOUT);
177   if (result <= 0)
178     {
179       if (verbose > 2)
180 	printf ("    Couldn't send write control message (%s)\n",
181 		strerror (errno));
182       finish_interface (handle);
183       return 0;
184     }
185   result =
186     usb_control_msg (handle, 0xc0, 0x01, 0x2011, 0x3f00, req, 64, TIMEOUT);
187   if (result <= 0)
188     {
189       if (verbose > 2)
190 	printf ("    Couldn't send read control message (%s)\n",
191 		strerror (errno));
192       finish_interface (handle);
193       return 0;
194     }
195   if (req[0] != 0 || (req[1] != 0x2e && req[1] != 0))
196     {
197       if (verbose > 2)
198 	printf ("    Unexpected result from control message (%0x/%0x)\n",
199 		req[0], req[1]);
200       finish_interface (handle);
201       return 0;
202     }
203   finish_interface (handle);
204   return "GT-6801";
205 }
206 
207 /* Check for Grandtech GT-6816 */
208 static char *
check_gt6816(struct usb_device * dev)209 check_gt6816 (struct usb_device *dev)
210 {
211   char req[64];
212   usb_dev_handle *handle;
213   int result;
214   int i;
215 
216   if (verbose > 2)
217     printf ("    checking for GT-6816 ...\n");
218 
219   /* Check device descriptor */
220   if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE)
221       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass !=
222 	  USB_CLASS_VENDOR_SPEC))
223     {
224       if (verbose > 2)
225 	printf
226 	  ("    this is not a GT-6816 (bDeviceClass = %d, bInterfaceClass = %d)\n",
227 	   dev->descriptor.bDeviceClass,
228 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
229       return 0;
230     }
231   if (dev->descriptor.bcdUSB != 0x110)
232     {
233       if (verbose > 2)
234 	printf ("    this is not a GT-6816 (bcdUSB = 0x%x)\n",
235 		dev->descriptor.bcdUSB);
236       return 0;
237     }
238   if (dev->descriptor.bDeviceSubClass != 0x00)
239     {
240       if (verbose > 2)
241 	printf ("    this is not a GT-6816 (bDeviceSubClass = 0x%x)\n",
242 		dev->descriptor.bDeviceSubClass);
243       return 0;
244     }
245   if (dev->descriptor.bDeviceProtocol != 0x00)
246     {
247       if (verbose > 2)
248 	printf ("    this is not a GT-6816 (bDeviceProtocol = 0x%x)\n",
249 		dev->descriptor.bDeviceProtocol);
250       return 0;
251     }
252 
253   if (dev->config[0].bNumInterfaces != 0x01)
254     {
255       if (verbose > 2)
256 	printf ("    this is not a GT-6816 (bNumInterfaces = 0x%x)\n",
257 		dev->config[0].bNumInterfaces);
258       return 0;
259     }
260 
261   /* Check endpoints */
262   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 2)
263     {
264       if (verbose > 2)
265 	printf ("    this is not a GT-6816 (bNumEndpoints = %d)\n",
266 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
267       return 0;
268     }
269   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
270        bEndpointAddress != 0x81)
271       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
272 	  bmAttributes != 0x02)
273       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
274 	  wMaxPacketSize != 0x40)
275       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
276 	  0x00))
277     {
278       if (verbose > 2)
279 	printf
280 	  ("    this is not a GT-6816 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
281 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
282 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
283 	   bEndpointAddress,
284 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
285 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
286 	   wMaxPacketSize,
287 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
288       return 0;
289     }
290   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
291        bEndpointAddress != 0x02)
292       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
293 	  bmAttributes != 0x02)
294       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
295 	  wMaxPacketSize != 0x40)
296       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
297 	  0x00))
298     {
299       if (verbose > 2)
300 	printf
301 	  ("    this is not a GT-6816 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
302 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
303 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
304 	   bEndpointAddress,
305 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
306 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
307 	   wMaxPacketSize,
308 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
309       return 0;
310 
311     }
312 
313   /* Now we send a control message */
314   result = prepare_interface (dev, &handle);
315   if (!result)
316     return "GT-6816?";
317 
318   memset (req, 0, 64);
319   for (i = 0; i < 8; i++)
320     {
321       req[8 * i + 0] = 0x73;	/* check firmware */
322       req[8 * i + 1] = 0x01;
323     }
324 
325   result =
326     usb_control_msg (handle, 0x40, 0x04, 0x2012, 0x3f40, req, 64, TIMEOUT);
327   if (result <= 0)
328     {
329       if (verbose > 2)
330 	printf ("    Couldn't send write control message (%s)\n",
331 		strerror (errno));
332       finish_interface (handle);
333       return 0;
334     }
335   result =
336     usb_control_msg (handle, 0xc0, 0x01, 0x2013, 0x3f00, req, 64, TIMEOUT);
337   if (result <= 0)
338     {
339       /* Before firmware upload, 64 bytes are returned. Some libusb
340 	 implementations/operating systems can't seem to cope with short
341 	 packets. */
342       result =
343 	usb_control_msg (handle, 0xc0, 0x01, 0x2013, 0x3f00, req, 8, TIMEOUT);
344       if (result <= 0)
345 	{
346 	  if (verbose > 2)
347 	    printf ("    Couldn't send read control message (%s)\n",
348 		    strerror (errno));
349 	  finish_interface (handle);
350 	  return 0;
351 	}
352     }
353 
354   if (req[0] != 0)
355     {
356       if (verbose > 2)
357 	printf ("    Unexpected result from control message (%0x/%0x)\n",
358 		req[0], req[1]);
359       finish_interface (handle);
360       return 0;
361     }
362   finish_interface (handle);
363   return "GT-6816";
364 }
365 
366 /* Check for Grandtech GT-8911 */
367 static char *
check_gt8911(struct usb_device * dev)368 check_gt8911 (struct usb_device *dev)
369 {
370   char req[64];
371   usb_dev_handle *handle;
372   int result;
373 
374   if (verbose > 2)
375     printf ("    checking for GT-8911 ...\n");
376 
377   /* Check device descriptor */
378   if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE)
379       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass !=
380 	  USB_CLASS_VENDOR_SPEC))
381     {
382       if (verbose > 2)
383 	printf
384 	  ("    this is not a GT-8911 (check 1, bDeviceClass = %d, bInterfaceClass = %d)\n",
385 	   dev->descriptor.bDeviceClass,
386 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
387       return 0;
388     }
389   if (dev->descriptor.bcdUSB != 0x110)
390     {
391       if (verbose > 2)
392 	printf ("    this is not a GT-8911 (check 2, bcdUSB = 0x%x)\n",
393 		dev->descriptor.bcdUSB);
394       return 0;
395     }
396   if (dev->descriptor.bDeviceSubClass != 0x00)
397     {
398       if (verbose > 2)
399 	printf
400 	  ("    this is not a GT-8911 (check 3, bDeviceSubClass = 0x%x)\n",
401 	   dev->descriptor.bDeviceSubClass);
402       return 0;
403     }
404   if (dev->descriptor.bDeviceProtocol != 0x00)
405     {
406       if (verbose > 2)
407 	printf
408 	  ("    this is not a GT-8911 (check 4, bDeviceProtocol = 0x%x)\n",
409 	   dev->descriptor.bDeviceProtocol);
410       return 0;
411     }
412 
413   /* Check endpoints */
414   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 2)
415     {
416       if (verbose > 2)
417 	printf ("    this is not a GT-8911 (check 5, bNumEndpoints = %d)\n",
418 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
419       return 0;
420     }
421   /* Check first endpoint descriptor block */
422   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
423        bEndpointAddress != 0x81)
424       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
425 	  bmAttributes != 0x02)
426       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
427 	  wMaxPacketSize != 0x40)
428       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
429 	  0x00))
430     {
431       if (verbose > 2)
432 	printf
433 	  ("    this is not a GT-8911 (check 6, bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
434 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
435 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
436 	   bEndpointAddress,
437 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
438 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
439 	   wMaxPacketSize,
440 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
441       return 0;
442     }
443   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
444        bEndpointAddress != 0x02)
445       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
446 	  bmAttributes != 0x02)
447       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
448 	  wMaxPacketSize != 0x40)
449       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
450 	  0x00))
451     {
452       if (verbose > 2)
453 	printf
454 	  ("    this is not a GT-8911 (check 7, bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
455 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
456 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
457 	   bEndpointAddress,
458 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
459 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
460 	   wMaxPacketSize,
461 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
462       return 0;
463 
464     }
465   if (dev->config[0].bNumInterfaces < 2)
466     {
467       if (verbose > 2)
468 	printf ("    this is not a GT-8911 (check 8, bNumInterfaces = %d)\n",
469 		dev->config[0].bNumInterfaces);
470       return 0;
471     }
472   if (dev->config[0].interface[1].num_altsetting < 3)
473     {
474       if (verbose > 2)
475 	printf ("    this is not a GT-8911 (check 9, num_altsetting = %d)\n",
476 		dev->config[0].interface[1].num_altsetting);
477       return 0;
478     }
479 
480   /* Check fourth endpoint descriptor block */
481   if ((dev->config[0].interface[1].altsetting[2].endpoint[0].
482        bEndpointAddress != 0x83)
483       || (dev->config[0].interface[1].altsetting[2].endpoint[0].
484 	  bmAttributes != 0x01)
485       || (dev->config[0].interface[1].altsetting[2].endpoint[0].
486 	  wMaxPacketSize != 0x01d0)
487       || (dev->config[0].interface[1].altsetting[2].endpoint[0].bInterval !=
488 	  0x01))
489     {
490       if (verbose > 2)
491 	printf
492 	  ("    this is not a GT-8911 (check 10, bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
493 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
494 	   dev->config[0].interface[1].altsetting[2].endpoint[0].
495 	   bEndpointAddress,
496 	   dev->config[0].interface[1].altsetting[2].endpoint[0].bmAttributes,
497 	   dev->config[0].interface[1].altsetting[2].endpoint[0].
498 	   wMaxPacketSize,
499 	   dev->config[0].interface[1].altsetting[2].endpoint[0].bInterval);
500       return 0;
501     }
502   if ((dev->config[0].interface[1].altsetting[2].endpoint[1].
503        bEndpointAddress != 0x04)
504       || (dev->config[0].interface[1].altsetting[2].endpoint[1].
505 	  bmAttributes != 0x02)
506       || (dev->config[0].interface[1].altsetting[2].endpoint[1].
507 	  wMaxPacketSize != 0x40)
508       || (dev->config[0].interface[1].altsetting[2].endpoint[1].bInterval !=
509 	  0x00))
510     {
511       if (verbose > 2)
512 	printf
513 	  ("    this is not a GT-8911 (check 11, bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
514 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
515 	   dev->config[0].interface[1].altsetting[2].endpoint[1].
516 	   bEndpointAddress,
517 	   dev->config[0].interface[1].altsetting[2].endpoint[1].bmAttributes,
518 	   dev->config[0].interface[1].altsetting[2].endpoint[1].
519 	   wMaxPacketSize,
520 	   dev->config[0].interface[1].altsetting[2].endpoint[1].bInterval);
521       return 0;
522 
523     }
524 
525   /* Now we send a control message */
526   result = prepare_interface (dev, &handle);
527   if (!result)
528     return "GT-8911?";
529 
530   memset (req, 0, 8);
531   req[0] = 0x55;
532   req[1] = 0x66;
533 
534   result =
535     usb_control_msg (handle, 0xc0, 0x10, 0x41, 0x0000, req, 64, TIMEOUT);
536   if (result <= 0)
537     {
538       if (verbose > 2)
539 	printf
540 	  ("    this is not a GT-8911 (check 12, couldn't send read control message (%s))\n",
541 	   strerror (errno));
542       finish_interface (handle);
543       return 0;
544     }
545   result =
546     usb_control_msg (handle, 0xc0, 0x10, 0x05, 0x0000, req, 64, TIMEOUT);
547   if (result <= 0)
548     {
549       if (verbose > 2)
550 	printf
551 	  ("    this is not a GT-8911 (check 13, couldn't send read control message (%s)\n",
552 	   strerror (errno));
553       finish_interface (handle);
554       return 0;
555     }
556   /* tested on model hardware version 0xffffffc0, firmware version 0x10)) */
557   if (verbose > 2)
558     printf
559       ("    Check 14, control message (hardware version %0x / firmware version %0x)\n",
560        req[0], req[1]);
561 
562   finish_interface (handle);
563   return "GT-8911";
564 }
565 
566 /* Check for Mustek MA-1017 */
567 static char *
check_ma1017(struct usb_device * dev)568 check_ma1017 (struct usb_device *dev)
569 {
570   char req[2];
571   usb_dev_handle *handle;
572   int result;
573   char res;
574 
575   if (verbose > 2)
576     printf ("    checking for MA-1017 ...\n");
577 
578   /* Check device descriptor */
579   if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE)
580       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass !=
581 	  USB_CLASS_PER_INTERFACE))
582     {
583       if (verbose > 2)
584 	printf
585 	  ("    this is not a MA-1017 (bDeviceClass = %d, bInterfaceClass = %d)\n",
586 	   dev->descriptor.bDeviceClass,
587 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
588       return 0;
589     }
590   if (dev->descriptor.bcdUSB != 0x100)
591     {
592       if (verbose > 2)
593 	printf ("    this is not a MA-1017 (bcdUSB = 0x%x)\n",
594 		dev->descriptor.bcdUSB);
595       return 0;
596     }
597   if (dev->descriptor.bDeviceSubClass != 0x00)
598     {
599       if (verbose > 2)
600 	printf ("    this is not a MA-1017 (bDeviceSubClass = 0x%x)\n",
601 		dev->descriptor.bDeviceSubClass);
602       return 0;
603     }
604   if (dev->descriptor.bDeviceProtocol != 0x00)
605     {
606       if (verbose > 2)
607 	printf ("    this is not a MA-1017 (bDeviceProtocol = 0x%x)\n",
608 		dev->descriptor.bDeviceProtocol);
609       return 0;
610     }
611 
612   /* Check endpoints */
613   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
614     {
615       if (verbose > 2)
616 	printf ("    this is not a MA-1017 (bNumEndpoints = %d)\n",
617 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
618       return 0;
619     }
620   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
621        bEndpointAddress != 0x01)
622       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
623 	  bmAttributes != 0x02)
624       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
625 	  wMaxPacketSize != 0x02)
626       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
627 	  0x00))
628     {
629       if (verbose > 2)
630 	printf
631 	  ("    this is not a MA-1017 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
632 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
633 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
634 	   bEndpointAddress,
635 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
636 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
637 	   wMaxPacketSize,
638 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
639       return 0;
640     }
641   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
642        bEndpointAddress != 0x82)
643       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
644 	  bmAttributes != 0x02)
645       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
646 	  wMaxPacketSize != 0x40)
647       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
648 	  0x00))
649     {
650       if (verbose > 2)
651 	printf
652 	  ("    this is not a MA-1017 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
653 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
654 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
655 	   bEndpointAddress,
656 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
657 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
658 	   wMaxPacketSize,
659 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
660       return 0;
661     }
662   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
663        bEndpointAddress != 0x83)
664       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
665 	  bmAttributes != 0x03)
666       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
667 	  wMaxPacketSize != 0x01)
668       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
669 	  0x01))
670     {
671       if (verbose > 2)
672 	printf
673 	  ("    this is not a MA-1017 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
674 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
675 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
676 	   bEndpointAddress,
677 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
678 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
679 	   wMaxPacketSize,
680 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
681       return 0;
682     }
683 
684   /* read a register value */
685   result = prepare_interface (dev, &handle);
686   if (!result)
687     return "MA-1017?";
688 
689   req[0] = 0x00;
690   req[1] = 0x02 | 0x20;
691   result = usb_bulk_write (handle, 0x01, req, 2, 1000);
692   if (result <= 0)
693     {
694       if (verbose > 2)
695 	printf ("    this is not a MA-1017 (Error during bulk write)\n");
696       finish_interface (handle);
697       return 0;
698     }
699   result = usb_bulk_read (handle, 0x82, &res, 1, 1000);
700   if (result <= 0)
701     {
702       if (verbose > 2)
703 	printf ("    this is not a MA-1017 (Error during bulk read)\n");
704       finish_interface (handle);
705       return 0;
706     }
707   /* Read one byte again to work around a bug in the MA-1017 chipset that
708      appears when an odd number of bytes is read or written. */
709   result = usb_bulk_write (handle, 0x01, req, 2, 1000);
710   result = usb_bulk_read (handle, 0x82, &res, 1, 1000);
711   finish_interface (handle);
712   return "MA-1017";
713 }
714 
715 /* Check for Mustek MA-1015 */
716 static char *
check_ma1015(struct usb_device * dev)717 check_ma1015 (struct usb_device *dev)
718 {
719   char req[8];
720   usb_dev_handle *handle;
721   int result;
722   unsigned char res;
723 
724   if (verbose > 2)
725     printf ("    checking for MA-1015 ...\n");
726 
727   /* Check device descriptor */
728   if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
729     {
730       if (verbose > 2)
731 	printf ("    this is not a MA-1015 (bDeviceClass = %d)\n",
732 		dev->descriptor.bDeviceClass);
733       return 0;
734     }
735   if (dev->descriptor.bcdUSB != 0x100)
736     {
737       if (verbose > 2)
738 	printf ("    this is not a MA-1015 (bcdUSB = 0x%x)\n",
739 		dev->descriptor.bcdUSB);
740       return 0;
741     }
742   if (dev->descriptor.bDeviceSubClass != 0xff)
743     {
744       if (verbose > 2)
745 	printf ("    this is not a MA-1015 (bDeviceSubClass = 0x%x)\n",
746 		dev->descriptor.bDeviceSubClass);
747       return 0;
748     }
749   if (dev->descriptor.bDeviceProtocol != 0xff)
750     {
751       if (verbose > 2)
752 	printf ("    this is not a MA-1015 (bDeviceProtocol = 0x%x)\n",
753 		dev->descriptor.bDeviceProtocol);
754       return 0;
755     }
756 
757   /* Check endpoints */
758   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 2)
759     {
760       if (verbose > 2)
761 	printf ("    this is not a MA-1015 (bNumEndpoints = %d)\n",
762 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
763       return 0;
764     }
765   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
766        bEndpointAddress != 0x81)
767       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
768 	  bmAttributes != 0x02)
769       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
770 	  wMaxPacketSize != 0x40)
771       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
772 	  0x00))
773     {
774       if (verbose > 2)
775 	printf
776 	  ("    this is not a MA-1015 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
777 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
778 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
779 	   bEndpointAddress,
780 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
781 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
782 	   wMaxPacketSize,
783 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
784       return 0;
785     }
786   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
787        bEndpointAddress != 0x02)
788       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
789 	  bmAttributes != 0x02)
790       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
791 	  wMaxPacketSize != 0x08)
792       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
793 	  0x00))
794     {
795       if (verbose > 2)
796 	printf
797 	  ("    this is not a MA-1015 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
798 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
799 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
800 	   bEndpointAddress,
801 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
802 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
803 	   wMaxPacketSize,
804 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
805       return 0;
806     }
807 
808   /* Now we read register 0 to find out if this is really a MA-1015 */
809   result = prepare_interface (dev, &handle);
810   if (!result)
811     return 0;
812 
813   memset (req, 0, 8);
814   req[0] = 33;
815   req[1] = 0x00;
816   result = usb_bulk_write (handle, 0x02, req, 8, TIMEOUT);
817   if (result <= 0)
818     {
819       if (verbose > 2)
820 	printf ("    this is not a MA-1015 (Error during bulk write)\n");
821       finish_interface (handle);
822       return 0;
823     }
824   result = usb_bulk_read (handle, 0x81, (char *) &res, 1, TIMEOUT);
825   if (result <= 0)
826     {
827       if (verbose > 2)
828 	printf ("    this is not a MA-1015 (Error during bulk read)\n");
829       finish_interface (handle);
830       return 0;
831     }
832   if (res != 0xa5)
833     {
834       if (verbose > 2)
835 	printf ("    this is not a MA-1015 (got 0x%x, expected 0xa5)\n", res);
836       finish_interface (handle);
837       return 0;
838     }
839   finish_interface (handle);
840   return "MA-1015";
841 }
842 
843 /* Check for Mustek MA-1509 */
844 static char *
check_ma1509(struct usb_device * dev)845 check_ma1509 (struct usb_device *dev)
846 {
847   char req[8];
848   char inquiry[0x60];
849   usb_dev_handle *handle;
850   int result;
851 
852   if (verbose > 2)
853     printf ("    checking for MA-1509 ...\n");
854 
855   /* Check device descriptor */
856   if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
857     {
858       if (verbose > 2)
859 	printf ("    this is not a MA-1509 (bDeviceClass = %d)\n",
860 		dev->descriptor.bDeviceClass);
861       return 0;
862     }
863   if (dev->descriptor.bcdUSB != 0x110)
864     {
865       if (verbose > 2)
866 	printf ("    this is not a MA-1509 (bcdUSB = 0x%x)\n",
867 		dev->descriptor.bcdUSB);
868       return 0;
869     }
870   if (dev->descriptor.bDeviceSubClass != 0xff)
871     {
872       if (verbose > 2)
873 	printf ("    this is not a MA-1509 (bDeviceSubClass = 0x%x)\n",
874 		dev->descriptor.bDeviceSubClass);
875       return 0;
876     }
877   if (dev->descriptor.bDeviceProtocol != 0xff)
878     {
879       if (verbose > 2)
880 	printf ("    this is not a MA-1509 (bDeviceProtocol = 0x%x)\n",
881 		dev->descriptor.bDeviceProtocol);
882       return 0;
883     }
884 
885   /* Check endpoints */
886   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
887     {
888       if (verbose > 2)
889 	printf ("    this is not a MA-1509 (bNumEndpoints = %d)\n",
890 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
891       return 0;
892     }
893   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
894        bEndpointAddress != 0x81)
895       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
896 	  bmAttributes != 0x02)
897       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
898 	  wMaxPacketSize != 0x40))
899     {
900       if (verbose > 2)
901 	printf
902 	  ("    this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
903 	   "wMaxPacketSize = 0x%x)\n",
904 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
905 	   bEndpointAddress,
906 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
907 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
908 	   wMaxPacketSize);
909       return 0;
910     }
911   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
912        bEndpointAddress != 0x02)
913       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
914 	  bmAttributes != 0x02)
915       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
916 	  wMaxPacketSize != 0x08))
917     {
918       if (verbose > 2)
919 	printf
920 	  ("    this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
921 	   "wMaxPacketSize = 0x%x)\n",
922 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
923 	   bEndpointAddress,
924 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
925 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
926 	   wMaxPacketSize);
927       return 0;
928     }
929   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
930        bEndpointAddress != 0x83)
931       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
932 	  bmAttributes != 0x03)
933       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
934 	  wMaxPacketSize != 0x08)
935       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
936 	  0x10))
937     {
938       if (verbose > 2)
939 	printf
940 	  ("    this is not a MA-1509 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
941 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
942 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
943 	   bEndpointAddress,
944 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
945 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
946 	   wMaxPacketSize,
947 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
948       return 0;
949     }
950 
951   /* This is a SCSI-over-USB chip, we'll read the inquiry */
952   result = prepare_interface (dev, &handle);
953   if (!result)
954     return "MA-1509?";
955 
956   memset (req, 0, 8);
957   req[0] = 0x12;
958   req[1] = 1;
959   req[6] = 0x60;
960 
961   result = usb_bulk_write (handle, 0x02, req, 8, TIMEOUT);
962   if (result <= 0)
963     {
964       if (verbose > 2)
965 	printf ("    this is not a MA-1509 (Error during bulk write)\n");
966       finish_interface (handle);
967       return 0;
968     }
969   memset (inquiry, 0, 0x60);
970   result = usb_bulk_read (handle, 0x81, (char *) inquiry, 0x60, TIMEOUT);
971   if (result != 0x60)
972     {
973       if (verbose > 2)
974 	printf ("    this is not a MA-1509 (Error during bulk read: %d)\n",
975 		result);
976       finish_interface (handle);
977       return 0;
978     }
979   if ((inquiry[0] & 0x1f) != 0x06)
980     {
981       if (verbose > 2)
982 	printf ("    this is not a MA-1509 (inquiry [0] = %d)\n", inquiry[0]);
983       finish_interface (handle);
984       return 0;
985     }
986   if (strncmp (inquiry + 8, "SCANNER ", 8) != 0)
987     {
988       inquiry[16] = 0;
989       if (verbose > 2)
990 	printf ("    this is not a MA-1509 (vendor=%s)\n", inquiry + 8);
991       finish_interface (handle);
992       return 0;
993     }
994   inquiry[36] = 0;
995   if (verbose > 2)
996     printf ("    MA-1509 version %s\n", inquiry + 32);
997 
998   finish_interface (handle);
999   return "MA-1509";
1000 }
1001 
1002 /********** the lm983x section **********/
1003 
1004 static int
lm983x_wb(usb_dev_handle * handle,unsigned char reg,unsigned char val)1005 lm983x_wb (usb_dev_handle * handle, unsigned char reg, unsigned char val)
1006 {
1007   unsigned char buf[5];
1008   int result;
1009 
1010   buf[0] = 0;
1011   buf[1] = reg;
1012   buf[2] = 0;
1013   buf[3] = 1;
1014   buf[4] = val;
1015 
1016   result = usb_bulk_write (handle, 3, (char *) buf, 5, TIMEOUT);
1017   if (result != 5)
1018     return 0;
1019 
1020   return 1;
1021 }
1022 
1023 static int
lm983x_rb(usb_dev_handle * handle,unsigned char reg,unsigned char * val)1024 lm983x_rb (usb_dev_handle * handle, unsigned char reg, unsigned char *val)
1025 {
1026   unsigned char buf[5];
1027   int result;
1028 
1029   buf[0] = 1;
1030   buf[1] = reg;
1031   buf[2] = 0;
1032   buf[3] = 1;
1033 
1034   result = usb_bulk_write (handle, 3, (char *) buf, 4, TIMEOUT);
1035   if (result != 4)
1036     return 0;
1037 
1038 
1039   result = usb_bulk_read (handle, 2, (char *) val, 1, TIMEOUT);
1040   if (result != 1)
1041     return 0;
1042 
1043   return 1;
1044 }
1045 
1046 static char *
check_merlin(struct usb_device * dev)1047 check_merlin (struct usb_device *dev)
1048 {
1049   unsigned char val;
1050   int result;
1051   usb_dev_handle *handle;
1052 
1053   if (verbose > 2)
1054     printf ("    checking for LM983[1,2,3] ...\n");
1055 
1056   /* Check device descriptor */
1057   if (((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
1058        && (dev->descriptor.bDeviceClass != 0))
1059       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass !=
1060 	  USB_CLASS_VENDOR_SPEC))
1061     {
1062       if (verbose > 2)
1063 	printf
1064 	  ("    this is not a LM983x (bDeviceClass = %d, bInterfaceClass = %d)\n",
1065 	   dev->descriptor.bDeviceClass,
1066 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
1067       return 0;
1068     }
1069   if ((dev->descriptor.bcdUSB != 0x110)
1070       && (dev->descriptor.bcdUSB != 0x101)
1071       && (dev->descriptor.bcdUSB != 0x100))
1072     {
1073       if (verbose > 2)
1074 	printf ("    this is not a LM983x (bcdUSB = 0x%x)\n",
1075 		dev->descriptor.bcdUSB);
1076       return 0;
1077     }
1078   if (dev->descriptor.bDeviceSubClass != 0x00)
1079     {
1080       if (verbose > 2)
1081 	printf ("    this is not a LM983x (bDeviceSubClass = 0x%x)\n",
1082 		dev->descriptor.bDeviceSubClass);
1083       return 0;
1084     }
1085   if ((dev->descriptor.bDeviceProtocol != 0) &&
1086       (dev->descriptor.bDeviceProtocol != 0xff))
1087     {
1088       if (verbose > 2)
1089 	printf ("    this is not a LM983x (bDeviceProtocol = 0x%x)\n",
1090 		dev->descriptor.bDeviceProtocol);
1091       return 0;
1092     }
1093 
1094   /* Check endpoints */
1095   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
1096     {
1097       if (verbose > 2)
1098 	printf ("    this is not a LM983x (bNumEndpoints = %d)\n",
1099 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
1100       return 0;
1101     }
1102 
1103   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1104        bEndpointAddress != 0x81)
1105       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1106 	  bmAttributes != 0x03)
1107       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1108 	  wMaxPacketSize != 0x1)
1109       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
1110 	  0x10))
1111     {
1112       if (verbose > 2)
1113 	printf
1114 	  ("    this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1115 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1116 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1117 	   bEndpointAddress,
1118 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
1119 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1120 	   wMaxPacketSize,
1121 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
1122       return 0;
1123     }
1124 
1125   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1126        bEndpointAddress != 0x82)
1127       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1128 	  bmAttributes != 0x02)
1129       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1130 	  wMaxPacketSize != 0x40)
1131       /* Currently disabled as we have some problems in detection here ! */
1132       /*|| (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0) */
1133     )
1134     {
1135       if (verbose > 2)
1136 	printf
1137 	  ("    this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1138 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1139 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1140 	   bEndpointAddress,
1141 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
1142 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1143 	   wMaxPacketSize,
1144 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
1145       return 0;
1146     }
1147 
1148   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
1149        bEndpointAddress != 0x03)
1150       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1151 	  bmAttributes != 0x02)
1152       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1153 	  wMaxPacketSize != 0x40)
1154       /* Currently disabled as we have some problems in detection here ! */
1155       /* || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 0) */
1156     )
1157     {
1158       if (verbose > 2)
1159 	printf
1160 	  ("    this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1161 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1162 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1163 	   bEndpointAddress,
1164 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
1165 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1166 	   wMaxPacketSize,
1167 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
1168       return 0;
1169     }
1170 
1171   result = prepare_interface (dev, &handle);
1172   if (!result)
1173     return "LM983x?";
1174 
1175   result = lm983x_wb (handle, 0x07, 0x00);
1176   if (1 == result)
1177     result = lm983x_wb (handle, 0x08, 0x02);
1178   if (1 == result)
1179     result = lm983x_rb (handle, 0x07, &val);
1180   if (1 == result)
1181     result = lm983x_rb (handle, 0x08, &val);
1182   if (1 == result)
1183     result = lm983x_rb (handle, 0x69, &val);
1184 
1185   if (0 == result)
1186     {
1187       if (verbose > 2)
1188 	printf ("  Couldn't access LM983x registers.\n");
1189       finish_interface (handle);
1190       return 0;
1191     }
1192 
1193   finish_interface (handle);
1194 
1195   switch (val)
1196     {
1197     case 4:
1198       return "LM9832/3";
1199       break;
1200     case 3:
1201       return "LM9831";
1202       break;
1203     case 2:
1204       return "LM9830";
1205       break;
1206     default:
1207       return "LM983x?";
1208       break;
1209     }
1210 }
1211 
1212 /********** the gl646 section **********/
1213 
1214 
1215 static int
gl646_write_reg(usb_dev_handle * handle,unsigned char reg,unsigned char val)1216 gl646_write_reg (usb_dev_handle * handle, unsigned char reg,
1217 		 unsigned char val)
1218 {
1219   int result;
1220 
1221   result =
1222     usb_control_msg (handle, 0x00, 0x00, 0x83, 0x00, (char *) &reg, 0x01,
1223 		     TIMEOUT);
1224   if (result < 0)
1225     return 0;
1226 
1227   result =
1228     usb_control_msg (handle, 0x00, 0x00, 0x85, 0x00, (char *) &val, 0x01,
1229 		     TIMEOUT);
1230   if (result < 0)
1231     return 0;
1232 
1233   return 1;
1234 }
1235 
1236 static int
gl646_read_reg(usb_dev_handle * handle,unsigned char reg,unsigned char * val)1237 gl646_read_reg (usb_dev_handle * handle, unsigned char reg,
1238 		unsigned char *val)
1239 {
1240   int result;
1241 
1242   result =
1243     usb_control_msg (handle, 0x00, 0x00, 0x83, 0x00, (char *) &reg, 0x01,
1244 		     TIMEOUT);
1245   if (result < 0)
1246     return 0;
1247 
1248   result =
1249     usb_control_msg (handle, 0x80, 0x00, 0x84, 0x00, (char *) val, 0x01,
1250 		     TIMEOUT);
1251   if (result < 0)
1252     return 0;
1253 
1254   return 1;
1255 }
1256 
1257 
1258 static char *
check_gl646(struct usb_device * dev)1259 check_gl646 (struct usb_device *dev)
1260 {
1261   unsigned char val;
1262   int result;
1263   usb_dev_handle *handle;
1264 
1265   if (verbose > 2)
1266     printf ("    checking for GL646 ...\n");
1267 
1268   /* Check device descriptor */
1269   if ((dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE)
1270       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 0x10))
1271     {
1272       if (verbose > 2)
1273 	printf
1274 	  ("    this is not a GL646 (bDeviceClass = %d, bInterfaceClass = %d)\n",
1275 	   dev->descriptor.bDeviceClass,
1276 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
1277       return 0;
1278     }
1279   if (dev->descriptor.bcdUSB != 0x110)
1280     {
1281       if (verbose > 2)
1282 	printf ("    this is not a GL646 (bcdUSB = 0x%x)\n",
1283 		dev->descriptor.bcdUSB);
1284       return 0;
1285     }
1286   if (dev->descriptor.bDeviceSubClass != 0x00)
1287     {
1288       if (verbose > 2)
1289 	printf ("    this is not a GL646 (bDeviceSubClass = 0x%x)\n",
1290 		dev->descriptor.bDeviceSubClass);
1291       return 0;
1292     }
1293   if (dev->descriptor.bDeviceProtocol != 0)
1294     {
1295       if (verbose > 2)
1296 	printf ("    this is not a GL646 (bDeviceProtocol = 0x%x)\n",
1297 		dev->descriptor.bDeviceProtocol);
1298       return 0;
1299     }
1300 
1301   /* Check endpoints */
1302   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
1303     {
1304       if (verbose > 2)
1305 	printf ("    this is not a GL646 (bNumEndpoints = %d)\n",
1306 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
1307       return 0;
1308     }
1309 
1310   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1311        bEndpointAddress != 0x81)
1312       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1313 	  bmAttributes != 0x02)
1314       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1315 	  wMaxPacketSize != 0x40)
1316       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
1317 	  0x0))
1318     {
1319       if (verbose > 2)
1320 	printf
1321 	  ("    this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1322 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1323 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1324 	   bEndpointAddress,
1325 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
1326 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1327 	   wMaxPacketSize,
1328 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
1329       return 0;
1330     }
1331 
1332   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1333        bEndpointAddress != 0x02)
1334       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1335 	  bmAttributes != 0x02)
1336       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1337 	  wMaxPacketSize != 0x40)
1338       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
1339 	  0))
1340     {
1341       if (verbose > 2)
1342 	printf
1343 	  ("    this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1344 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1345 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1346 	   bEndpointAddress,
1347 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
1348 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1349 	   wMaxPacketSize,
1350 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
1351       return 0;
1352     }
1353 
1354   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
1355        bEndpointAddress != 0x83)
1356       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1357 	  bmAttributes != 0x03)
1358       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1359 	  wMaxPacketSize != 0x1)
1360       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
1361 	  8))
1362     {
1363       if (verbose > 2)
1364 	printf
1365 	  ("    this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1366 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1367 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1368 	   bEndpointAddress,
1369 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
1370 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1371 	   wMaxPacketSize,
1372 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
1373       return 0;
1374     }
1375 
1376   result = prepare_interface (dev, &handle);
1377   if (!result)
1378     return "GL646?";
1379 
1380   result = gl646_write_reg (handle, 0x38, 0x15);
1381   if (!result)
1382     {
1383       if (verbose > 2)
1384 	printf ("    this is not a GL646 (writing register failed)\n");
1385       finish_interface (handle);
1386       return 0;
1387     }
1388 
1389   result = gl646_read_reg (handle, 0x4e, &val);
1390   if (!result)
1391     {
1392       if (verbose > 2)
1393 	printf ("    this is not a GL646 (reading register failed)\n");
1394       finish_interface (handle);
1395       return 0;
1396     }
1397 
1398   if (val != 0x15)
1399     {
1400       if (verbose > 2)
1401 	printf ("    this is not a GL646 (reg 0x4e != reg 0x38)\n");
1402       finish_interface (handle);
1403       return 0;
1404     }
1405   finish_interface (handle);
1406   return "GL646";
1407 }
1408 
1409 /* Same as check_gl646, except that sanity checks are different. */
1410 static char *
check_gl646_hp(struct usb_device * dev)1411 check_gl646_hp (struct usb_device *dev)
1412 {
1413   unsigned char val;
1414   int result;
1415   usb_dev_handle *handle;
1416 
1417   if (verbose > 2)
1418     printf ("    checking for GL646_HP ...\n");
1419 
1420   /* Check device descriptor */
1421   if ((dev->descriptor.bDeviceClass != 0xff)
1422       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 0xff))
1423     {
1424       if (verbose > 2)
1425 	printf
1426 	  ("    this is not a GL646_HP (bDeviceClass = %d, bInterfaceClass = %d)\n",
1427 	   dev->descriptor.bDeviceClass,
1428 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
1429       return 0;
1430     }
1431   if (dev->descriptor.bcdUSB != 0x110)
1432     {
1433       if (verbose > 2)
1434 	printf ("    this is not a GL646_HP (bcdUSB = 0x%x)\n",
1435 		dev->descriptor.bcdUSB);
1436       return 0;
1437     }
1438   if (dev->descriptor.bDeviceSubClass != 0xff)
1439     {
1440       if (verbose > 2)
1441 	printf ("    this is not a GL646_HP (bDeviceSubClass = 0x%x)\n",
1442 		dev->descriptor.bDeviceSubClass);
1443       return 0;
1444     }
1445   if (dev->descriptor.bDeviceProtocol != 0xff)
1446     {
1447       if (verbose > 2)
1448 	printf ("    this is not a GL646_HP (bDeviceProtocol = 0x%x)\n",
1449 		dev->descriptor.bDeviceProtocol);
1450       return 0;
1451     }
1452 
1453   /* Check endpoints */
1454   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
1455     {
1456       if (verbose > 2)
1457 	printf ("    this is not a GL646_HP (bNumEndpoints = %d)\n",
1458 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
1459       return 0;
1460     }
1461 
1462   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1463        bEndpointAddress != 0x81)
1464       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1465 	  bmAttributes != 0x02)
1466       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1467 	  wMaxPacketSize != 0x40)
1468       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
1469 	  0x0))
1470     {
1471       if (verbose > 2)
1472 	printf
1473 	  ("    this is not a GL646_HP (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1474 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1475 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1476 	   bEndpointAddress,
1477 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
1478 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1479 	   wMaxPacketSize,
1480 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
1481       return 0;
1482     }
1483 
1484   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1485        bEndpointAddress != 0x02)
1486       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1487 	  bmAttributes != 0x02)
1488       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1489 	  wMaxPacketSize != 0x40)
1490       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
1491 	  0))
1492     {
1493       if (verbose > 2)
1494 	printf
1495 	  ("    this is not a GL646_HP (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1496 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1497 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1498 	   bEndpointAddress,
1499 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
1500 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1501 	   wMaxPacketSize,
1502 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
1503       return 0;
1504     }
1505 
1506   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
1507        bEndpointAddress != 0x83)
1508       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1509 	  bmAttributes != 0x03)
1510       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1511 	  wMaxPacketSize != 0x1)
1512       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
1513 	  8))
1514     {
1515       if (verbose > 2)
1516 	printf
1517 	  ("    this is not a GL646_HP (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1518 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1519 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1520 	   bEndpointAddress,
1521 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
1522 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1523 	   wMaxPacketSize,
1524 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
1525       return 0;
1526     }
1527 
1528   result = prepare_interface (dev, &handle);
1529   if (!result)
1530     return "GL646_HP?";
1531 
1532   result = gl646_write_reg (handle, 0x38, 0x15);
1533   if (!result)
1534     {
1535       if (verbose > 2)
1536 	printf ("    this is not a GL646_HP (writing register failed)\n");
1537       finish_interface (handle);
1538       return 0;
1539     }
1540 
1541   result = gl646_read_reg (handle, 0x4e, &val);
1542   if (!result)
1543     {
1544       if (verbose > 2)
1545 	printf ("    this is not a GL646_HP (reading register failed)\n");
1546       finish_interface (handle);
1547       return 0;
1548     }
1549 
1550   if (val != 0x15)
1551     {
1552       if (verbose > 2)
1553 	printf ("    this is not a GL646_HP (reg 0x4e != reg 0x38)\n");
1554       finish_interface (handle);
1555       return 0;
1556     }
1557 
1558   finish_interface (handle);
1559 
1560   return "GL646_HP";
1561 }
1562 
1563 /* check for the combination of gl660 and gl646 */
1564 static char *
check_gl660_gl646(struct usb_device * dev)1565 check_gl660_gl646 (struct usb_device *dev)
1566 {
1567   unsigned char val;
1568   int result;
1569   usb_dev_handle *handle;
1570 
1571   if (verbose > 2)
1572     printf ("    checking for GL660+GL646 ...\n");
1573 
1574   /* Check device descriptor */
1575   if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
1576       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass !=
1577 	  USB_CLASS_PER_INTERFACE))
1578     {
1579       if (verbose > 2)
1580 	printf
1581 	  ("    this is not a GL660+GL646 (bDeviceClass = %d, bInterfaceClass = %d)\n",
1582 	   dev->descriptor.bDeviceClass,
1583 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
1584       return 0;
1585     }
1586   if (dev->descriptor.bcdUSB != 0x200)
1587     {
1588       if (verbose > 2)
1589 	printf ("    this is not a GL660+GL646 (bcdUSB = 0x%x)\n",
1590 		dev->descriptor.bcdUSB);
1591       return 0;
1592     }
1593   if (dev->descriptor.bDeviceSubClass != 0xff)
1594     {
1595       if (verbose > 2)
1596 	printf ("    this is not a GL660+GL646 (bDeviceSubClass = 0x%x)\n",
1597 		dev->descriptor.bDeviceSubClass);
1598       return 0;
1599     }
1600   if (dev->descriptor.bDeviceProtocol != 0xff)
1601     {
1602       if (verbose > 2)
1603 	printf ("    this is not a GL660+GL646 (bDeviceProtocol = 0x%x)\n",
1604 		dev->descriptor.bDeviceProtocol);
1605       return 0;
1606     }
1607 
1608   /* Check endpoints */
1609   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
1610     {
1611       if (verbose > 2)
1612 	printf ("    this is not a GL660+GL646 (bNumEndpoints = %d)\n",
1613 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
1614       return 0;
1615     }
1616 
1617   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1618        bEndpointAddress != 0x81)
1619       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1620 	  bmAttributes != 0x02)
1621       ||
1622       ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1623 	wMaxPacketSize != 0x40)
1624        && (dev->config[0].interface[0].altsetting[0].endpoint[0].
1625 	   wMaxPacketSize != 0x200))
1626       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
1627 	  0x0))
1628     {
1629       if (verbose > 2)
1630 	printf
1631 	  ("    this is not a GL660+GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1632 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1633 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1634 	   bEndpointAddress,
1635 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
1636 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1637 	   wMaxPacketSize,
1638 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
1639       return 0;
1640     }
1641 
1642   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1643        bEndpointAddress != 0x02)
1644       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1645 	  bmAttributes != 0x02)
1646       ||
1647       ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1648 	wMaxPacketSize != 0x40)
1649        && (dev->config[0].interface[0].altsetting[0].endpoint[0].
1650 	   wMaxPacketSize != 0x200))
1651       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
1652 	  0))
1653     {
1654       if (verbose > 2)
1655 	printf
1656 	  ("    this is not a GL660+GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1657 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1658 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1659 	   bEndpointAddress,
1660 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
1661 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1662 	   wMaxPacketSize,
1663 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
1664       return 0;
1665     }
1666 
1667   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
1668        bEndpointAddress != 0x83)
1669       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1670 	  bmAttributes != 0x03)
1671       ||
1672       ((dev->config[0].interface[0].altsetting[0].endpoint[2].
1673 	wMaxPacketSize != 0x1)
1674        && (dev->config[0].interface[0].altsetting[0].endpoint[0].
1675 	   wMaxPacketSize != 0x200))
1676       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
1677 	  8))
1678     {
1679       if (verbose > 2)
1680 	printf
1681 	  ("    this is not a GL660+GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1682 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1683 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1684 	   bEndpointAddress,
1685 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
1686 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1687 	   wMaxPacketSize,
1688 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
1689       return 0;
1690     }
1691 
1692   result = prepare_interface (dev, &handle);
1693   if (!result)
1694     return "GL660+GL646?";
1695 
1696   result = gl646_write_reg (handle, 0x38, 0x15);
1697   if (!result)
1698     {
1699       if (verbose > 2)
1700 	printf ("    this is not a GL660+GL646 (writing register failed)\n");
1701       finish_interface (handle);
1702       return 0;
1703     }
1704 
1705   result = gl646_read_reg (handle, 0x4e, &val);
1706   if (!result)
1707     {
1708       if (verbose > 2)
1709 	printf ("    this is not a GL660+GL646 (reading register failed)\n");
1710       finish_interface (handle);
1711       return 0;
1712     }
1713 
1714   if (val != 0x15)
1715     {
1716       if (verbose > 2)
1717 	printf ("    this is not a GL660+GL646 (reg 0x4e != reg 0x38)\n");
1718       finish_interface (handle);
1719       return 0;
1720     }
1721   finish_interface (handle);
1722   return "GL660+GL646";
1723 }
1724 
1725 
1726 /********** the gl841 section **********/
1727 
1728 /* the various incarnations could be distinguished by the
1729  * bcdDevice entry:
1730  *    0x701 --> GL124
1731  *    0x700 --> ?
1732  *    0x605 --> GL845
1733  *    0x603 --> GL847
1734  *    0x601 --> GL846
1735  *    0x500 --> GL843
1736  *    0x300 --> GL842 (perhaps only >= 0x303 ?)
1737  *    0x200 --> GL841
1738  */
1739 static char *
check_gl841(struct usb_device * dev)1740 check_gl841 (struct usb_device *dev)
1741 {
1742   unsigned char val;
1743   int result;
1744   usb_dev_handle *handle;
1745 
1746   if (verbose > 2)
1747     printf ("    checking for GL84x ...\n");
1748 
1749   /* Check device descriptor */
1750   if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
1751       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass !=
1752 	  USB_CLASS_VENDOR_SPEC))
1753     {
1754       if (verbose > 2)
1755 	printf
1756 	  ("    this is not a GL84x (bDeviceClass = %d, bInterfaceClass = %d)\n",
1757 	   dev->descriptor.bDeviceClass,
1758 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
1759       return 0;
1760     }
1761   if (dev->descriptor.bcdUSB != 0x200)
1762     {
1763       if (verbose > 2)
1764 	printf ("    this is not a GL84x (bcdUSB = 0x%x)\n",
1765 		dev->descriptor.bcdUSB);
1766       return 0;
1767     }
1768   if (dev->descriptor.bDeviceSubClass != 0xff)
1769     {
1770       if (verbose > 2)
1771 	printf ("    this is not a GL84x (bDeviceSubClass = 0x%x)\n",
1772 		dev->descriptor.bDeviceSubClass);
1773       return 0;
1774     }
1775   if (dev->descriptor.bDeviceProtocol != 0xff)
1776     {
1777       if (verbose > 2)
1778 	printf ("    this is not a GL84x (bDeviceProtocol = 0x%x)\n",
1779 		dev->descriptor.bDeviceProtocol);
1780       return 0;
1781     }
1782 
1783   /* Check endpoints */
1784   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
1785     {
1786       if (verbose > 2)
1787 	printf ("    this is not a GL84x (bNumEndpoints = %d)\n",
1788 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
1789       return 0;
1790     }
1791 
1792   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1793        bEndpointAddress != 0x81)
1794       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
1795 	  bmAttributes != 0x02)
1796       || ((dev->config[0].interface[0].altsetting[0].endpoint[0].
1797 	   wMaxPacketSize != 0x40) &&
1798 	  (dev->config[0].interface[0].altsetting[0].endpoint[0].
1799 	   wMaxPacketSize != 0x200))
1800       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
1801 	  0x0))
1802     {
1803       if (verbose > 2)
1804 	printf
1805 	  ("    this is not a GL84x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1806 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1807 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1808 	   bEndpointAddress,
1809 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
1810 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1811 	   wMaxPacketSize,
1812 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
1813       return 0;
1814     }
1815 
1816   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1817        bEndpointAddress != 0x02)
1818       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
1819 	  bmAttributes != 0x02)
1820       || ((dev->config[0].interface[0].altsetting[0].endpoint[1].
1821 	   wMaxPacketSize != 0x40) &&
1822 	  (dev->config[0].interface[0].altsetting[0].endpoint[1].
1823 	   wMaxPacketSize != 0x200))
1824       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
1825 	  0))
1826     {
1827       if (verbose > 2)
1828 	printf
1829 	  ("    this is not a GL84x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1830 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1831 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1832 	   bEndpointAddress,
1833 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
1834 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
1835 	   wMaxPacketSize,
1836 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
1837       return 0;
1838     }
1839 
1840   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
1841        bEndpointAddress != 0x83)
1842       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1843 	  bmAttributes != 0x03)
1844       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
1845 	  wMaxPacketSize != 0x1)
1846       ||
1847       ((dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8)
1848        && (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
1849 	   16)))
1850     {
1851       if (verbose > 2)
1852 	printf
1853 	  ("    this is not a GL84x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
1854 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
1855 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1856 	   bEndpointAddress,
1857 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
1858 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
1859 	   wMaxPacketSize,
1860 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
1861       return 0;
1862     }
1863 
1864   result = prepare_interface (dev, &handle);
1865   if (!result) {
1866     if (dev->descriptor.bcdDevice == 0x702)
1867         return "GL124?";
1868     if (dev->descriptor.bcdDevice == 0x701)
1869         return "GL124?";
1870     if (dev->descriptor.bcdDevice >= 0x700)
1871 	return "GL848+?";
1872     if (dev->descriptor.bcdDevice >= 0x603)
1873 	return "GL847?";
1874     if (dev->descriptor.bcdDevice >= 0x600)
1875 	return "GL846?";
1876     if (dev->descriptor.bcdDevice >= 0x500)
1877 	return "GL845?";
1878     if (dev->descriptor.bcdDevice >= 0x400)
1879 	return "GL843?";
1880     if (dev->descriptor.bcdDevice >= 0x300)
1881 	return "GL842?";
1882     else
1883 	return "GL841?";
1884   }
1885 
1886   result = gl646_write_reg (handle, 0x38, 0x15);
1887   if (!result)
1888     {
1889       if (verbose > 2)
1890 	printf ("    this is not a GL84x (writing register failed)\n");
1891       finish_interface (handle);
1892       return 0;
1893     }
1894 
1895   result = gl646_read_reg (handle, 0x38, &val);
1896   if (!result)
1897     {
1898       if (verbose > 2)
1899 	printf ("    this is not a GL84x (reading register failed)\n");
1900       finish_interface (handle);
1901       return 0;
1902     }
1903 
1904   if (val != 0x15)
1905     {
1906       if (verbose > 2)
1907 	printf ("    this is not a GL84x (reg 0x38 != 0x15)\n");
1908       finish_interface (handle);
1909       return 0;
1910     }
1911   finish_interface (handle);
1912 
1913   if (dev->descriptor.bcdDevice == 0x702)
1914     return "GL128";
1915   if (dev->descriptor.bcdDevice == 0x701)
1916     return "GL124";
1917   if (dev->descriptor.bcdDevice >= 0x700)
1918     return "GL848+";
1919   if (dev->descriptor.bcdDevice >= 0x605)
1920     return "GL845";
1921   if (dev->descriptor.bcdDevice >= 0x603)
1922     return "GL847";
1923   if (dev->descriptor.bcdDevice >= 0x600)
1924     return "GL846";
1925   if (dev->descriptor.bcdDevice >= 0x500)
1926     return "GL843";
1927   if (dev->descriptor.bcdDevice >= 0x300)
1928     return "GL842";
1929   return "GL841";
1930 }
1931 
1932 
1933 /********** the icm532b section version 0.2 **********/
1934 /*          no write and read test registers yet     */
1935 
1936 static char *
check_icm532b(struct usb_device * dev)1937 check_icm532b (struct usb_device *dev)
1938 {
1939   int result;
1940   usb_dev_handle *handle;
1941 
1942   if (verbose > 2)
1943     printf ("    checking for ICM532B ...\n");
1944 
1945   /* Check device descriptor */
1946   if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
1947       || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 0xff))
1948     {
1949       if (verbose > 2)
1950 	printf
1951 	  ("    this is not a ICM532B (check 1, bDeviceClass = %d, bInterfaceClass = %d)\n",
1952 	   dev->descriptor.bDeviceClass,
1953 	   dev->config[0].interface[0].altsetting[0].bInterfaceClass);
1954       return 0;
1955     }
1956   if (dev->descriptor.bcdUSB != 0x110)
1957     {
1958       if (verbose > 2)
1959 	printf ("    this is not a ICM532B (check 2, bcdUSB = 0x%x)\n",
1960 		dev->descriptor.bcdUSB);
1961       return 0;
1962     }
1963   if (dev->descriptor.bDeviceSubClass != 0xff)
1964     {
1965       if (verbose > 2)
1966 	printf
1967 	  ("    this is not a ICM532B (check 3, bDeviceSubClass = 0x%x)\n",
1968 	   dev->descriptor.bDeviceSubClass);
1969       return 0;
1970     }
1971   if (dev->descriptor.bDeviceProtocol != 0xff)
1972     {
1973       if (verbose > 2)
1974 	printf
1975 	  ("    this is not a ICM532B (check 4, bDeviceProtocol = 0x%x)\n",
1976 	   dev->descriptor.bDeviceProtocol);
1977       return 0;
1978     }
1979 
1980   /* Check endpoints */
1981   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 0x01)
1982     {
1983       if (verbose > 2)
1984 	printf ("    this is not a ICM532B (check 5, bNumEndpoints = %d)\n",
1985 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
1986       return 0;
1987     }
1988   /* Check bEndpointAddress */
1989   if (dev->config[0].interface[0].altsetting[0].endpoint[0].
1990       bEndpointAddress != 0x81)
1991     {
1992       if (verbose > 2)
1993 	printf
1994 	  ("    this is not a ICM532B (check 6, bEndpointAddress = %d)\n",
1995 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
1996 	   bEndpointAddress);
1997       return 0;
1998     }
1999   /* Check bmAttributes */
2000   if (dev->config[0].interface[0].altsetting[0].endpoint[0].
2001       bmAttributes != 0x01)
2002     {
2003       if (verbose > 2)
2004 	printf
2005 	  ("    this is not a ICM532B (check 7, bEndpointAddress = %d)\n",
2006 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2007 	   bmAttributes);
2008       return 0;
2009     }
2010   if ((dev->config[0].interface[0].altsetting[0].bAlternateSetting != 0x00)
2011       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2012 	  wMaxPacketSize != 0x00))
2013     {
2014       if (verbose > 2)
2015 	printf
2016 	  ("    this is not a ICM532B (check 8, bAlternateSetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2017 	   dev->config[0].interface[0].altsetting[0].bAlternateSetting,
2018 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2019 	   wMaxPacketSize);
2020       return 0;
2021     }
2022 
2023   if ((dev->config[0].interface[0].altsetting[1].bAlternateSetting != 0x01)
2024       || (dev->config[0].interface[0].altsetting[1].endpoint[0].
2025 	  wMaxPacketSize != 0x100))
2026     {
2027       if (verbose > 2)
2028 	printf
2029 	  ("    this is not a ICM532B (check 9, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2030 	   dev->config[0].interface[0].altsetting[1].bAlternateSetting,
2031 	   dev->config[0].interface[0].altsetting[1].endpoint[0].
2032 	   wMaxPacketSize);
2033       return 0;
2034     }
2035   if ((dev->config[0].interface[0].altsetting[2].bAlternateSetting != 0x02)
2036       || (dev->config[0].interface[0].altsetting[2].endpoint[0].
2037 	  wMaxPacketSize != 0x180))
2038     {
2039       if (verbose > 2)
2040 	printf
2041 	  ("    this is not a ICM532B (check 10, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2042 	   dev->config[0].interface[0].altsetting[2].bAlternateSetting,
2043 	   dev->config[0].interface[0].altsetting[2].endpoint[0].
2044 	   wMaxPacketSize);
2045       return 0;
2046     }
2047   if ((dev->config[0].interface[0].altsetting[3].bAlternateSetting != 0x03)
2048       || (dev->config[0].interface[0].altsetting[3].endpoint[0].
2049 	  wMaxPacketSize != 0x200))
2050     {
2051       if (verbose > 2)
2052 	printf
2053 	  ("    this is not a ICM532B (check 11, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2054 	   dev->config[0].interface[0].altsetting[3].bAlternateSetting,
2055 	   dev->config[0].interface[0].altsetting[3].endpoint[0].
2056 	   wMaxPacketSize);
2057       return 0;
2058     }
2059   if ((dev->config[0].interface[0].altsetting[4].bAlternateSetting != 0x04)
2060       || (dev->config[0].interface[0].altsetting[4].endpoint[0].
2061 	  wMaxPacketSize != 0x280))
2062     {
2063       if (verbose > 2)
2064 	printf
2065 	  ("    this is not a ICM532B (check 12, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2066 	   dev->config[0].interface[0].altsetting[4].bAlternateSetting,
2067 	   dev->config[0].interface[0].altsetting[4].endpoint[0].
2068 	   wMaxPacketSize);
2069       return 0;
2070     }
2071   if ((dev->config[0].interface[0].altsetting[5].bAlternateSetting != 0x05)
2072       || (dev->config[0].interface[0].altsetting[5].endpoint[0].
2073 	  wMaxPacketSize != 0x300))
2074     {
2075       if (verbose > 2)
2076 	printf
2077 	  ("    this is not a ICM532B (check 13, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2078 	   dev->config[0].interface[0].altsetting[5].bAlternateSetting,
2079 	   dev->config[0].interface[0].altsetting[5].endpoint[0].
2080 	   wMaxPacketSize);
2081       return 0;
2082     }
2083   if ((dev->config[0].interface[0].altsetting[6].bAlternateSetting != 0x06)
2084       || (dev->config[0].interface[0].altsetting[6].endpoint[0].
2085 	  wMaxPacketSize != 0x380))
2086     {
2087       if (verbose > 2)
2088 	printf
2089 	  ("    this is not a ICM532B (check 14, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2090 	   dev->config[0].interface[0].altsetting[6].bAlternateSetting,
2091 	   dev->config[0].interface[0].altsetting[6].endpoint[0].
2092 	   wMaxPacketSize);
2093       return 0;
2094     }
2095   if ((dev->config[0].interface[0].altsetting[7].bAlternateSetting != 0x07)
2096       || (dev->config[0].interface[0].altsetting[7].endpoint[0].
2097 	  wMaxPacketSize != 0x3ff))
2098     {
2099       if (verbose > 2)
2100 	printf
2101 	  ("    this is not a ICM532B (check 15, bAlternatesetting = 0x%x, wMaxPacketSize = 0x%x)\n",
2102 	   dev->config[0].interface[0].altsetting[7].bAlternateSetting,
2103 	   dev->config[0].interface[0].altsetting[7].endpoint[0].
2104 	   wMaxPacketSize);
2105       return 0;
2106     }
2107 
2108   result = prepare_interface (dev, &handle);
2109   if (!result)
2110     return "ICM532B?";
2111 
2112   finish_interface (handle);
2113   return "ICM532B";
2114 }
2115 /* ====================================== end of icm532b ==================*/
2116 
2117 
2118 /* Check for the combination of a PowerVision PV8630 (USB->parport bridge)
2119    and National Semiconductor LM9830 */
2120 static char *
check_pv8630_lm9830(struct usb_device * dev)2121 check_pv8630_lm9830 (struct usb_device *dev)
2122 {
2123   usb_dev_handle *handle;
2124   int result;
2125   char data;
2126 
2127   if (verbose > 2)
2128     printf ("    checking for PV8630/LM9830 ...\n");
2129 
2130   /* Check device descriptor */
2131   if (dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE)
2132     {
2133       if (verbose > 2)
2134 	printf ("    this is not a PV8630/LM9830 (bDeviceClass = %d)\n",
2135 		dev->descriptor.bDeviceClass);
2136       return 0;
2137     }
2138   if (dev->descriptor.bcdUSB != 0x100)
2139     {
2140       if (verbose > 2)
2141 	printf ("    this is not a PV8630/LM9830 (bcdUSB = 0x%x)\n",
2142 		dev->descriptor.bcdUSB);
2143       return 0;
2144     }
2145   if (dev->descriptor.bDeviceSubClass != 0x00)
2146     {
2147       if (verbose > 2)
2148 	printf ("    this is not a PV8630/LM9830 (bDeviceSubClass = 0x%x)\n",
2149 		dev->descriptor.bDeviceSubClass);
2150       return 0;
2151     }
2152   if (dev->descriptor.bDeviceProtocol != 0x00)
2153     {
2154       if (verbose > 2)
2155 	printf ("    this is not a PV8630/LM9830 (bDeviceProtocol = 0x%x)\n",
2156 		dev->descriptor.bDeviceProtocol);
2157       return 0;
2158     }
2159 
2160   /* Check endpoints */
2161   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
2162     {
2163       if (verbose > 2)
2164 	printf ("    this is not a PV8630/LM9830 (bNumEndpoints = %d)\n",
2165 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
2166       return 0;
2167     }
2168   /* Endpoint 0 */
2169   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
2170        bEndpointAddress != 0x01)
2171       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2172 	  bmAttributes != 0x02)
2173       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2174 	  wMaxPacketSize != 0x40)
2175       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
2176 	  0x00))
2177     {
2178       if (verbose > 2)
2179 	printf
2180 	  ("    this is not a PV8630/LM9830 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2181 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2182 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2183 	   bEndpointAddress,
2184 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
2185 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2186 	   wMaxPacketSize,
2187 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
2188       return 0;
2189     }
2190   /* Endpoint 1 */
2191   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
2192        bEndpointAddress != 0x82)
2193       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2194 	  bmAttributes != 0x02)
2195       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2196 	  wMaxPacketSize != 0x40)
2197       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
2198 	  0x00))
2199     {
2200       if (verbose > 2)
2201 	printf
2202 	  ("    this is not a PV8630/LM9830 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2203 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2204 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2205 	   bEndpointAddress,
2206 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
2207 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2208 	   wMaxPacketSize,
2209 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
2210       return 0;
2211     }
2212   /* Endpoint 2 */
2213   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
2214        bEndpointAddress != 0x83)
2215       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2216 	  bmAttributes != 0x03)
2217       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2218 	  wMaxPacketSize != 0x01)
2219       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
2220 	  0x01))
2221     {
2222       if (verbose > 2)
2223 	printf
2224 	  ("    this is not a PV8630/LM9830 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2225 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2226 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2227 	   bEndpointAddress,
2228 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
2229 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2230 	   wMaxPacketSize,
2231 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
2232       return 0;
2233     }
2234 
2235   /* Now we write/read a register (red offset) */
2236   result = prepare_interface (dev, &handle);
2237   if (!result)
2238     return "PV8630/LM9830?";
2239 
2240   result =
2241     usb_control_msg (handle, 0x40, 0x01, 0x38, 0x01, NULL, 0, TIMEOUT);
2242   if (result < 0)
2243     {
2244       if (verbose > 2)
2245 	printf ("    Couldn't send write register number (%s)\n",
2246 		usb_strerror ());
2247       finish_interface (handle);
2248       return 0;
2249     }
2250 
2251   result =
2252     usb_control_msg (handle, 0x40, 0x01, 0x0f, 0x00,  NULL, 0, TIMEOUT);
2253   if (result < 0)
2254     {
2255       if (verbose > 2)
2256 	printf ("    Couldn't send register data (%s)\n",
2257 		usb_strerror ());
2258       finish_interface (handle);
2259       return 0;
2260     }
2261 
2262   result =
2263     usb_control_msg (handle, 0x40, 0x01, 0x38, 0x01, NULL, 0, TIMEOUT);
2264   if (result < 0)
2265     {
2266       if (verbose > 2)
2267 	printf ("    Couldn't send read register number (%s)\n",
2268 		usb_strerror ());
2269       finish_interface (handle);
2270       return 0;
2271     }
2272 
2273   result =
2274     usb_control_msg (handle, 0xc0, 0x00, 0, 0x00, &data, 1, TIMEOUT);
2275   if (result <= 0)
2276     {
2277       if (verbose > 2)
2278 	printf ("    Couldn't read register data (%s)\n",
2279 		usb_strerror ());
2280       finish_interface (handle);
2281       return 0;
2282     }
2283 
2284   if (data != 0x0f)
2285     {
2286       if (verbose > 2)
2287 	printf ("    Data read != data written (%d/%d)\n", data, 0x0f);
2288       finish_interface (handle);
2289       return 0;
2290     }
2291 
2292   finish_interface (handle);
2293   return "PV8630/LM9830";
2294 }
2295 
2296 
2297 /* Check for Toshiba M011 */
2298 static char *
check_m011(struct usb_device * dev)2299 check_m011 (struct usb_device *dev)
2300 {
2301   usb_dev_handle *handle;
2302   int result;
2303   char data;
2304 
2305   if (verbose > 2)
2306     printf ("    checking for M011 ...\n");
2307 
2308   /* Check device descriptor */
2309   if (dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC)
2310     {
2311       if (verbose > 2)
2312 	printf ("    this is not a M011 (bDeviceClass = %d)\n",
2313 		dev->descriptor.bDeviceClass);
2314       return 0;
2315     }
2316   if (dev->descriptor.bcdUSB != 0x100)
2317     {
2318       if (verbose > 2)
2319 	printf ("    this is not a M011 (bcdUSB = 0x%x)\n",
2320 		dev->descriptor.bcdUSB);
2321       return 0;
2322     }
2323   if (dev->descriptor.bDeviceSubClass != USB_CLASS_VENDOR_SPEC)
2324     {
2325       if (verbose > 2)
2326 	printf ("    this is not a M011 (bDeviceSubClass = 0x%x)\n",
2327 		dev->descriptor.bDeviceSubClass);
2328       return 0;
2329     }
2330   if (dev->descriptor.bDeviceProtocol != USB_CLASS_VENDOR_SPEC)
2331     {
2332       if (verbose > 2)
2333 	printf ("    this is not a M011 (bDeviceProtocol = 0x%x)\n",
2334 		dev->descriptor.bDeviceProtocol);
2335       return 0;
2336     }
2337 
2338   /* Check endpoints */
2339   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 1)
2340     {
2341       if (verbose > 2)
2342 	printf ("    this is not a M011 (bNumEndpoints = %d)\n",
2343 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
2344       return 0;
2345     }
2346   /* Endpoint 0 */
2347   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
2348        bEndpointAddress != 0x82)
2349       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2350 	  bmAttributes != 0x02)
2351       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2352 	  wMaxPacketSize != 0x40)
2353       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
2354 	  0x00))
2355     {
2356       if (verbose > 2)
2357 	printf
2358 	  ("    this is not a M011 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2359 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2360 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2361 	   bEndpointAddress,
2362 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
2363 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2364 	   wMaxPacketSize,
2365 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
2366       return 0;
2367     }
2368 
2369   /* Now we write/read a register (red offset) */
2370   result = prepare_interface (dev, &handle);
2371   if (!result)
2372     return "M011?";
2373 
2374   data = 0x63;
2375 
2376   result =
2377     usb_control_msg (handle, 0x40, 0x08, 0x34, 0x00, &data, 1, TIMEOUT);
2378   if (result < 0)
2379     {
2380       if (verbose > 2)
2381 	printf ("    Couldn't write register (%s)\n",
2382 		usb_strerror ());
2383       finish_interface (handle);
2384       return 0;
2385     }
2386   data = 0;
2387 
2388   result =
2389     usb_control_msg (handle, 0xc0, 0x00, 0x34, 0x00, &data, 1, TIMEOUT);
2390   if (result <= 0)
2391     {
2392       if (verbose > 2)
2393 	printf ("    Couldn't read register (%s)\n",
2394 		usb_strerror ());
2395       finish_interface (handle);
2396       return 0;
2397     }
2398 
2399   if (data != 0x63)
2400     {
2401       if (verbose > 2)
2402 	printf ("    Data read != data written (%d/%d)\n", data, 0x63);
2403       finish_interface (handle);
2404       return 0;
2405     }
2406 
2407   finish_interface (handle);
2408   return "M011";
2409 }
2410 
2411 
2412 /* Check for Realtek rts88xx */
2413 static int
rts88xx_read_reg(usb_dev_handle * handle,unsigned char * req,unsigned char * res,int size)2414 rts88xx_read_reg (usb_dev_handle * handle, unsigned char *req, unsigned char *res, int size)
2415 {
2416   int result;
2417 
2418   result =
2419     usb_bulk_write (handle, 0x02, (char *)req, 0x04, TIMEOUT);
2420   if (result < 0)
2421     return 0;
2422 
2423   result =
2424     usb_bulk_read (handle,  0x81, (char *)res, size, TIMEOUT);
2425   if (result < 0)
2426     return 0;
2427 
2428   return 1;
2429 }
2430 
2431 static char *
check_rts8858c(struct usb_device * dev)2432 check_rts8858c (struct usb_device *dev)
2433 {
2434   unsigned char req[4];
2435   unsigned char res[10];
2436   usb_dev_handle *handle;
2437   int result;
2438 
2439   if (verbose > 2)
2440     printf ("    checking for rts8858c ...\n");
2441 
2442   /* Check device descriptor */
2443   if (dev->descriptor.bDeviceClass != 0)
2444     {
2445       if (verbose > 2)
2446 	printf ("    this is not a rts8858c (bDeviceClass = %d)\n",
2447 		dev->descriptor.bDeviceClass);
2448       return 0;
2449     }
2450   if (dev->descriptor.bcdUSB != 0x110)
2451     {
2452       if (verbose > 2)
2453 	printf ("    this is not a rts8858c (bcdUSB = 0x%x)\n",
2454 		dev->descriptor.bcdUSB);
2455       return 0;
2456     }
2457   if (dev->descriptor.bDeviceSubClass != 0)
2458     {
2459       if (verbose > 2)
2460 	printf ("    this is not a rts8858c (bDeviceSubClass = 0x%x)\n",
2461 		dev->descriptor.bDeviceSubClass);
2462       return 0;
2463     }
2464   if (dev->descriptor.bDeviceProtocol != 0)
2465     {
2466       if (verbose > 2)
2467 	printf ("    this is not a rts8858c (bDeviceProtocol = 0x%x)\n",
2468 		dev->descriptor.bDeviceProtocol);
2469       return 0;
2470     }
2471 
2472   /* Check endpoints */
2473   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
2474     {
2475       if (verbose > 2)
2476 	printf ("    this is not a rts8858c (bNumEndpoints = %d)\n",
2477 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
2478       return 0;
2479     }
2480   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
2481        bEndpointAddress != 0x81)
2482       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2483 	  bmAttributes != 0x02)
2484       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2485 	  wMaxPacketSize != 0x40)
2486       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
2487 	  0x00))
2488     {
2489       if (verbose > 2)
2490 	printf
2491 	  ("    this is not a rts8858c (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2492 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2493 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2494 	   bEndpointAddress,
2495 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
2496 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2497 	   wMaxPacketSize,
2498 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
2499       return 0;
2500     }
2501 
2502   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
2503        bEndpointAddress != 0x02)
2504       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2505 	  bmAttributes != 0x02)
2506       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2507 	  wMaxPacketSize != 0x08)
2508       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
2509 	  0x00))
2510     {
2511       if (verbose > 2)
2512 	printf
2513 	  ("    this is not a rts8858c (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2514 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2515 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2516 	   bEndpointAddress,
2517 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
2518 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2519 	   wMaxPacketSize,
2520 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
2521       return 0;
2522     }
2523 
2524   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
2525        bEndpointAddress != 0x83)
2526       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2527 	  bmAttributes != 0x03)
2528       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2529 	  wMaxPacketSize != 0x01)
2530       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
2531 	  0xFA))
2532     {
2533       if (verbose > 2)
2534 	printf
2535 	  ("    this is not a rts8858c (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2536 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2537 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2538 	   bEndpointAddress,
2539 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
2540 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2541 	   wMaxPacketSize,
2542 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
2543       return 0;
2544     }
2545 
2546   /* Now we read 10 registers */
2547   result = prepare_interface (dev, &handle);
2548   if (!result)
2549     return "rts8858c?";
2550 
2551   memset (req, 0, 4);
2552   req[0] = 0x80;		/* get registers 0x12-0x1c */
2553   req[1] = 0x12;
2554   req[2] = 0x00;
2555   req[3] = 0x0a;
2556 
2557   result = rts88xx_read_reg(handle,req,res,req[3]);
2558   if (result <= 0)
2559     {
2560       if (verbose > 2)
2561 	printf ("    Couldn't read registers\n");
2562       finish_interface (handle);
2563       return 0;
2564     }
2565 
2566   if (res[1] != 0x03 || res[2] != 0x00)
2567     {
2568       if (verbose > 2)
2569 	printf ("    Unexpected result from register reading (0x%0x/0x%0x)\n",
2570 		res[1], res[2]);
2571       finish_interface (handle);
2572       return 0;
2573     }
2574   finish_interface (handle);
2575   return "rts8858c";
2576 }	/* end of rts8858 detection */
2577 
2578 static char *
check_rts88x1(struct usb_device * dev)2579 check_rts88x1 (struct usb_device *dev)
2580 {
2581   unsigned char req[4];
2582   unsigned char res[243];
2583   usb_dev_handle *handle;
2584   int result;
2585 
2586   if (verbose > 2)
2587     printf ("    checking for rts8801/rts8891 ...\n");
2588 
2589   /* Check device descriptor */
2590   if (dev->descriptor.bDeviceClass != 0)
2591     {
2592       if (verbose > 2)
2593 	printf ("    this is not a rts8801/rts8891 (bDeviceClass = %d)\n",
2594 		dev->descriptor.bDeviceClass);
2595       return 0;
2596     }
2597   if (dev->descriptor.bcdUSB != 0x110)
2598     {
2599       if (verbose > 2)
2600 	printf ("    this is not a rts8801/rts8891 (bcdUSB = 0x%x)\n",
2601 		dev->descriptor.bcdUSB);
2602       return 0;
2603     }
2604   if (dev->descriptor.bDeviceSubClass != 0)
2605     {
2606       if (verbose > 2)
2607 	printf ("    this is not a rts8801/rts8891 (bDeviceSubClass = 0x%x)\n",
2608 		dev->descriptor.bDeviceSubClass);
2609       return 0;
2610     }
2611   if (dev->descriptor.bDeviceProtocol != 0)
2612     {
2613       if (verbose > 2)
2614 	printf ("    this is not a rts8801/rts8891 (bDeviceProtocol = 0x%x)\n",
2615 		dev->descriptor.bDeviceProtocol);
2616       return 0;
2617     }
2618 
2619   /* Check endpoints */
2620   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
2621     {
2622       if (verbose > 2)
2623 	printf ("    this is not a rts8801/rts8891 (bNumEndpoints = %d)\n",
2624 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
2625       return 0;
2626     }
2627   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
2628        bEndpointAddress != 0x81)
2629       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2630 	  bmAttributes != 0x02)
2631       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2632 	  wMaxPacketSize != 0x40)
2633       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
2634 	  0x00))
2635     {
2636       if (verbose > 2)
2637 	printf
2638 	  ("    this is not a rts8801/rts8891 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2639 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2640 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2641 	   bEndpointAddress,
2642 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
2643 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2644 	   wMaxPacketSize,
2645 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
2646       return 0;
2647     }
2648 
2649   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
2650        bEndpointAddress != 0x02)
2651       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2652 	  bmAttributes != 0x02)
2653       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2654 	  wMaxPacketSize != 0x08)
2655       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
2656 	  0x00))
2657     {
2658       if (verbose > 2)
2659 	printf
2660 	  ("    this is not a rts8801/rts8891 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2661 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2662 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2663 	   bEndpointAddress,
2664 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
2665 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2666 	   wMaxPacketSize,
2667 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
2668       return 0;
2669     }
2670 
2671   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
2672        bEndpointAddress != 0x83)
2673       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2674 	  bmAttributes != 0x03)
2675       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2676 	  wMaxPacketSize != 0x01)
2677       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
2678 	  0xFA))
2679     {
2680       if (verbose > 2)
2681 	printf
2682 	  ("    this is not a rts8801/rts8891 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2683 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2684 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2685 	   bEndpointAddress,
2686 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
2687 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2688 	   wMaxPacketSize,
2689 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
2690       return 0;
2691     }
2692 
2693   /* Now we read 10 registers */
2694   result = prepare_interface (dev, &handle);
2695   if (!result)
2696     return "rts8801/rts8891?";
2697 
2698   memset (req, 0, 4);
2699   req[0] = 0x80;		/* get registers 0x00-0xF2 */
2700   req[1] = 0x00;
2701   req[2] = 0x00;
2702   req[3] = 0xf3;
2703 
2704   result = rts88xx_read_reg(handle,req,res,req[3]);
2705   if (result <= 0)
2706     {
2707       if (verbose > 2)
2708 	printf ("    Couldn't read registers\n");
2709       finish_interface (handle);
2710       return 0;
2711     }
2712 
2713   /* test CCD and link registers */
2714   if (res[0xb0] != 0x80 || ((res[0] & 0x0f)!=0x05))
2715     {
2716       if (verbose > 2)
2717 	printf ("    Unexpected result from register reading (0x%0x/0x%0x)\n",
2718 		res[0xb0], res[2]);
2719       finish_interface (handle);
2720       return 0;
2721     }
2722   finish_interface (handle);
2723   return "rts8801/rts8891";
2724 }	/* end of rts8801/rts8891 detection */
2725 
2726 
2727 /* Check for Service & Quality SQ113 */
2728 static char *
check_sq113(struct usb_device * dev)2729 check_sq113 (struct usb_device *dev)
2730 {
2731   usb_dev_handle *handle;
2732   int result;
2733   unsigned char data;
2734   unsigned char buffer[4];
2735 
2736   if (verbose > 2)
2737     printf ("    checking for SQ113 ...\n");
2738 
2739   /* Check device descriptor */
2740   if (dev->descriptor.bDeviceClass != 0)
2741     {
2742       if (verbose > 2)
2743 	printf ("    this is not a SQ113 (bDeviceClass = %d)\n",
2744 		dev->descriptor.bDeviceClass);
2745       return 0;
2746     }
2747   if (dev->descriptor.bcdUSB != 0x200)
2748     {
2749       if (verbose > 2)
2750 	printf ("    this is not a SQ113 (bcdUSB = 0x%x)\n",
2751 		dev->descriptor.bcdUSB);
2752       return 0;
2753     }
2754   if (dev->descriptor.bDeviceSubClass != 0)
2755     {
2756       if (verbose > 2)
2757 	printf ("    this is not a SQ113 (bDeviceSubClass = 0x%x)\n",
2758 		dev->descriptor.bDeviceSubClass);
2759       return 0;
2760     }
2761   if (dev->descriptor.bDeviceProtocol != 0)
2762     {
2763       if (verbose > 2)
2764 	printf ("    this is not a SQ113 (bDeviceProtocol = 0x%x)\n",
2765 		dev->descriptor.bDeviceProtocol);
2766       return 0;
2767     }
2768 
2769   /* Check interface */
2770   if (dev->config[0].interface[0].altsetting[0].bInterfaceClass != 255)
2771     {
2772       if (verbose > 2)
2773 	printf ("    this is not a SQ113 (bInterfaceClass = %d)\n",
2774 		dev->config[0].interface[0].altsetting[0].bInterfaceClass);
2775       return 0;
2776     }
2777 
2778   if (dev->config[0].interface[0].altsetting[0].bInterfaceSubClass != 255)
2779     {
2780       if (verbose > 2)
2781 	printf ("    this is not a SQ113 (bInterfaceSubClass = %d)\n",
2782 		dev->config[0].interface[0].altsetting[0].bInterfaceSubClass);
2783       return 0;
2784     }
2785   if (dev->config[0].interface[0].altsetting[0].bInterfaceProtocol != 255)
2786     {
2787       if (verbose > 2)
2788 	printf ("    this is not a SQ113 (bInterfaceProtocol = %d)\n",
2789 		dev->config[0].interface[0].altsetting[0].bInterfaceProtocol);
2790       return 0;
2791     }
2792 
2793   /* Check endpoints */
2794   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
2795     {
2796       if (verbose > 2)
2797 	printf ("    this is not a SQ113 (bNumEndpoints = %d)\n",
2798 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
2799       return 0;
2800     }
2801   /* Endpoint 0 */
2802   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
2803        bEndpointAddress != 0x01)
2804       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
2805 	  bmAttributes != 0x02)
2806       || ((dev->config[0].interface[0].altsetting[0].endpoint[0].
2807 	  wMaxPacketSize != 0x40)
2808 	  && (dev->config[0].interface[0].altsetting[0].endpoint[0].
2809 	      wMaxPacketSize != 0x200))
2810       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
2811 	  0x00))
2812     {
2813       if (verbose > 2)
2814 	printf
2815 	  ("    this is not a SQ113 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2816 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2817 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2818 	   bEndpointAddress,
2819 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
2820 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
2821 	   wMaxPacketSize,
2822 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
2823       return 0;
2824     }
2825 
2826   /* Endpoint 1 */
2827   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
2828        bEndpointAddress != 0x82)
2829       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
2830 	  bmAttributes != 0x02)
2831       || ((dev->config[0].interface[0].altsetting[0].endpoint[1].
2832 	  wMaxPacketSize != 0x40)
2833 	  && (dev->config[0].interface[0].altsetting[0].endpoint[1].
2834 	      wMaxPacketSize != 0x200))
2835       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
2836 	  0x00))
2837     {
2838       if (verbose > 2)
2839 	printf
2840 	  ("    this is not a SQ113 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2841 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2842 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2843 	   bEndpointAddress,
2844 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
2845 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
2846 	   wMaxPacketSize,
2847 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
2848       return 0;
2849     }
2850   /* Endpoint 2 */
2851   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
2852        bEndpointAddress != 0x83)
2853       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2854 	  bmAttributes != 0x03)
2855       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
2856 	  wMaxPacketSize != 0x1)
2857       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
2858 	  0x03))
2859     {
2860       if (verbose > 2)
2861 	printf
2862 	  ("    this is not a SQ113 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
2863 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
2864 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2865 	   bEndpointAddress,
2866 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
2867 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
2868 	   wMaxPacketSize,
2869 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
2870       return 0;
2871     }
2872 
2873   /* Now we read the status register */
2874   result = prepare_interface (dev, &handle);
2875   if (!result)
2876     return "SQ113?";
2877 
2878   buffer [0] = 0x5f;
2879   buffer [1] = 0x00;
2880   buffer [2] = 0x5f;
2881   buffer [3] = 0x00;
2882 
2883   result =
2884     usb_control_msg (handle, 0x40, 0x01, 0xb0, 0, (char *) buffer, 4, TIMEOUT);
2885   if (result < 0)
2886     {
2887       if (verbose > 2)
2888 	printf ("    Couldn't set bank (%s)\n",
2889 		usb_strerror ());
2890       finish_interface (handle);
2891       return 0;
2892     }
2893 
2894   data = 0x00;
2895 
2896   buffer [0] = 0x8b;
2897   buffer [1] = data;
2898   buffer [2] = 0x8b;
2899   buffer [3] = data;
2900 
2901   result =
2902     usb_control_msg (handle, 0x40, 0x01, 0xb0, 0, (char *) buffer, 4, TIMEOUT);
2903   if (result < 0)
2904     {
2905       if (verbose > 2)
2906 	printf ("    Couldn't write register (%s)\n",
2907 		usb_strerror ());
2908       finish_interface (handle);
2909       return 0;
2910     }
2911 
2912   buffer [0] = 0x8b;
2913   buffer [1] = 0x8b;
2914   buffer [2] = 0x8b;
2915   buffer [3] = 0x8b;
2916   result =
2917     usb_control_msg (handle, 0x40, 0x01, 0x04, 0x8b, (char *) buffer, 4, TIMEOUT);
2918   if (result < 0)
2919     {
2920       if (verbose > 2)
2921 	printf ("    Couldn't set read register address (%s)\n",
2922 		usb_strerror ());
2923       finish_interface (handle);
2924       return 0;
2925     }
2926 
2927   result =
2928     usb_control_msg (handle, 0xc0, 0x01, 0x07, 0, (char *) buffer, 4, TIMEOUT);
2929   if (result < 0)
2930     {
2931       if (verbose > 2)
2932 	printf ("    Couldn't read register (%s)\n",
2933 		usb_strerror ());
2934       finish_interface (handle);
2935       return 0;
2936     }
2937 
2938   if ((buffer[0] & 0x10) != 0x10)
2939     {
2940       if (verbose > 2)
2941 	printf ("    Sensor not home? (0x%02x)\n", buffer[0]);
2942       finish_interface (handle);
2943       return 0;
2944     }
2945 
2946   finish_interface (handle);
2947   return "SQ113";
2948 }
2949 
2950 /* Check for Realtek RTS8822 chipset*/
2951 static char *
check_rts8822(struct usb_device * dev)2952 check_rts8822 (struct usb_device *dev)
2953 {
2954   char data[2];
2955   usb_dev_handle *handle;
2956   int result;
2957 
2958   if (verbose > 2)
2959     printf ("    checking for RTS8822 ...\n");
2960 
2961   /* Check device descriptor */
2962   if (dev->descriptor.bDeviceClass != 0)
2963     {
2964       if (verbose > 2)
2965 	printf ("    this is not a RTS8822 (bDeviceClass = %d)\n",
2966 		dev->descriptor.bDeviceClass);
2967       return 0;
2968     }
2969   if ((dev->descriptor.bcdUSB != 0x200)&&(dev->descriptor.bcdUSB != 0x110))
2970     {
2971       if (verbose > 2)
2972 	printf ("    this is not a RTS8822 (bcdUSB = 0x%x)\n",
2973 		dev->descriptor.bcdUSB);
2974       return 0;
2975     }
2976   if (dev->descriptor.bDeviceSubClass != 0)
2977     {
2978       if (verbose > 2)
2979 	printf ("    this is not a RTS8822 (bDeviceSubClass = 0x%x)\n",
2980 		dev->descriptor.bDeviceSubClass);
2981       return 0;
2982     }
2983   if (dev->descriptor.bDeviceProtocol != 0)
2984     {
2985       if (verbose > 2)
2986 	printf ("    this is not a RTS8822 (bDeviceProtocol = 0x%x)\n",
2987 		dev->descriptor.bDeviceProtocol);
2988       return 0;
2989     }
2990 
2991   /* Check endpoints */
2992   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
2993     {
2994       if (verbose > 2)
2995 	printf ("    this is not a RTS8822 (bNumEndpoints = %d)\n",
2996 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
2997       return 0;
2998     }
2999   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
3000        bEndpointAddress != 0x81)
3001       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
3002 	  bmAttributes != 0x02)
3003       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
3004 	  wMaxPacketSize != 0x200)
3005       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
3006 	  0x00))
3007     {
3008       if (verbose > 2)
3009 	printf
3010 	  ("    this is not a RTS8822 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3011 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3012 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
3013 	   bEndpointAddress,
3014 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
3015 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
3016 	   wMaxPacketSize,
3017 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
3018       return 0;
3019     }
3020 
3021   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
3022        bEndpointAddress != 0x02)
3023       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
3024 	  bmAttributes != 0x02)
3025       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
3026 	  wMaxPacketSize != 0x200)
3027       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
3028 	  0x00))
3029     {
3030       if (verbose > 2)
3031 	printf
3032 	  ("    this is not a RTS8822 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3033 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3034 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
3035 	   bEndpointAddress,
3036 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
3037 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
3038 	   wMaxPacketSize,
3039 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
3040       return 0;
3041     }
3042 
3043   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
3044        bEndpointAddress != 0x83)
3045       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
3046 	  bmAttributes != 0x03)
3047       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
3048 	  wMaxPacketSize != 0x01)
3049       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
3050 	  0x0c))
3051     {
3052       if (verbose > 2)
3053 	printf
3054 	  ("    this is not a RTS8822 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3055 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3056 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
3057 	   bEndpointAddress,
3058 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
3059 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
3060 	   wMaxPacketSize,
3061 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
3062       return 0;
3063     }
3064 
3065   /* Now we read 1 register */
3066   result = prepare_interface (dev, &handle);
3067   if (!result)
3068     return "RTS8822?";
3069 
3070   memset (data, 0, 2);
3071 
3072   result =
3073     usb_control_msg(handle, 0xc0, 0x04, 0xfe11, 0x100, data, 0x02, TIMEOUT);
3074 
3075   if (result <= 0)
3076     {
3077       if (verbose > 2)
3078 	printf ("    Couldn't send read control message (%s)\n",
3079 		strerror (errno));
3080       finish_interface (handle);
3081       return 0;
3082     }
3083 
3084   if ((data[0] == 0)&&(data[1] == 0))
3085     {
3086       if (verbose > 2)
3087 	printf ("    Unexpected result from register 0xfe11 : 0x%0x%0x\n",
3088 		data[1], data[0]);
3089       finish_interface (handle);
3090       return 0;
3091     }
3092   finish_interface (handle);
3093   return "RTS8822";
3094 }	/* end of RTS8822 detection */
3095 
3096 /* Check for Silitek chipset found in HP ScanJet 4500C/4570C/5500C/5550C/5590/7650 scanners */
3097 static char *
check_hp5590(struct usb_device * dev)3098 check_hp5590 (struct usb_device *dev)
3099 {
3100   usb_dev_handle	*handle;
3101   int			result;
3102   uint8_t		status;
3103   struct usb_ctrl_setup ctrl;
3104   uint8_t		data[0x32];
3105   uint8_t		ack;
3106   uint8_t		*ptr;
3107   int			next_packet_size;
3108   unsigned int		len;
3109 #define HP5590_NAMES	"HP4500C/4570C/5500C/5550C/5590/7650"
3110 
3111   if (verbose > 2)
3112     printf ("    checking for " HP5590_NAMES " chipset ...\n");
3113 
3114   /* Check device descriptor */
3115   if (dev->descriptor.bDeviceClass != 0xff)
3116     {
3117       if (verbose > 2)
3118 	printf ("    this is not a " HP5590_NAMES " chipset (bDeviceClass = %d)\n",
3119 		dev->descriptor.bDeviceClass);
3120       return 0;
3121     }
3122   if (dev->descriptor.bcdUSB != 0x200)
3123     {
3124       if (verbose > 2)
3125 	printf ("    this is not a " HP5590_NAMES " chipset (bcdUSB = 0x%x)\n",
3126 		dev->descriptor.bcdUSB);
3127       return 0;
3128     }
3129   if (dev->descriptor.bDeviceSubClass != 0xff)
3130     {
3131       if (verbose > 2)
3132 	printf ("    this is not a " HP5590_NAMES " chipset (bDeviceSubClass = 0x%x)\n",
3133 		dev->descriptor.bDeviceSubClass);
3134       return 0;
3135     }
3136   if (dev->descriptor.bDeviceProtocol != 0xff)
3137     {
3138       if (verbose > 2)
3139 	printf ("    this is not a " HP5590_NAMES " chipset (bDeviceProtocol = 0x%x)\n",
3140 		dev->descriptor.bDeviceProtocol);
3141       return 0;
3142     }
3143 
3144   /* Check endpoints */
3145   if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3)
3146     {
3147       if (verbose > 2)
3148 	printf ("    this is not a " HP5590_NAMES " chipset (bNumEndpoints = %d)\n",
3149 		dev->config[0].interface[0].altsetting[0].bNumEndpoints);
3150       return 0;
3151     }
3152   if ((dev->config[0].interface[0].altsetting[0].endpoint[0].
3153        bEndpointAddress != 0x81)
3154       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
3155 	  bmAttributes != 0x02)
3156       || (dev->config[0].interface[0].altsetting[0].endpoint[0].
3157 	  wMaxPacketSize != 0x200)
3158       || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval !=
3159 	  0x00))
3160     {
3161       if (verbose > 2)
3162 	printf
3163 	  ("    this is not a " HP5590_NAMES " chipset (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3164 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3165 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
3166 	   bEndpointAddress,
3167 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes,
3168 	   dev->config[0].interface[0].altsetting[0].endpoint[0].
3169 	   wMaxPacketSize,
3170 	   dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval);
3171       return 0;
3172     }
3173 
3174   if ((dev->config[0].interface[0].altsetting[0].endpoint[1].
3175        bEndpointAddress != 0x02)
3176       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
3177 	  bmAttributes != 0x02)
3178       || (dev->config[0].interface[0].altsetting[0].endpoint[1].
3179 	  wMaxPacketSize != 0x200)
3180       || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval !=
3181 	  0x00))
3182     {
3183       if (verbose > 2)
3184 	printf
3185 	  ("    this is not a " HP5590_NAMES " chipset (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3186 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3187 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
3188 	   bEndpointAddress,
3189 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes,
3190 	   dev->config[0].interface[0].altsetting[0].endpoint[1].
3191 	   wMaxPacketSize,
3192 	   dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval);
3193       return 0;
3194     }
3195 
3196   if ((dev->config[0].interface[0].altsetting[0].endpoint[2].
3197        bEndpointAddress != 0x83)
3198       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
3199 	  bmAttributes != 0x03)
3200       || (dev->config[0].interface[0].altsetting[0].endpoint[2].
3201 	  wMaxPacketSize != 0x01)
3202       || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval !=
3203 	  0x08))
3204     {
3205       if (verbose > 2)
3206 	printf
3207 	  ("    this is not a " HP5590_NAMES " chipset (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3208 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3209 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
3210 	   bEndpointAddress,
3211 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes,
3212 	   dev->config[0].interface[0].altsetting[0].endpoint[2].
3213 	   wMaxPacketSize,
3214 	   dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval);
3215       return 0;
3216     }
3217 
3218   result = prepare_interface (dev, &handle);
3219   if (!result)
3220     return NULL;
3221 
3222   /* USB-in-USB command URB - command 0x0012 (init scanner), returns 0x32 bytes */
3223   memset (&ctrl, 0, sizeof(ctrl));
3224   ctrl.bRequestType = 0xc0;
3225   ctrl.bRequest = 0x04;
3226   ctrl.wValue = 0x1200;
3227   ctrl.wIndex = 0x00;
3228   ctrl.wLength = sizeof(data);
3229   result = usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR,
3230 			    0x04, 0x8f, 0x00,
3231 			    (char *) &ctrl, sizeof (ctrl), TIMEOUT);
3232   if (result < 0)
3233     {
3234       if (verbose > 2)
3235 	printf ("    Couldn't send send USB-in-USB command (%s)\n",
3236 		strerror (errno));
3237       return NULL;
3238     }
3239 
3240   /* Get confirmation for USB-in-USB command */
3241   result = usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR,
3242 			    0x0c, 0x8e, 0x20,
3243 			    (char *) &status, sizeof(status), TIMEOUT);
3244   if (result < 0)
3245     {
3246       if (verbose > 2)
3247 	printf ("    Couldn't read USB-in-USB confirmation (%s)\n",
3248 		strerror (errno));
3249       finish_interface (handle);
3250       return NULL;
3251     }
3252 
3253   /* Check the confirmation received */
3254   if (status != 0x01)
3255     {
3256       if (verbose > 2)
3257 	printf ("    Didn't get correct confirmation for USB-in-USB command "
3258 		"(needed: 0x01, got: 0x%02x\n",
3259 		status);
3260       finish_interface (handle);
3261       return NULL;
3262     }
3263 
3264   /* Read data in 8 byte packets */
3265   ptr = data;
3266   len = sizeof(data);
3267   while (len)
3268     {
3269       next_packet_size = 8;
3270       if (len < 8)
3271 	next_packet_size = len;
3272 
3273       /* Read data packet */
3274       result = usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR,
3275 				0x04, 0x90, 0x00,
3276 				(char *) ptr, next_packet_size, TIMEOUT);
3277       if (result < 0)
3278 	{
3279 	  if (verbose > 2)
3280 	    printf ("    Couldn't read USB-in-USB data (%s)\n",
3281 		    strerror (errno));
3282 	  finish_interface (handle);
3283 	  return NULL;
3284 	}
3285 
3286       /* Check if all of the requested data was received */
3287       if (result != next_packet_size)
3288 	{
3289 	  if (verbose > 2)
3290 	    printf ("    Incomplete USB-in-USB data received (needed: %u, got: %u)\n",
3291 		    next_packet_size, result);
3292 	  finish_interface (handle);
3293 	  return NULL;
3294 	}
3295 
3296       ptr += next_packet_size;
3297       len -= next_packet_size;
3298     }
3299 
3300   /* Acknowledge the whole received data */
3301   ack = 0;
3302   result = usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR,
3303 			    0x0c, 0x8f, 0x00,
3304 			    (char *) &ack, sizeof(ack), TIMEOUT);
3305   if (result < 0)
3306     {
3307       if (verbose > 2)
3308 	printf ("    Couldn't send USB-in-USB data confirmation (%s)\n",
3309 		strerror (errno));
3310       finish_interface (handle);
3311       return NULL;
3312     }
3313 
3314   /* Get confirmation for acknowledge */
3315   result = usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR,
3316 			    0x0c, 0x8e, 0x20,
3317 			    (char *) &status, sizeof(status), TIMEOUT);
3318   if (result < 0)
3319     {
3320       if (verbose > 2)
3321 	printf ("    Couldn't read USB-in-USB confirmation for data confirmation (%s)\n",
3322 		strerror (errno));
3323       finish_interface (handle);
3324       return NULL;
3325     }
3326 
3327   /* Check the confirmation received */
3328   if (status != 0x01)
3329     {
3330       if (verbose > 2)
3331 	printf ("    Didn't get correct confirmation for USB-in-USB command "
3332 		"(needed: 0x01, got: 0x%02x\n",
3333 		status);
3334       finish_interface (handle);
3335       return NULL;
3336     }
3337 
3338   /* Check vendor ID */
3339   if (memcmp (data+1, "SILITEK", 7) != 0)
3340     {
3341       if (verbose > 2)
3342 	printf ("   Incorrect product ID received\n");
3343       finish_interface (handle);
3344       return NULL;
3345     }
3346 
3347   finish_interface (handle);
3348   return HP5590_NAMES;
3349 }
3350 
3351 char *
check_usb_chip(struct usb_device * dev,int verbosity,SANE_Bool from_file)3352 check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file)
3353 {
3354   char *chip_name = 0;
3355 
3356   verbose = verbosity;
3357   no_chipset_access = from_file;
3358 
3359   if (verbose > 2)
3360     printf ("\n<trying to find out which USB chip is used>\n");
3361 
3362   chip_name = check_gt6801 (dev);
3363 
3364   if (!chip_name)
3365     chip_name = check_gt6816 (dev);
3366 
3367   if (!chip_name)
3368     chip_name = check_gt8911 (dev);
3369 
3370   if (!chip_name)
3371     chip_name = check_ma1017 (dev);
3372 
3373   if (!chip_name)
3374     chip_name = check_ma1015 (dev);
3375 
3376   if (!chip_name)
3377     chip_name = check_ma1509 (dev);
3378 
3379   if (!chip_name)
3380     chip_name = check_merlin (dev);
3381 
3382   if (!chip_name)
3383     chip_name = check_gl646 (dev);
3384 
3385   if (!chip_name)
3386     chip_name = check_gl646_hp (dev);
3387 
3388   if (!chip_name)
3389     chip_name = check_gl660_gl646 (dev);
3390 
3391   if (!chip_name)
3392     chip_name = check_gl841 (dev);
3393 
3394   if (!chip_name)
3395     chip_name = check_icm532b (dev);
3396 
3397   if (!chip_name)
3398     chip_name = check_pv8630_lm9830 (dev);
3399 
3400   if (!chip_name)
3401     chip_name = check_m011 (dev);
3402 
3403   if (!chip_name)
3404     chip_name = check_rts8822 (dev);
3405 
3406   if (!chip_name)
3407     chip_name = check_rts8858c (dev);
3408 
3409   if (!chip_name)
3410     chip_name = check_sq113 (dev);
3411 
3412   if (!chip_name)
3413     chip_name = check_hp5590 (dev);
3414 
3415   if (!chip_name)
3416     chip_name = check_rts88x1 (dev);
3417 
3418   if (verbose > 2)
3419     {
3420       if (chip_name)
3421 	printf ("<This USB chip looks like a %s (result from %s)>\n\n",
3422 		chip_name, PACKAGE_STRING);
3423       else
3424 	printf ("<Couldn't determine the type of the USB chip (result from %s)>\n\n",
3425 		PACKAGE_STRING);
3426     }
3427 
3428   return chip_name;
3429 }
3430 
3431 #endif /* HAVE_LIBUSB_LEGACY */
3432 
3433 #ifdef HAVE_LIBUSB
3434 
3435 #include <libusb.h>
3436 
3437 #include "../include/sane/sane.h"
3438 #include <stdio.h>
3439 #include <string.h>
3440 #include <errno.h>
3441 
3442 #include "../include/_stdint.h"
3443 
3444 #define TIMEOUT 1000
3445 
3446 
3447 /** @brief detect used chip
3448  *
3449  * Try to detect the chip used by a device that looks like a scanner by
3450  * trying some basic operation like reading/writing registers.
3451  * @param dev libusb_device to probe
3452  * @param verbosity level of messages verbosity
3453  * @param from_file SANE_True if data read from file
3454  * @return a string containing the name of the detected scanner chip
3455  */
3456 char *check_usb_chip (int verbosity,
3457 		      struct libusb_device_descriptor desc,
3458 		      libusb_device_handle * hdl,
3459 		      struct libusb_config_descriptor *config0);
3460 
3461 static int verbose = 0;
3462 
3463 static int
genesys_write_reg(libusb_device_handle * handle,unsigned char reg,unsigned char val)3464 genesys_write_reg (libusb_device_handle * handle, unsigned char reg,
3465 		   unsigned char val)
3466 {
3467   int result;
3468   unsigned char data[2];
3469 
3470   data[0] = reg;
3471   data[1] = val;
3472 
3473   result = libusb_control_transfer (handle,
3474 				    0x40,
3475 				    0x04, 0x83, 0x00, data, 0x02, TIMEOUT);
3476   if (result < 0)
3477     return 0;
3478   return 1;
3479 }
3480 
3481 static int
genesys_read_reg(libusb_device_handle * handle,unsigned char reg,unsigned char * val)3482 genesys_read_reg (libusb_device_handle * handle, unsigned char reg,
3483 		  unsigned char *val)
3484 {
3485   int result;
3486 
3487   result = libusb_control_transfer (handle,
3488 				    0x40,
3489 				    0x0c, 0x83, 0x00, &reg, 0x01, TIMEOUT);
3490   if (result < 0)
3491     return 0;
3492 
3493   result = libusb_control_transfer (handle,
3494 				    0xc0,
3495 				    0x0c, 0x84, 0x00, val, 0x01, TIMEOUT);
3496   if (result < 0)
3497     return 0;
3498 
3499   return 1;
3500 }
3501 
3502 /** @brief check for genesys GL646 chips
3503  *
3504  * @param dev libusb device
3505  * @param hdl libusb opened handle
3506  * @param config0 configuration 0 from get config _descriptor
3507  * @return a string with ASIC name, or NULL if not recognized
3508  */
3509 static char *
check_gl646(libusb_device_handle * handle,struct libusb_device_descriptor desc,struct libusb_config_descriptor * config0)3510 check_gl646 (libusb_device_handle * handle,
3511 	     struct libusb_device_descriptor desc,
3512 	     struct libusb_config_descriptor *config0)
3513 {
3514   unsigned char val;
3515   int result;
3516 
3517   if (desc.bcdUSB != 0x110)
3518     {
3519       if (verbose > 2)
3520 	printf ("    this is not a GL646 (bcdUSB = 0x%x)\n", desc.bcdUSB);
3521       return 0;
3522     }
3523   if (desc.bDeviceSubClass != 0x00)
3524     {
3525       if (verbose > 2)
3526 	printf ("    this is not a GL646 (bDeviceSubClass = 0x%x)\n",
3527 		desc.bDeviceSubClass);
3528       return 0;
3529     }
3530   if (desc.bDeviceProtocol != 0)
3531     {
3532       if (verbose > 2)
3533 	printf ("    this is not a GL646 (bDeviceProtocol = 0x%x)\n",
3534 		desc.bDeviceProtocol);
3535       return 0;
3536     }
3537 
3538   /* Check endpoints */
3539   if (config0->interface[0].altsetting[0].bNumEndpoints != 3)
3540     {
3541       if (verbose > 2)
3542 	printf ("    this is not a GL646 (bNumEndpoints = %d)\n",
3543 		config0->interface[0].altsetting[0].bNumEndpoints);
3544       return 0;
3545     }
3546 
3547   if ((config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress !=
3548        0x81)
3549       || (config0->interface[0].altsetting[0].endpoint[0].bmAttributes !=
3550 	  0x02)
3551       || (config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize !=
3552 	  0x40)
3553       || (config0->interface[0].altsetting[0].endpoint[0].bInterval != 0x0))
3554     {
3555       if (verbose > 2)
3556 	printf
3557 	  ("    this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3558 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3559 	   config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress,
3560 	   config0->interface[0].altsetting[0].endpoint[0].bmAttributes,
3561 	   config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize,
3562 	   config0->interface[0].altsetting[0].endpoint[0].bInterval);
3563       return 0;
3564     }
3565 
3566   if ((config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress !=
3567        0x02)
3568       || (config0->interface[0].altsetting[0].endpoint[1].bmAttributes !=
3569 	  0x02)
3570       || (config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize !=
3571 	  0x40)
3572       || (config0->interface[0].altsetting[0].endpoint[1].bInterval != 0))
3573     {
3574       if (verbose > 2)
3575 	printf
3576 	  ("    this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3577 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3578 	   config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress,
3579 	   config0->interface[0].altsetting[0].endpoint[1].bmAttributes,
3580 	   config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize,
3581 	   config0->interface[0].altsetting[0].endpoint[1].bInterval);
3582       return 0;
3583     }
3584 
3585   if ((config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress !=
3586        0x83)
3587       || (config0->interface[0].altsetting[0].endpoint[2].bmAttributes !=
3588 	  0x03)
3589       || (config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize !=
3590 	  0x1)
3591       || (config0->interface[0].altsetting[0].endpoint[2].bInterval != 8))
3592     {
3593       if (verbose > 2)
3594 	printf
3595 	  ("    this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3596 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3597 	   config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress,
3598 	   config0->interface[0].altsetting[0].endpoint[2].bmAttributes,
3599 	   config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize,
3600 	   config0->interface[0].altsetting[0].endpoint[2].bInterval);
3601       return 0;
3602     }
3603 
3604   result = genesys_write_reg (handle, 0x38, 0x15);
3605   if (!result)
3606     {
3607       if (verbose > 2)
3608 	printf ("    this is not a GL646 (writing register failed)\n");
3609       return 0;
3610     }
3611 
3612   result = genesys_read_reg (handle, 0x4e, &val);
3613   if (!result)
3614     {
3615       if (verbose > 2)
3616 	printf ("    this is not a GL646 (reading register failed)\n");
3617       return 0;
3618     }
3619 
3620   if (val != 0x15)
3621     {
3622       if (verbose > 2)
3623 	printf ("    this is not a GL646 (reg 0x4e != reg 0x38)\n");
3624       return 0;
3625     }
3626 
3627   return "GL646";
3628 }
3629 
3630 /** @brief check for gt6801 chip
3631  *
3632  * @param dev libusb device
3633  * @param hdl libusb opened handle
3634  * @param config0 configuration 0 from get config _descriptor
3635  * @return a string with ASIC name, or NULL if not recognized
3636  */
3637 static char *
check_gt6801(libusb_device_handle * handle,struct libusb_device_descriptor desc,struct libusb_config_descriptor * config0)3638 check_gt6801 (libusb_device_handle * handle,
3639 	       struct libusb_device_descriptor desc,
3640 	       struct libusb_config_descriptor *config0)
3641 {
3642   unsigned char req[64];
3643   int result;
3644 
3645   if (verbose > 2)
3646     printf ("    checking for GT-6801 ...\n");
3647 
3648   /* Check device descriptor */
3649   if (desc.bDeviceClass != LIBUSB_CLASS_VENDOR_SPEC)
3650     {
3651       if (verbose > 2)
3652 	printf ("    this is not a GT-6801 (bDeviceClass = %d)\n",
3653 		desc.bDeviceClass);
3654       return 0;
3655     }
3656   if (desc.bcdUSB != 0x110)
3657     {
3658       if (verbose > 2)
3659 	printf ("    this is not a GT-6801 (bcdUSB = 0x%x)\n", desc.bcdUSB);
3660       return 0;
3661     }
3662   if (desc.bDeviceSubClass != 0xff)
3663     {
3664       if (verbose > 2)
3665 	printf ("    this is not a GT-6801 (bDeviceSubClass = 0x%x)\n",
3666 		desc.bDeviceSubClass);
3667       return 0;
3668     }
3669   if (desc.bDeviceProtocol != 0xff)
3670     {
3671       if (verbose > 2)
3672 	printf ("    this is not a GT-6801 (bDeviceProtocol = 0x%x)\n",
3673 		desc.bDeviceProtocol);
3674       return 0;
3675     }
3676 
3677   /* Check endpoints */
3678   if (config0->interface[0].altsetting[0].bNumEndpoints != 1)
3679     {
3680       if (verbose > 2)
3681 	printf ("    this is not a GT-6801 (bNumEndpoints = %d)\n",
3682 		config0->interface[0].altsetting[0].bNumEndpoints);
3683       return 0;
3684     }
3685   if ((config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress != 0x81)
3686       || (config0->interface[0].altsetting[0].endpoint[0].bmAttributes != 0x02)
3687       || (config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize != 0x40)
3688       || (config0->interface[0].altsetting[0].endpoint[0].bInterval != 0x00))
3689     {
3690       if (verbose > 2)
3691 	printf
3692 	  ("    this is not a GT-6801 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3693 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3694 	   config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress,
3695 	   config0->interface[0].altsetting[0].endpoint[0].bmAttributes,
3696 	   config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize,
3697 	   config0->interface[0].altsetting[0].endpoint[0].bInterval);
3698       return 0;
3699     }
3700 
3701   /* Now we send a control message */
3702 
3703   memset (req, 0, 64);
3704   req[0] = 0x2e;		/* get identification information */
3705   req[1] = 0x01;
3706 
3707   result = libusb_control_transfer (handle, 0x40, 0x01, 0x2010, 0x3f40, req, 64, TIMEOUT);
3708   if (result <= 0)
3709     {
3710       if (verbose > 2)
3711 	printf ("    Couldn't send write control message (%s)\n",
3712 		strerror (errno));
3713       return NULL;
3714     }
3715   result = libusb_control_transfer (handle, 0xc0, 0x01, 0x2011, 0x3f00, req, 64, TIMEOUT);
3716   if (result <= 0)
3717     {
3718       if (verbose > 2)
3719 	printf ("    Couldn't send read control message (%s)\n",
3720 		strerror (errno));
3721       return NULL;
3722     }
3723   if (req[0] != 0 || (req[1] != 0x2e && req[1] != 0))
3724     {
3725       if (verbose > 2)
3726 	printf ("    Unexpected result from control message (%0x/%0x)\n",
3727 		req[0], req[1]);
3728       return NULL;
3729     }
3730   return "GT-6801";
3731 }
3732 
3733 /** @brief check for gt6816 chip
3734  *
3735  * @param dev libusb device
3736  * @param hdl libusb opened handle
3737  * @param config0 configuration 0 from get config _descriptor
3738  * @return a string with ASIC name, or NULL if not recognized
3739  */
3740 static char *
check_gt6816(libusb_device_handle * handle,struct libusb_device_descriptor desc,struct libusb_config_descriptor * config0)3741 check_gt6816 (libusb_device_handle * handle,
3742 	       struct libusb_device_descriptor desc,
3743 	       struct libusb_config_descriptor *config0)
3744 {
3745   unsigned char req[64];
3746   int result,i;
3747 
3748   if (verbose > 2)
3749     printf ("    checking for GT-6816 ...\n");
3750 
3751   /* Check device descriptor */
3752   if ((desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE)
3753       || (config0->interface[0].altsetting[0].bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC))
3754     {
3755       if (verbose > 2)
3756 	printf
3757 	  ("    this is not a GT-6816 (bDeviceClass = %d, bInterfaceClass = %d)\n",
3758 	   desc.bDeviceClass,
3759 	   config0->interface[0].altsetting[0].bInterfaceClass);
3760       return 0;
3761     }
3762   if (desc.bcdUSB != 0x110)
3763     {
3764       if (verbose > 2)
3765 	printf ("    this is not a GT-6816 (bcdUSB = 0x%x)\n", desc.bcdUSB);
3766       return 0;
3767     }
3768   if (desc.bDeviceSubClass != 0x00)
3769     {
3770       if (verbose > 2)
3771 	printf ("    this is not a GT-6816 (bDeviceSubClass = 0x%x)\n",
3772 		desc.bDeviceSubClass);
3773       return 0;
3774     }
3775   if (desc.bDeviceProtocol != 0x00)
3776     {
3777       if (verbose > 2)
3778 	printf ("    this is not a GT-6816 (bDeviceProtocol = 0x%x)\n",
3779 		desc.bDeviceProtocol);
3780       return 0;
3781     }
3782 
3783   if (config0->bNumInterfaces != 0x01)
3784     {
3785       if (verbose > 2)
3786 	printf ("    this is not a GT-6816 (bNumInterfaces = 0x%x)\n",
3787 		config0->bNumInterfaces);
3788       return 0;
3789     }
3790 
3791   /* Check endpoints */
3792   if (config0->interface[0].altsetting[0].bNumEndpoints != 2)
3793     {
3794       if (verbose > 2)
3795 	printf ("    this is not a GT-6816 (bNumEndpoints = %d)\n",
3796 		config0->interface[0].altsetting[0].bNumEndpoints);
3797       return 0;
3798     }
3799   if ((config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress != 0x81)
3800       || (config0->interface[0].altsetting[0].endpoint[0].bmAttributes != 0x02)
3801       || (config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize != 0x40)
3802       || (config0->interface[0].altsetting[0].endpoint[0].bInterval != 0x00))
3803     {
3804       if (verbose > 2)
3805 	printf
3806 	  ("    this is not a GT-6816 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3807 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3808 	   config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress,
3809 	   config0->interface[0].altsetting[0].endpoint[0].bmAttributes,
3810 	   config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize,
3811 	   config0->interface[0].altsetting[0].endpoint[0].bInterval);
3812       return 0;
3813     }
3814   if ((config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress != 0x02)
3815       || (config0->interface[0].altsetting[0].endpoint[1].bmAttributes != 0x02)
3816       || (config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize != 0x40)
3817       || (config0->interface[0].altsetting[0].endpoint[1].bInterval != 0x00))
3818     {
3819       if (verbose > 2)
3820 	printf
3821 	  ("    this is not a GT-6816 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3822 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3823 	   config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress,
3824 	   config0->interface[0].altsetting[0].endpoint[1].bmAttributes,
3825 	   config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize,
3826 	   config0->interface[0].altsetting[0].endpoint[1].bInterval);
3827       return 0;
3828     }
3829 
3830   /* Now we send a control message */
3831 
3832   memset (req, 0, 64);
3833   for (i = 0; i < 8; i++)
3834     {
3835       req[8 * i + 0] = 0x73;	/* check firmware */
3836       req[8 * i + 1] = 0x01;
3837     }
3838 
3839   result = libusb_control_transfer (handle, 0x40, 0x04, 0x2012, 0x3f40, req, 64, TIMEOUT);
3840   if (result <= 0)
3841     {
3842       if (verbose > 2)
3843 	printf ("    Couldn't send write control message (%s)\n",
3844 		strerror (errno));
3845       return NULL;
3846     }
3847   result = libusb_control_transfer (handle, 0xc0, 0x01, 0x2013, 0x3f00, req, 64, TIMEOUT);
3848   if (result <= 0)
3849     {
3850       /* Before firmware upload, 64 bytes are returned. Some libusb
3851 	 implementations/operating systems can't seem to cope with short
3852 	 packets. */
3853       result = libusb_control_transfer (handle, 0xc0, 0x01, 0x2013, 0x3f00, req, 8, TIMEOUT);
3854       if (result <= 0)
3855         {
3856           if (verbose > 2)
3857 	    printf ("    Couldn't send read control message (%s)\n",
3858 		    strerror (errno));
3859           return NULL;
3860         }
3861     }
3862   if (req[0] != 0)
3863     {
3864       if (verbose > 2)
3865 	printf ("    Unexpected result from control message (%0x/%0x)\n",
3866 		req[0], req[1]);
3867       return NULL;
3868     }
3869   return "GT-6816";
3870 }
3871 
3872 /** @brief check for known genesys chip
3873  *
3874  * Try to check if the scanner use a known genesys ASIC.
3875  * The various incarnations could be distinguished by the
3876  * bcdDevice entry:
3877  *    0x701 --> GL124
3878  *    0x700 --> ?
3879  *    0x605 --> GL845
3880  *    0x603 --> GL847
3881  *    0x601 --> GL846
3882  *    0x500 --> GL843
3883  *    0x300 --> GL842 (perhaps only >= 0x303 ?)
3884  *    0x200 --> GL841
3885  *
3886  * @param dev libusb device
3887  * @param hdl libusb opened handle
3888  * @param config0 configuration 0 from get config _descriptor
3889  * @return a string with ASIC name, or NULL if not recognized
3890  */
3891 static char *
check_genesys(libusb_device_handle * handle,struct libusb_device_descriptor desc,struct libusb_config_descriptor * config0)3892 check_genesys (libusb_device_handle * handle,
3893 	       struct libusb_device_descriptor desc,
3894 	       struct libusb_config_descriptor *config0)
3895 {
3896   unsigned char val;
3897   int result;
3898 
3899   if (verbose > 2)
3900     printf ("    checking for GLxxx ...\n");
3901 
3902   /* Check GL646 device descriptor */
3903   if ((desc.bDeviceClass == LIBUSB_CLASS_PER_INTERFACE)
3904       && (config0->interface[0].altsetting[0].bInterfaceClass == 0x10))
3905     {
3906       return check_gl646 (handle, desc, config0);
3907     }
3908   if (verbose > 2)
3909     {
3910       printf
3911 	("    this is not a GL646 (bDeviceClass = %d, bInterfaceClass = %d)\n",
3912 	 desc.bDeviceClass,
3913 	 config0->interface[0].altsetting[0].bInterfaceClass);
3914     }
3915 
3916   /* Check device desc */
3917   if ((desc.bDeviceClass != LIBUSB_CLASS_VENDOR_SPEC)
3918       || (config0->interface[0].altsetting[0].bInterfaceClass !=
3919 	  LIBUSB_CLASS_VENDOR_SPEC))
3920     {
3921       if (verbose > 2)
3922 	printf
3923 	  ("    this is not a GLxxx (bDeviceClass = %d, bInterfaceClass = %d)\n",
3924 	   desc.bDeviceClass,
3925 	   config0->interface[0].altsetting[0].bInterfaceClass);
3926       return NULL;
3927     }
3928 
3929   if (desc.bDeviceSubClass != 0xff)
3930     {
3931       if (verbose > 2)
3932 	printf ("    this is not a GLxxx (bDeviceSubClass = 0x%x)\n",
3933 		desc.bDeviceSubClass);
3934       return NULL;
3935     }
3936   if (desc.bDeviceProtocol != 0xff)
3937     {
3938       if (verbose > 2)
3939 	printf ("    this is not a GLxxx (bDeviceProtocol = 0x%x)\n",
3940 		desc.bDeviceProtocol);
3941       return NULL;
3942     }
3943 
3944   /* Check endpoints */
3945   if (config0->interface[0].altsetting[0].bNumEndpoints != 3)
3946     {
3947       if (verbose > 2)
3948 	printf ("    this is not a GLxxx (bNumEndpoints = %d)\n",
3949 		config0->interface[0].altsetting[0].bNumEndpoints);
3950       return NULL;
3951     }
3952 
3953   if ((config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress !=
3954        0x81)
3955       || (config0->interface[0].altsetting[0].endpoint[0].bmAttributes !=
3956 	  0x02)
3957       ||
3958       ((config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize !=
3959 	0x40)
3960        && (config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize !=
3961 	   0x200))
3962       || (config0->interface[0].altsetting[0].endpoint[0].bInterval != 0x0))
3963     {
3964       if (verbose > 2)
3965 	printf
3966 	  ("    this is not a GLxxx (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3967 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3968 	   config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress,
3969 	   config0->interface[0].altsetting[0].endpoint[0].bmAttributes,
3970 	   config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize,
3971 	   config0->interface[0].altsetting[0].endpoint[0].bInterval);
3972       return NULL;
3973     }
3974 
3975   if ((config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress !=
3976        0x02)
3977       || (config0->interface[0].altsetting[0].endpoint[1].bmAttributes !=
3978 	  0x02)
3979       ||
3980       ((config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize !=
3981 	0x40)
3982        && (config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize !=
3983 	   0x200))
3984       || (config0->interface[0].altsetting[0].endpoint[1].bInterval != 0))
3985     {
3986       if (verbose > 2)
3987 	printf
3988 	  ("    this is not a GLxxx (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
3989 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
3990 	   config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress,
3991 	   config0->interface[0].altsetting[0].endpoint[1].bmAttributes,
3992 	   config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize,
3993 	   config0->interface[0].altsetting[0].endpoint[1].bInterval);
3994       return NULL;
3995     }
3996 
3997   if ((config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress !=
3998        0x83)
3999       || (config0->interface[0].altsetting[0].endpoint[2].bmAttributes !=
4000 	  0x03)
4001       || (config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize !=
4002 	  0x1)
4003       || ((config0->interface[0].altsetting[0].endpoint[2].bInterval != 8)
4004 	  && (config0->interface[0].altsetting[0].endpoint[2].bInterval !=
4005 	      16)))
4006     {
4007       if (verbose > 2)
4008 	printf
4009 	  ("    this is not a GLxxx (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
4010 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
4011 	   config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress,
4012 	   config0->interface[0].altsetting[0].endpoint[2].bmAttributes,
4013 	   config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize,
4014 	   config0->interface[0].altsetting[0].endpoint[2].bInterval);
4015       return NULL;
4016     }
4017 
4018   /* write then read a register using common read/write control message */
4019   result = genesys_write_reg (handle, 0x38, 0x15);
4020   if (!result)
4021     {
4022       if (verbose > 2)
4023 	printf ("    this is not a GLxxx (writing register failed)\n");
4024       return NULL;
4025     }
4026 
4027   result = genesys_read_reg (handle, 0x38, &val);
4028   if (!result)
4029     {
4030       if (verbose > 2)
4031 	printf ("    this is not a GLxxx (reading register failed)\n");
4032       return NULL;
4033     }
4034 
4035   if (val != 0x15)
4036     {
4037       if (verbose > 2)
4038 	printf ("    this is not a GLxxx (reg 0x38 != 0x15)\n");
4039       return NULL;
4040     }
4041 
4042   /* decide revision number based on bcdUsb heuristics */
4043   if (desc.bcdDevice == 0x702)
4044     return "GL128";
4045   if (desc.bcdDevice == 0x701)
4046     return "GL124";
4047   if (desc.bcdDevice >= 0x700)
4048     return "GL848+";
4049   if (desc.bcdDevice >= 0x605)
4050     return "GL845";
4051   if (desc.bcdDevice >= 0x603)
4052     return "GL847";
4053   if (desc.bcdDevice >= 0x600)
4054     return "GL846";
4055   if (desc.bcdDevice >= 0x500)
4056     return "GL843";
4057   if (desc.bcdDevice >= 0x300)
4058     return "GL842";
4059   if (desc.bcdDevice > 0x101)
4060     return "GL841";
4061   return "GL646_HP";
4062 }
4063 
4064 /********** the lm983x section **********/
4065 
4066 static int
lm983x_wb(libusb_device_handle * handle,unsigned char reg,unsigned char val)4067 lm983x_wb (libusb_device_handle *handle, unsigned char reg, unsigned char val)
4068 {
4069   unsigned char buf[5];
4070   int written;
4071   int result;
4072 
4073   buf[0] = 0;
4074   buf[1] = reg;
4075   buf[2] = 0;
4076   buf[3] = 1;
4077   buf[4] = val;
4078 
4079   result = libusb_bulk_transfer(handle, 0x03, buf, 5, &written, TIMEOUT);
4080   if (result < 0)
4081     return 0;
4082 
4083   if (written != 5)
4084     return 0;
4085 
4086   return 1;
4087 }
4088 
4089 static int
lm983x_rb(libusb_device_handle * handle,unsigned char reg,unsigned char * val)4090 lm983x_rb (libusb_device_handle *handle, unsigned char reg, unsigned char *val)
4091 {
4092   unsigned char buf[5];
4093   int result;
4094   int tfx;
4095 
4096   buf[0] = 1;
4097   buf[1] = reg;
4098   buf[2] = 0;
4099   buf[3] = 1;
4100 
4101   result = libusb_bulk_transfer(handle, 0x03, buf, 4, &tfx, TIMEOUT);
4102   if (result < 0)
4103     return 0;
4104 
4105   if (tfx != 4)
4106     return 0;
4107 
4108   result = libusb_bulk_transfer(handle, 0x82, val, 1, &tfx, TIMEOUT);
4109   if (result < 0)
4110     return 0;
4111 
4112   if (tfx != 1)
4113     return 0;
4114 
4115   return 1;
4116 }
4117 
4118 /** @brief check for known LM983x chip (aka Merlin)
4119  *
4120  * Try to check if the scanner uses a LM983x ASIC.
4121  *
4122  * @param dev libusb device
4123  * @param hdl libusb opened handle
4124  * @param config0 configuration 0 from get config _descriptor
4125  * @return a string with ASIC name, or NULL if not recognized
4126  */
4127 static char *
check_merlin(libusb_device_handle * handle,struct libusb_device_descriptor desc,struct libusb_config_descriptor * config0)4128 check_merlin(libusb_device_handle * handle,
4129 	       struct libusb_device_descriptor desc,
4130 	       struct libusb_config_descriptor *config0)
4131 {
4132   unsigned char val;
4133   int result;
4134 
4135   if (verbose > 2)
4136     printf ("    checking for LM983[1,2,3] ...\n");
4137 
4138   /* Check device descriptor */
4139   if (((desc.bDeviceClass != LIBUSB_CLASS_VENDOR_SPEC)
4140        && (desc.bDeviceClass != 0))
4141       || (config0->interface[0].altsetting[0].bInterfaceClass !=
4142 	  LIBUSB_CLASS_VENDOR_SPEC))
4143     {
4144       if (verbose > 2)
4145 	printf
4146 	  ("    this is not a LM983x (bDeviceClass = %d, bInterfaceClass = %d)\n",
4147 	   desc.bDeviceClass,
4148 	   config0->interface[0].altsetting[0].bInterfaceClass);
4149       return 0;
4150     }
4151   if ((desc.bcdUSB != 0x110)
4152       && (desc.bcdUSB != 0x101)
4153       && (desc.bcdUSB != 0x100))
4154     {
4155       if (verbose > 2)
4156 	printf ("    this is not a LM983x (bcdUSB = 0x%x)\n", desc.bcdUSB);
4157       return 0;
4158     }
4159   if (desc.bDeviceSubClass != 0x00)
4160     {
4161       if (verbose > 2)
4162 	printf ("    this is not a LM983x (bDeviceSubClass = 0x%x)\n",
4163 		desc.bDeviceSubClass);
4164       return 0;
4165     }
4166   if ((desc.bDeviceProtocol != 0) &&
4167       (desc.bDeviceProtocol != 0xff))
4168     {
4169       if (verbose > 2)
4170 	printf ("    this is not a LM983x (bDeviceProtocol = 0x%x)\n",
4171 		desc.bDeviceProtocol);
4172       return 0;
4173     }
4174 
4175   /* Check endpoints */
4176   if (config0->interface[0].altsetting[0].bNumEndpoints != 3)
4177     {
4178       if (verbose > 2)
4179 	printf ("    this is not a LM983x (bNumEndpoints = %d)\n",
4180 		config0->interface[0].altsetting[0].bNumEndpoints);
4181       return 0;
4182     }
4183 
4184   if ((config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress != 0x81)
4185       || (config0->interface[0].altsetting[0].endpoint[0].bmAttributes != 0x03)
4186       || (config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize != 0x1)
4187       || (config0->interface[0].altsetting[0].endpoint[0].bInterval != 0x10))
4188     {
4189       if (verbose > 2)
4190 	printf
4191 	  ("    this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
4192 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
4193 	   config0->interface[0].altsetting[0].endpoint[0].bEndpointAddress,
4194 	   config0->interface[0].altsetting[0].endpoint[0].bmAttributes,
4195 	   config0->interface[0].altsetting[0].endpoint[0].wMaxPacketSize,
4196 	   config0->interface[0].altsetting[0].endpoint[0].bInterval);
4197       return 0;
4198     }
4199 
4200   if ((config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress != 0x82)
4201       || (config0->interface[0].altsetting[0].endpoint[1].bmAttributes != 0x02)
4202       || (config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize != 0x40)
4203       /* Currently disabled as we have some problems in detection here ! */
4204       /*|| (config0->interface[0].altsetting[0].endpoint[1].bInterval != 0) */
4205     )
4206     {
4207       if (verbose > 2)
4208 	printf
4209 	  ("    this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
4210 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
4211 	   config0->interface[0].altsetting[0].endpoint[1].bEndpointAddress,
4212 	   config0->interface[0].altsetting[0].endpoint[1].bmAttributes,
4213 	   config0->interface[0].altsetting[0].endpoint[1].wMaxPacketSize,
4214 	   config0->interface[0].altsetting[0].endpoint[1].bInterval);
4215       return 0;
4216     }
4217 
4218   if ((config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress != 0x03)
4219       || (config0->interface[0].altsetting[0].endpoint[2].bmAttributes != 0x02)
4220       || (config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize != 0x40)
4221       /* Currently disabled as we have some problems in detection here ! */
4222       /* || (config0->interface[0].altsetting[0].endpoint[2].bInterval != 0) */
4223     )
4224     {
4225       if (verbose > 2)
4226 	printf
4227 	  ("    this is not a LM983x (bEndpointAddress = 0x%x, bmAttributes = 0x%x, "
4228 	   "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n",
4229 	   config0->interface[0].altsetting[0].endpoint[2].bEndpointAddress,
4230 	   config0->interface[0].altsetting[0].endpoint[2].bmAttributes,
4231 	   config0->interface[0].altsetting[0].endpoint[2].wMaxPacketSize,
4232 	   config0->interface[0].altsetting[0].endpoint[2].bInterval);
4233       return 0;
4234     }
4235 
4236   result = lm983x_wb (handle, 0x07, 0x00);
4237   if (1 == result)
4238     result = lm983x_wb (handle, 0x08, 0x02);
4239   if (1 == result)
4240     result = lm983x_rb (handle, 0x07, &val);
4241   if (1 == result)
4242     result = lm983x_rb (handle, 0x08, &val);
4243   if (1 == result)
4244     result = lm983x_rb (handle, 0x69, &val);
4245 
4246   if (0 == result)
4247     {
4248       if (verbose > 2)
4249 	printf ("  Couldn't access LM983x registers.\n");
4250       return 0;
4251     }
4252 
4253   switch (val)
4254     {
4255     case 4:
4256       return "LM9832/3";
4257       break;
4258     case 3:
4259       return "LM9831";
4260       break;
4261     case 2:
4262       return "LM9830";
4263       break;
4264     default:
4265       return "LM983x?";
4266       break;
4267     }
4268 }
4269 
4270 
4271 char *
check_usb_chip(int verbosity,struct libusb_device_descriptor desc,libusb_device_handle * hdl,struct libusb_config_descriptor * config0)4272 check_usb_chip (int verbosity,
4273 		struct libusb_device_descriptor desc,
4274 		libusb_device_handle * hdl,
4275 		struct libusb_config_descriptor *config0)
4276 {
4277   char *chip_name = NULL;
4278   int ret;
4279 
4280   verbose = verbosity;
4281 
4282   if (verbose > 2)
4283     printf ("\n<trying to find out which USB chip is used>\n");
4284 
4285   /* set config if needed */
4286   if (desc.bNumConfigurations > 1)
4287     {
4288       ret = libusb_set_configuration (hdl, config0->bConfigurationValue);
4289       if (ret < 0)
4290 	{
4291 	  if (verbose > 2)
4292 	    printf ("couldn't set device to configuration %d\n",
4293 		    config0->bConfigurationValue);
4294 	  return NULL;
4295 	}
4296     }
4297 
4298   /* claim the interface (only interface 0 is currently handled */
4299   ret = libusb_claim_interface (hdl, 0);
4300   if (ret < 0)
4301     {
4302       if (verbose > 2)
4303 	printf ("could not claim USB device interface\n");
4304       return NULL;
4305     }
4306 
4307   /* now USB is opened and set up, actual chip detection */
4308 
4309   if (!chip_name)
4310     chip_name = check_merlin (hdl, desc, config0);
4311 
4312   if (!chip_name)
4313   	chip_name = check_gt6801 (hdl, desc, config0);
4314 
4315   if (!chip_name)
4316   	chip_name = check_gt6816 (hdl, desc, config0);
4317 
4318   if (!chip_name)
4319     chip_name = check_genesys (hdl, desc, config0);
4320 
4321   if (verbose > 2)
4322     {
4323       if (chip_name)
4324 	printf ("<This USB chip looks like a %s (result from %s)>\n\n",
4325 		chip_name, PACKAGE_STRING);
4326       else
4327 	printf
4328 	  ("<Couldn't determine the type of the USB chip (result from %s)>\n\n",
4329 	   PACKAGE_STRING);
4330     }
4331 
4332   /* close USB device */
4333   libusb_release_interface (hdl, 0);
4334   return chip_name;
4335 }
4336 #endif /* HAVE_LIBUSB */
4337