diff options
author | Pete Zaitcev <zaitcev@redhat.com> | 2007-06-21 15:44:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:34:39 -0400 |
commit | 317c67b8f7092db325a3df825646eb26982908c6 (patch) | |
tree | b1a9eae5c68048ee230df120b07b9f843b6497dd /drivers/usb/class | |
parent | 73e4fb3f70987b36fd0f16b5f762b2018ab84e4f (diff) |
USB: usblp: add dynamic URBs, fix races
This patch's main bulk aims to make usblp the premier driver for code
pillaging once again. The code is as streamlined as possible and is bug-free
as possible. The usb-skeleton performs the same function, but is somewhat
abstract. The usblp is usb-skeleton which is actually used by many.
Since I combed a few small bugs away, this also fixes the small races we
had in usblp for a while. For example, now it's possible for several threads
to make write(2) calls (sounds silly, but consider a printer for paper
record, where every line of text is self-contained and thus it's all right
to have them interleaved). Also gone are issues with interrupts using
barriers dangerously.
This patch makes use of Oliver's anchor, and so it must trail the anchor
patch on the way to Linus.
Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/class')
-rw-r--r-- | drivers/usb/class/usblp.c | 618 |
1 files changed, 376 insertions, 242 deletions
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 6778f9af7943..9a1478972bf5 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * usblp.c Version 0.13 | 2 | * usblp.c |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Michael Gee <michael@linuxspecific.com> | 4 | * Copyright (c) 1999 Michael Gee <michael@linuxspecific.com> |
5 | * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> | 5 | * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> |
@@ -61,11 +61,11 @@ | |||
61 | /* | 61 | /* |
62 | * Version Information | 62 | * Version Information |
63 | */ | 63 | */ |
64 | #define DRIVER_VERSION "v0.13" | ||
65 | #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal" | 64 | #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal" |
66 | #define DRIVER_DESC "USB Printer Device Class driver" | 65 | #define DRIVER_DESC "USB Printer Device Class driver" |
67 | 66 | ||
68 | #define USBLP_BUF_SIZE 8192 | 67 | #define USBLP_BUF_SIZE 8192 |
68 | #define USBLP_BUF_SIZE_IN 1024 | ||
69 | #define USBLP_DEVICE_ID_SIZE 1024 | 69 | #define USBLP_DEVICE_ID_SIZE 1024 |
70 | 70 | ||
71 | /* ioctls: */ | 71 | /* ioctls: */ |
@@ -127,14 +127,22 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H | |||
127 | */ | 127 | */ |
128 | #define STATUS_BUF_SIZE 8 | 128 | #define STATUS_BUF_SIZE 8 |
129 | 129 | ||
130 | /* | ||
131 | * Locks down the locking order: | ||
132 | * ->wmut locks wstatus. | ||
133 | * ->mut locks the whole usblp, except [rw]complete, and thus, by indirection, | ||
134 | * [rw]status. We only touch status when we know the side idle. | ||
135 | * ->lock locks what interrupt accesses. | ||
136 | */ | ||
130 | struct usblp { | 137 | struct usblp { |
131 | struct usb_device *dev; /* USB device */ | 138 | struct usb_device *dev; /* USB device */ |
132 | struct mutex mut; /* locks this struct, especially "dev" */ | 139 | struct mutex wmut; |
133 | char *writebuf; /* write transfer_buffer */ | 140 | struct mutex mut; |
141 | spinlock_t lock; /* locks rcomplete, wcomplete */ | ||
134 | char *readbuf; /* read transfer_buffer */ | 142 | char *readbuf; /* read transfer_buffer */ |
135 | char *statusbuf; /* status transfer_buffer */ | 143 | char *statusbuf; /* status transfer_buffer */ |
136 | struct urb *readurb, *writeurb; /* The urbs */ | 144 | struct usb_anchor urbs; |
137 | wait_queue_head_t wait; /* Zzzzz ... */ | 145 | wait_queue_head_t rwait, wwait; |
138 | int readcount; /* Counter for reads */ | 146 | int readcount; /* Counter for reads */ |
139 | int ifnum; /* Interface number */ | 147 | int ifnum; /* Interface number */ |
140 | struct usb_interface *intf; /* The interface */ | 148 | struct usb_interface *intf; /* The interface */ |
@@ -147,8 +155,9 @@ struct usblp { | |||
147 | } protocol[USBLP_MAX_PROTOCOLS]; | 155 | } protocol[USBLP_MAX_PROTOCOLS]; |
148 | int current_protocol; | 156 | int current_protocol; |
149 | int minor; /* minor number of device */ | 157 | int minor; /* minor number of device */ |
150 | int wcomplete; /* writing is completed */ | 158 | int wcomplete, rcomplete; |
151 | int rcomplete; /* reading is completed */ | 159 | int wstatus; /* bytes written or error */ |
160 | int rstatus; /* bytes ready or error */ | ||
152 | unsigned int quirks; /* quirks flags */ | 161 | unsigned int quirks; /* quirks flags */ |
153 | unsigned char used; /* True if open */ | 162 | unsigned char used; /* True if open */ |
154 | unsigned char present; /* True if not disconnected */ | 163 | unsigned char present; /* True if not disconnected */ |
@@ -166,9 +175,6 @@ static void usblp_dump(struct usblp *usblp) { | |||
166 | dbg("dev=0x%p", usblp->dev); | 175 | dbg("dev=0x%p", usblp->dev); |
167 | dbg("present=%d", usblp->present); | 176 | dbg("present=%d", usblp->present); |
168 | dbg("readbuf=0x%p", usblp->readbuf); | 177 | dbg("readbuf=0x%p", usblp->readbuf); |
169 | dbg("writebuf=0x%p", usblp->writebuf); | ||
170 | dbg("readurb=0x%p", usblp->readurb); | ||
171 | dbg("writeurb=0x%p", usblp->writeurb); | ||
172 | dbg("readcount=%d", usblp->readcount); | 178 | dbg("readcount=%d", usblp->readcount); |
173 | dbg("ifnum=%d", usblp->ifnum); | 179 | dbg("ifnum=%d", usblp->ifnum); |
174 | for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) { | 180 | for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) { |
@@ -178,8 +184,8 @@ static void usblp_dump(struct usblp *usblp) { | |||
178 | } | 184 | } |
179 | dbg("current_protocol=%d", usblp->current_protocol); | 185 | dbg("current_protocol=%d", usblp->current_protocol); |
180 | dbg("minor=%d", usblp->minor); | 186 | dbg("minor=%d", usblp->minor); |
181 | dbg("wcomplete=%d", usblp->wcomplete); | 187 | dbg("wstatus=%d", usblp->wstatus); |
182 | dbg("rcomplete=%d", usblp->rcomplete); | 188 | dbg("rstatus=%d", usblp->rstatus); |
183 | dbg("quirks=%d", usblp->quirks); | 189 | dbg("quirks=%d", usblp->quirks); |
184 | dbg("used=%d", usblp->used); | 190 | dbg("used=%d", usblp->used); |
185 | dbg("bidir=%d", usblp->bidir); | 191 | dbg("bidir=%d", usblp->bidir); |
@@ -222,6 +228,11 @@ static const struct quirk_printer_struct quirk_printers[] = { | |||
222 | { 0, 0 } | 228 | { 0, 0 } |
223 | }; | 229 | }; |
224 | 230 | ||
231 | static int usblp_wwait(struct usblp *usblp, int nonblock); | ||
232 | static int usblp_wtest(struct usblp *usblp, int nonblock); | ||
233 | static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock); | ||
234 | static int usblp_rtest(struct usblp *usblp, int nonblock); | ||
235 | static int usblp_submit_read(struct usblp *usblp); | ||
225 | static int usblp_select_alts(struct usblp *usblp); | 236 | static int usblp_select_alts(struct usblp *usblp); |
226 | static int usblp_set_protocol(struct usblp *usblp, int protocol); | 237 | static int usblp_set_protocol(struct usblp *usblp, int protocol); |
227 | static int usblp_cache_device_id_string(struct usblp *usblp); | 238 | static int usblp_cache_device_id_string(struct usblp *usblp); |
@@ -279,33 +290,47 @@ static void usblp_bulk_read(struct urb *urb) | |||
279 | { | 290 | { |
280 | struct usblp *usblp = urb->context; | 291 | struct usblp *usblp = urb->context; |
281 | 292 | ||
282 | if (unlikely(!usblp || !usblp->dev || !usblp->used)) | 293 | if (usblp->present && usblp->used) { |
283 | return; | 294 | if (urb->status) |
284 | 295 | printk(KERN_WARNING "usblp%d: " | |
285 | if (unlikely(!usblp->present)) | 296 | "nonzero read bulk status received: %d\n", |
286 | goto unplug; | 297 | usblp->minor, urb->status); |
287 | if (unlikely(urb->status)) | 298 | } |
288 | warn("usblp%d: nonzero read/write bulk status received: %d", | 299 | spin_lock(&usblp->lock); |
289 | usblp->minor, urb->status); | 300 | if (urb->status < 0) |
301 | usblp->rstatus = urb->status; | ||
302 | else | ||
303 | usblp->rstatus = urb->actual_length; | ||
290 | usblp->rcomplete = 1; | 304 | usblp->rcomplete = 1; |
291 | unplug: | 305 | wake_up(&usblp->rwait); |
292 | wake_up_interruptible(&usblp->wait); | 306 | spin_unlock(&usblp->lock); |
307 | |||
308 | usb_free_urb(urb); | ||
293 | } | 309 | } |
294 | 310 | ||
295 | static void usblp_bulk_write(struct urb *urb) | 311 | static void usblp_bulk_write(struct urb *urb) |
296 | { | 312 | { |
297 | struct usblp *usblp = urb->context; | 313 | struct usblp *usblp = urb->context; |
298 | 314 | ||
299 | if (unlikely(!usblp || !usblp->dev || !usblp->used)) | 315 | if (usblp->present && usblp->used) { |
300 | return; | 316 | if (urb->status) |
301 | if (unlikely(!usblp->present)) | 317 | printk(KERN_WARNING "usblp%d: " |
302 | goto unplug; | 318 | "nonzero write bulk status received: %d\n", |
303 | if (unlikely(urb->status)) | 319 | usblp->minor, urb->status); |
304 | warn("usblp%d: nonzero read/write bulk status received: %d", | 320 | } |
305 | usblp->minor, urb->status); | 321 | spin_lock(&usblp->lock); |
322 | if (urb->status < 0) | ||
323 | usblp->wstatus = urb->status; | ||
324 | else | ||
325 | usblp->wstatus = urb->actual_length; | ||
306 | usblp->wcomplete = 1; | 326 | usblp->wcomplete = 1; |
307 | unplug: | 327 | wake_up(&usblp->wwait); |
308 | wake_up_interruptible(&usblp->wait); | 328 | spin_unlock(&usblp->lock); |
329 | |||
330 | /* XXX Use usb_setup_bulk_urb when available. Talk to Marcel. */ | ||
331 | kfree(urb->transfer_buffer); | ||
332 | urb->transfer_buffer = NULL; /* Not refcounted, so to be safe... */ | ||
333 | usb_free_urb(urb); | ||
309 | } | 334 | } |
310 | 335 | ||
311 | /* | 336 | /* |
@@ -322,7 +347,8 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
322 | error = usblp_read_status (usblp, usblp->statusbuf); | 347 | error = usblp_read_status (usblp, usblp->statusbuf); |
323 | if (error < 0) { | 348 | if (error < 0) { |
324 | if (printk_ratelimit()) | 349 | if (printk_ratelimit()) |
325 | err("usblp%d: error %d reading printer status", | 350 | printk(KERN_ERR |
351 | "usblp%d: error %d reading printer status\n", | ||
326 | usblp->minor, error); | 352 | usblp->minor, error); |
327 | return 0; | 353 | return 0; |
328 | } | 354 | } |
@@ -336,8 +362,10 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
336 | if (~status & LP_PSELECD) | 362 | if (~status & LP_PSELECD) |
337 | newerr = 2; | 363 | newerr = 2; |
338 | 364 | ||
339 | if (newerr != err) | 365 | if (newerr != err) { |
340 | info("usblp%d: %s", usblp->minor, usblp_messages[newerr]); | 366 | printk(KERN_INFO "usblp%d: %s\n", |
367 | usblp->minor, usblp_messages[newerr]); | ||
368 | } | ||
341 | 369 | ||
342 | return newerr; | 370 | return newerr; |
343 | } | 371 | } |
@@ -345,12 +373,9 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
345 | static int handle_bidir (struct usblp *usblp) | 373 | static int handle_bidir (struct usblp *usblp) |
346 | { | 374 | { |
347 | if (usblp->bidir && usblp->used && !usblp->sleeping) { | 375 | if (usblp->bidir && usblp->used && !usblp->sleeping) { |
348 | usblp->readcount = 0; | 376 | if (usblp_submit_read(usblp) < 0) |
349 | usblp->readurb->dev = usblp->dev; | ||
350 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) | ||
351 | return -EIO; | 377 | return -EIO; |
352 | } | 378 | } |
353 | |||
354 | return 0; | 379 | return 0; |
355 | } | 380 | } |
356 | 381 | ||
@@ -403,11 +428,9 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
403 | usblp->used = 1; | 428 | usblp->used = 1; |
404 | file->private_data = usblp; | 429 | file->private_data = usblp; |
405 | 430 | ||
406 | usblp->writeurb->transfer_buffer_length = 0; | ||
407 | usblp->wcomplete = 1; /* we begin writeable */ | 431 | usblp->wcomplete = 1; /* we begin writeable */ |
432 | usblp->wstatus = 0; | ||
408 | usblp->rcomplete = 0; | 433 | usblp->rcomplete = 0; |
409 | usblp->writeurb->status = 0; | ||
410 | usblp->readurb->status = 0; | ||
411 | 434 | ||
412 | if (handle_bidir(usblp) < 0) { | 435 | if (handle_bidir(usblp) < 0) { |
413 | usblp->used = 0; | 436 | usblp->used = 0; |
@@ -421,20 +444,17 @@ out: | |||
421 | 444 | ||
422 | static void usblp_cleanup (struct usblp *usblp) | 445 | static void usblp_cleanup (struct usblp *usblp) |
423 | { | 446 | { |
424 | info("usblp%d: removed", usblp->minor); | 447 | printk(KERN_INFO "usblp%d: removed\n", usblp->minor); |
425 | 448 | ||
449 | kfree(usblp->readbuf); | ||
426 | kfree (usblp->device_id_string); | 450 | kfree (usblp->device_id_string); |
427 | kfree (usblp->statusbuf); | 451 | kfree (usblp->statusbuf); |
428 | usb_free_urb(usblp->writeurb); | ||
429 | usb_free_urb(usblp->readurb); | ||
430 | kfree (usblp); | 452 | kfree (usblp); |
431 | } | 453 | } |
432 | 454 | ||
433 | static void usblp_unlink_urbs(struct usblp *usblp) | 455 | static void usblp_unlink_urbs(struct usblp *usblp) |
434 | { | 456 | { |
435 | usb_kill_urb(usblp->writeurb); | 457 | usb_kill_anchored_urbs(&usblp->urbs); |
436 | if (usblp->bidir) | ||
437 | usb_kill_urb(usblp->readurb); | ||
438 | } | 458 | } |
439 | 459 | ||
440 | static int usblp_release(struct inode *inode, struct file *file) | 460 | static int usblp_release(struct inode *inode, struct file *file) |
@@ -455,10 +475,18 @@ static int usblp_release(struct inode *inode, struct file *file) | |||
455 | /* No kernel lock - fine */ | 475 | /* No kernel lock - fine */ |
456 | static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait) | 476 | static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait) |
457 | { | 477 | { |
478 | int ret; | ||
479 | unsigned long flags; | ||
480 | |||
458 | struct usblp *usblp = file->private_data; | 481 | struct usblp *usblp = file->private_data; |
459 | poll_wait(file, &usblp->wait, wait); | 482 | /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */ |
460 | return ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM) | 483 | poll_wait(file, &usblp->rwait, wait); |
484 | poll_wait(file, &usblp->wwait, wait); | ||
485 | spin_lock_irqsave(&usblp->lock, flags); | ||
486 | ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM) | ||
461 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); | 487 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); |
488 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
489 | return ret; | ||
462 | } | 490 | } |
463 | 491 | ||
464 | static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 492 | static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
@@ -632,10 +660,11 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
632 | switch (cmd) { | 660 | switch (cmd) { |
633 | 661 | ||
634 | case LPGETSTATUS: | 662 | case LPGETSTATUS: |
635 | if (usblp_read_status(usblp, usblp->statusbuf)) { | 663 | if ((retval = usblp_read_status(usblp, usblp->statusbuf))) { |
636 | if (printk_ratelimit()) | 664 | if (printk_ratelimit()) |
637 | err("usblp%d: failed reading printer status", | 665 | printk(KERN_ERR "usblp%d:" |
638 | usblp->minor); | 666 | "failed reading printer status (%d)\n", |
667 | usblp->minor, retval); | ||
639 | retval = -EIO; | 668 | retval = -EIO; |
640 | goto done; | 669 | goto done; |
641 | } | 670 | } |
@@ -656,168 +685,303 @@ done: | |||
656 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 685 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
657 | { | 686 | { |
658 | struct usblp *usblp = file->private_data; | 687 | struct usblp *usblp = file->private_data; |
659 | int timeout, intr, rv, err = 0, transfer_length = 0; | 688 | char *writebuf; |
660 | size_t writecount = 0; | 689 | struct urb *writeurb; |
690 | int rv; | ||
691 | int transfer_length; | ||
692 | ssize_t writecount = 0; | ||
693 | |||
694 | if (mutex_lock_interruptible(&usblp->wmut)) { | ||
695 | rv = -EINTR; | ||
696 | goto raise_biglock; | ||
697 | } | ||
698 | if ((rv = usblp_wwait(usblp, !!(file->f_flags & O_NONBLOCK))) < 0) | ||
699 | goto raise_wait; | ||
661 | 700 | ||
662 | while (writecount < count) { | 701 | while (writecount < count) { |
663 | if (!usblp->wcomplete) { | 702 | /* |
664 | barrier(); | 703 | * Step 1: Submit next block. |
665 | if (file->f_flags & O_NONBLOCK) { | ||
666 | writecount += transfer_length; | ||
667 | return writecount ? writecount : -EAGAIN; | ||
668 | } | ||
669 | |||
670 | timeout = USBLP_WRITE_TIMEOUT; | ||
671 | |||
672 | rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout); | ||
673 | if (rv < 0) | ||
674 | return writecount ? writecount : -EINTR; | ||
675 | } | ||
676 | intr = mutex_lock_interruptible (&usblp->mut); | ||
677 | if (intr) | ||
678 | return writecount ? writecount : -EINTR; | ||
679 | if (!usblp->present) { | ||
680 | mutex_unlock (&usblp->mut); | ||
681 | return -ENODEV; | ||
682 | } | ||
683 | |||
684 | if (usblp->sleeping) { | ||
685 | mutex_unlock (&usblp->mut); | ||
686 | return writecount ? writecount : -ENODEV; | ||
687 | } | ||
688 | |||
689 | if (usblp->writeurb->status != 0) { | ||
690 | if (usblp->quirks & USBLP_QUIRK_BIDIR) { | ||
691 | if (!usblp->wcomplete) | ||
692 | err("usblp%d: error %d writing to printer", | ||
693 | usblp->minor, usblp->writeurb->status); | ||
694 | err = usblp->writeurb->status; | ||
695 | } else | ||
696 | err = usblp_check_status(usblp, err); | ||
697 | mutex_unlock (&usblp->mut); | ||
698 | |||
699 | /* if the fault was due to disconnect, let khubd's | ||
700 | * call to usblp_disconnect() grab usblp->mut ... | ||
701 | */ | ||
702 | schedule (); | ||
703 | continue; | ||
704 | } | ||
705 | |||
706 | /* We must increment writecount here, and not at the | ||
707 | * end of the loop. Otherwise, the final loop iteration may | ||
708 | * be skipped, leading to incomplete printer output. | ||
709 | */ | 704 | */ |
710 | writecount += transfer_length; | 705 | if ((transfer_length = count - writecount) > USBLP_BUF_SIZE) |
711 | if (writecount == count) { | ||
712 | mutex_unlock(&usblp->mut); | ||
713 | break; | ||
714 | } | ||
715 | |||
716 | transfer_length=(count - writecount); | ||
717 | if (transfer_length > USBLP_BUF_SIZE) | ||
718 | transfer_length = USBLP_BUF_SIZE; | 706 | transfer_length = USBLP_BUF_SIZE; |
719 | 707 | ||
720 | usblp->writeurb->transfer_buffer_length = transfer_length; | 708 | rv = -ENOMEM; |
721 | 709 | if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL) | |
722 | if (copy_from_user(usblp->writeurb->transfer_buffer, | 710 | goto raise_buf; |
711 | if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) | ||
712 | goto raise_urb; | ||
713 | usb_fill_bulk_urb(writeurb, usblp->dev, | ||
714 | usb_sndbulkpipe(usblp->dev, | ||
715 | usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress), | ||
716 | writebuf, transfer_length, usblp_bulk_write, usblp); | ||
717 | usb_anchor_urb(writeurb, &usblp->urbs); | ||
718 | |||
719 | if (copy_from_user(writebuf, | ||
723 | buffer + writecount, transfer_length)) { | 720 | buffer + writecount, transfer_length)) { |
724 | mutex_unlock(&usblp->mut); | 721 | rv = -EFAULT; |
725 | return writecount ? writecount : -EFAULT; | 722 | goto raise_badaddr; |
726 | } | 723 | } |
727 | 724 | ||
728 | usblp->writeurb->dev = usblp->dev; | 725 | spin_lock_irq(&usblp->lock); |
729 | usblp->wcomplete = 0; | 726 | usblp->wcomplete = 0; |
730 | err = usb_submit_urb(usblp->writeurb, GFP_KERNEL); | 727 | spin_unlock_irq(&usblp->lock); |
731 | if (err) { | 728 | if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) { |
729 | usblp->wstatus = 0; | ||
730 | spin_lock_irq(&usblp->lock); | ||
732 | usblp->wcomplete = 1; | 731 | usblp->wcomplete = 1; |
733 | if (err != -ENOMEM) | 732 | wake_up(&usblp->wwait); |
734 | count = -EIO; | 733 | spin_unlock_irq(&usblp->lock); |
735 | else | 734 | if (rv != -ENOMEM) |
736 | count = writecount ? writecount : -ENOMEM; | 735 | rv = -EIO; |
737 | mutex_unlock (&usblp->mut); | 736 | goto raise_submit; |
738 | break; | 737 | } |
738 | |||
739 | /* | ||
740 | * Step 2: Wait for transfer to end, collect results. | ||
741 | */ | ||
742 | rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); | ||
743 | if (rv < 0) { | ||
744 | /* | ||
745 | * If interrupted, we simply leave the URB to dangle, | ||
746 | * so the ->release will call usb_kill_urb(). | ||
747 | */ | ||
748 | goto collect_error; | ||
739 | } | 749 | } |
740 | mutex_unlock (&usblp->mut); | 750 | |
751 | if (usblp->wstatus < 0) { | ||
752 | usblp_check_status(usblp, 0); | ||
753 | rv = -EIO; | ||
754 | goto collect_error; | ||
755 | } | ||
756 | /* | ||
757 | * This is critical: it must be our URB, not other writer's. | ||
758 | * The wmut exists mainly to cover us here. | ||
759 | */ | ||
760 | writecount += usblp->wstatus; | ||
741 | } | 761 | } |
742 | 762 | ||
743 | return count; | 763 | mutex_unlock(&usblp->wmut); |
764 | return writecount; | ||
765 | |||
766 | raise_submit: | ||
767 | raise_badaddr: | ||
768 | usb_unanchor_urb(writeurb); | ||
769 | usb_free_urb(writeurb); | ||
770 | raise_urb: | ||
771 | kfree(writebuf); | ||
772 | raise_buf: | ||
773 | raise_wait: | ||
774 | collect_error: /* Out of raise sequence */ | ||
775 | mutex_unlock(&usblp->wmut); | ||
776 | raise_biglock: | ||
777 | return writecount ? writecount : rv; | ||
744 | } | 778 | } |
745 | 779 | ||
746 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 780 | /* |
781 | * Notice that we fail to restart in a few cases: on EFAULT, on restart | ||
782 | * error, etc. This is the historical behaviour. In all such cases we return | ||
783 | * EIO, and applications loop in order to get the new read going. | ||
784 | */ | ||
785 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t len, loff_t *ppos) | ||
747 | { | 786 | { |
748 | struct usblp *usblp = file->private_data; | 787 | struct usblp *usblp = file->private_data; |
749 | int rv, intr; | 788 | ssize_t count; |
789 | ssize_t avail; | ||
790 | int rv; | ||
750 | 791 | ||
751 | if (!usblp->bidir) | 792 | if (!usblp->bidir) |
752 | return -EINVAL; | 793 | return -EINVAL; |
753 | 794 | ||
754 | intr = mutex_lock_interruptible (&usblp->mut); | 795 | rv = usblp_rwait_and_lock(usblp, !!(file->f_flags & O_NONBLOCK)); |
755 | if (intr) | 796 | if (rv < 0) |
756 | return -EINTR; | 797 | return rv; |
757 | if (!usblp->present) { | 798 | |
758 | count = -ENODEV; | 799 | if ((avail = usblp->rstatus) < 0) { |
800 | printk(KERN_ERR "usblp%d: error %d reading from printer\n", | ||
801 | usblp->minor, (int)avail); | ||
802 | usblp_submit_read(usblp); | ||
803 | count = -EIO; | ||
759 | goto done; | 804 | goto done; |
760 | } | 805 | } |
761 | 806 | ||
762 | if (!usblp->rcomplete) { | 807 | count = len < avail - usblp->readcount ? len : avail - usblp->readcount; |
763 | barrier(); | 808 | if (count != 0 && |
809 | copy_to_user(buffer, usblp->readbuf + usblp->readcount, count)) { | ||
810 | count = -EFAULT; | ||
811 | goto done; | ||
812 | } | ||
764 | 813 | ||
765 | if (file->f_flags & O_NONBLOCK) { | 814 | if ((usblp->readcount += count) == avail) { |
766 | count = -EAGAIN; | 815 | if (usblp_submit_read(usblp) < 0) { |
767 | goto done; | 816 | /* We don't want to leak USB return codes into errno. */ |
768 | } | 817 | if (count == 0) |
769 | mutex_unlock(&usblp->mut); | 818 | count = -EIO; |
770 | rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); | ||
771 | mutex_lock(&usblp->mut); | ||
772 | if (rv < 0) { | ||
773 | count = -EINTR; | ||
774 | goto done; | 819 | goto done; |
775 | } | 820 | } |
776 | } | 821 | } |
777 | 822 | ||
778 | if (!usblp->present) { | 823 | done: |
779 | count = -ENODEV; | 824 | mutex_unlock (&usblp->mut); |
780 | goto done; | 825 | return count; |
826 | } | ||
827 | |||
828 | /* | ||
829 | * Wait for the write path to come idle. | ||
830 | * This is called under the ->wmut, so the idle path stays idle. | ||
831 | * | ||
832 | * Our write path has a peculiar property: it does not buffer like a tty, | ||
833 | * but waits for the write to succeed. This allows our ->release to bug out | ||
834 | * without waiting for writes to drain. But it obviously does not work | ||
835 | * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use | ||
836 | * select(2) or poll(2) to wait for the buffer to drain before closing. | ||
837 | * Alternatively, set blocking mode with fcntl and issue a zero-size write. | ||
838 | * | ||
839 | * Old v0.13 code had a non-functional timeout for wait_event(). Someone forgot | ||
840 | * to check the return code for timeout expiration, so it had no effect. | ||
841 | * Apparently, it was intended to check for error conditons, such as out | ||
842 | * of paper. It is going to return when we settle things with CUPS. XXX | ||
843 | */ | ||
844 | static int usblp_wwait(struct usblp *usblp, int nonblock) | ||
845 | { | ||
846 | DECLARE_WAITQUEUE(waita, current); | ||
847 | int rc; | ||
848 | |||
849 | add_wait_queue(&usblp->wwait, &waita); | ||
850 | for (;;) { | ||
851 | if (mutex_lock_interruptible(&usblp->mut)) { | ||
852 | rc = -EINTR; | ||
853 | break; | ||
854 | } | ||
855 | set_current_state(TASK_INTERRUPTIBLE); | ||
856 | if ((rc = usblp_wtest(usblp, nonblock)) < 0) { | ||
857 | mutex_unlock(&usblp->mut); | ||
858 | break; | ||
859 | } | ||
860 | mutex_unlock(&usblp->mut); | ||
861 | if (rc == 0) | ||
862 | break; | ||
863 | schedule(); | ||
781 | } | 864 | } |
865 | set_current_state(TASK_RUNNING); | ||
866 | remove_wait_queue(&usblp->wwait, &waita); | ||
867 | return rc; | ||
868 | } | ||
782 | 869 | ||
783 | if (usblp->sleeping) { | 870 | static int usblp_wtest(struct usblp *usblp, int nonblock) |
784 | count = -ENODEV; | 871 | { |
785 | goto done; | 872 | unsigned long flags; |
873 | |||
874 | if (!usblp->present) | ||
875 | return -ENODEV; | ||
876 | if (signal_pending(current)) | ||
877 | return -EINTR; | ||
878 | spin_lock_irqsave(&usblp->lock, flags); | ||
879 | if (usblp->wcomplete) { | ||
880 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
881 | return 0; | ||
786 | } | 882 | } |
883 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
884 | if (usblp->sleeping) | ||
885 | return -ENODEV; | ||
886 | if (nonblock) | ||
887 | return -EAGAIN; | ||
888 | return 1; | ||
889 | } | ||
787 | 890 | ||
788 | if (usblp->readurb->status) { | 891 | /* |
789 | err("usblp%d: error %d reading from printer", | 892 | * Wait for read bytes to become available. This probably should have been |
790 | usblp->minor, usblp->readurb->status); | 893 | * called usblp_r_lock_and_wait(), because we lock first. But it's a traditional |
791 | usblp->readurb->dev = usblp->dev; | 894 | * name for functions which lock and return. |
792 | usblp->readcount = 0; | 895 | * |
793 | usblp->rcomplete = 0; | 896 | * We do not use wait_event_interruptible because it makes locking iffy. |
794 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) | 897 | */ |
795 | dbg("error submitting urb"); | 898 | static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock) |
796 | count = -EIO; | 899 | { |
797 | goto done; | 900 | DECLARE_WAITQUEUE(waita, current); |
901 | int rc; | ||
902 | |||
903 | add_wait_queue(&usblp->rwait, &waita); | ||
904 | for (;;) { | ||
905 | if (mutex_lock_interruptible(&usblp->mut)) { | ||
906 | rc = -EINTR; | ||
907 | break; | ||
908 | } | ||
909 | set_current_state(TASK_INTERRUPTIBLE); | ||
910 | if ((rc = usblp_rtest(usblp, nonblock)) < 0) { | ||
911 | mutex_unlock(&usblp->mut); | ||
912 | break; | ||
913 | } | ||
914 | if (rc == 0) /* Keep it locked */ | ||
915 | break; | ||
916 | mutex_unlock(&usblp->mut); | ||
917 | schedule(); | ||
798 | } | 918 | } |
919 | set_current_state(TASK_RUNNING); | ||
920 | remove_wait_queue(&usblp->rwait, &waita); | ||
921 | return rc; | ||
922 | } | ||
799 | 923 | ||
800 | count = count < usblp->readurb->actual_length - usblp->readcount ? | 924 | static int usblp_rtest(struct usblp *usblp, int nonblock) |
801 | count : usblp->readurb->actual_length - usblp->readcount; | 925 | { |
926 | unsigned long flags; | ||
802 | 927 | ||
803 | if (copy_to_user(buffer, usblp->readurb->transfer_buffer + usblp->readcount, count)) { | 928 | if (!usblp->present) |
804 | count = -EFAULT; | 929 | return -ENODEV; |
805 | goto done; | 930 | if (signal_pending(current)) |
931 | return -EINTR; | ||
932 | spin_lock_irqsave(&usblp->lock, flags); | ||
933 | if (usblp->rcomplete) { | ||
934 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
935 | return 0; | ||
806 | } | 936 | } |
937 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
938 | if (usblp->sleeping) | ||
939 | return -ENODEV; | ||
940 | if (nonblock) | ||
941 | return -EAGAIN; | ||
942 | return 1; | ||
943 | } | ||
807 | 944 | ||
808 | if ((usblp->readcount += count) == usblp->readurb->actual_length) { | 945 | /* |
809 | usblp->readcount = 0; | 946 | * Please check ->bidir and other such things outside for now. |
810 | usblp->readurb->dev = usblp->dev; | 947 | */ |
811 | usblp->rcomplete = 0; | 948 | static int usblp_submit_read(struct usblp *usblp) |
812 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL)) { | 949 | { |
813 | count = -EIO; | 950 | struct urb *urb; |
814 | goto done; | 951 | unsigned long flags; |
815 | } | 952 | int rc; |
953 | |||
954 | rc = -ENOMEM; | ||
955 | if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) | ||
956 | goto raise_urb; | ||
957 | |||
958 | usb_fill_bulk_urb(urb, usblp->dev, | ||
959 | usb_rcvbulkpipe(usblp->dev, | ||
960 | usblp->protocol[usblp->current_protocol].epread->bEndpointAddress), | ||
961 | usblp->readbuf, USBLP_BUF_SIZE_IN, | ||
962 | usblp_bulk_read, usblp); | ||
963 | usb_anchor_urb(urb, &usblp->urbs); | ||
964 | |||
965 | spin_lock_irqsave(&usblp->lock, flags); | ||
966 | usblp->readcount = 0; /* XXX Why here? */ | ||
967 | usblp->rcomplete = 0; | ||
968 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
969 | if ((rc = usb_submit_urb(urb, GFP_KERNEL)) < 0) { | ||
970 | dbg("error submitting urb (%d)", rc); | ||
971 | spin_lock_irqsave(&usblp->lock, flags); | ||
972 | usblp->rstatus = rc; | ||
973 | usblp->rcomplete = 1; | ||
974 | spin_unlock_irqrestore(&usblp->lock, flags); | ||
975 | goto raise_submit; | ||
816 | } | 976 | } |
817 | 977 | ||
818 | done: | 978 | return 0; |
819 | mutex_unlock (&usblp->mut); | 979 | |
820 | return count; | 980 | raise_submit: |
981 | usb_unanchor_urb(urb); | ||
982 | usb_free_urb(urb); | ||
983 | raise_urb: | ||
984 | return rc; | ||
821 | } | 985 | } |
822 | 986 | ||
823 | /* | 987 | /* |
@@ -891,55 +1055,41 @@ static int usblp_probe(struct usb_interface *intf, | |||
891 | /* Malloc and start initializing usblp structure so we can use it | 1055 | /* Malloc and start initializing usblp structure so we can use it |
892 | * directly. */ | 1056 | * directly. */ |
893 | if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { | 1057 | if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { |
894 | err("out of memory for usblp"); | 1058 | retval = -ENOMEM; |
895 | goto abort; | 1059 | goto abort; |
896 | } | 1060 | } |
897 | usblp->dev = dev; | 1061 | usblp->dev = dev; |
1062 | mutex_init(&usblp->wmut); | ||
898 | mutex_init (&usblp->mut); | 1063 | mutex_init (&usblp->mut); |
899 | init_waitqueue_head(&usblp->wait); | 1064 | spin_lock_init(&usblp->lock); |
1065 | init_waitqueue_head(&usblp->rwait); | ||
1066 | init_waitqueue_head(&usblp->wwait); | ||
1067 | init_usb_anchor(&usblp->urbs); | ||
900 | usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 1068 | usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; |
901 | usblp->intf = intf; | 1069 | usblp->intf = intf; |
902 | 1070 | ||
903 | usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL); | ||
904 | if (!usblp->writeurb) { | ||
905 | err("out of memory"); | ||
906 | goto abort; | ||
907 | } | ||
908 | usblp->readurb = usb_alloc_urb(0, GFP_KERNEL); | ||
909 | if (!usblp->readurb) { | ||
910 | err("out of memory"); | ||
911 | goto abort; | ||
912 | } | ||
913 | |||
914 | /* Malloc device ID string buffer to the largest expected length, | 1071 | /* Malloc device ID string buffer to the largest expected length, |
915 | * since we can re-query it on an ioctl and a dynamic string | 1072 | * since we can re-query it on an ioctl and a dynamic string |
916 | * could change in length. */ | 1073 | * could change in length. */ |
917 | if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) { | 1074 | if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) { |
918 | err("out of memory for device_id_string"); | 1075 | retval = -ENOMEM; |
919 | goto abort; | 1076 | goto abort; |
920 | } | 1077 | } |
921 | 1078 | ||
922 | usblp->writebuf = usblp->readbuf = NULL; | 1079 | /* |
923 | usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 1080 | * Allocate read buffer. We somewhat wastefully |
924 | usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | ||
925 | /* Malloc write & read buffers. We somewhat wastefully | ||
926 | * malloc both regardless of bidirectionality, because the | 1081 | * malloc both regardless of bidirectionality, because the |
927 | * alternate setting can be changed later via an ioctl. */ | 1082 | * alternate setting can be changed later via an ioctl. |
928 | if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE, | 1083 | */ |
929 | GFP_KERNEL, &usblp->writeurb->transfer_dma))) { | 1084 | if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE_IN, GFP_KERNEL))) { |
930 | err("out of memory for write buf"); | 1085 | retval = -ENOMEM; |
931 | goto abort; | ||
932 | } | ||
933 | if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE, | ||
934 | GFP_KERNEL, &usblp->readurb->transfer_dma))) { | ||
935 | err("out of memory for read buf"); | ||
936 | goto abort; | 1086 | goto abort; |
937 | } | 1087 | } |
938 | 1088 | ||
939 | /* Allocate buffer for printer status */ | 1089 | /* Allocate buffer for printer status */ |
940 | usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL); | 1090 | usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL); |
941 | if (!usblp->statusbuf) { | 1091 | if (!usblp->statusbuf) { |
942 | err("out of memory for statusbuf"); | 1092 | retval = -ENOMEM; |
943 | goto abort; | 1093 | goto abort; |
944 | } | 1094 | } |
945 | 1095 | ||
@@ -954,12 +1104,15 @@ static int usblp_probe(struct usb_interface *intf, | |||
954 | dbg("incompatible printer-class device 0x%4.4X/0x%4.4X", | 1104 | dbg("incompatible printer-class device 0x%4.4X/0x%4.4X", |
955 | le16_to_cpu(dev->descriptor.idVendor), | 1105 | le16_to_cpu(dev->descriptor.idVendor), |
956 | le16_to_cpu(dev->descriptor.idProduct)); | 1106 | le16_to_cpu(dev->descriptor.idProduct)); |
1107 | retval = -ENODEV; | ||
957 | goto abort; | 1108 | goto abort; |
958 | } | 1109 | } |
959 | 1110 | ||
960 | /* Setup the selected alternate setting and endpoints. */ | 1111 | /* Setup the selected alternate setting and endpoints. */ |
961 | if (usblp_set_protocol(usblp, protocol) < 0) | 1112 | if (usblp_set_protocol(usblp, protocol) < 0) { |
1113 | retval = -ENODEV; /* ->probe isn't ->ioctl */ | ||
962 | goto abort; | 1114 | goto abort; |
1115 | } | ||
963 | 1116 | ||
964 | /* Retrieve and store the device ID string. */ | 1117 | /* Retrieve and store the device ID string. */ |
965 | usblp_cache_device_id_string(usblp); | 1118 | usblp_cache_device_id_string(usblp); |
@@ -977,12 +1130,14 @@ static int usblp_probe(struct usb_interface *intf, | |||
977 | 1130 | ||
978 | retval = usb_register_dev(intf, &usblp_class); | 1131 | retval = usb_register_dev(intf, &usblp_class); |
979 | if (retval) { | 1132 | if (retval) { |
980 | err("Not able to get a minor for this device."); | 1133 | printk(KERN_ERR "usblp: Not able to get a minor" |
1134 | " (base %u, slice default): %d\n", | ||
1135 | USBLP_MINOR_BASE, retval); | ||
981 | goto abort_intfdata; | 1136 | goto abort_intfdata; |
982 | } | 1137 | } |
983 | usblp->minor = intf->minor; | 1138 | usblp->minor = intf->minor; |
984 | info("usblp%d: USB %sdirectional printer dev %d " | 1139 | printk(KERN_INFO "usblp%d: USB %sdirectional printer dev %d " |
985 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | 1140 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n", |
986 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | 1141 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, |
987 | usblp->ifnum, | 1142 | usblp->ifnum, |
988 | usblp->protocol[usblp->current_protocol].alt_setting, | 1143 | usblp->protocol[usblp->current_protocol].alt_setting, |
@@ -997,19 +1152,12 @@ abort_intfdata: | |||
997 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | 1152 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); |
998 | abort: | 1153 | abort: |
999 | if (usblp) { | 1154 | if (usblp) { |
1000 | if (usblp->writebuf) | 1155 | kfree(usblp->readbuf); |
1001 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, | ||
1002 | usblp->writebuf, usblp->writeurb->transfer_dma); | ||
1003 | if (usblp->readbuf) | ||
1004 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, | ||
1005 | usblp->readbuf, usblp->readurb->transfer_dma); | ||
1006 | kfree(usblp->statusbuf); | 1156 | kfree(usblp->statusbuf); |
1007 | kfree(usblp->device_id_string); | 1157 | kfree(usblp->device_id_string); |
1008 | usb_free_urb(usblp->writeurb); | ||
1009 | usb_free_urb(usblp->readurb); | ||
1010 | kfree(usblp); | 1158 | kfree(usblp); |
1011 | } | 1159 | } |
1012 | return -EIO; | 1160 | return retval; |
1013 | } | 1161 | } |
1014 | 1162 | ||
1015 | /* | 1163 | /* |
@@ -1078,8 +1226,9 @@ static int usblp_select_alts(struct usblp *usblp) | |||
1078 | if (ifd->desc.bInterfaceProtocol == 1) { | 1226 | if (ifd->desc.bInterfaceProtocol == 1) { |
1079 | epread = NULL; | 1227 | epread = NULL; |
1080 | } else if (usblp->quirks & USBLP_QUIRK_BIDIR) { | 1228 | } else if (usblp->quirks & USBLP_QUIRK_BIDIR) { |
1081 | info("Disabling reads from problem bidirectional " | 1229 | printk(KERN_INFO "usblp%d: Disabling reads from " |
1082 | "printer on usblp%d", usblp->minor); | 1230 | "problematic bidirectional printer\n", |
1231 | usblp->minor); | ||
1083 | epread = NULL; | 1232 | epread = NULL; |
1084 | } | 1233 | } |
1085 | 1234 | ||
@@ -1119,25 +1268,12 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol) | |||
1119 | return -EINVAL; | 1268 | return -EINVAL; |
1120 | r = usb_set_interface(usblp->dev, usblp->ifnum, alts); | 1269 | r = usb_set_interface(usblp->dev, usblp->ifnum, alts); |
1121 | if (r < 0) { | 1270 | if (r < 0) { |
1122 | err("can't set desired altsetting %d on interface %d", | 1271 | printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", |
1123 | alts, usblp->ifnum); | 1272 | alts, usblp->ifnum); |
1124 | return r; | 1273 | return r; |
1125 | } | 1274 | } |
1126 | 1275 | ||
1127 | usb_fill_bulk_urb(usblp->writeurb, usblp->dev, | ||
1128 | usb_sndbulkpipe(usblp->dev, | ||
1129 | usblp->protocol[protocol].epwrite->bEndpointAddress), | ||
1130 | usblp->writebuf, 0, | ||
1131 | usblp_bulk_write, usblp); | ||
1132 | |||
1133 | usblp->bidir = (usblp->protocol[protocol].epread != NULL); | 1276 | usblp->bidir = (usblp->protocol[protocol].epread != NULL); |
1134 | if (usblp->bidir) | ||
1135 | usb_fill_bulk_urb(usblp->readurb, usblp->dev, | ||
1136 | usb_rcvbulkpipe(usblp->dev, | ||
1137 | usblp->protocol[protocol].epread->bEndpointAddress), | ||
1138 | usblp->readbuf, USBLP_BUF_SIZE, | ||
1139 | usblp_bulk_read, usblp); | ||
1140 | |||
1141 | usblp->current_protocol = protocol; | 1277 | usblp->current_protocol = protocol; |
1142 | dbg("usblp%d set protocol %d", usblp->minor, protocol); | 1278 | dbg("usblp%d set protocol %d", usblp->minor, protocol); |
1143 | return 0; | 1279 | return 0; |
@@ -1190,13 +1326,11 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1190 | mutex_lock (&usblp_mutex); | 1326 | mutex_lock (&usblp_mutex); |
1191 | mutex_lock (&usblp->mut); | 1327 | mutex_lock (&usblp->mut); |
1192 | usblp->present = 0; | 1328 | usblp->present = 0; |
1329 | wake_up(&usblp->wwait); | ||
1330 | wake_up(&usblp->rwait); | ||
1193 | usb_set_intfdata (intf, NULL); | 1331 | usb_set_intfdata (intf, NULL); |
1194 | 1332 | ||
1195 | usblp_unlink_urbs(usblp); | 1333 | usblp_unlink_urbs(usblp); |
1196 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, | ||
1197 | usblp->writebuf, usblp->writeurb->transfer_dma); | ||
1198 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, | ||
1199 | usblp->readbuf, usblp->readurb->transfer_dma); | ||
1200 | mutex_unlock (&usblp->mut); | 1334 | mutex_unlock (&usblp->mut); |
1201 | 1335 | ||
1202 | if (!usblp->used) | 1336 | if (!usblp->used) |
@@ -1211,6 +1345,11 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | |||
1211 | /* we take no more IO */ | 1345 | /* we take no more IO */ |
1212 | usblp->sleeping = 1; | 1346 | usblp->sleeping = 1; |
1213 | usblp_unlink_urbs(usblp); | 1347 | usblp_unlink_urbs(usblp); |
1348 | #if 0 /* XXX Do we want this? What if someone is reading, should we fail? */ | ||
1349 | /* not strictly necessary, but just in case */ | ||
1350 | wake_up(&usblp->wwait); | ||
1351 | wake_up(&usblp->rwait); | ||
1352 | #endif | ||
1214 | 1353 | ||
1215 | return 0; | 1354 | return 0; |
1216 | } | 1355 | } |
@@ -1251,12 +1390,7 @@ static struct usb_driver usblp_driver = { | |||
1251 | 1390 | ||
1252 | static int __init usblp_init(void) | 1391 | static int __init usblp_init(void) |
1253 | { | 1392 | { |
1254 | int retval; | 1393 | return usb_register(&usblp_driver); |
1255 | retval = usb_register(&usblp_driver); | ||
1256 | if (!retval) | ||
1257 | info(DRIVER_VERSION ": " DRIVER_DESC); | ||
1258 | |||
1259 | return retval; | ||
1260 | } | 1394 | } |
1261 | 1395 | ||
1262 | static void __exit usblp_exit(void) | 1396 | static void __exit usblp_exit(void) |