1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy.
2141cc406Sopenharmony_ci   Copyright (C) 1998 F.W. Dillema (dillema@acm.org)
3141cc406Sopenharmony_ci
4141cc406Sopenharmony_ci   This file is part of the SANE package.
5141cc406Sopenharmony_ci
6141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
7141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
8141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
9141cc406Sopenharmony_ci   License, or (at your option) any later version.
10141cc406Sopenharmony_ci
11141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
12141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
13141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14141cc406Sopenharmony_ci   General Public License for more details.
15141cc406Sopenharmony_ci
16141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
17141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
18141cc406Sopenharmony_ci
19141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
20141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
21141cc406Sopenharmony_ci
22141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
23141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
24141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
25141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
26141cc406Sopenharmony_ci   account of linking the SANE library code into it.
27141cc406Sopenharmony_ci
28141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
29141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
30141cc406Sopenharmony_ci   License.
31141cc406Sopenharmony_ci
32141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
33141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
34141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
35141cc406Sopenharmony_ci
36141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
37141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
38141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
39141cc406Sopenharmony_ci*/
40141cc406Sopenharmony_ci
41141cc406Sopenharmony_ci/*
42141cc406Sopenharmony_ci	This file implements the low-level scsi-commands.
43141cc406Sopenharmony_ci*/
44141cc406Sopenharmony_ci
45141cc406Sopenharmony_ci/* SCSI commands that the Ricoh scanners understand: */
46141cc406Sopenharmony_ci#define RICOH_SCSI_TEST_UNIT_READY	0x00
47141cc406Sopenharmony_ci#define RICOH_SCSI_SET_WINDOW	        0x24
48141cc406Sopenharmony_ci#define RICOH_SCSI_GET_WINDOW	        0x25
49141cc406Sopenharmony_ci#define RICOH_SCSI_READ_SCANNED_DATA	0x28
50141cc406Sopenharmony_ci#define RICOH_SCSI_INQUIRY		0x12
51141cc406Sopenharmony_ci#define RICOH_SCSI_MODE_SELECT		0x15
52141cc406Sopenharmony_ci#define RICOH_SCSI_START_SCAN		0x1b
53141cc406Sopenharmony_ci#define RICOH_SCSI_MODE_SENSE		0x1a
54141cc406Sopenharmony_ci#define RICOH_SCSI_GET_BUFFER_STATUS	0x34
55141cc406Sopenharmony_ci#define RICOH_SCSI_OBJECT_POSITION      0x31
56141cc406Sopenharmony_ci
57141cc406Sopenharmony_ci/* How long do we wait for scanner to have data for us */
58141cc406Sopenharmony_ci#define MAX_WAITING_TIME       15
59141cc406Sopenharmony_ci
60141cc406Sopenharmony_cistruct scsi_window_cmd {
61141cc406Sopenharmony_ci        SANE_Byte opcode;
62141cc406Sopenharmony_ci        SANE_Byte byte2;
63141cc406Sopenharmony_ci        SANE_Byte reserved[4];
64141cc406Sopenharmony_ci        SANE_Byte len[3];
65141cc406Sopenharmony_ci        SANE_Byte control;
66141cc406Sopenharmony_ci};
67141cc406Sopenharmony_ci
68141cc406Sopenharmony_cistruct scsi_mode_select_cmd {
69141cc406Sopenharmony_ci        SANE_Byte opcode;
70141cc406Sopenharmony_ci        SANE_Byte byte2;
71141cc406Sopenharmony_ci#define SMS_SP  0x01
72141cc406Sopenharmony_ci#define SMS_PF  0x10
73141cc406Sopenharmony_ci        SANE_Byte page_code; /* for mode_sense, reserved for mode_select */
74141cc406Sopenharmony_ci        SANE_Byte unused[1];
75141cc406Sopenharmony_ci        SANE_Byte len;
76141cc406Sopenharmony_ci        SANE_Byte control;
77141cc406Sopenharmony_ci};
78141cc406Sopenharmony_ci
79141cc406Sopenharmony_cistruct scsi_mode_header {
80141cc406Sopenharmony_ci         SANE_Byte data_length;   /* Sense data length */
81141cc406Sopenharmony_ci         SANE_Byte medium_type;
82141cc406Sopenharmony_ci         SANE_Byte dev_spec;
83141cc406Sopenharmony_ci         SANE_Byte blk_desc_len;
84141cc406Sopenharmony_ci};
85141cc406Sopenharmony_ci
86141cc406Sopenharmony_cistruct scsi_get_buffer_status_cmd {
87141cc406Sopenharmony_ci        SANE_Byte opcode;
88141cc406Sopenharmony_ci        SANE_Byte byte2;
89141cc406Sopenharmony_ci        SANE_Byte res[5];
90141cc406Sopenharmony_ci        SANE_Byte len[2];
91141cc406Sopenharmony_ci        SANE_Byte control;
92141cc406Sopenharmony_ci};
93141cc406Sopenharmony_ci
94141cc406Sopenharmony_cistruct scsi_status_desc {
95141cc406Sopenharmony_ci        SANE_Byte window_id;
96141cc406Sopenharmony_ci        SANE_Byte byte2;
97141cc406Sopenharmony_ci        SANE_Byte available[3];
98141cc406Sopenharmony_ci        SANE_Byte filled[3];
99141cc406Sopenharmony_ci};
100141cc406Sopenharmony_ci
101141cc406Sopenharmony_cistruct scsi_status_data {
102141cc406Sopenharmony_ci        SANE_Byte len[3];
103141cc406Sopenharmony_ci        SANE_Byte byte4;
104141cc406Sopenharmony_ci        struct scsi_status_desc desc;
105141cc406Sopenharmony_ci};
106141cc406Sopenharmony_ci
107141cc406Sopenharmony_cistruct scsi_start_scan_cmd {
108141cc406Sopenharmony_ci        SANE_Byte opcode;
109141cc406Sopenharmony_ci        SANE_Byte byte2;
110141cc406Sopenharmony_ci        SANE_Byte unused[2];
111141cc406Sopenharmony_ci        SANE_Byte len;
112141cc406Sopenharmony_ci        SANE_Byte control;
113141cc406Sopenharmony_ci};
114141cc406Sopenharmony_ci
115141cc406Sopenharmony_cistruct scsi_read_scanner_cmd {
116141cc406Sopenharmony_ci        SANE_Byte opcode;
117141cc406Sopenharmony_ci        SANE_Byte byte2;
118141cc406Sopenharmony_ci        SANE_Byte data_type;
119141cc406Sopenharmony_ci        SANE_Byte byte3;
120141cc406Sopenharmony_ci        SANE_Byte data_type_qualifier[2];
121141cc406Sopenharmony_ci        SANE_Byte len[3];
122141cc406Sopenharmony_ci        SANE_Byte control;
123141cc406Sopenharmony_ci};
124141cc406Sopenharmony_ci
125141cc406Sopenharmony_cistatic SANE_Status
126141cc406Sopenharmony_citest_unit_ready (int fd)
127141cc406Sopenharmony_ci{
128141cc406Sopenharmony_ci  static SANE_Byte cmd[6];
129141cc406Sopenharmony_ci  SANE_Status status;
130141cc406Sopenharmony_ci  DBG (11, ">> test_unit_ready\n");
131141cc406Sopenharmony_ci
132141cc406Sopenharmony_ci  cmd[0] = RICOH_SCSI_TEST_UNIT_READY;
133141cc406Sopenharmony_ci  memset (cmd, 0, sizeof (cmd));
134141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
135141cc406Sopenharmony_ci
136141cc406Sopenharmony_ci  DBG (11, "<< test_unit_ready\n");
137141cc406Sopenharmony_ci  return (status);
138141cc406Sopenharmony_ci}
139141cc406Sopenharmony_ci
140141cc406Sopenharmony_cistatic SANE_Status
141141cc406Sopenharmony_ciinquiry (int fd, void *buf, size_t  * buf_size)
142141cc406Sopenharmony_ci{
143141cc406Sopenharmony_ci  static SANE_Byte cmd[6];
144141cc406Sopenharmony_ci  SANE_Status status;
145141cc406Sopenharmony_ci  DBG (11, ">> inquiry\n");
146141cc406Sopenharmony_ci
147141cc406Sopenharmony_ci  memset (cmd, 0, sizeof (cmd));
148141cc406Sopenharmony_ci  cmd[0] = RICOH_SCSI_INQUIRY;
149141cc406Sopenharmony_ci  cmd[4] = *buf_size;
150141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
151141cc406Sopenharmony_ci
152141cc406Sopenharmony_ci  DBG (11, "<< inquiry\n");
153141cc406Sopenharmony_ci  return (status);
154141cc406Sopenharmony_ci}
155141cc406Sopenharmony_ci
156141cc406Sopenharmony_cistatic SANE_Status
157141cc406Sopenharmony_cimode_select (int fd, struct mode_pages *mp)
158141cc406Sopenharmony_ci{
159141cc406Sopenharmony_ci  static struct {
160141cc406Sopenharmony_ci    struct scsi_mode_select_cmd cmd;
161141cc406Sopenharmony_ci    struct scsi_mode_header smh;
162141cc406Sopenharmony_ci    struct mode_pages mp;
163141cc406Sopenharmony_ci  } select_cmd;
164141cc406Sopenharmony_ci  SANE_Status status;
165141cc406Sopenharmony_ci  DBG (11, ">> mode_select\n");
166141cc406Sopenharmony_ci
167141cc406Sopenharmony_ci  memset (&select_cmd, 0, sizeof (select_cmd));
168141cc406Sopenharmony_ci  select_cmd.cmd.opcode = RICOH_SCSI_MODE_SELECT;
169141cc406Sopenharmony_ci  select_cmd.cmd.byte2 |= SMS_PF;
170141cc406Sopenharmony_ci  select_cmd.cmd.len = sizeof(select_cmd.smh) + sizeof(select_cmd.mp);
171141cc406Sopenharmony_ci  memcpy (&select_cmd.mp, mp, sizeof(*mp));
172141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, &select_cmd, sizeof (select_cmd), 0, 0);
173141cc406Sopenharmony_ci
174141cc406Sopenharmony_ci  DBG (11, "<< mode_select\n");
175141cc406Sopenharmony_ci  return (status);
176141cc406Sopenharmony_ci}
177141cc406Sopenharmony_ci
178141cc406Sopenharmony_ci#if 0
179141cc406Sopenharmony_cistatic SANE_Status
180141cc406Sopenharmony_cimode_sense (int fd, struct mode_pages *mp, SANE_Byte page_code)
181141cc406Sopenharmony_ci{
182141cc406Sopenharmony_ci  static struct scsi_mode_select_cmd cmd; /* no type, we can reuse it for sensing */
183141cc406Sopenharmony_ci  static struct {
184141cc406Sopenharmony_ci    struct scsi_mode_header smh;
185141cc406Sopenharmony_ci    struct mode_pages mp;
186141cc406Sopenharmony_ci  } select_data;
187141cc406Sopenharmony_ci  static size_t select_size = sizeof(select_data);
188141cc406Sopenharmony_ci  SANE_Status status;
189141cc406Sopenharmony_ci  DBG (11, ">> mode_sense\n");
190141cc406Sopenharmony_ci
191141cc406Sopenharmony_ci  memset (&cmd, 0, sizeof (cmd));
192141cc406Sopenharmony_ci  cmd.opcode = RICOH_SCSI_MODE_SENSE;
193141cc406Sopenharmony_ci  cmd.page_code = page_code;
194141cc406Sopenharmony_ci  cmd.len =  sizeof(select_data);
195141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), &select_data, &select_size);
196141cc406Sopenharmony_ci  memcpy (mp, &select_data.mp, sizeof(*mp));
197141cc406Sopenharmony_ci
198141cc406Sopenharmony_ci  DBG (11, "<< mode_sense\n");
199141cc406Sopenharmony_ci  return (status);
200141cc406Sopenharmony_ci}
201141cc406Sopenharmony_ci#endif
202141cc406Sopenharmony_ci
203141cc406Sopenharmony_cistatic SANE_Status
204141cc406Sopenharmony_citrigger_scan (int fd)
205141cc406Sopenharmony_ci{
206141cc406Sopenharmony_ci  static struct scsi_start_scan_cmd cmd;
207141cc406Sopenharmony_ci  static char   window_id_list[1] = { '\0' }; /* scan start data out */
208141cc406Sopenharmony_ci  static size_t wl_size = 1;
209141cc406Sopenharmony_ci  SANE_Status status;
210141cc406Sopenharmony_ci  DBG (11, ">> trigger scan\n");
211141cc406Sopenharmony_ci
212141cc406Sopenharmony_ci  memset (&cmd, 0, sizeof (cmd));
213141cc406Sopenharmony_ci  cmd.opcode = RICOH_SCSI_START_SCAN;
214141cc406Sopenharmony_ci  cmd.len = wl_size;
215141cc406Sopenharmony_ci  if (wl_size)
216141cc406Sopenharmony_ci    status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), &window_id_list, &wl_size);
217141cc406Sopenharmony_ci  else
218141cc406Sopenharmony_ci    status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), 0, 0);
219141cc406Sopenharmony_ci
220141cc406Sopenharmony_ci  DBG (11, "<< trigger scan\n");
221141cc406Sopenharmony_ci  return (status);
222141cc406Sopenharmony_ci}
223141cc406Sopenharmony_ci
224141cc406Sopenharmony_cistatic SANE_Status
225141cc406Sopenharmony_ciset_window (int fd, struct ricoh_window_data *rwd)
226141cc406Sopenharmony_ci{
227141cc406Sopenharmony_ci
228141cc406Sopenharmony_ci  static struct {
229141cc406Sopenharmony_ci    struct scsi_window_cmd cmd;
230141cc406Sopenharmony_ci    struct ricoh_window_data rwd;
231141cc406Sopenharmony_ci  } win;
232141cc406Sopenharmony_ci
233141cc406Sopenharmony_ci  SANE_Status status;
234141cc406Sopenharmony_ci  DBG (11, ">> set_window\n");
235141cc406Sopenharmony_ci
236141cc406Sopenharmony_ci  memset (&win, 0, sizeof (win));
237141cc406Sopenharmony_ci  win.cmd.opcode = RICOH_SCSI_SET_WINDOW;
238141cc406Sopenharmony_ci  _lto3b(sizeof(*rwd), win.cmd.len);
239141cc406Sopenharmony_ci  memcpy (&win.rwd, rwd, sizeof(*rwd));
240141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, &win, sizeof (win), 0, 0);
241141cc406Sopenharmony_ci
242141cc406Sopenharmony_ci  DBG (11, "<< set_window\n");
243141cc406Sopenharmony_ci  return (status);
244141cc406Sopenharmony_ci}
245141cc406Sopenharmony_ci
246141cc406Sopenharmony_cistatic SANE_Status
247141cc406Sopenharmony_ciget_window (int fd, struct ricoh_window_data *rwd)
248141cc406Sopenharmony_ci{
249141cc406Sopenharmony_ci
250141cc406Sopenharmony_ci  static struct scsi_window_cmd cmd;
251141cc406Sopenharmony_ci  static size_t rwd_size;
252141cc406Sopenharmony_ci  SANE_Status status;
253141cc406Sopenharmony_ci
254141cc406Sopenharmony_ci  rwd_size = sizeof(*rwd);
255141cc406Sopenharmony_ci  DBG (11, ">> get_window datalen = %lu\n", (unsigned long) rwd_size);
256141cc406Sopenharmony_ci
257141cc406Sopenharmony_ci  memset (&cmd, 0, sizeof (cmd));
258141cc406Sopenharmony_ci  cmd.opcode = RICOH_SCSI_GET_WINDOW;
259141cc406Sopenharmony_ci#if 0
260141cc406Sopenharmony_ci  cmd.byte2 |= (SANE_Byte)0x01; /* set Single bit to get one window desc. */
261141cc406Sopenharmony_ci#endif
262141cc406Sopenharmony_ci  _lto3b(rwd_size, cmd.len);
263141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), rwd, &rwd_size);
264141cc406Sopenharmony_ci
265141cc406Sopenharmony_ci  DBG (11, "<< get_window, datalen = %lu\n", (unsigned long) rwd_size);
266141cc406Sopenharmony_ci  return (status);
267141cc406Sopenharmony_ci}
268141cc406Sopenharmony_ci
269141cc406Sopenharmony_cistatic SANE_Status
270141cc406Sopenharmony_ciread_data (int fd, void *buf, size_t * buf_size)
271141cc406Sopenharmony_ci{
272141cc406Sopenharmony_ci  static struct scsi_read_scanner_cmd cmd;
273141cc406Sopenharmony_ci  SANE_Status status;
274141cc406Sopenharmony_ci  DBG (11, ">> read_data %lu\n", (unsigned long) *buf_size);
275141cc406Sopenharmony_ci
276141cc406Sopenharmony_ci  memset (&cmd, 0, sizeof (cmd));
277141cc406Sopenharmony_ci  cmd.opcode = RICOH_SCSI_READ_SCANNED_DATA;
278141cc406Sopenharmony_ci  _lto3b(*buf_size, cmd.len);
279141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), buf, buf_size);
280141cc406Sopenharmony_ci
281141cc406Sopenharmony_ci  DBG (11, "<< read_data %lu\n", (unsigned long) *buf_size);
282141cc406Sopenharmony_ci  return (status);
283141cc406Sopenharmony_ci}
284141cc406Sopenharmony_ci
285141cc406Sopenharmony_cistatic SANE_Status
286141cc406Sopenharmony_ciobject_position (int fd)
287141cc406Sopenharmony_ci{
288141cc406Sopenharmony_ci  static SANE_Byte cmd[10];
289141cc406Sopenharmony_ci  SANE_Status status;
290141cc406Sopenharmony_ci  DBG (11, ">> object_position\n");
291141cc406Sopenharmony_ci
292141cc406Sopenharmony_ci  memset (cmd, 0, sizeof (cmd));
293141cc406Sopenharmony_ci  cmd[0] = RICOH_SCSI_OBJECT_POSITION;
294141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
295141cc406Sopenharmony_ci
296141cc406Sopenharmony_ci  DBG (11, "<< object_position\n");
297141cc406Sopenharmony_ci  return (status);
298141cc406Sopenharmony_ci}
299141cc406Sopenharmony_ci
300141cc406Sopenharmony_cistatic SANE_Status
301141cc406Sopenharmony_ciget_data_status (int fd, struct scsi_status_desc *dbs)
302141cc406Sopenharmony_ci{
303141cc406Sopenharmony_ci  static struct scsi_get_buffer_status_cmd cmd;
304141cc406Sopenharmony_ci  static struct scsi_status_data ssd;
305141cc406Sopenharmony_ci  size_t ssd_size = sizeof(ssd);
306141cc406Sopenharmony_ci  SANE_Status status;
307141cc406Sopenharmony_ci  DBG (11, ">> get_data_status %lu\n", (unsigned long) ssd_size);
308141cc406Sopenharmony_ci
309141cc406Sopenharmony_ci  memset (&cmd, 0, sizeof (cmd));
310141cc406Sopenharmony_ci  cmd.opcode = RICOH_SCSI_GET_BUFFER_STATUS;
311141cc406Sopenharmony_ci  _lto2b(ssd_size, cmd.len);
312141cc406Sopenharmony_ci  status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), &ssd, &ssd_size);
313141cc406Sopenharmony_ci
314141cc406Sopenharmony_ci  memcpy (dbs, &ssd.desc, sizeof(*dbs));
315141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD &&
316141cc406Sopenharmony_ci      (((unsigned int) _3btol(ssd.len)) <= sizeof(*dbs) || _3btol(ssd.desc.filled) == 0)) {
317141cc406Sopenharmony_ci    DBG (11, "get_data_status: busy\n");
318141cc406Sopenharmony_ci    status = SANE_STATUS_DEVICE_BUSY;
319141cc406Sopenharmony_ci  }
320141cc406Sopenharmony_ci
321141cc406Sopenharmony_ci  DBG (11, "<< get_data_status %lu\n", (unsigned long) ssd_size);
322141cc406Sopenharmony_ci  return (status);
323141cc406Sopenharmony_ci}
324141cc406Sopenharmony_ci
325141cc406Sopenharmony_ci#if 0
326141cc406Sopenharmony_cistatic SANE_Status
327141cc406Sopenharmony_ciricoh_wait_ready_tur (int fd)
328141cc406Sopenharmony_ci{
329141cc406Sopenharmony_ci  struct timeval now, start;
330141cc406Sopenharmony_ci  SANE_Status status;
331141cc406Sopenharmony_ci
332141cc406Sopenharmony_ci  gettimeofday (&start, 0);
333141cc406Sopenharmony_ci
334141cc406Sopenharmony_ci  while (1)
335141cc406Sopenharmony_ci    {
336141cc406Sopenharmony_ci      DBG(3, "scsi_wait_ready: sending TEST_UNIT_READY\n");
337141cc406Sopenharmony_ci
338141cc406Sopenharmony_ci      status = sanei_scsi_cmd (fd, test_unit_ready, sizeof (test_unit_ready),
339141cc406Sopenharmony_ci                               0, 0);
340141cc406Sopenharmony_ci      switch (status)
341141cc406Sopenharmony_ci        {
342141cc406Sopenharmony_ci        default:
343141cc406Sopenharmony_ci          /* Ignore errors while waiting for scanner to become ready.
344141cc406Sopenharmony_ci             Some SCSI drivers return EIO while the scanner is
345141cc406Sopenharmony_ci             returning to the home position.  */
346141cc406Sopenharmony_ci          DBG(1, "scsi_wait_ready: test unit ready failed (%s)\n",
347141cc406Sopenharmony_ci              sane_strstatus (status));
348141cc406Sopenharmony_ci          /* fall through */
349141cc406Sopenharmony_ci        case SANE_STATUS_DEVICE_BUSY:
350141cc406Sopenharmony_ci          gettimeofday (&now, 0);
351141cc406Sopenharmony_ci          if (now.tv_sec - start.tv_sec >= MAX_WAITING_TIME)
352141cc406Sopenharmony_ci            {
353141cc406Sopenharmony_ci              DBG(1, "ricoh_wait_ready: timed out after %lu seconds\n",
354141cc406Sopenharmony_ci                  (u_long) (now.tv_sec - start.tv_sec));
355141cc406Sopenharmony_ci              return SANE_STATUS_INVAL;
356141cc406Sopenharmony_ci            }
357141cc406Sopenharmony_ci          usleep (100000);      /* retry after 100ms */
358141cc406Sopenharmony_ci          break;
359141cc406Sopenharmony_ci
360141cc406Sopenharmony_ci        case SANE_STATUS_GOOD:
361141cc406Sopenharmony_ci          return status;
362141cc406Sopenharmony_ci        }
363141cc406Sopenharmony_ci    }
364141cc406Sopenharmony_ci  return SANE_STATUS_INVAL;
365141cc406Sopenharmony_ci}
366141cc406Sopenharmony_ci#endif
367141cc406Sopenharmony_ci
368141cc406Sopenharmony_cistatic SANE_Status
369141cc406Sopenharmony_ciricoh_wait_ready (Ricoh_Scanner * s)
370141cc406Sopenharmony_ci{
371141cc406Sopenharmony_ci  struct scsi_status_desc dbs;
372141cc406Sopenharmony_ci  time_t now, start;
373141cc406Sopenharmony_ci  SANE_Status status;
374141cc406Sopenharmony_ci
375141cc406Sopenharmony_ci  start = time(NULL);
376141cc406Sopenharmony_ci
377141cc406Sopenharmony_ci  while (1)
378141cc406Sopenharmony_ci    {
379141cc406Sopenharmony_ci      status = get_data_status (s->fd, &dbs);
380141cc406Sopenharmony_ci
381141cc406Sopenharmony_ci      switch (status)
382141cc406Sopenharmony_ci        {
383141cc406Sopenharmony_ci        default:
384141cc406Sopenharmony_ci          /* Ignore errors while waiting for scanner to become ready.
385141cc406Sopenharmony_ci             Some SCSI drivers return EIO while the scanner is
386141cc406Sopenharmony_ci             returning to the home position.  */
387141cc406Sopenharmony_ci          DBG(1, "scsi_wait_ready: get datat status failed (%s)\n",
388141cc406Sopenharmony_ci              sane_strstatus (status));
389141cc406Sopenharmony_ci          /* fall through */
390141cc406Sopenharmony_ci        case SANE_STATUS_DEVICE_BUSY:
391141cc406Sopenharmony_ci          now = time(NULL);
392141cc406Sopenharmony_ci          if (now - start >= MAX_WAITING_TIME)
393141cc406Sopenharmony_ci            {
394141cc406Sopenharmony_ci              DBG(1, "ricoh_wait_ready: timed out after %lu seconds\n",
395141cc406Sopenharmony_ci                  (u_long) (now - start));
396141cc406Sopenharmony_ci              return SANE_STATUS_INVAL;
397141cc406Sopenharmony_ci            }
398141cc406Sopenharmony_ci          break;
399141cc406Sopenharmony_ci
400141cc406Sopenharmony_ci        case SANE_STATUS_GOOD:
401141cc406Sopenharmony_ci	  DBG(11, "ricoh_wait_ready: %d bytes ready\n", _3btol(dbs.filled));
402141cc406Sopenharmony_ci	  return status;
403141cc406Sopenharmony_ci	  break;
404141cc406Sopenharmony_ci	}
405141cc406Sopenharmony_ci      usleep (1000000);      /* retry after 100ms */
406141cc406Sopenharmony_ci    }
407141cc406Sopenharmony_ci  return SANE_STATUS_INVAL;
408141cc406Sopenharmony_ci}
409