2 * printer.c Version 0.6
4 * Copyright (c) 1999 Michael Gee <michael@linuxspecific.com>
5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
6 * Copyright (c) 2000 Randy Dunlap <randy.dunlap@intel.com>
7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
9 * USB Printer Device Class driver for USB printers and printer cables
14 * v0.1 - thorough cleaning, URBification, almost a rewrite
15 * v0.2 - some more cleanups
16 * v0.3 - cleaner again, waitqueue fixes
17 * v0.4 - fixes in unidirectional mode
18 * v0.5 - add DEVICE_ID string support
19 * v0.6 - never time out
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #include <linux/module.h>
39 #include <linux/kernel.h>
40 #include <linux/sched.h>
41 #include <linux/smp_lock.h>
42 #include <linux/signal.h>
43 #include <linux/poll.h>
44 #include <linux/init.h>
45 #include <linux/malloc.h>
48 #include <linux/usb.h>
50 #define USBLP_BUF_SIZE 8192
51 #define DEVICE_ID_SIZE 1024
53 #define IOCNR_GET_DEVICE_ID 1
54 #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) /* get device_id string */
55 #define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */
58 * A DEVICE_ID string may include the printer's serial number.
59 * It should end with a semi-colon (';').
60 * An example from an HP 970C DeskJet printer is (this is one long string,
61 * with the serial number changed):
62 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: ;
66 * USB Printer Requests
69 #define USBLP_REQ_GET_ID 0x00
70 #define USBLP_REQ_GET_STATUS 0x01
71 #define USBLP_REQ_RESET 0x02
73 #define USBLP_MINORS 16
74 #define USBLP_MINOR_BASE 0
76 #define USBLP_WRITE_TIMEOUT (5*HZ) /* 5 seconds */
79 struct usb_device
*dev
; /* USB device */
80 struct urb readurb
, writeurb
; /* The urbs */
81 wait_queue_head_t wait
; /* Zzzzz ... */
82 int readcount
; /* Counter for reads */
83 int ifnum
; /* Interface number */
84 int minor
; /* minor number of device */
85 unsigned int quirks
; /* quirks flags */
86 unsigned char used
; /* True if open */
87 unsigned char bidir
; /* interface is bidirectional */
88 unsigned char *device_id_string
; /* IEEE 1284 DEVICE ID string (ptr) */
89 /* first 2 bytes are (big-endian) length */
92 static struct usblp
*usblp_table
[USBLP_MINORS
];
94 /* Quirks: various printer quirks are handled by this table & its flags. */
96 struct quirk_printer_struct
{
102 #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */
103 #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */
105 static struct quirk_printer_struct quirk_printers
[] = {
106 { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR
}, /* HP DeskJet 895C */
107 { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR
}, /* HP DeskJet 880C */
108 { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR
}, /* HP DeskJet 815C */
109 { 0x03f0, 0x0304, USBLP_QUIRK_BIDIR
}, /* HP DeskJet 810C/812C */
110 { 0x03f0, 0x0404, USBLP_QUIRK_BIDIR
}, /* HP DeskJet 830C */
115 * Functions for usblp control messages.
118 static int usblp_ctrl_msg(struct usblp
*usblp
, int request
, int dir
, int recip
, int value
, void *buf
, int len
)
120 int retval
= usb_control_msg(usblp
->dev
,
121 dir
? usb_rcvctrlpipe(usblp
->dev
, 0) : usb_sndctrlpipe(usblp
->dev
, 0),
122 request
, USB_TYPE_CLASS
| dir
| recip
, value
, usblp
->ifnum
, buf
, len
, HZ
* 5);
123 dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d",
124 request
, !!dir
, recip
, value
, len
, retval
);
125 return retval
< 0 ? retval
: 0;
128 #define usblp_read_status(usblp, status)\
129 usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
130 #define usblp_get_id(usblp, config, id, maxlen)\
131 usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
132 #define usblp_reset(usblp)\
133 usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
139 static void usblp_bulk(struct urb
*urb
)
141 struct usblp
*usblp
= urb
->context
;
143 if (!usblp
|| !usblp
->dev
|| !usblp
->used
)
147 warn("usblp%d: nonzero read/write bulk status received: %d",
148 usblp
->minor
, urb
->status
);
150 wake_up_interruptible(&usblp
->wait
);
154 * Get and print printer errors.
157 static char *usblp_messages
[] = { "ok", "out of paper", "off-line", "on fire" };
159 static int usblp_check_status(struct usblp
*usblp
, int err
)
161 unsigned char status
, newerr
= 0;
163 if (usblp_read_status(usblp
, &status
)) {
164 err("usblp%d: failed reading printer status", usblp
->minor
);
168 if (~status
& LP_PERRORP
) {
170 if (status
& LP_POUTPA
) newerr
= 1;
171 if (~status
& LP_PSELECD
) newerr
= 2;
175 info("usblp%d: %s", usblp
->minor
, usblp_messages
[newerr
]);
184 static int usblp_open(struct inode
*inode
, struct file
*file
)
186 int minor
= MINOR(inode
->i_rdev
) - USBLP_MINOR_BASE
;
190 if (minor
< 0 || minor
>= USBLP_MINORS
)
194 usblp
= usblp_table
[minor
];
197 if (!usblp
|| !usblp
->dev
)
205 * TODO: need to implement LP_ABORTOPEN + O_NONBLOCK as in drivers/char/lp.c ???
206 * This is #if 0-ed because we *don't* want to fail an open
207 * just because the printer is off-line.
210 if ((retval
= usblp_check_status(usblp
, 0))) {
211 retval
= retval
> 1 ? -EIO
: -ENOSPC
;
219 file
->private_data
= usblp
;
221 usblp
->writeurb
.transfer_buffer_length
= 0;
222 usblp
->writeurb
.status
= 0;
225 usblp
->readcount
= 0;
226 usblp
->readurb
.dev
= usblp
->dev
;
227 usb_submit_urb(&usblp
->readurb
);
234 static int usblp_release(struct inode
*inode
, struct file
*file
)
236 struct usblp
*usblp
= file
->private_data
;
242 usb_unlink_urb(&usblp
->readurb
);
243 usb_unlink_urb(&usblp
->writeurb
);
247 usblp_table
[usblp
->minor
] = NULL
;
248 kfree(usblp
->device_id_string
);
254 /* No kernel lock - fine */
255 static unsigned int usblp_poll(struct file
*file
, struct poll_table_struct
*wait
)
257 struct usblp
*usblp
= file
->private_data
;
258 poll_wait(file
, &usblp
->wait
, wait
);
259 return ((usblp
->bidir
|| usblp
->readurb
.status
== -EINPROGRESS
) ? 0 : POLLIN
| POLLRDNORM
)
260 | (usblp
->writeurb
.status
== -EINPROGRESS
? 0 : POLLOUT
| POLLWRNORM
);
263 static int usblp_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
265 struct usblp
*usblp
= file
->private_data
;
267 unsigned char status
;
269 if (_IOC_TYPE(cmd
) == 'P') /* new-style ioctl number */
271 switch (_IOC_NR(cmd
)) {
273 case IOCNR_GET_DEVICE_ID
: /* get the DEVICE_ID string */
274 if (_IOC_DIR(cmd
) != _IOC_READ
)
277 err
= usblp_get_id(usblp
, 0, usblp
->device_id_string
, DEVICE_ID_SIZE
- 1);
279 dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
281 usblp
->device_id_string
[0] = usblp
->device_id_string
[1] = '\0';
285 length
= (usblp
->device_id_string
[0] << 8) + usblp
->device_id_string
[1]; /* big-endian */
286 if (length
< DEVICE_ID_SIZE
)
287 usblp
->device_id_string
[length
] = '\0';
289 usblp
->device_id_string
[DEVICE_ID_SIZE
- 1] = '\0';
291 dbg ("usblp%d Device ID string [%d/max %d]='%s'",
292 usblp
->minor
, length
, _IOC_SIZE(cmd
), &usblp
->device_id_string
[2]);
294 if (length
> _IOC_SIZE(cmd
)) length
= _IOC_SIZE(cmd
); /* truncate */
296 if (copy_to_user((unsigned char *) arg
, usblp
->device_id_string
, (unsigned long) length
))
304 else /* old-style ioctl value */
308 if (usblp_read_status(usblp
, &status
)) {
309 err("usblp%d: failed reading printer status", usblp
->minor
);
312 if (copy_to_user ((unsigned char *)arg
, &status
, 1))
323 static ssize_t
usblp_write(struct file
*file
, const char *buffer
, size_t count
, loff_t
*ppos
)
325 struct usblp
*usblp
= file
->private_data
;
326 int timeout
, err
= 0, writecount
= 0;
328 while (writecount
< count
) {
330 if (usblp
->writeurb
.status
== -EINPROGRESS
) {
332 if (file
->f_flags
& O_NONBLOCK
)
335 timeout
= USBLP_WRITE_TIMEOUT
;
336 while (timeout
&& usblp
->writeurb
.status
== -EINPROGRESS
) {
338 if (signal_pending(current
))
339 return writecount
? writecount
: -EINTR
;
341 timeout
= interruptible_sleep_on_timeout(&usblp
->wait
, timeout
);
348 if (usblp
->writeurb
.status
) {
349 if (usblp
->quirks
& USBLP_QUIRK_BIDIR
) {
350 if (usblp
->writeurb
.status
!= -EINPROGRESS
)
351 err("usblp%d: error %d writing to printer",
352 usblp
->minor
, usblp
->writeurb
.status
);
353 err
= usblp
->writeurb
.status
;
357 err
= usblp_check_status(usblp
, err
);
362 writecount
+= usblp
->writeurb
.transfer_buffer_length
;
363 usblp
->writeurb
.transfer_buffer_length
= 0;
365 if (writecount
== count
)
368 usblp
->writeurb
.transfer_buffer_length
= (count
- writecount
) < USBLP_BUF_SIZE
?
369 (count
- writecount
) : USBLP_BUF_SIZE
;
371 if (copy_from_user(usblp
->writeurb
.transfer_buffer
, buffer
+ writecount
,
372 usblp
->writeurb
.transfer_buffer_length
)) return -EFAULT
;
374 usblp
->writeurb
.dev
= usblp
->dev
;
375 usb_submit_urb(&usblp
->writeurb
);
381 static ssize_t
usblp_read(struct file
*file
, char *buffer
, size_t count
, loff_t
*ppos
)
383 struct usblp
*usblp
= file
->private_data
;
388 if (usblp
->readurb
.status
== -EINPROGRESS
) {
390 if (file
->f_flags
& O_NONBLOCK
)
393 while (usblp
->readurb
.status
== -EINPROGRESS
) {
394 if (signal_pending(current
))
396 interruptible_sleep_on(&usblp
->wait
);
403 if (usblp
->readurb
.status
) {
404 err("usblp%d: error %d reading from printer",
405 usblp
->minor
, usblp
->readurb
.status
);
406 usblp
->readurb
.dev
= usblp
->dev
;
407 usb_submit_urb(&usblp
->readurb
);
411 count
= count
< usblp
->readurb
.actual_length
- usblp
->readcount
?
412 count
: usblp
->readurb
.actual_length
- usblp
->readcount
;
414 if (copy_to_user(buffer
, usblp
->readurb
.transfer_buffer
+ usblp
->readcount
, count
))
417 if ((usblp
->readcount
+= count
) == usblp
->readurb
.actual_length
) {
418 usblp
->readcount
= 0;
419 usblp
->readurb
.dev
= usblp
->dev
;
420 usb_submit_urb(&usblp
->readurb
);
427 * Checks for printers that have quirks, such as requiring unidirectional
428 * communication but reporting bidirectional; currently some HP printers
429 * have this flaw (HP 810, 880, 895, etc.), or needing an init string
430 * sent at each open (like some Epsons).
431 * Returns 1 if found, 0 if not found.
433 * HP recommended that we use the bidirectional interface but
434 * don't attempt any bulk IN transfers from the IN endpoint.
435 * Here's some more detail on the problem:
436 * The problem is not that it isn't bidirectional though. The problem
437 * is that if you request a device ID, or status information, while
438 * the buffers are full, the return data will end up in the print data
439 * buffer. For example if you make sure you never request the device ID
440 * while you are sending print data, and you don't try to query the
441 * printer status every couple of milliseconds, you will probably be OK.
443 static unsigned int usblp_quirks (__u16 vendor
, __u16 product
)
447 for (i
= 0; quirk_printers
[i
].vendorId
; i
++) {
448 if (vendor
== quirk_printers
[i
].vendorId
&&
449 product
== quirk_printers
[i
].productId
)
450 return quirk_printers
[i
].quirks
;
455 static void *usblp_probe(struct usb_device
*dev
, unsigned int ifnum
,
456 const struct usb_device_id
*id
)
458 struct usb_interface_descriptor
*interface
;
459 struct usb_endpoint_descriptor
*epread
, *epwrite
;
461 int minor
, i
, bidir
= 0, quirks
;
462 int alts
= dev
->actconfig
->interface
[ifnum
].act_altsetting
;
466 /* If a bidirectional interface exists, use it. */
467 for (i
= 0; i
< dev
->actconfig
->interface
[ifnum
].num_altsetting
; i
++) {
469 interface
= &dev
->actconfig
->interface
[ifnum
].altsetting
[i
];
471 if (interface
->bInterfaceClass
!= 7 || interface
->bInterfaceSubClass
!= 1 ||
472 interface
->bInterfaceProtocol
< 1 || interface
->bInterfaceProtocol
> 3 ||
473 (interface
->bInterfaceProtocol
> 1 && interface
->bNumEndpoints
< 2))
476 if (interface
->bInterfaceProtocol
> 1) {
483 interface
= &dev
->actconfig
->interface
[ifnum
].altsetting
[alts
];
484 if (usb_set_interface(dev
, ifnum
, alts
))
485 err("can't set desired altsetting %d on interface %d", alts
, ifnum
);
487 epwrite
= interface
->endpoint
+ 0;
488 epread
= bidir
? interface
->endpoint
+ 1 : NULL
;
490 if ((epwrite
->bEndpointAddress
& 0x80) == 0x80) {
491 if (interface
->bNumEndpoints
== 1)
493 epwrite
= interface
->endpoint
+ 1;
494 epread
= bidir
? interface
->endpoint
+ 0 : NULL
;
497 if ((epwrite
->bEndpointAddress
& 0x80) == 0x80)
500 if (bidir
&& (epread
->bEndpointAddress
& 0x80) != 0x80)
503 for (minor
= 0; minor
< USBLP_MINORS
&& usblp_table
[minor
]; minor
++);
504 if (usblp_table
[minor
]) {
505 err("no more free usblp devices");
509 if (!(usblp
= kmalloc(sizeof(struct usblp
), GFP_KERNEL
))) {
510 err("out of memory");
513 memset(usblp
, 0, sizeof(struct usblp
));
515 /* lookup quirks for this printer */
516 quirks
= usblp_quirks(dev
->descriptor
.idVendor
, dev
->descriptor
.idProduct
);
518 if (bidir
&& (quirks
& USBLP_QUIRK_BIDIR
)) {
521 info ("Disabling reads from problem bidirectional printer on usblp%d",
526 usblp
->ifnum
= ifnum
;
527 usblp
->minor
= minor
;
528 usblp
->bidir
= bidir
;
529 usblp
->quirks
= quirks
;
531 init_waitqueue_head(&usblp
->wait
);
533 if (!(buf
= kmalloc(USBLP_BUF_SIZE
* (bidir
? 2 : 1), GFP_KERNEL
))) {
534 err("out of memory");
539 if (!(usblp
->device_id_string
= kmalloc(DEVICE_ID_SIZE
, GFP_KERNEL
))) {
540 err("out of memory");
546 FILL_BULK_URB(&usblp
->writeurb
, dev
, usb_sndbulkpipe(dev
, epwrite
->bEndpointAddress
),
547 buf
, 0, usblp_bulk
, usblp
);
550 FILL_BULK_URB(&usblp
->readurb
, dev
, usb_rcvbulkpipe(dev
, epread
->bEndpointAddress
),
551 buf
+ USBLP_BUF_SIZE
, USBLP_BUF_SIZE
, usblp_bulk
, usblp
);
553 /* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
554 err
= usblp_get_id(usblp
, 0, usblp
->device_id_string
, DEVICE_ID_SIZE
- 1);
556 length
= (usblp
->device_id_string
[0] << 8) + usblp
->device_id_string
[1]; /* big-endian */
557 if (length
< DEVICE_ID_SIZE
)
558 usblp
->device_id_string
[length
] = '\0';
560 usblp
->device_id_string
[DEVICE_ID_SIZE
- 1] = '\0';
561 dbg ("usblp%d Device ID string [%d]=%s",
562 minor
, length
, &usblp
->device_id_string
[2]);
565 err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
567 usblp
->device_id_string
[0] = usblp
->device_id_string
[1] = '\0';
571 usblp_check_status(usblp
, 0);
574 info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
575 minor
, bidir
? "Bi" : "Uni", dev
->devnum
, ifnum
, alts
);
577 return usblp_table
[minor
] = usblp
;
580 static void usblp_disconnect(struct usb_device
*dev
, void *ptr
)
582 struct usblp
*usblp
= ptr
;
584 if (!usblp
|| !usblp
->dev
) {
585 err("disconnect on nonexisting interface");
591 usb_unlink_urb(&usblp
->writeurb
);
593 usb_unlink_urb(&usblp
->readurb
);
595 kfree(usblp
->writeurb
.transfer_buffer
);
597 if (usblp
->used
) return;
599 kfree(usblp
->device_id_string
);
601 usblp_table
[usblp
->minor
] = NULL
;
605 static struct file_operations usblp_fops
= {
612 release
: usblp_release
,
615 static struct usb_device_id usblp_ids
[] = {
616 { bInterfaceClass
: 7, bInterfaceSubClass
: 1, bInterfaceProtocol
: 1},
617 { bInterfaceClass
: 7, bInterfaceSubClass
: 1, bInterfaceProtocol
: 2},
618 { bInterfaceClass
: 7, bInterfaceSubClass
: 1, bInterfaceProtocol
: 3},
619 { } /* Terminating entry */
622 MODULE_DEVICE_TABLE (usb
, usblp_ids
);
624 static struct usb_driver usblp_driver
= {
627 disconnect
: usblp_disconnect
,
629 minor
: USBLP_MINOR_BASE
,
633 static int __init
usblp_init(void)
635 if (usb_register(&usblp_driver
))
640 static void __exit
usblp_exit(void)
642 usb_deregister(&usblp_driver
);
645 module_init(usblp_init
);
646 module_exit(usblp_exit
);
648 MODULE_AUTHOR("Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap");
649 MODULE_DESCRIPTION("USB Printer Device Class driver");