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 
50 SANE_Int dataline_count = 0;
51 
52 /* USB layer commands */
53 static SANE_Int usb_ctl_write (USB_Handle usb_handle, SANE_Int address,
54 			       SANE_Byte * buffer, SANE_Int size,
55 			       SANE_Int index);
56 static 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 
62 static SANE_Int IRead_Byte (USB_Handle usb_handle, SANE_Int address,
63 			    SANE_Byte * data, SANE_Int index);
64 static SANE_Int IRead_Word (USB_Handle usb_handle, SANE_Int address,
65 			    SANE_Int * data, SANE_Int index);
66 static SANE_Int IRead_Integer (USB_Handle usb_handle, SANE_Int address,
67 			       SANE_Int * data, SANE_Int index);
68 static SANE_Int IRead_Buffer (USB_Handle usb_handle, SANE_Int address,
69 			      SANE_Byte * buffer, SANE_Int size,
70 			      SANE_Int index);
71 static SANE_Int IWrite_Byte (USB_Handle usb_handle, SANE_Int address,
72 			     SANE_Byte data, SANE_Int index1,
73 			     SANE_Int index2);
74 static SANE_Int IWrite_Word (USB_Handle usb_handle, SANE_Int address,
75 			     SANE_Int data, SANE_Int index);
76 static SANE_Int IWrite_Integer (USB_Handle usb_handle, SANE_Int address,
77 				SANE_Int data, SANE_Int index);
78 static SANE_Int IWrite_Buffer (USB_Handle usb_handle, SANE_Int address,
79 			       SANE_Byte * buffer, SANE_Int size,
80 			       SANE_Int index);
81 
82 static SANE_Int Read_Byte (USB_Handle usb_handle, SANE_Int address,
83 			   SANE_Byte * data);
84 static SANE_Int Read_Word (USB_Handle usb_handle, SANE_Int address,
85 			   SANE_Int * data);
86 static SANE_Int Read_Integer (USB_Handle usb_handle, SANE_Int address,
87 			      SANE_Int * data);
88 static SANE_Int Read_Buffer (USB_Handle usb_handle, SANE_Int address,
89 			     SANE_Byte * buffer, SANE_Int size);
90 static SANE_Int Read_Bulk (USB_Handle usb_handle, SANE_Byte * buffer,
91 			   size_t size);
92 static SANE_Int Write_Byte (USB_Handle usb_handle, SANE_Int address,
93 			    SANE_Byte data);
94 static 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);*/
97 static SANE_Int Write_Buffer (USB_Handle usb_handle, SANE_Int address,
98 			      SANE_Byte * buffer, SANE_Int size);
99 static SANE_Int Write_Bulk (USB_Handle usb_handle, SANE_Byte * buffer,
100 			    SANE_Int size);
101 
102 static SANE_Int show_buffer (SANE_Int level, SANE_Byte * buffer,
103 			     SANE_Int size);
104 
105 /* Implementation */
106 
107 static SANE_Int
IWrite_Byte(USB_Handle usb_handle, SANE_Int address, SANE_Byte data, SANE_Int index1, SANE_Int index2)108 IWrite_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 
126 static SANE_Int
IWrite_Word(USB_Handle usb_handle, SANE_Int address, SANE_Int data, SANE_Int index)127 IWrite_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 
142 static SANE_Int
IWrite_Integer(USB_Handle usb_handle, SANE_Int address, SANE_Int data, SANE_Int index)143 IWrite_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 
160 static SANE_Int
IWrite_Buffer(USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer, SANE_Int size, SANE_Int index)161 IWrite_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 
173 static SANE_Int
IRead_Byte(USB_Handle usb_handle, SANE_Int address, SANE_Byte * data, SANE_Int index)174 IRead_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 
190 static SANE_Int
IRead_Word(USB_Handle usb_handle, SANE_Int address, SANE_Int * data, SANE_Int index)191 IRead_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 
207 static SANE_Int
IRead_Integer(USB_Handle usb_handle, SANE_Int address, SANE_Int * data, SANE_Int index)208 IRead_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 
229 static SANE_Int
IRead_Buffer(USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer, SANE_Int size, SANE_Int index)230 IRead_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 
242 static SANE_Int
Write_Byte(USB_Handle usb_handle, SANE_Int address, SANE_Byte data)243 Write_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte data)
244 {
245   return IWrite_Byte (usb_handle, address, data, 0x100, 0);
246 }
247 
248 static SANE_Int
Write_Word(USB_Handle usb_handle, SANE_Int address, SANE_Int data)249 Write_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 
259 static SANE_Int
Write_Buffer(USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer, SANE_Int size)260 Write_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 
266 static SANE_Int
Read_Byte(USB_Handle usb_handle, SANE_Int address, SANE_Byte * data)267 Read_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte * data)
268 {
269   return IRead_Byte (usb_handle, address, data, 0x100);
270 }
271 
272 static SANE_Int
Read_Word(USB_Handle usb_handle, SANE_Int address, SANE_Int * data)273 Read_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
274 {
275   return IRead_Word (usb_handle, address, data, 0x100);
276 }
277 
278 static SANE_Int
Read_Integer(USB_Handle usb_handle, SANE_Int address, SANE_Int * data)279 Read_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
280 {
281   return IRead_Integer (usb_handle, address, data, 0x100);
282 }
283 
284 static SANE_Int
Read_Buffer(USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer, SANE_Int size)285 Read_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 
291 static SANE_Int
Write_Bulk(USB_Handle usb_handle, SANE_Byte * buffer, SANE_Int size)292 Write_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 
325 static SANE_Int
Read_Bulk(USB_Handle usb_handle, SANE_Byte * buffer, size_t size)326 Read_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 
357 static SANE_Int
usb_ctl_write(USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer, SANE_Int size, SANE_Int index)358 usb_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 
399 static SANE_Int
usb_ctl_read(USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer, SANE_Int size, SANE_Int index)400 usb_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 
444 static SANE_Int
show_buffer(SANE_Int level, SANE_Byte * buffer, SANE_Int size)445 show_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