diff options
Diffstat (limited to 'drivers/usb/gadget/printer.c')
| -rw-r--r-- | drivers/usb/gadget/printer.c | 92 |
1 files changed, 57 insertions, 35 deletions
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 2c32bd08ee7d..76be75e3ab8f 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); |
| @@ -894,7 +915,7 @@ static void printer_reset_interface(struct printer_dev *dev) | |||
| 894 | if (dev->interface < 0) | 915 | if (dev->interface < 0) |
| 895 | return; | 916 | return; |
| 896 | 917 | ||
| 897 | DBG(dev, "%s\n", __FUNCTION__); | 918 | DBG(dev, "%s\n", __func__); |
| 898 | 919 | ||
| 899 | if (dev->in) | 920 | if (dev->in) |
| 900 | usb_ep_disable(dev->in_ep); | 921 | usb_ep_disable(dev->in_ep); |
| @@ -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 | } |
| @@ -1262,7 +1284,7 @@ printer_disconnect(struct usb_gadget *gadget) | |||
| 1262 | struct printer_dev *dev = get_gadget_data(gadget); | 1284 | struct printer_dev *dev = get_gadget_data(gadget); |
| 1263 | unsigned long flags; | 1285 | unsigned long flags; |
| 1264 | 1286 | ||
| 1265 | DBG(dev, "%s\n", __FUNCTION__); | 1287 | DBG(dev, "%s\n", __func__); |
| 1266 | 1288 | ||
| 1267 | spin_lock_irqsave(&dev->lock, flags); | 1289 | spin_lock_irqsave(&dev->lock, flags); |
| 1268 | 1290 | ||
| @@ -1278,7 +1300,7 @@ printer_unbind(struct usb_gadget *gadget) | |||
| 1278 | struct usb_request *req; | 1300 | struct usb_request *req; |
| 1279 | 1301 | ||
| 1280 | 1302 | ||
| 1281 | DBG(dev, "%s\n", __FUNCTION__); | 1303 | DBG(dev, "%s\n", __func__); |
| 1282 | 1304 | ||
| 1283 | /* Remove sysfs files */ | 1305 | /* Remove sysfs files */ |
| 1284 | device_destroy(usb_gadget_class, g_printer_devno); | 1306 | device_destroy(usb_gadget_class, g_printer_devno); |
