1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
4 Copyright (C) 2002 - 2007 Henning Geinitz <sane@geinitz.org>
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 /** @file
44 * @brief Implementation of the low-level scanner interface functions.
45 */
46
47 #include "gt68xx_low.h"
48
49 #include "../include/sane/sane.h"
50 #include "../include/sane/sanei_debug.h"
51 #include "../include/sane/sanei_usb.h"
52
53 #include <stdlib.h>
54 #include <string.h>
55
56 #ifdef USE_FORK
57 #include <sys/wait.h>
58 #include <unistd.h>
59 #include "gt68xx_shm_channel.c"
60 #endif
61
62 /** Check that the device pointer is not NULL.
63 *
64 * @param dev Pointer to the device object (GT68xx_Device).
65 * @param func_name Function name (for use in debug messages).
66 */
67 #define CHECK_DEV_NOT_NULL(dev, func_name) \
68 do { \
69 IF_DBG( \
70 if (!(dev)) \
71 { \
72 DBG (0, "BUG: NULL device\n"); \
73 return SANE_STATUS_INVAL; \
74 } \
75 ) \
76 } while (SANE_FALSE)
77
78 /** Check that the device is open.
79 *
80 * @param dev Pointer to the device object (GT68xx_Device).
81 * @param func_name Function name (for use in debug messages).
82 */
83 #define CHECK_DEV_OPEN(dev, func_name) \
84 do { \
85 IF_DBG( \
86 CHECK_DEV_NOT_NULL ((dev), (func_name)); \
87 if ((dev)->fd == -1) \
88 { \
89 DBG (0, "%s: BUG: device %p not open\n", (func_name), \
90 ((void *) dev)); \
91 return SANE_STATUS_INVAL; \
92 } \
93 ) \
94 } while (SANE_FALSE)
95
96 /** Check that the device is open and active.
97 *
98 * @param dev Pointer to the device (GT68xx_Device).
99 * @param func_name Function name (for use in debug messages).
100 */
101 #define CHECK_DEV_ACTIVE(dev, func_name) \
102 do { \
103 IF_DBG( \
104 CHECK_DEV_OPEN ((dev), (func_name)); \
105 if (!(dev)->active) \
106 { \
107 DBG (0, "%s: BUG: device %p not active\n", (func_name), \
108 ((void *) dev)); \
109 return SANE_STATUS_INVAL; \
110 } \
111 ) \
112 } while (SANE_FALSE)
113
114
115 #ifndef NDEBUG
116
117 /** Dump a request packet for debugging purposes.
118 *
119 * @param prefix String printed before the packet contents.
120 * @param req The request packet to be dumped.
121 */
122 static void
dump_req(SANE_String_Const prefix, GT68xx_Packet req)123 dump_req (SANE_String_Const prefix, GT68xx_Packet req)
124 {
125 int i;
126 char buf[GT68XX_PACKET_SIZE * 3 + 1];
127
128 for (i = 0; i < GT68XX_PACKET_SIZE; ++i)
129 sprintf (buf + i * 3, " %02x", req[i]);
130 DBG (8, "%s%s\n", prefix, buf);
131 }
132
133 #endif /* not NDEBUG */
134
135 /** Dump a request packet if the debug level is at 8 or above.
136 *
137 * @param prefix String printed before the packet contents.
138 * @param req The request packet to be dumped.
139 */
140 #define DUMP_REQ(prefix, req) \
141 do { IF_DBG( if (DBG_LEVEL >= 8) dump_req ((prefix), (req)); ) } while (0)
142
143
144 SANE_Status
gt68xx_device_new(GT68xx_Device ** dev_return)145 gt68xx_device_new (GT68xx_Device ** dev_return)
146 {
147 GT68xx_Device *dev;
148
149 DBG (7, "gt68xx_device_new: enter\n");
150 if (!dev_return)
151 return SANE_STATUS_INVAL;
152
153 dev = (GT68xx_Device *) malloc (sizeof (GT68xx_Device));
154
155 if (!dev)
156 {
157 DBG (3, "gt68xx_device_new: couldn't malloc %lu bytes for device\n",
158 (u_long) sizeof (GT68xx_Device));
159 *dev_return = 0;
160 return SANE_STATUS_NO_MEM;
161 }
162 *dev_return = dev;
163
164 memset (dev, 0, sizeof (GT68xx_Device));
165
166 dev->fd = -1;
167 dev->active = SANE_FALSE;
168
169 dev->model = NULL;
170 dev->command_set_private = NULL;
171
172 dev->read_buffer = NULL;
173 dev->read_buffer_size = 32768;
174
175 dev->manual_selection = SANE_FALSE;
176
177 dev->scan_started = SANE_FALSE;
178
179 #ifdef USE_FORK
180 dev->shm_channel = NULL;
181 #endif /* USE_FORK */
182
183 DBG (7, "gt68xx_device_new:: leave: ok\n");
184 return SANE_STATUS_GOOD;
185 }
186
187 SANE_Status
gt68xx_device_free(GT68xx_Device * dev)188 gt68xx_device_free (GT68xx_Device * dev)
189 {
190 DBG (7, "gt68xx_device_free: enter: dev=%p\n", (void *) dev);
191 if (dev)
192 {
193 if (dev->active)
194 gt68xx_device_deactivate (dev);
195
196 if (dev->fd != -1)
197 gt68xx_device_close (dev);
198
199 if (dev->model && dev->model->allocated)
200 {
201 DBG (7, "gt68xx_device_free: freeing model data %p\n",
202 (void *) dev->model);
203 free (dev->model);
204 }
205
206 DBG (7, "gt68xx_device_free: freeing dev\n");
207 free (dev);
208 }
209 DBG (7, "gt68xx_device_free: leave: ok\n");
210 return SANE_STATUS_GOOD;
211 }
212
213 static GT68xx_USB_Device_Entry *
gt68xx_find_usb_device_entry(SANE_Word vendor, SANE_Word product)214 gt68xx_find_usb_device_entry (SANE_Word vendor, SANE_Word product)
215 {
216 GT68xx_USB_Device_Entry *entry;
217
218 for (entry = gt68xx_usb_device_list; entry->model; ++entry)
219 {
220 if (vendor == entry->vendor && product == entry->product)
221 return entry;
222 }
223
224 return NULL;
225 }
226
227 static SANE_Status
gt68xx_device_identify(GT68xx_Device * dev)228 gt68xx_device_identify (GT68xx_Device * dev)
229 {
230 SANE_Status status;
231 SANE_Word vendor, product;
232 GT68xx_USB_Device_Entry *entry;
233
234 CHECK_DEV_OPEN (dev, "gt68xx_device_identify");
235
236 status = sanei_usb_get_vendor_product (dev->fd, &vendor, &product);
237 if (status != SANE_STATUS_GOOD)
238 {
239 DBG (3, "gt68xx_device_identify: error getting USB id: %s\n",
240 sane_strstatus (status));
241 return status;
242 }
243
244 entry = gt68xx_find_usb_device_entry (vendor, product);
245
246 if (entry)
247 {
248 dev->model = entry->model;
249 }
250 else
251 {
252 dev->model = NULL;
253 DBG (3, "gt68xx_device_identify: unknown USB device (vendor 0x%04x, "
254 "product 0x%04x)\n", vendor, product);
255 return SANE_STATUS_INVAL;
256 }
257
258 return SANE_STATUS_GOOD;
259 }
260
261 SANE_Status
gt68xx_device_open(GT68xx_Device * dev, const char *dev_name)262 gt68xx_device_open (GT68xx_Device * dev, const char *dev_name)
263 {
264 SANE_Status status;
265 SANE_Int fd;
266
267 DBG (7, "gt68xx_device_open: enter: dev=%p\n", (void *) dev);
268
269 CHECK_DEV_NOT_NULL (dev, "gt68xx_device_open");
270
271 if (dev->fd != -1)
272 {
273 DBG (3, "gt68xx_device_open: device already open\n");
274 return SANE_STATUS_INVAL;
275 }
276
277 status = sanei_usb_open (dev_name, &fd);
278 if (status != SANE_STATUS_GOOD)
279 {
280 DBG (3, "gt68xx_device_open: sanei_usb_open failed: %s\n",
281 sane_strstatus (status));
282 return status;
283 }
284
285 dev->fd = fd;
286
287 if (!dev->model)
288 gt68xx_device_identify (dev);
289
290 DBG (7, "gt68xx_device_open: leave: ok\n");
291 return SANE_STATUS_GOOD;
292 }
293
294 SANE_Status
gt68xx_device_close(GT68xx_Device * dev)295 gt68xx_device_close (GT68xx_Device * dev)
296 {
297 DBG (7, "gt68xx_device_close: enter: dev=%p\n", (void *) dev);
298
299 CHECK_DEV_OPEN (dev, "gt68xx_device_close");
300
301 if (dev->active)
302 gt68xx_device_deactivate (dev);
303
304 sanei_usb_close (dev->fd);
305 dev->fd = -1;
306
307 DBG (7, "gt68xx_device_close: leave: ok\n");
308 return SANE_STATUS_GOOD;
309 }
310
311 SANE_Bool
gt68xx_device_is_configured(GT68xx_Device * dev)312 gt68xx_device_is_configured (GT68xx_Device * dev)
313 {
314 if (dev && dev->model && dev->model->command_set)
315 return SANE_TRUE;
316 else
317 return SANE_FALSE;
318 }
319
320 SANE_Status
gt68xx_device_set_model(GT68xx_Device * dev, GT68xx_Model * model)321 gt68xx_device_set_model (GT68xx_Device * dev, GT68xx_Model * model)
322 {
323 if (dev->active)
324 {
325 DBG (3, "gt68xx_device_set_model: device already active\n");
326 return SANE_STATUS_INVAL;
327 }
328
329 if (dev->model && dev->model->allocated)
330 free (dev->model);
331
332 dev->model = model;
333
334 return SANE_STATUS_GOOD;
335 }
336
337 static SANE_Bool
gt68xx_device_get_model(SANE_String name, GT68xx_Model ** model)338 gt68xx_device_get_model (SANE_String name, GT68xx_Model ** model)
339 {
340 GT68xx_USB_Device_Entry *entry;
341
342 for (entry = gt68xx_usb_device_list; entry->model; ++entry)
343 {
344 if (strcmp (name, entry->model->name) == 0)
345 {
346 *model = entry->model;
347 return SANE_TRUE;
348 }
349 }
350 return SANE_FALSE;
351 }
352
353
354 SANE_Status
gt68xx_device_activate(GT68xx_Device * dev)355 gt68xx_device_activate (GT68xx_Device * dev)
356 {
357 SANE_Status status;
358 CHECK_DEV_OPEN (dev, "gt68xx_device_activate");
359 if (dev->active)
360 {
361 DBG (3, "gt68xx_device_activate: device already active\n");
362 return SANE_STATUS_INVAL;
363 }
364
365 if (!gt68xx_device_is_configured (dev))
366 {
367 DBG (3, "gt68xx_device_activate: device is not configured\n");
368 return SANE_STATUS_INVAL;
369 }
370
371 DBG (7, "gt68xx_device_activate: model \"%s\"\n", dev->model->name);
372 if (dev->model->command_set->activate)
373 {
374 status = (*dev->model->command_set->activate) (dev);
375 if (status != SANE_STATUS_GOOD)
376 {
377 DBG (3, "gt68xx_device_activate: command-set-specific "
378 "activate failed: %s\n", sane_strstatus (status));
379 return status;
380 }
381 }
382 dev->afe = malloc (sizeof (*dev->afe));
383 dev->exposure = malloc (sizeof (*dev->exposure));
384 if (!dev->afe || !dev->exposure)
385 return SANE_STATUS_NO_MEM;
386 memcpy (dev->afe, &dev->model->afe_params, sizeof (*dev->afe));
387 memcpy (dev->exposure, &dev->model->exposure, sizeof (*dev->exposure));
388 dev->gamma_value = dev->model->default_gamma_value;
389 dev->active = SANE_TRUE;
390 return SANE_STATUS_GOOD;
391 }
392
393 SANE_Status
gt68xx_device_deactivate(GT68xx_Device * dev)394 gt68xx_device_deactivate (GT68xx_Device * dev)
395 {
396 SANE_Status status = SANE_STATUS_GOOD;
397 CHECK_DEV_ACTIVE (dev, "gt68xx_device_deactivate");
398 if (dev->read_active)
399 gt68xx_device_read_finish (dev);
400 if (dev->model->command_set->deactivate)
401 {
402 status = (*dev->model->command_set->deactivate) (dev);
403 if (status != SANE_STATUS_GOOD)
404 {
405 DBG (3,
406 "gt68xx_device_deactivate: command set-specific deactivate failed: %s\n",
407 sane_strstatus (status));
408 /* proceed with deactivate anyway */
409 }
410 }
411 if (dev->afe)
412 free (dev->afe);
413 dev->afe = 0;
414 if (dev->exposure)
415 free (dev->exposure);
416 dev->exposure = 0;
417 dev->active = SANE_FALSE;
418 return status;
419 }
420
421 SANE_Status
gt68xx_device_memory_write(GT68xx_Device * dev, SANE_Word addr, SANE_Word size, SANE_Byte * data)422 gt68xx_device_memory_write (GT68xx_Device * dev,
423 SANE_Word addr, SANE_Word size, SANE_Byte * data)
424 {
425 SANE_Status status;
426 DBG (8,
427 "gt68xx_device_memory_write: dev=%p, addr=0x%x, size=0x%x, data=%p\n",
428 (void *) dev, addr, size, (void *) data);
429 CHECK_DEV_ACTIVE (dev, "gt68xx_device_memory_write");
430 status =
431 sanei_usb_control_msg (dev->fd, 0x40,
432 dev->model->command_set->request,
433 dev->model->command_set->memory_write_value,
434 addr, size, data);
435 if (status != SANE_STATUS_GOOD)
436 {
437 DBG (3,
438 "gt68xx_device_memory_write: sanei_usb_control_msg failed: %s\n",
439 sane_strstatus (status));
440 }
441 return status;
442 }
443
444 SANE_Status
gt68xx_device_memory_read(GT68xx_Device * dev, SANE_Word addr, SANE_Word size, SANE_Byte * data)445 gt68xx_device_memory_read (GT68xx_Device * dev,
446 SANE_Word addr, SANE_Word size, SANE_Byte * data)
447 {
448 SANE_Status status;
449 DBG (8,
450 "gt68xx_device_memory_read: dev=%p, addr=0x%x, size=0x%x, data=%p\n",
451 (void *) dev, addr, size, (void *) data);
452 CHECK_DEV_ACTIVE (dev, "gt68xx_device_memory_read");
453 status =
454 sanei_usb_control_msg (dev->fd, 0xc0,
455 dev->model->command_set->request,
456 dev->model->command_set->memory_read_value,
457 addr, size, data);
458 if (status != SANE_STATUS_GOOD)
459 {
460 DBG (3,
461 "gt68xx_device_memory_read: sanei_usb_control_msg failed: %s\n",
462 sane_strstatus (status));
463 }
464
465 return status;
466 }
467
468 static SANE_Status
gt68xx_device_generic_req(GT68xx_Device * dev, SANE_Byte request_type, SANE_Word request, SANE_Word cmd_value, SANE_Word cmd_index, SANE_Word res_value, SANE_Word res_index, GT68xx_Packet cmd, GT68xx_Packet res, size_t res_size)469 gt68xx_device_generic_req (GT68xx_Device * dev,
470 SANE_Byte request_type, SANE_Word request,
471 SANE_Word cmd_value, SANE_Word cmd_index,
472 SANE_Word res_value, SANE_Word res_index,
473 GT68xx_Packet cmd, GT68xx_Packet res,
474 size_t res_size)
475 {
476 SANE_Status status;
477 DBG (7, "gt68xx_device_generic_req: command=0x%02x\n", cmd[0]);
478 DUMP_REQ (">>", cmd);
479 CHECK_DEV_ACTIVE (dev, "gt68xx_device_generic_req");
480 status = sanei_usb_control_msg (dev->fd,
481 request_type, request, cmd_value,
482 cmd_index, GT68XX_PACKET_SIZE, cmd);
483 if (status != SANE_STATUS_GOOD)
484 {
485 DBG (3, "gt68xx_device_generic_req: writing command failed: %s\n",
486 sane_strstatus (status));
487 return status;
488 }
489
490 memset (res, 0, sizeof (GT68xx_Packet));
491 status = sanei_usb_control_msg (dev->fd,
492 request_type | 0x80, request,
493 res_value, res_index, res_size, res);
494 if (status != SANE_STATUS_GOOD)
495 {
496 DBG (3, "gt68xx_device_generic_req: reading response failed: %s\n",
497 sane_strstatus (status));
498 return status;
499 }
500
501 DUMP_REQ ("<<", res);
502 return status;
503 }
504
505 SANE_Status
gt68xx_device_req(GT68xx_Device * dev, GT68xx_Packet cmd, GT68xx_Packet res)506 gt68xx_device_req (GT68xx_Device * dev, GT68xx_Packet cmd, GT68xx_Packet res)
507 {
508 GT68xx_Command_Set *command_set = dev->model->command_set;
509 return gt68xx_device_generic_req (dev,
510 command_set->request_type,
511 command_set->request,
512 command_set->send_cmd_value,
513 command_set->send_cmd_index,
514 command_set->recv_res_value,
515 command_set->recv_res_index, cmd,
516 res, GT68XX_PACKET_SIZE);
517 }
518
519 SANE_Status
gt68xx_device_small_req(GT68xx_Device * dev, GT68xx_Packet cmd, GT68xx_Packet res)520 gt68xx_device_small_req (GT68xx_Device * dev, GT68xx_Packet cmd,
521 GT68xx_Packet res)
522 {
523 GT68xx_Command_Set *command_set = dev->model->command_set;
524 GT68xx_Packet fixed_cmd;
525 int i;
526 for (i = 0; i < 8; ++i)
527 memcpy (fixed_cmd + i * 8, cmd, 8);
528 return gt68xx_device_generic_req (dev,
529 command_set->request_type,
530 command_set->request,
531 command_set->send_small_cmd_value,
532 command_set->send_small_cmd_index,
533 command_set->recv_small_res_value,
534 command_set->recv_small_res_index,
535 fixed_cmd, res, 0x08);
536 }
537
538
539 SANE_Status
gt68xx_device_download_firmware(GT68xx_Device * dev, SANE_Byte * data, SANE_Word size)540 gt68xx_device_download_firmware (GT68xx_Device * dev,
541 SANE_Byte * data, SANE_Word size)
542 {
543 CHECK_DEV_ACTIVE (dev, "gt68xx_device_download_firmware");
544 if (dev->model->command_set->download_firmware)
545 return (*dev->model->command_set->download_firmware) (dev, data, size);
546 else
547 return SANE_STATUS_UNSUPPORTED;
548 }
549
550 SANE_Status
gt68xx_device_get_power_status(GT68xx_Device * dev, SANE_Bool * power_ok)551 gt68xx_device_get_power_status (GT68xx_Device * dev, SANE_Bool * power_ok)
552 {
553 CHECK_DEV_ACTIVE (dev, "gt68xx_device_get_power_status");
554 if (dev->model->command_set->get_power_status)
555 return (*dev->model->command_set->get_power_status) (dev, power_ok);
556 else
557 return SANE_STATUS_UNSUPPORTED;
558 }
559
560 SANE_Status
gt68xx_device_get_ta_status(GT68xx_Device * dev, SANE_Bool * ta_attached)561 gt68xx_device_get_ta_status (GT68xx_Device * dev, SANE_Bool * ta_attached)
562 {
563 CHECK_DEV_ACTIVE (dev, "gt68xx_device_get_ta_status");
564 if (dev->model->command_set->get_ta_status)
565 return (*dev->model->command_set->get_ta_status) (dev, ta_attached);
566 else
567 return SANE_STATUS_UNSUPPORTED;
568 }
569
570 SANE_Status
gt68xx_device_lamp_control(GT68xx_Device * dev, SANE_Bool fb_lamp, SANE_Bool ta_lamp)571 gt68xx_device_lamp_control (GT68xx_Device * dev, SANE_Bool fb_lamp,
572 SANE_Bool ta_lamp)
573 {
574 CHECK_DEV_ACTIVE (dev, "gt68xx_device_lamp_control");
575 if (dev->model->command_set->lamp_control)
576 return (*dev->model->command_set->lamp_control) (dev, fb_lamp, ta_lamp);
577 else
578 return SANE_STATUS_UNSUPPORTED;
579 }
580
581 SANE_Status
gt68xx_device_is_moving(GT68xx_Device * dev, SANE_Bool * moving)582 gt68xx_device_is_moving (GT68xx_Device * dev, SANE_Bool * moving)
583 {
584 CHECK_DEV_ACTIVE (dev, "gt68xx_device_is_moving");
585 if (dev->model->command_set->is_moving)
586 return (*dev->model->command_set->is_moving) (dev, moving);
587 else
588 return SANE_STATUS_UNSUPPORTED;
589 }
590
591 /* currently not used */
592 #if 0
593 static SANE_Status
594 gt68xx_device_move_relative (GT68xx_Device * dev, SANE_Int distance)
595 {
596 CHECK_DEV_ACTIVE (dev, "gt68xx_device_move_relative");
597 if (dev->model->command_set->move_relative)
598 return (*dev->model->command_set->move_relative) (dev, distance);
599 else
600 return SANE_STATUS_UNSUPPORTED;
601 }
602 #endif
603
604 SANE_Status
gt68xx_device_carriage_home(GT68xx_Device * dev)605 gt68xx_device_carriage_home (GT68xx_Device * dev)
606 {
607 CHECK_DEV_ACTIVE (dev, "gt68xx_device_carriage_home");
608 if (dev->model->command_set->carriage_home)
609 return (*dev->model->command_set->carriage_home) (dev);
610 else
611 return SANE_STATUS_UNSUPPORTED;
612 }
613
614 SANE_Status
gt68xx_device_paperfeed(GT68xx_Device * dev)615 gt68xx_device_paperfeed (GT68xx_Device * dev)
616 {
617 CHECK_DEV_ACTIVE (dev, "gt68xx_device_paperfeed");
618 if (dev->model->command_set->paperfeed)
619 return (*dev->model->command_set->paperfeed) (dev);
620 else
621 return SANE_STATUS_UNSUPPORTED;
622 }
623
624 SANE_Status
gt68xx_device_start_scan(GT68xx_Device * dev)625 gt68xx_device_start_scan (GT68xx_Device * dev)
626 {
627 CHECK_DEV_ACTIVE (dev, "gt68xx_device_start_scan");
628 if (dev->model->command_set->start_scan)
629 {
630 if (!dev->scan_started)
631 {
632 dev->scan_started = SANE_TRUE;
633 return (*dev->model->command_set->start_scan) (dev);
634 }
635 return SANE_STATUS_DEVICE_BUSY;
636 }
637 else
638 return SANE_STATUS_UNSUPPORTED;
639 }
640
641 SANE_Status
gt68xx_device_read_scanned_data(GT68xx_Device * dev, SANE_Bool * ready)642 gt68xx_device_read_scanned_data (GT68xx_Device * dev, SANE_Bool * ready)
643 {
644 CHECK_DEV_ACTIVE (dev, "gt68xx_device_read_scanned_data");
645 if (dev->model->command_set->read_scanned_data)
646 return (*dev->model->command_set->read_scanned_data) (dev, ready);
647 else
648 return SANE_STATUS_UNSUPPORTED;
649 }
650
651 SANE_Status
gt68xx_device_setup_scan(GT68xx_Device * dev, GT68xx_Scan_Request * request, GT68xx_Scan_Action action, GT68xx_Scan_Parameters * params)652 gt68xx_device_setup_scan (GT68xx_Device * dev,
653 GT68xx_Scan_Request * request,
654 GT68xx_Scan_Action action,
655 GT68xx_Scan_Parameters * params)
656 {
657 CHECK_DEV_ACTIVE (dev, "gt68xx_device_setup_scan");
658 if (dev->model->command_set->setup_scan)
659 return (*dev->model->command_set->setup_scan) (dev, request, action,
660 params);
661 else
662 return SANE_STATUS_UNSUPPORTED;
663 }
664
665 SANE_Status
gt68xx_device_set_afe(GT68xx_Device * dev, GT68xx_AFE_Parameters * params)666 gt68xx_device_set_afe (GT68xx_Device * dev, GT68xx_AFE_Parameters * params)
667 {
668 CHECK_DEV_ACTIVE (dev, "gt68xx_device_set_afe");
669 if (dev->model->command_set->set_afe)
670 return (*dev->model->command_set->set_afe) (dev, params);
671 else
672 return SANE_STATUS_UNSUPPORTED;
673 }
674
675 SANE_Status
gt68xx_device_set_exposure_time(GT68xx_Device * dev, GT68xx_Exposure_Parameters * params)676 gt68xx_device_set_exposure_time (GT68xx_Device * dev,
677 GT68xx_Exposure_Parameters * params)
678 {
679 CHECK_DEV_ACTIVE (dev, "gt68xx_device_set_exposure_time");
680 if (dev->model->command_set->set_exposure_time)
681 return (*dev->model->command_set->set_exposure_time) (dev, params);
682 else
683 return SANE_STATUS_UNSUPPORTED;
684 }
685
686 SANE_Status
gt68xx_device_stop_scan(GT68xx_Device * dev)687 gt68xx_device_stop_scan (GT68xx_Device * dev)
688 {
689 CHECK_DEV_ACTIVE (dev, "gt68xx_device_stop_scan");
690 if (dev->model->command_set->stop_scan)
691 {
692 if (dev->scan_started)
693 {
694 dev->scan_started = SANE_FALSE;
695 return (*dev->model->command_set->stop_scan) (dev);
696 }
697 return SANE_STATUS_GOOD; // Essentially a NOP.
698 }
699 else
700 return SANE_STATUS_UNSUPPORTED;
701 }
702
703 SANE_Status
gt68xx_device_read_raw(GT68xx_Device * dev, SANE_Byte * buffer, size_t * size)704 gt68xx_device_read_raw (GT68xx_Device * dev, SANE_Byte * buffer,
705 size_t * size)
706 {
707 SANE_Status status;
708 CHECK_DEV_ACTIVE (dev, "gt68xx_device_read_raw");
709 DBG (7, "gt68xx_device_read_raw: enter: size=%lu\n", (unsigned long) *size);
710 status = sanei_usb_read_bulk (dev->fd, buffer, size);
711 if (status != SANE_STATUS_GOOD)
712 {
713 DBG (3, "gt68xx_device_read_raw: bulk read failed: %s\n",
714 sane_strstatus (status));
715 return status;
716 }
717 DBG (7, "gt68xx_device_read_raw: leave: size=%lu\n", (unsigned long) *size);
718 return SANE_STATUS_GOOD;
719 }
720
721 SANE_Status
gt68xx_device_set_read_buffer_size(GT68xx_Device * dev, size_t buffer_size)722 gt68xx_device_set_read_buffer_size (GT68xx_Device * dev, size_t buffer_size)
723 {
724 CHECK_DEV_NOT_NULL (dev, "gt68xx_device_set_read_buffer_size");
725 if (dev->read_active)
726 {
727 DBG (3, "gt68xx_device_set_read_buffer_size: BUG: read already "
728 "active\n");
729 return SANE_STATUS_INVAL;
730 }
731
732 buffer_size = (buffer_size + 63UL) & ~63UL;
733 if (buffer_size > 0)
734 {
735 dev->requested_buffer_size = buffer_size;
736 return SANE_STATUS_GOOD;
737 }
738
739 DBG (3, "gt68xx_device_set_read_buffer_size: bad buffer size\n");
740 return SANE_STATUS_INVAL;
741 }
742
743 SANE_Status
gt68xx_device_read_prepare(GT68xx_Device * dev, size_t expected_count, SANE_Bool final_scan)744 gt68xx_device_read_prepare (GT68xx_Device * dev,
745 size_t expected_count, SANE_Bool final_scan)
746 {
747 size_t buffer_size;
748 CHECK_DEV_ACTIVE (dev, "gt68xx_device_read_prepare");
749 if (dev->read_active)
750 {
751 DBG (3, "gt68xx_device_read_prepare: read already active\n");
752 return SANE_STATUS_INVAL;
753 }
754 DBG (5, "gt68xx_device_read_prepare: total size: %lu bytes\n",
755 (unsigned long) expected_count);
756 buffer_size = dev->requested_buffer_size;
757 DBG (5, "gt68xx_device_read_prepare: requested buffer size: %lu\n",
758 (unsigned long) buffer_size);
759 if (buffer_size > expected_count)
760 {
761 buffer_size = (expected_count + 63UL) & ~63UL;
762 }
763 DBG (5, "gt68xx_device_read_prepare: real size: %lu\n",
764 (unsigned long) buffer_size);
765 dev->read_buffer_size = buffer_size;
766 dev->read_buffer = (SANE_Byte *) malloc (buffer_size);
767 if (!dev->read_buffer)
768 {
769 DBG (3,
770 "gt68xx_device_read_prepare: not enough memory for the read buffer (%lu bytes)\n",
771 (unsigned long) buffer_size);
772 return SANE_STATUS_NO_MEM;
773 }
774
775 dev->read_active = SANE_TRUE;
776 dev->final_scan = final_scan;
777 dev->read_pos = dev->read_bytes_in_buffer = 0;
778 dev->read_bytes_left = expected_count;
779 return SANE_STATUS_GOOD;
780 }
781
782 #ifdef USE_FORK
783
784 static SANE_Status
gt68xx_reader_process(GT68xx_Device * dev)785 gt68xx_reader_process (GT68xx_Device * dev)
786 {
787 SANE_Status status = SANE_STATUS_GOOD;
788 SANE_Int buffer_id;
789 SANE_Byte *buffer_addr;
790 size_t size;
791 SANE_Int line = 0;
792 size_t read_bytes_left = dev->read_bytes_left;
793 shm_channel_writer_init (dev->shm_channel);
794 while (read_bytes_left > 0)
795 {
796 status = shm_channel_writer_get_buffer (dev->shm_channel,
797 &buffer_id, &buffer_addr);
798 if (status != SANE_STATUS_GOOD)
799 break;
800 DBG (9, "gt68xx_reader_process: buffer %d: get\n", buffer_id);
801 size = dev->read_buffer_size;
802 DBG (9, "gt68xx_reader_process: buffer %d: trying to read %lu bytes "
803 "(%lu bytes left, line %d)\n", buffer_id, (unsigned long) size,
804 (unsigned long) read_bytes_left, line);
805 status = gt68xx_device_read_raw (dev, buffer_addr, &size);
806 if (status != SANE_STATUS_GOOD)
807 break;
808 DBG (9,
809 "gt68xx_reader_process: buffer %d: read %lu bytes (line %d)\n",
810 buffer_id, (unsigned long) size, line);
811 status =
812 shm_channel_writer_put_buffer (dev->shm_channel, buffer_id, size);
813 if (status != SANE_STATUS_GOOD)
814 break;
815 DBG (9, "gt68xx_reader_process: buffer %d: put\n", buffer_id);
816 read_bytes_left -= size;
817 line++;
818 }
819 DBG (9, "gt68xx_reader_process: finished, now sleeping\n");
820 if (status != SANE_STATUS_GOOD)
821 return status;
822 sleep (5 * 60); /* wait until we are killed (or timeout) */
823 shm_channel_writer_close (dev->shm_channel);
824 return status;
825 }
826
827 static SANE_Status
gt68xx_device_read_start_fork(GT68xx_Device * dev)828 gt68xx_device_read_start_fork (GT68xx_Device * dev)
829 {
830 SANE_Status status;
831 int pid;
832 if (dev->shm_channel)
833 {
834 DBG (3,
835 "gt68xx_device_read_start_fork: BUG: shm_channel already created\n");
836 return SANE_STATUS_INVAL;
837 }
838
839 status =
840 shm_channel_new (dev->read_buffer_size, SHM_BUFFERS, &dev->shm_channel);
841 if (status != SANE_STATUS_GOOD)
842 {
843 DBG (3,
844 "gt68xx_device_read_start_fork: cannot create shared memory channel: "
845 "%s\n", sane_strstatus (status));
846 dev->shm_channel = NULL;
847 return status;
848 }
849
850 pid = fork ();
851 if (pid == -1)
852 {
853 DBG (3, "gt68xx_device_read_start_fork: cannot fork: %s\n",
854 strerror (errno));
855 shm_channel_free (dev->shm_channel);
856 dev->shm_channel = NULL;
857 return SANE_STATUS_NO_MEM;
858 }
859
860 if (pid == 0)
861 {
862 /* Child process */
863 status = gt68xx_reader_process (dev);
864 _exit (status);
865 }
866 else
867 {
868 /* Parent process */
869 dev->reader_pid = pid;
870 shm_channel_reader_init (dev->shm_channel);
871 shm_channel_reader_start (dev->shm_channel);
872 return SANE_STATUS_GOOD;
873 }
874 }
875
876 #endif /* USE_FORK */
877
878
879 static SANE_Status
gt68xx_device_read_start(GT68xx_Device * dev)880 gt68xx_device_read_start (GT68xx_Device * dev)
881 {
882 CHECK_DEV_ACTIVE (dev, "gt68xx_device_read_start");
883 #ifdef USE_FORK
884 /* Don't fork a separate process for every calibration scan. */
885 if (dev->final_scan)
886 return gt68xx_device_read_start_fork (dev);
887 #endif /* USE_FORK */
888 return SANE_STATUS_GOOD;
889 }
890
891 SANE_Status
gt68xx_device_read(GT68xx_Device * dev, SANE_Byte * buffer, size_t * size)892 gt68xx_device_read (GT68xx_Device * dev, SANE_Byte * buffer, size_t * size)
893 {
894 SANE_Status status;
895 size_t byte_count = 0;
896 size_t left_to_read = *size;
897 size_t transfer_size, block_size, raw_block_size;
898 #ifdef USE_FORK
899 SANE_Int buffer_id;
900 SANE_Byte *buffer_addr;
901 SANE_Int buffer_bytes;
902 #endif /* USE_FORK */
903 CHECK_DEV_ACTIVE (dev, "gt68xx_device_read");
904 if (!dev->read_active)
905 {
906 DBG (3, "gt68xx_device_read: read not active\n");
907 return SANE_STATUS_INVAL;
908 }
909
910 while (left_to_read > 0)
911 {
912 if (dev->read_bytes_in_buffer == 0)
913 {
914 block_size = dev->read_buffer_size;
915 if (block_size > dev->read_bytes_left)
916 block_size = dev->read_bytes_left;
917 if (block_size == 0)
918 break;
919 raw_block_size = (block_size + 63UL) & ~63UL;
920 DBG (7, "gt68xx_device_read: trying to read %ld bytes\n",
921 (long) raw_block_size);
922 #ifdef USE_FORK
923 if (dev->shm_channel)
924 {
925 status = shm_channel_reader_get_buffer (dev->shm_channel,
926 &buffer_id,
927 &buffer_addr,
928 &buffer_bytes);
929 if (status == SANE_STATUS_GOOD && buffer_addr != NULL)
930 {
931 DBG (9, "gt68xx_device_read: buffer %d: get\n", buffer_id);
932 memcpy (dev->read_buffer, buffer_addr, buffer_bytes);
933 shm_channel_reader_put_buffer (dev->shm_channel, buffer_id);
934 DBG (9, "gt68xx_device_read: buffer %d: put\n", buffer_id);
935 }
936 }
937 else
938 #endif /* USE_FORK */
939 status = gt68xx_device_read_raw (dev, dev->read_buffer,
940 &raw_block_size);
941 if (status != SANE_STATUS_GOOD)
942 {
943 DBG (3, "gt68xx_device_read: read failed\n");
944 return status;
945 }
946 dev->read_pos = 0;
947 dev->read_bytes_in_buffer = block_size;
948 dev->read_bytes_left -= block_size;
949 }
950
951 transfer_size = left_to_read;
952 if (transfer_size > dev->read_bytes_in_buffer)
953 transfer_size = dev->read_bytes_in_buffer;
954 if (transfer_size > 0)
955 {
956 memcpy (buffer, dev->read_buffer + dev->read_pos, transfer_size);
957 dev->read_pos += transfer_size;
958 dev->read_bytes_in_buffer -= transfer_size;
959 byte_count += transfer_size;
960 left_to_read -= transfer_size;
961 buffer += transfer_size;
962 }
963 }
964
965 *size = byte_count;
966 if (byte_count == 0)
967 return SANE_STATUS_EOF;
968 else
969 return SANE_STATUS_GOOD;
970 }
971
972 SANE_Status
gt68xx_device_read_finish(GT68xx_Device * dev)973 gt68xx_device_read_finish (GT68xx_Device * dev)
974 {
975 SANE_Status status = SANE_STATUS_GOOD;
976 CHECK_DEV_ACTIVE (dev, "gt68xx_device_read_finish");
977 if (!dev->read_active)
978 {
979 DBG (3, "gt68xx_device_read_finish: read not active\n");
980 return SANE_STATUS_INVAL;
981 }
982
983 DBG (7, "gt68xx_device_read_finish: read_bytes_left = %ld\n",
984 (long) dev->read_bytes_left);
985 #ifdef USE_FORK
986 if (dev->reader_pid != 0)
987 {
988 int pid_status;
989 /* usleep (100000); */
990 DBG (7, "gt68xx_device_read_finish: trying to kill reader process\n");
991 kill (dev->reader_pid, SIGKILL);
992 waitpid (dev->reader_pid, &pid_status, 0);
993 if (WIFEXITED (pid_status))
994 status = WEXITSTATUS (pid_status);
995 DBG (7, "gt68xx_device_read_finish: reader process killed\n");
996 dev->reader_pid = 0;
997 }
998 if (dev->shm_channel)
999 {
1000 shm_channel_free (dev->shm_channel);
1001 dev->shm_channel = NULL;
1002 }
1003
1004 #endif /* USE_FORK */
1005
1006 free (dev->read_buffer);
1007 dev->read_buffer = NULL;
1008 dev->read_active = SANE_FALSE;
1009 DBG (7, "gt68xx_device_read_finish: exit (%s)\n", sane_strstatus (status));
1010 return status;
1011 }
1012
1013 static SANE_Status
gt68xx_device_check_result(GT68xx_Packet res, SANE_Byte command)1014 gt68xx_device_check_result (GT68xx_Packet res, SANE_Byte command)
1015 {
1016 if (res[0] != 0)
1017 {
1018 DBG (1, "gt68xx_device_check_result: result was %2X %2X "
1019 "(expected: %2X %2X)\n", res[0], res[1], 0, command);
1020 return SANE_STATUS_IO_ERROR;
1021 }
1022 /* The Gt681xfw.usb firmware doesn't return the command byte
1023 in the second byte, so we can't rely on that test */
1024 if (res[1] != command)
1025 DBG (5, "gt68xx_device_check_result: warning: result was %2X %2X "
1026 "(expected: %2X %2X)\n", res[0], res[1], 0, command);
1027 return SANE_STATUS_GOOD;
1028 }
1029
1030 SANE_Status
gt68xx_device_get_id(GT68xx_Device * dev)1031 gt68xx_device_get_id (GT68xx_Device * dev)
1032 {
1033 CHECK_DEV_ACTIVE (dev, "gt68xx_device_get_id");
1034 if (dev->model->command_set->get_id)
1035 return (*dev->model->command_set->get_id) (dev);
1036 else
1037 return SANE_STATUS_UNSUPPORTED;
1038 }
1039
1040 static void
gt68xx_device_fix_descriptor(GT68xx_Device * dev)1041 gt68xx_device_fix_descriptor (GT68xx_Device * dev)
1042 {
1043 SANE_Byte data[8];
1044 sanei_usb_control_msg (dev->fd, 0x80, 0x06, 0x01 << 8, 0, 8, data);
1045 }
1046
1047
1048 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
1049