Index: usb-libusb.c =================================================================== --- usb-libusb.c (revision 10087) +++ usb-libusb.c (working copy) @@ -631,6 +631,7 @@ int verbose) /* I - Update connecting-to-device state? */ { int number; /* Configuration/interface/altset numbers */ + char current_bConfiguration; /* @@ -647,27 +648,40 @@ if ((printer->handle = usb_open(printer->device)) == NULL) return (-1); - /* - * Then set the desired configuration... - */ if (verbose) fputs("STATE: +connecting-to-device\n", stderr); + /* + * Set the desired configuration, but only if it needs changing. Some + * printers (e.g., Samsung) don't like usb_set_configuration. It will succeed, + * but the following print job is sometimes silently lost by the printer. + */ + if (usb_control_msg(printer->handle, + USB_TYPE_STANDARD | USB_ENDPOINT_IN | USB_RECIP_DEVICE, + 8, /* GET_CONFIGURATION */ + 0, 0, ¤t_bConfiguration, 1, 5000) != 1) + { + current_bConfiguration = 0; /* Failed. Assume not configured */ + } + number = printer->device->config[printer->conf].bConfigurationValue; - - if (usb_set_configuration(printer->handle, number) < 0) + if (number != current_bConfiguration) { - /* - * If the set fails, chances are that the printer only supports a - * single configuration. Technically these printers don't conform to - * the USB printer specification, but otherwise they'll work... - */ - if (errno != EBUSY) - fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n", - number, printer->device->descriptor.idVendor, - printer->device->descriptor.idProduct); + if (usb_set_configuration(printer->handle, number) < 0) + { + /* + * If the set fails, chances are that the printer only supports a + * single configuration. Technically these printers don't conform to + * the USB printer specification, but otherwise they'll work... + */ + + if (errno != EBUSY) + fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n", + number, printer->device->descriptor.idVendor, + printer->device->descriptor.idProduct); + } } /* @@ -700,20 +714,24 @@ #endif /* 0 */ /* - * Set alternate setting... + * Set alternate setting, but only if there is more than one option. + * Some printers (e.g., Samsung) don't like usb_set_altinterface. */ - - number = printer->device->config[printer->conf].interface[printer->iface]. - altsetting[printer->altset].bAlternateSetting; - while (usb_set_altinterface(printer->handle, number) < 0) + if (printer->device->config[printer->conf].interface[printer->iface]. + num_altsetting > 1) { - if (errno != EBUSY) - fprintf(stderr, - "DEBUG: Failed to set alternate interface %d for %04x:%04x: %s\n", - number, printer->device->descriptor.idVendor, - printer->device->descriptor.idProduct, strerror(errno)); + number = printer->device->config[printer->conf].interface[printer->iface]. + altsetting[printer->altset].bAlternateSetting; + while (usb_set_altinterface(printer->handle, number) < 0) + { + if (errno != EBUSY) + fprintf(stderr, + "DEBUG: Failed to set alternate interface %d for %04x:%04x: %s\n", + number, printer->device->descriptor.idVendor, + printer->device->descriptor.idProduct, strerror(errno)); - goto error; + goto error; + } } if (verbose)