diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/printer.c | 86 |
1 files changed, 54 insertions, 32 deletions
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 2c32bd08ee7d..ecc1410073f4 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -390,9 +390,12 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
390 | 390 | ||
391 | /* normal completion */ | 391 | /* normal completion */ |
392 | case 0: | 392 | case 0: |
393 | list_add_tail(&req->list, &dev->rx_buffers); | 393 | if (req->actual > 0) { |
394 | wake_up_interruptible(&dev->rx_wait); | 394 | list_add_tail(&req->list, &dev->rx_buffers); |
395 | DBG(dev, "G_Printer : rx length %d\n", req->actual); | 395 | DBG(dev, "G_Printer : rx length %d\n", req->actual); |
396 | } else { | ||
397 | list_add(&req->list, &dev->rx_reqs); | ||
398 | } | ||
396 | break; | 399 | break; |
397 | 400 | ||
398 | /* software-driven interface shutdown */ | 401 | /* software-driven interface shutdown */ |
@@ -417,6 +420,8 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
417 | list_add(&req->list, &dev->rx_reqs); | 420 | list_add(&req->list, &dev->rx_reqs); |
418 | break; | 421 | break; |
419 | } | 422 | } |
423 | |||
424 | wake_up_interruptible(&dev->rx_wait); | ||
420 | spin_unlock_irqrestore(&dev->lock, flags); | 425 | spin_unlock_irqrestore(&dev->lock, flags); |
421 | } | 426 | } |
422 | 427 | ||
@@ -494,6 +499,39 @@ printer_close(struct inode *inode, struct file *fd) | |||
494 | return 0; | 499 | return 0; |
495 | } | 500 | } |
496 | 501 | ||
502 | /* This function must be called with interrupts turned off. */ | ||
503 | static void | ||
504 | setup_rx_reqs(struct printer_dev *dev) | ||
505 | { | ||
506 | struct usb_request *req; | ||
507 | |||
508 | while (likely(!list_empty(&dev->rx_reqs))) { | ||
509 | int error; | ||
510 | |||
511 | req = container_of(dev->rx_reqs.next, | ||
512 | struct usb_request, list); | ||
513 | list_del_init(&req->list); | ||
514 | |||
515 | /* The USB Host sends us whatever amount of data it wants to | ||
516 | * so we always set the length field to the full USB_BUFSIZE. | ||
517 | * If the amount of data is more than the read() caller asked | ||
518 | * for it will be stored in the request buffer until it is | ||
519 | * asked for by read(). | ||
520 | */ | ||
521 | req->length = USB_BUFSIZE; | ||
522 | req->complete = rx_complete; | ||
523 | |||
524 | error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); | ||
525 | if (error) { | ||
526 | DBG(dev, "rx submit --> %d\n", error); | ||
527 | list_add(&req->list, &dev->rx_reqs); | ||
528 | break; | ||
529 | } else { | ||
530 | list_add(&req->list, &dev->rx_reqs_active); | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | |||
497 | static ssize_t | 535 | static ssize_t |
498 | printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) | 536 | printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) |
499 | { | 537 | { |
@@ -522,31 +560,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
522 | */ | 560 | */ |
523 | dev->reset_printer = 0; | 561 | dev->reset_printer = 0; |
524 | 562 | ||
525 | while (likely(!list_empty(&dev->rx_reqs))) { | 563 | setup_rx_reqs(dev); |
526 | int error; | ||
527 | |||
528 | req = container_of(dev->rx_reqs.next, | ||
529 | struct usb_request, list); | ||
530 | list_del_init(&req->list); | ||
531 | |||
532 | /* The USB Host sends us whatever amount of data it wants to | ||
533 | * so we always set the length field to the full USB_BUFSIZE. | ||
534 | * If the amount of data is more than the read() caller asked | ||
535 | * for it will be stored in the request buffer until it is | ||
536 | * asked for by read(). | ||
537 | */ | ||
538 | req->length = USB_BUFSIZE; | ||
539 | req->complete = rx_complete; | ||
540 | |||
541 | error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); | ||
542 | if (error) { | ||
543 | DBG(dev, "rx submit --> %d\n", error); | ||
544 | list_add(&req->list, &dev->rx_reqs); | ||
545 | break; | ||
546 | } else { | ||
547 | list_add(&req->list, &dev->rx_reqs_active); | ||
548 | } | ||
549 | } | ||
550 | 564 | ||
551 | bytes_copied = 0; | 565 | bytes_copied = 0; |
552 | current_rx_req = dev->current_rx_req; | 566 | current_rx_req = dev->current_rx_req; |
@@ -615,9 +629,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
615 | 629 | ||
616 | spin_lock_irqsave(&dev->lock, flags); | 630 | spin_lock_irqsave(&dev->lock, flags); |
617 | 631 | ||
618 | /* We've disconnected or reset free the req and buffer */ | 632 | /* We've disconnected or reset so return. */ |
619 | if (dev->reset_printer) { | 633 | if (dev->reset_printer) { |
620 | printer_req_free(dev->out_ep, current_rx_req); | 634 | list_add(¤t_rx_req->list, &dev->rx_reqs); |
621 | spin_unlock_irqrestore(&dev->lock, flags); | 635 | spin_unlock_irqrestore(&dev->lock, flags); |
622 | spin_unlock(&dev->lock_printer_io); | 636 | spin_unlock(&dev->lock_printer_io); |
623 | return -EAGAIN; | 637 | return -EAGAIN; |
@@ -735,7 +749,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
735 | 749 | ||
736 | /* We've disconnected or reset so free the req and buffer */ | 750 | /* We've disconnected or reset so free the req and buffer */ |
737 | if (dev->reset_printer) { | 751 | if (dev->reset_printer) { |
738 | printer_req_free(dev->in_ep, req); | 752 | list_add(&req->list, &dev->tx_reqs); |
739 | spin_unlock_irqrestore(&dev->lock, flags); | 753 | spin_unlock_irqrestore(&dev->lock, flags); |
740 | spin_unlock(&dev->lock_printer_io); | 754 | spin_unlock(&dev->lock_printer_io); |
741 | return -EAGAIN; | 755 | return -EAGAIN; |
@@ -791,6 +805,12 @@ printer_poll(struct file *fd, poll_table *wait) | |||
791 | unsigned long flags; | 805 | unsigned long flags; |
792 | int status = 0; | 806 | int status = 0; |
793 | 807 | ||
808 | spin_lock(&dev->lock_printer_io); | ||
809 | spin_lock_irqsave(&dev->lock, flags); | ||
810 | setup_rx_reqs(dev); | ||
811 | spin_unlock_irqrestore(&dev->lock, flags); | ||
812 | spin_unlock(&dev->lock_printer_io); | ||
813 | |||
794 | poll_wait(fd, &dev->rx_wait, wait); | 814 | poll_wait(fd, &dev->rx_wait, wait); |
795 | poll_wait(fd, &dev->tx_wait, wait); | 815 | poll_wait(fd, &dev->tx_wait, wait); |
796 | 816 | ||
@@ -798,7 +818,8 @@ printer_poll(struct file *fd, poll_table *wait) | |||
798 | if (likely(!list_empty(&dev->tx_reqs))) | 818 | if (likely(!list_empty(&dev->tx_reqs))) |
799 | status |= POLLOUT | POLLWRNORM; | 819 | status |= POLLOUT | POLLWRNORM; |
800 | 820 | ||
801 | if (likely(!list_empty(&dev->rx_buffers))) | 821 | if (likely(dev->current_rx_bytes) || |
822 | likely(!list_empty(&dev->rx_buffers))) | ||
802 | status |= POLLIN | POLLRDNORM; | 823 | status |= POLLIN | POLLRDNORM; |
803 | 824 | ||
804 | spin_unlock_irqrestore(&dev->lock, flags); | 825 | spin_unlock_irqrestore(&dev->lock, flags); |
@@ -1084,6 +1105,7 @@ static void printer_soft_reset(struct printer_dev *dev) | |||
1084 | if (usb_ep_enable(dev->out_ep, dev->out)) | 1105 | if (usb_ep_enable(dev->out_ep, dev->out)) |
1085 | DBG(dev, "Failed to enable USB out_ep\n"); | 1106 | DBG(dev, "Failed to enable USB out_ep\n"); |
1086 | 1107 | ||
1108 | wake_up_interruptible(&dev->rx_wait); | ||
1087 | wake_up_interruptible(&dev->tx_wait); | 1109 | wake_up_interruptible(&dev->tx_wait); |
1088 | wake_up_interruptible(&dev->tx_flush_wait); | 1110 | wake_up_interruptible(&dev->tx_flush_wait); |
1089 | } | 1111 | } |