From 0625c396663f9ac9697ae4aa036be0d879e05aa6 Mon Sep 17 00:00:00 2001 From: Lenar Shakirov Date: Wed, 3 Dec 2025 18:17:09 +0300 Subject: [PATCH 1/4] new usb quirk: no-alt-set - won't even try set_conf or set_int_alt_set new usb quirk: no-alt-set - won't even try libusb_set_configuration or libusb_set_interface_alt_setting I noticed that sometimes garbage is printed with my Samsung ProXpress M3870FD, this happens most often if the printer has gone to sleep (after 1 min by default). So if I print something 10 times, I get garbage 3-4 times. After month of investigating I found that Samsung devices don't like libusb_set_configuration or libusb_set_interface_alt_setting. My device: 04e8:3460 Samsung Electronics Co., Ltd M337x 387x 407x Series https://blog.stuffedcow.net/2011/10/samsung-linux-cups-usb-printing/ apple/cups#3965 OpenPrinting/system-config-printer#408 https://github.com/OpenPrinting/cups/blob/master/backend/usb-libusb.c (search by "Samsung") --- backend/usb-libusb.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/backend/usb-libusb.c b/backend/usb-libusb.c index 21a4ac89c..411321048 100644 --- a/backend/usb-libusb.c +++ b/backend/usb-libusb.c @@ -97,6 +97,9 @@ typedef struct usb_globals_s /* Global USB printer information */ #define USB_QUIRK_VENDOR_CLASS 0x0020 /* Descriptor uses vendor-specific Class or SubClass */ #define USB_QUIRK_DELAY_CLOSE 0x0040 /* Delay close */ +#define USB_QUIRK_NO_ALT_SET 0x0080 /* Some USB printers do not */ + like set_configuration and + set_interface */ #define USB_QUIRK_WHITELIST 0x0000 /* no quirks */ @@ -692,7 +695,10 @@ close_device(usb_printer_t *printer) /* I - Printer */ * If we have changed the configuration from one valid configuration * to another, restore the old one */ - if (printer->origconf > 0 && printer->origconf != number2) + if (printer->quirks & USB_QUIRK_NO_ALT_SET) + fprintf(stderr, "DEBUG: close_device - Skipping libusb_set_configuration\n"); + + if (printer->origconf > 0 && printer->origconf != number2 && !(printer->quirks & USB_QUIRK_NO_ALT_SET)) { fprintf(stderr, "DEBUG: Restoring USB device configuration: %d -> %d\n", number2, printer->origconf); @@ -1339,6 +1345,9 @@ load_quirks(void) if (strstr(line, " vendor-class")) quirk->quirks |= USB_QUIRK_VENDOR_CLASS; + if (strstr(line, " no-alt-set")) + quirk->quirks |= USB_QUIRK_NO_ALT_SET; + cupsArrayAdd(all_quirks, quirk); } @@ -1597,7 +1606,10 @@ open_device(usb_printer_t *printer, /* I - Printer */ } number1 = confptr->bConfigurationValue; - if (number1 != current) + if (printer->quirks & USB_QUIRK_NO_ALT_SET) + fprintf(stderr, "DEBUG: open_device - Skipping libusb_set_configuration\n"); + + if (number1 != current && !(printer->quirks & USB_QUIRK_NO_ALT_SET)) { fprintf(stderr, "DEBUG: Switching USB device configuration: %d -> %d\n", current, number1); @@ -1649,7 +1661,10 @@ open_device(usb_printer_t *printer, /* I - Printer */ * printers (e.g., Samsung) don't like usb_set_altinterface. */ - if (confptr->interface[printer->iface].num_altsetting > 1) + if (printer->quirks & USB_QUIRK_NO_ALT_SET) + fprintf(stderr, "DEBUG: open_device - Skipping libusb_set_interface_alt_setting\n"); + + if (confptr->interface[printer->iface].num_altsetting > 1 && !(printer->quirks & USB_QUIRK_NO_ALT_SET)) { number1 = confptr->interface[printer->iface]. altsetting[printer->altset].bInterfaceNumber; From 9871557172bcc4481e59a75a7d56aa668229296d Mon Sep 17 00:00:00 2001 From: Lenar Shakirov Date: Wed, 3 Dec 2025 18:21:12 +0300 Subject: [PATCH 2/4] usb-quirks: enable no-alt-set for Samsung M337x 387x 407x Series 04e8:3460 Samsung Electronics Co., Ltd M337x 387x 407x Series This model print garbage after libusb_set_configuration or libusb_set_interface_alt_setting, especially when the printer has gone into sleep mode. --- backend/org.cups.usb-quirks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/org.cups.usb-quirks b/backend/org.cups.usb-quirks index db57a5991..bb96870aa 100644 --- a/backend/org.cups.usb-quirks +++ b/backend/org.cups.usb-quirks @@ -208,7 +208,7 @@ 0x04e8 0x344f whitelist # Samsung M337x 387x 407x Series works without quirks -0x04e8 0x3460 whitelist +0x04e8 0x3460 whitelist no-alt-set # Samsung ML-2160 Series (https://bugzilla.redhat.com/show_bug.cgi?id=873123) 0x04e8 0x330f unidir From d0038ef10d31f1285cc5f810f4c2123e91c6575a Mon Sep 17 00:00:00 2001 From: Lenar Shakirov Date: Fri, 5 Dec 2025 14:26:12 +0300 Subject: [PATCH 3/4] No need extra debug printfs when NO_ALT_SET enabled --- backend/usb-libusb.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/backend/usb-libusb.c b/backend/usb-libusb.c index 411321048..ecc879f4f 100644 --- a/backend/usb-libusb.c +++ b/backend/usb-libusb.c @@ -695,8 +695,6 @@ close_device(usb_printer_t *printer) /* I - Printer */ * If we have changed the configuration from one valid configuration * to another, restore the old one */ - if (printer->quirks & USB_QUIRK_NO_ALT_SET) - fprintf(stderr, "DEBUG: close_device - Skipping libusb_set_configuration\n"); if (printer->origconf > 0 && printer->origconf != number2 && !(printer->quirks & USB_QUIRK_NO_ALT_SET)) { @@ -1606,9 +1604,6 @@ open_device(usb_printer_t *printer, /* I - Printer */ } number1 = confptr->bConfigurationValue; - if (printer->quirks & USB_QUIRK_NO_ALT_SET) - fprintf(stderr, "DEBUG: open_device - Skipping libusb_set_configuration\n"); - if (number1 != current && !(printer->quirks & USB_QUIRK_NO_ALT_SET)) { fprintf(stderr, "DEBUG: Switching USB device configuration: %d -> %d\n", @@ -1661,9 +1656,6 @@ open_device(usb_printer_t *printer, /* I - Printer */ * printers (e.g., Samsung) don't like usb_set_altinterface. */ - if (printer->quirks & USB_QUIRK_NO_ALT_SET) - fprintf(stderr, "DEBUG: open_device - Skipping libusb_set_interface_alt_setting\n"); - if (confptr->interface[printer->iface].num_altsetting > 1 && !(printer->quirks & USB_QUIRK_NO_ALT_SET)) { number1 = confptr->interface[printer->iface]. From 84289eaf0b1fc2f3bbf74d0adcdcc25e9c632692 Mon Sep 17 00:00:00 2001 From: Lenar Shakirov Date: Fri, 5 Dec 2025 18:34:43 +0300 Subject: [PATCH 4/4] Fixed an annoying typo in the comments --- backend/usb-libusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/usb-libusb.c b/backend/usb-libusb.c index ecc879f4f..181ba6cb0 100644 --- a/backend/usb-libusb.c +++ b/backend/usb-libusb.c @@ -97,7 +97,7 @@ typedef struct usb_globals_s /* Global USB printer information */ #define USB_QUIRK_VENDOR_CLASS 0x0020 /* Descriptor uses vendor-specific Class or SubClass */ #define USB_QUIRK_DELAY_CLOSE 0x0040 /* Delay close */ -#define USB_QUIRK_NO_ALT_SET 0x0080 /* Some USB printers do not */ +#define USB_QUIRK_NO_ALT_SET 0x0080 /* Some USB printers do not like set_configuration and set_interface */ #define USB_QUIRK_WHITELIST 0x0000 /* no quirks */