usblp.c 38.7 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/*
2
 * usblp.c
Linus Torvalds's avatar
Linus Torvalds committed
3
4
5
 *
 * Copyright (c) 1999 Michael Gee	<michael@linuxspecific.com>
 * Copyright (c) 1999 Pavel Machek	<pavel@suse.cz>
6
 * Copyright (c) 2000 Randy Dunlap	<rdunlap@xenotime.net>
Linus Torvalds's avatar
Linus Torvalds committed
7
8
9
 * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
 # Copyright (c) 2001 Pete Zaitcev	<zaitcev@redhat.com>
 # Copyright (c) 2001 David Paschal	<paschal@rcsis.com>
Oliver Neukum's avatar
Oliver Neukum committed
10
 * Copyright (c) 2006 Oliver Neukum	<oliver@neukum.name>
Linus Torvalds's avatar
Linus Torvalds committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *
 * USB Printer Device Class driver for USB printers and printer cables
 *
 * Sponsored by SuSE
 *
 * ChangeLog:
 *	v0.1 - thorough cleaning, URBification, almost a rewrite
 *	v0.2 - some more cleanups
 *	v0.3 - cleaner again, waitqueue fixes
 *	v0.4 - fixes in unidirectional mode
 *	v0.5 - add DEVICE_ID string support
 *	v0.6 - never time out
 *	v0.7 - fixed bulk-IN read and poll (David Paschal)
 *	v0.8 - add devfs support
 *	v0.9 - fix unplug-while-open paths
 *	v0.10- remove sleep_on, fix error on oom (oliver@neukum.org)
 *	v0.11 - add proto_bias option (Pete Zaitcev)
 *	v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
 *	v0.13 - alloc space for statusbuf (<status> not on stack);
 *		use usb_buffer_alloc() for read buf & write buf;
Pete Zaitcev's avatar
Pete Zaitcev committed
31
 *      none  - Maintained in Linux kernel after v0.13
Linus Torvalds's avatar
Linus Torvalds committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/lp.h>
58
#include <linux/mutex.h>
Linus Torvalds's avatar
Linus Torvalds committed
59
60
61
62
63
64
65
66
67
68
#undef DEBUG
#include <linux/usb.h>

/*
 * Version Information
 */
#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal"
#define DRIVER_DESC "USB Printer Device Class driver"

#define USBLP_BUF_SIZE		8192
69
#define USBLP_BUF_SIZE_IN	1024
Linus Torvalds's avatar
Linus Torvalds committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#define USBLP_DEVICE_ID_SIZE	1024

/* ioctls: */
#define IOCNR_GET_DEVICE_ID		1
#define IOCNR_GET_PROTOCOLS		2
#define IOCNR_SET_PROTOCOL		3
#define IOCNR_HP_SET_CHANNEL		4
#define IOCNR_GET_BUS_ADDRESS		5
#define IOCNR_GET_VID_PID		6
#define IOCNR_SOFT_RESET		7
/* Get device_id string: */
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
/* The following ioctls were added for http://hpoj.sourceforge.net: */
/* Get two-int array:
 * [0]=current protocol (1=7/1/1, 2=7/1/2, 3=7/1/3),
 * [1]=supported protocol mask (mask&(1<<n)!=0 means 7/1/n supported): */
#define LPIOC_GET_PROTOCOLS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_PROTOCOLS, len)
/* Set protocol (arg: 1=7/1/1, 2=7/1/2, 3=7/1/3): */
#define LPIOC_SET_PROTOCOL _IOC(_IOC_WRITE, 'P', IOCNR_SET_PROTOCOL, 0)
/* Set channel number (HP Vendor-specific command): */
#define LPIOC_HP_SET_CHANNEL _IOC(_IOC_WRITE, 'P', IOCNR_HP_SET_CHANNEL, 0)
/* Get two-int array: [0]=bus number, [1]=device address: */
#define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
/* Get two-int array: [0]=vendor ID, [1]=product ID: */
#define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
/* Perform class specific soft reset */
#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0);

/*
 * A DEVICE_ID string may include the printer's serial number.
 * It should end with a semi-colon (';').
 * An example from an HP 970C DeskJet printer is (this is one long string,
 * with the serial number changed):
MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:Hewlett-Packard DeskJet 970C;SERN:US970CSEPROF;VSTATUS:$HB0$NC0,ff,DN,IDLE,CUT,K1,C0,DP,NR,KP000,CP027;VP:0800,FL,B0;VJ:                    ;
 */

/*
 * USB Printer Requests
 */

#define USBLP_REQ_GET_ID			0x00
#define USBLP_REQ_GET_STATUS			0x01
#define USBLP_REQ_RESET				0x02
#define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST	0x00	/* HP Vendor-specific */

#define USBLP_MINORS		16
#define USBLP_MINOR_BASE	0

Pete Zaitcev's avatar
Pete Zaitcev committed
118
#define USBLP_CTL_TIMEOUT	5000			/* 5 seconds */
Linus Torvalds's avatar
Linus Torvalds committed
119
120
121
122
123
124
125
126
127
128
129

#define USBLP_FIRST_PROTOCOL	1
#define USBLP_LAST_PROTOCOL	3
#define USBLP_MAX_PROTOCOLS	(USBLP_LAST_PROTOCOL+1)

/*
 * some arbitrary status buffer size;
 * need a status buffer that is allocated via kmalloc(), not on stack
 */
#define STATUS_BUF_SIZE		8

130
131
132
133
134
135
136
/*
 * Locks down the locking order:
 * ->wmut locks wstatus.
 * ->mut locks the whole usblp, except [rw]complete, and thus, by indirection,
 * [rw]status. We only touch status when we know the side idle.
 * ->lock locks what interrupt accesses.
 */
Linus Torvalds's avatar
Linus Torvalds committed
137
138
struct usblp {
	struct usb_device 	*dev;			/* USB device */
139
140
141
	struct mutex		wmut;
	struct mutex		mut;
	spinlock_t		lock;		/* locks rcomplete, wcomplete */
Linus Torvalds's avatar
Linus Torvalds committed
142
143
	char			*readbuf;		/* read transfer_buffer */
	char			*statusbuf;		/* status transfer_buffer */
144
145
	struct usb_anchor	urbs;
	wait_queue_head_t	rwait, wwait;
Linus Torvalds's avatar
Linus Torvalds committed
146
147
148
149
150
151
152
153
154
155
156
157
	int			readcount;		/* Counter for reads */
	int			ifnum;			/* Interface number */
	struct usb_interface	*intf;			/* The interface */
	/* Alternate-setting numbers and endpoints for each protocol
	 * (7/1/{index=1,2,3}) that the device supports: */
	struct {
		int				alt_setting;
		struct usb_endpoint_descriptor	*epwrite;
		struct usb_endpoint_descriptor	*epread;
	}			protocol[USBLP_MAX_PROTOCOLS];
	int			current_protocol;
	int			minor;			/* minor number of device */
158
159
160
	int			wcomplete, rcomplete;
	int			wstatus;	/* bytes written or error */
	int			rstatus;	/* bytes ready or error */
Linus Torvalds's avatar
Linus Torvalds committed
161
	unsigned int		quirks;			/* quirks flags */
162
	unsigned int		flags;			/* mode flags */
Linus Torvalds's avatar
Linus Torvalds committed
163
164
165
	unsigned char		used;			/* True if open */
	unsigned char		present;		/* True if not disconnected */
	unsigned char		bidir;			/* interface is bidirectional */
166
	unsigned char		sleeping;		/* interface is suspended */
167
	unsigned char		no_paper;		/* Paper Out happened */
Linus Torvalds's avatar
Linus Torvalds committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
	unsigned char		*device_id_string;	/* IEEE 1284 DEVICE ID string (ptr) */
							/* first 2 bytes are (big-endian) length */
};

#ifdef DEBUG
static void usblp_dump(struct usblp *usblp) {
	int p;

	dbg("usblp=0x%p", usblp);
	dbg("dev=0x%p", usblp->dev);
	dbg("present=%d", usblp->present);
	dbg("readbuf=0x%p", usblp->readbuf);
	dbg("readcount=%d", usblp->readcount);
	dbg("ifnum=%d", usblp->ifnum);
    for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
	dbg("protocol[%d].alt_setting=%d", p, usblp->protocol[p].alt_setting);
	dbg("protocol[%d].epwrite=%p", p, usblp->protocol[p].epwrite);
	dbg("protocol[%d].epread=%p", p, usblp->protocol[p].epread);
    }
	dbg("current_protocol=%d", usblp->current_protocol);
	dbg("minor=%d", usblp->minor);
189
190
	dbg("wstatus=%d", usblp->wstatus);
	dbg("rstatus=%d", usblp->rstatus);
Linus Torvalds's avatar
Linus Torvalds committed
191
192
193
	dbg("quirks=%d", usblp->quirks);
	dbg("used=%d", usblp->used);
	dbg("bidir=%d", usblp->bidir);
194
	dbg("sleeping=%d", usblp->sleeping);
Linus Torvalds's avatar
Linus Torvalds committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
	dbg("device_id_string=\"%s\"",
		usblp->device_id_string ?
			usblp->device_id_string + 2 :
			(unsigned char *)"(null)");
}
#endif

/* Quirks: various printer quirks are handled by this table & its flags. */

struct quirk_printer_struct {
	__u16 vendorId;
	__u16 productId;
	unsigned int quirks;
};

#define USBLP_QUIRK_BIDIR	0x1	/* reports bidir but requires unidirectional mode (no INs/reads) */
#define USBLP_QUIRK_USB_INIT	0x2	/* needs vendor USB init string */
212
#define USBLP_QUIRK_BAD_CLASS	0x4	/* descriptor uses vendor-specific Class or SubClass */
Linus Torvalds's avatar
Linus Torvalds committed
213

214
static const struct quirk_printer_struct quirk_printers[] = {
Linus Torvalds's avatar
Linus Torvalds committed
215
216
217
218
219
220
221
222
223
224
225
226
227
	{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
	{ 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
	{ 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
	{ 0x03f0, 0x0304, USBLP_QUIRK_BIDIR }, /* HP DeskJet 810C/812C */
	{ 0x03f0, 0x0404, USBLP_QUIRK_BIDIR }, /* HP DeskJet 830C */
	{ 0x03f0, 0x0504, USBLP_QUIRK_BIDIR }, /* HP DeskJet 885C */
	{ 0x03f0, 0x0604, USBLP_QUIRK_BIDIR }, /* HP DeskJet 840C */   
	{ 0x03f0, 0x0804, USBLP_QUIRK_BIDIR }, /* HP DeskJet 816C */   
	{ 0x03f0, 0x1104, USBLP_QUIRK_BIDIR }, /* HP Deskjet 959C */
	{ 0x0409, 0xefbe, USBLP_QUIRK_BIDIR }, /* NEC Picty900 (HP OEM) */
	{ 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */
	{ 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
	{ 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
228
	{ 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
229
	{ 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
Linus Torvalds's avatar
Linus Torvalds committed
230
231
232
	{ 0, 0 }
};

233
234
235
236
237
static int usblp_wwait(struct usblp *usblp, int nonblock);
static int usblp_wtest(struct usblp *usblp, int nonblock);
static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock);
static int usblp_rtest(struct usblp *usblp, int nonblock);
static int usblp_submit_read(struct usblp *usblp);
Linus Torvalds's avatar
Linus Torvalds committed
238
239
240
241
242
243
static int usblp_select_alts(struct usblp *usblp);
static int usblp_set_protocol(struct usblp *usblp, int protocol);
static int usblp_cache_device_id_string(struct usblp *usblp);

/* forward reference to make our lives easier */
static struct usb_driver usblp_driver;
244
static DEFINE_MUTEX(usblp_mutex);	/* locks the existence of usblp's */
Linus Torvalds's avatar
Linus Torvalds committed
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

/*
 * Functions for usblp control messages.
 */

static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, int recip, int value, void *buf, int len)
{
	int retval;
	int index = usblp->ifnum;

	/* High byte has the interface index.
	   Low byte has the alternate setting.
	 */
	if ((request == USBLP_REQ_GET_ID) && (type == USB_TYPE_CLASS)) {
	  index = (usblp->ifnum<<8)|usblp->protocol[usblp->current_protocol].alt_setting;
	}

	retval = usb_control_msg(usblp->dev,
		dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
Pete Zaitcev's avatar
Pete Zaitcev committed
264
		request, type | dir | recip, value, index, buf, len, USBLP_CTL_TIMEOUT);
Linus Torvalds's avatar
Linus Torvalds committed
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
	dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d",
		request, !!dir, recip, value, index, len, retval);
	return retval < 0 ? retval : 0;
}

#define usblp_read_status(usblp, status)\
	usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_TYPE_CLASS, USB_DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
#define usblp_get_id(usblp, config, id, maxlen)\
	usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_TYPE_CLASS, USB_DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
#define usblp_reset(usblp)\
	usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)

#define usblp_hp_channel_change_request(usblp, channel, buffer) \
	usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1)

/*
 * See the description for usblp_select_alts() below for the usage
 * explanation.  Look into your /proc/bus/usb/devices and dmesg in
 * case of any trouble.
 */
static int proto_bias = -1;

/*
 * URB callback.
 */

291
static void usblp_bulk_read(struct urb *urb)
Linus Torvalds's avatar
Linus Torvalds committed
292
293
{
	struct usblp *usblp = urb->context;
294
	int status = urb->status;
Linus Torvalds's avatar
Linus Torvalds committed
295

296
	if (usblp->present && usblp->used) {
297
		if (status)
298
299
			printk(KERN_WARNING "usblp%d: "
			    "nonzero read bulk status received: %d\n",
300
			    usblp->minor, status);
301
302
	}
	spin_lock(&usblp->lock);
303
304
	if (status < 0)
		usblp->rstatus = status;
305
306
	else
		usblp->rstatus = urb->actual_length;
Linus Torvalds's avatar
Linus Torvalds committed
307
	usblp->rcomplete = 1;
308
309
310
311
	wake_up(&usblp->rwait);
	spin_unlock(&usblp->lock);

	usb_free_urb(urb);
Linus Torvalds's avatar
Linus Torvalds committed
312
313
}

314
static void usblp_bulk_write(struct urb *urb)
Linus Torvalds's avatar
Linus Torvalds committed
315
316
{
	struct usblp *usblp = urb->context;
317
	int status = urb->status;
Linus Torvalds's avatar
Linus Torvalds committed
318

319
	if (usblp->present && usblp->used) {
320
		if (status)
321
322
			printk(KERN_WARNING "usblp%d: "
			    "nonzero write bulk status received: %d\n",
323
			    usblp->minor, status);
324
325
	}
	spin_lock(&usblp->lock);
326
327
	if (status < 0)
		usblp->wstatus = status;
328
329
	else
		usblp->wstatus = urb->actual_length;
330
	usblp->no_paper = 0;
Linus Torvalds's avatar
Linus Torvalds committed
331
	usblp->wcomplete = 1;
332
333
334
335
	wake_up(&usblp->wwait);
	spin_unlock(&usblp->lock);

	usb_free_urb(urb);
Linus Torvalds's avatar
Linus Torvalds committed
336
337
338
339
340
341
}

/*
 * Get and print printer errors.
 */

342
static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
Linus Torvalds's avatar
Linus Torvalds committed
343
344
345
346
347
348

static int usblp_check_status(struct usblp *usblp, int err)
{
	unsigned char status, newerr = 0;
	int error;

349
350
351
	mutex_lock(&usblp->mut);
	if ((error = usblp_read_status(usblp, usblp->statusbuf)) < 0) {
		mutex_unlock(&usblp->mut);
352
		if (printk_ratelimit())
353
354
			printk(KERN_ERR
				"usblp%d: error %d reading printer status\n",
355
				usblp->minor, error);
Linus Torvalds's avatar
Linus Torvalds committed
356
357
358
		return 0;
	}
	status = *usblp->statusbuf;
359
	mutex_unlock(&usblp->mut);
Linus Torvalds's avatar
Linus Torvalds committed
360
361
362
363
364
365
366
367

	if (~status & LP_PERRORP)
		newerr = 3;
	if (status & LP_POUTPA)
		newerr = 1;
	if (~status & LP_PSELECD)
		newerr = 2;

368
369
370
371
	if (newerr != err) {
		printk(KERN_INFO "usblp%d: %s\n",
		   usblp->minor, usblp_messages[newerr]);
	}
Linus Torvalds's avatar
Linus Torvalds committed
372
373
374
375

	return newerr;
}

376
377
378
static int handle_bidir (struct usblp *usblp)
{
	if (usblp->bidir && usblp->used && !usblp->sleeping) {
379
		if (usblp_submit_read(usblp) < 0)
380
381
382
383
384
			return -EIO;
	}
	return 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
385
386
387
388
389
390
391
392
393
394
395
396
397
398
/*
 * File op functions.
 */

static int usblp_open(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	struct usblp *usblp;
	struct usb_interface *intf;
	int retval;

	if (minor < 0)
		return -ENODEV;

399
	mutex_lock (&usblp_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

	retval = -ENODEV;
	intf = usb_find_interface(&usblp_driver, minor);
	if (!intf) {
		goto out;
	}
	usblp = usb_get_intfdata (intf);
	if (!usblp || !usblp->dev || !usblp->present)
		goto out;

	retval = -EBUSY;
	if (usblp->used)
		goto out;

	/*
415
416
417
	 * We do not implement LP_ABORTOPEN/LPABORTOPEN for two reasons:
	 *  - We do not want persistent state which close(2) does not clear
	 *  - It is not used anyway, according to CUPS people
Linus Torvalds's avatar
Linus Torvalds committed
418
419
	 */

420
421
422
	retval = usb_autopm_get_interface(intf);
	if (retval < 0)
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
423
424
425
426
	usblp->used = 1;
	file->private_data = usblp;

	usblp->wcomplete = 1; /* we begin writeable */
427
	usblp->wstatus = 0;
Linus Torvalds's avatar
Linus Torvalds committed
428
429
	usblp->rcomplete = 0;

430
	if (handle_bidir(usblp) < 0) {
431
		usblp->used = 0;
432
433
		file->private_data = NULL;
		retval = -EIO;
Linus Torvalds's avatar
Linus Torvalds committed
434
435
	}
out:
436
	mutex_unlock (&usblp_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
437
438
439
440
441
	return retval;
}

static void usblp_cleanup (struct usblp *usblp)
{
442
	printk(KERN_INFO "usblp%d: removed\n", usblp->minor);
Linus Torvalds's avatar
Linus Torvalds committed
443

444
	kfree(usblp->readbuf);
Linus Torvalds's avatar
Linus Torvalds committed
445
446
447
448
449
450
451
	kfree (usblp->device_id_string);
	kfree (usblp->statusbuf);
	kfree (usblp);
}

static void usblp_unlink_urbs(struct usblp *usblp)
{
452
	usb_kill_anchored_urbs(&usblp->urbs);
Linus Torvalds's avatar
Linus Torvalds committed
453
454
455
456
457
458
}

static int usblp_release(struct inode *inode, struct file *file)
{
	struct usblp *usblp = file->private_data;

459
460
	usblp->flags &= ~LP_ABORT;

461
	mutex_lock (&usblp_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
462
463
464
	usblp->used = 0;
	if (usblp->present) {
		usblp_unlink_urbs(usblp);
465
		usb_autopm_put_interface(usblp->intf);
Linus Torvalds's avatar
Linus Torvalds committed
466
467
	} else 		/* finish cleanup from disconnect */
		usblp_cleanup (usblp);
468
	mutex_unlock (&usblp_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
469
470
471
472
473
474
	return 0;
}

/* No kernel lock - fine */
static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait)
{
475
476
477
	int ret;
	unsigned long flags;

Linus Torvalds's avatar
Linus Torvalds committed
478
	struct usblp *usblp = file->private_data;
479
480
481
482
	/* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */
	poll_wait(file, &usblp->rwait, wait);
	poll_wait(file, &usblp->wwait, wait);
	spin_lock_irqsave(&usblp->lock, flags);
Pete Zaitcev's avatar
Pete Zaitcev committed
483
484
	ret = ((usblp->bidir && usblp->rcomplete) ? POLLIN  | POLLRDNORM : 0) |
	   ((usblp->no_paper || usblp->wcomplete) ? POLLOUT | POLLWRNORM : 0);
485
486
	spin_unlock_irqrestore(&usblp->lock, flags);
	return ret;
Linus Torvalds's avatar
Linus Torvalds committed
487
488
}

489
static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds's avatar
Linus Torvalds committed
490
491
492
493
494
495
496
497
{
	struct usblp *usblp = file->private_data;
	int length, err, i;
	unsigned char newChannel;
	int status;
	int twoints[2];
	int retval = 0;

Oliver Neukum's avatar
Oliver Neukum committed
498
	mutex_lock (&usblp->mut);
Linus Torvalds's avatar
Linus Torvalds committed
499
500
501
502
503
	if (!usblp->present) {
		retval = -ENODEV;
		goto done;
	}

504
505
506
507
508
	if (usblp->sleeping) {
		retval = -ENODEV;
		goto done;
	}

Linus Torvalds's avatar
Linus Torvalds committed
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
	dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd),
		_IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) );

	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */

		switch (_IOC_NR(cmd)) {

			case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
				if (_IOC_DIR(cmd) != _IOC_READ) {
					retval = -EINVAL;
					goto done;
				}

				length = usblp_cache_device_id_string(usblp);
				if (length < 0) {
					retval = length;
					goto done;
				}
				if (length > _IOC_SIZE(cmd))
					length = _IOC_SIZE(cmd); /* truncate */

				if (copy_to_user((void __user *) arg,
						usblp->device_id_string,
						(unsigned long) length)) {
					retval = -EFAULT;
					goto done;
				}

				break;

			case IOCNR_GET_PROTOCOLS:
				if (_IOC_DIR(cmd) != _IOC_READ ||
				    _IOC_SIZE(cmd) < sizeof(twoints)) {
					retval = -EINVAL;
					goto done;
				}

				twoints[0] = usblp->current_protocol;
				twoints[1] = 0;
				for (i = USBLP_FIRST_PROTOCOL;
				     i <= USBLP_LAST_PROTOCOL; i++) {
					if (usblp->protocol[i].alt_setting >= 0)
						twoints[1] |= (1<<i);
				}

				if (copy_to_user((void __user *)arg,
						(unsigned char *)twoints,
						sizeof(twoints))) {
					retval = -EFAULT;
					goto done;
				}

				break;

			case IOCNR_SET_PROTOCOL:
				if (_IOC_DIR(cmd) != _IOC_WRITE) {
					retval = -EINVAL;
					goto done;
				}

#ifdef DEBUG
				if (arg == -10) {
					usblp_dump(usblp);
					break;
				}
#endif

				usblp_unlink_urbs(usblp);
				retval = usblp_set_protocol(usblp, arg);
				if (retval < 0) {
					usblp_set_protocol(usblp,
						usblp->current_protocol);
				}
				break;

			case IOCNR_HP_SET_CHANNEL:
				if (_IOC_DIR(cmd) != _IOC_WRITE ||
				    le16_to_cpu(usblp->dev->descriptor.idVendor) != 0x03F0 ||
				    usblp->quirks & USBLP_QUIRK_BIDIR) {
					retval = -EINVAL;
					goto done;
				}

				err = usblp_hp_channel_change_request(usblp,
					arg, &newChannel);
				if (err < 0) {
					err("usblp%d: error = %d setting "
						"HP channel",
						usblp->minor, err);
					retval = -EIO;
					goto done;
				}

				dbg("usblp%d requested/got HP channel %ld/%d",
					usblp->minor, arg, newChannel);
				break;

			case IOCNR_GET_BUS_ADDRESS:
				if (_IOC_DIR(cmd) != _IOC_READ ||
				    _IOC_SIZE(cmd) < sizeof(twoints)) {
					retval = -EINVAL;
					goto done;
				}

				twoints[0] = usblp->dev->bus->busnum;
				twoints[1] = usblp->dev->devnum;
				if (copy_to_user((void __user *)arg,
						(unsigned char *)twoints,
						sizeof(twoints))) {
					retval = -EFAULT;
					goto done;
				}

				dbg("usblp%d is bus=%d, device=%d",
					usblp->minor, twoints[0], twoints[1]);
				break;

			case IOCNR_GET_VID_PID:
				if (_IOC_DIR(cmd) != _IOC_READ ||
				    _IOC_SIZE(cmd) < sizeof(twoints)) {
					retval = -EINVAL;
					goto done;
				}

				twoints[0] = le16_to_cpu(usblp->dev->descriptor.idVendor);
				twoints[1] = le16_to_cpu(usblp->dev->descriptor.idProduct);
				if (copy_to_user((void __user *)arg,
						(unsigned char *)twoints,
						sizeof(twoints))) {
					retval = -EFAULT;
					goto done;
				}

				dbg("usblp%d is VID=0x%4.4X, PID=0x%4.4X",
					usblp->minor, twoints[0], twoints[1]);
				break;

			case IOCNR_SOFT_RESET:
				if (_IOC_DIR(cmd) != _IOC_NONE) {
					retval = -EINVAL;
					goto done;
				}
				retval = usblp_reset(usblp);
				break;
			default:
				retval = -ENOTTY;
		}
	else	/* old-style ioctl value */
		switch (cmd) {

			case LPGETSTATUS:
660
				if ((retval = usblp_read_status(usblp, usblp->statusbuf))) {
661
					if (printk_ratelimit())
662
663
664
						printk(KERN_ERR "usblp%d:"
						    "failed reading printer status (%d)\n",
						    usblp->minor, retval);
Linus Torvalds's avatar
Linus Torvalds committed
665
666
667
668
669
670
671
672
					retval = -EIO;
					goto done;
				}
				status = *usblp->statusbuf;
				if (copy_to_user ((void __user *)arg, &status, sizeof(int)))
					retval = -EFAULT;
				break;

673
674
675
676
677
678
679
			case LPABORT:
				if (arg)
					usblp->flags |= LP_ABORT;
				else
					usblp->flags &= ~LP_ABORT;
				break;

Linus Torvalds's avatar
Linus Torvalds committed
680
681
682
683
684
			default:
				retval = -ENOTTY;
		}

done:
Oliver Neukum's avatar
Oliver Neukum committed
685
	mutex_unlock (&usblp->mut);
Linus Torvalds's avatar
Linus Torvalds committed
686
687
688
689
690
691
	return retval;
}

static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
	struct usblp *usblp = file->private_data;
692
693
694
695
696
697
698
699
700
701
702
703
	char *writebuf;
	struct urb *writeurb;
	int rv;
	int transfer_length;
	ssize_t writecount = 0;

	if (mutex_lock_interruptible(&usblp->wmut)) {
		rv = -EINTR;
		goto raise_biglock;
	}
	if ((rv = usblp_wwait(usblp, !!(file->f_flags & O_NONBLOCK))) < 0)
		goto raise_wait;
Linus Torvalds's avatar
Linus Torvalds committed
704
705

	while (writecount < count) {
706
707
		/*
		 * Step 1: Submit next block.
Linus Torvalds's avatar
Linus Torvalds committed
708
		 */
709
		if ((transfer_length = count - writecount) > USBLP_BUF_SIZE)
Linus Torvalds's avatar
Linus Torvalds committed
710
711
			transfer_length = USBLP_BUF_SIZE;

712
713
714
715
716
717
718
719
720
		rv = -ENOMEM;
		if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL)
			goto raise_buf;
		if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL)
			goto raise_urb;
		usb_fill_bulk_urb(writeurb, usblp->dev,
			usb_sndbulkpipe(usblp->dev,
			  usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress),
			writebuf, transfer_length, usblp_bulk_write, usblp);
721
		writeurb->transfer_flags |= URB_FREE_BUFFER;
722
723
724
		usb_anchor_urb(writeurb, &usblp->urbs);

		if (copy_from_user(writebuf,
Linus Torvalds's avatar
Linus Torvalds committed
725
				   buffer + writecount, transfer_length)) {
726
727
			rv = -EFAULT;
			goto raise_badaddr;
Linus Torvalds's avatar
Linus Torvalds committed
728
729
		}

730
		spin_lock_irq(&usblp->lock);
Linus Torvalds's avatar
Linus Torvalds committed
731
		usblp->wcomplete = 0;
732
733
734
735
		spin_unlock_irq(&usblp->lock);
		if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) {
			usblp->wstatus = 0;
			spin_lock_irq(&usblp->lock);
736
			usblp->no_paper = 0;
737
			usblp->wcomplete = 1;
738
739
740
741
742
743
744
745
746
747
748
749
			wake_up(&usblp->wwait);
			spin_unlock_irq(&usblp->lock);
			if (rv != -ENOMEM)
				rv = -EIO;
			goto raise_submit;
		}

		/*
		 * Step 2: Wait for transfer to end, collect results.
		 */
		rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK));
		if (rv < 0) {
750
751
752
753
			if (rv == -EAGAIN) {
				/* Presume that it's going to complete well. */
				writecount += transfer_length;
			}
754
755
756
757
758
759
			if (rv == -ENOSPC) {
				spin_lock_irq(&usblp->lock);
				usblp->no_paper = 1;	/* Mark for poll(2) */
				spin_unlock_irq(&usblp->lock);
				writecount += transfer_length;
			}
760
			/* Leave URB dangling, to be cleaned on close. */
761
			goto collect_error;
Linus Torvalds's avatar
Linus Torvalds committed
762
		}
763
764
765
766
767
768
769
770
771
772

		if (usblp->wstatus < 0) {
			rv = -EIO;
			goto collect_error;
		}
		/*
		 * This is critical: it must be our URB, not other writer's.
		 * The wmut exists mainly to cover us here.
		 */
		writecount += usblp->wstatus;
Linus Torvalds's avatar
Linus Torvalds committed
773
774
	}

775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
	mutex_unlock(&usblp->wmut);
	return writecount;

raise_submit:
raise_badaddr:
	usb_unanchor_urb(writeurb);
	usb_free_urb(writeurb);
raise_urb:
	kfree(writebuf);
raise_buf:
raise_wait:
collect_error:		/* Out of raise sequence */
	mutex_unlock(&usblp->wmut);
raise_biglock:
	return writecount ? writecount : rv;
Linus Torvalds's avatar
Linus Torvalds committed
790
791
}

792
793
794
795
796
797
/*
 * Notice that we fail to restart in a few cases: on EFAULT, on restart
 * error, etc. This is the historical behaviour. In all such cases we return
 * EIO, and applications loop in order to get the new read going.
 */
static ssize_t usblp_read(struct file *file, char __user *buffer, size_t len, loff_t *ppos)
Linus Torvalds's avatar
Linus Torvalds committed
798
799
{
	struct usblp *usblp = file->private_data;
800
801
802
	ssize_t count;
	ssize_t avail;
	int rv;
Linus Torvalds's avatar
Linus Torvalds committed
803
804
805
806

	if (!usblp->bidir)
		return -EINVAL;

807
808
809
810
811
812
813
814
815
	rv = usblp_rwait_and_lock(usblp, !!(file->f_flags & O_NONBLOCK));
	if (rv < 0)
		return rv;

	if ((avail = usblp->rstatus) < 0) {
		printk(KERN_ERR "usblp%d: error %d reading from printer\n",
		    usblp->minor, (int)avail);
		usblp_submit_read(usblp);
		count = -EIO;
Linus Torvalds's avatar
Linus Torvalds committed
816
817
818
		goto done;
	}

819
820
821
822
823
824
	count = len < avail - usblp->readcount ? len : avail - usblp->readcount;
	if (count != 0 &&
	    copy_to_user(buffer, usblp->readbuf + usblp->readcount, count)) {
		count = -EFAULT;
		goto done;
	}
Linus Torvalds's avatar
Linus Torvalds committed
825

826
827
828
829
830
	if ((usblp->readcount += count) == avail) {
		if (usblp_submit_read(usblp) < 0) {
			/* We don't want to leak USB return codes into errno. */
			if (count == 0)
				count = -EIO;
Oliver Neukum's avatar
Oliver Neukum committed
831
			goto done;
Linus Torvalds's avatar
Linus Torvalds committed
832
833
834
		}
	}

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
done:
	mutex_unlock (&usblp->mut);
	return count;
}

/*
 * Wait for the write path to come idle.
 * This is called under the ->wmut, so the idle path stays idle.
 *
 * Our write path has a peculiar property: it does not buffer like a tty,
 * but waits for the write to succeed. This allows our ->release to bug out
 * without waiting for writes to drain. But it obviously does not work
 * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use
 * select(2) or poll(2) to wait for the buffer to drain before closing.
 * Alternatively, set blocking mode with fcntl and issue a zero-size write.
 */
static int usblp_wwait(struct usblp *usblp, int nonblock)
{
	DECLARE_WAITQUEUE(waita, current);
	int rc;
855
	int err = 0;
856
857
858

	add_wait_queue(&usblp->wwait, &waita);
	for (;;) {
859
		set_current_state(TASK_INTERRUPTIBLE);
860
861
862
863
		if (mutex_lock_interruptible(&usblp->mut)) {
			rc = -EINTR;
			break;
		}
864
		rc = usblp_wtest(usblp, nonblock);
865
		mutex_unlock(&usblp->mut);
866
		if (rc <= 0)
867
			break;
868
869
870
871
872
873
874
875
876
877
878
879

		if (usblp->flags & LP_ABORT) {
			if (schedule_timeout(msecs_to_jiffies(5000)) == 0) {
				err = usblp_check_status(usblp, err);
				if (err == 1) {	/* Paper out */
					rc = -ENOSPC;
					break;
				}
			}
		} else {
			schedule();
		}
Linus Torvalds's avatar
Linus Torvalds committed
880
	}
881
882
883
884
	set_current_state(TASK_RUNNING);
	remove_wait_queue(&usblp->wwait, &waita);
	return rc;
}
Linus Torvalds's avatar
Linus Torvalds committed
885

886
887
888
889
890
891
892
893
894
895
896
897
static int usblp_wtest(struct usblp *usblp, int nonblock)
{
	unsigned long flags;

	if (!usblp->present)
		return -ENODEV;
	if (signal_pending(current))
		return -EINTR;
	spin_lock_irqsave(&usblp->lock, flags);
	if (usblp->wcomplete) {
		spin_unlock_irqrestore(&usblp->lock, flags);
		return 0;
898
	}
899
900
901
902
903
904
905
	spin_unlock_irqrestore(&usblp->lock, flags);
	if (usblp->sleeping)
		return -ENODEV;
	if (nonblock)
		return -EAGAIN;
	return 1;
}
906

907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
/*
 * Wait for read bytes to become available. This probably should have been
 * called usblp_r_lock_and_wait(), because we lock first. But it's a traditional
 * name for functions which lock and return.
 *
 * We do not use wait_event_interruptible because it makes locking iffy.
 */
static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock)
{
	DECLARE_WAITQUEUE(waita, current);
	int rc;

	add_wait_queue(&usblp->rwait, &waita);
	for (;;) {
		if (mutex_lock_interruptible(&usblp->mut)) {
			rc = -EINTR;
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		if ((rc = usblp_rtest(usblp, nonblock)) < 0) {
			mutex_unlock(&usblp->mut);
			break;
		}
		if (rc == 0)	/* Keep it locked */
			break;
		mutex_unlock(&usblp->mut);
		schedule();
Linus Torvalds's avatar
Linus Torvalds committed
934
	}
935
936
937
938
	set_current_state(TASK_RUNNING);
	remove_wait_queue(&usblp->rwait, &waita);
	return rc;
}
Linus Torvalds's avatar
Linus Torvalds committed
939

940
941
942
static int usblp_rtest(struct usblp *usblp, int nonblock)
{
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
943

944
945
946
947
948
949
950
951
	if (!usblp->present)
		return -ENODEV;
	if (signal_pending(current))
		return -EINTR;
	spin_lock_irqsave(&usblp->lock, flags);
	if (usblp->rcomplete) {
		spin_unlock_irqrestore(&usblp->lock, flags);
		return 0;
Linus Torvalds's avatar
Linus Torvalds committed
952
	}
953
954
955
956
957
958
959
	spin_unlock_irqrestore(&usblp->lock, flags);
	if (usblp->sleeping)
		return -ENODEV;
	if (nonblock)
		return -EAGAIN;
	return 1;
}
Linus Torvalds's avatar
Linus Torvalds committed
960

961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
/*
 * Please check ->bidir and other such things outside for now.
 */
static int usblp_submit_read(struct usblp *usblp)
{
	struct urb *urb;
	unsigned long flags;
	int rc;

	rc = -ENOMEM;
	if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL)
		goto raise_urb;

	usb_fill_bulk_urb(urb, usblp->dev,
		usb_rcvbulkpipe(usblp->dev,
		  usblp->protocol[usblp->current_protocol].epread->bEndpointAddress),
		usblp->readbuf, USBLP_BUF_SIZE_IN,
		usblp_bulk_read, usblp);
	usb_anchor_urb(urb, &usblp->urbs);

	spin_lock_irqsave(&usblp->lock, flags);
	usblp->readcount = 0; /* XXX Why here? */
	usblp->rcomplete = 0;
	spin_unlock_irqrestore(&usblp->lock, flags);
	if ((rc = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
		dbg("error submitting urb (%d)", rc);
		spin_lock_irqsave(&usblp->lock, flags);
		usblp->rstatus = rc;
		usblp->rcomplete = 1;
		spin_unlock_irqrestore(&usblp->lock, flags);
		goto raise_submit;
Linus Torvalds's avatar
Linus Torvalds committed
992
993
	}

994
995
996
997
998
999
1000
	return 0;

raise_submit:
	usb_unanchor_urb(urb);
	usb_free_urb(urb);
raise_urb:
	return rc;
Linus Torvalds's avatar
Linus Torvalds committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
}

/*
 * Checks for printers that have quirks, such as requiring unidirectional
 * communication but reporting bidirectional; currently some HP printers
 * have this flaw (HP 810, 880, 895, etc.), or needing an init string
 * sent at each open (like some Epsons).
 * Returns 1 if found, 0 if not found.
 *
 * HP recommended that we use the bidirectional interface but
 * don't attempt any bulk IN transfers from the IN endpoint.
 * Here's some more detail on the problem:
 * The problem is not that it isn't bidirectional though. The problem
 * is that if you request a device ID, or status information, while
 * the buffers are full, the return data will end up in the print data
 * buffer. For example if you make sure you never request the device ID
 * while you are sending print data, and you don't try to query the
 * printer status every couple of milliseconds, you will probably be OK.
 */
static unsigned int usblp_quirks (__u16 vendor, __u16 product)
{
	int i;

	for (i = 0; quirk_printers[i].vendorId; i++) {
		if (vendor == quirk_printers[i].vendorId &&
		    product == quirk_printers[i].productId)
			return quirk_printers[i].quirks;
 	}
	return 0;
}

1032
static const struct file_operations usblp_fops = {
Linus Torvalds's avatar
Linus Torvalds committed
1033
1034
1035
1036
	.owner =	THIS_MODULE,
	.read =		usblp_read,
	.write =	usblp_write,
	.poll =		usblp_poll,
1037
1038
	.unlocked_ioctl =	usblp_ioctl,
	.compat_ioctl =		usblp_ioctl,
Linus Torvalds's avatar
Linus Torvalds committed
1039
1040
1041
1042
1043
	.open =		usblp_open,
	.release =	usblp_release,
};

static struct usb_class_driver usblp_class = {
1044
	.name =		"lp%d",
Linus Torvalds's avatar
Linus Torvalds committed
1045
1046
1047
1048
	.fops =		&usblp_fops,
	.minor_base =	USBLP_MINOR_BASE,
};

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct usblp *usblp = usb_get_intfdata (intf);

	if (usblp->device_id_string[0] == 0 &&
	    usblp->device_id_string[1] == 0)
		return 0;

	return sprintf(buf, "%s", usblp->device_id_string+2);
}

static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL);

Linus Torvalds's avatar
Linus Torvalds committed
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
static int usblp_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev (intf);
	struct usblp *usblp = NULL;
	int protocol;
	int retval;

	/* Malloc and start initializing usblp structure so we can use it
	 * directly. */
Oliver Neukum's avatar
Oliver Neukum committed
1073
	if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
1074
		retval = -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
1075
1076
1077
		goto abort;
	}
	usblp->dev = dev;
1078
	mutex_init(&usblp->wmut);
Oliver Neukum's avatar
Oliver Neukum committed
1079
	mutex_init (&usblp->mut);
1080
1081
1082
1083
	spin_lock_init(&usblp->lock);
	init_waitqueue_head(&usblp->rwait);
	init_waitqueue_head(&usblp->wwait);
	init_usb_anchor(&usblp->urbs);
Linus Torvalds's avatar
Linus Torvalds committed
1084
1085
1086
1087
1088
1089
1090
	usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
	usblp->intf = intf;

	/* Malloc device ID string buffer to the largest expected length,
	 * since we can re-query it on an ioctl and a dynamic string
	 * could change in length. */
	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
1091
		retval = -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
1092
1093
1094
		goto abort;
	}

1095
1096
	/*
	 * Allocate read buffer. We somewhat wastefully
Linus Torvalds's avatar
Linus Torvalds committed
1097
	 * malloc both regardless of bidirectionality, because the
1098
1099
1100
1101
	 * alternate setting can be changed later via an ioctl.
	 */
	if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE_IN, GFP_KERNEL))) {
		retval = -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
1102
1103
1104
1105
1106
1107
		goto abort;
	}

	/* Allocate buffer for printer status */
	usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
	if (!usblp->statusbuf) {
1108
		retval = -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
		goto abort;
	}

	/* Lookup quirks for this printer. */
	usblp->quirks = usblp_quirks(
		le16_to_cpu(dev->descriptor.idVendor),
		le16_to_cpu(dev->descriptor.idProduct));

	/* Analyze and pick initial alternate settings and endpoints. */
	protocol = usblp_select_alts(usblp);
	if (protocol < 0) {
		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
			le16_to_cpu(dev->descriptor.idVendor),
			le16_to_cpu(dev->descriptor.idProduct));
1123
		retval = -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
1124
1125
1126
1127
		goto abort;
	}

	/* Setup the selected alternate setting and endpoints. */
1128
1129
	if (usblp_set_protocol(usblp, protocol) < 0) {
		retval = -ENODEV;	/* ->probe isn't ->ioctl */
Linus Torvalds's avatar
Linus Torvalds committed
1130
		goto abort;
1131
	}
Linus Torvalds's avatar
Linus Torvalds committed
1132
1133
1134

	/* Retrieve and store the device ID string. */
	usblp_cache_device_id_string(usblp);
1135
1136
1137
	retval = device_create_file(&intf->dev, &dev_attr_ieee1284_id);
	if (retval)
		goto abort_intfdata;
Linus Torvalds's avatar
Linus Torvalds committed
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

#ifdef DEBUG
	usblp_check_status(usblp, 0);
#endif

	usb_set_intfdata (intf, usblp);

	usblp->present = 1;

	retval = usb_register_dev(intf, &usblp_class);
	if (retval) {
1149
1150
1151
		printk(KERN_ERR "usblp: Not able to get a minor"
		    " (base %u, slice default): %d\n",
		    USBLP_MINOR_BASE, retval);
Linus Torvalds's avatar
Linus Torvalds committed
1152
1153
1154
		goto abort_intfdata;
	}
	usblp->minor = intf->minor;
1155
1156
	printk(KERN_INFO "usblp%d: USB %sdirectional printer dev %d "
		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n",
1157
1158
1159
1160
1161
1162
		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
		usblp->ifnum,
		usblp->protocol[usblp->current_protocol].alt_setting,
		usblp->current_protocol,
		le16_to_cpu(usblp->dev->descriptor.idVendor),
		le16_to_cpu(usblp->dev->descriptor.idProduct));
Linus Torvalds's avatar
Linus Torvalds committed
1163
1164
1165
1166
1167

	return 0;

abort_intfdata:
	usb_set_intfdata (intf, NULL);
1168
	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
Linus Torvalds's avatar
Linus Torvalds committed
1169
1170
abort:
	if (usblp) {
1171
		kfree(usblp->readbuf);
Linus Torvalds's avatar
Linus Torvalds committed
1172
1173
1174
1175
		kfree(usblp->statusbuf);
		kfree(usblp->device_id_string);
		kfree(usblp);
	}
1176
	return retval;
Linus Torvalds's avatar
Linus Torvalds committed
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
}

/*
 * We are a "new" style driver with usb_device_id table,
 * but our requirements are too intricate for simple match to handle.
 *
 * The "proto_bias" option may be used to specify the preferred protocol
 * for all USB printers (1=7/1/1, 2=7/1/2, 3=7/1/3).  If the device
 * supports the preferred protocol, then we bind to it.
 *
 * The best interface for us is 7/1/2, because it is compatible
 * with a stream of characters. If we find it, we bind to it.
 *
 * Note that the people from hpoj.sourceforge.net need to be able to
 * bind to 7/1/3 (MLC/1284.4), so we provide them ioctls for this purpose.
 *
 * Failing 7/1/2, we look for 7/1/3, even though it's probably not
 * stream-compatible, because this matches the behaviour of the old code.
 *
 * If nothing else, we bind to 7/1/1 - the unidirectional interface.
 */
static int usblp_select_alts(struct usblp *usblp)
{
	struct usb_interface *if_alt;
	struct usb_host_interface *ifd;
	struct usb_endpoint_descriptor *epd, *epwrite, *epread;
	int p, i, e;

	if_alt = usblp->intf;

	for (p = 0; p < USBLP_MAX_PROTOCOLS; p++)
		usblp->protocol[p].alt_setting = -1;

	/* Find out what we have. */
	for (i = 0; i < if_alt->num_altsetting; i++) {
		ifd = &if_alt->altsetting[i];

		if (ifd->desc.bInterfaceClass != 7 || ifd->desc.bInterfaceSubClass != 1)
1215
1216
			if (!(usblp->quirks & USBLP_QUIRK_BAD_CLASS))
				continue;
Linus Torvalds's avatar
Linus Torvalds committed
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226

		if (ifd->desc.bInterfaceProtocol < USBLP_FIRST_PROTOCOL ||
		    ifd->desc.bInterfaceProtocol > USBLP_LAST_PROTOCOL)
			continue;

		/* Look for bulk OUT and IN endpoints. */
		epwrite = epread = NULL;
		for (e = 0; e < ifd->desc.bNumEndpoints; e++) {
			epd = &ifd->endpoint[e].desc;

1227
			if (usb_endpoint_is_bulk_out(epd))
Linus Torvalds's avatar
Linus Torvalds committed
1228
1229
1230
				if (!epwrite)
					epwrite = epd;

1231
			if (usb_endpoint_is_bulk_in(epd))
Linus Torvalds's avatar
Linus Torvalds committed
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
				if (!epread)
					epread = epd;
		}

		/* Ignore buggy hardware without the right endpoints. */
		if (!epwrite || (ifd->desc.bInterfaceProtocol > 1 && !epread))
			continue;

		/* Turn off reads for 7/1/1 (unidirectional) interfaces
		 * and buggy bidirectional printers. */
		if (ifd->desc.bInterfaceProtocol == 1) {
			epread = NULL;
		} else if (usblp->quirks & USBLP_QUIRK_BIDIR) {
1245
1246
1247
			printk(KERN_INFO "usblp%d: Disabling reads from "
			    "problematic bidirectional printer\n",
			    usblp->minor);
Linus Torvalds's avatar
Linus Torvalds committed
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
			epread = NULL;
		}

		usblp->protocol[ifd->desc.bInterfaceProtocol].alt_setting =
				ifd->desc.bAlternateSetting;
		usblp->protocol[ifd->desc.bInterfaceProtocol].epwrite = epwrite;
		usblp->protocol[ifd->desc.bInterfaceProtocol].epread = epread;
	}

	/* If our requested protocol is supported, then use it. */
	if (proto_bias >= USBLP_FIRST_PROTOCOL &&
	    proto_bias <= USBLP_LAST_PROTOCOL &&
	    usblp->protocol[proto_bias].alt_setting != -1)
		return proto_bias;

	/* Ordering is important here. */
	if (usblp->protocol[2].alt_setting != -1)
		return 2;
	if (usblp->protocol[1].alt_setting != -1)
		return 1;
	if (usblp->protocol[3].alt_setting != -1)
		return 3;

	/* If nothing is available, then don't bind to this device. */
	return -1;
}

static int usblp_set_protocol(struct usblp *usblp, int protocol)
{
	int r, alts;

	if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
		return -EINVAL;

	alts = usblp->protocol[protocol].alt_setting;
	if (alts < 0)
		return -EINVAL;
	r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
	if (r < 0) {
1287
		printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
Linus Torvalds's avatar
Linus Torvalds committed
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
			alts, usblp->ifnum);
		return r;
	}

	usblp->bidir = (usblp->protocol[protocol].epread != NULL);
	usblp->current_protocol = protocol;
	dbg("usblp%d set protocol %d", usblp->minor, protocol);
	return 0;
}

/* Retrieves and caches device ID string.
 * Returns length, including length bytes but not null terminator.
 * On error, returns a negative errno value. */
static int usblp_cache_device_id_string(struct usblp *usblp)
{
	int err, length;

	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
	if (err < 0) {
		dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
			usblp->minor, err);
		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
		return -EIO;
	}

	/* First two bytes are length in big-endian.
	 * They count themselves, and we copy them into
	 * the user's buffer. */
	length = be16_to_cpu(*((__be16 *)usblp->device_id_string));
	if (length < 2)
		length = 2;
	else if (length >= USBLP_DEVICE_ID_SIZE)
		length = USBLP_DEVICE_ID_SIZE - 1;
	usblp->device_id_string[length] = '\0';

	dbg("usblp%d Device ID string [len=%d]=\"%s\"",
		usblp->minor, length, &usblp->device_id_string[2]);

	return length;
}

static void usblp_disconnect(struct usb_interface *intf)
{
	struct usblp *usblp = usb_get_intfdata (intf);

	usb_deregister_dev(intf, &usblp_class);

	if (!usblp || !usblp->dev) {
		err("bogus disconnect");
		BUG ();
	}

1340
1341
	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);

1342
	mutex_lock (&usblp_mutex);
Oliver Neukum's avatar
Oliver Neukum committed
1343
	mutex_lock (&usblp->mut);
Linus Torvalds's avatar
Linus Torvalds committed
1344
	usblp->present = 0;
1345
1346
	wake_up(&usblp->wwait);
	wake_up(&usblp->rwait);
Linus Torvalds's avatar
Linus Torvalds committed
1347
1348
1349
	usb_set_intfdata (intf, NULL);

	usblp_unlink_urbs(usblp);
Oliver Neukum's avatar
Oliver Neukum committed
1350
	mutex_unlock (&usblp->mut);
Linus Torvalds's avatar
Linus Torvalds committed
1351
1352
1353

	if (!usblp->used)
		usblp_cleanup (usblp);
1354
	mutex_unlock (&usblp_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
1355
1356
}

1357
1358
1359
1360
1361
1362
1363
static int usblp_suspend (struct usb_interface *intf, pm_message_t message)
{
	struct usblp *usblp = usb_get_intfdata (intf);

	/* we take no more IO */
	usblp->sleeping = 1;
	usblp_unlink_urbs(usblp);
1364
1365
1366
1367
1368
#if 0 /* XXX Do we want this? What if someone is reading, should we fail? */
	/* not strictly necessary, but just in case */
	wake_up(&usblp->wwait);
	wake_up(&usblp->rwait);
#endif
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383

	return 0;
}

static int usblp_resume (struct usb_interface *intf)
{
	struct usblp *usblp = usb_get_intfdata (intf);
	int r;

	usblp->sleeping = 0;
	r = handle_bidir (usblp);

	return r;
}

Linus Torvalds's avatar
Linus Torvalds committed
1384
1385
1386
1387
1388
1389
1390
static struct usb_device_id usblp_ids [] = {
	{ USB_DEVICE_INFO(7, 1, 1) },
	{ USB_DEVICE_INFO(7, 1, 2) },
	{ USB_DEVICE_INFO(7, 1, 3) },
	{ USB_INTERFACE_INFO(7, 1, 1) },
	{ USB_INTERFACE_INFO(7, 1, 2) },
	{ USB_INTERFACE_INFO(7, 1, 3) },
1391
	{ USB_DEVICE(0x04b8, 0x0202) },	/* Seiko Epson Receipt Printer M129C */
Linus Torvalds's avatar
Linus Torvalds committed
1392
1393
1394
1395
1396
1397
1398
1399
1400
	{ }						/* Terminating entry */
};

MODULE_DEVICE_TABLE (usb, usblp_ids);

static struct usb_driver usblp_driver = {
	.name =		"usblp",
	.probe =	usblp_probe,
	.disconnect =	usblp_disconnect,
1401
1402
	.suspend =	usblp_suspend,
	.resume =	usblp_resume,
Linus Torvalds's avatar
Linus Torvalds committed
1403
	.id_table =	usblp_ids,
1404
	.supports_autosuspend =	1,
Linus Torvalds's avatar
Linus Torvalds committed
1405
1406
1407
1408
};

static int __init usblp_init(void)
{
1409
	return usb_register(&usblp_driver);
Linus Torvalds's avatar
Linus Torvalds committed
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
}

static void __exit usblp_exit(void)
{
	usb_deregister(&usblp_driver);
}

module_init(usblp_init);
module_exit(usblp_exit);

MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
module_param(proto_bias, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(proto_bias, "Favourite protocol number");
MODULE_LICENSE("GPL");