File: /usr/src/linux/drivers/usb/printer.c
1 /*
2 * printer.c Version 0.8
3 *
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>
8 *
9 * USB Printer Device Class driver for USB printers and printer cables
10 *
11 * Sponsored by SuSE
12 *
13 * ChangeLog:
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
20 * v0.7 - fixed bulk-IN read and poll (David Paschal, paschal@rcsis.com)
21 * v0.8 - add devfs support
22 * v0.9 - fix unplug-while-open paths
23 */
24
25 /*
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
30 *
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
35 *
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 */
40
41 #include <linux/module.h>
42 #include <linux/kernel.h>
43 #include <linux/sched.h>
44 #include <linux/smp_lock.h>
45 #include <linux/signal.h>
46 #include <linux/poll.h>
47 #include <linux/init.h>
48 #include <linux/slab.h>
49 #include <linux/lp.h>
50 #include <linux/devfs_fs_kernel.h>
51 #undef DEBUG
52 #include <linux/usb.h>
53
54 /*
55 * Version Information
56 */
57 #define DRIVER_VERSION "v0.8"
58 #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap"
59 #define DRIVER_DESC "USB Printer Device Class driver"
60
61 #define USBLP_BUF_SIZE 8192
62 #define DEVICE_ID_SIZE 1024
63
64 #define IOCNR_GET_DEVICE_ID 1
65 #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) /* get device_id string */
66 #define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */
67
68 /*
69 * A DEVICE_ID string may include the printer's serial number.
70 * It should end with a semi-colon (';').
71 * An example from an HP 970C DeskJet printer is (this is one long string,
72 * with the serial number changed):
73 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: ;
74 */
75
76 /*
77 * USB Printer Requests
78 */
79
80 #define USBLP_REQ_GET_ID 0x00
81 #define USBLP_REQ_GET_STATUS 0x01
82 #define USBLP_REQ_RESET 0x02
83
84 #define USBLP_MINORS 16
85 #define USBLP_MINOR_BASE 0
86
87 #define USBLP_WRITE_TIMEOUT (5*HZ) /* 5 seconds */
88
89 struct usblp {
90 struct usb_device *dev; /* USB device */
91 devfs_handle_t devfs; /* devfs device */
92 struct semaphore sem; /* locks this struct, especially "dev" */
93 struct urb readurb, writeurb; /* The urbs */
94 wait_queue_head_t wait; /* Zzzzz ... */
95 int readcount; /* Counter for reads */
96 int ifnum; /* Interface number */
97 int minor; /* minor number of device */
98 unsigned int quirks; /* quirks flags */
99 unsigned char used; /* True if open */
100 unsigned char bidir; /* interface is bidirectional */
101 unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */
102 /* first 2 bytes are (big-endian) length */
103 };
104
105 extern devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
106
107 static struct usblp *usblp_table[USBLP_MINORS];
108
109 /* Quirks: various printer quirks are handled by this table & its flags. */
110
111 struct quirk_printer_struct {
112 __u16 vendorId;
113 __u16 productId;
114 unsigned int quirks;
115 };
116
117 #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */
118 #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */
119
120 static struct quirk_printer_struct quirk_printers[] = {
121 { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
122 { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
123 { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
124 { 0x03f0, 0x0304, USBLP_QUIRK_BIDIR }, /* HP DeskJet 810C/812C */
125 { 0x03f0, 0x0404, USBLP_QUIRK_BIDIR }, /* HP DeskJet 830C */
126 { 0, 0 }
127 };
128
129 /*
130 * Functions for usblp control messages.
131 */
132
133 static int usblp_ctrl_msg(struct usblp *usblp, int request, int dir, int recip, int value, void *buf, int len)
134 {
135 int retval = usb_control_msg(usblp->dev,
136 dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
137 request, USB_TYPE_CLASS | dir | recip, value, usblp->ifnum, buf, len, HZ * 5);
138 dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d",
139 request, !!dir, recip, value, len, retval);
140 return retval < 0 ? retval : 0;
141 }
142
143 #define usblp_read_status(usblp, status)\
144 usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
145 #define usblp_get_id(usblp, config, id, maxlen)\
146 usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
147 #define usblp_reset(usblp)\
148 usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
149
150 /*
151 * URB callback.
152 */
153
154 static void usblp_bulk(struct urb *urb)
155 {
156 struct usblp *usblp = urb->context;
157
158 if (!usblp || !usblp->dev || !usblp->used)
159 return;
160
161 if (urb->status)
162 warn("usblp%d: nonzero read/write bulk status received: %d",
163 usblp->minor, urb->status);
164
165 wake_up_interruptible(&usblp->wait);
166 }
167
168 /*
169 * Get and print printer errors.
170 */
171
172 static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
173
174 static int usblp_check_status(struct usblp *usblp, int err)
175 {
176 unsigned char status, newerr = 0;
177 int error;
178
179 error = usblp_read_status (usblp, &status);
180 if (error < 0) {
181 err("usblp%d: error %d reading printer status",
182 usblp->minor, error);
183 return 0;
184 }
185
186 if (~status & LP_PERRORP) {
187 newerr = 3;
188 if (status & LP_POUTPA) newerr = 1;
189 if (~status & LP_PSELECD) newerr = 2;
190 }
191
192 if (newerr != err)
193 info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
194
195 return newerr;
196 }
197
198 /*
199 * File op functions.
200 */
201
202 static int usblp_open(struct inode *inode, struct file *file)
203 {
204 int minor = MINOR(inode->i_rdev) - USBLP_MINOR_BASE;
205 struct usblp *usblp;
206 int retval;
207
208 if (minor < 0 || minor >= USBLP_MINORS)
209 return -ENODEV;
210
211 lock_kernel();
212 usblp = usblp_table[minor];
213
214 retval = -ENODEV;
215 if (!usblp || !usblp->dev)
216 goto out;
217
218 retval = -EBUSY;
219 if (usblp->used)
220 goto out;
221
222 /*
223 * TODO: need to implement LP_ABORTOPEN + O_NONBLOCK as in drivers/char/lp.c ???
224 * This is #if 0-ed because we *don't* want to fail an open
225 * just because the printer is off-line.
226 */
227 #if 0
228 if ((retval = usblp_check_status(usblp, 0))) {
229 retval = retval > 1 ? -EIO : -ENOSPC;
230 goto out;
231 }
232 #else
233 retval = 0;
234 #endif
235
236 usblp->used = 1;
237 file->private_data = usblp;
238
239 usblp->writeurb.transfer_buffer_length = 0;
240 usblp->writeurb.status = 0;
241
242 if (usblp->bidir) {
243 usblp->readcount = 0;
244 usblp->readurb.dev = usblp->dev;
245 if (usb_submit_urb(&usblp->readurb) < 0) {
246 retval = -EIO;
247 usblp->used = 0;
248 file->private_data = NULL;
249 }
250 }
251 out:
252 unlock_kernel();
253 return retval;
254 }
255
256 static void usblp_cleanup (struct usblp *usblp)
257 {
258 devfs_unregister (usblp->devfs);
259 usblp_table [usblp->minor] = NULL;
260 info ("usblp%d: removed", usblp->minor);
261
262 kfree (usblp->writeurb.transfer_buffer);
263 kfree (usblp->device_id_string);
264 kfree (usblp);
265 }
266
267 static int usblp_release(struct inode *inode, struct file *file)
268 {
269 struct usblp *usblp = file->private_data;
270
271 down (&usblp->sem);
272 lock_kernel();
273 usblp->used = 0;
274 if (usblp->dev) {
275 if (usblp->bidir)
276 usb_unlink_urb(&usblp->readurb);
277 usb_unlink_urb(&usblp->writeurb);
278 up(&usblp->sem);
279 } else /* finish cleanup from disconnect */
280 usblp_cleanup (usblp);
281 unlock_kernel();
282 return 0;
283 }
284
285 /* No kernel lock - fine */
286 static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait)
287 {
288 struct usblp *usblp = file->private_data;
289 poll_wait(file, &usblp->wait, wait);
290 return ((!usblp->bidir || usblp->readurb.status == -EINPROGRESS) ? 0 : POLLIN | POLLRDNORM)
291 | (usblp->writeurb.status == -EINPROGRESS ? 0 : POLLOUT | POLLWRNORM);
292 }
293
294 static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
295 {
296 struct usblp *usblp = file->private_data;
297 int length, err;
298 unsigned char status;
299 int retval = 0;
300
301 down (&usblp->sem);
302 if (!usblp->dev) {
303 retval = -ENODEV;
304 goto done;
305 }
306
307 if (_IOC_TYPE(cmd) == 'P') /* new-style ioctl number */
308
309 switch (_IOC_NR(cmd)) {
310
311 case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
312 if (_IOC_DIR(cmd) != _IOC_READ) {
313 retval = -EINVAL;
314 goto done;
315 }
316
317 err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
318 if (err < 0) {
319 dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
320 usblp->minor, err);
321 usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
322 retval = -EIO;
323 goto done;
324 }
325
326 length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
327 if (length < DEVICE_ID_SIZE)
328 usblp->device_id_string[length] = '\0';
329 else
330 usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
331
332 dbg ("usblp%d Device ID string [%d/max %d]='%s'",
333 usblp->minor, length, _IOC_SIZE(cmd), &usblp->device_id_string[2]);
334
335 if (length > _IOC_SIZE(cmd)) length = _IOC_SIZE(cmd); /* truncate */
336
337 if (copy_to_user((unsigned char *) arg,
338 usblp->device_id_string, (unsigned long) length)) {
339 retval = -EFAULT;
340 goto done;
341 }
342
343 break;
344
345 default:
346 retval = -EINVAL;
347 }
348 else /* old-style ioctl value */
349 switch (cmd) {
350
351 case LPGETSTATUS:
352 if (usblp_read_status(usblp, &status)) {
353 err("usblp%d: failed reading printer status", usblp->minor);
354 retval = -EIO;
355 goto done;
356 }
357 if (copy_to_user ((unsigned char *)arg, &status, 1))
358 retval = -EFAULT;
359 break;
360
361 default:
362 retval = -EINVAL;
363 }
364
365 done:
366 up (&usblp->sem);
367 return retval;
368 }
369
370 static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
371 {
372 struct usblp *usblp = file->private_data;
373 int timeout, err = 0, writecount = 0;
374
375 while (writecount < count) {
376
377 // FIXME: only use urb->status inside completion
378 // callbacks; this way is racey...
379 if (usblp->writeurb.status == -EINPROGRESS) {
380
381 if (file->f_flags & O_NONBLOCK)
382 return -EAGAIN;
383
384 timeout = USBLP_WRITE_TIMEOUT;
385 while (timeout && usblp->writeurb.status == -EINPROGRESS) {
386
387 if (signal_pending(current))
388 return writecount ? writecount : -EINTR;
389
390 timeout = interruptible_sleep_on_timeout(&usblp->wait, timeout);
391 }
392 }
393
394 down (&usblp->sem);
395 if (!usblp->dev) {
396 up (&usblp->sem);
397 return -ENODEV;
398 }
399
400 if (usblp->writeurb.status != 0) {
401 if (usblp->quirks & USBLP_QUIRK_BIDIR) {
402 if (usblp->writeurb.status != -EINPROGRESS)
403 err("usblp%d: error %d writing to printer",
404 usblp->minor, usblp->writeurb.status);
405 err = usblp->writeurb.status;
406 } else
407 err = usblp_check_status(usblp, err);
408 up (&usblp->sem);
409
410 /* if the fault was due to disconnect, let khubd's
411 * call to usblp_disconnect() grab usblp->sem ...
412 */
413 schedule ();
414 continue;
415 }
416
417 writecount += usblp->writeurb.transfer_buffer_length;
418 usblp->writeurb.transfer_buffer_length = 0;
419
420 if (writecount == count) {
421 up (&usblp->sem);
422 break;
423 }
424
425 usblp->writeurb.transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ?
426 (count - writecount) : USBLP_BUF_SIZE;
427
428 if (copy_from_user(usblp->writeurb.transfer_buffer, buffer + writecount,
429 usblp->writeurb.transfer_buffer_length)) return -EFAULT;
430
431 usblp->writeurb.dev = usblp->dev;
432 usb_submit_urb(&usblp->writeurb);
433 up (&usblp->sem);
434 }
435
436 return count;
437 }
438
439 static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
440 {
441 struct usblp *usblp = file->private_data;
442
443 if (!usblp->bidir)
444 return -EINVAL;
445
446 down (&usblp->sem);
447 if (!usblp->dev) {
448 count = -ENODEV;
449 goto done;
450 }
451
452 if (usblp->readurb.status == -EINPROGRESS) {
453
454 if (file->f_flags & O_NONBLOCK) {
455 count = -EAGAIN;
456 goto done;
457 }
458
459 // FIXME: only use urb->status inside completion
460 // callbacks; this way is racey...
461 while (usblp->readurb.status == -EINPROGRESS) {
462 if (signal_pending(current)) {
463 count = -EINTR;
464 goto done;
465 }
466 up (&usblp->sem);
467 interruptible_sleep_on(&usblp->wait);
468 down (&usblp->sem);
469 }
470 }
471
472 if (!usblp->dev) {
473 count = -ENODEV;
474 goto done;
475 }
476
477 if (usblp->readurb.status) {
478 err("usblp%d: error %d reading from printer",
479 usblp->minor, usblp->readurb.status);
480 usblp->readurb.dev = usblp->dev;
481 usblp->readcount = 0;
482 usb_submit_urb(&usblp->readurb);
483 count = -EIO;
484 goto done;
485 }
486
487 count = count < usblp->readurb.actual_length - usblp->readcount ?
488 count : usblp->readurb.actual_length - usblp->readcount;
489
490 if (copy_to_user(buffer, usblp->readurb.transfer_buffer + usblp->readcount, count)) {
491 count = -EFAULT;
492 goto done;
493 }
494
495 if ((usblp->readcount += count) == usblp->readurb.actual_length) {
496 usblp->readcount = 0;
497 usblp->readurb.dev = usblp->dev;
498 usb_submit_urb(&usblp->readurb);
499 }
500
501 done:
502 up (&usblp->sem);
503 return count;
504 }
505
506 /*
507 * Checks for printers that have quirks, such as requiring unidirectional
508 * communication but reporting bidirectional; currently some HP printers
509 * have this flaw (HP 810, 880, 895, etc.), or needing an init string
510 * sent at each open (like some Epsons).
511 * Returns 1 if found, 0 if not found.
512 *
513 * HP recommended that we use the bidirectional interface but
514 * don't attempt any bulk IN transfers from the IN endpoint.
515 * Here's some more detail on the problem:
516 * The problem is not that it isn't bidirectional though. The problem
517 * is that if you request a device ID, or status information, while
518 * the buffers are full, the return data will end up in the print data
519 * buffer. For example if you make sure you never request the device ID
520 * while you are sending print data, and you don't try to query the
521 * printer status every couple of milliseconds, you will probably be OK.
522 */
523 static unsigned int usblp_quirks (__u16 vendor, __u16 product)
524 {
525 int i;
526
527 for (i = 0; quirk_printers[i].vendorId; i++) {
528 if (vendor == quirk_printers[i].vendorId &&
529 product == quirk_printers[i].productId)
530 return quirk_printers[i].quirks;
531 }
532 return 0;
533 }
534
535 static struct file_operations usblp_fops = {
536 owner: THIS_MODULE,
537 read: usblp_read,
538 write: usblp_write,
539 poll: usblp_poll,
540 ioctl: usblp_ioctl,
541 open: usblp_open,
542 release: usblp_release,
543 };
544
545 static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
546 const struct usb_device_id *id)
547 {
548 struct usb_interface_descriptor *interface;
549 struct usb_endpoint_descriptor *epread, *epwrite;
550 struct usblp *usblp;
551 int minor, i, bidir = 0, quirks;
552 int alts = dev->actconfig->interface[ifnum].act_altsetting;
553 int length, err;
554 char *buf;
555 char name[6];
556
557 /* If a bidirectional interface exists, use it. */
558 for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) {
559
560 interface = &dev->actconfig->interface[ifnum].altsetting[i];
561
562 if (interface->bInterfaceClass != 7 || interface->bInterfaceSubClass != 1 ||
563 interface->bInterfaceProtocol < 1 || interface->bInterfaceProtocol > 3 ||
564 (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2))
565 continue;
566
567 if (interface->bInterfaceProtocol > 1) {
568 bidir = 1;
569 alts = i;
570 break;
571 }
572 }
573
574 interface = &dev->actconfig->interface[ifnum].altsetting[alts];
575 if (usb_set_interface(dev, ifnum, alts))
576 err("can't set desired altsetting %d on interface %d", alts, ifnum);
577
578 epwrite = interface->endpoint + 0;
579 epread = bidir ? interface->endpoint + 1 : NULL;
580
581 if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
582 if (interface->bNumEndpoints == 1)
583 return NULL;
584 epwrite = interface->endpoint + 1;
585 epread = bidir ? interface->endpoint + 0 : NULL;
586 }
587
588 if ((epwrite->bEndpointAddress & 0x80) == 0x80)
589 return NULL;
590
591 if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
592 return NULL;
593
594 for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
595 if (usblp_table[minor]) {
596 err("no more free usblp devices");
597 return NULL;
598 }
599
600 if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
601 err("out of memory");
602 return NULL;
603 }
604 memset(usblp, 0, sizeof(struct usblp));
605 init_MUTEX (&usblp->sem);
606
607 /* lookup quirks for this printer */
608 quirks = usblp_quirks(dev->descriptor.idVendor, dev->descriptor.idProduct);
609
610 if (bidir && (quirks & USBLP_QUIRK_BIDIR)) {
611 bidir = 0;
612 epread = NULL;
613 info ("Disabling reads from problem bidirectional printer on usblp%d",
614 minor);
615 }
616
617 usblp->dev = dev;
618 usblp->ifnum = ifnum;
619 usblp->minor = minor;
620 usblp->bidir = bidir;
621 usblp->quirks = quirks;
622
623 init_waitqueue_head(&usblp->wait);
624
625 if (!(buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))) {
626 err("out of memory");
627 kfree(usblp);
628 return NULL;
629 }
630
631 if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
632 err("out of memory");
633 kfree(usblp);
634 kfree(buf);
635 return NULL;
636 }
637
638 FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
639 buf, 0, usblp_bulk, usblp);
640
641 if (bidir)
642 FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
643 buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);
644
645 /* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
646 err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
647 if (err >= 0) {
648 length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
649 if (length < DEVICE_ID_SIZE)
650 usblp->device_id_string[length] = '\0';
651 else
652 usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
653 dbg ("usblp%d Device ID string [%d]=%s",
654 minor, length, &usblp->device_id_string[2]);
655 }
656 else {
657 err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
658 minor, err);
659 usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
660 }
661
662 #ifdef DEBUG
663 usblp_check_status(usblp, 0);
664 #endif
665
666 sprintf(name, "lp%d", minor);
667
668 /* if we have devfs, create with perms=660 */
669 usblp->devfs = devfs_register(usb_devfs_handle, name,
670 DEVFS_FL_DEFAULT, USB_MAJOR,
671 USBLP_MINOR_BASE + minor,
672 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
673 S_IWGRP, &usblp_fops, NULL);
674
675 info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
676 minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);
677
678 return usblp_table[minor] = usblp;
679 }
680
681 static void usblp_disconnect(struct usb_device *dev, void *ptr)
682 {
683 struct usblp *usblp = ptr;
684
685 if (!usblp || !usblp->dev) {
686 err("bogus disconnect");
687 BUG ();
688 }
689
690 down (&usblp->sem);
691 lock_kernel();
692 usblp->dev = NULL;
693
694 usb_unlink_urb(&usblp->writeurb);
695 if (usblp->bidir)
696 usb_unlink_urb(&usblp->readurb);
697
698 if (!usblp->used)
699 usblp_cleanup (usblp);
700 else /* cleanup later, on close */
701 up (&usblp->sem);
702 unlock_kernel();
703 }
704
705 static struct usb_device_id usblp_ids [] = {
706 { USB_INTERFACE_INFO(7, 1, 1) },
707 { USB_INTERFACE_INFO(7, 1, 2) },
708 { USB_INTERFACE_INFO(7, 1, 3) },
709 { } /* Terminating entry */
710 };
711
712 MODULE_DEVICE_TABLE (usb, usblp_ids);
713
714 static struct usb_driver usblp_driver = {
715 name: "usblp",
716 probe: usblp_probe,
717 disconnect: usblp_disconnect,
718 fops: &usblp_fops,
719 minor: USBLP_MINOR_BASE,
720 id_table: usblp_ids,
721 };
722
723 static int __init usblp_init(void)
724 {
725 if (usb_register(&usblp_driver))
726 return -1;
727 info(DRIVER_VERSION ":" DRIVER_DESC);
728 return 0;
729 }
730
731 static void __exit usblp_exit(void)
732 {
733 usb_deregister(&usblp_driver);
734 }
735
736 module_init(usblp_init);
737 module_exit(usblp_exit);
738
739 MODULE_AUTHOR( DRIVER_AUTHOR );
740 MODULE_DESCRIPTION( DRIVER_DESC );
741
742