* [PATCH] Input: usbtouchscreen - separate report and transmit buffer size handling @ 2013-10-15 14:50 Christian Engelmayer 2013-10-16 6:29 ` Dmitry Torokhov 0 siblings, 1 reply; 3+ messages in thread From: Christian Engelmayer @ 2013-10-15 14:50 UTC (permalink / raw) To: Dmitry Torokhov, Forest Bond, Daniel Ritz Cc: linux-input, linux-usb, christian.engelmayer This patch supports the separate handling of the USB transfer buffer length and the length of the buffer used for multi packet support. The USB transfer size can now be explicitly configured via the device_info record. Otherwise it defaults to the configured report packet size as before. For devices supporting multiple report or diagnostic packets, the USB transfer size is now reduced to the USB endpoints wMaxPacketSize if not explicitly set. This fixes an issue where event reporting can be delayed for an arbitrary time for multi packet devices. For instance the report size for eGalax devices is defined to the 16 byte maximum diagnostic packet size as opposed to the 5 byte report packet size. In case the driver requests 16 byte from the USB interrupt endpoint, the USB host controller driver needs to split up the request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte. When the first transfer is answered by the eGalax device with not less than the full 8 byte requested, the host controller has got no way of knowing whether the touch controller has got additional data queued and will issue the second transfer. If per example a liftoff event finishes at such a wMaxPacketSize boundary, the data will not be available to the usbtouch driver until a further event is triggered and transfered to the host. From user perspective the BTN_TOUCH release event in this case is stuck until the next touch down event. Signed-off-by: Christian Engelmayer <christian.engelmayer@frequentis.com> --- drivers/input/touchscreen/usbtouchscreen.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 721fdb3..aa1f6a7 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -76,6 +76,7 @@ struct usbtouch_device_info { int min_yc, max_yc; int min_press, max_press; int rept_size; + int xmit_size; /* * Always service the USB devices irq not just when the input device is @@ -1523,7 +1524,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf) static void usbtouch_free_buffers(struct usb_device *udev, struct usbtouch_usb *usbtouch) { - usb_free_coherent(udev, usbtouch->type->rept_size, + usb_free_coherent(udev, usbtouch->type->xmit_size, usbtouch->data, usbtouch->data_dma); kfree(usbtouch->buffer); } @@ -1567,8 +1568,15 @@ static int usbtouch_probe(struct usb_interface *intf, usbtouch->type = type; if (!type->process_pkt) type->process_pkt = usbtouch_process_pkt; + if (!type->xmit_size) { + if ((type->get_pkt_len) && + (type->rept_size > le16_to_cpu(endpoint->wMaxPacketSize))) + type->xmit_size = le16_to_cpu(endpoint->wMaxPacketSize); + else + type->xmit_size = type->rept_size; + } - usbtouch->data = usb_alloc_coherent(udev, type->rept_size, + usbtouch->data = usb_alloc_coherent(udev, type->xmit_size, GFP_KERNEL, &usbtouch->data_dma); if (!usbtouch->data) goto out_free; @@ -1628,12 +1636,12 @@ static int usbtouch_probe(struct usb_interface *intf, if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) usb_fill_int_urb(usbtouch->irq, udev, usb_rcvintpipe(udev, endpoint->bEndpointAddress), - usbtouch->data, type->rept_size, + usbtouch->data, type->xmit_size, usbtouch_irq, usbtouch, endpoint->bInterval); else usb_fill_bulk_urb(usbtouch->irq, udev, usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), - usbtouch->data, type->rept_size, + usbtouch->data, type->xmit_size, usbtouch_irq, usbtouch); usbtouch->irq->dev = udev; -- 1.7.2.5 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] Input: usbtouchscreen - separate report and transmit buffer size handling 2013-10-15 14:50 [PATCH] Input: usbtouchscreen - separate report and transmit buffer size handling Christian Engelmayer @ 2013-10-16 6:29 ` Dmitry Torokhov [not found] ` <20131016062902.GA4282-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org> 0 siblings, 1 reply; 3+ messages in thread From: Dmitry Torokhov @ 2013-10-16 6:29 UTC (permalink / raw) To: Christian Engelmayer; +Cc: Forest Bond, Daniel Ritz, linux-input, linux-usb Hi Christian, On Tue, Oct 15, 2013 at 04:50:00PM +0200, Christian Engelmayer wrote: > This patch supports the separate handling of the USB transfer buffer length > and the length of the buffer used for multi packet support. The USB transfer > size can now be explicitly configured via the device_info record. Otherwise > it defaults to the configured report packet size as before. For devices > supporting multiple report or diagnostic packets, the USB transfer size is > now reduced to the USB endpoints wMaxPacketSize if not explicitly set. > > This fixes an issue where event reporting can be delayed for an arbitrary > time for multi packet devices. For instance the report size for eGalax devices > is defined to the 16 byte maximum diagnostic packet size as opposed to the 5 > byte report packet size. In case the driver requests 16 byte from the USB > interrupt endpoint, the USB host controller driver needs to split up the > request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte. > When the first transfer is answered by the eGalax device with not less than > the full 8 byte requested, the host controller has got no way of knowing > whether the touch controller has got additional data queued and will issue > the second transfer. If per example a liftoff event finishes at such a > wMaxPacketSize boundary, the data will not be available to the usbtouch driver > until a further event is triggered and transfered to the host. From user > perspective the BTN_TOUCH release event in this case is stuck until the next > touch down event. > > Signed-off-by: Christian Engelmayer <christian.engelmayer@frequentis.com> > --- > drivers/input/touchscreen/usbtouchscreen.c | 16 ++++++++++++---- > 1 files changed, 12 insertions(+), 4 deletions(-) > > diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c > index 721fdb3..aa1f6a7 100644 > --- a/drivers/input/touchscreen/usbtouchscreen.c > +++ b/drivers/input/touchscreen/usbtouchscreen.c > @@ -76,6 +76,7 @@ struct usbtouch_device_info { > int min_yc, max_yc; > int min_press, max_press; > int rept_size; > + int xmit_size; > > /* > * Always service the USB devices irq not just when the input device is > @@ -1523,7 +1524,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf) > static void usbtouch_free_buffers(struct usb_device *udev, > struct usbtouch_usb *usbtouch) > { > - usb_free_coherent(udev, usbtouch->type->rept_size, > + usb_free_coherent(udev, usbtouch->type->xmit_size, > usbtouch->data, usbtouch->data_dma); > kfree(usbtouch->buffer); > } > @@ -1567,8 +1568,15 @@ static int usbtouch_probe(struct usb_interface *intf, > usbtouch->type = type; > if (!type->process_pkt) > type->process_pkt = usbtouch_process_pkt; > + if (!type->xmit_size) { > + if ((type->get_pkt_len) && > + (type->rept_size > le16_to_cpu(endpoint->wMaxPacketSize))) > + type->xmit_size = le16_to_cpu(endpoint->wMaxPacketSize); > + else > + type->xmit_size = type->rept_size; 'type' points to a shared data structure and should not be modified. It looks like we already violating this so a cleanup patch would be appreciated as well. BTW, maybe we should do: u16 wMaxPaxetSize = le16_to_cpu(endpoint->wMaxPacketSize); xmit_size = min(type->rept_size, wMaxPaxetSize); ? Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 3+ messages in thread
[parent not found: <20131016062902.GA4282-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>]
* [PATCH v2] Input: usbtouchscreen - separate report and transmit buffer size handling [not found] ` <20131016062902.GA4282-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org> @ 2013-10-16 21:15 ` Christian Engelmayer 0 siblings, 0 replies; 3+ messages in thread From: Christian Engelmayer @ 2013-10-16 21:15 UTC (permalink / raw) To: Dmitry Torokhov Cc: Forest Bond, Daniel Ritz, linux-input-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA, christian.engelmayer-USXAA5bZaHGDvotElmWtJA This patch supports the separate handling of the USB transfer buffer length and the length of the buffer used for multi packet support. For devices supporting multiple report or diagnostic packets, the USB transfer size is now limited to the USB endpoints wMaxPacketSize - otherwise it defaults to the configured report packet size as before This fixes an issue where event reporting can be delayed for an arbitrary time for multi packet devices. For instance the report size for eGalax devices is defined to the 16 byte maximum diagnostic packet size as opposed to the 5 byte report packet size. In case the driver requests 16 byte from the USB interrupt endpoint, the USB host controller driver needs to split up the request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte. When the first transfer is answered by the eGalax device with not less than the full 8 byte requested, the host controller has got no way of knowing whether the touch controller has got additional data queued and will issue the second transfer. If per example a liftoff event finishes at such a wMaxPacketSize boundary, the data will not be available to the usbtouch driver until a further event is triggered and transfered to the host. From user perspective the BTN_TOUCH release event in this case is stuck until the next touch down event. Signed-off-by: Christian Engelmayer <christian.engelmayer-USXAA5bZaHGDvotElmWtJA@public.gmane.org> --- v2: Added changes suggested by Dmitry Torokhov: * Prefer a temporary variable over a multiple conversion of wMaxPaxetSize. * Avoid further modifiction of the shared device info structure. The existing violation in the probe function if (!type->process_pkt) type->process_pkt = usbtouch_process_pkt; seems to be conveniance triggered and while at least at the moment applicable for all devices of a type, could be easily removed. For a complete cleanup and eg. setting the shared device information 'const', we would have to adapt the Nexio support first - nexio_read_data: if (!usbtouch->type->max_xc) { usbtouch->type->max_xc = 2 * x_len; input_set_abs_params(usbtouch->input, ABS_X, 0, usbtouch->type->max_xc, 0, 0); usbtouch->type->max_yc = 2 * y_len; input_set_abs_params(usbtouch->input, ABS_Y, 0, usbtouch->type->max_yc, 0, 0); } --- drivers/input/touchscreen/usbtouchscreen.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 721fdb3..d632848 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -106,6 +106,7 @@ struct usbtouch_device_info { struct usbtouch_usb { unsigned char *data; dma_addr_t data_dma; + int data_size; unsigned char *buffer; int buf_len; struct urb *irq; @@ -1523,7 +1524,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf) static void usbtouch_free_buffers(struct usb_device *udev, struct usbtouch_usb *usbtouch) { - usb_free_coherent(udev, usbtouch->type->rept_size, + usb_free_coherent(udev, usbtouch->data_size, usbtouch->data, usbtouch->data_dma); kfree(usbtouch->buffer); } @@ -1548,6 +1549,7 @@ static int usbtouch_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *endpoint; struct usb_device *udev = interface_to_usbdev(intf); struct usbtouch_device_info *type; + int wMaxPacketSize; int err = -ENOMEM; /* some devices are ignored */ @@ -1557,6 +1559,7 @@ static int usbtouch_probe(struct usb_interface *intf, endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting); if (!endpoint) return -ENXIO; + wMaxPacketSize = le16_to_cpu(endpoint->wMaxPacketSize); usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); input_dev = input_allocate_device(); @@ -1568,7 +1571,9 @@ static int usbtouch_probe(struct usb_interface *intf, if (!type->process_pkt) type->process_pkt = usbtouch_process_pkt; - usbtouch->data = usb_alloc_coherent(udev, type->rept_size, + usbtouch->data_size = (type->get_pkt_len) ? + min(type->rept_size, wMaxPacketSize) : type->rept_size; + usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size, GFP_KERNEL, &usbtouch->data_dma); if (!usbtouch->data) goto out_free; @@ -1628,12 +1633,12 @@ static int usbtouch_probe(struct usb_interface *intf, if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) usb_fill_int_urb(usbtouch->irq, udev, usb_rcvintpipe(udev, endpoint->bEndpointAddress), - usbtouch->data, type->rept_size, + usbtouch->data, usbtouch->data_size, usbtouch_irq, usbtouch, endpoint->bInterval); else usb_fill_bulk_urb(usbtouch->irq, udev, usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), - usbtouch->data, type->rept_size, + usbtouch->data, usbtouch->data_size, usbtouch_irq, usbtouch); usbtouch->irq->dev = udev; -- 1.7.2.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-10-16 21:15 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-10-15 14:50 [PATCH] Input: usbtouchscreen - separate report and transmit buffer size handling Christian Engelmayer 2013-10-16 6:29 ` Dmitry Torokhov [not found] ` <20131016062902.GA4282-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org> 2013-10-16 21:15 ` [PATCH v2] " Christian Engelmayer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).