1 /*
2 Copyright (C) 2008, Panasonic Russia Ltd.
3 Copyright (C) 2010, m. allan noah
4 */
5 /*
6 Panasonic KV-S20xx USB-SCSI scanners.
7 */
8
9 #define DEBUG_NOT_STATIC
10 #define BUILD 2
11
12 #include "../include/sane/config.h"
13
14 #include <string.h>
15 #include <unistd.h>
16
17 #include "../include/sane/sanei_backend.h"
18 #include "../include/sane/sanei_scsi.h"
19 #include "../include/sane/sanei_usb.h"
20 #include "../include/sane/saneopts.h"
21 #include "../include/sane/sanei_config.h"
22 #include "../include/lassert.h"
23
24 #include "kvs20xx.h"
25 #include "kvs20xx_cmd.h"
26
27 struct known_device
28 {
29 const SANE_Int id;
30 const SANE_Device scanner;
31 };
32
33 static const struct known_device known_devices[] = {
34 {
35 KV_S2025C,
36 { "", "MATSHITA", "KV-S2025C", "sheetfed scanner" },
37 },
38 {
39 KV_S2045C,
40 { "", "MATSHITA", "KV-S2045C", "sheetfed scanner" },
41 },
42 {
43 KV_S2026C,
44 { "", "MATSHITA", "KV-S2026C", "sheetfed scanner" },
45 },
46 {
47 KV_S2046C,
48 { "", "MATSHITA", "KV-S2046C", "sheetfed scanner" },
49 },
50 {
51 KV_S2028C,
52 { "", "MATSHITA", "KV-S2028C", "sheetfed scanner" },
53 },
54 {
55 KV_S2048C,
56 { "", "MATSHITA", "KV-S2048C", "sheetfed scanner" },
57 },
58 };
59
60 SANE_Status
sane_init(SANE_Int __sane_unused__ * version_code,SANE_Auth_Callback __sane_unused__ authorize)61 sane_init (SANE_Int __sane_unused__ * version_code,
62 SANE_Auth_Callback __sane_unused__ authorize)
63 {
64 DBG_INIT ();
65 DBG (DBG_INFO, "This is panasonic kvs20xx driver\n");
66
67 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
68
69 /* Initialize USB */
70 sanei_usb_init ();
71
72 return SANE_STATUS_GOOD;
73 }
74
75 /*
76 * List of available devices, allocated by sane_get_devices, released
77 * by sane_exit()
78 */
79 static SANE_Device **devlist = NULL;
80 static unsigned curr_scan_dev = 0;
81
82 void
sane_exit(void)83 sane_exit (void)
84 {
85 if (devlist)
86 {
87 int i;
88 for (i = 0; devlist[i]; i++)
89 {
90 free ((void *) devlist[i]->name);
91 free ((void *) devlist[i]);
92 }
93 free ((void *) devlist);
94 devlist = NULL;
95 }
96 }
97
98 static SANE_Status
attach(SANE_String_Const devname)99 attach (SANE_String_Const devname)
100 {
101 int i = 0;
102 if (devlist)
103 {
104 for (; devlist[i]; i++);
105 devlist = realloc (devlist, sizeof (SANE_Device *) * (i + 1));
106 if (!devlist)
107 return SANE_STATUS_NO_MEM;
108 }
109 else
110 {
111 devlist = malloc (sizeof (SANE_Device *) * 2);
112 if (!devlist)
113 return SANE_STATUS_NO_MEM;
114 }
115 devlist[i] = malloc (sizeof (SANE_Device));
116 if (!devlist[i])
117 return SANE_STATUS_NO_MEM;
118 memcpy (devlist[i], &known_devices[curr_scan_dev].scanner,
119 sizeof (SANE_Device));
120 devlist[i]->name = strdup (devname);
121 /* terminate device list with NULL entry: */
122 devlist[i + 1] = 0;
123 DBG (DBG_INFO, "%s device attached\n", devname);
124 return SANE_STATUS_GOOD;
125 }
126
127 /* Get device list */
128 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)129 sane_get_devices (const SANE_Device *** device_list,
130 SANE_Bool __sane_unused__ local_only)
131 {
132 if (devlist)
133 {
134 int i;
135 for (i = 0; devlist[i]; i++)
136 {
137 free ((void *) devlist[i]->name);
138 free ((void *) devlist[i]);
139 }
140 free ((void *) devlist);
141 devlist = NULL;
142 }
143
144 for (curr_scan_dev = 0;
145 curr_scan_dev < sizeof (known_devices) / sizeof (known_devices[0]);
146 curr_scan_dev++)
147 {
148 sanei_usb_find_devices (PANASONIC_ID,
149 known_devices[curr_scan_dev].id, attach);
150 }
151 for (curr_scan_dev = 0;
152 curr_scan_dev < sizeof (known_devices) / sizeof (known_devices[0]);
153 curr_scan_dev++)
154 {
155 sanei_scsi_find_devices (known_devices[curr_scan_dev].scanner.vendor,
156 known_devices[curr_scan_dev].scanner.model,
157 NULL, -1, -1, -1, -1, attach);
158 }
159 if(device_list)
160 *device_list = (const SANE_Device **) devlist;
161 return SANE_STATUS_GOOD;
162 }
163
164 /* Open device, return the device handle */
165 SANE_Status
sane_open(SANE_String_Const devname,SANE_Handle * handle)166 sane_open (SANE_String_Const devname, SANE_Handle * handle)
167 {
168 unsigned i, j, id = 0;
169 struct scanner *s;
170 SANE_Int h, bus;
171 SANE_Status st;
172 if (!devlist)
173 {
174 st = sane_get_devices (NULL, 0);
175 if (st)
176 return st;
177 }
178 for (i = 0; devlist[i]; i++)
179 {
180 if (!strcmp (devlist[i]->name, devname))
181 break;
182 }
183 if (!devlist[i])
184 return SANE_STATUS_INVAL;
185 for (j = 0; j < sizeof (known_devices) / sizeof (known_devices[0]); j++)
186 {
187 if (!strcmp (devlist[i]->model, known_devices[j].scanner.model))
188 {
189 id = known_devices[j].id;
190 break;
191 }
192 }
193
194 st = sanei_usb_open (devname, &h);
195 if (st == SANE_STATUS_ACCESS_DENIED)
196 return st;
197 if (st)
198 {
199 st = sanei_scsi_open (devname, &h, kvs20xx_sense_handler, NULL);
200 if (st)
201 {
202 return st;
203 }
204 bus = SCSI;
205 }
206 else
207 {
208 bus = USB;
209 st = sanei_usb_claim_interface (h, 0);
210 if (st)
211 {
212 sanei_usb_close (h);
213 return st;
214 }
215 }
216
217 s = malloc (sizeof (struct scanner));
218 if (!s)
219 return SANE_STATUS_NO_MEM;
220 memset (s, 0, sizeof (struct scanner));
221 s->buffer = malloc (MAX_READ_DATA_SIZE + BULK_HEADER_SIZE);
222 if (!s->buffer)
223 return SANE_STATUS_NO_MEM;
224 s->file = h;
225 s->bus = bus;
226 s->id = id;
227 kvs20xx_init_options (s);
228 *handle = s;
229 for (i = 0; i < 3; i++)
230 {
231 st = kvs20xx_test_unit_ready (s);
232 if (st)
233 {
234 if (s->bus == SCSI)
235 {
236 sanei_scsi_close (s->file);
237 st = sanei_scsi_open (devname, &h, kvs20xx_sense_handler, NULL);
238 if (st)
239 return st;
240 }
241 else
242 {
243 sanei_usb_release_interface (s->file, 0);
244 sanei_usb_close (s->file);
245 st = sanei_usb_open (devname, &h);
246 if (st)
247 return st;
248 st = sanei_usb_claim_interface (h, 0);
249 if (st)
250 {
251 sanei_usb_close (h);
252 return st;
253 }
254 }
255 s->file = h;
256 }
257 else
258 break;
259 }
260 if (i == 3)
261 return SANE_STATUS_DEVICE_BUSY;
262
263 st = kvs20xx_set_timeout (s, s->val[FEED_TIMEOUT].w);
264 if (st)
265 {
266 sane_close (s);
267 return st;
268 }
269
270 return SANE_STATUS_GOOD;
271 }
272
273 /* Close device */
274 void
sane_close(SANE_Handle handle)275 sane_close (SANE_Handle handle)
276 {
277 struct scanner *s = (struct scanner *) handle;
278 int i;
279 if (s->bus == USB)
280 {
281 sanei_usb_release_interface (s->file, 0);
282 sanei_usb_close (s->file);
283 }
284 else
285 sanei_scsi_close (s->file);
286
287 for (i = 1; i < NUM_OPTIONS; i++)
288 {
289 if (s->opt[i].type == SANE_TYPE_STRING && s->val[i].s)
290 free (s->val[i].s);
291 }
292 if (s->data)
293 free (s->data);
294 free (s->buffer);
295 free (s);
296
297 }
298
299 /* Get option descriptor */
300 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)301 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
302 {
303 struct scanner *s = handle;
304
305 if ((unsigned) option >= NUM_OPTIONS || option < 0)
306 return NULL;
307 return s->opt + option;
308 }
309
310 static SANE_Status
wait_document(struct scanner * s)311 wait_document (struct scanner *s)
312 {
313 SANE_Status st;
314 int i;
315 if (!strcmp ("off", s->val[MANUALFEED].s))
316 return kvs20xx_document_exist (s);
317
318 for (i = 0; i < s->val[FEED_TIMEOUT].w; i++)
319 {
320 st = kvs20xx_document_exist (s);
321 if (st != SANE_STATUS_NO_DOCS)
322 return st;
323 sleep (1);
324 }
325 return SANE_STATUS_NO_DOCS;
326 }
327
328 /* Start scanning */
329 SANE_Status
sane_start(SANE_Handle handle)330 sane_start (SANE_Handle handle)
331 {
332 struct scanner *s = (struct scanner *) handle;
333 SANE_Status st;
334 int duplex = s->val[DUPLEX].w;
335
336 if (!s->scanning)
337 {
338 unsigned dummy_length;
339 st = kvs20xx_test_unit_ready (s);
340 if (st)
341 return st;
342
343 st = wait_document (s);
344 if (st)
345 return st;
346
347 st = kvs20xx_reset_window (s);
348 if (st)
349 return st;
350 st = kvs20xx_set_window (s, SIDE_FRONT);
351 if (st)
352 return st;
353 if (duplex)
354 {
355 st = kvs20xx_set_window (s, SIDE_BACK);
356 if (st)
357 return st;
358 }
359 st = kvs20xx_scan (s);
360 if (st)
361 return st;
362
363 st = kvs20xx_read_picture_element (s, SIDE_FRONT, &s->params);
364 if (st)
365 return st;
366 if (duplex)
367 {
368 st = get_adjust_data (s, &dummy_length);
369 if (st)
370 return st;
371 }
372 else
373 {
374 dummy_length = 0;
375 }
376 s->scanning = 1;
377 s->page = 0;
378 s->read = 0;
379 s->side = SIDE_FRONT;
380 sane_get_parameters (s, NULL);
381 s->saved_dummy_size = s->dummy_size = dummy_length
382 ? (dummy_length * s->val[RESOLUTION].w / 1200 - 1)
383 * s->params.bytes_per_line : 0;
384 s->side_size = s->params.lines * s->params.bytes_per_line;
385
386 s->data = realloc (s->data, duplex ? s->side_size * 2 : s->side_size);
387 if (!s->data)
388 {
389 s->scanning = 0;
390 return SANE_STATUS_NO_MEM;
391 }
392 }
393
394 if (duplex)
395 {
396 unsigned side = SIDE_FRONT;
397 unsigned read, mx;
398 if (s->side == SIDE_FRONT && s->read == s->side_size - s->dummy_size)
399 {
400 s->side = SIDE_BACK;
401 s->read = s->dummy_size;
402 s->dummy_size = 0;
403 return SANE_STATUS_GOOD;
404 }
405 s->read = 0;
406 s->dummy_size = s->saved_dummy_size;
407 s->side = SIDE_FRONT;
408 st = kvs20xx_document_exist (s);
409 if (st)
410 return st;
411 for (mx = s->side_size * 2; !st; mx -= read, side ^= SIDE_BACK)
412 st = kvs20xx_read_image_data (s, s->page, side,
413 &s->data[s->side_size * 2 - mx], mx,
414 &read);
415 }
416 else
417 {
418 unsigned read, mx;
419 s->read = 0;
420 st = kvs20xx_document_exist (s);
421 if (st)
422 return st;
423 DBG (DBG_INFO, "start: %d\n", s->page);
424
425 for (mx = s->side_size; !st; mx -= read)
426 st = kvs20xx_read_image_data (s, s->page, SIDE_FRONT,
427 &s->data[s->side_size - mx], mx, &read);
428 }
429 if (st && st != SANE_STATUS_EOF)
430 {
431 s->scanning = 0;
432 return st;
433 }
434 s->page++;
435 return SANE_STATUS_GOOD;
436 }
437
438 inline static void
memcpy24(u8 * dest,u8 * src,unsigned size,unsigned ls)439 memcpy24 (u8 * dest, u8 * src, unsigned size, unsigned ls)
440 {
441 unsigned i;
442 for (i = 0; i < size; i++)
443 {
444 dest[i * 3] = src[i];
445 dest[i * 3 + 1] = src[i + ls];
446 dest[i * 3 + 2] = src[i + 2 * ls];
447 }
448 }
449
450 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)451 sane_read (SANE_Handle handle, SANE_Byte * buf,
452 SANE_Int max_len, SANE_Int * len)
453 {
454 struct scanner *s = (struct scanner *) handle;
455 int duplex = s->val[DUPLEX].w;
456 int color = !strcmp (s->val[MODE].s, SANE_VALUE_SCAN_MODE_COLOR);
457 int rest = s->side_size - s->read - s->dummy_size;
458 *len = 0;
459
460 if (!s->scanning || !rest)
461 {
462 if (strcmp (s->val[FEEDER_MODE].s, SANE_I18N ("continuous")))
463 {
464 if (!duplex || s->side == SIDE_BACK)
465 s->scanning = 0;
466 }
467 return SANE_STATUS_EOF;
468 }
469
470 *len = max_len < rest ? max_len : rest;
471 if (duplex && (s->id == KV_S2025C
472 || s->id == KV_S2026C || s->id == KV_S2028C))
473 {
474 if (color)
475 {
476 unsigned ls = s->params.bytes_per_line;
477 unsigned i, a = s->side == SIDE_FRONT ? 0 : ls / 3;
478 u8 *data;
479 *len = (*len / ls) * ls;
480 for (i = 0, data = s->data + s->read * 2 + a;
481 i < *len / ls; buf += ls, data += 2 * ls, i++)
482 memcpy24 (buf, data, ls / 3, ls * 2 / 3);
483 }
484 else
485 {
486 unsigned ls = s->params.bytes_per_line;
487 unsigned i = s->side == SIDE_FRONT ? 0 : ls;
488 unsigned head = ls - (s->read % ls);
489 unsigned tail = (*len - head) % ls;
490 unsigned lines = (*len - head) / ls;
491 u8 *data = s->data + (s->read / ls) * ls * 2 + i + s->read % ls;
492 assert (data <= s->data + s->side_size * 2);
493 memcpy (buf, data, head);
494 for (i = 0, buf += head, data += head + (head ? ls : 0);
495 i < lines; buf += ls, data += ls * 2, i++)
496 {
497 assert (data <= s->data + s->side_size * 2);
498 memcpy (buf, data, ls);
499 }
500 assert ((data <= s->data + s->side_size * 2) || !tail);
501 memcpy (buf, data, tail);
502 }
503 s->read += *len;
504 }
505 else
506 {
507 if (color)
508 {
509 unsigned i, ls = s->params.bytes_per_line;
510 u8 *data = s->data + s->read;
511 *len = (*len / ls) * ls;
512 for (i = 0; i < *len / ls; buf += ls, data += ls, i++)
513 memcpy24 (buf, data, ls / 3, ls / 3);
514 }
515 else
516 {
517 memcpy (buf, s->data + s->read, *len);
518 }
519 s->read += *len;
520 }
521 return SANE_STATUS_GOOD;
522 }
523
524 void
sane_cancel(SANE_Handle handle)525 sane_cancel (SANE_Handle handle)
526 {
527 struct scanner *s = (struct scanner *) handle;
528 s->scanning = 0;
529 }
530
531 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ h,SANE_Bool __sane_unused__ m)532 sane_set_io_mode (SANE_Handle __sane_unused__ h, SANE_Bool __sane_unused__ m)
533 {
534 return SANE_STATUS_UNSUPPORTED;
535 }
536
537 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ h,SANE_Int __sane_unused__ * fd)538 sane_get_select_fd (SANE_Handle __sane_unused__ h,
539 SANE_Int __sane_unused__ * fd)
540 {
541 return SANE_STATUS_UNSUPPORTED;
542 }
543