1141cc406Sopenharmony_ci/* HP Scanjet 3900 series - USB layer
2141cc406Sopenharmony_ci
3141cc406Sopenharmony_ci   Copyright (C) 2005-2008 Jonathan Bravo Lopez <jkdsoft@gmail.com>
4141cc406Sopenharmony_ci
5141cc406Sopenharmony_ci   This file is part of the SANE package.
6141cc406Sopenharmony_ci
7141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
8141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License
9141cc406Sopenharmony_ci   as published by the Free Software Foundation; either version 2
10141cc406Sopenharmony_ci   of the License, or (at your option) any later version.
11141cc406Sopenharmony_ci
12141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful,
13141cc406Sopenharmony_ci   but WITHOUT ANY WARRANTY; without even the implied warranty of
14141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15141cc406Sopenharmony_ci   GNU General Public License for more details.
16141cc406Sopenharmony_ci
17141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
18141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
19141cc406Sopenharmony_ci
20141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
21141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
22141cc406Sopenharmony_ci
23141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
24141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
25141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
26141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
27141cc406Sopenharmony_ci   account of linking the SANE library code into it.
28141cc406Sopenharmony_ci
29141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
30141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
31141cc406Sopenharmony_ci   License.
32141cc406Sopenharmony_ci
33141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
34141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
35141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
36141cc406Sopenharmony_ci
37141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
38141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
39141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
40141cc406Sopenharmony_ci*/
41141cc406Sopenharmony_ci
42141cc406Sopenharmony_ci#ifndef USBLAYER
43141cc406Sopenharmony_ci
44141cc406Sopenharmony_ci#define USBLAYER
45141cc406Sopenharmony_ci
46141cc406Sopenharmony_ci#define TIMEOUT      1000
47141cc406Sopenharmony_ci#define BLK_READ_EP  0x81
48141cc406Sopenharmony_ci#define BLK_WRITE_EP 0x02
49141cc406Sopenharmony_ci
50141cc406Sopenharmony_ciSANE_Int dataline_count = 0;
51141cc406Sopenharmony_ci
52141cc406Sopenharmony_ci/* USB layer commands */
53141cc406Sopenharmony_cistatic SANE_Int usb_ctl_write (USB_Handle usb_handle, SANE_Int address,
54141cc406Sopenharmony_ci			       SANE_Byte * buffer, SANE_Int size,
55141cc406Sopenharmony_ci			       SANE_Int index);
56141cc406Sopenharmony_cistatic SANE_Int usb_ctl_read (USB_Handle usb_handle, SANE_Int address,
57141cc406Sopenharmony_ci			      SANE_Byte * buffer, SANE_Int size,
58141cc406Sopenharmony_ci			      SANE_Int index);
59141cc406Sopenharmony_ci
60141cc406Sopenharmony_ci/* Higher level commands*/
61141cc406Sopenharmony_ci
62141cc406Sopenharmony_cistatic SANE_Int IRead_Byte (USB_Handle usb_handle, SANE_Int address,
63141cc406Sopenharmony_ci			    SANE_Byte * data, SANE_Int index);
64141cc406Sopenharmony_cistatic SANE_Int IRead_Word (USB_Handle usb_handle, SANE_Int address,
65141cc406Sopenharmony_ci			    SANE_Int * data, SANE_Int index);
66141cc406Sopenharmony_cistatic SANE_Int IRead_Integer (USB_Handle usb_handle, SANE_Int address,
67141cc406Sopenharmony_ci			       SANE_Int * data, SANE_Int index);
68141cc406Sopenharmony_cistatic SANE_Int IRead_Buffer (USB_Handle usb_handle, SANE_Int address,
69141cc406Sopenharmony_ci			      SANE_Byte * buffer, SANE_Int size,
70141cc406Sopenharmony_ci			      SANE_Int index);
71141cc406Sopenharmony_cistatic SANE_Int IWrite_Byte (USB_Handle usb_handle, SANE_Int address,
72141cc406Sopenharmony_ci			     SANE_Byte data, SANE_Int index1,
73141cc406Sopenharmony_ci			     SANE_Int index2);
74141cc406Sopenharmony_cistatic SANE_Int IWrite_Word (USB_Handle usb_handle, SANE_Int address,
75141cc406Sopenharmony_ci			     SANE_Int data, SANE_Int index);
76141cc406Sopenharmony_cistatic SANE_Int IWrite_Integer (USB_Handle usb_handle, SANE_Int address,
77141cc406Sopenharmony_ci				SANE_Int data, SANE_Int index);
78141cc406Sopenharmony_cistatic SANE_Int IWrite_Buffer (USB_Handle usb_handle, SANE_Int address,
79141cc406Sopenharmony_ci			       SANE_Byte * buffer, SANE_Int size,
80141cc406Sopenharmony_ci			       SANE_Int index);
81141cc406Sopenharmony_ci
82141cc406Sopenharmony_cistatic SANE_Int Read_Byte (USB_Handle usb_handle, SANE_Int address,
83141cc406Sopenharmony_ci			   SANE_Byte * data);
84141cc406Sopenharmony_cistatic SANE_Int Read_Word (USB_Handle usb_handle, SANE_Int address,
85141cc406Sopenharmony_ci			   SANE_Int * data);
86141cc406Sopenharmony_cistatic SANE_Int Read_Integer (USB_Handle usb_handle, SANE_Int address,
87141cc406Sopenharmony_ci			      SANE_Int * data);
88141cc406Sopenharmony_cistatic SANE_Int Read_Buffer (USB_Handle usb_handle, SANE_Int address,
89141cc406Sopenharmony_ci			     SANE_Byte * buffer, SANE_Int size);
90141cc406Sopenharmony_cistatic SANE_Int Read_Bulk (USB_Handle usb_handle, SANE_Byte * buffer,
91141cc406Sopenharmony_ci			   size_t size);
92141cc406Sopenharmony_cistatic SANE_Int Write_Byte (USB_Handle usb_handle, SANE_Int address,
93141cc406Sopenharmony_ci			    SANE_Byte data);
94141cc406Sopenharmony_cistatic SANE_Int Write_Word (USB_Handle usb_handle, SANE_Int address,
95141cc406Sopenharmony_ci			    SANE_Int data);
96141cc406Sopenharmony_ci/*static SANE_Int  Write_Integer  (USB_Handle usb_handle, SANE_Int address, SANE_Int data);*/
97141cc406Sopenharmony_cistatic SANE_Int Write_Buffer (USB_Handle usb_handle, SANE_Int address,
98141cc406Sopenharmony_ci			      SANE_Byte * buffer, SANE_Int size);
99141cc406Sopenharmony_cistatic SANE_Int Write_Bulk (USB_Handle usb_handle, SANE_Byte * buffer,
100141cc406Sopenharmony_ci			    SANE_Int size);
101141cc406Sopenharmony_ci
102141cc406Sopenharmony_cistatic SANE_Int show_buffer (SANE_Int level, SANE_Byte * buffer,
103141cc406Sopenharmony_ci			     SANE_Int size);
104141cc406Sopenharmony_ci
105141cc406Sopenharmony_ci/* Implementation */
106141cc406Sopenharmony_ci
107141cc406Sopenharmony_cistatic SANE_Int
108141cc406Sopenharmony_ciIWrite_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte data,
109141cc406Sopenharmony_ci	     SANE_Int index1, SANE_Int index2)
110141cc406Sopenharmony_ci{
111141cc406Sopenharmony_ci  SANE_Int rst = ERROR;
112141cc406Sopenharmony_ci  SANE_Byte buffer[2] = { 0x00, 0x00 };
113141cc406Sopenharmony_ci
114141cc406Sopenharmony_ci  if (usb_ctl_read (usb_handle, address + 1, buffer, 0x02, index1) == 2)
115141cc406Sopenharmony_ci    {
116141cc406Sopenharmony_ci      buffer[1] = (buffer[0] & 0xff);
117141cc406Sopenharmony_ci      buffer[0] = (data & 0xff);
118141cc406Sopenharmony_ci
119141cc406Sopenharmony_ci      if (usb_ctl_write (usb_handle, address, buffer, 0x02, index2) == 2)
120141cc406Sopenharmony_ci	rst = OK;
121141cc406Sopenharmony_ci    }
122141cc406Sopenharmony_ci
123141cc406Sopenharmony_ci  return rst;
124141cc406Sopenharmony_ci}
125141cc406Sopenharmony_ci
126141cc406Sopenharmony_cistatic SANE_Int
127141cc406Sopenharmony_ciIWrite_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int data,
128141cc406Sopenharmony_ci	     SANE_Int index)
129141cc406Sopenharmony_ci{
130141cc406Sopenharmony_ci  SANE_Int rst = ERROR;
131141cc406Sopenharmony_ci  SANE_Byte buffer[2];
132141cc406Sopenharmony_ci
133141cc406Sopenharmony_ci  buffer[0] = (data & 0xff);
134141cc406Sopenharmony_ci  buffer[1] = ((data >> 8) & 0xff);
135141cc406Sopenharmony_ci
136141cc406Sopenharmony_ci  if (usb_ctl_write (usb_handle, address, buffer, 0x02, index) == 2)
137141cc406Sopenharmony_ci    rst = OK;
138141cc406Sopenharmony_ci
139141cc406Sopenharmony_ci  return rst;
140141cc406Sopenharmony_ci}
141141cc406Sopenharmony_ci
142141cc406Sopenharmony_cistatic SANE_Int
143141cc406Sopenharmony_ciIWrite_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int data,
144141cc406Sopenharmony_ci		SANE_Int index)
145141cc406Sopenharmony_ci{
146141cc406Sopenharmony_ci  SANE_Int rst = ERROR;
147141cc406Sopenharmony_ci  SANE_Byte buffer[4];
148141cc406Sopenharmony_ci
149141cc406Sopenharmony_ci  buffer[0] = (data & 0xff);
150141cc406Sopenharmony_ci  buffer[1] = ((data >> 8) & 0xff);
151141cc406Sopenharmony_ci  buffer[2] = ((data >> 16) & 0xff);
152141cc406Sopenharmony_ci  buffer[3] = ((data >> 24) & 0xff);
153141cc406Sopenharmony_ci
154141cc406Sopenharmony_ci  if (usb_ctl_write (usb_handle, address, buffer, 0x04, index) == 4)
155141cc406Sopenharmony_ci    rst = OK;
156141cc406Sopenharmony_ci
157141cc406Sopenharmony_ci  return rst;
158141cc406Sopenharmony_ci}
159141cc406Sopenharmony_ci
160141cc406Sopenharmony_cistatic SANE_Int
161141cc406Sopenharmony_ciIWrite_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
162141cc406Sopenharmony_ci	       SANE_Int size, SANE_Int index)
163141cc406Sopenharmony_ci{
164141cc406Sopenharmony_ci  SANE_Int ret = ERROR;
165141cc406Sopenharmony_ci
166141cc406Sopenharmony_ci  if (!((buffer == NULL) && (size > 0)))
167141cc406Sopenharmony_ci    if (usb_ctl_write (usb_handle, address, buffer, size, index) == size)
168141cc406Sopenharmony_ci      ret = OK;
169141cc406Sopenharmony_ci
170141cc406Sopenharmony_ci  return ret;
171141cc406Sopenharmony_ci}
172141cc406Sopenharmony_ci
173141cc406Sopenharmony_cistatic SANE_Int
174141cc406Sopenharmony_ciIRead_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte * data,
175141cc406Sopenharmony_ci	    SANE_Int index)
176141cc406Sopenharmony_ci{
177141cc406Sopenharmony_ci  SANE_Byte buffer[2] = { 0x00, 0x00 };
178141cc406Sopenharmony_ci  SANE_Int ret = ERROR;
179141cc406Sopenharmony_ci
180141cc406Sopenharmony_ci  if (data != NULL)
181141cc406Sopenharmony_ci    if (usb_ctl_read (usb_handle, address, buffer, 0x02, index) == 2)
182141cc406Sopenharmony_ci      {
183141cc406Sopenharmony_ci	*data = (SANE_Byte) (buffer[0] & 0xff);
184141cc406Sopenharmony_ci	ret = OK;
185141cc406Sopenharmony_ci      }
186141cc406Sopenharmony_ci
187141cc406Sopenharmony_ci  return ret;
188141cc406Sopenharmony_ci}
189141cc406Sopenharmony_ci
190141cc406Sopenharmony_cistatic SANE_Int
191141cc406Sopenharmony_ciIRead_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int * data,
192141cc406Sopenharmony_ci	    SANE_Int index)
193141cc406Sopenharmony_ci{
194141cc406Sopenharmony_ci  SANE_Byte buffer[2] = { 0x00, 0x00 };
195141cc406Sopenharmony_ci  SANE_Int ret = ERROR;
196141cc406Sopenharmony_ci
197141cc406Sopenharmony_ci  if (data != NULL)
198141cc406Sopenharmony_ci    if (usb_ctl_read (usb_handle, address, buffer, 0x02, index) == 2)
199141cc406Sopenharmony_ci      {
200141cc406Sopenharmony_ci	*data = ((buffer[1] << 8) & 0xffff) + (buffer[0] & 0xff);
201141cc406Sopenharmony_ci	ret = OK;
202141cc406Sopenharmony_ci      }
203141cc406Sopenharmony_ci
204141cc406Sopenharmony_ci  return ret;
205141cc406Sopenharmony_ci}
206141cc406Sopenharmony_ci
207141cc406Sopenharmony_cistatic SANE_Int
208141cc406Sopenharmony_ciIRead_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int * data,
209141cc406Sopenharmony_ci	       SANE_Int index)
210141cc406Sopenharmony_ci{
211141cc406Sopenharmony_ci  SANE_Byte buffer[4] = { 0x00, 0x00, 0x00, 0x00 };
212141cc406Sopenharmony_ci  SANE_Int ret = ERROR;
213141cc406Sopenharmony_ci
214141cc406Sopenharmony_ci  if (data != NULL)
215141cc406Sopenharmony_ci    {
216141cc406Sopenharmony_ci      *data = 0;
217141cc406Sopenharmony_ci      if (usb_ctl_read (usb_handle, address, buffer, 0x04, index) == 4)
218141cc406Sopenharmony_ci	{
219141cc406Sopenharmony_ci	  SANE_Int C;
220141cc406Sopenharmony_ci	  for (C = 3; C >= 0; C--)
221141cc406Sopenharmony_ci	    *data = ((*data << 8) + (buffer[C] & 0xff)) & 0xffffffff;
222141cc406Sopenharmony_ci	  ret = OK;
223141cc406Sopenharmony_ci	}
224141cc406Sopenharmony_ci    }
225141cc406Sopenharmony_ci
226141cc406Sopenharmony_ci  return ret;
227141cc406Sopenharmony_ci}
228141cc406Sopenharmony_ci
229141cc406Sopenharmony_cistatic SANE_Int
230141cc406Sopenharmony_ciIRead_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
231141cc406Sopenharmony_ci	      SANE_Int size, SANE_Int index)
232141cc406Sopenharmony_ci{
233141cc406Sopenharmony_ci  SANE_Int ret = ERROR;
234141cc406Sopenharmony_ci
235141cc406Sopenharmony_ci  if (buffer != NULL)
236141cc406Sopenharmony_ci    if (usb_ctl_read (usb_handle, address, buffer, size, index) == size)
237141cc406Sopenharmony_ci      ret = OK;
238141cc406Sopenharmony_ci
239141cc406Sopenharmony_ci  return ret;
240141cc406Sopenharmony_ci}
241141cc406Sopenharmony_ci
242141cc406Sopenharmony_cistatic SANE_Int
243141cc406Sopenharmony_ciWrite_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte data)
244141cc406Sopenharmony_ci{
245141cc406Sopenharmony_ci  return IWrite_Byte (usb_handle, address, data, 0x100, 0);
246141cc406Sopenharmony_ci}
247141cc406Sopenharmony_ci
248141cc406Sopenharmony_cistatic SANE_Int
249141cc406Sopenharmony_ciWrite_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int data)
250141cc406Sopenharmony_ci{
251141cc406Sopenharmony_ci  return IWrite_Word (usb_handle, address, data, 0);
252141cc406Sopenharmony_ci}
253141cc406Sopenharmony_ci
254141cc406Sopenharmony_ci/*static SANE_Int Write_Integer(USB_Handle usb_handle, SANE_Int address, SANE_Int data)
255141cc406Sopenharmony_ci{
256141cc406Sopenharmony_ci	return IWrite_Integer(usb_handle, address, data, 0);
257141cc406Sopenharmony_ci}*/
258141cc406Sopenharmony_ci
259141cc406Sopenharmony_cistatic SANE_Int
260141cc406Sopenharmony_ciWrite_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
261141cc406Sopenharmony_ci	      SANE_Int size)
262141cc406Sopenharmony_ci{
263141cc406Sopenharmony_ci  return IWrite_Buffer (usb_handle, address, buffer, size, 0);
264141cc406Sopenharmony_ci}
265141cc406Sopenharmony_ci
266141cc406Sopenharmony_cistatic SANE_Int
267141cc406Sopenharmony_ciRead_Byte (USB_Handle usb_handle, SANE_Int address, SANE_Byte * data)
268141cc406Sopenharmony_ci{
269141cc406Sopenharmony_ci  return IRead_Byte (usb_handle, address, data, 0x100);
270141cc406Sopenharmony_ci}
271141cc406Sopenharmony_ci
272141cc406Sopenharmony_cistatic SANE_Int
273141cc406Sopenharmony_ciRead_Word (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
274141cc406Sopenharmony_ci{
275141cc406Sopenharmony_ci  return IRead_Word (usb_handle, address, data, 0x100);
276141cc406Sopenharmony_ci}
277141cc406Sopenharmony_ci
278141cc406Sopenharmony_cistatic SANE_Int
279141cc406Sopenharmony_ciRead_Integer (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
280141cc406Sopenharmony_ci{
281141cc406Sopenharmony_ci  return IRead_Integer (usb_handle, address, data, 0x100);
282141cc406Sopenharmony_ci}
283141cc406Sopenharmony_ci
284141cc406Sopenharmony_cistatic SANE_Int
285141cc406Sopenharmony_ciRead_Buffer (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
286141cc406Sopenharmony_ci	     SANE_Int size)
287141cc406Sopenharmony_ci{
288141cc406Sopenharmony_ci  return IRead_Buffer (usb_handle, address, buffer, size, 0x100);
289141cc406Sopenharmony_ci}
290141cc406Sopenharmony_ci
291141cc406Sopenharmony_cistatic SANE_Int
292141cc406Sopenharmony_ciWrite_Bulk (USB_Handle usb_handle, SANE_Byte * buffer, SANE_Int size)
293141cc406Sopenharmony_ci{
294141cc406Sopenharmony_ci  SANE_Int rst = ERROR;
295141cc406Sopenharmony_ci
296141cc406Sopenharmony_ci  if (buffer != NULL)
297141cc406Sopenharmony_ci    {
298141cc406Sopenharmony_ci      dataline_count++;
299141cc406Sopenharmony_ci      DBG (DBG_CTL, "%06i BLK DO: %i. bytes\n", dataline_count, size);
300141cc406Sopenharmony_ci      show_buffer (4, buffer, size);
301141cc406Sopenharmony_ci
302141cc406Sopenharmony_ci#ifdef STANDALONE
303141cc406Sopenharmony_ci      if (usb_handle != NULL)
304141cc406Sopenharmony_ci	if (usb_bulk_write
305141cc406Sopenharmony_ci	    (usb_handle, BLK_WRITE_EP, (char *) buffer, size,
306141cc406Sopenharmony_ci	     TIMEOUT) == size)
307141cc406Sopenharmony_ci	  rst = OK;
308141cc406Sopenharmony_ci#else
309141cc406Sopenharmony_ci      if (usb_handle != -1)
310141cc406Sopenharmony_ci	{
311141cc406Sopenharmony_ci	  size_t mysize = size;
312141cc406Sopenharmony_ci	  if (sanei_usb_write_bulk (usb_handle, buffer, &mysize) ==
313141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
314141cc406Sopenharmony_ci	    rst = OK;
315141cc406Sopenharmony_ci	}
316141cc406Sopenharmony_ci#endif
317141cc406Sopenharmony_ci    }
318141cc406Sopenharmony_ci
319141cc406Sopenharmony_ci  if (rst != OK)
320141cc406Sopenharmony_ci    DBG (DBG_CTL, "             : Write_Bulk error\n");
321141cc406Sopenharmony_ci
322141cc406Sopenharmony_ci  return rst;
323141cc406Sopenharmony_ci}
324141cc406Sopenharmony_ci
325141cc406Sopenharmony_cistatic SANE_Int
326141cc406Sopenharmony_ciRead_Bulk (USB_Handle usb_handle, SANE_Byte * buffer, size_t size)
327141cc406Sopenharmony_ci{
328141cc406Sopenharmony_ci  SANE_Int rst = ERROR;
329141cc406Sopenharmony_ci
330141cc406Sopenharmony_ci  if (buffer != NULL)
331141cc406Sopenharmony_ci    {
332141cc406Sopenharmony_ci      dataline_count++;
333141cc406Sopenharmony_ci      DBG (DBG_CTL, "%06i BLK DI: Buffer length = %lu. bytes\n",
334141cc406Sopenharmony_ci	   dataline_count, (u_long) size);
335141cc406Sopenharmony_ci
336141cc406Sopenharmony_ci#ifdef STANDALONE
337141cc406Sopenharmony_ci      if (usb_handle != NULL)
338141cc406Sopenharmony_ci	rst =
339141cc406Sopenharmony_ci	  usb_bulk_read (usb_handle, BLK_READ_EP, (char *) buffer, size,
340141cc406Sopenharmony_ci			 TIMEOUT);
341141cc406Sopenharmony_ci#else
342141cc406Sopenharmony_ci      if (usb_handle != -1)
343141cc406Sopenharmony_ci	if (sanei_usb_read_bulk (usb_handle, buffer, &size) ==
344141cc406Sopenharmony_ci	    SANE_STATUS_GOOD)
345141cc406Sopenharmony_ci	  rst = size;
346141cc406Sopenharmony_ci#endif
347141cc406Sopenharmony_ci    }
348141cc406Sopenharmony_ci
349141cc406Sopenharmony_ci  if (rst < 0)
350141cc406Sopenharmony_ci    DBG (DBG_CTL, "             : Read_Bulk error\n");
351141cc406Sopenharmony_ci  else
352141cc406Sopenharmony_ci    show_buffer (4, buffer, rst);
353141cc406Sopenharmony_ci
354141cc406Sopenharmony_ci  return rst;
355141cc406Sopenharmony_ci}
356141cc406Sopenharmony_ci
357141cc406Sopenharmony_cistatic SANE_Int
358141cc406Sopenharmony_ciusb_ctl_write (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
359141cc406Sopenharmony_ci	       SANE_Int size, SANE_Int index)
360141cc406Sopenharmony_ci{
361141cc406Sopenharmony_ci  SANE_Int rst = ERROR;
362141cc406Sopenharmony_ci
363141cc406Sopenharmony_ci  dataline_count++;
364141cc406Sopenharmony_ci  DBG (DBG_CTL, "%06i CTL DO: 40 04 %04x %04x %04x\n",
365141cc406Sopenharmony_ci       dataline_count, address & 0xffff, index, size);
366141cc406Sopenharmony_ci  show_buffer (DBG_CTL, buffer, size);
367141cc406Sopenharmony_ci
368141cc406Sopenharmony_ci#ifdef STANDALONE
369141cc406Sopenharmony_ci  if (usb_handle != NULL)
370141cc406Sopenharmony_ci    rst = usb_control_msg (usb_handle, 0x40,	/* Request type */
371141cc406Sopenharmony_ci			   0x04,	/* Request      */
372141cc406Sopenharmony_ci			   address,	/* Value        */
373141cc406Sopenharmony_ci			   index,	/* Index        */
374141cc406Sopenharmony_ci			   (char *) buffer,	/* Buffer       */
375141cc406Sopenharmony_ci			   size,	/* Size         */
376141cc406Sopenharmony_ci			   TIMEOUT);
377141cc406Sopenharmony_ci#else
378141cc406Sopenharmony_ci  if (usb_handle != -1)
379141cc406Sopenharmony_ci    {
380141cc406Sopenharmony_ci      if (sanei_usb_control_msg (usb_handle, 0x40,	/* Request type */
381141cc406Sopenharmony_ci				 0x04,	/* Request      */
382141cc406Sopenharmony_ci				 address,	/* Value        */
383141cc406Sopenharmony_ci				 index,	/* Index        */
384141cc406Sopenharmony_ci				 size,	/* Size         */
385141cc406Sopenharmony_ci				 buffer)	/* Buffer       */
386141cc406Sopenharmony_ci	  == SANE_STATUS_GOOD)
387141cc406Sopenharmony_ci	rst = size;
388141cc406Sopenharmony_ci      else
389141cc406Sopenharmony_ci	rst = -1;
390141cc406Sopenharmony_ci    }
391141cc406Sopenharmony_ci#endif
392141cc406Sopenharmony_ci
393141cc406Sopenharmony_ci  if (rst < 0)
394141cc406Sopenharmony_ci    DBG (DBG_CTL, "             : Error, returned %i\n", rst);
395141cc406Sopenharmony_ci
396141cc406Sopenharmony_ci  return rst;
397141cc406Sopenharmony_ci}
398141cc406Sopenharmony_ci
399141cc406Sopenharmony_cistatic SANE_Int
400141cc406Sopenharmony_ciusb_ctl_read (USB_Handle usb_handle, SANE_Int address, SANE_Byte * buffer,
401141cc406Sopenharmony_ci	      SANE_Int size, SANE_Int index)
402141cc406Sopenharmony_ci{
403141cc406Sopenharmony_ci  SANE_Int rst;
404141cc406Sopenharmony_ci
405141cc406Sopenharmony_ci  rst = ERROR;
406141cc406Sopenharmony_ci
407141cc406Sopenharmony_ci  dataline_count++;
408141cc406Sopenharmony_ci  DBG (DBG_CTL, "%06i CTL DI: c0 04 %04x %04x %04x\n",
409141cc406Sopenharmony_ci       dataline_count, address & 0xffff, index, size);
410141cc406Sopenharmony_ci
411141cc406Sopenharmony_ci#ifdef STANDALONE
412141cc406Sopenharmony_ci  if (usb_handle != NULL)
413141cc406Sopenharmony_ci    rst = usb_control_msg (usb_handle, 0xc0,	/* Request type */
414141cc406Sopenharmony_ci			   0x04,	/* Request      */
415141cc406Sopenharmony_ci			   address,	/* Value        */
416141cc406Sopenharmony_ci			   index,	/* Index        */
417141cc406Sopenharmony_ci			   (char *) buffer,	/* Buffer       */
418141cc406Sopenharmony_ci			   size,	/* Size         */
419141cc406Sopenharmony_ci			   TIMEOUT);
420141cc406Sopenharmony_ci#else
421141cc406Sopenharmony_ci  if (usb_handle != -1)
422141cc406Sopenharmony_ci    {
423141cc406Sopenharmony_ci      if (sanei_usb_control_msg (usb_handle, 0xc0,	/* Request type */
424141cc406Sopenharmony_ci				 0x04,	/* Request      */
425141cc406Sopenharmony_ci				 address,	/* Value        */
426141cc406Sopenharmony_ci				 index,	/* Index        */
427141cc406Sopenharmony_ci				 size,	/* Size         */
428141cc406Sopenharmony_ci				 buffer)	/* Buffer       */
429141cc406Sopenharmony_ci	  == SANE_STATUS_GOOD)
430141cc406Sopenharmony_ci	rst = size;
431141cc406Sopenharmony_ci      else
432141cc406Sopenharmony_ci	rst = -1;
433141cc406Sopenharmony_ci    }
434141cc406Sopenharmony_ci#endif
435141cc406Sopenharmony_ci
436141cc406Sopenharmony_ci  if (rst < 0)
437141cc406Sopenharmony_ci    DBG (DBG_CTL, "             : Error, returned %i\n", rst);
438141cc406Sopenharmony_ci  else
439141cc406Sopenharmony_ci    show_buffer (DBG_CTL, buffer, rst);
440141cc406Sopenharmony_ci
441141cc406Sopenharmony_ci  return rst;
442141cc406Sopenharmony_ci}
443141cc406Sopenharmony_ci
444141cc406Sopenharmony_cistatic SANE_Int
445141cc406Sopenharmony_cishow_buffer (SANE_Int level, SANE_Byte * buffer, SANE_Int size)
446141cc406Sopenharmony_ci{
447141cc406Sopenharmony_ci  if (DBG_LEVEL >= level)
448141cc406Sopenharmony_ci    {
449141cc406Sopenharmony_ci      char *sline = NULL;
450141cc406Sopenharmony_ci      char *sdata = NULL;
451141cc406Sopenharmony_ci      SANE_Int cont, data, offset = 0, col = 0;
452141cc406Sopenharmony_ci
453141cc406Sopenharmony_ci      if ((size > 0) && (buffer != NULL))
454141cc406Sopenharmony_ci	{
455141cc406Sopenharmony_ci	  sline = (char *) malloc (256);
456141cc406Sopenharmony_ci	  if (sline != NULL)
457141cc406Sopenharmony_ci	    {
458141cc406Sopenharmony_ci	      sdata = (char *) malloc (256);
459141cc406Sopenharmony_ci	      if (sdata != NULL)
460141cc406Sopenharmony_ci		{
461141cc406Sopenharmony_ci		  memset (sline, 0, 256);
462141cc406Sopenharmony_ci		  for (cont = 0; cont < size; cont++)
463141cc406Sopenharmony_ci		    {
464141cc406Sopenharmony_ci		      if (col == 0)
465141cc406Sopenharmony_ci			{
466141cc406Sopenharmony_ci			  if (cont == 0)
467141cc406Sopenharmony_ci			    snprintf (sline, 255, "           BF: ");
468141cc406Sopenharmony_ci			  else
469141cc406Sopenharmony_ci			    snprintf (sline, 255, "               ");
470141cc406Sopenharmony_ci			}
471141cc406Sopenharmony_ci		      data = (buffer[cont] & 0xff);
472141cc406Sopenharmony_ci		      snprintf (sdata, 255, "%02x ", data);
473141cc406Sopenharmony_ci		      sline = strcat (sline, sdata);
474141cc406Sopenharmony_ci		      col++;
475141cc406Sopenharmony_ci		      offset++;
476141cc406Sopenharmony_ci		      if (col == 8)
477141cc406Sopenharmony_ci			{
478141cc406Sopenharmony_ci			  col = 0;
479141cc406Sopenharmony_ci			  snprintf (sdata, 255, " : %i\n", offset - 8);
480141cc406Sopenharmony_ci			  sline = strcat (sline, sdata);
481141cc406Sopenharmony_ci			  DBG (level, "%s", sline);
482141cc406Sopenharmony_ci			  memset (sline, 0, 256);
483141cc406Sopenharmony_ci			}
484141cc406Sopenharmony_ci		    }
485141cc406Sopenharmony_ci		  if (col > 0)
486141cc406Sopenharmony_ci		    {
487141cc406Sopenharmony_ci		      for (cont = col; cont < 8; cont++)
488141cc406Sopenharmony_ci			{
489141cc406Sopenharmony_ci			  snprintf (sdata, 255, "-- ");
490141cc406Sopenharmony_ci			  sline = strcat (sline, sdata);
491141cc406Sopenharmony_ci			  offset++;
492141cc406Sopenharmony_ci			}
493141cc406Sopenharmony_ci		      snprintf (sdata, 255, " : %i\n", offset - 8);
494141cc406Sopenharmony_ci		      sline = strcat (sline, sdata);
495141cc406Sopenharmony_ci		      DBG (level, "%s", sline);
496141cc406Sopenharmony_ci		      memset (sline, 0, 256);
497141cc406Sopenharmony_ci		    }
498141cc406Sopenharmony_ci		  free (sdata);
499141cc406Sopenharmony_ci		}
500141cc406Sopenharmony_ci	      free (sline);
501141cc406Sopenharmony_ci	    }
502141cc406Sopenharmony_ci	}
503141cc406Sopenharmony_ci      else
504141cc406Sopenharmony_ci	DBG (level, "           BF: Empty buffer\n");
505141cc406Sopenharmony_ci    }
506141cc406Sopenharmony_ci  return OK;
507141cc406Sopenharmony_ci}
508141cc406Sopenharmony_ci#endif /*USBLAYER*/
509