• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    Copyright (C) 2008, Panasonic Russia Ltd.
3 */
4 /* sane - Scanner Access Now Easy.
5    Panasonic KV-S1020C / KV-S1025C USB scanners.
6 */
7 
8 #define DEBUG_DECLARE_ONLY
9 
10 #include "../include/sane/config.h"
11 
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <limits.h>
15 #include <signal.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <unistd.h>
22 #include <sys/ioctl.h>
23 
24 #include "../include/sane/sane.h"
25 #include "../include/sane/saneopts.h"
26 #include "../include/sane/sanei.h"
27 #include "../include/sane/sanei_usb.h"
28 #include "../include/sane/sanei_backend.h"
29 #include "../include/sane/sanei_config.h"
30 #include "../include/lassert.h"
31 
32 #include "kvs1025.h"
33 #include "kvs1025_low.h"
34 #include "kvs1025_usb.h"
35 #include "kvs1025_cmds.h"
36 
37 #include "../include/sane/sanei_debug.h"
38 
39 extern PKV_DEV g_devices;	/* Chain of devices */
40 extern const SANE_Device **g_devlist;
41 
42 /* static functions */
43 
44 /* Attach USB scanner */
45 static SANE_Status
attach_scanner_usb(const char * device_name)46 attach_scanner_usb (const char *device_name)
47 {
48   PKV_DEV dev;
49   SANE_Word vendor, product;
50 
51   DBG (DBG_error, "attaching USB scanner %s\n", device_name);
52 
53   sanei_usb_get_vendor_product_byname(device_name,&vendor,&product);
54 
55   dev = (PKV_DEV) malloc (sizeof (KV_DEV));
56 
57   if (dev == NULL)
58     return SANE_STATUS_NO_MEM;
59 
60   memset (dev, 0, sizeof (KV_DEV));
61 
62   dev->bus_mode = KV_USB_BUS;
63   dev->usb_fd = -1;
64   dev->scsi_fd = -1;
65   strcpy (dev->device_name, device_name);
66 
67   dev->buffer0 = (unsigned char *) malloc (SCSI_BUFFER_SIZE + 12);
68   dev->buffer = dev->buffer0 + 12;
69 
70   if (dev->buffer0 == NULL)
71     {
72       free (dev);
73       return SANE_STATUS_NO_MEM;
74     }
75 
76   dev->scsi_type = 6;
77   strcpy (dev->scsi_type_str, "ADF Scanner");
78   strcpy (dev->scsi_vendor, "Panasonic");
79   strcpy (dev->scsi_product,
80     product == (int) KV_S1020C ? "KV-S1020C" :
81     product == (int) KV_S1025C ? "KV-S1025C" :
82     product == (int) KV_S1045C ? "KV-S1045C" :
83     "KV-S10xxC");
84   strcpy (dev->scsi_version, "1.00");
85 
86   /* Set SANE_Device */
87   dev->sane.name = dev->device_name;
88   dev->sane.vendor = dev->scsi_vendor;
89   dev->sane.model = dev->scsi_product;
90   dev->sane.type = dev->scsi_type_str;
91 
92   /* Add into g_devices chain */
93   dev->next = g_devices;
94   g_devices = dev;
95 
96   return SANE_STATUS_GOOD;
97 }
98 
99 /* Get all supported scanners, and store into g_devlist */
100 SANE_Status
kv_usb_enum_devices(void)101 kv_usb_enum_devices (void)
102 {
103   int cnt = 0;
104   int i;
105   PKV_DEV pd;
106   char usb_str[18];
107 
108   DBG (DBG_proc, "kv_usb_enum_devices: enter\n");
109 
110   sanei_usb_init();
111 
112   sprintf(usb_str,"usb %#04x %#04x",VENDOR_ID,KV_S1020C);
113   sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb);
114 
115   sprintf(usb_str,"usb %#04x %#04x",VENDOR_ID,KV_S1025C);
116   sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb);
117 
118   sprintf(usb_str,"usb %#04x %#04x",VENDOR_ID,KV_S1045C);
119   sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb);
120 
121   for (pd = g_devices; pd; pd=pd->next) {
122     cnt++;
123   }
124 
125   g_devlist =
126     (const SANE_Device **) malloc (sizeof (SANE_Device *) * (cnt + 1));
127   if (g_devlist == NULL)
128     {
129       DBG (DBG_proc,
130 	   "kv_usb_enum_devices: leave on error " " --out of memory\n");
131       return SANE_STATUS_NO_MEM;
132     }
133 
134   pd = g_devices;
135   for (i = 0; i < cnt; i++)
136     {
137       g_devlist[i] = (const SANE_Device *) &pd->sane;
138       pd = pd->next;
139     }
140   g_devlist[cnt] = 0;
141 
142   DBG (DBG_proc, "kv_usb_enum_devices: leave with %d devices.\n", cnt);
143 
144   return SANE_STATUS_GOOD;
145 }
146 
147 /* Check if device is already open */
148 SANE_Bool
kv_usb_already_open(PKV_DEV dev)149 kv_usb_already_open (PKV_DEV dev)
150 {
151   return (dev->usb_fd > -1);
152 }
153 
154 /* Open an USB device */
155 SANE_Status
kv_usb_open(PKV_DEV dev)156 kv_usb_open (PKV_DEV dev)
157 {
158   SANE_Status ret;
159 
160   DBG (DBG_proc, "kv_usb_open: enter\n");
161   if (kv_usb_already_open(dev))
162     {
163       DBG (DBG_proc, "kv_usb_open: leave -- already open\n");
164       return SANE_STATUS_GOOD;
165     }
166 
167   ret = sanei_usb_open (dev->device_name, &(dev->usb_fd));
168   if (ret)
169     {
170       DBG (DBG_error, "kv_usb_open: leave -- cannot open device\n");
171       return SANE_STATUS_IO_ERROR;
172     }
173 
174   sanei_usb_clear_halt (dev->usb_fd);
175 
176   DBG (DBG_proc, "kv_usb_open: leave\n");
177   return SANE_STATUS_GOOD;
178 }
179 
180 /* Close an USB device */
181 void
kv_usb_close(PKV_DEV dev)182 kv_usb_close (PKV_DEV dev)
183 {
184   DBG (DBG_proc, "kv_usb_close: enter\n");
185   if (kv_usb_already_open(dev))
186     {
187       sanei_usb_close(dev->usb_fd);
188       dev->usb_fd = -1;
189     }
190   DBG (DBG_proc, "kv_usb_close: leave\n");
191 }
192 
193 /* Clean up the USB bus and release all resources allocated to devices */
194 void
kv_usb_cleanup(void)195 kv_usb_cleanup (void)
196 {
197 }
198 
199 /* Send command via USB, and get response data */
200 SANE_Status
kv_usb_escape(PKV_DEV dev,PKV_CMD_HEADER header,unsigned char * status_byte)201 kv_usb_escape (PKV_DEV dev,
202 	       PKV_CMD_HEADER header, unsigned char *status_byte)
203 {
204   int got_response = 0;
205   size_t len;
206   unsigned char cmd_buff[24];
207   memset (cmd_buff, 0, 24);
208   cmd_buff[3] = 0x18;		/* container length */
209   cmd_buff[5] = 1;		/* container type: command block */
210   cmd_buff[6] = 0x90;		/* code */
211 
212   if (!kv_usb_already_open(dev))
213     {
214       DBG (DBG_error, "kv_usb_escape: error, device not open.\n");
215       return SANE_STATUS_IO_ERROR;
216     }
217   memcpy (cmd_buff + 12, header->cdb, header->cdb_size);
218 
219   /* change timeout */
220   sanei_usb_set_timeout(KV_CMD_TIMEOUT);
221 
222   /* Send command */
223   len = 24;
224   if (sanei_usb_write_bulk (dev->usb_fd, (SANE_Byte *) cmd_buff, &len))
225     {
226       DBG (DBG_error, "usb_bulk_write: Error writing command.\n");
227       hexdump (DBG_error, "cmd block", cmd_buff, 24);
228       return SANE_STATUS_IO_ERROR;
229     }
230 
231   /* Send / Read data */
232   if (header->direction == KV_CMD_IN)
233     {
234       size_t size = header->data_size + 12;
235       size_t size_read = size;
236       unsigned char *data = ((unsigned char *) header->data) - 12;
237       SANE_Status ret;
238 
239       ret  = sanei_usb_read_bulk (dev->usb_fd, (SANE_Byte *) data, &size_read);
240 
241       /*empty read is ok?*/
242       if (ret == SANE_STATUS_EOF){
243 	sanei_usb_clear_halt (dev->usb_fd);
244         ret = SANE_STATUS_GOOD;
245       }
246 
247       if (ret) {
248 	sanei_usb_clear_halt (dev->usb_fd);
249 	DBG (DBG_error, "usb_bulk_read: Error reading data.\n");
250 	return SANE_STATUS_IO_ERROR;
251       }
252 
253       if (size_read != size)
254 	{
255 	  DBG (DBG_shortread, "usb_bulk_read: Warning - short read\n");
256 	  DBG (DBG_shortread, "usb_bulk_read: bytes to read = %lu\n", (unsigned long)size);
257 	  DBG (DBG_shortread,
258 	       "usb_bulk_read: bytes actual read = %lu\n", (unsigned long)size_read);
259 	  /*hexdump (DBG_shortread, "data", data, size_read); */
260 	}
261     }
262 
263   if (header->direction == KV_CMD_OUT)
264     {
265       size_t size = header->data_size + 12;
266       size_t size_written = size;
267       unsigned char *data = ((unsigned char *) header->data) - 12;
268       SANE_Status ret;
269 
270       memset (data, 0, 12);
271       Ito32 (size, data);
272       data[5] = 0x02;		/* container type: data block */
273       data[6] = 0xb0;		/* code */
274 
275       ret = sanei_usb_write_bulk (dev->usb_fd, (SANE_Byte *) data, &size_written);
276 
277       /*empty write is ok?*/
278       if (ret == SANE_STATUS_EOF){
279 	sanei_usb_clear_halt (dev->usb_fd);
280         ret = SANE_STATUS_GOOD;
281       }
282 
283       if (ret) {
284 	sanei_usb_clear_halt (dev->usb_fd);
285 	DBG (DBG_error, "usb_bulk_write: Error writing data.\n");
286 	return SANE_STATUS_IO_ERROR;
287       }
288 
289       if (size_written != size)
290 	{
291 	  DBG (DBG_shortread, "usb_bulk_write: Warning - short written\n");
292 	  DBG (DBG_shortread, "usb_bulk_write: bytes to write = %lu\n", (unsigned long)size);
293 	  DBG (DBG_shortread,
294 	       "usb_bulk_write: bytes actual written = %lu\n", (unsigned long)size_written);
295 	  hexdump (DBG_shortread, "data", data, size_written);
296 	}
297     }
298 
299   /* Get response */
300   if (!got_response)
301     {
302       SANE_Status ret;
303       size_t len = 16;
304 
305       ret = sanei_usb_read_bulk (dev->usb_fd, (SANE_Byte *) cmd_buff, &len);
306 
307       if (ret || len != 16)
308 	{
309 	  DBG (DBG_error, "usb_bulk_read: Error reading response."
310 	       " read %lu bytes\n", (unsigned long)len);
311 	  sanei_usb_clear_halt (dev->usb_fd);
312 	  return SANE_STATUS_IO_ERROR;
313 	}
314     }
315 
316   if (cmd_buff[5] != 3)
317     {
318       DBG (DBG_error, "usb_bulk_read: Invalid response block.\n");
319       hexdump (DBG_error, "response", cmd_buff, 16);
320       return SANE_STATUS_IO_ERROR;
321     }
322 
323   *status_byte = cmd_buff[15] & 0x3E;
324 
325   return SANE_STATUS_GOOD;
326 }
327 
328 /* Send command via USB, and request sense on CHECK CONDITION status */
329 SANE_Status
kv_usb_send_command(PKV_DEV dev,PKV_CMD_HEADER header,PKV_CMD_RESPONSE response)330 kv_usb_send_command (PKV_DEV dev,
331 		     PKV_CMD_HEADER header, PKV_CMD_RESPONSE response)
332 {
333   unsigned char status = 0;
334   SANE_Status s;
335   memset (response, 0, sizeof (KV_CMD_RESPONSE));
336   response->status = KV_FAILED;
337 
338   s = kv_usb_escape (dev, header, &status);
339 
340   if (s)
341     {
342       status = 0x02;
343     }
344 
345   if (status == 0x02)
346     {				/* check condition */
347       /* request sense */
348       KV_CMD_HEADER hdr;
349       memset (&hdr, 0, sizeof (hdr));
350       hdr.direction = KV_CMD_IN;
351       hdr.cdb[0] = SCSI_REQUEST_SENSE;
352       hdr.cdb[4] = 0x12;
353       hdr.cdb_size = 6;
354       hdr.data_size = 0x12;
355       hdr.data = &response->sense;
356 
357       if (kv_usb_escape (dev, &hdr, &status) != 0)
358 	return SANE_STATUS_IO_ERROR;
359 
360       hexdump (DBG_error, "sense data", (unsigned char *) &response->sense,
361 	       0x12);
362 
363       response->status = KV_CHK_CONDITION;
364     }
365   else
366     {
367       response->status = KV_SUCCESS;
368     }
369   return SANE_STATUS_GOOD;
370 }
371