From: Lenar Shakirov Date: Wed, 3 Dec 2025 15:17:09 +0000 (+0300) Subject: new usb quirk: no-alt-set - won't even try set_conf or set_int_alt_set X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0625c396663f9ac9697ae4aa036be0d879e05aa6;p=thirdparty%2Fcups.git 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") --- diff --git a/backend/usb-libusb.c b/backend/usb-libusb.c index 21a4ac89cc..4113210489 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;