From 0e8f9c935eb764b5f7095ff4d9cdc82a8a5811c1 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 9 Apr 2020 23:50:45 +0300 Subject: [PATCH 1/4] genesys: Correctly initialize test USB device --- backend/genesys/test_scanner_interface.cpp | 4 +++- backend/genesys/test_usb_device.h | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/genesys/test_scanner_interface.cpp b/backend/genesys/test_scanner_interface.cpp index d5dcaaa5a..dc01c395a 100644 --- a/backend/genesys/test_scanner_interface.cpp +++ b/backend/genesys/test_scanner_interface.cpp @@ -49,7 +49,9 @@ namespace genesys { -TestScannerInterface::TestScannerInterface(Genesys_Device* dev) : dev_{dev} +TestScannerInterface::TestScannerInterface(Genesys_Device* dev) : + dev_{dev}, + usb_dev_{get_testing_vendor_id(), get_testing_product_id(), get_testing_bcd_device()} { // initialize status registers if (dev_->model->asic_type == AsicType::GL124) { diff --git a/backend/genesys/test_usb_device.h b/backend/genesys/test_usb_device.h index b39464d34..4682792ff 100644 --- a/backend/genesys/test_usb_device.h +++ b/backend/genesys/test_usb_device.h @@ -51,8 +51,6 @@ namespace genesys { class TestUsbDevice : public IUsbDevice { public: TestUsbDevice(std::uint16_t vendor, std::uint16_t product, std::uint16_t bcd_device); - TestUsbDevice() = default; - ~TestUsbDevice() override; bool is_open() const override { return is_open_; } From 13dffa0915fb76ad730fb558e451589fc6c7194f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 9 Apr 2020 23:50:46 +0300 Subject: [PATCH 2/4] genesys: Defer evaluation of bcdDevice until open() --- backend/genesys/device.h | 4 +-- backend/genesys/genesys.cpp | 72 +++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/backend/genesys/device.h b/backend/genesys/device.h index fae0ab31f..2687bb405 100644 --- a/backend/genesys/device.h +++ b/backend/genesys/device.h @@ -265,8 +265,8 @@ struct Genesys_Device // frees commonly used data void clear(); - SANE_Word vendorId = 0; /**< USB vendor identifier */ - SANE_Word productId = 0; /**< USB product identifier */ + std::uint16_t vendorId = 0; // USB vendor identifier + std::uint16_t productId = 0; // USB product identifier // USB mode: // 0: not set diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index ab2f8d62c..41c106acd 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -4141,7 +4141,7 @@ static std::string calibration_filename(Genesys_Device *currdev) /* count models of the same names if several scanners attached */ if(s_devices->size() > 1) { for (const auto& dev : *s_devices) { - if (dev.model->model_id == currdev->model->model_id) { + if (dev.vendorId == currdev->vendorId && dev.productId == currdev->productId) { count++; } } @@ -4793,31 +4793,31 @@ check_present (SANE_String_Const devname) noexcept return SANE_STATUS_GOOD; } -static Genesys_Device* attach_usb_device(const char* devname, - std::uint16_t vendor_id, std::uint16_t product_id, - std::uint16_t bcd_device) +const UsbDeviceEntry& get_matching_usb_dev(std::uint16_t vendor_id, std::uint16_t product_id, + std::uint16_t bcd_device) { - UsbDeviceEntry* found_usb_dev = nullptr; for (auto& usb_dev : *s_usb_devices) { - if (usb_dev.matches(vendor_id, product_id, bcd_device)) - { - found_usb_dev = &usb_dev; - break; + if (usb_dev.matches(vendor_id, product_id, bcd_device)) { + return usb_dev; } } - if (found_usb_dev == nullptr) { - throw SaneException("vendor 0x%x product 0x%x is not supported by this backend", - vendor_id, product_id); - } + throw SaneException("vendor 0x%x product 0x%x is not supported by this backend", + vendor_id, product_id); +} + +static Genesys_Device* attach_usb_device(const char* devname, + std::uint16_t vendor_id, std::uint16_t product_id) +{ + // verify that there's at least one entry for this vendor and product ids. We will check + // bcdDevice in open(). + get_matching_usb_dev(vendor_id, product_id, UsbDeviceEntry::BCD_DEVICE_NOT_SET); s_devices->emplace_back(); Genesys_Device* dev = &s_devices->back(); dev->file_name = devname; - - dev->model = &found_usb_dev->model(); - dev->vendorId = found_usb_dev->vendor_id(); - dev->productId = found_usb_dev->product_id(); + dev->vendorId = vendor_id; + dev->productId = product_id; dev->usb_mode = 0; // i.e. unset dev->already_initialized = false; return dev; @@ -4847,8 +4847,6 @@ static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may int vendor, product; usb_dev.get_vendor_product(vendor, product); - - auto bcd_device = usb_dev.get_bcd_device(); usb_dev.close(); /* KV-SS080 is an auxiliary device which requires a master device to be here */ @@ -4863,10 +4861,10 @@ static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may } } - Genesys_Device* dev = attach_usb_device(devname, vendor, product, bcd_device); + Genesys_Device* dev = attach_usb_device(devname, vendor, product); - DBG(DBG_info, "%s: found %s flatbed scanner %s at %s\n", __func__, dev->model->vendor, - dev->model->model, dev->file_name.c_str()); + DBG(DBG_info, "%s: found %u flatbed scanner %u at %s\n", __func__, vendor, product, + dev->file_name.c_str()); return dev; } @@ -4901,8 +4899,7 @@ static void probe_genesys_devices() DBG_HELPER(dbg); if (is_testing_mode()) { attach_usb_device(get_testing_device_name().c_str(), - get_testing_vendor_id(), get_testing_product_id(), - get_testing_bcd_device()); + get_testing_vendor_id(), get_testing_product_id()); return; } @@ -5257,7 +5254,7 @@ static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle) } if (dev) { - DBG(DBG_info, "%s: found `%s' in devlist\n", __func__, dev->model->name); + DBG(DBG_info, "%s: found `%s' in devlist\n", __func__, dev->file_name.c_str()); } else if (is_testing_mode()) { DBG(DBG_info, "%s: couldn't find `%s' in devlist, not attaching", __func__, devicename); } else { @@ -5279,15 +5276,6 @@ static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle) throw SaneException("could not find the device to open: %s", devicename); } - if (has_flag(dev->model->flags, ModelFlag::UNTESTED)) { - DBG(DBG_error0, "WARNING: Your scanner is not fully supported or at least \n"); - DBG(DBG_error0, " had only limited testing. Please be careful and \n"); - DBG(DBG_error0, " report any failure/success to \n"); - DBG(DBG_error0, " sane-devel@alioth-lists.debian.net. Please provide as many\n"); - DBG(DBG_error0, " details as possible, e.g. the exact name of your\n"); - DBG(DBG_error0, " scanner and what does (not) work.\n"); - } - dbg.vstatus("open device '%s'", dev->file_name.c_str()); if (is_testing_mode()) { @@ -5300,6 +5288,22 @@ static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle) dev->interface->get_usb_device().open(dev->file_name.c_str()); dbg.clear(); + auto bcd_device = dev->interface->get_usb_device().get_bcd_device(); + const auto& usb_dev = get_matching_usb_dev(dev->vendorId, dev->productId, bcd_device); + + dev->model = &usb_dev.model(); + + dbg.vlog(DBG_info, "Opened device %s", dev->model->name); + + if (has_flag(dev->model->flags, ModelFlag::UNTESTED)) { + DBG(DBG_error0, "WARNING: Your scanner is not fully supported or at least \n"); + DBG(DBG_error0, " had only limited testing. Please be careful and \n"); + DBG(DBG_error0, " report any failure/success to \n"); + DBG(DBG_error0, " sane-devel@alioth-lists.debian.net. Please provide as many\n"); + DBG(DBG_error0, " details as possible, e.g. the exact name of your\n"); + DBG(DBG_error0, " scanner and what does (not) work.\n"); + } + s_scanners->push_back(Genesys_Scanner()); auto* s = &s_scanners->back(); From bb318cf8f31ea84540f80b32ef4558c35a494cf5 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 9 Apr 2020 23:50:47 +0300 Subject: [PATCH 3/4] genesys: Simplify USB id retrieval --- backend/genesys/genesys.cpp | 17 ++++++++--------- backend/genesys/test_usb_device.cpp | 12 +++++++++--- backend/genesys/test_usb_device.h | 3 ++- backend/genesys/usb_device.cpp | 15 ++++++++++++++- backend/genesys/usb_device.h | 6 ++++-- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 41c106acd..1629355e5 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -4845,25 +4845,24 @@ static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may usb_dev.open(devname); DBG(DBG_info, "%s: device `%s' successfully opened\n", __func__, devname); - int vendor, product; - usb_dev.get_vendor_product(vendor, product); + auto vendor_id = usb_dev.get_vendor_id(); + auto product_id = usb_dev.get_product_id(); usb_dev.close(); /* KV-SS080 is an auxiliary device which requires a master device to be here */ - if(vendor == 0x04da && product == 0x100f) - { + if (vendor_id == 0x04da && product_id == 0x100f) { present = false; - sanei_usb_find_devices (vendor, 0x1006, check_present); - sanei_usb_find_devices (vendor, 0x1007, check_present); - sanei_usb_find_devices (vendor, 0x1010, check_present); + sanei_usb_find_devices(vendor_id, 0x1006, check_present); + sanei_usb_find_devices(vendor_id, 0x1007, check_present); + sanei_usb_find_devices(vendor_id, 0x1010, check_present); if (present == false) { throw SaneException("master device not present"); } } - Genesys_Device* dev = attach_usb_device(devname, vendor, product); + Genesys_Device* dev = attach_usb_device(devname, vendor_id, product_id); - DBG(DBG_info, "%s: found %u flatbed scanner %u at %s\n", __func__, vendor, product, + DBG(DBG_info, "%s: found %u flatbed scanner %u at %s\n", __func__, vendor_id, product_id, dev->file_name.c_str()); return dev; diff --git a/backend/genesys/test_usb_device.cpp b/backend/genesys/test_usb_device.cpp index 19a1dc62f..1612eae6e 100644 --- a/backend/genesys/test_usb_device.cpp +++ b/backend/genesys/test_usb_device.cpp @@ -96,12 +96,18 @@ void TestUsbDevice::close() name_ = ""; } -void TestUsbDevice::get_vendor_product(int& vendor, int& product) +std::uint16_t TestUsbDevice::get_vendor_id() { DBG_HELPER(dbg); assert_is_open(); - vendor = vendor_; - product = product_; + return vendor_; +} + +std::uint16_t TestUsbDevice::get_product_id() +{ + DBG_HELPER(dbg); + assert_is_open(); + return product_; } std::uint16_t TestUsbDevice::get_bcd_device() diff --git a/backend/genesys/test_usb_device.h b/backend/genesys/test_usb_device.h index 4682792ff..03b49ccb7 100644 --- a/backend/genesys/test_usb_device.h +++ b/backend/genesys/test_usb_device.h @@ -63,7 +63,8 @@ public: void reset() override; void close() override; - void get_vendor_product(int& vendor, int& product) override; + std::uint16_t get_vendor_id() override; + std::uint16_t get_product_id() override; std::uint16_t get_bcd_device() override; void control_msg(int rtype, int reg, int value, int index, int length, diff --git a/backend/genesys/usb_device.cpp b/backend/genesys/usb_device.cpp index 05d6a7cb0..d6cbaed6a 100644 --- a/backend/genesys/usb_device.cpp +++ b/backend/genesys/usb_device.cpp @@ -101,11 +101,24 @@ void UsbDevice::close() sanei_usb_close(device_num); } -void UsbDevice::get_vendor_product(int& vendor, int& product) +std::uint16_t UsbDevice::get_vendor_id() { DBG_HELPER(dbg); assert_is_open(); + int vendor = 0; + int product = 0; TIE(sanei_usb_get_vendor_product(device_num_, &vendor, &product)); + return static_cast(vendor); +} + +std::uint16_t UsbDevice::get_product_id() +{ + DBG_HELPER(dbg); + assert_is_open(); + int vendor = 0; + int product = 0; + TIE(sanei_usb_get_vendor_product(device_num_, &vendor, &product)); + return static_cast(product); } std::uint16_t UsbDevice::get_bcd_device() diff --git a/backend/genesys/usb_device.h b/backend/genesys/usb_device.h index 9c9469bd5..aa8b89ab2 100644 --- a/backend/genesys/usb_device.h +++ b/backend/genesys/usb_device.h @@ -71,7 +71,8 @@ public: virtual void reset() = 0; virtual void close() = 0; - virtual void get_vendor_product(int& vendor, int& product) = 0; + virtual std::uint16_t get_vendor_id() = 0; + virtual std::uint16_t get_product_id() = 0; virtual std::uint16_t get_bcd_device() = 0; virtual void control_msg(int rtype, int reg, int value, int index, int length, @@ -97,7 +98,8 @@ public: void reset() override; void close() override; - void get_vendor_product(int& vendor, int& product) override; + std::uint16_t get_vendor_id() override; + std::uint16_t get_product_id() override; std::uint16_t get_bcd_device() override; void control_msg(int rtype, int reg, int value, int index, int length, From 0d1542cbe6f3c85693e3495f032f1887cbda6c8e Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 9 Apr 2020 23:50:48 +0300 Subject: [PATCH 4/4] genesys: Fix bcdDevice filtering --- backend/genesys/genesys.cpp | 5 +++-- backend/genesys/low.h | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 1629355e5..fc0eef828 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -4802,8 +4802,9 @@ const UsbDeviceEntry& get_matching_usb_dev(std::uint16_t vendor_id, std::uint16_ } } - throw SaneException("vendor 0x%x product 0x%x is not supported by this backend", - vendor_id, product_id); + throw SaneException("vendor 0x%x product 0x%x (bcdDevice 0x%x) " + "is not supported by this backend", + vendor_id, product_id, bcd_device); } static Genesys_Device* attach_usb_device(const char* devname, diff --git a/backend/genesys/low.h b/backend/genesys/low.h index 728c22fa1..e999fb2ae 100644 --- a/backend/genesys/low.h +++ b/backend/genesys/low.h @@ -196,8 +196,11 @@ public: return false; if (product_ != product_id) return false; - if (bcd_device_ != BCD_DEVICE_NOT_SET && bcd_device_ != bcd_device) + if (bcd_device_ != BCD_DEVICE_NOT_SET && bcd_device != BCD_DEVICE_NOT_SET && + bcd_device_ != bcd_device) + { return false; + } return true; }