Merge with 2.3.48.
[linux-2.6/linux-mips.git] / drivers / usb / printer.c
blob182915a194b7dd794313d0d95a53feba3b204620
1 /*
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
10 * Sponsored by SuSE
12 * ChangeLog:
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>
41 #include <linux/lp.h>
43 #define DEBUG
45 #include "usb.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 */
62 struct usblp {
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)
96 * URB callback.
99 static void usblp_bulk(struct urb *urb)
101 struct usblp *usblp = urb->context;
103 if (!usblp || !usblp->dev || !usblp->used)
104 return;
106 if (urb->status)
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");
122 return -EIO;
125 if (status & LP_PERRORP) {
127 if (status & LP_POUTPA) {
128 info("usblp%d: out of paper", usblp->minor);
129 return -ENOSPC;
131 if (~status & LP_PSELECD) {
132 info("usblp%d: off-line", usblp->minor);
133 return -EIO;
135 if (~status & LP_PERRORP) {
136 info("usblp%d: on fire", usblp->minor);
137 return -EIO;
141 return 0;
145 * File op functions.
148 static int usblp_open(struct inode *inode, struct file *file)
150 int minor = MINOR(inode->i_rdev) - USBLP_MINOR_BASE;
151 struct usblp *usblp;
152 int retval;
154 if (minor < 0 || minor >= USBLP_MINORS)
155 return -ENODEV;
157 usblp = usblp_table[minor];
159 if (!usblp || !usblp->dev)
160 return -ENODEV;
162 if (usblp->used)
163 return -EBUSY;
165 if ((retval = usblp_check_status(usblp)))
166 return retval;
168 MOD_INC_USE_COUNT;
169 usblp->used = 1;
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);
177 return 0;
180 static int usblp_release(struct inode *inode, struct file *file)
182 struct usblp *usblp = file->private_data;
184 MOD_DEC_USE_COUNT;
185 usblp->used = 0;
187 if (usblp->dev) {
188 usb_unlink_urb(&usblp->readurb);
189 usb_unlink_urb(&usblp->writeurb);
190 return 0;
193 usblp_table[usblp->minor] = NULL;
194 kfree(usblp);
196 return 0;
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)
217 return -EAGAIN;
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);
232 return -EIO;
235 if (!usblp->dev)
236 return -ENODEV;
238 if (!usblp->writeurb.status) {
239 writecount += usblp->writeurb.transfer_buffer_length;
240 usblp->writeurb.transfer_buffer_length = 0;
241 } else {
242 if (!(retval = usblp_check_status(usblp))) {
243 err("usblp%d: error %d writing to printer",
244 usblp->minor, usblp->writeurb.status);
245 return -EIO;
248 return retval;
251 if (writecount == count)
252 continue;
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);
263 return count;
266 static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
268 struct usblp *usblp = file->private_data;
270 if (!usblp->bidir)
271 return -EINVAL;
273 if (usblp->readurb.status == -EINPROGRESS) {
275 if (file->f_flags & O_NONBLOCK)
276 return -EAGAIN;
278 while (usblp->readurb.status == -EINPROGRESS) {
279 if (signal_pending(current))
280 return -EINTR;
281 interruptible_sleep_on(&usblp->wait);
285 if (!usblp->dev)
286 return -ENODEV;
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);
292 return -EIO;
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))
299 return -EFAULT;
301 if ((usblp->readcount += count) == usblp->readurb.actual_length)
302 usb_submit_urb(&usblp->readurb);
304 return count;
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;
311 struct usblp *usblp;
312 int minor, i, alts = -1, bidir = 0;
313 char *buf;
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))
323 continue;
325 if (alts == -1)
326 alts = i;
328 if (!bidir && interface->bInterfaceProtocol == 2) {
329 bidir = 1;
330 alts = i;
334 if (alts == -1)
335 return NULL;
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;
342 epread = NULL;
344 if (bidir) {
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)
351 return NULL;
355 if ((epwrite->bEndpointAddress & 0x80) == 0x80)
356 return NULL;
358 for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
359 if (usblp_table[minor]) {
360 err("no more free usblp devices");
361 return NULL;
364 if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
365 err("out of memory");
366 return NULL;
368 memset(usblp, 0, sizeof(struct usblp));
370 usblp->dev = dev;
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");
379 kfree(usblp);
380 return NULL;
383 FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
384 buf, 0, usblp_bulk, usblp);
386 if (bidir) {
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");
403 return;
406 usblp->dev = NULL;
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;
416 kfree(usblp);
419 static struct file_operations usblp_fops = {
420 read: usblp_read,
421 write: usblp_write,
422 open: usblp_open,
423 release: usblp_release,
424 poll: usblp_poll,
427 static struct usb_driver usblp_driver = {
428 name: "usblp",
429 probe: usblp_probe,
430 disconnect: usblp_disconnect,
431 fops: &usblp_fops,
432 minor: USBLP_MINOR_BASE
435 static int __init usblp_init(void)
437 if (usb_register(&usblp_driver))
438 return -1;
439 return 0;
442 static void __exit usblp_exit(void)
444 usb_deregister(&usblp_driver);
447 module_init(usblp_init);
448 module_exit(usblp_exit);