Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1173596
| Path | csiph.com!aioe.org!bofh.it!news.nic.it!robomod |
|---|---|
| From | Reyad Attiyat <reyad.attiyat@gmail.com> |
| Newsgroups | linux.kernel |
| Subject | [PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers |
| Date | Mon, 29 Jun 2015 03:00:01 +0200 |
| Message-ID | <pGvAt-44e-5@gated-at.bofh.it> (permalink) |
| X-Original-To | gregkh@linuxfoundation.org, mathias.nyman@intel.com |
| Dkim-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=XXGDuLJJXgtLRge+wcQSybHZDqWsvAAggSHVAkQPOOc=; b=ObgHPzAse3JRsn6wLEA+oQ9s3fKIabC7xqoGKfBt7dWUnQ9s8TFZSRHcndUzshwmzR I2jW6qlapw3fMmz7xX2dxpcIRACGR4Jig8jJqIUY3CepulVQSkmGfoNoOxHcf/i/YDHw SFQrdhKyVuSG7kyJ7oNb1mOY7CyD19dU+y4WtcLy7w9bpkooPY1T261kz9f5DNaV7ESK ExbvlfAZGhN1S9ReQjEN7XDfhcCFj81CBG/1sfpdGu543chKn08V5wml0xhgHLivt/oA 0VlXae9kS68mi+BWBw0gBt9OZT6t44i2170exTpHG13yFjA69qeIWHpgf4e485PWCOt9 ICYA== |
| X-Received | by 10.70.48.34 with SMTP id i2mr26244380pdn.125.1435539192741; Sun, 28 Jun 2015 17:53:12 -0700 (PDT) |
| X-Mailer | git-send-email 2.4.3 |
| Sender | robomod@news.nic.it |
| List-ID | <linux-kernel.vger.kernel.org> |
| X-Mailing-List | linux-kernel@vger.kernel.org |
| Approved | robomod@news.nic.it |
| Lines | 142 |
| Organization | linux.* mail to news gateway |
| X-Original-Cc | linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Reyad Attiyat <reyad.attiyat@gmail.com> |
| X-Original-Date | Sun, 28 Jun 2015 19:53:08 -0500 |
| X-Original-Message-ID | <1435539188-11360-1-git-send-email-reyad.attiyat@gmail.com> |
| X-Original-Sender | linux-kernel-owner@vger.kernel.org |
| Xref | aioe.org linux.kernel:1173596 |
Show key headers only | View raw
This commmit checks for the URB_ZERO_PACKET flag and creates an extra
zero-length td if the urb transfer length is a multiple of the endpoint's
max packet length.
Signed-off-by: Reyad Attiyat <reyad.attiyat@gmail.com>
---
drivers/usb/host/xhci-ring.c | 43 +++++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7d34cbf..3d57a7a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3040,7 +3040,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
int num_sgs;
int trb_buff_len, this_sg_len, running_total;
unsigned int total_packet_count;
+ bool zero_length_needed;
bool first_trb;
+ int last_trb;
u64 addr;
bool more_trbs_coming;
@@ -3056,6 +3058,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
+ /* Deal with URB_ZERO_PACKET - need one more td/trb */
+ zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
+ && !(urb->transfer_buffer_length % usb_endpoint_maxp(&urb->ep->desc));
+ if(zero_length_needed){
+ num_trbs++;
+ xhci_dbg(xhci, "Creating zero length td.\n");
+ }
+
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
num_trbs, urb, 0, mem_flags);
@@ -3092,6 +3102,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
trb_buff_len = urb->transfer_buffer_length;
first_trb = true;
+ last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
@@ -3109,12 +3120,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
* TRB to indicate it's the last TRB in the chain.
*/
- if (num_trbs > 1) {
+ if (num_trbs > last_trb) {
field |= TRB_CHAIN;
- } else {
- /* FIXME - add check for ZERO_PACKET flag before this */
+ } else if (num_trbs == last_trb) {
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
+ } else if (zero_length_needed && num_trbs == 1) {
+ trb_buff_len = 0;
}
/* Only set interrupt on short packet for IN endpoints */
@@ -3176,7 +3188,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
if (running_total + trb_buff_len > urb->transfer_buffer_length)
trb_buff_len =
urb->transfer_buffer_length - running_total;
- } while (running_total < urb->transfer_buffer_length);
+ } while (num_trbs > 0);
check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
@@ -3194,7 +3206,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+ int last_trb;
bool more_trbs_coming;
+ bool zero_length_needed;
int start_cycle;
u32 field, length_field;
@@ -3225,7 +3239,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
- /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
+
+ /* Deal with URB_ZERO_PACKET - need one more td/trb */
+ zero_length_needed = (urb->transfer_flags & URB_ZERO_PACKET)
+ && !(urb->transfer_buffer_length % usb_endpoint_maxp(&urb->ep->desc));
+ if(zero_length_needed){
+ num_trbs++;
+ xhci_dbg(xhci, "Creating zero length td.\n");
+ }
ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
@@ -3255,7 +3276,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
trb_buff_len = urb->transfer_buffer_length;
first_trb = true;
-
+ last_trb = zero_length_needed ? 2 : 1;
/* Queue the first TRB, even if it's zero-length */
do {
u32 remainder = 0;
@@ -3272,12 +3293,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Chain all the TRBs together; clear the chain bit in the last
* TRB to indicate it's the last TRB in the chain.
*/
- if (num_trbs > 1) {
+
+ if (num_trbs > last_trb) {
field |= TRB_CHAIN;
- } else {
- /* FIXME - add check for ZERO_PACKET flag before this */
+ } else if (num_trbs == last_trb) {
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
+ } else if (zero_length_needed && num_trbs == 1) {
+ trb_buff_len = 0;
}
/* Only set interrupt on short packet for IN endpoints */
@@ -3315,7 +3338,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
trb_buff_len = urb->transfer_buffer_length - running_total;
if (trb_buff_len > TRB_MAX_BUFF_SIZE)
trb_buff_len = TRB_MAX_BUFF_SIZE;
- } while (running_total < urb->transfer_buffer_length);
+ } while (num_trbs > 0);
check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
--
2.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to linux.kernel | Previous | Next — Next in thread | Find similar | Unroll thread
[PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers Reyad Attiyat <reyad.attiyat@gmail.com> - 2015-06-29 03:00 +0200
Re: [PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers Mathias Nyman <mathias.nyman@intel.com> - 2015-06-29 17:50 +0200
Re: [PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers Reyad Attiyat <reyad.attiyat@gmail.com> - 2015-06-30 04:00 +0200
csiph-web