xref: /third_party/backends/backend/hp3900_usb.c (revision 141cc406)
1/* HP Scanjet 3900 series - USB layer
2
3   Copyright (C) 2005-2008 Jonathan Bravo Lopez <jkdsoft@gmail.com>
4
5   This file is part of the SANE package.
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License
9   as published by the Free Software Foundation; either version 2
10   of the License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20   As a special exception, the authors of SANE give permission for
21   additional uses of the libraries contained in this release of SANE.
22
23   The exception is that, if you link a SANE library with other files
24   to produce an executable, this does not by itself cause the
25   resulting executable to be covered by the GNU General Public
26   License.  Your use of that executable is in no way restricted on
27   account of linking the SANE library code into it.
28
29   This exception does not, however, invalidate any other reasons why
30   the executable file might be covered by the GNU General Public
31   License.
32
33   If you submit changes to SANE to the maintainers to be included in
34   a subsequent release, you agree by submitting the changes that
35   those changes may be distributed with this exception intact.
36
37   If you write modifications of your own for SANE, it is your choice
38   whether to permit this exception to apply to your modifications.
39   If you do not wish that, delete this exception notice.
40*/
41
42#ifndef USBLAYER
43
44#define USBLAYER
45
46#define TIMEOUT      1000
47#define BLK_READ_EP  0x81
48#define BLK_WRITE_EP 0x02
49
50SANE_Int dataline_count = 0;
51
52/* USB layer commands */
53static SANE_Int usb_ctl_write (USB_Handle usb_handle, SANE_Int address,
54			       SANE_Byte * buffer, SANE_Int size,
55			       SANE_Int index);
56static SANE_Int usb_ctl_read (USB_Handle usb_handle, SANE_Int address,
57			      SANE_Byte * buffer, SANE_Int size,
58			      SANE_Int index);
59
60/* Higher level commands*/
61
62static SANE_Int IRead_Byte (USB_Handle usb_handle, SANE_Int address,
63			    SANE_Byte * data, SANE_Int index);
64static SANE_Int IRead_Word (USB_Handle usb_handle, SANE_Int address,
65			    SANE_Int * data, SANE_Int index);
66static SANE_Int IRead_Integer (USB_Handle usb_handle, SANE_Int address,
67			       SANE_Int * data, SANE_Int index);
68static SANE_Int IRead_Buffer (USB_Handle usb_handle, SANE_Int address,
69			      SANE_Byte * buffer, SANE_Int size,
70			      SANE_Int index);
71static SANE_Int IWrite_Byte (USB_Handle usb_handle, SANE_Int address,
72			     SANE_Byte data, SANE_Int index1,
73			     SANE_Int index2);
74static SANE_Int IWrite_Word (USB_Handle usb_handle, SANE_Int address,
75			     SANE_Int data, SANE_Int index);
76static SANE_Int IWrite_Integer (USB_Handle usb_handle, SANE_Int address,
77				SANE_Int data, SANE_Int index);
78static SANE_Int IWrite_Buffer (USB_Handle usb_handle, SANE_Int address,
79			       SANE_Byte * buffer, SANE_Int size,
80			       SANE_Int index);
81
82static SANE_Int Read_Byte (USB_Handle usb_handle, SANE_Int address,
83			   SANE_Byte * data);
84static SANE_Int Read_Word (USB_Handle usb_handle, SANE_Int address,
85			   SANE_Int * data);
86static SANE_Int Read_Integer (USB_Handle usb_handle, SANE_Int address,
87			      SANE_Int * data);
88static SANE_Int Read_Buffer (USB_Handle usb_handle, SANE_Int address,
89			     SANE_Byte * buffer, SANE_Int size);
90static SANE_Int Read_Bulk (USB_Handle usb_handle, SANE_Byte * buffer,
91			   size_t size);
92static SANE_Int Write_Byte (USB_Handle usb_handle, SANE_Int address,
93			    SANE_Byte data);
94static SANE_Int Write_Word (USB_Handle usb_handle, SANE_Int address,
95			    SANE_Int data);
96/*static SANE_Int  Write_Integer  (USB_Handle usb_handle, SANE_Int address, SANE_Int data);*/
97static SANE_Int Write_Buffer (USB_Handle usb_handle, SANE_Int address,
98			      SANE_Byte * buffer, SANE_Int size);
99static SANE_Int Write_Bulk (USB_Handle usb_handle, SANE_Byte * buffer,
100			    SANE_Int size);
101
102static SANE_Int show_buffer (SANE_Int level, SANE_Byte * buffer,
103			     SANE_Int size);
104
105/* Implementation */
106
107static SANE_Int
108IWrite_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte data,
109	     SANE_Int index1, SANE_Int index2)
110{
111  SANE_Int rst = ERROR;
112  SANE_Byte buffer[2] = { 0x00, 0x00 };
113
114  if (usb_ctl_read (usb_handle, address + 1, buffer, 0x02, index1) == 2)
115    {
116      buffer[1] = (buffer[0] & 0xff);
117      buffer[0] = (data & 0xff);
118
119      if (usb_ctl_write (usb_handle, address, buffer, 0x02, index2) == 2)
120	rst = OK;
121    }
122
123  return rst;
124}
125
126static SANE_Int
127IWrite_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int data,
128	     SANE_Int index)
129{
130  SANE_Int rst = ERROR;
131  SANE_Byte buffer[2];
132
133  buffer[0] = (data & 0xff);
134  buffer[1] = ((data >> 8) & 0xff);
135
136  if (usb_ctl_write (usb_handle, address, buffer, 0x02, index) == 2)
137    rst = OK;
138
139  return rst;
140}
141
142static SANE_Int
143IWrite_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int data,
144		SANE_Int index)
145{
146  SANE_Int rst = ERROR;
147  SANE_Byte buffer[4];
148
149  buffer[0] = (data & 0xff);
150  buffer[1] = ((data >> 8) & 0xff);
151  buffer[2] = ((data >> 16) & 0xff);
152  buffer[3] = ((data >> 24) & 0xff);
153
154  if (usb_ctl_write (usb_handle, address, buffer, 0x04, index) == 4)
155    rst = OK;
156
157  return rst;
158}
159
160static SANE_Int
161IWrite_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
162	       SANE_Int size, SANE_Int index)
163{
164  SANE_Int ret = ERROR;
165
166  if (!((buffer == NULL) && (size > 0)))
167    if (usb_ctl_write (usb_handle, address, buffer, size, index) == size)
168      ret = OK;
169
170  return ret;
171}
172
173static SANE_Int
174IRead_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte * data,
175	    SANE_Int index)
176{
177  SANE_Byte buffer[2] = { 0x00, 0x00 };
178  SANE_Int ret = ERROR;
179
180  if (data != NULL)
181    if (usb_ctl_read (usb_handle, address, buffer, 0x02, index) == 2)
182      {
183	*data = (SANE_Byte) (buffer[0] & 0xff);
184	ret = OK;
185      }
186
187  return ret;
188}
189
190static SANE_Int
191IRead_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int * data,
192	    SANE_Int index)
193{
194  SANE_Byte buffer[2] = { 0x00, 0x00 };
195  SANE_Int ret = ERROR;
196
197  if (data != NULL)
198    if (usb_ctl_read (usb_handle, address, buffer, 0x02, index) == 2)
199      {
200	*data = ((buffer[1] << 8) & 0xffff) + (buffer[0] & 0xff);
201	ret = OK;
202      }
203
204  return ret;
205}
206
207static SANE_Int
208IRead_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int * data,
209	       SANE_Int index)
210{
211  SANE_Byte buffer[4] = { 0x00, 0x00, 0x00, 0x00 };
212  SANE_Int ret = ERROR;
213
214  if (data != NULL)
215    {
216      *data = 0;
217      if (usb_ctl_read (usb_handle, address, buffer, 0x04, index) == 4)
218	{
219	  SANE_Int C;
220	  for (C = 3; C >= 0; C--)
221	    *data = ((*data << 8) + (buffer[C] & 0xff)) & 0xffffffff;
222	  ret = OK;
223	}
224    }
225
226  return ret;
227}
228
229static SANE_Int
230IRead_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
231	      SANE_Int size, SANE_Int index)
232{
233  SANE_Int ret = ERROR;
234
235  if (buffer != NULL)
236    if (usb_ctl_read (usb_handle, address, buffer, size, index) == size)
237      ret = OK;
238
239  return ret;
240}
241
242static SANE_Int
243Write_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte data)
244{
245  return IWrite_Byte (usb_handle, address, data, 0x100, 0);
246}
247
248static SANE_Int
249Write_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int data)
250{
251  return IWrite_Word (usb_handle, address, data, 0);
252}
253
254/*static SANE_Int Write_Integer(USB_Handle usb_handle, SANE_Int address, SANE_Int data)
255{
256	return IWrite_Integer(usb_handle, address, data, 0);
257}*/
258
259static SANE_Int
260Write_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
261	      SANE_Int size)
262{
263  return IWrite_Buffer (usb_handle, address, buffer, size, 0);
264}
265
266static SANE_Int
267Read_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte * data)
268{
269  return IRead_Byte (usb_handle, address, data, 0x100);
270}
271
272static SANE_Int
273Read_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
274{
275  return IRead_Word (usb_handle, address, data, 0x100);
276}
277
278static SANE_Int
279Read_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
280{
281  return IRead_Integer (usb_handle, address, data, 0x100);
282}
283
284static SANE_Int
285Read_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
286	     SANE_Int size)
287{
288  return IRead_Buffer (usb_handle, address, buffer, size, 0x100);
289}
290
291static SANE_Int
292Write_Bulk (USB_Handle usb_handle, SANE_Byte * buffer, SANE_Int size)
293{
294  SANE_Int rst = ERROR;
295
296  if (buffer != NULL)
297    {
298      dataline_count++;
299      DBG (DBG_CTL, "%06i BLK DO: %i. bytes\n", dataline_count, size);
300      show_buffer (4, buffer, size);
301
302#ifdef STANDALONE
303      if (usb_handle != NULL)
304	if (usb_bulk_write
305	    (usb_handle, BLK_WRITE_EP, (char *) buffer, size,
306	     TIMEOUT) == size)
307	  rst = OK;
308#else
309      if (usb_handle != -1)
310	{
311	  size_t mysize = size;
312	  if (sanei_usb_write_bulk (usb_handle, buffer, &mysize) ==
313	      SANE_STATUS_GOOD)
314	    rst = OK;
315	}
316#endif
317    }
318
319  if (rst != OK)
320    DBG (DBG_CTL, "             : Write_Bulk error\n");
321
322  return rst;
323}
324
325static SANE_Int
326Read_Bulk (USB_Handle usb_handle, SANE_Byte * buffer, size_t size)
327{
328  SANE_Int rst = ERROR;
329
330  if (buffer != NULL)
331    {
332      dataline_count++;
333      DBG (DBG_CTL, "%06i BLK DI: Buffer length = %lu. bytes\n",
334	   dataline_count, (u_long) size);
335
336#ifdef STANDALONE
337      if (usb_handle != NULL)
338	rst =
339	  usb_bulk_read (usb_handle, BLK_READ_EP, (char *) buffer, size,
340			 TIMEOUT);
341#else
342      if (usb_handle != -1)
343	if (sanei_usb_read_bulk (usb_handle, buffer, &size) ==
344	    SANE_STATUS_GOOD)
345	  rst = size;
346#endif
347    }
348
349  if (rst < 0)
350    DBG (DBG_CTL, "             : Read_Bulk error\n");
351  else
352    show_buffer (4, buffer, rst);
353
354  return rst;
355}
356
357static SANE_Int
358usb_ctl_write (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
359	       SANE_Int size, SANE_Int index)
360{
361  SANE_Int rst = ERROR;
362
363  dataline_count++;
364  DBG (DBG_CTL, "%06i CTL DO: 40 04 %04x %04x %04x\n",
365       dataline_count, address & 0xffff, index, size);
366  show_buffer (DBG_CTL, buffer, size);
367
368#ifdef STANDALONE
369  if (usb_handle != NULL)
370    rst = usb_control_msg (usb_handle, 0x40,	/* Request type */
371			   0x04,	/* Request      */
372			   address,	/* Value        */
373			   index,	/* Index        */
374			   (char *) buffer,	/* Buffer       */
375			   size,	/* Size         */
376			   TIMEOUT);
377#else
378  if (usb_handle != -1)
379    {
380      if (sanei_usb_control_msg (usb_handle, 0x40,	/* Request type */
381				 0x04,	/* Request      */
382				 address,	/* Value        */
383				 index,	/* Index        */
384				 size,	/* Size         */
385				 buffer)	/* Buffer       */
386	  == SANE_STATUS_GOOD)
387	rst = size;
388      else
389	rst = -1;
390    }
391#endif
392
393  if (rst < 0)
394    DBG (DBG_CTL, "             : Error, returned %i\n", rst);
395
396  return rst;
397}
398
399static SANE_Int
400usb_ctl_read (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
401	      SANE_Int size, SANE_Int index)
402{
403  SANE_Int rst;
404
405  rst = ERROR;
406
407  dataline_count++;
408  DBG (DBG_CTL, "%06i CTL DI: c0 04 %04x %04x %04x\n",
409       dataline_count, address & 0xffff, index, size);
410
411#ifdef STANDALONE
412  if (usb_handle != NULL)
413    rst = usb_control_msg (usb_handle, 0xc0,	/* Request type */
414			   0x04,	/* Request      */
415			   address,	/* Value        */
416			   index,	/* Index        */
417			   (char *) buffer,	/* Buffer       */
418			   size,	/* Size         */
419			   TIMEOUT);
420#else
421  if (usb_handle != -1)
422    {
423      if (sanei_usb_control_msg (usb_handle, 0xc0,	/* Request type */
424				 0x04,	/* Request      */
425				 address,	/* Value        */
426				 index,	/* Index        */
427				 size,	/* Size         */
428				 buffer)	/* Buffer       */
429	  == SANE_STATUS_GOOD)
430	rst = size;
431      else
432	rst = -1;
433    }
434#endif
435
436  if (rst < 0)
437    DBG (DBG_CTL, "             : Error, returned %i\n", rst);
438  else
439    show_buffer (DBG_CTL, buffer, rst);
440
441  return rst;
442}
443
444static SANE_Int
445show_buffer (SANE_Int level, SANE_Byte * buffer, SANE_Int size)
446{
447  if (DBG_LEVEL >= level)
448    {
449      char *sline = NULL;
450      char *sdata = NULL;
451      SANE_Int cont, data, offset = 0, col = 0;
452
453      if ((size > 0) && (buffer != NULL))
454	{
455	  sline = (char *) malloc (256);
456	  if (sline != NULL)
457	    {
458	      sdata = (char *) malloc (256);
459	      if (sdata != NULL)
460		{
461		  memset (sline, 0, 256);
462		  for (cont = 0; cont < size; cont++)
463		    {
464		      if (col == 0)
465			{
466			  if (cont == 0)
467			    snprintf (sline, 255, "           BF: ");
468			  else
469			    snprintf (sline, 255, "               ");
470			}
471		      data = (buffer[cont] & 0xff);
472		      snprintf (sdata, 255, "%02x ", data);
473		      sline = strcat (sline, sdata);
474		      col++;
475		      offset++;
476		      if (col == 8)
477			{
478			  col = 0;
479			  snprintf (sdata, 255, " : %i\n", offset - 8);
480			  sline = strcat (sline, sdata);
481			  DBG (level, "%s", sline);
482			  memset (sline, 0, 256);
483			}
484		    }
485		  if (col > 0)
486		    {
487		      for (cont = col; cont < 8; cont++)
488			{
489			  snprintf (sdata, 255, "-- ");
490			  sline = strcat (sline, sdata);
491			  offset++;
492			}
493		      snprintf (sdata, 255, " : %i\n", offset - 8);
494		      sline = strcat (sline, sdata);
495		      DBG (level, "%s", sline);
496		      memset (sline, 0, 256);
497		    }
498		  free (sdata);
499		}
500	      free (sline);
501	    }
502	}
503      else
504	DBG (level, "           BF: Empty buffer\n");
505    }
506  return OK;
507}
508#endif /*USBLAYER*/
509