19
19
* read_thread() - Thread to read the backchannel data on.
20
20
* sidechannel_thread() - Handle side-channel requests.
21
21
* soft_reset() - Send a soft reset to the device.
24
24
struct libusb_device *device; /* Device info */
25
25
int conf, /* Configuration */
32
32
protocol, /* Protocol: 1 = Uni-di, 2 = Bi-di. */
33
33
- usblp_attached; /* Is the "usblp" kernel module
35
+ usblp_attached; /* "usblp" kernel module attached? */
35
+ usblp_attached, /* "usblp" kernel module attached? */
36
+ opened_for_job; /* Set to 1 by print_device() */
36
37
+ unsigned int quirks; /* Quirks flags */
37
38
struct libusb_device_handle *handle; /* Open handle to device */
41
42
int sidechannel_thread_done;
97
98
static int open_device(usb_printer_t *printer, int verbose);
98
99
static int print_cb(usb_printer_t *printer, const char *device_uri,
99
100
const char *device_id, const void *data);
102
103
static void *read_thread(void *reference);
103
104
static void *sidechannel_thread(void *reference);
104
105
static void soft_reset(void);
106
107
iostatus; /* Current IO status */
107
108
pthread_t read_thread_id, /* Read thread */
108
109
sidechannel_thread_id; /* Side-channel thread */
112
113
struct stat sidechannel_info; /* Side-channel file descriptor info */
113
114
unsigned char print_buffer[8192], /* Print data buffer */
114
115
*print_ptr; /* Pointer into print data buffer */
116
117
struct timeval *timeout, /* Timeout pointer */
117
118
tv; /* Time value */
118
119
struct timespec cond_timeout; /* pthread condition timeout */
130
131
while ((g.printer = find_device(print_cb, uri)) == NULL)
132
133
_cupsLangPrintFilter(stderr, "INFO",
133
@@ -240,26 +300,63 @@
137
g.print_fd = print_fd;
138
+ g.printer->opened_for_job = 1;
141
* If we are printing data from a print driver on stdin, ignore SIGTERM
142
@@ -240,24 +302,61 @@
137
146
- * Get the read thread going...
138
147
+ * Debug mode: If option "usb-unidir" is given, always deactivate
142
- g.read_thread_stop = 0;
143
- g.read_thread_done = 0;
144
151
+ num_opts = cupsParseOptions(argv[5], 0, &opts);
145
152
+ val = cupsGetOption("usb-unidir", num_opts, opts);
146
153
+ if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
150
157
+ fprintf(stderr, "DEBUG: Forced uni-directional communication "
151
158
+ "via \"usb-unidir\" option.\n");
162
+ * Debug mode: If option "usb-no-reattach" is given, do not re-attach
163
+ * the usblp kernel module after the job has completed.
166
- g.read_thread_stop = 0;
167
- g.read_thread_done = 0;
168
+ val = cupsGetOption("usb-no-reattach", num_opts, opts);
169
+ if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
170
+ strcasecmp(val, "false"))
172
+ g.printer->usblp_attached = 0;
173
+ fprintf(stderr, "DEBUG: Forced not re-attaching the usblp kernel module "
174
+ "after the job via \"usb-no-reattach\" option.\n");
154
177
- pthread_cond_init(&g.read_thread_cond, NULL);
155
178
- pthread_mutex_init(&g.read_thread_mutex, NULL);
157
+ * Debug mode: If option "usb-no-reattach" is given, do not re-attach
158
+ * the usblp kernel module after the job has completed.
180
+ * Get the read thread going...
161
183
- if (pthread_create(&read_thread_id, NULL, read_thread, NULL))
162
+ val = cupsGetOption("usb-no-reattach", num_opts, opts);
163
+ if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
164
+ strcasecmp(val, "false"))
184
+ if (g.printer->read_endp != -1)
166
186
- fprintf(stderr, "DEBUG: Fatal USB error.\n");
167
187
- _cupsLangPrintFilter(stderr, "ERROR",
169
189
- fputs("DEBUG: Couldn't create read thread.\n", stderr);
170
190
- close_device(g.printer);
171
191
- return (CUPS_BACKEND_STOP);
172
+ g.printer->usblp_attached = 0;
173
+ fprintf(stderr, "DEBUG: Forced not re-attaching the usblp kernel module "
174
+ "after the job via \"usb-no-reattach\" option.\n");
178
+ * Get the read thread going...
181
+ if (g.printer->read_endp != -1)
183
192
+ have_backchannel = 1;
185
194
+ g.read_thread_stop = 0;
197
206
+ close_device(g.printer);
198
207
+ return (CUPS_BACKEND_STOP);
202
211
+ fprintf(stderr, "DEBUG: Uni-directional device/mode, back channel "
203
212
+ "deactivated.\n");
206
215
* The main thread sends the print file...
209
@@ -515,50 +612,54 @@
216
@@ -515,50 +614,54 @@
210
217
* Signal the read thread to exit then wait 7 seconds for it to complete...
223
230
- gettimeofday(&tv, NULL);
224
231
- cond_timeout.tv_sec = tv.tv_sec + WAIT_EOF_DELAY;
225
232
- cond_timeout.tv_nsec = tv.tv_usec * 1000;
226
+ pthread_mutex_lock(&g.read_thread_mutex);
228
234
- while (!g.read_thread_done)
230
236
- if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex,
231
237
- &cond_timeout) != 0)
240
+ pthread_mutex_lock(&g.read_thread_mutex);
236
243
- * If it didn't exit abort the pending read and wait an additional second...
353
360
errcode = libusb_get_device_descriptor (printer->device, &devdesc);
356
363
"DEBUG: Failed to re-attach \"usblp\" kernel module to "
357
364
"%04x:%04x\n", devdesc.idVendor, devdesc.idProduct);
360
- libusb_free_config_descriptor(confptr);
363
368
+ fprintf(stderr,
364
369
+ "DEBUG: Failed to get configuration descriptor %d\n",
365
370
+ printer->conf);
372
- libusb_free_config_descriptor(confptr);
374
+ * Reset the device to clean up after the job
377
+ if (printer->opened_for_job == 1)
379
+ if ((errcode = libusb_reset_device(printer->handle)) < 0)
381
+ "DEBUG: Device reset failed, error code: %d\n",
385
+ "DEBUG: Resetting printer.\n");
368
* Close the interface and return...
369
@@ -702,16 +835,18 @@
389
@@ -702,16 +852,18 @@
466
486
return (&printer);
470
490
if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
471
491
if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
472
492
if ((sern = cupsGetOption("SN", num_values, values)) == NULL &&
498
519
fprintf(stderr, "DEBUG: Failed to get device descriptor, code: %d\n",
500
@@ -1151,6 +1323,8 @@
521
@@ -1151,6 +1341,8 @@
501
522
0, 0, (unsigned char *)¤t, 1, 5000) < 0)
502
523
current = 0; /* Assume not configured */