• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    Copyright (C) 2009, Panasonic Russia Ltd.
3    Copyright (C) 2010,2011, m. allan noah
4 */
5 /*
6    Panasonic KV-S40xx USB-SCSI scanner driver.
7 */
8 #include "../include/sane/config.h"
9 #include <string.h>
10 
11 #define DEBUG_DECLARE_ONLY
12 #define BACKEND_NAME kvs40xx
13 
14 #include "../include/sane/sanei_backend.h"
15 #include "../include/sane/saneopts.h"
16 #include "../include/sane/sanei.h"
17 #include "../include/sane/sanei_usb.h"
18 #include "../include/sane/sanei_scsi.h"
19 #include "../include/sane/sanei_config.h"
20 
21 #include "kvs40xx.h"
22 
23 #include "../include/sane/sanei_debug.h"
24 
25 #define COMMAND_BLOCK	1
26 #define DATA_BLOCK	2
27 #define RESPONSE_BLOCK	3
28 
29 #define COMMAND_CODE	0x9000
30 #define DATA_CODE	0xb000
31 #define RESPONSE_CODE	0xa000
32 #define STATUS_SIZE 4
33 
34 struct bulk_header
35 {
36   u32 length;
37   u16 type;
38   u16 code;
39   u32 transaction_id;
40 };
41 
42 #define TEST_UNIT_READY        0x00
43 #define INQUIRY                0x12
44 #define SET_WINDOW             0x24
45 #define SCAN                   0x1B
46 #define SEND_10                0x2A
47 #define READ_10                0x28
48 #define REQUEST_SENSE          0x03
49 #define GET_BUFFER_STATUS      0x34
50 #define SET_TIMEOUT	    	0xE1
51 #define GET_ADJUST_DATA	    	0xE0
52 #define HOPPER_DOWN	    	0xE1
53 #define STOP_ADF		0xE1
54 
55 
56 
57 #define SUPPORT_INFO		0x93
58 
59 
60 #define GOOD 0
61 #define CHECK_CONDITION 2
62 
63 typedef enum
64 {
65   CMD_NONE = 0,
66   CMD_IN = 0x81,		/* scanner to pc */
67   CMD_OUT = 0x02		/* pc to scanner */
68 } CMD_DIRECTION;		/* equals to endpoint address */
69 
70 #define RESPONSE_SIZE	0x12
71 #define MAX_CMD_SIZE	12
72 struct cmd
73 {
74   unsigned char cmd[MAX_CMD_SIZE];
75   int cmd_size;
76   void *data;
77   int data_size;
78   int dir;
79 };
80 struct response
81 {
82   int status;
83   unsigned char data[RESPONSE_SIZE];
84 };
85 
86 static SANE_Status
usb_send_command(struct scanner * s,struct cmd * c,struct response * r,void * buf)87 usb_send_command (struct scanner *s, struct cmd *c, struct response *r,
88 		  void *buf)
89 {
90   SANE_Status st;
91   struct bulk_header *h = (struct bulk_header *) buf;
92   u8 resp[sizeof (*h) + STATUS_SIZE];
93   size_t sz = sizeof (*h) + MAX_CMD_SIZE;
94   memset (h, 0, sz);
95   h->length = cpu2be32 (sz);
96   h->type = cpu2be16 (COMMAND_BLOCK);
97   h->code = cpu2be16 (COMMAND_CODE);
98   memcpy (h + 1, c->cmd, c->cmd_size);
99 
100   st = sanei_usb_write_bulk (s->file, (const SANE_Byte *) h, &sz);
101   if (st)
102     return st;
103 
104   if (sz != sizeof (*h) + MAX_CMD_SIZE)
105     return SANE_STATUS_IO_ERROR;
106 
107   if (c->dir == CMD_IN)
108     {
109       unsigned l;
110       sz = sizeof (*h) + c->data_size;
111       c->data_size = 0;
112       st = sanei_usb_read_bulk (s->file, (SANE_Byte *) h, &sz);
113       for (l = sz; !st && l != be2cpu32 (h->length); l += sz)
114 	{
115 	  DBG (DBG_WARN, "usb wrong read (%d instead %d)\n",
116 	       c->data_size, be2cpu32 (h->length));
117 	  sz = be2cpu32 (h->length) - l;
118 	  st = sanei_usb_read_bulk (s->file, ((SANE_Byte *) h) + l, &sz);
119 
120 	}
121 
122       c->data = h + 1;
123 
124       if (st)
125 	{
126 	  st = sanei_usb_release_interface (s->file, 0);
127 	  if (st)
128 	    return st;
129 	  st = sanei_usb_claim_interface (s->file, 0);
130 
131 	  if (st)
132 	    return st;
133 
134 	  r->status = CHECK_CONDITION;
135 	  return SANE_STATUS_GOOD;
136 	}
137 
138       c->data_size = sz - sizeof (*h);
139 
140 
141     }
142   else if (c->dir == CMD_OUT)
143     {
144       sz = sizeof (*h) + c->data_size;
145       memset (h, 0, sizeof (*h));
146       h->length = cpu2be32 (sizeof (*h) + c->data_size);
147       h->type = cpu2be16 (DATA_BLOCK);
148       h->code = cpu2be16 (DATA_CODE);
149       memcpy (h + 1, c->data, c->data_size);
150       st = sanei_usb_write_bulk (s->file, (const SANE_Byte *) h, &sz);
151       if (st)
152 	return st;
153     }
154   sz = sizeof (resp);
155   st = sanei_usb_read_bulk (s->file, resp, &sz);
156   if (st || sz != sizeof (resp))
157     return SANE_STATUS_IO_ERROR;
158 
159   r->status = be2cpu32 (*((u32 *) (resp + sizeof (*h))));
160   return st;
161 }
162 
163 #define END_OF_MEDIUM			(1<<6)
164 #define INCORRECT_LENGTH_INDICATOR	(1<<5)
165 static const struct
166 {
167   unsigned sense, asc, ascq;
168   SANE_Status st;
169 } s_errors[] =
170 {
171   {
172   2, 0, 0, SANE_STATUS_DEVICE_BUSY},
173   {
174   2, 4, 1, SANE_STATUS_DEVICE_BUSY},
175   {
176   2, 4, 0x80, SANE_STATUS_COVER_OPEN},
177   {
178   2, 4, 0x81, SANE_STATUS_COVER_OPEN},
179   {
180   2, 4, 0x82, SANE_STATUS_COVER_OPEN},
181   {
182   2, 4, 0x83, SANE_STATUS_COVER_OPEN},
183   {
184   2, 4, 0x84, SANE_STATUS_COVER_OPEN},
185   {
186   2, 0x80, 1, SANE_STATUS_CANCELLED},
187   {
188   2, 0x80, 2, SANE_STATUS_CANCELLED},
189   {
190   3, 0x3a, 0, SANE_STATUS_NO_DOCS},
191   {
192   3, 0x80, 1, SANE_STATUS_JAMMED},
193   {
194   3, 0x80, 2, SANE_STATUS_JAMMED},
195   {
196   3, 0x80, 3, SANE_STATUS_JAMMED},
197   {
198   3, 0x80, 4, SANE_STATUS_JAMMED},
199   {
200   3, 0x80, 5, SANE_STATUS_JAMMED},
201   {
202   3, 0x80, 6, SANE_STATUS_JAMMED},
203   {
204   3, 0x80, 7, SANE_STATUS_JAMMED},
205   {
206   3, 0x80, 8, SANE_STATUS_JAMMED},
207   {
208   3, 0x80, 9, SANE_STATUS_JAMMED},
209   {
210   3, 0x80, 0xa, SANE_STATUS_JAMMED},
211   {
212   3, 0x80, 0xb, SANE_STATUS_JAMMED},
213   {
214   3, 0x80, 0xc, SANE_STATUS_JAMMED},
215   {
216   3, 0x80, 0xd, SANE_STATUS_JAMMED},
217   {
218   3, 0x80, 0xe, SANE_STATUS_JAMMED},
219   {
220   3, 0x80, 0xf, SANE_STATUS_JAMMED},
221   {
222   3, 0x80, 0x10, SANE_STATUS_JAMMED},
223   {
224   3, 0x80, 0x11, SANE_STATUS_JAMMED},
225   {
226   5, 0x1a, 0x0, SANE_STATUS_INVAL},
227   {
228   5, 0x20, 0x0, SANE_STATUS_INVAL},
229   {
230   5, 0x24, 0x0, SANE_STATUS_INVAL},
231   {
232   5, 0x25, 0x0, SANE_STATUS_INVAL},
233   {
234   5, 0x26, 0x0, SANE_STATUS_INVAL},
235   {
236   5, 0x2c, 0x01, SANE_STATUS_INVAL},
237   {
238   5, 0x2c, 0x02, SANE_STATUS_INVAL},
239   {
240   5, 0x2c, 0x80, SANE_STATUS_INVAL},
241   {
242   5, 0x2c, 0x81, SANE_STATUS_INVAL},
243   {
244   5, 0x2c, 0x82, SANE_STATUS_INVAL},
245   {
246 5, 0x2c, 0x83, SANE_STATUS_INVAL},};
247 
248 SANE_Status
kvs40xx_sense_handler(int __sane_unused__ fd,u_char * sense_buffer,void __sane_unused__ * arg)249 kvs40xx_sense_handler (int __sane_unused__ fd,
250 		       u_char * sense_buffer, void __sane_unused__ * arg)
251 {
252   unsigned i;
253   SANE_Status st = SANE_STATUS_GOOD;
254   if (sense_buffer[2] & 0xf)
255     {				/*error */
256       for (i = 0; i < sizeof (s_errors) / sizeof (s_errors[0]); i++)
257 	{
258 	  if ((sense_buffer[2] & 0xf) == s_errors[i].sense
259 	      && sense_buffer[12] == s_errors[i].asc
260 	      && sense_buffer[13] == s_errors[i].ascq)
261 	    {
262 	      st = s_errors[i].st;
263 	      break;
264 	    }
265 	}
266       if (i == sizeof (s_errors) / sizeof (s_errors[0]))
267 	st = SANE_STATUS_IO_ERROR;
268     }
269   else
270     {
271       if (sense_buffer[2] & END_OF_MEDIUM)
272 	st = SANE_STATUS_EOF;
273       else if (sense_buffer[2] & INCORRECT_LENGTH_INDICATOR)
274 	st = INCORRECT_LENGTH;
275     }
276 
277   DBG (DBG_ERR,
278        "send_command: CHECK_CONDITION: sense:0x%x ASC:0x%x ASCQ:0x%x\n",
279        sense_buffer[2], sense_buffer[12], sense_buffer[13]);
280 
281   return st;
282 }
283 
284 static SANE_Status
send_command(struct scanner * s,struct cmd * c)285 send_command (struct scanner * s, struct cmd * c)
286 {
287   SANE_Status st = SANE_STATUS_GOOD;
288   if (s->bus == USB)
289     {
290       struct response r;
291       memset (&r, 0, sizeof (r));
292       st = usb_send_command (s, c, &r, s->buffer);
293       if (st)
294 	return st;
295       if (r.status)
296 	{
297 	  u8 b[sizeof (struct bulk_header) + RESPONSE_SIZE];
298 	  struct cmd c2 = {
299             {0}, 6,
300 	    NULL, RESPONSE_SIZE,
301 	    CMD_IN
302 	  };
303 	  c2.cmd[0] = REQUEST_SENSE;
304 	  c2.cmd[4] = RESPONSE_SIZE;
305 
306 	  st = usb_send_command (s, &c2, &r, b);
307 	  if (st)
308 	    return st;
309 	  st = kvs40xx_sense_handler (0, b + sizeof (struct bulk_header), NULL);
310 	}
311     }
312   else
313     {
314       if (c->dir == CMD_OUT)
315 	{
316 	  memcpy (s->buffer, c->cmd, c->cmd_size);
317 	  memcpy (s->buffer + c->cmd_size, c->data, c->data_size);
318 	  st = sanei_scsi_cmd (s->file, s->buffer,
319 			       c->cmd_size + c->data_size, NULL, NULL);
320 	}
321       else if (c->dir == CMD_IN)
322 	{
323 	  c->data = s->buffer;
324 	  st = sanei_scsi_cmd (s->file, c->cmd, c->cmd_size,
325 			       c->data, (size_t *) & c->data_size);
326 	}
327       else
328 	{
329 	  st = sanei_scsi_cmd (s->file, c->cmd, c->cmd_size, NULL, NULL);
330 	}
331     }
332   return st;
333 }
334 
335 SANE_Status
kvs40xx_test_unit_ready(struct scanner * s)336 kvs40xx_test_unit_ready (struct scanner * s)
337 {
338   struct cmd c = {
339     {0}, 6,
340     NULL, 0,
341     CMD_NONE
342   };
343   c.cmd[0] = TEST_UNIT_READY;
344   if (send_command (s, &c))
345     return SANE_STATUS_DEVICE_BUSY;
346 
347   return SANE_STATUS_GOOD;
348 }
349 
350 SANE_Status
kvs40xx_set_timeout(struct scanner * s,int timeout)351 kvs40xx_set_timeout (struct scanner * s, int timeout)
352 {
353   u16 t = cpu2be16 ((u16) timeout);
354   struct cmd c = {
355     {0}, 10,
356     NULL, 0,
357     CMD_OUT
358   };
359   c.data = &t;
360   c.data_size = sizeof (t);
361   c.cmd[0] = SET_TIMEOUT;
362   c.cmd[2] = 0x8d;
363   copy16 (c.cmd + 7, cpu2be16 (sizeof (t)));
364   if (s->bus == USB)
365     sanei_usb_set_timeout (timeout * 1000);
366 
367   return send_command (s, &c);
368 }
369 
370 SANE_Status
kvs40xx_set_window(struct scanner * s,int wnd_id)371 kvs40xx_set_window (struct scanner * s, int wnd_id)
372 {
373   struct window wnd;
374   struct cmd c = {
375     {0}, 10,
376     NULL, 0,
377     CMD_OUT
378   };
379   c.data = &wnd;
380   c.data_size = sizeof (wnd);
381   c.cmd[0] = SET_WINDOW;
382   copy16 (c.cmd + 7, cpu2be16 (sizeof (wnd)));
383   kvs40xx_init_window (s, &wnd, wnd_id);
384 
385   return send_command (s, &c);
386 }
387 
388 SANE_Status
kvs40xx_reset_window(struct scanner * s)389 kvs40xx_reset_window (struct scanner * s)
390 {
391   struct cmd c = {
392     {0}, 10,
393     NULL, 0,
394     CMD_NONE
395   };
396   c.cmd[0] = SET_WINDOW;
397 
398   return send_command (s, &c);
399 }
400 
401 SANE_Status
kvs40xx_scan(struct scanner * s)402 kvs40xx_scan (struct scanner * s)
403 {
404   struct cmd c = {
405     {0}, 6,
406     NULL, 0,
407     CMD_NONE
408   };
409   c.cmd[0] = SCAN;
410   return send_command (s, &c);
411 }
412 
413 SANE_Status
hopper_down(struct scanner * s)414 hopper_down (struct scanner * s)
415 {
416   struct cmd c = {
417     {0}, 10,
418     NULL, 0,
419     CMD_NONE
420   };
421   c.cmd[0] = HOPPER_DOWN;
422   c.cmd[2] = 5;
423 
424   if (s->id == KV_S7075C)
425     return SANE_STATUS_GOOD;
426   return send_command (s, &c);
427 }
428 
429 SANE_Status
stop_adf(struct scanner * s)430 stop_adf (struct scanner * s)
431 {
432   struct cmd c = {
433     {0}, 10,
434     NULL, 0,
435     CMD_NONE
436   };
437   c.cmd[0] = STOP_ADF;
438   c.cmd[2] = 0x8b;
439   return send_command (s, &c);
440 }
441 
442 SANE_Status
kvs40xx_document_exist(struct scanner * s)443 kvs40xx_document_exist (struct scanner * s)
444 {
445   SANE_Status status;
446   struct cmd c = {
447     {0}, 10,
448     NULL, 6,
449     CMD_IN
450   };
451   u8 *d;
452   c.cmd[0] = READ_10;
453   c.cmd[2] = 0x81;
454   set24 (c.cmd + 6, c.data_size);
455   status = send_command (s, &c);
456   if (status)
457     return status;
458   d = c.data;
459   if (d[0] & 0x20)
460     return SANE_STATUS_GOOD;
461 
462   return SANE_STATUS_NO_DOCS;
463 }
464 
465 SANE_Status
kvs40xx_read_picture_element(struct scanner * s,unsigned side,SANE_Parameters * p)466 kvs40xx_read_picture_element (struct scanner * s, unsigned side,
467 			      SANE_Parameters * p)
468 {
469   SANE_Status status;
470   struct cmd c = {
471      {0}, 10,
472      NULL, 16,
473      CMD_IN
474   };
475   u32 *data;
476   c.cmd[0] = READ_10;
477   c.cmd[2] = 0x80;
478   c.cmd[5] = side;
479   set24 (c.cmd + 6, c.data_size);
480 
481   status = send_command (s, &c);
482   if (status)
483     return status;
484   data = (u32 *) c.data;
485   p->pixels_per_line = be2cpu32 (data[0]);
486   p->lines = be2cpu32 (data[1]);
487 
488   return SANE_STATUS_GOOD;
489 }
490 
491 SANE_Status
get_buffer_status(struct scanner * s,unsigned * data_avalible)492 get_buffer_status (struct scanner * s, unsigned *data_avalible)
493 {
494   SANE_Status status;
495   struct cmd c = {
496     {0}, 10,
497     NULL, 12,
498     CMD_IN
499   };
500   c.cmd[0] = GET_BUFFER_STATUS;
501   c.cmd[7] = 12;
502 
503   status = send_command (s, &c);
504   if (status)
505     return status;
506   *data_avalible = get24 ((unsigned char *)c.data + 9);
507   return SANE_STATUS_GOOD;
508 }
509 
510 SANE_Status
kvs40xx_read_image_data(struct scanner * s,unsigned page,unsigned side,void * buf,unsigned max_size,unsigned * size)511 kvs40xx_read_image_data (struct scanner * s, unsigned page, unsigned side,
512 			 void *buf, unsigned max_size, unsigned *size)
513 {
514   SANE_Status status;
515   struct cmd c = {
516     {0}, 10,
517     NULL, 0,
518     CMD_IN
519   };
520   c.data_size = max_size < MAX_READ_DATA_SIZE ? max_size : MAX_READ_DATA_SIZE;
521   c.cmd[0] = READ_10;
522   c.cmd[4] = page;
523   c.cmd[5] = side;
524 
525   set24 (c.cmd + 6, c.data_size);
526   *size = 0;
527   status = send_command (s, &c);
528 
529   if (status && status != SANE_STATUS_EOF && status != INCORRECT_LENGTH)
530     return status;
531 
532   *size = c.data_size;
533   memcpy (buf, c.data, *size);
534   return status;
535 }
536 
537 SANE_Status
read_support_info(struct scanner * s,struct support_info * inf)538 read_support_info (struct scanner * s, struct support_info * inf)
539 {
540   SANE_Status st;
541   struct cmd c = {
542     {0}, 10,
543     NULL, sizeof (*inf),
544     CMD_IN
545   };
546 
547   c.cmd[0] = READ_10;
548   c.cmd[2] = SUPPORT_INFO;
549   set24 (c.cmd + 6, c.data_size);
550 
551   st = send_command (s, &c);
552   if (st)
553     return st;
554   memcpy (inf, c.data, sizeof (*inf));
555   return SANE_STATUS_GOOD;
556 }
557 
558 SANE_Status
inquiry(struct scanner * s,char * id)559 inquiry (struct scanner * s, char *id)
560 {
561   int i;
562   SANE_Status st;
563   struct cmd c = {
564     {0}, 5,
565     NULL, 0x60,
566     CMD_IN
567   };
568 
569   c.cmd[0] = INQUIRY;
570   c.cmd[4] = c.data_size;
571 
572   st = send_command (s, &c);
573   if (st)
574     return st;
575   memcpy (id, (unsigned char *)c.data + 16, 16);
576   for (i = 0; i < 15 && id[i] != ' '; i++);
577   id[i] = 0;
578   return SANE_STATUS_GOOD;
579 }
580