1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy.
2141cc406Sopenharmony_ci   Copyright (C) 2003 James Perry
3141cc406Sopenharmony_ci   This file is part of the SANE package.
4141cc406Sopenharmony_ci
5141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
6141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
7141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
8141cc406Sopenharmony_ci   License, or (at your option) any later version.
9141cc406Sopenharmony_ci
10141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
11141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
12141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13141cc406Sopenharmony_ci   General Public License for more details.
14141cc406Sopenharmony_ci
15141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
16141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17141cc406Sopenharmony_ci
18141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
19141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
20141cc406Sopenharmony_ci
21141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
22141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
23141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
24141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
25141cc406Sopenharmony_ci   account of linking the SANE library code into it.
26141cc406Sopenharmony_ci
27141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
28141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
29141cc406Sopenharmony_ci   License.
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
32141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
33141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
34141cc406Sopenharmony_ci
35141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
36141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
37141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
38141cc406Sopenharmony_ci
39141cc406Sopenharmony_ci   This file implements the Mustek SCSI-over-parallel port protocol
40141cc406Sopenharmony_ci   used by, for example, the Paragon 600 II EP
41141cc406Sopenharmony_ci*/
42141cc406Sopenharmony_ci
43141cc406Sopenharmony_ci
44141cc406Sopenharmony_ci/**************************************************************************/
45141cc406Sopenharmony_ci#include "../include/sane/config.h"
46141cc406Sopenharmony_ci
47141cc406Sopenharmony_ci#include <ctype.h>
48141cc406Sopenharmony_ci#include <errno.h>
49141cc406Sopenharmony_ci#include <fcntl.h>
50141cc406Sopenharmony_ci#include <limits.h>
51141cc406Sopenharmony_ci#include <signal.h>
52141cc406Sopenharmony_ci#include <stdio.h>
53141cc406Sopenharmony_ci#include <stdlib.h>
54141cc406Sopenharmony_ci#include <string.h>
55141cc406Sopenharmony_ci#include <unistd.h>
56141cc406Sopenharmony_ci
57141cc406Sopenharmony_ci#include <sys/time.h>
58141cc406Sopenharmony_ci#include <sys/types.h>
59141cc406Sopenharmony_ci#include <sys/wait.h>
60141cc406Sopenharmony_ci
61141cc406Sopenharmony_ci#include <time.h>
62141cc406Sopenharmony_ci
63141cc406Sopenharmony_ci#include "../include/sane/sane.h"
64141cc406Sopenharmony_ci#include "../include/sane/sanei.h"
65141cc406Sopenharmony_ci#include "../include/sane/saneopts.h"
66141cc406Sopenharmony_ci#include "../include/sane/sanei_debug.h"
67141cc406Sopenharmony_ci#include "../include/sane/sanei_pa4s2.h"
68141cc406Sopenharmony_ci
69141cc406Sopenharmony_ci/*
70141cc406Sopenharmony_ci * Number of times to retry sending a SCSI command before giving up
71141cc406Sopenharmony_ci */
72141cc406Sopenharmony_ci#define MUSTEK_SCSI_PP_NUM_RETRIES 4
73141cc406Sopenharmony_ci
74141cc406Sopenharmony_ci/*
75141cc406Sopenharmony_ci * Internal middle-level API functionality
76141cc406Sopenharmony_ci */
77141cc406Sopenharmony_cistatic int mustek_scsi_pp_timeout = 5000;
78141cc406Sopenharmony_ci
79141cc406Sopenharmony_ci/* FIXME: use same method as mustek.c ? */
80141cc406Sopenharmony_cistatic int
81141cc406Sopenharmony_cimustek_scsi_pp_get_time ()
82141cc406Sopenharmony_ci{
83141cc406Sopenharmony_ci  struct timeval tv;
84141cc406Sopenharmony_ci  int retval;
85141cc406Sopenharmony_ci
86141cc406Sopenharmony_ci  gettimeofday (&tv, 0);
87141cc406Sopenharmony_ci
88141cc406Sopenharmony_ci  retval = tv.tv_sec * 1000 + tv.tv_usec / 1000;
89141cc406Sopenharmony_ci
90141cc406Sopenharmony_ci  return retval;
91141cc406Sopenharmony_ci}
92141cc406Sopenharmony_ci
93141cc406Sopenharmony_cistatic u_char mustek_scsi_pp_register = 0;
94141cc406Sopenharmony_ci
95141cc406Sopenharmony_ci
96141cc406Sopenharmony_cistatic SANE_Status
97141cc406Sopenharmony_cimustek_scsi_pp_select_register (int fd, u_char reg)
98141cc406Sopenharmony_ci{
99141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_select_register: selecting register %d on fd %d\n",
100141cc406Sopenharmony_ci       reg, fd);
101141cc406Sopenharmony_ci
102141cc406Sopenharmony_ci  mustek_scsi_pp_register = reg;
103141cc406Sopenharmony_ci
104141cc406Sopenharmony_ci  return sanei_pa4s2_scsi_pp_reg_select (fd, reg);
105141cc406Sopenharmony_ci}
106141cc406Sopenharmony_ci
107141cc406Sopenharmony_cistatic SANE_Status
108141cc406Sopenharmony_cimustek_scsi_pp_wait_for_valid_status (int fd)
109141cc406Sopenharmony_ci{
110141cc406Sopenharmony_ci  int start_time;
111141cc406Sopenharmony_ci  u_char status;
112141cc406Sopenharmony_ci
113141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_valid_status: entering\n");
114141cc406Sopenharmony_ci
115141cc406Sopenharmony_ci  start_time = mustek_scsi_pp_get_time ();
116141cc406Sopenharmony_ci
117141cc406Sopenharmony_ci  do
118141cc406Sopenharmony_ci    {
119141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
120141cc406Sopenharmony_ci	{
121141cc406Sopenharmony_ci	  DBG (2,
122141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_valid_status: I/O error while getting status\n");
123141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
124141cc406Sopenharmony_ci	}
125141cc406Sopenharmony_ci
126141cc406Sopenharmony_ci      status &= 0xf0;
127141cc406Sopenharmony_ci
128141cc406Sopenharmony_ci      if ((status != 0xf0) && (!(status & 0x40)) && (status & 0x20))
129141cc406Sopenharmony_ci	{
130141cc406Sopenharmony_ci	  DBG (5,
131141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_valid_status: returning success\n");
132141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
133141cc406Sopenharmony_ci	}
134141cc406Sopenharmony_ci    }
135141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - start_time) < mustek_scsi_pp_timeout);
136141cc406Sopenharmony_ci
137141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_valid_status: timed out\n");
138141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
139141cc406Sopenharmony_ci}
140141cc406Sopenharmony_ci
141141cc406Sopenharmony_cistatic SANE_Status
142141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_5_set (int fd)
143141cc406Sopenharmony_ci{
144141cc406Sopenharmony_ci  int t;
145141cc406Sopenharmony_ci  u_char status;
146141cc406Sopenharmony_ci
147141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_5_set: entering\n");
148141cc406Sopenharmony_ci
149141cc406Sopenharmony_ci  t = mustek_scsi_pp_get_time ();
150141cc406Sopenharmony_ci
151141cc406Sopenharmony_ci  do
152141cc406Sopenharmony_ci    {
153141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
154141cc406Sopenharmony_ci	{
155141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_set: I/O error\n");
156141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
157141cc406Sopenharmony_ci	}
158141cc406Sopenharmony_ci      if (status & 0x20)
159141cc406Sopenharmony_ci	{
160141cc406Sopenharmony_ci	  DBG (5,
161141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_status_bit_5_set: returning success\n");
162141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
163141cc406Sopenharmony_ci	}
164141cc406Sopenharmony_ci    }
165141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout);
166141cc406Sopenharmony_ci
167141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_set: timed out\n");
168141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
169141cc406Sopenharmony_ci}
170141cc406Sopenharmony_ci
171141cc406Sopenharmony_cistatic SANE_Status
172141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_5_clear (int fd)
173141cc406Sopenharmony_ci{
174141cc406Sopenharmony_ci  int t;
175141cc406Sopenharmony_ci  u_char status;
176141cc406Sopenharmony_ci
177141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_5_clear: entering\n");
178141cc406Sopenharmony_ci
179141cc406Sopenharmony_ci  t = mustek_scsi_pp_get_time ();
180141cc406Sopenharmony_ci
181141cc406Sopenharmony_ci  do
182141cc406Sopenharmony_ci    {
183141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
184141cc406Sopenharmony_ci	{
185141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_clear: I/O error\n");
186141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
187141cc406Sopenharmony_ci	}
188141cc406Sopenharmony_ci
189141cc406Sopenharmony_ci      if (!(status & 0x20))
190141cc406Sopenharmony_ci	{
191141cc406Sopenharmony_ci	  DBG (5,
192141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_status_bit_5_clear: returning success\n");
193141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
194141cc406Sopenharmony_ci	}
195141cc406Sopenharmony_ci    }
196141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout);
197141cc406Sopenharmony_ci
198141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_clear: timed out\n");
199141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
200141cc406Sopenharmony_ci}
201141cc406Sopenharmony_ci
202141cc406Sopenharmony_cistatic SANE_Status
203141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_7_set (int fd)
204141cc406Sopenharmony_ci{
205141cc406Sopenharmony_ci  int t;
206141cc406Sopenharmony_ci  u_char status;
207141cc406Sopenharmony_ci
208141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_7_set: entering\n");
209141cc406Sopenharmony_ci
210141cc406Sopenharmony_ci  t = mustek_scsi_pp_get_time ();
211141cc406Sopenharmony_ci  do
212141cc406Sopenharmony_ci    {
213141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
214141cc406Sopenharmony_ci	{
215141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_set: I/O error\n");
216141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
217141cc406Sopenharmony_ci	}
218141cc406Sopenharmony_ci      if (status & 0x80)
219141cc406Sopenharmony_ci	{
220141cc406Sopenharmony_ci	  DBG (5,
221141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_status_bit_7_set: returning success\n");
222141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
223141cc406Sopenharmony_ci	}
224141cc406Sopenharmony_ci    }
225141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout);
226141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 0);
227141cc406Sopenharmony_ci
228141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_set: timed out\n");
229141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
230141cc406Sopenharmony_ci}
231141cc406Sopenharmony_ci
232141cc406Sopenharmony_cistatic SANE_Status
233141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_7_clear (int fd)
234141cc406Sopenharmony_ci{
235141cc406Sopenharmony_ci  int t;
236141cc406Sopenharmony_ci  u_char status;
237141cc406Sopenharmony_ci
238141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_7_clear: entering\n");
239141cc406Sopenharmony_ci
240141cc406Sopenharmony_ci  t = mustek_scsi_pp_get_time ();
241141cc406Sopenharmony_ci  do
242141cc406Sopenharmony_ci    {
243141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
244141cc406Sopenharmony_ci	{
245141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_clear: I/O error\n");
246141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
247141cc406Sopenharmony_ci	}
248141cc406Sopenharmony_ci      if (!(status & 0x80))
249141cc406Sopenharmony_ci	{
250141cc406Sopenharmony_ci	  DBG (5,
251141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_status_bit_7_clear: returning success\n");
252141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
253141cc406Sopenharmony_ci	}
254141cc406Sopenharmony_ci    }
255141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout);
256141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 0);
257141cc406Sopenharmony_ci
258141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_clear: timed out\n");
259141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
260141cc406Sopenharmony_ci}
261141cc406Sopenharmony_ci
262141cc406Sopenharmony_cistatic SANE_Status
263141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_4_set (int fd)
264141cc406Sopenharmony_ci{
265141cc406Sopenharmony_ci  int t;
266141cc406Sopenharmony_ci  u_char status;
267141cc406Sopenharmony_ci
268141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_4_set: entering\n");
269141cc406Sopenharmony_ci
270141cc406Sopenharmony_ci  if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
271141cc406Sopenharmony_ci    {
272141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: I/O error\n");
273141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
274141cc406Sopenharmony_ci    }
275141cc406Sopenharmony_ci
276141cc406Sopenharmony_ci  if (status & 0x10)
277141cc406Sopenharmony_ci    {
278141cc406Sopenharmony_ci      DBG (5,
279141cc406Sopenharmony_ci	   "mustek_scsi_pp_wait_for_status_bit_4_set: returning success\n");
280141cc406Sopenharmony_ci      return SANE_STATUS_GOOD;
281141cc406Sopenharmony_ci    }
282141cc406Sopenharmony_ci
283141cc406Sopenharmony_ci  t = mustek_scsi_pp_get_time ();
284141cc406Sopenharmony_ci  do
285141cc406Sopenharmony_ci    {
286141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
287141cc406Sopenharmony_ci	{
288141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: I/O error\n");
289141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
290141cc406Sopenharmony_ci	}
291141cc406Sopenharmony_ci      if (status & 0x40)
292141cc406Sopenharmony_ci	{
293141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: bit 6 set\n");
294141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
295141cc406Sopenharmony_ci	}
296141cc406Sopenharmony_ci      if (status & 0x10)
297141cc406Sopenharmony_ci	{
298141cc406Sopenharmony_ci	  DBG (5,
299141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_status_bit_4_set: returning success\n");
300141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
301141cc406Sopenharmony_ci	}
302141cc406Sopenharmony_ci    }
303141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout);
304141cc406Sopenharmony_ci
305141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: timed out\n");
306141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
307141cc406Sopenharmony_ci}
308141cc406Sopenharmony_ci
309141cc406Sopenharmony_cistatic SANE_Status
310141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_4_clear (int fd)
311141cc406Sopenharmony_ci{
312141cc406Sopenharmony_ci  int t;
313141cc406Sopenharmony_ci  u_char status;
314141cc406Sopenharmony_ci
315141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_4_clear: entering\n");
316141cc406Sopenharmony_ci
317141cc406Sopenharmony_ci  if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
318141cc406Sopenharmony_ci    {
319141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: I/O error\n");
320141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
321141cc406Sopenharmony_ci    }
322141cc406Sopenharmony_ci
323141cc406Sopenharmony_ci  if (!(status & 0x10))
324141cc406Sopenharmony_ci    {
325141cc406Sopenharmony_ci      DBG (5,
326141cc406Sopenharmony_ci	   "mustek_scsi_pp_wait_for_status_bit_4_clear: returning success\n");
327141cc406Sopenharmony_ci      return SANE_STATUS_GOOD;
328141cc406Sopenharmony_ci    }
329141cc406Sopenharmony_ci
330141cc406Sopenharmony_ci  t = mustek_scsi_pp_get_time ();
331141cc406Sopenharmony_ci  do
332141cc406Sopenharmony_ci    {
333141cc406Sopenharmony_ci      if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
334141cc406Sopenharmony_ci	{
335141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: I/O error\n");
336141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
337141cc406Sopenharmony_ci	}
338141cc406Sopenharmony_ci      if (status & 0x40)
339141cc406Sopenharmony_ci	{
340141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: bit 6 set\n");
341141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
342141cc406Sopenharmony_ci	}
343141cc406Sopenharmony_ci      if (!(status & 0x10))
344141cc406Sopenharmony_ci	{
345141cc406Sopenharmony_ci	  DBG (5,
346141cc406Sopenharmony_ci	       "mustek_scsi_pp_wait_for_status_bit_4_clear: returning success\n");
347141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
348141cc406Sopenharmony_ci	}
349141cc406Sopenharmony_ci    }
350141cc406Sopenharmony_ci  while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout);
351141cc406Sopenharmony_ci
352141cc406Sopenharmony_ci  DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: timed out\n");
353141cc406Sopenharmony_ci  return SANE_STATUS_DEVICE_BUSY;
354141cc406Sopenharmony_ci}
355141cc406Sopenharmony_ci
356141cc406Sopenharmony_cistatic u_char mustek_scsi_pp_bit_4_state = 0;
357141cc406Sopenharmony_ci
358141cc406Sopenharmony_cistatic SANE_Status
359141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_4_toggle (int fd)
360141cc406Sopenharmony_ci{
361141cc406Sopenharmony_ci  SANE_Status result;
362141cc406Sopenharmony_ci
363141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_wait_for_status_bit_4_toggle: entering\n");
364141cc406Sopenharmony_ci
365141cc406Sopenharmony_ci  mustek_scsi_pp_bit_4_state ^= 0xff;
366141cc406Sopenharmony_ci  if (mustek_scsi_pp_bit_4_state)
367141cc406Sopenharmony_ci    {
368141cc406Sopenharmony_ci      DBG (5,
369141cc406Sopenharmony_ci	   "mustek_scsi_pp_wait_for_status_bit_4_toggle: waiting for set\n");
370141cc406Sopenharmony_ci      result = mustek_scsi_pp_wait_for_status_bit_4_set (fd);
371141cc406Sopenharmony_ci      mustek_scsi_pp_timeout = 5000;
372141cc406Sopenharmony_ci    }
373141cc406Sopenharmony_ci  else
374141cc406Sopenharmony_ci    {
375141cc406Sopenharmony_ci      DBG (5,
376141cc406Sopenharmony_ci	   "mustek_scsi_pp_wait_for_status_bit_4_toggle: waiting for clear\n");
377141cc406Sopenharmony_ci      result = mustek_scsi_pp_wait_for_status_bit_4_clear (fd);
378141cc406Sopenharmony_ci    }
379141cc406Sopenharmony_ci
380141cc406Sopenharmony_ci  return result;
381141cc406Sopenharmony_ci}
382141cc406Sopenharmony_ci
383141cc406Sopenharmony_cistatic SANE_Status
384141cc406Sopenharmony_cimustek_scsi_pp_send_command_byte (int fd, u_char cmd)
385141cc406Sopenharmony_ci{
386141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_send_command byte: sending 0x%02X\n", cmd);
387141cc406Sopenharmony_ci
388141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 0);
389141cc406Sopenharmony_ci
390141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_7_clear (fd) != SANE_STATUS_GOOD)
391141cc406Sopenharmony_ci    {
392141cc406Sopenharmony_ci      mustek_scsi_pp_select_register (fd, 0);
393141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
394141cc406Sopenharmony_ci    }
395141cc406Sopenharmony_ci
396141cc406Sopenharmony_ci  if (sanei_pa4s2_writebyte (fd, mustek_scsi_pp_register, cmd) !=
397141cc406Sopenharmony_ci      SANE_STATUS_GOOD)
398141cc406Sopenharmony_ci    {
399141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
400141cc406Sopenharmony_ci    }
401141cc406Sopenharmony_ci
402141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 1);
403141cc406Sopenharmony_ci
404141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_7_set (fd) != SANE_STATUS_GOOD)
405141cc406Sopenharmony_ci    {
406141cc406Sopenharmony_ci      mustek_scsi_pp_select_register (fd, 0);
407141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
408141cc406Sopenharmony_ci    }
409141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 0);
410141cc406Sopenharmony_ci
411141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_send_command_byte: returning success\n");
412141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
413141cc406Sopenharmony_ci}
414141cc406Sopenharmony_ci
415141cc406Sopenharmony_cistatic u_char
416141cc406Sopenharmony_cimustek_scsi_pp_read_response (int fd)
417141cc406Sopenharmony_ci{
418141cc406Sopenharmony_ci  u_char result;
419141cc406Sopenharmony_ci
420141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_read_response: entering\n");
421141cc406Sopenharmony_ci
422141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_7_set (fd) != SANE_STATUS_GOOD)
423141cc406Sopenharmony_ci    {
424141cc406Sopenharmony_ci      mustek_scsi_pp_select_register (fd, 0);
425141cc406Sopenharmony_ci      return 0xff;
426141cc406Sopenharmony_ci    }
427141cc406Sopenharmony_ci
428141cc406Sopenharmony_ci  if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != SANE_STATUS_GOOD)
429141cc406Sopenharmony_ci    {
430141cc406Sopenharmony_ci      return 0xff;
431141cc406Sopenharmony_ci    }
432141cc406Sopenharmony_ci  if (sanei_pa4s2_readbyte (fd, &result) != SANE_STATUS_GOOD)
433141cc406Sopenharmony_ci    {
434141cc406Sopenharmony_ci      return 0xff;
435141cc406Sopenharmony_ci    }
436141cc406Sopenharmony_ci  if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD)
437141cc406Sopenharmony_ci    {
438141cc406Sopenharmony_ci      return 0xff;
439141cc406Sopenharmony_ci    }
440141cc406Sopenharmony_ci
441141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 1);
442141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_7_clear (fd) != SANE_STATUS_GOOD)
443141cc406Sopenharmony_ci    {
444141cc406Sopenharmony_ci      result = 0xff;
445141cc406Sopenharmony_ci    }
446141cc406Sopenharmony_ci  mustek_scsi_pp_select_register (fd, 0);
447141cc406Sopenharmony_ci
448141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_read_response: returning 0x%02X\n", result);
449141cc406Sopenharmony_ci  return result;
450141cc406Sopenharmony_ci}
451141cc406Sopenharmony_ci
452141cc406Sopenharmony_cistatic SANE_Status
453141cc406Sopenharmony_cimustek_scsi_pp_check_response (int fd)
454141cc406Sopenharmony_ci{
455141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_5_clear (fd) != SANE_STATUS_GOOD)
456141cc406Sopenharmony_ci    {
457141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
458141cc406Sopenharmony_ci    }
459141cc406Sopenharmony_ci
460141cc406Sopenharmony_ci  if (mustek_scsi_pp_read_response (fd) != 0xA5)
461141cc406Sopenharmony_ci    {
462141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_check_response: response!=0xA5\n");
463141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
464141cc406Sopenharmony_ci    }
465141cc406Sopenharmony_ci
466141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_check_response: returning success\n");
467141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
468141cc406Sopenharmony_ci}
469141cc406Sopenharmony_ci
470141cc406Sopenharmony_cistatic SANE_Status
471141cc406Sopenharmony_cimustek_scsi_pp_send_command (int fd, const u_char * cmd)
472141cc406Sopenharmony_ci{
473141cc406Sopenharmony_ci  int i;
474141cc406Sopenharmony_ci  signed char checksum;
475141cc406Sopenharmony_ci
476141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_send_command: sending SCSI command 0x%02X\n",
477141cc406Sopenharmony_ci       cmd[0]);
478141cc406Sopenharmony_ci
479141cc406Sopenharmony_ci  /* Set timeout depending on command type */
480141cc406Sopenharmony_ci  switch (cmd[0])
481141cc406Sopenharmony_ci    {
482141cc406Sopenharmony_ci    case 0xf:
483141cc406Sopenharmony_ci    case 0x8:
484141cc406Sopenharmony_ci      mustek_scsi_pp_timeout = 1000;
485141cc406Sopenharmony_ci      break;
486141cc406Sopenharmony_ci    case 0x2:
487141cc406Sopenharmony_ci      mustek_scsi_pp_timeout = 80;
488141cc406Sopenharmony_ci      break;
489141cc406Sopenharmony_ci    case 0x12:
490141cc406Sopenharmony_ci    case 0x3:
491141cc406Sopenharmony_ci    case 0x11:
492141cc406Sopenharmony_ci      mustek_scsi_pp_timeout = 500;
493141cc406Sopenharmony_ci      break;
494141cc406Sopenharmony_ci    default:
495141cc406Sopenharmony_ci      mustek_scsi_pp_timeout = 1000;
496141cc406Sopenharmony_ci      break;
497141cc406Sopenharmony_ci    }
498141cc406Sopenharmony_ci
499141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_5_set (fd) != SANE_STATUS_GOOD)
500141cc406Sopenharmony_ci    {
501141cc406Sopenharmony_ci      DBG (2,
502141cc406Sopenharmony_ci	   "mustek_scsi_pp_send_command: timed out waiting for bit 5 to set\n");
503141cc406Sopenharmony_ci      return SANE_STATUS_DEVICE_BUSY;
504141cc406Sopenharmony_ci    }
505141cc406Sopenharmony_ci
506141cc406Sopenharmony_ci  checksum = 0;
507141cc406Sopenharmony_ci  for (i = 0; i < 6; i++)
508141cc406Sopenharmony_ci    {
509141cc406Sopenharmony_ci      if (mustek_scsi_pp_send_command_byte (fd, cmd[i]) != SANE_STATUS_GOOD)
510141cc406Sopenharmony_ci	{
511141cc406Sopenharmony_ci	  DBG (2,
512141cc406Sopenharmony_ci	       "mustek_scsi_pp_send_command: error sending byte %d (0x%02X)\n",
513141cc406Sopenharmony_ci	       i, cmd[i]);
514141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
515141cc406Sopenharmony_ci	}
516141cc406Sopenharmony_ci      checksum += cmd[i];
517141cc406Sopenharmony_ci    }
518141cc406Sopenharmony_ci  if (mustek_scsi_pp_send_command_byte (fd, -checksum) != SANE_STATUS_GOOD)
519141cc406Sopenharmony_ci    {
520141cc406Sopenharmony_ci      DBG (2,
521141cc406Sopenharmony_ci	   "mustek_scsi_pp_send_command: error sending checksum (0x%02X)\n",
522141cc406Sopenharmony_ci	   -checksum);
523141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
524141cc406Sopenharmony_ci    }
525141cc406Sopenharmony_ci  return mustek_scsi_pp_check_response (fd);
526141cc406Sopenharmony_ci}
527141cc406Sopenharmony_ci
528141cc406Sopenharmony_cistatic SANE_Status
529141cc406Sopenharmony_cimustek_scsi_pp_send_data_block (int fd, const u_char * data, int len)
530141cc406Sopenharmony_ci{
531141cc406Sopenharmony_ci  int i;
532141cc406Sopenharmony_ci  signed char checksum;
533141cc406Sopenharmony_ci
534141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_send_data_block: sending block of length %d\n",
535141cc406Sopenharmony_ci       len);
536141cc406Sopenharmony_ci
537141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_5_set (fd) != SANE_STATUS_GOOD)
538141cc406Sopenharmony_ci    {
539141cc406Sopenharmony_ci      DBG (2,
540141cc406Sopenharmony_ci	   "mustek_scsi_pp_send_data_block: timed out waiting for bit 5 to set\n");
541141cc406Sopenharmony_ci      return SANE_STATUS_DEVICE_BUSY;
542141cc406Sopenharmony_ci    }
543141cc406Sopenharmony_ci
544141cc406Sopenharmony_ci  checksum = 0;
545141cc406Sopenharmony_ci  for (i = 0; i < len; i++)
546141cc406Sopenharmony_ci    {
547141cc406Sopenharmony_ci      if (mustek_scsi_pp_send_command_byte (fd, data[i]) != SANE_STATUS_GOOD)
548141cc406Sopenharmony_ci	{
549141cc406Sopenharmony_ci	  DBG (2,
550141cc406Sopenharmony_ci	       "mustek_scsi_pp_send_data_block: error sending byte %d (0x%02X)\n",
551141cc406Sopenharmony_ci	       i, data[i]);
552141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
553141cc406Sopenharmony_ci	}
554141cc406Sopenharmony_ci      checksum += data[i];
555141cc406Sopenharmony_ci    }
556141cc406Sopenharmony_ci  if (mustek_scsi_pp_send_command_byte (fd, -checksum) != SANE_STATUS_GOOD)
557141cc406Sopenharmony_ci    {
558141cc406Sopenharmony_ci      DBG (2,
559141cc406Sopenharmony_ci	   "mustek_scsi_pp_send_data_block: error sending checksum (0x%02X)\n",
560141cc406Sopenharmony_ci	   -checksum);
561141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
562141cc406Sopenharmony_ci    }
563141cc406Sopenharmony_ci  return mustek_scsi_pp_check_response (fd);
564141cc406Sopenharmony_ci}
565141cc406Sopenharmony_ci
566141cc406Sopenharmony_cistatic SANE_Status
567141cc406Sopenharmony_cimustek_scsi_pp_read_data_block (int fd, u_char * buffer, int len)
568141cc406Sopenharmony_ci{
569141cc406Sopenharmony_ci  int i;
570141cc406Sopenharmony_ci  signed char checksum;
571141cc406Sopenharmony_ci
572141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_read_data_block: reading block of length %d\n",
573141cc406Sopenharmony_ci       len);
574141cc406Sopenharmony_ci
575141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_5_clear (fd) != SANE_STATUS_GOOD)
576141cc406Sopenharmony_ci    {
577141cc406Sopenharmony_ci      DBG (2,
578141cc406Sopenharmony_ci	   "mustek_scsi_pp_read_data_block: timed out waiting for bit 5 to clear\n");
579141cc406Sopenharmony_ci      return SANE_STATUS_DEVICE_BUSY;
580141cc406Sopenharmony_ci    }
581141cc406Sopenharmony_ci
582141cc406Sopenharmony_ci  checksum = 0;
583141cc406Sopenharmony_ci  for (i = 0; i < len; i++)
584141cc406Sopenharmony_ci    {
585141cc406Sopenharmony_ci      buffer[i] = mustek_scsi_pp_read_response (fd);
586141cc406Sopenharmony_ci      checksum += buffer[i];
587141cc406Sopenharmony_ci    }
588141cc406Sopenharmony_ci  if ((signed char) mustek_scsi_pp_read_response (fd) != (-checksum))
589141cc406Sopenharmony_ci    {
590141cc406Sopenharmony_ci      mustek_scsi_pp_send_command_byte (fd, 0xff);
591141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_read_data_block: checksums do not match\n");
592141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
593141cc406Sopenharmony_ci    }
594141cc406Sopenharmony_ci  if (mustek_scsi_pp_wait_for_status_bit_5_set (fd) != SANE_STATUS_GOOD)
595141cc406Sopenharmony_ci    {
596141cc406Sopenharmony_ci      DBG (2,
597141cc406Sopenharmony_ci	   "mustek_scsi_pp_read_data_block: error waiting for bit 5 to set\n");
598141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
599141cc406Sopenharmony_ci    }
600141cc406Sopenharmony_ci  if (mustek_scsi_pp_send_command_byte (fd, 0) != SANE_STATUS_GOOD)
601141cc406Sopenharmony_ci    {
602141cc406Sopenharmony_ci      mustek_scsi_pp_send_command_byte (fd, 0xff);
603141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_read_data_block: error sending final 0 byte\n");
604141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
605141cc406Sopenharmony_ci    }
606141cc406Sopenharmony_ci
607141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_read_data_block: returning success\n");
608141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
609141cc406Sopenharmony_ci}
610141cc406Sopenharmony_ci
611141cc406Sopenharmony_ci
612141cc406Sopenharmony_ci
613141cc406Sopenharmony_ci/*
614141cc406Sopenharmony_ci * Externally visible functions
615141cc406Sopenharmony_ci */
616141cc406Sopenharmony_ciSANE_Status
617141cc406Sopenharmony_cimustek_scsi_pp_open (const char *dev, int *fd)
618141cc406Sopenharmony_ci{
619141cc406Sopenharmony_ci  SANE_Status status;
620141cc406Sopenharmony_ci
621141cc406Sopenharmony_ci  status = sanei_pa4s2_scsi_pp_open (dev, fd);
622141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
623141cc406Sopenharmony_ci    {
624141cc406Sopenharmony_ci      DBG (5, "mustek_scsi_pp_open: device %s opened as fd %d\n", dev, *fd);
625141cc406Sopenharmony_ci    }
626141cc406Sopenharmony_ci  else
627141cc406Sopenharmony_ci    {
628141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_open: error opening device %s\n", dev);
629141cc406Sopenharmony_ci    }
630141cc406Sopenharmony_ci  return status;
631141cc406Sopenharmony_ci}
632141cc406Sopenharmony_ci
633141cc406Sopenharmony_cistatic void
634141cc406Sopenharmony_cimustek_scsi_pp_close (int fd)
635141cc406Sopenharmony_ci{
636141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_close: closing fd %d\n", fd);
637141cc406Sopenharmony_ci  sanei_pa4s2_close (fd);
638141cc406Sopenharmony_ci}
639141cc406Sopenharmony_ci
640141cc406Sopenharmony_cistatic void
641141cc406Sopenharmony_cimustek_scsi_pp_exit (void)
642141cc406Sopenharmony_ci{
643141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_exit: entering\n");
644141cc406Sopenharmony_ci}
645141cc406Sopenharmony_ci
646141cc406Sopenharmony_cistatic SANE_Status
647141cc406Sopenharmony_cimustek_scsi_pp_test_ready (int fd)
648141cc406Sopenharmony_ci{
649141cc406Sopenharmony_ci  u_char status;
650141cc406Sopenharmony_ci  SANE_Status retval;
651141cc406Sopenharmony_ci
652141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_test_ready: entering with fd=%d\n", fd);
653141cc406Sopenharmony_ci
654141cc406Sopenharmony_ci  if (sanei_pa4s2_enable (fd, SANE_TRUE) != SANE_STATUS_GOOD)
655141cc406Sopenharmony_ci    {
656141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_test_ready: error enabling scanner\n");
657141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
658141cc406Sopenharmony_ci    }
659141cc406Sopenharmony_ci
660141cc406Sopenharmony_ci  if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD)
661141cc406Sopenharmony_ci    {
662141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_test_ready: error getting status\n");
663141cc406Sopenharmony_ci      sanei_pa4s2_enable (fd, SANE_FALSE);
664141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
665141cc406Sopenharmony_ci    }
666141cc406Sopenharmony_ci
667141cc406Sopenharmony_ci  retval = SANE_STATUS_GOOD;
668141cc406Sopenharmony_ci
669141cc406Sopenharmony_ci  status &= 0xf0;
670141cc406Sopenharmony_ci
671141cc406Sopenharmony_ci  if (status == 0xf0)
672141cc406Sopenharmony_ci    {
673141cc406Sopenharmony_ci      retval = SANE_STATUS_DEVICE_BUSY;
674141cc406Sopenharmony_ci    }
675141cc406Sopenharmony_ci  if (status & 0x40)
676141cc406Sopenharmony_ci    {
677141cc406Sopenharmony_ci      retval = SANE_STATUS_DEVICE_BUSY;
678141cc406Sopenharmony_ci    }
679141cc406Sopenharmony_ci  if (!(status & 0x20))
680141cc406Sopenharmony_ci    {
681141cc406Sopenharmony_ci      retval = SANE_STATUS_DEVICE_BUSY;
682141cc406Sopenharmony_ci    }
683141cc406Sopenharmony_ci
684141cc406Sopenharmony_ci  if (sanei_pa4s2_enable (fd, SANE_FALSE) != SANE_STATUS_GOOD)
685141cc406Sopenharmony_ci    {
686141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_test_ready: error disabling scanner\n");
687141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
688141cc406Sopenharmony_ci    }
689141cc406Sopenharmony_ci
690141cc406Sopenharmony_ci  if (retval == SANE_STATUS_GOOD)
691141cc406Sopenharmony_ci    {
692141cc406Sopenharmony_ci      DBG (5, "mustek_scsi_pp_test_ready: returning SANE_STATUS_GOOD\n");
693141cc406Sopenharmony_ci    }
694141cc406Sopenharmony_ci  else
695141cc406Sopenharmony_ci    {
696141cc406Sopenharmony_ci      DBG (5,
697141cc406Sopenharmony_ci	   "mustek_scsi_pp_test_ready: returning SANE_STATUS_DEVICE_BUSY\n");
698141cc406Sopenharmony_ci    }
699141cc406Sopenharmony_ci
700141cc406Sopenharmony_ci  return retval;
701141cc406Sopenharmony_ci}
702141cc406Sopenharmony_ci
703141cc406Sopenharmony_cistatic SANE_Status
704141cc406Sopenharmony_cimustek_scsi_pp_cmd (int fd, const void *src, size_t src_size,
705141cc406Sopenharmony_ci		    void *dst, size_t * dst_size)
706141cc406Sopenharmony_ci{
707141cc406Sopenharmony_ci  SANE_Status stat;
708141cc406Sopenharmony_ci  int num_tries = 0;
709141cc406Sopenharmony_ci  static u_char scan_options = 0;
710141cc406Sopenharmony_ci  const u_char *cmd;
711141cc406Sopenharmony_ci  u_char stop_cmd[6] = { 0x1b, 0, 0, 0, 0, 0 };
712141cc406Sopenharmony_ci  int max_tries;
713141cc406Sopenharmony_ci
714141cc406Sopenharmony_ci  max_tries = MUSTEK_SCSI_PP_NUM_RETRIES;
715141cc406Sopenharmony_ci
716141cc406Sopenharmony_ci  cmd = (const u_char *) src;
717141cc406Sopenharmony_ci
718141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_cmd: sending command 0x%02X to device %d\n",
719141cc406Sopenharmony_ci       cmd[0], fd);
720141cc406Sopenharmony_ci
721141cc406Sopenharmony_ci  if (sanei_pa4s2_enable (fd, SANE_TRUE) != SANE_STATUS_GOOD)
722141cc406Sopenharmony_ci    {
723141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_cmd: error enabling scanner\n");
724141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
725141cc406Sopenharmony_ci    }
726141cc406Sopenharmony_ci
727141cc406Sopenharmony_ci  if (cmd[0] == 0x1b)
728141cc406Sopenharmony_ci    {
729141cc406Sopenharmony_ci      if (!(cmd[4] & 0x1))
730141cc406Sopenharmony_ci	{
731141cc406Sopenharmony_ci	  unsigned char c;
732141cc406Sopenharmony_ci	  int i;
733141cc406Sopenharmony_ci
734141cc406Sopenharmony_ci	  DBG (5, "mustek_scsi_pp_cmd: doing stop-specific stuff\n");
735141cc406Sopenharmony_ci
736141cc406Sopenharmony_ci	  /*
737141cc406Sopenharmony_ci	   * Remembers what flags were sent with a 'start' command, and
738141cc406Sopenharmony_ci	   * replicate them with a stop command.
739141cc406Sopenharmony_ci	   */
740141cc406Sopenharmony_ci	  stop_cmd[4] = scan_options & 0xfe;
741141cc406Sopenharmony_ci	  cmd = &stop_cmd[0];
742141cc406Sopenharmony_ci
743141cc406Sopenharmony_ci	  /*
744141cc406Sopenharmony_ci	   * In color mode at least, the scanner doesn't seem to like stopping at
745141cc406Sopenharmony_ci	   * the end. It's a bit of a horrible hack, but reading loads of bytes and
746141cc406Sopenharmony_ci	   * allowing 20 tries for the stop command is the only way I've found that
747141cc406Sopenharmony_ci	   * solves the problem.
748141cc406Sopenharmony_ci	   */
749141cc406Sopenharmony_ci	  max_tries = 20;
750141cc406Sopenharmony_ci
751141cc406Sopenharmony_ci	  if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) !=
752141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
753141cc406Sopenharmony_ci	    {
754141cc406Sopenharmony_ci	      DBG (2, "mustek_scsi_pp_cmd: error in readbegin for stop\n");
755141cc406Sopenharmony_ci	    }
756141cc406Sopenharmony_ci
757141cc406Sopenharmony_ci	  for (i = 0; i < 10000; i++)
758141cc406Sopenharmony_ci	    {
759141cc406Sopenharmony_ci	      if (sanei_pa4s2_readbyte (fd, &c) != SANE_STATUS_GOOD)
760141cc406Sopenharmony_ci		{
761141cc406Sopenharmony_ci		  DBG (2,
762141cc406Sopenharmony_ci		       "mustek_scsi_pp_cmd: error reading byte for stop\n");
763141cc406Sopenharmony_ci		  break;
764141cc406Sopenharmony_ci		}
765141cc406Sopenharmony_ci	      DBG (5, "mustek_scsi_pp_cmd: successfully read byte %d\n", i);
766141cc406Sopenharmony_ci	    }
767141cc406Sopenharmony_ci	  if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD)
768141cc406Sopenharmony_ci	    {
769141cc406Sopenharmony_ci	      DBG (2, "mustek_scsi_pp_cmd: error in readend for stop\n");
770141cc406Sopenharmony_ci	    }
771141cc406Sopenharmony_ci	}
772141cc406Sopenharmony_ci    }
773141cc406Sopenharmony_ci
774141cc406Sopenharmony_ci  if (cmd[0] == 0x08)
775141cc406Sopenharmony_ci    {
776141cc406Sopenharmony_ci      DBG (5, "mustek_scsi_pp_cmd: doing read-specific stuff\n");
777141cc406Sopenharmony_ci      mustek_scsi_pp_timeout = 30000;
778141cc406Sopenharmony_ci      mustek_scsi_pp_bit_4_state = 0xff;
779141cc406Sopenharmony_ci    }
780141cc406Sopenharmony_ci
781141cc406Sopenharmony_ci  /*
782141cc406Sopenharmony_ci   * Send the command itself in one block, then any extra input data in a second
783141cc406Sopenharmony_ci   * block. Not sure if that's necessary.
784141cc406Sopenharmony_ci   */
785141cc406Sopenharmony_ci  if (src_size < 6)
786141cc406Sopenharmony_ci    {
787141cc406Sopenharmony_ci      sanei_pa4s2_enable (fd, SANE_FALSE);
788141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_cmd: source size is only %lu (<6)\n", (u_long) src_size);
789141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
790141cc406Sopenharmony_ci    }
791141cc406Sopenharmony_ci
792141cc406Sopenharmony_ci  /*
793141cc406Sopenharmony_ci   * Retry the command several times, as occasionally it doesn't
794141cc406Sopenharmony_ci   * work first time.
795141cc406Sopenharmony_ci   */
796141cc406Sopenharmony_ci  do
797141cc406Sopenharmony_ci    {
798141cc406Sopenharmony_ci      stat = mustek_scsi_pp_send_command (fd, cmd);
799141cc406Sopenharmony_ci      num_tries++;
800141cc406Sopenharmony_ci    }
801141cc406Sopenharmony_ci  while ((stat != SANE_STATUS_GOOD) && (num_tries < max_tries));
802141cc406Sopenharmony_ci
803141cc406Sopenharmony_ci  if (stat != SANE_STATUS_GOOD)
804141cc406Sopenharmony_ci    {
805141cc406Sopenharmony_ci      sanei_pa4s2_enable (fd, SANE_FALSE);
806141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_cmd: sending command failed\n");
807141cc406Sopenharmony_ci      return stat;
808141cc406Sopenharmony_ci    }
809141cc406Sopenharmony_ci
810141cc406Sopenharmony_ci  if (src_size > 6)
811141cc406Sopenharmony_ci    {
812141cc406Sopenharmony_ci      DBG (5, "mustek_scsi_pp_cmd: sending data block of length %lu\n",
813141cc406Sopenharmony_ci	   (u_long) (src_size - 6));
814141cc406Sopenharmony_ci
815141cc406Sopenharmony_ci      stat =
816141cc406Sopenharmony_ci	mustek_scsi_pp_send_data_block (fd, ((const u_char *) src) + 6,
817141cc406Sopenharmony_ci					src_size - 6);
818141cc406Sopenharmony_ci      if (stat != SANE_STATUS_GOOD)
819141cc406Sopenharmony_ci	{
820141cc406Sopenharmony_ci	  sanei_pa4s2_enable (fd, SANE_FALSE);
821141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_cmd: sending data block failed\n");
822141cc406Sopenharmony_ci	  return stat;
823141cc406Sopenharmony_ci	}
824141cc406Sopenharmony_ci    }
825141cc406Sopenharmony_ci
826141cc406Sopenharmony_ci
827141cc406Sopenharmony_ci  if (dst)
828141cc406Sopenharmony_ci    {
829141cc406Sopenharmony_ci      unsigned int length;
830141cc406Sopenharmony_ci
831141cc406Sopenharmony_ci      /* check buffer is big enough to receive data */
832141cc406Sopenharmony_ci      length = (cmd[3] << 8) | cmd[4];
833141cc406Sopenharmony_ci
834141cc406Sopenharmony_ci      DBG (5, "mustek_scsi_pp_cmd: reading %d bytes\n", length);
835141cc406Sopenharmony_ci
836141cc406Sopenharmony_ci      if (length > *dst_size)
837141cc406Sopenharmony_ci	{
838141cc406Sopenharmony_ci	  sanei_pa4s2_enable (fd, SANE_FALSE);
839141cc406Sopenharmony_ci	  DBG (2,
840141cc406Sopenharmony_ci	       "mustek_scsi_pp_cmd: buffer (size %lu) not big enough for data (size %d)\n",
841141cc406Sopenharmony_ci	       (u_long) *dst_size, length);
842141cc406Sopenharmony_ci	  return SANE_STATUS_INVAL;
843141cc406Sopenharmony_ci	}
844141cc406Sopenharmony_ci
845141cc406Sopenharmony_ci      stat = mustek_scsi_pp_read_data_block (fd, dst, length);
846141cc406Sopenharmony_ci      if (stat != SANE_STATUS_GOOD)
847141cc406Sopenharmony_ci	{
848141cc406Sopenharmony_ci	  DBG (2, "mustek_scsi_pp_cmd: error reading data block\n");
849141cc406Sopenharmony_ci	}
850141cc406Sopenharmony_ci    }
851141cc406Sopenharmony_ci
852141cc406Sopenharmony_ci  if (cmd[0] == 0x1b)
853141cc406Sopenharmony_ci    {
854141cc406Sopenharmony_ci      if (cmd[4] & 0x1)
855141cc406Sopenharmony_ci	{
856141cc406Sopenharmony_ci	  DBG (5, "mustek_scsi_pp_cmd: doing start-specific stuff\n");
857141cc406Sopenharmony_ci
858141cc406Sopenharmony_ci	  scan_options = cmd[4];
859141cc406Sopenharmony_ci
860141cc406Sopenharmony_ci	  /* 'Start' command - wait for valid status */
861141cc406Sopenharmony_ci	  mustek_scsi_pp_timeout = 70000;
862141cc406Sopenharmony_ci	  stat = mustek_scsi_pp_wait_for_valid_status (fd);
863141cc406Sopenharmony_ci
864141cc406Sopenharmony_ci	  if (stat != SANE_STATUS_GOOD)
865141cc406Sopenharmony_ci	    {
866141cc406Sopenharmony_ci	      DBG (2,
867141cc406Sopenharmony_ci		   "mustek_scsi_pp_cmd: error waiting for valid status after start\n");
868141cc406Sopenharmony_ci	    }
869141cc406Sopenharmony_ci	}
870141cc406Sopenharmony_ci    }
871141cc406Sopenharmony_ci
872141cc406Sopenharmony_ci  if (sanei_pa4s2_enable (fd, SANE_FALSE) != SANE_STATUS_GOOD)
873141cc406Sopenharmony_ci    {
874141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_cmd: error disabling scanner\n");
875141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
876141cc406Sopenharmony_ci    }
877141cc406Sopenharmony_ci
878141cc406Sopenharmony_ci  if (stat == SANE_STATUS_GOOD)
879141cc406Sopenharmony_ci    {
880141cc406Sopenharmony_ci      DBG (5, "mustek_scsi_pp_cmd: returning success\n");
881141cc406Sopenharmony_ci    }
882141cc406Sopenharmony_ci
883141cc406Sopenharmony_ci  return stat;
884141cc406Sopenharmony_ci}
885141cc406Sopenharmony_ci
886141cc406Sopenharmony_cistatic SANE_Status
887141cc406Sopenharmony_cimustek_scsi_pp_rdata (int fd, int planes, SANE_Byte * buf, int lines, int bpl)
888141cc406Sopenharmony_ci{
889141cc406Sopenharmony_ci  int i, j;
890141cc406Sopenharmony_ci
891141cc406Sopenharmony_ci  DBG (5,
892141cc406Sopenharmony_ci       "mustek_scsi_pp_rdata: reading %d lines at %d bpl, %d planes from %d\n",
893141cc406Sopenharmony_ci       lines, bpl, planes, fd);
894141cc406Sopenharmony_ci
895141cc406Sopenharmony_ci  if ((planes != 1) && (planes != 3))
896141cc406Sopenharmony_ci    {
897141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_rdata: invalid number of planes (%d)\n",
898141cc406Sopenharmony_ci	   planes);
899141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
900141cc406Sopenharmony_ci    }
901141cc406Sopenharmony_ci
902141cc406Sopenharmony_ci  if (sanei_pa4s2_enable (fd, SANE_TRUE) != SANE_STATUS_GOOD)
903141cc406Sopenharmony_ci    {
904141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_rdata: error enabling scanner\n");
905141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
906141cc406Sopenharmony_ci    }
907141cc406Sopenharmony_ci
908141cc406Sopenharmony_ci  for (i = 0; i < lines; i++)
909141cc406Sopenharmony_ci    {
910141cc406Sopenharmony_ci      if (planes == 3)
911141cc406Sopenharmony_ci	{
912141cc406Sopenharmony_ci	  if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) !=
913141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
914141cc406Sopenharmony_ci	    {
915141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
916141cc406Sopenharmony_ci	      DBG (2,
917141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error waiting for bit 4 toggle for red, line %d\n",
918141cc406Sopenharmony_ci		   i);
919141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
920141cc406Sopenharmony_ci	    }
921141cc406Sopenharmony_ci	  if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) !=
922141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
923141cc406Sopenharmony_ci	    {
924141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
925141cc406Sopenharmony_ci	      DBG (2,
926141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error in readbegin for red, line %d\n",
927141cc406Sopenharmony_ci		   i);
928141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
929141cc406Sopenharmony_ci	    }
930141cc406Sopenharmony_ci	  for (j = 0; j < (bpl / 3); j++)
931141cc406Sopenharmony_ci	    {
932141cc406Sopenharmony_ci	      if (sanei_pa4s2_readbyte (fd, &buf[j]) != SANE_STATUS_GOOD)
933141cc406Sopenharmony_ci		{
934141cc406Sopenharmony_ci		  sanei_pa4s2_readend (fd);
935141cc406Sopenharmony_ci		  sanei_pa4s2_enable (fd, SANE_FALSE);
936141cc406Sopenharmony_ci		  DBG (2,
937141cc406Sopenharmony_ci		       "mustek_scsi_pp_rdata: error reading red byte, line %d, byte %d\n",
938141cc406Sopenharmony_ci		       i, j);
939141cc406Sopenharmony_ci		  return SANE_STATUS_IO_ERROR;
940141cc406Sopenharmony_ci		}
941141cc406Sopenharmony_ci	    }
942141cc406Sopenharmony_ci	  if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD)
943141cc406Sopenharmony_ci	    {
944141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
945141cc406Sopenharmony_ci	      DBG (2,
946141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error in readend for red, line %d\n",
947141cc406Sopenharmony_ci		   i);
948141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
949141cc406Sopenharmony_ci	    }
950141cc406Sopenharmony_ci
951141cc406Sopenharmony_ci
952141cc406Sopenharmony_ci	  if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) !=
953141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
954141cc406Sopenharmony_ci	    {
955141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
956141cc406Sopenharmony_ci	      DBG (2,
957141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error waiting for bit 4 toggle for green, line %d\n",
958141cc406Sopenharmony_ci		   i);
959141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
960141cc406Sopenharmony_ci	    }
961141cc406Sopenharmony_ci	  if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) !=
962141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
963141cc406Sopenharmony_ci	    {
964141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
965141cc406Sopenharmony_ci	      DBG (2,
966141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error in readbegin for green, line %d\n",
967141cc406Sopenharmony_ci		   i);
968141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
969141cc406Sopenharmony_ci	    }
970141cc406Sopenharmony_ci	  for (j = 0; j < (bpl / 3); j++)
971141cc406Sopenharmony_ci	    {
972141cc406Sopenharmony_ci	      if (sanei_pa4s2_readbyte (fd, &buf[j + (bpl / 3)]) !=
973141cc406Sopenharmony_ci		  SANE_STATUS_GOOD)
974141cc406Sopenharmony_ci		{
975141cc406Sopenharmony_ci		  sanei_pa4s2_readend (fd);
976141cc406Sopenharmony_ci		  sanei_pa4s2_enable (fd, SANE_FALSE);
977141cc406Sopenharmony_ci		  DBG (2,
978141cc406Sopenharmony_ci		       "mustek_scsi_pp_rdata: error reading green byte, line %d, byte %d\n",
979141cc406Sopenharmony_ci		       i, j);
980141cc406Sopenharmony_ci		  return SANE_STATUS_IO_ERROR;
981141cc406Sopenharmony_ci		}
982141cc406Sopenharmony_ci	    }
983141cc406Sopenharmony_ci	  if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD)
984141cc406Sopenharmony_ci	    {
985141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
986141cc406Sopenharmony_ci	      DBG (2,
987141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error in readend for green, line %d\n",
988141cc406Sopenharmony_ci		   i);
989141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
990141cc406Sopenharmony_ci	    }
991141cc406Sopenharmony_ci
992141cc406Sopenharmony_ci
993141cc406Sopenharmony_ci	  if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) !=
994141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
995141cc406Sopenharmony_ci	    {
996141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
997141cc406Sopenharmony_ci	      DBG (2,
998141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error waiting for bit 4 toggle for blue, line %d\n",
999141cc406Sopenharmony_ci		   i);
1000141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1001141cc406Sopenharmony_ci	    }
1002141cc406Sopenharmony_ci	  if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) !=
1003141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
1004141cc406Sopenharmony_ci	    {
1005141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
1006141cc406Sopenharmony_ci	      DBG (2,
1007141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error in readbegin for blue, line %d\n",
1008141cc406Sopenharmony_ci		   i);
1009141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1010141cc406Sopenharmony_ci	    }
1011141cc406Sopenharmony_ci	  for (j = 0; j < (bpl / 3); j++)
1012141cc406Sopenharmony_ci	    {
1013141cc406Sopenharmony_ci	      if (sanei_pa4s2_readbyte (fd, &buf[j + (2 * (bpl / 3))]) !=
1014141cc406Sopenharmony_ci		  SANE_STATUS_GOOD)
1015141cc406Sopenharmony_ci		{
1016141cc406Sopenharmony_ci		  sanei_pa4s2_readend (fd);
1017141cc406Sopenharmony_ci		  sanei_pa4s2_enable (fd, SANE_FALSE);
1018141cc406Sopenharmony_ci		  DBG (2,
1019141cc406Sopenharmony_ci		       "mustek_scsi_pp_rdata: error reading blue byte, line %d, byte %d\n",
1020141cc406Sopenharmony_ci		       i, j);
1021141cc406Sopenharmony_ci		  return SANE_STATUS_IO_ERROR;
1022141cc406Sopenharmony_ci		}
1023141cc406Sopenharmony_ci	    }
1024141cc406Sopenharmony_ci	  if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD)
1025141cc406Sopenharmony_ci	    {
1026141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
1027141cc406Sopenharmony_ci	      DBG (2,
1028141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error in readend for blue, line %d\n",
1029141cc406Sopenharmony_ci		   i);
1030141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1031141cc406Sopenharmony_ci	    }
1032141cc406Sopenharmony_ci	}
1033141cc406Sopenharmony_ci      else
1034141cc406Sopenharmony_ci	{
1035141cc406Sopenharmony_ci	  if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) !=
1036141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
1037141cc406Sopenharmony_ci	    {
1038141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
1039141cc406Sopenharmony_ci	      DBG (2,
1040141cc406Sopenharmony_ci		   "mustek_scsi_pp_rdata: error waiting for bit 4 toggle, line %d\n",
1041141cc406Sopenharmony_ci		   i);
1042141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1043141cc406Sopenharmony_ci	    }
1044141cc406Sopenharmony_ci	  if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) !=
1045141cc406Sopenharmony_ci	      SANE_STATUS_GOOD)
1046141cc406Sopenharmony_ci	    {
1047141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
1048141cc406Sopenharmony_ci	      DBG (2, "mustek_scsi_pp_rdata: error in readbegin, line %d\n",
1049141cc406Sopenharmony_ci		   i);
1050141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1051141cc406Sopenharmony_ci	    }
1052141cc406Sopenharmony_ci
1053141cc406Sopenharmony_ci	  for (j = 0; j < bpl; j++)
1054141cc406Sopenharmony_ci	    {
1055141cc406Sopenharmony_ci	      if (sanei_pa4s2_readbyte (fd, &buf[j]) != SANE_STATUS_GOOD)
1056141cc406Sopenharmony_ci		{
1057141cc406Sopenharmony_ci		  sanei_pa4s2_readend (fd);
1058141cc406Sopenharmony_ci		  sanei_pa4s2_enable (fd, SANE_FALSE);
1059141cc406Sopenharmony_ci		  DBG (2,
1060141cc406Sopenharmony_ci		       "mustek_scsi_pp_rdata: error reading byte, line %d, byte %d\n",
1061141cc406Sopenharmony_ci		       i, j);
1062141cc406Sopenharmony_ci		  return SANE_STATUS_IO_ERROR;
1063141cc406Sopenharmony_ci		}
1064141cc406Sopenharmony_ci	    }
1065141cc406Sopenharmony_ci
1066141cc406Sopenharmony_ci	  if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD)
1067141cc406Sopenharmony_ci	    {
1068141cc406Sopenharmony_ci	      sanei_pa4s2_enable (fd, SANE_FALSE);
1069141cc406Sopenharmony_ci	      DBG (2, "mustek_scsi_pp_rdata: error in readend, line %d\n", i);
1070141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1071141cc406Sopenharmony_ci	    }
1072141cc406Sopenharmony_ci	}
1073141cc406Sopenharmony_ci      buf += bpl;
1074141cc406Sopenharmony_ci    }
1075141cc406Sopenharmony_ci
1076141cc406Sopenharmony_ci  if (sanei_pa4s2_enable (fd, SANE_FALSE) != SANE_STATUS_GOOD)
1077141cc406Sopenharmony_ci    {
1078141cc406Sopenharmony_ci      DBG (2, "mustek_scsi_pp_rdata: error enabling scanner\n");
1079141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
1080141cc406Sopenharmony_ci    }
1081141cc406Sopenharmony_ci
1082141cc406Sopenharmony_ci  DBG (5, "mustek_scsi_pp_rdata: returning success\n");
1083141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1084141cc406Sopenharmony_ci}
1085