xref: /third_party/backends/backend/ricoh2.c (revision 141cc406)
1/* sane - Scanner Access Now Easy.
2
3   Copyright (C) 2018, 2019 Stanislav Yuzvinsky
4   Based on the work done by viruxx
5
6   This file is part of the SANE package.
7
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License as
10   published by the Free Software Foundation; either version 2 of the
11   License, or (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
21   As a special exception, the authors of SANE give permission for
22   additional uses of the libraries contained in this release of SANE.
23
24   The exception is that, if you link a SANE library with other files
25   to produce an executable, this does not by itself cause the
26   resulting executable to be covered by the GNU General Public
27   License.  Your use of that executable is in no way restricted on
28   account of linking the SANE library code into it.
29
30   This exception does not, however, invalidate any other reasons why
31   the executable file might be covered by the GNU General Public
32   License.
33
34   If you submit changes to SANE to the maintainers to be included in
35   a subsequent release, you agree by submitting the changes that
36   those changes may be distributed with this exception intact.
37
38   If you write modifications of your own for SANE, it is your choice
39   whether to permit this exception to apply to your modifications.
40   If you do not wish that, delete this exception notice.
41*/
42
43#include "../include/sane/config.h"
44
45#include <string.h>
46
47#include "../include/sane/sane.h"
48#include "../include/sane/sanei.h"
49#include "../include/sane/sanei_usb.h"
50#include "../include/sane/saneopts.h"
51#include "../include/sane/sanei_backend.h"
52#include "../include/sane/sanei_debug.h"
53
54#include "ricoh2_buffer.c"
55
56#define MAX_OPTION_STRING_SIZE  255
57#define MAX_LINE_SIZE           240 * 256 /* = 61440 */
58#define HEIGHT_PIXELS_300DPI    3508
59#define WIDTH_BYTES_300DPI      2560
60#define WIDTH_PIXELS_300DPI     2550
61#define INFO_SIZE               (WIDTH_BYTES_300DPI - WIDTH_PIXELS_300DPI)
62#define USB_TIMEOUT_MS          20000
63#define MAX_COMMAND_SIZE        64
64
65#define CHECK_IF(x) if (!(x)) return SANE_STATUS_INVAL
66
67typedef enum
68{
69  OPT_NUM_OPTS = 0,
70  OPT_MODE,
71  OPT_RESOLUTION,
72
73  /* must come last: */
74  NUM_OPTIONS
75}
76Ricoh_Options;
77
78typedef enum
79{
80  SCAN_MODE_COLOR,
81  SCAN_MODE_GRAY
82}
83Scan_Mode;
84
85
86typedef struct Ricoh2_Device {
87  struct Ricoh2_Device *next;
88  SANE_Device           sane;
89  SANE_Bool             active;
90
91  /* options */
92  SANE_Option_Descriptor opt[NUM_OPTIONS];
93  Option_Value           val[NUM_OPTIONS];
94
95  /* acquiring session */
96  SANE_Int       dn;
97  SANE_Bool      cancelled;
98  Scan_Mode      mode;
99  SANE_Int       resolution;
100  SANE_Bool      eof;
101  size_t         bytes_to_read;
102  ricoh2_buffer *buffer;
103
104}
105Ricoh2_Device;
106
107typedef struct Ricoh2_device_info {
108  SANE_Int          product_id;
109  SANE_String_Const device_name;
110}
111Ricoh2_device_info;
112
113static Ricoh2_device_info supported_devices[] = {
114  { 0x042c, "Aficio SP-100SU"   },
115  { 0x0438, "Aficio SG-3100SNw" },
116  { 0x0439, "Aficio SG-3110SFNw" },
117  { 0x0448, "Aficio SP-111SU/SP-112SU" }
118};
119
120static SANE_String_Const mode_list[] = {
121  SANE_VALUE_SCAN_MODE_COLOR,
122  SANE_VALUE_SCAN_MODE_GRAY,
123  NULL
124};
125static SANE_String_Const default_mode = SANE_VALUE_SCAN_MODE_COLOR;
126
127static SANE_Int resolution_list[] = {
128  2, 300, 600
129};
130static SANE_Int default_resolution = 300;
131
132static SANE_Bool initialized = SANE_FALSE;
133static Ricoh2_Device *ricoh2_devices = NULL;
134static const SANE_Device **sane_devices = NULL;
135static SANE_Int num_devices = 0;
136
137static Ricoh2_Device *
138lookup_handle(SANE_Handle handle)
139{
140  Ricoh2_Device *device;
141
142  for (device = ricoh2_devices; device; device = device->next)
143    {
144      if (device == handle)
145        return device;
146    }
147
148  return NULL;
149}
150
151static SANE_String_Const get_model_by_productid(SANE_Int id)
152{
153  size_t i = 0;
154  for (; i < sizeof (supported_devices) / sizeof (supported_devices[0]); ++i)
155    {
156      if (supported_devices[i].product_id == id)
157        {
158          return supported_devices[i].device_name;
159        }
160    }
161
162  return "Unidentified device";
163}
164
165static SANE_Status
166attach (SANE_String_Const devname)
167{
168  SANE_Int dn = -1;
169  SANE_Status status = SANE_STATUS_GOOD;
170  Ricoh2_Device *device = NULL;
171  SANE_Int vendor, product;
172
173  for (device = ricoh2_devices; device; device = device->next)
174    {
175      if (strcmp (device->sane.name, devname) == 0)
176        {
177          device->active = SANE_TRUE;
178          return SANE_STATUS_GOOD;
179        }
180    }
181
182  device = (Ricoh2_Device *) malloc (sizeof (Ricoh2_Device));
183  if (!device)
184    {
185      return SANE_STATUS_NO_MEM;
186    }
187
188  DBG (8, "attach %s\n", devname);
189  status = sanei_usb_open (devname, &dn);
190  if (status != SANE_STATUS_GOOD)
191    {
192      DBG (1, "attach: couldn't open device `%s': %s\n", devname,
193           sane_strstatus (status));
194      return status;
195    }
196
197  status = sanei_usb_get_vendor_product (dn, &vendor, &product);
198  if (status != SANE_STATUS_GOOD)
199    {
200      DBG (1,
201           "attach: couldn't get vendor and product ids of device `%s': %s\n",
202           devname, sane_strstatus (status));
203      sanei_usb_close (dn);
204      return status;
205    }
206
207  sanei_usb_close (dn);
208  device->sane.name = strdup (devname);
209  device->sane.vendor = "Ricoh";
210  device->sane.model = get_model_by_productid (product);
211  device->sane.type = "flatbed scanner";
212  device->active = SANE_TRUE;
213  device->buffer = NULL;
214
215  device->next = ricoh2_devices;
216  ricoh2_devices = device;
217
218  DBG (2, "Found device %s\n", device->sane.name);
219  ++num_devices;
220
221  return SANE_STATUS_GOOD;
222}
223
224static SANE_Status
225init_options(Ricoh2_Device *dev)
226{
227  SANE_Option_Descriptor *od;
228
229  DBG (8, "init_options: dev = %p\n", (void *) dev);
230
231  /* number of options */
232  od = &(dev->opt[OPT_NUM_OPTS]);
233  od->name = SANE_NAME_NUM_OPTIONS;
234  od->title = SANE_TITLE_NUM_OPTIONS;
235  od->desc = SANE_DESC_NUM_OPTIONS;
236  od->type = SANE_TYPE_INT;
237  od->unit = SANE_UNIT_NONE;
238  od->size = sizeof (SANE_Word);
239  od->cap = SANE_CAP_SOFT_DETECT;
240  od->constraint_type = SANE_CONSTRAINT_NONE;
241  od->constraint.range = 0;
242  dev->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
243
244  /* mode - sets the scan mode: Color, Gray */
245  od = &(dev->opt[OPT_MODE]);
246  od->name = SANE_NAME_SCAN_MODE;
247  od->title = SANE_TITLE_SCAN_MODE;
248  od->desc = SANE_DESC_SCAN_MODE;
249  od->type = SANE_TYPE_STRING;
250  od->unit = SANE_UNIT_NONE;
251  od->size = MAX_OPTION_STRING_SIZE;
252  od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
253  od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
254  od->constraint.string_list = mode_list;
255  dev->val[OPT_MODE].s = malloc (od->size);
256  if (!dev->val[OPT_MODE].s)
257    return SANE_STATUS_NO_MEM;
258  strcpy (dev->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR);
259
260  /* resolution */
261  od = &(dev->opt[OPT_RESOLUTION]);
262  od->name = SANE_NAME_SCAN_RESOLUTION;
263  od->title = SANE_TITLE_SCAN_RESOLUTION;
264  od->desc = SANE_DESC_SCAN_RESOLUTION;
265  od->type = SANE_TYPE_INT;
266  od->unit = SANE_UNIT_DPI;
267  od->size = sizeof (SANE_Word);
268  od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
269  od->constraint_type = SANE_CONSTRAINT_WORD_LIST;
270  od->constraint.word_list = resolution_list;
271  dev->val[OPT_RESOLUTION].w = 300;
272
273  return SANE_STATUS_GOOD;
274}
275
276SANE_Status
277sane_init (SANE_Int *vc, SANE_Auth_Callback __sane_unused__ cb)
278{
279  size_t i = 0;
280
281  DBG_INIT ();
282
283  DBG(8, ">sane_init\n");
284
285  sanei_usb_init ();
286  sanei_usb_set_timeout (USB_TIMEOUT_MS);
287
288  num_devices = 0;
289
290  for (; i < sizeof (supported_devices) / sizeof (supported_devices[0]); ++i)
291    {
292      sanei_usb_find_devices (0x5ca, supported_devices[i].product_id, attach);
293    }
294
295  if (vc)
296    *vc = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
297  DBG(8, "<sane_init\n");
298
299  initialized = SANE_TRUE;
300
301  return SANE_STATUS_GOOD;
302}
303
304SANE_Status
305sane_get_devices (const SANE_Device ***dl,
306                  SANE_Bool __sane_unused__ local)
307{
308  Ricoh2_Device *device = NULL;
309  SANE_Int i = 0;
310
311  DBG(8, ">sane_get_devices\n");
312
313  num_devices = 0;
314  sanei_usb_find_devices (0x5ca, 0x042c, attach);
315  sanei_usb_find_devices (0x5ca, 0x0448, attach);
316
317  if (sane_devices)
318    free (sane_devices);
319
320  sane_devices = (const SANE_Device **) malloc (sizeof (const SANE_Device *)
321                                               * (num_devices + 1));
322  if (!sane_devices)
323    return SANE_STATUS_NO_MEM;
324
325  for (device = ricoh2_devices; device; device = device->next)
326    if (device->active)
327      {
328        sane_devices[i++] = &(device->sane);
329      }
330
331  sane_devices[i] = NULL;
332  *dl = sane_devices;
333
334  DBG(2, "found %i devices\n", i);
335  DBG(8, "<sane_get_devices\n");
336
337  return SANE_STATUS_GOOD;
338}
339
340SANE_Status
341sane_open (SANE_String_Const name, SANE_Handle *handle)
342{
343  Ricoh2_Device *device;
344  SANE_Status status;
345
346  DBG (8, ">sane_open: devicename=\"%s\", handle=%p\n", name,
347       (void *) handle);
348
349  CHECK_IF (initialized);
350  CHECK_IF (handle);
351
352  /* walk the linked list of scanner device until there is a match
353   * with the device name */
354  for (device = ricoh2_devices; device; device = device->next)
355    {
356      DBG (2, "sane_open: devname from list: %s\n",
357           device->sane.name);
358      if (strcmp (name, "") == 0
359          || strcmp (name, "ricoh") == 0
360          || strcmp (name, device->sane.name) == 0)
361        break;
362    }
363
364  *handle = device;
365
366  if (!device)
367    {
368      DBG (1, "sane_open: Not a Ricoh device\n");
369      return SANE_STATUS_INVAL;
370    }
371
372  status = init_options (device);
373  if (status != SANE_STATUS_GOOD)
374    return status;
375
376  DBG (8, "<sane_open\n");
377
378  return SANE_STATUS_GOOD;
379}
380
381const SANE_Option_Descriptor *
382sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
383{
384  Ricoh2_Device *device;
385
386  DBG (8, "<sane_get_option_descriptor: handle=%p, option = %d\n",
387       (void *) handle, option);
388
389  if (!initialized)
390    return NULL;
391
392  /* Check for valid option number */
393  if ((option < 0) || (option >= NUM_OPTIONS))
394    return NULL;
395
396 if (!(device = lookup_handle(handle)))
397    return NULL;
398
399  if (device->opt[option].name)
400    {
401      DBG (8, ">sane_get_option_descriptor: name=%s\n",
402           device->opt[option].name);
403    }
404
405  return &(device->opt[option]);
406}
407
408SANE_Status
409sane_control_option (SANE_Handle handle,
410                     SANE_Int    option,
411                     SANE_Action action,
412                     void       *value,
413                     SANE_Word  *info)
414{
415  Ricoh2_Device *device;
416  SANE_Status status;
417
418  DBG (8,
419       ">sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n",
420       (void *) handle, option, action, (void *) value, (void *) info);
421
422  CHECK_IF (initialized);
423  device = lookup_handle (handle);
424  CHECK_IF (device);
425  CHECK_IF (value);
426  CHECK_IF (option >= 0 && option < NUM_OPTIONS);
427  CHECK_IF (device->opt[option].type != SANE_TYPE_GROUP);
428
429  switch (action)
430    {
431    case SANE_ACTION_SET_AUTO:
432      CHECK_IF (SANE_OPTION_IS_SETTABLE (device->opt[option].cap));
433      CHECK_IF (device->opt[option].cap & SANE_CAP_AUTOMATIC);
434
435      switch (option)
436        {
437        case OPT_RESOLUTION:
438          DBG (2,
439               "Setting value to default value of '%d' for option '%s'\n",
440               default_resolution,
441               device->opt[option].name);
442          device->val[option].w = default_resolution;
443          break;
444
445        case OPT_MODE:
446          DBG (2,
447               "Setting value to default value of '%s' for option '%s'\n",
448               (SANE_String_Const) default_mode,
449               device->opt[option].name);
450          strcpy (device->val[option].s, default_mode);
451          break;
452
453        default:
454          return SANE_STATUS_INVAL;
455        }
456      break;
457
458    case SANE_ACTION_SET_VALUE:
459      CHECK_IF (SANE_OPTION_IS_SETTABLE (device->opt[option].cap));
460
461      if (device->opt[option].type == SANE_TYPE_BOOL)
462        {
463          SANE_Bool bool_value = *(SANE_Bool *) value;
464          CHECK_IF (bool_value == SANE_TRUE || bool_value == SANE_FALSE);
465        }
466
467      if (device->opt[option].constraint_type == SANE_CONSTRAINT_RANGE)
468        {
469          status = sanei_constrain_value (&(device->opt[option]), value, info);
470          CHECK_IF (status == SANE_STATUS_GOOD);
471        }
472
473
474      switch (option)
475        {
476        case OPT_RESOLUTION:
477          DBG (2,
478               "Setting value to '%d' for option '%s'\n",
479               *(SANE_Word *) value,
480               device->opt[option].name);
481          device->val[option].w = *(SANE_Word *) value;
482          break;
483
484        case OPT_MODE:
485          DBG (2,
486               "Setting value to '%s' for option '%s'\n",
487               (SANE_String_Const)value,
488               device->opt[option].name);
489          strcpy (device->val[option].s, value);
490          break;
491
492        default:
493          return SANE_STATUS_INVAL;
494        }
495      break;
496
497    case SANE_ACTION_GET_VALUE:
498
499      switch (option)
500        {
501        case OPT_NUM_OPTS:
502        case OPT_RESOLUTION:
503          *(SANE_Word *) value = device->val[option].w;
504          DBG (2, "Option value = %d (%s)\n", *(SANE_Word *) value,
505               device->opt[option].name);
506          break;
507        case OPT_MODE:
508          strcpy (value, device->val[option].s);
509          break;
510        default:
511          return SANE_STATUS_INVAL;
512        }
513      break;
514
515    default:
516      return SANE_STATUS_INVAL;
517    }
518
519  DBG (8, "<sane_control_option\n");
520  return SANE_STATUS_GOOD;
521}
522
523static void
524update_scan_params (Ricoh2_Device *device)
525{
526  /* Scan mode: color or grayscale */
527  if (strcmp(device->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
528    {
529      device->mode = SCAN_MODE_COLOR;
530    }
531  else
532    {
533      device->mode = SCAN_MODE_GRAY;
534    }
535
536  /* resolution: 300 or 600dpi */
537  device->resolution = device->val[OPT_RESOLUTION].w;
538}
539
540
541SANE_Status
542sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
543{
544  Ricoh2_Device *device;
545
546  DBG (8, "sane_get_parameters: handle=%p, params=%p\n", (void *) handle,
547       (void *) params);
548
549  CHECK_IF (initialized);
550  device = lookup_handle (handle);
551  CHECK_IF (device);
552  CHECK_IF (params);
553
554  update_scan_params (device);
555
556  params->format =
557    device->mode == SCAN_MODE_COLOR ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
558  params->last_frame = SANE_TRUE;
559
560  params->pixels_per_line = WIDTH_PIXELS_300DPI;
561  params->bytes_per_line = params->pixels_per_line;
562  params->lines = HEIGHT_PIXELS_300DPI;
563  params->depth = 8;
564
565  if (device->resolution == 600)
566    {
567      params->bytes_per_line *= 2;
568      params->pixels_per_line *= 2;
569      params->lines *= 2;
570    }
571
572  if (device->mode == SCAN_MODE_COLOR)
573    {
574      params->bytes_per_line *= 3;
575    }
576
577  DBG (8, ">sane_get_parameters: format = %s bytes_per_line = %d "
578          "depth = %d "
579          "pixels_per_line = %d "
580          "lines = %d\n",
581       (params->format == SANE_FRAME_RGB ? "rgb" : "gray"),
582       params->bytes_per_line,
583       params->depth,
584       params->pixels_per_line,
585       params->lines);
586
587  return SANE_STATUS_GOOD;
588}
589
590typedef struct
591{
592  SANE_Byte *send_buffer;
593  size_t     to_send;
594  SANE_Byte *receive_buffer;
595  size_t     to_receive;
596}
597Send_Receive_Pair;
598
599static SANE_Status
600send_receive (SANE_Int dn, Send_Receive_Pair *transfer)
601{
602  SANE_Status status;
603  size_t io_size;
604  SANE_Byte send_buffer[MAX_COMMAND_SIZE];
605
606  assert(transfer->to_send <= MAX_COMMAND_SIZE);
607
608  memset(send_buffer, 0, MAX_COMMAND_SIZE);
609
610  /* send a command */
611  io_size = MAX_COMMAND_SIZE;
612  DBG (128, "sending a packet of size %lu\n", io_size);
613  memcpy (send_buffer, transfer->send_buffer, transfer->to_send);
614  status = sanei_usb_write_bulk (dn, send_buffer, &io_size);
615  if (status != SANE_STATUS_GOOD)
616    {
617      DBG (1, "could not send packet: %s\n", sane_strstatus (status));
618      return status;
619    }
620
621  /* receive a result */
622  io_size = transfer->to_receive;
623  DBG (128, "receiving a packet of size %lu\n", io_size);
624  if (io_size)
625    {
626      status = sanei_usb_read_bulk (dn, transfer->receive_buffer, &io_size);
627      if (status != SANE_STATUS_GOOD)
628        {
629          DBG (1, "could not get a response for packet: %s\n",
630               sane_strstatus (status));
631          return status;
632        }
633      if (io_size != transfer->to_receive)
634        {
635          DBG (1, "unexpected size of received packet: expected %lu, "
636                  "received %lu\n", transfer->to_receive, io_size);
637          return SANE_STATUS_IO_ERROR;
638        }
639    }
640  return SANE_STATUS_GOOD;
641}
642
643static SANE_Status
644init_scan(SANE_Int dn, Scan_Mode mode, SANE_Int resolution)
645{
646  SANE_Status status = SANE_STATUS_GOOD;
647  SANE_Byte dummy_buffer[11]; /* the longest expected reply */
648  size_t i;
649
650  SANE_Byte urb_init[] = { 0x03, 0x09, 0x01 };
651  SANE_Byte magic0[] = { 0x03, 0x0d, 0x0b };
652  SANE_Byte magic1[] = {
653    0x03, 0x0c, 0x11, 0x00, 0x00, 0x00, 0x01, 0x02, 0x05,
654    0xff, 0x00, 0x00, 0x00, 0x00, 0xec, 0x13, 0x6c, 0x1b };
655  SANE_Byte magic2[] = { 0x03, 0x0b, 0x08 };
656  SANE_Byte magic3[] = {
657    0x03, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x50, 0x6d, 0x06, 0x01 };
658
659  Send_Receive_Pair transfer[] =
660  {
661    { urb_init, sizeof (urb_init), dummy_buffer,  1 },
662    { magic0,   sizeof (magic0),   dummy_buffer, 11 },
663    { magic1,   sizeof (magic1),   dummy_buffer,  0 },
664    { magic2,   sizeof (magic2),   dummy_buffer,  8 },
665    { magic3,   sizeof (magic3),   dummy_buffer,  0 }
666  };
667
668  if (resolution == 600)
669    magic1[6] = 0x02;
670
671  if (mode == SCAN_MODE_COLOR)
672    magic1[7] = 0x03;
673
674  for (i = 0;
675       i < sizeof (transfer) / sizeof (transfer[0])
676       && (status == SANE_STATUS_GOOD);
677       ++i)
678    {
679      DBG (128, "sending initialization packet %zi\n", i);
680      status = send_receive (dn, transfer + i);
681    }
682
683  return status;
684}
685
686void
687teardown_scan(SANE_Int dn)
688{
689  SANE_Byte cancel_command[] = { 0x03, 0x0a };
690  SANE_Byte end_command[]    = { 0x03, 0x09, 0x01 };
691  SANE_Byte dummy_buffer;
692  Send_Receive_Pair transfer;
693
694  DBG (128, "Sending cancel command\n");
695  transfer.send_buffer = cancel_command;
696  transfer.to_send = sizeof (cancel_command);
697  transfer.receive_buffer = &dummy_buffer;
698  transfer.to_receive = 0;
699  send_receive (dn, &transfer);
700
701  transfer.send_buffer = end_command;
702  transfer.to_send = sizeof (end_command);
703  transfer.receive_buffer = &dummy_buffer;
704  transfer.to_receive = 1;
705  send_receive (dn, &transfer);
706}
707
708SANE_Status
709sane_start (SANE_Handle handle)
710{
711  Ricoh2_Device *device;
712  SANE_Status status;
713  SANE_Int pixels_per_line;
714  SANE_Int resolution_factor = 1;
715
716  DBG (8, ">sane_start: handle=%p\n", (void *) handle);
717
718  CHECK_IF (initialized);
719  device = lookup_handle (handle);
720  CHECK_IF (device);
721
722  update_scan_params (device);
723  device->cancelled = SANE_FALSE;
724
725  status = sanei_usb_open (device->sane.name, &(device->dn));
726  if (status != SANE_STATUS_GOOD)
727    {
728      DBG (1, "could not open device %s: %s\n",
729           device->sane.name, sane_strstatus (status));
730      return status;
731    }
732
733  DBG (2, "usb device %s opened, device number is %d\n",
734      device->sane.name, device->dn);
735
736  status = sanei_usb_claim_interface (device->dn, 0);
737  if (status != SANE_STATUS_GOOD)
738    {
739      DBG (1, "could not claim interface 0: %s\n",
740           sane_strstatus (status));
741      sanei_usb_close (device->dn);
742      return status;
743    }
744
745  sanei_usb_set_endpoint (device->dn,
746                          USB_DIR_OUT | USB_ENDPOINT_TYPE_BULK,
747                          0x03);
748
749  sanei_usb_set_endpoint (device->dn,
750                          USB_DIR_IN | USB_ENDPOINT_TYPE_BULK,
751                          0x85);
752
753  status = sanei_usb_reset (device->dn);
754  if (status != SANE_STATUS_GOOD)
755    {
756      DBG (1, "could not reset device %s: %s\n",
757           device->sane.name, sane_strstatus (status));
758      sanei_usb_close (device->dn);
759      return status;
760    }
761
762
763  status = init_scan (device->dn, device->mode, device->resolution);
764  if (status != SANE_STATUS_GOOD)
765    {
766      sanei_usb_close (device->dn);
767      return status;
768    }
769
770  resolution_factor = device->resolution == 600 ? 2 : 1;
771
772  pixels_per_line = WIDTH_PIXELS_300DPI * resolution_factor;
773
774  device->bytes_to_read =
775        WIDTH_PIXELS_300DPI * resolution_factor
776      * HEIGHT_PIXELS_300DPI * resolution_factor
777      * (device->mode == SCAN_MODE_COLOR ? 3 : 1);
778
779  device->buffer =
780      ricoh2_buffer_create (MAX_LINE_SIZE,
781                            pixels_per_line,
782                            INFO_SIZE * resolution_factor,
783                            device->mode == SCAN_MODE_COLOR);
784
785  DBG (8, "<sane_start: %lu bytes to read\n", device->bytes_to_read);
786
787  return SANE_STATUS_GOOD;
788}
789
790SANE_Status
791sane_read (SANE_Handle handle,
792           SANE_Byte  *data,
793           SANE_Int    maxlen,
794           SANE_Int   *length)
795{
796  SANE_Byte read_next_command[] = { 0x03, 0x0E, 0x04, 0, 0, 0, 0, 240 };
797
798  Ricoh2_Device *device;
799  SANE_Status status;
800  Send_Receive_Pair transfer;
801
802  DBG (16, ">sane_read: handle=%p, data=%p, maxlen = %d, length=%p\n",
803       (void *) handle, (void *) data, maxlen, (void *) length);
804
805  CHECK_IF (initialized);
806  device = lookup_handle (handle);
807  CHECK_IF (device);
808  CHECK_IF (length);
809  CHECK_IF (maxlen);
810
811  /*
812  EOF has already been reached before or acquisition process hasn't
813  been initiated at all
814  */
815  if (device->bytes_to_read <= 0)
816    {
817      return SANE_STATUS_EOF;
818    }
819
820  if (!ricoh2_buffer_get_bytes_remain (device->buffer))
821    {
822      transfer.send_buffer = read_next_command;
823      transfer.to_send = sizeof (read_next_command);
824      transfer.receive_buffer =
825          ricoh2_buffer_get_internal_buffer (device->buffer);
826      transfer.to_receive = MAX_LINE_SIZE;
827      read_next_command[7] = transfer.to_receive / 256;
828
829      DBG (128, "Receiving data of size %zi\n", transfer.to_receive);
830
831      status = send_receive (device->dn, &transfer);
832      if (status != SANE_STATUS_GOOD)
833        {
834          device->bytes_to_read = 0;
835          return status;
836        }
837    }
838
839  *length = ricoh2_buffer_get_data (device->buffer,
840                                    data,
841                                    min(maxlen, device->bytes_to_read));
842
843  device->bytes_to_read -= *length;
844
845  DBG (128,
846       "Read length %d, left to read %lu\n",
847       *length,
848       device->bytes_to_read);
849
850  DBG (128,
851       "%d bytes remain in the buffer\n",
852       ricoh2_buffer_get_bytes_remain(device->buffer));
853
854  /* we've just reached expected data size */
855  if (device->bytes_to_read <= 0)
856    {
857      ricoh2_buffer_dispose(device->buffer);
858      device->buffer = NULL;
859      return SANE_STATUS_EOF;
860    }
861
862  DBG (16, "<sane_read\n");
863
864  return SANE_STATUS_GOOD;
865}
866
867SANE_Status
868sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
869{
870  Ricoh2_Device *device;
871  DBG (8, "sane_set_io_mode: handle = %p, non_blocking = %d\n",
872       (void *) handle, non_blocking);
873
874  CHECK_IF (initialized);
875  device = lookup_handle (handle);
876  CHECK_IF (device);
877
878  if (non_blocking)
879    return SANE_STATUS_UNSUPPORTED;
880
881  return SANE_STATUS_GOOD;
882}
883
884SANE_Status
885sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
886{
887  Ricoh2_Device *device;
888  DBG (8, "sane_get_select_fd: handle = %p, fd %s 0\n", (void *) handle,
889       fd ? "!=" : "=");
890
891  CHECK_IF (initialized);
892  device = lookup_handle (handle);
893  CHECK_IF (device);
894
895  return SANE_STATUS_UNSUPPORTED;
896}
897
898void
899sane_cancel (SANE_Handle handle)
900{
901  Ricoh2_Device *device;
902
903  DBG (8, ">sane_cancel: handle = %p\n", (void *) handle);
904
905  if (!initialized)
906    return;
907
908  if (!(device = lookup_handle (handle)))
909    return;
910
911  if (device->cancelled)
912	return;
913
914  device->cancelled = SANE_TRUE;
915
916  teardown_scan (device->dn);
917  if (device->buffer)
918    {
919      ricoh2_buffer_dispose (device->buffer);
920      device->buffer = NULL;
921    }
922
923  sanei_usb_close(device->dn);
924
925  DBG (8, "<sane_cancel\n");
926}
927
928void
929sane_close (SANE_Handle handle)
930{
931  Ricoh2_Device *device;
932
933  DBG (8, ">sane_close\n");
934
935  if (!initialized)
936    return;
937
938  device = lookup_handle (handle);
939  if (!device)
940    return;
941
942  /* noop */
943
944  DBG (8, "<sane_close\n");
945}
946
947void
948sane_exit (void)
949{
950  Ricoh2_Device *device, *next;
951
952  DBG (8, ">sane_exit\n");
953
954  if (!initialized)
955    return;
956
957  for (device = ricoh2_devices, next = device; device; device = next)
958    {
959      next = device->next;
960      free (device);
961    }
962
963  if (sane_devices)
964    free (sane_devices);
965
966  sanei_usb_exit ();
967  initialized = SANE_FALSE;
968
969  DBG (8, "<sane_exit\n");
970}
971