2 * printer.c Version 0.3
4 * Copyright (c) 1999 Michael Gee <michael@linuxspecific.com>
5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
6 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
8 * USB Printer Device Class driver for USB printers and printer cables
13 * v0.1 - thorough cleaning, URBification, almost a rewrite
14 * v0.2 - some more cleanups
15 * v0.3 - cleaner again, waitqueue fixes
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/sched.h>
37 #include <linux/signal.h>
38 #include <linux/poll.h>
39 #include <linux/init.h>
40 #include <linux/malloc.h>
47 #define USBLP_BUF_SIZE 8192
50 * USB Printer Requests
53 #define USBLP_REQ_GET_ID 0x00
54 #define USBLP_REQ_GET_STATUS 0x01
55 #define USBLP_REQ_RESET 0x02
57 #define USBLP_MINORS 16
58 #define USBLP_MINOR_BASE 0
60 #define USBLP_WRITE_TIMEOUT (60*HZ) /* 60 seconds */
63 struct usb_device
*dev
; /* USB device */
64 struct urb readurb
, writeurb
; /* The urbs */
65 wait_queue_head_t wait
; /* Zzzzz ... */
66 int readcount
; /* Counter for reads */
67 int ifnum
; /* Interface number */
68 int minor
; /* minor number of device */
69 unsigned char used
; /* True if open */
70 unsigned char bidir
; /* interface is bidirectional */
73 static struct usblp
*usblp_table
[USBLP_MINORS
] = { NULL
, /* ... */ };
76 * Functions for usblp control messages.
79 static int usblp_ctrl_msg(struct usblp
*usblp
, int request
, int dir
, int recip
, void *buf
, int len
)
81 int retval
= usb_control_msg(usblp
->dev
,
82 dir
? usb_rcvctrlpipe(usblp
->dev
, 0) : usb_sndctrlpipe(usblp
->dev
, 0),
83 request
, USB_TYPE_CLASS
| dir
| recip
, 0, usblp
->ifnum
, buf
, len
, HZ
* 5);
84 dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d len: %#x result: %d", request
, !!dir
, recip
, len
, retval
);
85 return retval
< 0 ? retval
: 0;
88 #define usblp_read_status(usblp, status)\
89 usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_DIR_IN, USB_RECIP_INTERFACE, status, 1)
90 #define usblp_get_id(usblp, id, maxlen)\
91 usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_DIR_IN, USB_RECIP_INTERFACE, id, maxlen)
92 #define usblp_reset(usblp)\
93 usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_DIR_OUT, USB_RECIP_OTHER, NULL, 0)
99 static void usblp_bulk(struct urb
*urb
)
101 struct usblp
*usblp
= urb
->context
;
103 if (!usblp
|| !usblp
->dev
|| !usblp
->used
)
107 warn("nonzero read bulk status received: %d", urb
->status
);
109 wake_up_interruptible(&usblp
->wait
);
113 * Get and print printer errors.
116 static int usblp_check_status(struct usblp
*usblp
)
118 unsigned char status
;
120 if (usblp_read_status(usblp
, &status
)) {
121 err("failed reading usblp status");
125 if (status
& LP_PERRORP
) {
127 if (status
& LP_POUTPA
) {
128 info("usblp%d: out of paper", usblp
->minor
);
131 if (~status
& LP_PSELECD
) {
132 info("usblp%d: off-line", usblp
->minor
);
135 if (~status
& LP_PERRORP
) {
136 info("usblp%d: on fire", usblp
->minor
);
148 static int usblp_open(struct inode
*inode
, struct file
*file
)
150 int minor
= MINOR(inode
->i_rdev
) - USBLP_MINOR_BASE
;
154 if (minor
< 0 || minor
>= USBLP_MINORS
)
157 usblp
= usblp_table
[minor
];
159 if (!usblp
|| !usblp
->dev
)
165 if ((retval
= usblp_check_status(usblp
)))
170 file
->private_data
= usblp
;
172 usblp
->writeurb
.transfer_buffer_length
= 0;
173 usblp
->writeurb
.status
= 0;
174 usblp
->readcount
= 0;
176 usb_submit_urb(&usblp
->readurb
);
180 static int usblp_release(struct inode
*inode
, struct file
*file
)
182 struct usblp
*usblp
= file
->private_data
;
188 usb_unlink_urb(&usblp
->readurb
);
189 usb_unlink_urb(&usblp
->writeurb
);
193 usblp_table
[usblp
->minor
] = NULL
;
199 static unsigned int usblp_poll(struct file
*file
, struct poll_table_struct
*wait
)
201 struct usblp
*usblp
= file
->private_data
;
202 poll_wait(file
, &usblp
->wait
, wait
);
203 return (usblp
->readurb
.status
== -EINPROGRESS
? 0 : POLLIN
| POLLRDNORM
)
204 | (usblp
->writeurb
.status
== -EINPROGRESS
? 0 : POLLOUT
| POLLWRNORM
);
207 static ssize_t
usblp_write(struct file
*file
, const char *buffer
, size_t count
, loff_t
*ppos
)
209 struct usblp
*usblp
= file
->private_data
;
210 int retval
, timeout
, writecount
= 0;
212 while (writecount
< count
) {
214 if (usblp
->writeurb
.status
== -EINPROGRESS
) {
216 if (file
->f_flags
& O_NONBLOCK
)
219 timeout
= USBLP_WRITE_TIMEOUT
;
220 while (timeout
&& usblp
->writeurb
.status
== -EINPROGRESS
) {
222 if (signal_pending(current
))
223 return writecount
? writecount
: -EINTR
;
225 timeout
= interruptible_sleep_on_timeout(&usblp
->wait
, timeout
);
229 if (usblp
->writeurb
.status
== -EINPROGRESS
) {
230 usb_unlink_urb(&usblp
->writeurb
);
231 err("usblp%d: timed out", usblp
->minor
);
238 if (!usblp
->writeurb
.status
) {
239 writecount
+= usblp
->writeurb
.transfer_buffer_length
;
240 usblp
->writeurb
.transfer_buffer_length
= 0;
242 if (!(retval
= usblp_check_status(usblp
))) {
243 err("usblp%d: error %d writing to printer",
244 usblp
->minor
, usblp
->writeurb
.status
);
251 if (writecount
== count
)
254 usblp
->writeurb
.transfer_buffer_length
= (count
- writecount
) < USBLP_BUF_SIZE
?
255 (count
- writecount
) : USBLP_BUF_SIZE
;
257 if (copy_from_user(usblp
->writeurb
.transfer_buffer
, buffer
+ writecount
,
258 usblp
->writeurb
.transfer_buffer_length
)) return -EFAULT
;
260 usb_submit_urb(&usblp
->writeurb
);
266 static ssize_t
usblp_read(struct file
*file
, char *buffer
, size_t count
, loff_t
*ppos
)
268 struct usblp
*usblp
= file
->private_data
;
273 if (usblp
->readurb
.status
== -EINPROGRESS
) {
275 if (file
->f_flags
& O_NONBLOCK
)
278 while (usblp
->readurb
.status
== -EINPROGRESS
) {
279 if (signal_pending(current
))
281 interruptible_sleep_on(&usblp
->wait
);
288 if (usblp
->readurb
.status
) {
289 err("usblp%d: error %d reading from printer",
290 usblp
->minor
, usblp
->readurb
.status
);
291 usb_submit_urb(&usblp
->readurb
);
295 count
= count
< usblp
->readurb
.actual_length
- usblp
->readcount
?
296 count
: usblp
->readurb
.actual_length
- usblp
->readcount
;
298 if (copy_to_user(buffer
, usblp
->readurb
.transfer_buffer
+ usblp
->readcount
, count
))
301 if ((usblp
->readcount
+= count
) == usblp
->readurb
.actual_length
)
302 usb_submit_urb(&usblp
->readurb
);
307 static void *usblp_probe(struct usb_device
*dev
, unsigned int ifnum
)
309 struct usb_interface_descriptor
*interface
;
310 struct usb_endpoint_descriptor
*epread
, *epwrite
;
312 int minor
, i
, alts
= -1, bidir
= 0;
316 for (i
= 0; i
< dev
->actconfig
->interface
[ifnum
].num_altsetting
; i
++) {
318 interface
= &dev
->actconfig
->interface
[ifnum
].altsetting
[i
];
320 if (interface
->bInterfaceClass
!= 7 || interface
->bInterfaceSubClass
!= 1 ||
321 (interface
->bInterfaceProtocol
!= 1 && interface
->bInterfaceProtocol
!= 2) ||
322 (interface
->bInterfaceProtocol
> interface
->bNumEndpoints
))
328 if (!bidir
&& interface
->bInterfaceProtocol
== 2) {
337 interface
= &dev
->actconfig
->interface
[ifnum
].altsetting
[alts
];
338 if (usb_set_interface(dev
, ifnum
, alts
))
339 err("can't set desired altsetting %d on interface %d", alts
, ifnum
);
341 epwrite
= interface
->endpoint
+ 0;
345 epread
= interface
->endpoint
+ 1;
346 if ((epread
->bEndpointAddress
& 0x80) != 0x80) {
347 epwrite
= interface
->endpoint
+ 1;
348 epread
= interface
->endpoint
+ 0;
350 if ((epread
->bEndpointAddress
& 0x80) != 0x80)
355 if ((epwrite
->bEndpointAddress
& 0x80) == 0x80)
358 for (minor
= 0; minor
< USBLP_MINORS
&& usblp_table
[minor
]; minor
++);
359 if (usblp_table
[minor
]) {
360 err("no more free usblp devices");
364 if (!(usblp
= kmalloc(sizeof(struct usblp
), GFP_KERNEL
))) {
365 err("out of memory");
368 memset(usblp
, 0, sizeof(struct usblp
));
371 usblp
->ifnum
= ifnum
;
372 usblp
->minor
= minor
;
373 usblp
->bidir
= bidir
;
375 init_waitqueue_head(&usblp
->wait
);
377 if (!(buf
= kmalloc(USBLP_BUF_SIZE
* (bidir
? 2 : 1), GFP_KERNEL
))) {
378 err("out of memory");
383 FILL_BULK_URB(&usblp
->writeurb
, dev
, usb_sndbulkpipe(dev
, epwrite
->bEndpointAddress
),
384 buf
, 0, usblp_bulk
, usblp
);
387 FILL_BULK_URB(&usblp
->readurb
, dev
, usb_rcvbulkpipe(dev
, epread
->bEndpointAddress
),
388 buf
+ USBLP_BUF_SIZE
, USBLP_BUF_SIZE
, usblp_bulk
, usblp
);
391 info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
392 minor
, bidir
? "Bi" : "Uni", dev
->devnum
, ifnum
, alts
);
394 return usblp_table
[minor
] = usblp
;
397 static void usblp_disconnect(struct usb_device
*dev
, void *ptr
)
399 struct usblp
*usblp
= ptr
;
401 if (!usblp
|| !usblp
->dev
) {
402 err("disconnect on nonexisting interface");
408 usb_unlink_urb(&usblp
->readurb
);
409 usb_unlink_urb(&usblp
->writeurb
);
411 kfree(usblp
->writeurb
.transfer_buffer
);
413 if (usblp
->used
) return;
415 usblp_table
[usblp
->minor
] = NULL
;
419 static struct file_operations usblp_fops
= {
423 release
: usblp_release
,
427 static struct usb_driver usblp_driver
= {
430 disconnect
: usblp_disconnect
,
432 minor
: USBLP_MINOR_BASE
435 static int __init
usblp_init(void)
437 if (usb_register(&usblp_driver
))
442 static void __exit
usblp_exit(void)
444 usb_deregister(&usblp_driver
);
447 module_init(usblp_init
);
448 module_exit(usblp_exit
);