lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 29 Jun 2015 20:54:24 -0500
From:	Reyad Attiyat <reyad.attiyat@...il.com>
To:	Mathias Nyman <mathias.nyman@...el.com>
Cc:	gregkh@...uxfoundation.org, linux-usb@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2] usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers

Hey Mathias,

The intention is to send an extra endpoint packet of length zero as my
wireless card needs this to function properly. I have skimmed through
the xhci spec and assumed that each td would generate a packet. That
is why I do not chain the last trb or add a interrupt flag, since I
don't want to call the urb completion function called twice or called
with the incorrect td or length.

I have since tried a patch that just chains the trbs together, with
the zero-length trb, and this still creates a zero-length packet. I
was thinking I could remove the use of the last_trb variable I was
using and simply chain all the trbs together and place the interupt
flag on the zero-length trb if it exsits. Also I noticed that the
other host controller drivers (ehci and ohci) check to ensure that the
endpoint is sending data out and that the urb length is greater than
zero. I will add these checks as well to keep in line with the their
implementation.

Do you think this is the best method for creating a zero-length
packet, will every trb convert into at least one endpoint packet?

Thank you,
Reyad Attiyat



On Mon, Jun 29, 2015 at 10:48 AM, Mathias Nyman <mathias.nyman@...el.com> wrote:
> Hi
>
> On 29.06.2015 03:53, Reyad Attiyat wrote:
>> 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@...il.com>
>> ---
>
> Thanks for the patch.
> Generic idea and implementation looks good, there are some opens though
> See comments and questions inline.
>
>>  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;
>
> last_trb isn't a really a good name as it might be confused with td->last_trb.
> It's used for different purposes here.
>
>>       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));
>
> Please move the "&&" to end of previous line.
> (minor thing but helps readability)
>
> Checkpatch also complains about missing whitespaces in the if () statements.
>
>> +     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;
>>               }
>
> Normally chain bits are set for all TRBs except the last TRB, and the IOC (interrupt on completion)
> is usually set for only the last TRB.
>
> In case last_trb == 2, the chain bit is now not set between the TRB containing the last data
> and the actual last zero TRB, which is the last TRB in the TD.
> It now also sets the interrupt on completion (IOC) for the TRB with the last data,
> but not for the final last, zero lengt TRB in the TD.
>
> Is this intentional and how we want zero packet bulk transfers to behave?
>
> -Mathias
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ