• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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