diff --git a/ChangeLog b/ChangeLog index 0f611e89a..e25b4945d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-25 m. allan noah + * backend/kvs1025*: convert backend from libusb to sanei_usb + * doc/descriptions/kvs1025.desc, doc/sane-kvs1025.man: update docs + * backend/dll.conf.in, configure, configure.in: enable kvs1025 backend + 2010-03-16 Stéphane Voltz * backend/rts8891.c: change register 0x11 settings for sensor type 1 diff --git a/backend/dll.conf.in b/backend/dll.conf.in index 71bf68850..b91462409 100644 --- a/backend/dll.conf.in +++ b/backend/dll.conf.in @@ -39,6 +39,7 @@ hpljm1005 hs2p ibm kodak +kvs1025 leo lexmark ma1509 diff --git a/backend/kvs1025.c b/backend/kvs1025.c index db02b4875..bd1809e86 100644 --- a/backend/kvs1025.c +++ b/backend/kvs1025.c @@ -1,5 +1,6 @@ /* Copyright (C) 2008, Panasonic Russia Ltd. + Copyright (C) 2010, m. allan noah */ /* sane - Scanner Access Now Easy. Panasonic KV-S1020C / KV-S1025C USB scanners. @@ -51,9 +52,8 @@ sane_init (SANE_Int * version_code, DBG (DBG_sane_init, "sane_init\n"); DBG (DBG_error, - "This is panasonic KV-S1020C / KV-S1025C SCSI version %d.%d build %d\n", + "This is panasonic KV-S1020C / KV-S1025C version %d.%d build %d\n", V_MAJOR, V_MINOR, V_BUILD); - DBG (DBG_error, "(C) 2007 by Tao Zhang\n"); if (version_code) { @@ -402,11 +402,15 @@ sane_cancel (SANE_Handle handle) SANE_Status sane_set_io_mode (SANE_Handle h, SANE_Bool m) { + h=h; + m=m; return SANE_STATUS_UNSUPPORTED; } SANE_Status sane_get_select_fd (SANE_Handle h, SANE_Int * fd) { + h=h; + fd=fd; return SANE_STATUS_UNSUPPORTED; } diff --git a/backend/kvs1025.h b/backend/kvs1025.h index 75bc7de9d..02ecbc9cf 100644 --- a/backend/kvs1025.h +++ b/backend/kvs1025.h @@ -16,7 +16,7 @@ #define BACKEND_NAME kvs1025 /* Build version */ -#define V_BUILD 1 +#define V_BUILD 2 /* Paper range supported -- MAX A4 */ #define KV_MAX_X_RANGE 210 @@ -92,7 +92,7 @@ SANE_I18N("Automatic separation") SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback /* __sane_unused__ authorize */ ); -void sane_exit (); +void sane_exit (void); SANE_Status sane_get_devices (const SANE_Device *** device_list, SANE_Bool /*__sane_unused__ local_only*/ ); diff --git a/backend/kvs1025_low.c b/backend/kvs1025_low.c index 79c7cf262..a67826948 100644 --- a/backend/kvs1025_low.c +++ b/backend/kvs1025_low.c @@ -225,13 +225,13 @@ kv_send_command (PKV_DEV dev, SANE_Status status = SANE_STATUS_UNSUPPORTED; if (dev->bus_mode == KV_USB_BUS) { - if (dev->usb_handle == NULL) + if (!kv_usb_already_open(dev)) { DBG (DBG_error, "kv_send_command error: device not open.\n"); return SANE_STATUS_IO_ERROR; } - status = kv_usb_send_command (dev->usb_handle, header, response); + status = kv_usb_send_command (dev, header, response); } return status; @@ -953,12 +953,12 @@ ReadImageData (PKV_DEV dev, int page) if (IS_DUPLEX (dev)) { - DBG (DBG_proc, "ReadImageData: Duplex\n", page); + DBG (DBG_proc, "ReadImageData: Duplex %d\n", page); status = ReadImageDataDuplex (dev, page); } else { - DBG (DBG_proc, "ReadImageData: Simplex\n", page); + DBG (DBG_proc, "ReadImageData: Simplex %d\n", page); status = ReadImageDataSimplex (dev, page); } dev->img_pt[0] = dev->img_buffers[0]; diff --git a/backend/kvs1025_low.h b/backend/kvs1025_low.h index 38edac23e..653c8e6bf 100644 --- a/backend/kvs1025_low.h +++ b/backend/kvs1025_low.h @@ -160,8 +160,8 @@ typedef struct kv_scanner_dev /* Bus info */ KV_BUS_MODE bus_mode; - struct usb_device *usb_fd; - usb_dev_handle *usb_handle; + SANE_Int usb_fd; + char device_name[100]; char *scsi_device_name; SCSI_FD scsi_fd; @@ -224,9 +224,9 @@ void kv_set_window_data (PKV_DEV dev, /* Prototypes in kvs1025_low.c */ -SANE_Status kv_enum_devices (); +SANE_Status kv_enum_devices (void); void kv_get_devices_list (const SANE_Device *** devices_list); -void kv_exit (); +void kv_exit (void); SANE_Status kv_open (PKV_DEV dev); SANE_Bool kv_already_open (PKV_DEV dev); SANE_Status kv_open_by_name (SANE_String_Const devicename, diff --git a/backend/kvs1025_opt.c b/backend/kvs1025_opt.c index e3ee5fb6a..06792b941 100644 --- a/backend/kvs1025_opt.c +++ b/backend/kvs1025_opt.c @@ -940,7 +940,7 @@ kv_control_option (PKV_DEV dev, SANE_Int option, case OPT_LAMP: strcpy (val, dev->val[option].s); - DBG (DBG_error, "opt value = %s\n", val); + DBG (DBG_error, "opt value = %s\n", (char *) val); return SANE_STATUS_GOOD; default: diff --git a/backend/kvs1025_usb.c b/backend/kvs1025_usb.c index ee2346a05..d4695925e 100644 --- a/backend/kvs1025_usb.c +++ b/backend/kvs1025_usb.c @@ -21,11 +21,6 @@ #include #include -#include -#undef DIRECT_USB_IO -#ifdef DIRECT_USB_IO -#include -#endif #include "../include/sane/sane.h" #include "../include/sane/saneopts.h" #include "../include/sane/sanei.h" @@ -44,18 +39,18 @@ extern PKV_DEV g_devices; /* Chain of devices */ extern const SANE_Device **g_devlist; -void usb_free_dev (struct usb_device *dev); /* Defined in libusb 0.1.12 */ -void usb_free_bus (struct usb_bus *bus); - /* static functions */ /* Attach USB scanner */ static SANE_Status -attach_scanner_usb (struct usb_device *usb_fd) +attach_scanner_usb (const char *device_name) { PKV_DEV dev; + SANE_Word vendor, product; - DBG (DBG_error, "attaching USB scanner %s\n", usb_fd->filename); + DBG (DBG_error, "attaching USB scanner %s\n", device_name); + + sanei_usb_get_vendor_product_byname(device_name,&vendor,&product); dev = (PKV_DEV) malloc (sizeof (KV_DEV)); @@ -65,8 +60,9 @@ attach_scanner_usb (struct usb_device *usb_fd) memset (dev, 0, sizeof (KV_DEV)); dev->bus_mode = KV_USB_BUS; - dev->usb_fd = usb_fd; + dev->usb_fd = -1; dev->scsi_fd = -1; + strcpy (dev->device_name, device_name); dev->buffer0 = (unsigned char *) malloc (SCSI_BUFFER_SIZE + 12); dev->buffer = dev->buffer0 + 12; @@ -80,12 +76,12 @@ attach_scanner_usb (struct usb_device *usb_fd) dev->scsi_type = 6; strcpy (dev->scsi_type_str, "ADF Scanner"); strcpy (dev->scsi_vendor, "Panasonic"); - strcpy (dev->scsi_product, usb_fd->descriptor.idProduct - == (int) KV_S1025C ? "KV-S1025C" : "KV-S1020C"); + strcpy (dev->scsi_product, + product == (int) KV_S1025C ? "KV-S1025C" : "KV-S1020C"); strcpy (dev->scsi_version, "1.00"); /* Set SANE_Device */ - dev->sane.name = dev->usb_fd->filename; + dev->sane.name = dev->device_name; dev->sane.vendor = dev->scsi_vendor; dev->sane.model = dev->scsi_product; dev->sane.type = dev->scsi_type_str; @@ -97,53 +93,28 @@ attach_scanner_usb (struct usb_device *usb_fd) return SANE_STATUS_GOOD; } -/* Get all supported scanners, and store into g_scanners_supported */ +/* Get all supported scanners, and store into g_devlist */ SANE_Status kv_usb_enum_devices () { - struct usb_bus *bus; - struct usb_device *dev; - SANE_Status status; int cnt = 0; int i; PKV_DEV pd; + char usb_str[18]; DBG (DBG_proc, "kv_usb_enum_devices: enter\n"); - /* Use libusb */ + sanei_usb_init(); - if (!usb_get_busses ()) - { - usb_find_busses (); - usb_find_devices (); - } + sprintf(usb_str,"usb %04x %04x",VENDOR_ID,KV_S1025C); + sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb); - for (bus = usb_get_busses (); bus; bus = bus->next) - { - for (dev = bus->devices; dev; dev = dev->next) - { - if (dev->config && dev->descriptor.idVendor == VENDOR_ID) - { - if (dev->descriptor.idProduct == - (int) KV_S1025C - || dev->descriptor.idProduct == (int) KV_S1020C) - { - status = attach_scanner_usb (dev); - if (status) - { - DBG (DBG_proc, - "kv_usb_enum_devices: leave on error " - " --out of memory\n"); - return status; - } - else - { - cnt++; - } - } - } - } - } + sprintf(usb_str,"usb %04x %04x",VENDOR_ID,KV_S1020C); + sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb); + + for (pd = g_devices; pd; pd=pd->next) { + cnt++; + } g_devlist = (const SANE_Device **) malloc (sizeof (SANE_Device *) * (cnt + 1)); @@ -153,6 +124,7 @@ kv_usb_enum_devices () "kv_usb_enum_devices: leave on error " " --out of memory\n"); return SANE_STATUS_NO_MEM; } + pd = g_devices; for (i = 0; i < cnt; i++) { @@ -170,38 +142,31 @@ kv_usb_enum_devices () SANE_Bool kv_usb_already_open (PKV_DEV dev) { - return (dev->usb_handle != NULL); + return (dev->usb_fd > -1); } /* Open an USB device */ SANE_Status kv_usb_open (PKV_DEV dev) { + SANE_Status ret; + DBG (DBG_proc, "kv_usb_open: enter\n"); - if (dev->usb_handle) + if (kv_usb_already_open(dev)) { DBG (DBG_proc, "kv_usb_open: leave -- already open\n"); return SANE_STATUS_GOOD; } - dev->usb_handle = usb_open (dev->usb_fd); - if (!dev->usb_handle) + ret = sanei_usb_open (dev->device_name, &(dev->usb_fd)); + if (ret) { DBG (DBG_error, "kv_usb_open: leave -- cannot open device\n"); return SANE_STATUS_IO_ERROR; } - /* Claim USB interface 0 */ - if (usb_claim_interface (dev->usb_handle, 0) != 0) - { - DBG (DBG_error, "kv_usb_open: leave -- " - "cannot claim interface '0', " "check permission please.\n"); - usb_close (dev->usb_handle); - dev->usb_handle = NULL; - return SANE_STATUS_ACCESS_DENIED; - } - usb_clear_halt (dev->usb_handle, (int) KV_CMD_IN); - usb_clear_halt (dev->usb_handle, (int) KV_CMD_OUT); + sanei_usb_clear_halt (dev->usb_fd); + DBG (DBG_proc, "kv_usb_open: leave\n"); return SANE_STATUS_GOOD; } @@ -211,11 +176,10 @@ void kv_usb_close (PKV_DEV dev) { DBG (DBG_proc, "kv_usb_close: enter\n"); - if (dev->usb_handle) + if (kv_usb_already_open(dev)) { - usb_release_interface (dev->usb_handle, 0); - usb_close (dev->usb_handle); - dev->usb_handle = NULL; + sanei_usb_close(dev->usb_fd); + dev->usb_fd = -1; } DBG (DBG_proc, "kv_usb_close: leave\n"); } @@ -224,48 +188,34 @@ kv_usb_close (PKV_DEV dev) void kv_usb_cleanup () { - struct usb_bus *bus, *old_bus; - struct usb_device *dev, *old_dev; - - bus = usb_get_busses (); - - while (bus) - { - dev = bus->devices; - while (dev) - { - old_dev = dev; - dev = dev->next; - usb_free_dev (old_dev); - } - old_bus = bus; - bus = bus->next; - usb_free_bus (old_bus); - } } /* Send command via USB, and get response data */ SANE_Status -kv_usb_escape (usb_dev_handle * usb_handle, +kv_usb_escape (PKV_DEV dev, PKV_CMD_HEADER header, unsigned char *status_byte) { int got_response = 0; + size_t len; unsigned char cmd_buff[24]; memset (cmd_buff, 0, 24); cmd_buff[3] = 0x18; /* container length */ cmd_buff[5] = 1; /* container type: command block */ cmd_buff[6] = 0x90; /* code */ - if (usb_handle == NULL) + if (!kv_usb_already_open(dev)) { DBG (DBG_error, "kv_usb_escape: error, device not open.\n"); return SANE_STATUS_IO_ERROR; } memcpy (cmd_buff + 12, header->cdb, header->cdb_size); + /* change timeout */ + sanei_usb_set_timeout(KV_CMD_TIMEOUT); + /* Send command */ - if (usb_bulk_write (usb_handle, (int) KV_CMD_OUT, (char *) cmd_buff, - 24, KV_CMD_TIMEOUT) != 24) + len = 24; + if (!sanei_usb_write_bulk (dev->usb_fd, (SANE_Byte *) cmd_buff, &len)) { DBG (DBG_error, "usb_bulk_write: Error writing command.\n"); hexdump (DBG_error, "cmd block", cmd_buff, 24); @@ -275,19 +225,24 @@ kv_usb_escape (usb_dev_handle * usb_handle, /* Send / Read data */ if (header->direction == KV_CMD_IN) { - int size_read; - int size = header->data_size + 12; + size_t size = header->data_size + 12; + size_t size_read = size; unsigned char *data = ((unsigned char *) header->data) - 12; - size_read = - usb_bulk_read (usb_handle, (int) KV_CMD_IN, - (char *) data, size, KV_CMD_TIMEOUT); - if (size_read <= 0) - { - usb_clear_halt (usb_handle, (int) KV_CMD_IN); - usb_clear_halt (usb_handle, (int) KV_CMD_OUT); - DBG (DBG_error, "usb_bulk_read: Error reading data.\n"); - return SANE_STATUS_IO_ERROR; - } + SANE_Status ret; + + ret = sanei_usb_read_bulk (dev->usb_fd, (SANE_Byte *) data, &size_read); + + /*empty read is ok?*/ + if (ret == SANE_STATUS_EOF){ + sanei_usb_clear_halt (dev->usb_fd); + ret = SANE_STATUS_GOOD; + } + + if (ret) { + sanei_usb_clear_halt (dev->usb_fd); + DBG (DBG_error, "usb_bulk_read: Error reading data.\n"); + return SANE_STATUS_IO_ERROR; + } if (size_read != size) { @@ -301,26 +256,29 @@ kv_usb_escape (usb_dev_handle * usb_handle, if (header->direction == KV_CMD_OUT) { - int size_written; - int size = header->data_size + 12; + size_t size = header->data_size + 12; + size_t size_written = size; unsigned char *data = ((unsigned char *) header->data) - 12; + SANE_Status ret; + memset (data, 0, 12); Ito32 (size, data); data[5] = 0x02; /* container type: data block */ data[6] = 0xb0; /* code */ - size_written = usb_bulk_write (usb_handle, (int) KV_CMD_OUT, - (char *) data, size, KV_CMD_TIMEOUT); - if (size_written <= 0) - { - usb_clear_halt (usb_handle, (int) KV_CMD_IN); - usb_clear_halt (usb_handle, (int) KV_CMD_OUT); - } - if (size_written < 0) - { - DBG (DBG_error, "usb_bulk_write: Error writing data.\n"); - return SANE_STATUS_IO_ERROR; - } + ret = sanei_usb_write_bulk (dev->usb_fd, (SANE_Byte *) data, &size_written); + + /*empty write is ok?*/ + if (ret == SANE_STATUS_EOF){ + sanei_usb_clear_halt (dev->usb_fd); + ret = SANE_STATUS_GOOD; + } + + if (ret) { + sanei_usb_clear_halt (dev->usb_fd); + DBG (DBG_error, "usb_bulk_write: Error writing data.\n"); + return SANE_STATUS_IO_ERROR; + } if (size_written != size) { @@ -335,14 +293,16 @@ kv_usb_escape (usb_dev_handle * usb_handle, /* Get response */ if (!got_response) { - int r; - if ((r = usb_bulk_read (usb_handle, (int) KV_CMD_IN, (char *) cmd_buff, - 16, KV_CMD_TIMEOUT)) != 16) + SANE_Status ret; + size_t len = 16; + + ret = sanei_usb_read_bulk (dev->usb_fd, (SANE_Byte *) cmd_buff, &len); + + if (ret || len != 16) { DBG (DBG_error, "usb_bulk_read: Error reading response." - " read %d bytes\n", r); - usb_clear_halt (usb_handle, (int) KV_CMD_IN); - usb_clear_halt (usb_handle, (int) KV_CMD_OUT); + " read %d bytes\n", len); + sanei_usb_clear_halt (dev->usb_fd); return SANE_STATUS_IO_ERROR; } } @@ -361,7 +321,7 @@ kv_usb_escape (usb_dev_handle * usb_handle, /* Send command via USB, and request sense on CHECK CONDITION status */ SANE_Status -kv_usb_send_command (usb_dev_handle * usb_handle, +kv_usb_send_command (PKV_DEV dev, PKV_CMD_HEADER header, PKV_CMD_RESPONSE response) { unsigned char status = 0; @@ -369,16 +329,13 @@ kv_usb_send_command (usb_dev_handle * usb_handle, memset (response, 0, sizeof (KV_CMD_RESPONSE)); response->status = KV_FAILED; - s = kv_usb_escape (usb_handle, header, &status); + s = kv_usb_escape (dev, header, &status); if (s) { -#ifndef DIRECT_USB_IO status = 0x02; -#else - return s; -#endif } + if (status == 0x02) { /* check condition */ /* request sense */ @@ -391,7 +348,7 @@ kv_usb_send_command (usb_dev_handle * usb_handle, hdr.data_size = 0x12; hdr.data = &response->sense; - if (kv_usb_escape (usb_handle, &hdr, &status) != 0) + if (kv_usb_escape (dev, &hdr, &status) != 0) return SANE_STATUS_IO_ERROR; hexdump (DBG_error, "sense data", (unsigned char *) &response->sense, diff --git a/backend/kvs1025_usb.h b/backend/kvs1025_usb.h index 0fff75a95..3d0dbe4ad 100644 --- a/backend/kvs1025_usb.h +++ b/backend/kvs1025_usb.h @@ -10,13 +10,13 @@ #include "kvs1025_cmds.h" -SANE_Status kv_usb_enum_devices (); +SANE_Status kv_usb_enum_devices (void); SANE_Status kv_usb_open (PKV_DEV dev); SANE_Bool kv_usb_already_open (PKV_DEV dev); void kv_usb_close (PKV_DEV dev); -void kv_usb_cleanup (); +void kv_usb_cleanup (void); -SANE_Status kv_usb_send_command (usb_dev_handle * usb_handle, +SANE_Status kv_usb_send_command (PKV_DEV dev, PKV_CMD_HEADER header, PKV_CMD_RESPONSE response); diff --git a/configure b/configure index 1f84a77d1..65f6b42e6 100755 --- a/configure +++ b/configure @@ -34196,14 +34196,14 @@ ALL_BACKENDS="abaton agfafocus apple artec artec_eplus48u as6e \ coolscan coolscan2 coolscan3 dc25 dc210 dc240 \ dell1600n_net dmc epjitsu epson epson2 fujitsu genesys \ gphoto2 gt68xx hp hp3500 hp3900 hp4200 hp5400 \ - hp5590 hpsj5s hpljm1005 hs2p ibm kodak leo lexmark ma1509 \ + hp5590 hpsj5s hpljm1005 hs2p ibm kodak kvs1025 \ + leo lexmark ma1509 \ matsushita microtek microtek2 mustek mustek_pp \ mustek_usb mustek_usb2 nec net niash pie pint \ pixma plustek plustek_pp qcam ricoh rts8891 s9036 \ sceptre sharp sm3600 sm3840 snapscan sp15c st400 \ stv680 tamarack teco1 teco2 teco3 test u12 umax umax_pp umax1220u v4l xerox_mfp p5" -# kvs1025 \ # If user specifies backends manually then cause configure # to fail if its detected it can't be compiled. If we diff --git a/configure.in b/configure.in index 78bde5ab5..66e6dab95 100644 --- a/configure.in +++ b/configure.in @@ -510,14 +510,14 @@ ALL_BACKENDS="abaton agfafocus apple artec artec_eplus48u as6e \ coolscan coolscan2 coolscan3 dc25 dc210 dc240 \ dell1600n_net dmc epjitsu epson epson2 fujitsu genesys \ gphoto2 gt68xx hp hp3500 hp3900 hp4200 hp5400 \ - hp5590 hpsj5s hpljm1005 hs2p ibm kodak leo lexmark ma1509 \ + hp5590 hpsj5s hpljm1005 hs2p ibm kodak kvs1025 \ + leo lexmark ma1509 \ matsushita microtek microtek2 mustek mustek_pp \ mustek_usb mustek_usb2 nec net niash pie pint \ pixma plustek plustek_pp qcam ricoh rts8891 s9036 \ sceptre sharp sm3600 sm3840 snapscan sp15c st400 \ stv680 tamarack teco1 teco2 teco3 test u12 umax umax_pp umax1220u v4l xerox_mfp p5" -# kvs1025 \ # If user specifies backends manually then cause configure # to fail if its detected it can't be compiled. If we diff --git a/doc/descriptions/kvs1025.desc b/doc/descriptions/kvs1025.desc index 5e52348cb..3ec4911b2 100644 --- a/doc/descriptions/kvs1025.desc +++ b/doc/descriptions/kvs1025.desc @@ -10,7 +10,7 @@ ; :backend "kvs1025" ; name of backend -:version "1" ; version of backend +:version "2" ; version of backend :manpage "sane-kvs1025" ; name of manpage (if it exists) :comment "New backend for SANE release 1.0.21, see sane-kvs1025 manpage" :devicetype :scanner ; start of a list of devices.... diff --git a/doc/sane-kvs1025.man b/doc/sane-kvs1025.man index d8658562c..e12d40ceb 100644 --- a/doc/sane-kvs1025.man +++ b/doc/sane-kvs1025.man @@ -1,4 +1,4 @@ -.TH sane\-kvs1025 5 "12 Feb 2010" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" +.TH sane\-kvs1025 5 "25 Mar 2010" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" .IX sane\-kvs1025 .SH NAME @@ -11,17 +11,15 @@ library implements a SANE (Scanner Access Now Easy) backend which provides access to the Panasonic KV-S1020C and KV-S1025C scanners. .SH KNOWN ISSUES -The backend uses libusb directly, instead of sanei_usb, so it will not -work on some platforms. - This document was written by the SANE project, which has no information regarding the capabilites or reliability of the backend. All information contained here is suspect. .SH CREDITS -The backend was written by Panasonic Russia Ltd. +The backend was written by Tao Zhang / Panasonic Russia Ltd. -The backend was ported to sane-backends 1.0.21 by m. allan noah. +The backend was ported to sane-backends 1.0.21 and updated to use +sanei_usb instead of libusb by m. allan noah. .SH "SEE ALSO" sane(7), sane\-usb(5)