Re: xHCI regression for VIA USB 3.0 controller in handle_cmd_completion

2014-05-30 Thread Xenia Ragiadakou

On 30/05/2014 04:13 πμ, Saran Neti wrote:

Hi Xenia,

Thanks for looking into this.

On Thu, May 29, 2014 at 6:31 PM, Xenia Ragiadakou burzalod...@gmail.com wrote:

I misunderstood the following description regarding the slot id field of
Command Completion Event TRB:

The Slot ID field shall be updated by the xHC to reflect the slot
associated with the
command that generated the event, with the following exceptions:
- The Slot ID shall be cleared to ‘0’ for No Op, Set Latency Tolerance
Value, Get Port
Bandwidth, and Force Event Commands.
- The Slot ID shall be set to the ID of the newly allocated Device Slot for
the Enable Slot
Command.
- The value of Slot ID shall be vendor defined when generated by a vendor
defined command.
This value is used as an index in the Device Context Base Address Array to
select the Device
Context of the source device. If this Event is due to a Host Controller
Command, then this field
shall be cleared to ‘0’.

The xhci spec rev1.0, for the Stop Endpoint Command, the Set TR Dequeue
Pointer Command and the Reset Endpoint Command, states explicitely that the
Command Completion Event placed on the Event Ring by the xHC shall have
initialized the Slot ID field to the value of the command’s Slot ID.
However, regarding the Reset Device Command it states that this field should
be cleared to zero. So, it was my mistake and your hardware is compatible
with the spec.



While the spec appears to be unambiguous about Slot ID for
Reset Device event TRB (always 0), in the case of
Set TR Dequeue Pointer Command, Section 4.6.10 says (in xHCI rev 1.1 -
is rev 1.0 similar?):

To issue a Set TR Dequeue Pointer Command system software shall
perform the following operations:
...
  Write the Host Controller Doorbell with DB Target = Host Controller Command
...

When a Set TR Dequeue Pointer Command is executed by the xHC it shall
perform the following operations:
...
  Slot ID = The value of the command?s Slot ID.
...

So, when xHC writes a Set TR Dequeue Pointer Command Completion Event
on the ring, there seem to be two different, possibly contradictory,
ways to do it:
1. Following 4.6.10, Slot ID = The value of the command?s Slot ID.
2. Following your quoted block of text from 6.4.2.2, If this Event is
due to a Host Controller Command, then this (Slot ID) field shall be
cleared to 0

Both statements use 'shall', which according Word Usage is the new
'must'. Is there a Section-wise precedence order for cases like this?

The other two commands - Stop Endpoint Command and Reset Endpoint
Command are also subject to the same conundrum, if indeed there is
one.

If I'm mistaken, the email + patch I sent yesterday should be ignored:
http://www.spinics.net/lists/linux-usb/msg108566.html



Hi Saran,

I think the same ambiguation in spec holds also for the cases of Disable 
Slot, Address Device, Configure Endpoint and Evaluate Context Command 
Completion Event TRBs that they were using already the completion 
event's Slot ID field, right? So, based on which criteria in some cases 
completion event's slot id field can be used and in others cannot? I 
don't know maybe Sarah or Mathias can clear that out.


regards,
Xenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: xHCI regression for VIA USB 3.0 controller in handle_cmd_completion

2014-05-29 Thread Xenia Ragiadakou

On 28/05/2014 07:26 πμ, Saran Neti wrote:

Hi,

My VIA USB 3.0 controller has stopped working in recent kernels. 
During boot,

dmesg shows a WARNING stack trace at drivers/usb/host/xhci-ring.c:1615
containing handle_cmd_completion+0xdc7/0x1000.

USB ports become unusable - mouse, keyboard and fdisking mass storage
devices all spew error messages and stack traces followed by logs of
device resets.

Git-bisection from 3.10 to 3.14 for drivers/usb/host points to 
20e7acb13ff48,
which commit message appears to indicate that the VIA controller in 
question

may not be xhci spec rev1.0-compliant.

I'm not sure what Linux's policy on regression for non-compliant hardware
is, but it'll save me the trouble of patching/building a kernel each time
if you can revert, or otherwise fix this.

Thanks



Hi Saran,

Thanks for reporting this. I read again the spec and I realized that 
using the slot id field of the event TRB for a Reset Device Command was 
a mistake.


I misunderstood the following description regarding the slot id field of 
Command Completion Event TRB:
The Slot ID field shall be updated by the xHC to reflect the slot 
associated with the

command that generated the event, with the following exceptions:
- The Slot ID shall be cleared to ‘0’ for No Op, Set Latency Tolerance 
Value, Get Port

Bandwidth, and Force Event Commands.
- The Slot ID shall be set to the ID of the newly allocated Device Slot 
for the Enable Slot

Command.
- The value of Slot ID shall be vendor defined when generated by a 
vendor defined command.
This value is used as an index in the Device Context Base Address Array 
to select the Device
Context of the source device. If this Event is due to a Host Controller 
Command, then this field

shall be cleared to ‘0’.

The xhci spec rev1.0, for the Stop Endpoint Command, the Set TR Dequeue 
Pointer Command
and the Reset Endpoint Command, states explicitely that the Command 
Completion Event
placed on the Event Ring by the xHC shall have initialized the Slot ID 
field to the value of the
command’s Slot ID. However, regarding the Reset Device Command it states 
that this field
should be cleared to zero. So, it was my mistake and your hardware is 
compatible with the

spec.

Hence, either the patch can be reverted or I can send a patch to replace:

case TRB_RESET_DEV:
WARN_ON(slot_id != TRB_TO_SLOT_ID(
le32_to_cpu(cmd_trb-generic.field[3])));
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;

with:

case TRB_RESET_DEV:
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(cmd_trb-generic.field[3]));
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;

I cc Sarah Sharp and Mathias Nyman to decide which is the best way to 
revert this regression.


regards,
Xenia


--- Bisection details ---

# git bisect log
git bisect start '--' 'drivers/usb/host/'
# good: [8bb495e3f02401ee6f76d1b1d77f3ac9f079e376]
Linux 3.10
git bisect good 8bb495e3f02401ee6f76d1b1d77f3ac9f079e376
# bad: [455c6fdbd219161bd09b1165f11699d6d73de11c]
Linux 3.14
git bisect bad 455c6fdbd219161bd09b1165f11699d6d73de11c
# good: [40b3dc6da05c4ac0e317723a22eaa807c4b98648]
usb: pci-quirks: amd_chipset_sb_type_init() can be static
git bisect good 40b3dc6da05c4ac0e317723a22eaa807c4b98648
# bad: [9b547a882e9ffec67bb41a4e66b4bcc0e91a2737]
usb: r8a66597-hcd: Convert to clk_prepare/unprepare
git bisect bad 9b547a882e9ffec67bb41a4e66b4bcc0e91a2737
# good: [a393a807d0c805e7c723315ff0e88a857055e9c6]
USB: EHCI: start new isochronous streams ASAP
git bisect good a393a807d0c805e7c723315ff0e88a857055e9c6
# bad: [a2cdc3432c361bb885476d1c625e22b518e0bc07]
usb: xhci: remove the unused -address field
git bisect bad a2cdc3432c361bb885476d1c625e22b518e0bc07
# bad: [20e7acb13ff48fbc884d5918c3697c27de63922a]
xhci: use completion event's slot id rather than dig it out of command
git bisect bad 20e7acb13ff48fbc884d5918c3697c27de63922a
# good: [d194c031994d3fc1038fa09e9e92d9be24a21921]
xhci: correct the usage of USB_CTRL_SET_TIMEOUT
git bisect good d194c031994d3fc1038fa09e9e92d9be24a21921
# good: [b244b431f89e152dd4bf35d71786f1c0eb8cba7e]
xhci: refactor TRB_ENABLE_SLOT case into function
git bisect good b244b431f89e152dd4bf35d71786f1c0eb8cba7e
# good: [9b3103ac9d19525781c297c4fb1e544e077c8901]
xhci: refactor TRB_ADDR_DEV case into function
git bisect good 9b3103ac9d19525781c297c4fb1e544e077c8901
# first bad commit: [20e7acb13ff48fbc884d5918c3697c27de63922a]
xhci: use completion event's slot id rather than dig it out of command

# git show 20e7acb13ff48fbc884d5918c3697c27de63922a
commit 20e7acb13ff48fbc884d5918c3697c27de63922a
Author: Xenia Ragiadakou burzalod...@gmail.com 
mailto:burzalod...@gmail.com

Date:   Mon Sep 9 13:29:50 2013 +0300

 xhci: use completion event's slot id rather than dig it out of command
 Since the slot id retrieved from the Reset Device TRB matches the 
slot id in
 the command completion event, which is available, there is no need to 
determine

 it again.
 This patch removes

Re: xhci regression since xhci: replace xhci_write_64() with writeq() - devices not detected

2014-01-30 Thread Xenia Ragiadakou

On 30/01/2014 11:21 πμ, Rafał Miłecki wrote:

2014-01-29 Xenia Ragiadakou burzalod...@gmail.com:

Rafał is it possible to send all the bad output with xhci debugging on?
Since your config file shows that dynamic debugging is on, that would be
easy to do by adding dyndbg='module xhci_hcd +p' or xhci_hcd.dyndbg=+p boot
option to your linux command line.
Also, I am interested in the lspci -v output related to your usb3
controllers.

Sure. I booted without any USB device connected and then with
04d8:00df connected to the USB 3.0 port.

I also attach full lspci output (with -nnv) just in case.



Thanks a lot! The following logs show that definitely something does not 
go well when you perform 64bit mmio transfers:


[snip]
[2.599818] xhci_hcd :04:00.0: // Setting command ring address to 
0x20
[2.649882] xhci_hcd :04:00.0: // xHC command ring deq ptr low 
bits + flags = @
[2.649884] xhci_hcd :04:00.0: // xHC command ring deq ptr high 
bits = @

[snip]
[2.850199] xhci_hcd :04:00.0: ERST deq = 64'hfff0
[2.850202] xhci_hcd :04:00.0: // Set the interrupt modulation 
register

[2.850210] xhci_hcd :04:00.0: // Enable interrupts, cmd = 0x4.
[2.850215] xhci_hcd :04:00.0: // Enabling event ring interrupter 
c900056f1020 by writing 0x2 to irq_pending

[2.850221] xhci_hcd :04:00.0:   c900056f1020: ir_set[0]
[2.850223] xhci_hcd :04:00.0:   c900056f1020: ir_set.pending 
= 0x2
[2.850227] xhci_hcd :04:00.0:   c900056f1024: ir_set.control 
= 0xa0
[2.850232] xhci_hcd :04:00.0:   c900056f1028: 
ir_set.erst_size = 0x1
[2.900268] xhci_hcd :04:00.0:   c900056f1030: 
ir_set.erst_base = @
[2.950340] xhci_hcd :04:00.0:   c900056f1038: 
ir_set.erst_dequeue = @

[snip]

And since after reverting the writeq patch, everything works then for 
sure writeq does not seem to work as I expected. Probably the 64bit 
transaction on the bus is not atomic, but David seems to understand 
better what could be the reason for that problem.


Another thing is whether readq works correctly. According to xhci specs, 
the bits of the command ring control register when read should return 
always 0 (except from the bit 3).
So, i wonder why readq returns 0x (xHC command ring deq 
ptr low bits + flags = @, xHC command ring deq ptr high bits = 
@).


Still I cannot understand though why ordered split transfers are 
necessary for 32bit capable usb3.0 host controllers. Maybe the ordered 
32bit transfers its a requirement by some usb3.0 host controllers in 
order to read/write 64bit fields, regardless their addressing capability.


best regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: xhci regression since xhci: replace xhci_write_64() with writeq() - devices not detected

2014-01-30 Thread Xenia Ragiadakou

On 30/01/2014 12:00 πμ, Sarah Sharp wrote:

On Wed, Jan 29, 2014 at 12:50:04PM +0200, Xenia Ragiadakou wrote:

On 29/01/2014 12:08 μμ, Rafał Miłecki wrote:

I've enabled some debugging in xhci-dbg.c, does it help?
xhci_hcd :04:00.0: xHCI capability registers at c90004e6:
xhci_hcd :04:00.0: CAPLENGTH AND HCIVERSION 0x960020:
xhci_hcd :04:00.0: CAPLENGTH: 0x20
xhci_hcd :04:00.0: HCIVERSION: 0x96
xhci_hcd :04:00.0: HCSPARAMS 1: 0x4000820
xhci_hcd :04:00.0:   Max device slots: 32
xhci_hcd :04:00.0:   Max interrupters: 8
xhci_hcd :04:00.0:   Max ports: 4
xhci_hcd :04:00.0: HCSPARAMS 2: 0x17f1
xhci_hcd :04:00.0:   Isoc scheduling threshold: 1
xhci_hcd :04:00.0:   Maximum allowed segments in event ring: 15
xhci_hcd :04:00.0: HCSPARAMS 3 0x0:
xhci_hcd :04:00.0:   Worst case U1 device exit latency: 0
xhci_hcd :04:00.0:   Worst case U2 device exit latency: 0
xhci_hcd :04:00.0: HCC PARAMS 0x200f180:
xhci_hcd :04:00.0:   HC generates 32 bit addresses
xhci_hcd :04:00.0:   FIXME: more HCCPARAMS debugging
xhci_hcd :04:00.0: RTSOFF 0x1000:


Hi Rafał,

Like Bjørn already pointed out, I think too the problem is that the
USB3.0 host controller does not support 64 bit addressing (this can
be seen from the first bit of HCC PARAMS that is 0) but the patch
does not take it into account and blindly tries to perform 64bit
write accesses just because your system is 64bit. My mistake. I will
try to find a solution for that and send a patch when I ll return
home.

I think the solution should be to just revert the writeq patch, and
leave the xhci_write64 in place.  We can always optimize that function
later to do a writeq if the host supports 64-bit writes, but we'll have
to analyze whether the performance impact of doing so makes sense.

Sarah Sharp


I think another solution could be to undefine writeq just before 
including asm-generic/io-64-nonatomic-lo-hi.h header file, so that the 
readq gets defined as two 32bit writes in low-high order.
If you think that that could be a solution, tell me and I can send a 
patch to Rafał to test it when he has time.


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: xhci regression since xhci: replace xhci_write_64() with writeq() - devices not detected

2014-01-30 Thread Xenia Ragiadakou

On 30/01/2014 07:42 μμ, Xenia Ragiadakou wrote:

On 30/01/2014 12:00 πμ, Sarah Sharp wrote:

On Wed, Jan 29, 2014 at 12:50:04PM +0200, Xenia Ragiadakou wrote:

On 29/01/2014 12:08 μμ, Rafał Miłecki wrote:

I've enabled some debugging in xhci-dbg.c, does it help?
xhci_hcd :04:00.0: xHCI capability registers at c90004e6:
xhci_hcd :04:00.0: CAPLENGTH AND HCIVERSION 0x960020:
xhci_hcd :04:00.0: CAPLENGTH: 0x20
xhci_hcd :04:00.0: HCIVERSION: 0x96
xhci_hcd :04:00.0: HCSPARAMS 1: 0x4000820
xhci_hcd :04:00.0:   Max device slots: 32
xhci_hcd :04:00.0:   Max interrupters: 8
xhci_hcd :04:00.0:   Max ports: 4
xhci_hcd :04:00.0: HCSPARAMS 2: 0x17f1
xhci_hcd :04:00.0:   Isoc scheduling threshold: 1
xhci_hcd :04:00.0:   Maximum allowed segments in event ring: 15
xhci_hcd :04:00.0: HCSPARAMS 3 0x0:
xhci_hcd :04:00.0:   Worst case U1 device exit latency: 0
xhci_hcd :04:00.0:   Worst case U2 device exit latency: 0
xhci_hcd :04:00.0: HCC PARAMS 0x200f180:
xhci_hcd :04:00.0:   HC generates 32 bit addresses
xhci_hcd :04:00.0:   FIXME: more HCCPARAMS debugging
xhci_hcd :04:00.0: RTSOFF 0x1000:


Hi Rafał,

Like Bjørn already pointed out, I think too the problem is that the
USB3.0 host controller does not support 64 bit addressing (this can
be seen from the first bit of HCC PARAMS that is 0) but the patch
does not take it into account and blindly tries to perform 64bit
write accesses just because your system is 64bit. My mistake. I will
try to find a solution for that and send a patch when I ll return
home.

I think the solution should be to just revert the writeq patch, and
leave the xhci_write64 in place.  We can always optimize that function
later to do a writeq if the host supports 64-bit writes, but we'll have
to analyze whether the performance impact of doing so makes sense.

Sarah Sharp


I think another solution could be to undefine writeq just before 
including asm-generic/io-64-nonatomic-lo-hi.h header file, so that 
the readq gets defined as two 32bit writes in low-high order.
If you think that that could be a solution, tell me and I can send a 
patch to Rafał to test it when he has time.


regards,
ksenia


Well, actually a simple undef won't work here because 
asm-generic/io-64-nonatomic-lo-hi.h includes linux/io.h which defines 
writeq for 64bit systems. So the revert would be necessary i guess :(


ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: xhci regression since xhci: replace xhci_write_64() with writeq() - devices not detected

2014-01-29 Thread Xenia Ragiadakou

On 29/01/2014 12:08 μμ, Rafał Miłecki wrote:

2014-01-29 David Laight david.lai...@aculab.com:

Maybe I misunderstand something, but won't that commit end up replacing
the previous pair of writel() with a single native writeq() on 64bit
platforms?

Judging by the comment in front of the xhci_write_64(), that might not
necessarily be supported on all xHCI implementations:

  * Some xHCI implementations may support 64-bit address pointers.  Registers
  * with 64-bit address pointers should be written to with dword accesses by
  * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
  * xHCI implementations that do not support 64-bit address pointers will ignore
  * the high dword, and write order is irrelevant.

I wonder if (some of) these implementations actually depend on this
two-cycle write, making __raw_writeq() fail?

I think this is a 32bit kernel on hardware that would support a 64bit one.

This is notebook with i7-2670QM, see cpuinfo.txt for details.
I use x86_64 kernel:
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
(see attached config for details).



So the xhci controller supports 64 bits addressing (etc) but the cpu doesn't
have a 64bit write, so writeq() will do two 32bit accesses.
ISTR that these are in the correct order.
I assume the required compiler barrier is present.

I've enabled some debugging in xhci-dbg.c, does it help?
xhci_hcd :04:00.0: xHCI capability registers at c90004e6:
xhci_hcd :04:00.0: CAPLENGTH AND HCIVERSION 0x960020:
xhci_hcd :04:00.0: CAPLENGTH: 0x20
xhci_hcd :04:00.0: HCIVERSION: 0x96
xhci_hcd :04:00.0: HCSPARAMS 1: 0x4000820
xhci_hcd :04:00.0:   Max device slots: 32
xhci_hcd :04:00.0:   Max interrupters: 8
xhci_hcd :04:00.0:   Max ports: 4
xhci_hcd :04:00.0: HCSPARAMS 2: 0x17f1
xhci_hcd :04:00.0:   Isoc scheduling threshold: 1
xhci_hcd :04:00.0:   Maximum allowed segments in event ring: 15
xhci_hcd :04:00.0: HCSPARAMS 3 0x0:
xhci_hcd :04:00.0:   Worst case U1 device exit latency: 0
xhci_hcd :04:00.0:   Worst case U2 device exit latency: 0
xhci_hcd :04:00.0: HCC PARAMS 0x200f180:
xhci_hcd :04:00.0:   HC generates 32 bit addresses
xhci_hcd :04:00.0:   FIXME: more HCCPARAMS debugging
xhci_hcd :04:00.0: RTSOFF 0x1000:



Hi Rafał,

Like Bjørn already pointed out, I think too the problem is that the 
USB3.0 host controller does not support 64 bit addressing (this can be 
seen from the first bit of HCC PARAMS that is 0) but the patch does not 
take it into account and blindly tries to perform 64bit write accesses 
just because your system is 64bit. My mistake. I will try to find a 
solution for that and send a patch when I ll return home.


best regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: xhci regression since xhci: replace xhci_write_64() with writeq() - devices not detected

2014-01-29 Thread Xenia Ragiadakou

On 29/01/2014 01:43 μμ, David Laight wrote:

From: Xenia Ragiadakou

On 29/01/2014 12:08 μμ, Rafał Miłecki wrote:

2014-01-29 David Laight david.lai...@aculab.com:

Maybe I misunderstand something, but won't that commit end up replacing
the previous pair of writel() with a single native writeq() on 64bit
platforms?

Judging by the comment in front of the xhci_write_64(), that might not
necessarily be supported on all xHCI implementations:

   * Some xHCI implementations may support 64-bit address pointers.  Registers
   * with 64-bit address pointers should be written to with dword accesses by
   * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
   * xHCI implementations that do not support 64-bit address pointers will 
ignore
   * the high dword, and write order is irrelevant.

I wonder if (some of) these implementations actually depend on this
two-cycle write, making __raw_writeq() fail?

...

This is notebook with i7-2670QM, see cpuinfo.txt for details.
I use x86_64 kernel:
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
(see attached config for details).



So the xhci controller supports 64 bits addressing (etc) but the cpu doesn't
have a 64bit write, so writeq() will do two 32bit accesses.
ISTR that these are in the correct order.
I assume the required compiler barrier is present.

I've enabled some debugging in xhci-dbg.c, does it help?
xhci_hcd :04:00.0: xHCI capability registers at c90004e6:
xhci_hcd :04:00.0: CAPLENGTH AND HCIVERSION 0x960020:
xhci_hcd :04:00.0: CAPLENGTH: 0x20
xhci_hcd :04:00.0: HCIVERSION: 0x96
xhci_hcd :04:00.0: HCSPARAMS 1: 0x4000820

...

Like Bjørn already pointed out, I think too the problem is that the
USB3.0 host controller does not support 64 bit addressing (this can be
seen from the first bit of HCC PARAMS that is 0) but the patch does not
take it into account and blindly tries to perform 64bit write accesses
just because your system is 64bit. My mistake. I will try to find a
solution for that and send a patch when I ll return home.

I'm suffering from 'brain-fade' again.
The USB3 support on recent intel systems is in the chipset, not the cpu.
For some reason I've been thinking that it is cpu related.

So if you have a 32-bit xhci controller you'd think it would be a 32bit
slave and the something would split the 64bit cycle into two 32bit ones.
That would always happen on earlier systems for (say) 8 bit peripherals.

However I believe PCIe is always 64bit. If you do a 32bit write the target
actually sees a 64bit write with 4 byte enables asserted.
(This has causes confusion on some fpga PCIe slaves that then generate
two 32bit writes (to the internal components) one of which has no asserted
byte enables.)
This probably means that a 64bit write is never split before reaching the
PCIe slave.
In reality, if the slave needs the transfer split by the host then it
is badly broken!

Due to the high latency of PCIe transfers, you probably don't want to be
doing two transfers on systems where a single transfer will work.

It might be that support for 64bit transfers can be determined at run time
(to avoid a big quirk table). A global flag is probably fine as well.

David


Hi David,

I'm suffering from brain-fade, not you :) Sorry for being late.
I take back what I've said. Now I'm thinking that, performing 64bit 
transfers instead of ordered 32bit transfers, has nothing to do with 
whether the host controller supports 64bit addressing or not. The 64bit 
addressing capability enables the host controller to perform DMA 
transfers to higher memory addresses so some fields that correspond to 
DMA addresses are 64bit. These fields can be accesses either with 64bit 
transfers or with ordered 32bit transfers.


So the read/write order matters when we have a host controller capable 
of 64bit addressing but our system can perform only 32bit transfers. In 
that case, we need to read/write the 64bit values (which correspond to 
64bit pointers) in 32bit chunks with specific order.


If the system is 64bit but the host controller can address only 32bit 
addresses, then the values to be written with writeq should be actually 
32bit. And even if they are written as 64bit values, the host controller 
will ignore the higher order 32bit (that will be zeroes) anyway, so the 
order does not matter.


Since Rafał's system seems to fit to the second case, I am no sure yet 
why the patch caused problems. Maybe Sarah can figure out what s wrong.


Also, if the system is 64bit and the host controller is 64bit capable, 
the host controller will see the 64bit transfers as atomic, no? Is there 
still the need to impose a split transfer with specific order?


Rafał is it possible to send all the bad output with xhci debugging 
on? Since your config file shows that dynamic debugging is on, that 
would be easy to do by adding dyndbg='module xhci_hcd +p' or 
xhci_hcd.dyndbg=+p boot option to your linux command line.
Also, I am interested

Re: xhci_hcd and Canon Lide 110 not playing well together

2014-01-08 Thread Xenia Ragiadakou

On 07/01/2014 11:46 μμ, Sarah Sharp wrote:

On Wed, Dec 25, 2013 at 09:51:28PM -0500, Alan Stern wrote:

Okay, now we know that usb_enable_interface takes a long time.  That
routine does nothing but call usb_enable_endpoint, which does nothing
but call usb_hcd_reset_endpoint, which calls the xhci_endpoint_reset
routine.

So we have traced the problem into xhci-hcd.  You could trace it
farther down if you want, but at this point it probably would be more
productive to see what Sarah has to say.  She may know about some new
changes that are not yet available in the development kernel.

I suspect the patch I asked Matthias and Holger to apply [1] has some
issues, and it's entirely possible that there's deadlocks.  One other
tester (Michal) confirms it fixes his issue with a Samsung scanner, but
the patch leads to list corruption in some xHCI structures:

https://bugzilla.kernel.org/show_bug.cgi?id=47421

In any case, all three testers (Matthias, Holger, and Michal) confirm
the patch fixes the underlying issue.  So we just need to get the
remaining race conditions and locking issues fixed up.

Xenia, would you mind if Dan or I finished your patch?  I know you don't
have much time for xHCI work since you started your new job.

Sarah Sharp

[1] http://marc.info/?l=linux-usbm=138116117104619w=2


Yes, sure you can finish the patch.

regards,
xenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] xhci: fix reset for not halted endpoints

2013-11-25 Thread Xenia Ragiadakou

On 11/25/2013 04:41 AM, Alan Stern wrote:

On Mon, 25 Nov 2013, Xenia Ragiadakou wrote:


You can simplify part of the problem by not allowing an endpoint to be
reset if it has any pending URBs.  Just fail the reset in this case.

Yes, you are right since, from what i understand, it is the
responsibility of the device driver to unlink any pending URBs before
issuing a clear halt to the endpoint. So we expect the device driver to
call usb_unlink_urb() for each pending URB, which in turn calls

Actually you should expect the driver to call usb_kill_urb(), not
usb_unlink_urb().  The difference is that usb_kill_urb() waits for the
URB to complete.


xhci_urb_dequeue(). The function xhci_urb_dequeue() will add the URB to
endpoint's cancelled_td_list and will issue a Stop Endpoint command. The
completion handler of the Stop Endpoint command,
xhci_handle_cmd_stop_ep(), will eventually remove the unlinked URBs from
endpoint's both cancelled_td_list and td_list and give them back to core.
However, since xhci_urb_dequeue() does not wait on the completion of the
Stop Endpoint command, it is still possible for the URB not to have been
removed yet from the td_list when the xhci_reset_endpoint() is called,
right?

Not if the driver uses usb_kill_urb().  In that case the URB will
already be removed from the td_list.


In that case, is it better to check if td_list is not empty and fail the
reset after xhci_stop_endpoint_for_config() rather than before?

It probably doesn't matter.


Also, regarding the case that there is an attempt to enqueue a URB while
the endpoint is being reset, is it ok to fail the enqueue by adding a
check in prepare_ring() to fail when the endpoint's state is
EP_CONFIG_PENDING ?

That's up to Sarah (but I can't think of any alternative).  If you
decide to do this, add an explanation of the new error code to
Documentation/usb/error-codes.txt.

Alan Stern



Thanks Alan for your explanation, i understand better now how to handle 
this.


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] xhci: fix reset for not halted endpoints

2013-11-25 Thread Xenia Ragiadakou

On 11/25/2013 04:44 AM, Alan Stern wrote:

On Mon, 25 Nov 2013, Xenia Ragiadakou wrote:


On 11/25/2013 01:50 AM, Xenia Ragiadakou wrote:

[snip]

Also, while you're going through the whole remove-and-add procedure for
endpoints that aren't halted, do you want to hold the bandwidth mutex?
If the procedure isn't atomic, there's a possibility that some other
device could change configs in the middle.  This would also prevent
concurrent altsetting changes.

Yes, i need to lock the bandwidth_mutex. I will fix this.


Alan Stern

After i looked at it more carefully, there will be a deadlock if i try
to aqcuire the bandwidth_mutex in reset endpoint code.
In usb_set_configuration(), the bandwidth_mutex is held while
usb_enable_interface() is called for each interface and
usb_enable_interface() will attempt to reset the endpoints via
usb_enable_endpoint() since the 3rd argument is set to true.
So, I think it's not a good idea to try to lock the bandwidth_mutex
given that, right?

Right.  We don't have to worry about config changes anyway, because the
config can't be changed until all the old endpoints are disabled.  You
just have to make sure that an endpoint can't be disabled until a
pending reset is finished.

Alan Stern



Actually, xhci driver does not implement endpoint_disable(). So, how can 
I force the disable not to be finished until the pending reset is 
finished? The only way i see is by implementing endpoint_disable() 
callback for xhci. Do you have something else in mind maybe?
Also, probably there was an implementation for it, 
xhci_endpoint_disable(), but it seems to have been reverted. I just saw 
this function name to appear in a comment in xhci_add_endpoint().


thanks,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] xhci: fix reset for not halted endpoints

2013-11-24 Thread Xenia Ragiadakou

Hi Alan and Sarah,

Sorry for my late response but i had some personal issues that held me 
back for a while.

My comments follow below.

On 10/17/2013 06:11 PM, Alan Stern wrote:

On Wed, 16 Oct 2013, Sarah Sharp wrote:


I think there's some nasty race conditions here.  There's several
different structures this code and other functions are manipulating:

  - the endpoint ring contents
  - the endpoint ring dequeue pointer
  - the endpoint's cur_td and cancelled_td lists

The other functions you need to look at are xhci_urb_enqueue,
xhci_urb_dequeue, and xhci_handle_cmd_stop_ep.  Arguably, we should be
doing something about drivers attempting to change alternate interface
settings at the same time they're resetting endpoints, but I think the
solution should be that drivers just shouldn't do that.  However, we do
need to handle the case where the reset endpoint races with URB
cancellation and enqueue.

You can simplify part of the problem by not allowing an endpoint to be
reset if it has any pending URBs.  Just fail the reset in this case.


Yes, you are right since, from what i understand, it is the 
responsibility of the device driver to unlink any pending URBs before 
issuing a clear halt to the endpoint. So we expect the device driver to 
call usb_unlink_urb() for each pending URB, which in turn calls 
xhci_urb_dequeue(). The function xhci_urb_dequeue() will add the URB to 
endpoint's cancelled_td_list and will issue a Stop Endpoint command. The 
completion handler of the Stop Endpoint command, 
xhci_handle_cmd_stop_ep(), will eventually remove the unlinked URBs from 
endpoint's both cancelled_td_list and td_list and give them back to core.
However, since xhci_urb_dequeue() does not wait on the completion of the 
Stop Endpoint command, it is still possible for the URB not to have been 
removed yet from the td_list when the xhci_reset_endpoint() is called, 
right?
In that case, is it better to check if td_list is not empty and fail the 
reset after xhci_stop_endpoint_for_config() rather than before?



Also, while you're going through the whole remove-and-add procedure for
endpoints that aren't halted, do you want to hold the bandwidth mutex?
If the procedure isn't atomic, there's a possibility that some other
device could change configs in the middle.  This would also prevent
concurrent altsetting changes.


Yes, i need to lock the bandwidth_mutex. I will fix this.


Alan Stern


Also, regarding the case that there is an attempt to enqueue a URB while 
the endpoint is being reset, is it ok to fail the enqueue by adding a 
check in prepare_ring() to fail when the endpoint's state is 
EP_CONFIG_PENDING ?


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] xhci: fix reset for not halted endpoints

2013-11-24 Thread Xenia Ragiadakou

On 11/25/2013 01:50 AM, Xenia Ragiadakou wrote:

[snip]

Also, while you're going through the whole remove-and-add procedure for
endpoints that aren't halted, do you want to hold the bandwidth mutex?
If the procedure isn't atomic, there's a possibility that some other
device could change configs in the middle.  This would also prevent
concurrent altsetting changes.


Yes, i need to lock the bandwidth_mutex. I will fix this.


Alan Stern


After i looked at it more carefully, there will be a deadlock if i try 
to aqcuire the bandwidth_mutex in reset endpoint code.
In usb_set_configuration(), the bandwidth_mutex is held while 
usb_enable_interface() is called for each interface and 
usb_enable_interface() will attempt to reset the endpoints via 
usb_enable_endpoint() since the 3rd argument is set to true.
So, I think it's not a good idea to try to lock the bandwidth_mutex 
given that, right?


ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 03/21] xhci: fix incorrect type in assignment in xhci_address_device()

2013-11-14 Thread Xenia Ragiadakou

On 11/14/2013 10:52 PM, Sarah Sharp wrote:

Hi Xenia,

This patch doesn't apply any more either, could you resend when you have
time?

Thanks,
Sarah Sharp


Yes, sure! Do you want me to resend all the patch series or just the 
individual patches?


regards,
ksenia



On Mon, Sep 09, 2013 at 09:03:08PM +0300, Xenia Ragiadakou wrote:

The field 'dev_info' in struct xhci_slot_ctx has type __le32 and it needs
to be converted to CPU byteorder for the correct retrieval of its subfield
'Context Entries'. This field is used by the trace event 'xhci_address_ctx'
to trace only the contexts of valid endpoints.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
  drivers/usb/host/xhci.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index bda0cdf..9f22ddf 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3762,7 +3762,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
xhci_dbg(xhci, Slot ID %d Input Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-in_ctx, 2);
trace_xhci_address_ctx(xhci, virt_dev-in_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
  
  	spin_lock_irqsave(xhci-lock, flags);

cmd_trb = xhci-cmd_ring-dequeue;
@@ -3841,7 +3841,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
xhci_dbg(xhci, Slot ID %d Input Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-in_ctx, 2);
trace_xhci_address_ctx(xhci, virt_dev-in_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
xhci_dbg(xhci, Slot ID %d Output Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-out_ctx, 2);
/*
@@ -3850,7 +3850,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
 */
slot_ctx = xhci_get_slot_ctx(xhci, virt_dev-out_ctx);
trace_xhci_address_ctx(xhci, virt_dev-out_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
/* Use kernel assigned address for devices; store xHC assigned
 * address locally. */
virt_dev-address = (le32_to_cpu(slot_ctx-dev_state)  DEV_ADDR_MASK)
--
1.8.3.4



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2] xhci: fix incorrect type in assignment in xhci_address_device()

2013-11-14 Thread Xenia Ragiadakou
The field 'dev_info' in struct xhci_slot_ctx has type __le32 and it needs
to be converted to CPU byteorder for the correct retrieval of its subfield
'Context Entries'. This field is used by the trace event 'xhci_address_ctx'
to trace only the contexts of valid endpoints.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Changes from v1:
  * fix patch to apply cleanly on for-usb-next-queue branch of xhci tree

 drivers/usb/host/xhci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 1d26b3f..900ba36 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3771,7 +3771,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
xhci_dbg(xhci, Slot ID %d Input Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-in_ctx, 2);
trace_xhci_address_ctx(xhci, virt_dev-in_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
 
spin_lock_irqsave(xhci-lock, flags);
cmd_trb = xhci_find_next_enqueue(xhci-cmd_ring);
@@ -3850,7 +3850,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
xhci_dbg(xhci, Slot ID %d Input Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-in_ctx, 2);
trace_xhci_address_ctx(xhci, virt_dev-in_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
xhci_dbg(xhci, Slot ID %d Output Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-out_ctx, 2);
/*
@@ -3859,7 +3859,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
 */
slot_ctx = xhci_get_slot_ctx(xhci, virt_dev-out_ctx);
trace_xhci_address_ctx(xhci, virt_dev-out_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
/* Zero the input context control for later use */
ctrl_ctx-add_flags = 0;
ctrl_ctx-drop_flags = 0;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2] xhci: remove conversion from generic to pci device in xhci_mem.c

2013-11-14 Thread Xenia Ragiadakou
This patch removes the to_pci_dev() conversion performed to generic struct
device since it is not actually useful (the pointer to the generic device
can be used directly rather through a conversion to pci_dev) and it is pci
bus specific.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Changes from v1:
  * fix patch to apply cleanly on for-usb-next-queue branch of xhci tree

 drivers/usb/host/xhci-mem.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1445e08..99e7251 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -433,10 +433,10 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
unsigned int num_stream_ctxs,
struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
 {
-   struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)-self.controller);
+   struct device *dev = xhci_to_hcd(xhci)-self.controller;
 
if (num_stream_ctxs  MEDIUM_STREAM_ARRAY_SIZE)
-   dma_free_coherent(pdev-dev,
+   dma_free_coherent(dev,
sizeof(struct xhci_stream_ctx)*num_stream_ctxs,
stream_ctx, dma);
else if (num_stream_ctxs = SMALL_STREAM_ARRAY_SIZE)
@@ -461,10 +461,10 @@ static struct xhci_stream_ctx 
*xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
unsigned int num_stream_ctxs, dma_addr_t *dma,
gfp_t mem_flags)
 {
-   struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)-self.controller);
+   struct device *dev = xhci_to_hcd(xhci)-self.controller;
 
if (num_stream_ctxs  MEDIUM_STREAM_ARRAY_SIZE)
-   return dma_alloc_coherent(pdev-dev,
+   return dma_alloc_coherent(dev,
sizeof(struct xhci_stream_ctx)*num_stream_ctxs,
dma, mem_flags);
else if (num_stream_ctxs = SMALL_STREAM_ARRAY_SIZE)
@@ -1616,7 +1616,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)
 {
int num_sp;
int i;
-   struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)-self.controller);
+   struct device *dev = xhci_to_hcd(xhci)-self.controller;
 
if (!xhci-scratchpad)
return;
@@ -1624,13 +1624,13 @@ static void scratchpad_free(struct xhci_hcd *xhci)
num_sp = HCS_MAX_SCRATCHPAD(xhci-hcs_params2);
 
for (i = 0; i  num_sp; i++) {
-   dma_free_coherent(pdev-dev, xhci-page_size,
+   dma_free_coherent(dev, xhci-page_size,
xhci-scratchpad-sp_buffers[i],
xhci-scratchpad-sp_dma_buffers[i]);
}
kfree(xhci-scratchpad-sp_dma_buffers);
kfree(xhci-scratchpad-sp_buffers);
-   dma_free_coherent(pdev-dev, num_sp * sizeof(u64),
+   dma_free_coherent(dev, num_sp * sizeof(u64),
xhci-scratchpad-sp_array,
xhci-scratchpad-sp_dma);
kfree(xhci-scratchpad);
@@ -1692,7 +1692,7 @@ void xhci_free_command(struct xhci_hcd *xhci,
 
 void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
-   struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)-self.controller);
+   struct device   *dev = xhci_to_hcd(xhci)-self.controller;
struct xhci_cd  *cur_cd, *next_cd;
int size;
int i, j, num_ports;
@@ -1700,7 +1700,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
/* Free the Event Ring Segment Table and the actual Event Ring */
size = sizeof(struct xhci_erst_entry)*(xhci-erst.num_entries);
if (xhci-erst.entries)
-   dma_free_coherent(pdev-dev, size,
+   dma_free_coherent(dev, size,
xhci-erst.entries, xhci-erst.erst_dma_addr);
xhci-erst.entries = NULL;
xhci_dbg_trace(xhci, trace_xhci_dbg_init, Freed ERST);
@@ -1748,7 +1748,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
Freed medium stream array pool);
 
if (xhci-dcbaa)
-   dma_free_coherent(pdev-dev, sizeof(*xhci-dcbaa),
+   dma_free_coherent(dev, sizeof(*xhci-dcbaa),
xhci-dcbaa, xhci-dcbaa-dma);
xhci-dcbaa = NULL;
 
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 1/4] xhci: replace xhci_readl() with readl()

2013-11-14 Thread Xenia Ragiadakou
Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it. xhci_readl() internally simply calls readl(). This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.

Remove the unnecessary xhci_readl() wrapper function and replace its calls to
with calls to readl() to make the code more straightforward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-dbg.c  | 36 +--
 drivers/usb/host/xhci-hub.c  | 71 ++--
 drivers/usb/host/xhci-mem.c  | 20 +--
 drivers/usb/host/xhci-ring.c | 12 +++
 drivers/usb/host/xhci.c  | 86 ++--
 drivers/usb/host/xhci.h  |  5 ---
 6 files changed, 112 insertions(+), 118 deletions(-)

diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 73503a8..eb009a4 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -32,7 +32,7 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)
 
xhci_dbg(xhci, // xHCI capability registers at %p:\n,
xhci-cap_regs);
-   temp = xhci_readl(xhci, xhci-cap_regs-hc_capbase);
+   temp = readl(xhci-cap_regs-hc_capbase);
xhci_dbg(xhci, // @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n,
xhci-cap_regs-hc_capbase, temp);
xhci_dbg(xhci, //   CAPLENGTH: 0x%x\n,
@@ -44,13 +44,13 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)
 
xhci_dbg(xhci, // xHCI operational registers at %p:\n, xhci-op_regs);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-run_regs_off);
+   temp = readl(xhci-cap_regs-run_regs_off);
xhci_dbg(xhci, // @%p = 0x%x RTSOFF\n,
xhci-cap_regs-run_regs_off,
(unsigned int) temp  RTSOFF_MASK);
xhci_dbg(xhci, // xHCI runtime registers at %p:\n, xhci-run_regs);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-db_off);
+   temp = readl(xhci-cap_regs-db_off);
xhci_dbg(xhci, // @%p = 0x%x DBOFF\n, xhci-cap_regs-db_off, temp);
xhci_dbg(xhci, // Doorbell array at %p:\n, xhci-dba);
 }
@@ -61,7 +61,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
 
xhci_dbg(xhci, xHCI capability registers at %p:\n, xhci-cap_regs);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hc_capbase);
+   temp = readl(xhci-cap_regs-hc_capbase);
xhci_dbg(xhci, CAPLENGTH AND HCIVERSION 0x%x:\n,
(unsigned int) temp);
xhci_dbg(xhci, CAPLENGTH: 0x%x\n,
@@ -69,7 +69,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci, HCIVERSION: 0x%x\n,
(unsigned int) HC_VERSION(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params1);
+   temp = readl(xhci-cap_regs-hcs_params1);
xhci_dbg(xhci, HCSPARAMS 1: 0x%x\n,
(unsigned int) temp);
xhci_dbg(xhci,   Max device slots: %u\n,
@@ -79,7 +79,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci,   Max ports: %u\n,
(unsigned int) HCS_MAX_PORTS(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params2);
+   temp = readl(xhci-cap_regs-hcs_params2);
xhci_dbg(xhci, HCSPARAMS 2: 0x%x\n,
(unsigned int) temp);
xhci_dbg(xhci,   Isoc scheduling threshold: %u\n,
@@ -87,7 +87,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci,   Maximum allowed segments in event ring: %u\n,
(unsigned int) HCS_ERST_MAX(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params3);
+   temp = readl(xhci-cap_regs-hcs_params3);
xhci_dbg(xhci, HCSPARAMS 3 0x%x:\n,
(unsigned int) temp);
xhci_dbg(xhci,   Worst case U1 device exit latency: %u\n,
@@ -95,14 +95,14 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci,   Worst case U2 device exit latency: %u\n,
(unsigned int) HCS_U2_LATENCY(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcc_params);
+   temp = readl(xhci-cap_regs-hcc_params);
xhci_dbg(xhci, HCC PARAMS 0x%x:\n, (unsigned int) temp);
xhci_dbg(xhci,   HC generates %s bit addresses\n,
HCC_64BIT_ADDR(temp) ? 64 : 32);
/* FIXME */
xhci_dbg(xhci,   FIXME: more HCCPARAMS debugging\n);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-run_regs_off);
+   temp = readl(xhci-cap_regs-run_regs_off);
xhci_dbg(xhci, RTSOFF 0x%x:\n, temp  RTSOFF_MASK);
 }
 
@@ -110,7 +110,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)
 {
u32 temp;
 
-   temp = xhci_readl(xhci, xhci-op_regs-command);
+   temp = readl(xhci-op_regs-command);
xhci_dbg

[RFC v2 2/4] xhci: replace xhci_writel() with writel()

2013-11-14 Thread Xenia Ragiadakou
Function xhci_writel() is used to write a 32bit value in xHC registers residing
in MMIO address space. It takes as first argument a pointer to the xhci_hcd
although it does not use it. xhci_writel() internally simply calls writel().
This creates an illusion that xhci_writel() is an xhci specific function that
has to be called in a context where a pointer to xhci_hcd is available.

Remove xhci_writel() wrapper function and replace its calls with calls to
writel() to make the code more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-hub.c  | 35 ++
 drivers/usb/host/xhci-mem.c  |  6 +++---
 drivers/usb/host/xhci-ring.c |  8 +++
 drivers/usb/host/xhci.c  | 51 +---
 drivers/usb/host/xhci.h  |  8 ---
 5 files changed, 47 insertions(+), 61 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 70ed7c9..9992fbf 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -342,7 +342,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
}
 
/* Write 1 to disable the port */
-   xhci_writel(xhci, port_status | PORT_PE, addr);
+   writel(port_status | PORT_PE, addr);
port_status = readl(addr);
xhci_dbg(xhci, disable port, actual port %d status  = 0x%x\n,
wIndex, port_status);
@@ -388,7 +388,7 @@ static void xhci_clear_port_change_bit(struct xhci_hcd 
*xhci, u16 wValue,
return;
}
/* Change bits are all write 1 to clear */
-   xhci_writel(xhci, port_status | status, addr);
+   writel(port_status | status, addr);
port_status = readl(addr);
xhci_dbg(xhci, clear port %s change, actual port %d status  = 0x%x\n,
port_change_bit, wIndex, port_status);
@@ -419,7 +419,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
temp = xhci_port_state_to_neutral(temp);
temp = ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
-   xhci_writel(xhci, temp, port_array[port_id]);
+   writel(temp, port_array[port_id]);
 }
 
 static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
@@ -445,7 +445,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
else
temp = ~PORT_WKOC_E;
 
-   xhci_writel(xhci, temp, port_array[port_id]);
+   writel(temp, port_array[port_id]);
 }
 
 /* Test and clear port RWC bit */
@@ -458,7 +458,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
if (temp  port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
-   xhci_writel(xhci, temp, port_array[port_id]);
+   writel(temp, port_array[port_id]);
}
 }
 
@@ -838,8 +838,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
temp |= PORT_CSC | PORT_PEC | PORT_WRC |
PORT_OCC | PORT_RC | PORT_PLC |
PORT_CEC;
-   xhci_writel(xhci, temp | PORT_PE,
-   port_array[wIndex]);
+   writel(temp | PORT_PE, port_array[wIndex]);
temp = readl(port_array[wIndex]);
break;
}
@@ -894,8 +893,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
 * However, khubd will ignore the roothub events until
 * the roothub is registered.
 */
-   xhci_writel(xhci, temp | PORT_POWER,
-   port_array[wIndex]);
+   writel(temp | PORT_POWER, port_array[wIndex]);
 
temp = readl(port_array[wIndex]);
xhci_dbg(xhci, set port power, actual port %d status  
= 0x%x\n, wIndex, temp);
@@ -910,7 +908,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
-   xhci_writel(xhci, temp, port_array[wIndex]);
+   writel(temp, port_array[wIndex]);
 
temp = readl(port_array[wIndex]);
xhci_dbg(xhci, set port reset, actual port %d status  
= 0x%x\n, wIndex, temp);
@@ -925,7 +923,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
-   xhci_writel(xhci, temp, port_array[wIndex]);
+   writel(temp, port_array[wIndex

[RFC v2 3/4] xhci: replace xhci_read_64() with readq()

2013-11-14 Thread Xenia Ragiadakou
Function xhci_read_64() is used to read 64bit xHC registers residing in MMIO.
On 32bit systems, xHC registers need to be read with 32bit accesses by
reading first the lower 32bits and then the higher 32bits.

Replace all calls to xhci_read_64() with calls to readq() and include
asm-generic/io-64-nonatomic-lo-hi.h header file, so that if the system
is not 64bit, readq() will read registers in 32bit chunks with low-high order.

This is done to reduce code duplication since 64bit low-high read logic
is already implemented and to take advantage of inherent atomic 64bit
read operations on 64bit systems.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-dbg.c  |  6 +++---
 drivers/usb/host/xhci-mem.c  |  6 +++---
 drivers/usb/host/xhci-ring.c |  6 +++---
 drivers/usb/host/xhci.c  | 12 ++--
 drivers/usb/host/xhci.h  | 10 ++
 5 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index eb009a4..b016d38 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -203,12 +203,12 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num)
addr, (unsigned int)temp);
 
addr = ir_set-erst_base;
-   temp_64 = xhci_read_64(xhci, addr);
+   temp_64 = readq(addr);
xhci_dbg(xhci,   %p: ir_set.erst_base = @%08llx\n,
addr, temp_64);
 
addr = ir_set-erst_dequeue;
-   temp_64 = xhci_read_64(xhci, addr);
+   temp_64 = readq(addr);
xhci_dbg(xhci,   %p: ir_set.erst_dequeue = @%08llx\n,
addr, temp_64);
 }
@@ -412,7 +412,7 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
 {
u64 val;
 
-   val = xhci_read_64(xhci, xhci-op_regs-cmd_ring);
+   val = readq(xhci-op_regs-cmd_ring);
xhci_dbg(xhci, // xHC command ring deq ptr low bits + flags = @%08x\n,
lower_32_bits(val));
xhci_dbg(xhci, // xHC command ring deq ptr high bits = @%08x\n,
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bce4391..4b87026 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1958,7 +1958,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
xhci_warn(xhci, WARN something wrong with SW event ring 
dequeue ptr.\n);
/* Update HC event ring dequeue pointer */
-   temp = xhci_read_64(xhci, xhci-ir_set-erst_dequeue);
+   temp = readq(xhci-ir_set-erst_dequeue);
temp = ERST_PTR_MASK;
/* Don't clear the EHB bit (which is RW1C) because
 * there might be more events to service.
@@ -2312,7 +2312,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
(unsigned long long)xhci-cmd_ring-first_seg-dma);
 
/* Set the address in the Command Ring Control register */
-   val_64 = xhci_read_64(xhci, xhci-op_regs-cmd_ring);
+   val_64 = readq(xhci-op_regs-cmd_ring);
val_64 = (val_64  (u64) CMD_RING_RSVD_BITS) |
(xhci-cmd_ring-first_seg-dma  (u64) ~CMD_RING_RSVD_BITS) |
xhci-cmd_ring-cycle_state;
@@ -2396,7 +2396,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Set ERST base address for ir_set 0 = 0x%llx,
(unsigned long long)xhci-erst.erst_dma_addr);
-   val_64 = xhci_read_64(xhci, xhci-ir_set-erst_base);
+   val_64 = readq(xhci-ir_set-erst_base);
val_64 = ERST_PTR_MASK;
val_64 |= (xhci-erst.erst_dma_addr  (u64) ~ERST_PTR_MASK);
xhci_write_64(xhci, val_64, xhci-ir_set-erst_base);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index bc46cce..339733b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -313,7 +313,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
return 0;
}
 
-   temp_64 = xhci_read_64(xhci, xhci-op_regs-cmd_ring);
+   temp_64 = readq(xhci-op_regs-cmd_ring);
if (!(temp_64  CMD_RING_RUNNING)) {
xhci_dbg(xhci, Command ring had been stopped\n);
return 0;
@@ -2871,7 +2871,7 @@ hw_died:
/* Clear the event handler busy flag (RW1C);
 * the event ring should be empty.
 */
-   temp_64 = xhci_read_64(xhci, xhci-ir_set-erst_dequeue);
+   temp_64 = readq(xhci-ir_set-erst_dequeue);
xhci_write_64(xhci, temp_64 | ERST_EHB,
xhci-ir_set-erst_dequeue);
spin_unlock(xhci-lock);
@@ -2885,7 +2885,7 @@ hw_died:
 */
while (xhci_handle_event(xhci)  0) {}
 
-   temp_64 = xhci_read_64(xhci, xhci-ir_set-erst_dequeue);
+   temp_64 = readq(xhci-ir_set-erst_dequeue);
/* If necessary, update the HW's version

[RFC v2 0/4] remove unnecessary code related to MMIO reads/writes

2013-11-14 Thread Xenia Ragiadakou
Changes from v1:
  * create one patch per type of conversion instead of multiple patches
associated with specific xhci files
  * change commit messages to be more readable and to reflect the above change
  * add an empty line between #include asm-generic/io-64-nonatomic-lo-hi.h
and the rest of the headers to improve readability.

Xenia Ragiadakou (4):
  xhci: replace xhci_readl() with readl()
  xhci: replace xhci_writel() with writel()
  xhci: replace xhci_read_64() with readq()
  xhci: replace xhci_write_64() with writeq()

 drivers/usb/host/xhci-dbg.c  |  42 ++--
 drivers/usb/host/xhci-hub.c  | 106 ++---
 drivers/usb/host/xhci-mem.c  |  40 +--
 drivers/usb/host/xhci-ring.c |  34 +-
 drivers/usb/host/xhci.c  | 157 +--
 drivers/usb/host/xhci.h  |  52 +++---
 6 files changed, 196 insertions(+), 235 deletions(-)

-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 4/4] xhci: replace xhci_write_64() with writeq()

2013-11-14 Thread Xenia Ragiadakou
Function xhci_write_64() is used to write 64bit xHC registers residing in MMIO.
On 32bit systems, xHC registers need to be written with 32bit accesses by
writing first the lower 32bits and then the higher 32bits. The header file
asm-generic/io-64-nonatomic-lo-hi.h ensures that on 32bit systems writeq() will
will write 64bit registers in 32bit chunks with low-high order.

Replace all calls to xhci_write_64() with calls to writeq().

This is done to reduce code duplication since 64bit low-high write logic
is already implemented and to take advantage of inherent atomic 64bit
write operations on 64bit systems.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-mem.c  |  8 
 drivers/usb/host/xhci-ring.c |  8 +++-
 drivers/usb/host/xhci.c  |  8 
 drivers/usb/host/xhci.h  | 29 +
 4 files changed, 20 insertions(+), 33 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 4b87026..873c272 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1967,7 +1967,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Write event ring dequeue pointer, 
preserving EHB bit);
-   xhci_write_64(xhci, ((u64) deq  (u64) ~ERST_PTR_MASK) | temp,
+   writeq(((u64) deq  (u64) ~ERST_PTR_MASK) | temp,
xhci-ir_set-erst_dequeue);
 }
 
@@ -2269,7 +2269,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Device context base array address = 0x%llx (DMA), 
%p (virt),
(unsigned long long)xhci-dcbaa-dma, xhci-dcbaa);
-   xhci_write_64(xhci, dma, xhci-op_regs-dcbaa_ptr);
+   writeq(dma, xhci-op_regs-dcbaa_ptr);
 
/*
 * Initialize the ring segment pool.  The ring must be a contiguous
@@ -2318,7 +2318,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci-cmd_ring-cycle_state;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Setting command ring address to 0x%x, val);
-   xhci_write_64(xhci, val_64, xhci-op_regs-cmd_ring);
+   writeq(val_64, xhci-op_regs-cmd_ring);
xhci_dbg_cmd_ptrs(xhci);
 
xhci-lpm_command = xhci_alloc_command(xhci, true, true, flags);
@@ -2399,7 +2399,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
val_64 = readq(xhci-ir_set-erst_base);
val_64 = ERST_PTR_MASK;
val_64 |= (xhci-erst.erst_dma_addr  (u64) ~ERST_PTR_MASK);
-   xhci_write_64(xhci, val_64, xhci-ir_set-erst_base);
+   writeq(val_64, xhci-ir_set-erst_base);
 
/* Set the event ring dequeue address */
xhci_set_hc_event_deq(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 339733b..fe9208a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -319,8 +319,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
return 0;
}
xhci-cmd_ring_state = CMD_RING_STATE_ABORTED;
-   xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
-   xhci-op_regs-cmd_ring);
+   writeq(temp_64 | CMD_RING_ABORT, xhci-op_regs-cmd_ring);
 
/* Section 4.6.1.2 of xHCI 1.0 spec says software should
 * time the completion od all xHCI commands, including
@@ -2872,8 +2871,7 @@ hw_died:
 * the event ring should be empty.
 */
temp_64 = readq(xhci-ir_set-erst_dequeue);
-   xhci_write_64(xhci, temp_64 | ERST_EHB,
-   xhci-ir_set-erst_dequeue);
+   writeq(temp_64 | ERST_EHB, xhci-ir_set-erst_dequeue);
spin_unlock(xhci-lock);
 
return IRQ_HANDLED;
@@ -2900,7 +2898,7 @@ hw_died:
 
/* Clear the event handler busy flag (RW1C); event ring is empty. */
temp_64 |= ERST_EHB;
-   xhci_write_64(xhci, temp_64, xhci-ir_set-erst_dequeue);
+   writeq(temp_64, xhci-ir_set-erst_dequeue);
 
spin_unlock(xhci-lock);
 
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 858e992..7fe6f66 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -762,11 +762,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
 {
writel(xhci-s3.command, xhci-op_regs-command);
writel(xhci-s3.dev_nt, xhci-op_regs-dev_notification);
-   xhci_write_64(xhci, xhci-s3.dcbaa_ptr, xhci-op_regs-dcbaa_ptr);
+   writeq(xhci-s3.dcbaa_ptr, xhci-op_regs-dcbaa_ptr);
writel(xhci-s3.config_reg, xhci-op_regs-config_reg);
writel(xhci-s3.erst_size, xhci-ir_set-erst_size);
-   xhci_write_64(xhci, xhci-s3.erst_base, xhci-ir_set-erst_base);
-   xhci_write_64(xhci, xhci-s3.erst_dequeue, xhci-ir_set-erst_dequeue);
+   writeq(xhci-s3.erst_base

Re: [PATCH 2/2] xhci: fix last valid endpoint when dropping an endpoint

2013-10-11 Thread Xenia Ragiadakou

Hi Sarah,

On 10/10/2013 09:25 PM, Sarah Sharp wrote:

Hi Xenia,

On Mon, Oct 07, 2013 at 06:52:39PM +0300, Xenia Ragiadakou wrote:

The previous patch on the endpoint reset uses the already implemented function
xhci_drop_endpoint() to reduce code duplication. However, the way that xhci
updates the last valid endpoint in the Input Slot Context, when an endpoint
is dropped, can lead to incosistent value for the last valid endpoint.
That can happen when the endpoint to be reset has index smaller than the
current last valid endpoint. In that case the last valid endpoint will end up
being updated with a smaller value and if there are valid endpoints with index
higher than the index of the reset endpoint, the xHC will consider them as
invalid and the transactions to these endpoints will break.

This patch updates the last valid endpoint with the index of the first not
disabled endpoint, starting from the current last valid endpoint and skipping
the dropped endpoint.

I notice that in section 4.6.6 of the 08/2012 errata to the xHCI 1.0
spec, that when the host executes the Configure Endpoint command, it
must:

Set the Context Entries field in the Output Slot Context to the index
of the last valid Endpoint Context in its Output Device Context
structure, which shall be greater to or equal to the value of the
Context Entries field in the Input Slot Context.

There was a discussion about a similar patch to this one in June:

http://marc.info/?l=linux-usbm=137158978503741w=2

The end result was that I didn't take the patch, and VMWare fixed their
virtual xHCI host.


Hmmm, I was not aware of that patch.



Is this patch necessary for your first patch to work?


No, it is not necessary that's why before i send this patchset i decided 
to send it as second and not first.
The reason i send it is to cover a possible failure case because I have 
not found a satisfying way to test the reset endpoint patch exhaustively 
under all possible contexts.



What happens if you don't have this patch applied?  Did you actually experience 
the
transactions to those endpoints breaking, or do you just theorize that
it could happen?

Sarah Sharp


While i was working at this fix i met some problems that I thought at 
the moment that they were due to the fact that Context Entries were 
updated with a value smaller than the actual last valid endpoint and at 
that point i changed the implementation of last valid endpoint update. 
But since then I had changed the code so maybe they were due to some 
other bug. When later I tested my last version (without the last valid 
endpoint fix) I have not met problems but I still considered this patch 
necessary because I was theorizing that without it something will break.


The main reasons that made me come to this conclusion was the fact that 
Context Entries by being updated with a value other than the last valid 
endpoint will be inconsistent with the definition in xhci spec (revision 
1.0 5/21/10) Context Entries. This field identifies the index of the 
last valid Endpoint Context within this Device Context structure. and 
that in 6.4.3.8 Stop Endpoint Command TRB field definitions for Endpoint 
ID field it states that Valid values are ‘1’ to Slot Context Context 
Entries, from which i hypothesize that when Context Entries are set 
with a smaller value a subsequent Stop Command to an endpoint with 
higher index will fail.


I compile now to see if that actually can happen. However, the best 
person to answer this question is an xHC architect. Will the xHC take 
under consideration the value in Context Entries field of the Output 
Slot Context only when a Configure Endpoint command is issued or also 
for other commands in order to check if the endpoint affected by the 
command is a valid endpoint?


The fact is that if somebody attempts to reset an endpoint with index 
smaller than the actual last valid endpoint in Device Context, without 
that fix the Context Entries field of the Output Slot Context will be 
set to value lower than the actual last valid endpoint.


I don't know if I made clear the reasons of my confusion that made me 
consider this fix necessary.


regards,
ksenia


Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
  drivers/usb/host/xhci.c | 22 +++---
  1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index e6300b5..97670f5 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1547,7 +1547,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct 
usb_device *udev,
struct xhci_container_ctx *in_ctx, *out_ctx;
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_slot_ctx *slot_ctx;
-   unsigned int last_ctx;
+   unsigned int last_ep_index;
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
u32 drop_flag;
@@ -1598,13 +1598,21 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct 
usb_device *udev,
ctrl_ctx

Re: [PATCH 2/2] xhci: fix last valid endpoint when dropping an endpoint

2013-10-11 Thread Xenia Ragiadakou

On 10/11/2013 11:40 AM, Xenia Ragiadakou wrote:

[snip]
The main reasons that made me come to this conclusion was the fact 
that Context Entries by being updated with a value other than the last 
valid endpoint will be inconsistent with the definition in xhci spec 
(revision 1.0 5/21/10) Context Entries. This field identifies the 
index of the last valid Endpoint Context within this Device Context 
structure. and that in 6.4.3.8 Stop Endpoint Command TRB field 
definitions for Endpoint ID field it states that Valid values are ‘1’ 
to Slot Context Context Entries, from which i hypothesize that when 
Context Entries are set with a smaller value a subsequent Stop Command 
to an endpoint with higher index will fail.


I compile now to see if that actually can happen. However, the best 
person to answer this question is an xHC architect. Will the xHC take 
under consideration the value in Context Entries field of the Output 
Slot Context only when a Configure Endpoint command is issued or also 
for other commands in order to check if the endpoint affected by the 
command is a valid endpoint?




To test if a smaller value will cause a problem, I reset first endpoint 
4 and, then, endpoint 3 so that the Context Entries field get updated 
with the value 3 while the actual last valid endpoint is 4.
Endpoint 4 is a BULK OUT endpoint so I checked if I could write to the 
device. I didn't experience any issues when writing.
Then, I issued a Stop Endpoint command to EP 4 and although its number 
is higher than the number kept in Context Entries field, the Stop 
Endpoint command completed successfully.
Then, I issued a Set TR Dequeue pointer command to EP 4 and also 
completed successfully.
At last, I issued a Disable Slot command to see if all the Endpoint 
Contexts for the slot will be disabled and not only those in the range 
of Context Entries and indeed all of them were disabled.


So, I guess that my changelog was unreasonably ominous and that the 
patch can be dropped.
From the above it seems that xHC does not update with the vallue in the 
Context Entries field of the Input Slot Context any internal register 
used in determining currently valid endpoints.


regards,
ksenia

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] xhci: fix last valid endpoint when dropping an endpoint

2013-10-11 Thread Xenia Ragiadakou

On 10/11/2013 09:26 PM, Sarah Sharp wrote:

On Fri, Oct 11, 2013 at 07:30:17PM +0300, Xenia Ragiadakou wrote:

[snip]
To test if a smaller value will cause a problem, I reset first
endpoint 4 and, then, endpoint 3 so that the Context Entries field
get updated with the value 3 while the actual last valid endpoint is
4.

Did you happen to see what the Context Entries field in the Output Slot
Context was after the command finished?  I would expect it to remain at
4, even though the Context Entries field in the Input Slot Context would
have been 3.


No, it was changed to 3. When I say that the Context Entries field got 
updated I am always referring to the Context Entries field of the Output 
Slot Context.





Endpoint 4 is a BULK OUT endpoint so I checked if I could write to
the device. I didn't experience any issues when writing.
Then, I issued a Stop Endpoint command to EP 4 and although its
number is higher than the number kept in Context Entries field, the
Stop Endpoint command completed successfully.
Then, I issued a Set TR Dequeue pointer command to EP 4 and also
completed successfully.
At last, I issued a Disable Slot command to see if all the Endpoint
Contexts for the slot will be disabled and not only those in the
range of Context Entries and indeed all of them were disabled.

So, I guess that my changelog was unreasonably ominous and that the
patch can be dropped.

Ok, I'll drop it, and notify the testers they don't need the second
patch.


 From the above it seems that xHC does not update with the vallue in
the Context Entries field of the Input Slot Context any internal
register used in determining currently valid endpoints.

The Output Slot Context Entries should still reflect which endpoints the
hardware thinks are currently valid.


No, the Output Slot Context Entries gets updated with the value of the 
Input Slot Context Entries, irrespectively of whether the new value 
reflects the true number of context entries.

That's the confusing part.



Sarah Sharp


The thing is that the value in the Output Slot Context Entries stops to 
reflect the true last valid endpoint.
But xHC does not seem to care about. I don't know if the xhci driver 
needs it to reflect the true last valid endpoint but that is another thing.


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] xhci: fix reset for not halted endpoints

2013-10-10 Thread Xenia Ragiadakou

On 10/07/2013 06:52 PM, Xenia Ragiadakou wrote:

[snip]

+static int xhci_reset_ep0(struct xhci_hcd *xhci, struct usb_device *udev,
+   struct usb_host_endpoint *ep)
+{
+   struct xhci_virt_device *vdev;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   struct xhci_slot_ctx *slot_ctx_out;
+   int ret;
+
+   vdev = xhci-devs[udev-slot_id];
+
+   /* reinitialize endpoint's ring and setup its input context based
+* on its descriptors */
+   if (xhci_endpoint_init(xhci, vdev, udev, ep, GFP_NOIO)  0) {
+   xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
+   %s: failed to initialize ep 0, __func__);
+   return -ENOMEM;
+   }
+
+   /* issue an evaluate context command */
+   ctrl_ctx = xhci_get_input_control_ctx(xhci, vdev-in_ctx);
+   if (!ctrl_ctx) {
+   xhci_warn(xhci, %s: Could not get input context, bad type.\n,
+   __func__);
+
+   return -EINVAL;
+   }
+   ctrl_ctx-add_flags = cpu_to_le32(EP0_FLAG | SLOT_FLAG);
+   ctrl_ctx-drop_flags = 0;
+


Now, i see that here i should have not set the slot flag in the control 
context's added flags because that will make xHC to update also the 
slot's parameters (e.g max exit latency) which is not necessary.

Before i fix this I will wait for some other reviews.

By the way, that patch should have been sent as RFC in first place, but 
i forgot to set appropriately the subject prefix :(


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] xhci: fix last valid endpoint when dropping an endpoint

2013-10-07 Thread Xenia Ragiadakou
The previous patch on the endpoint reset uses the already implemented function
xhci_drop_endpoint() to reduce code duplication. However, the way that xhci
updates the last valid endpoint in the Input Slot Context, when an endpoint
is dropped, can lead to incosistent value for the last valid endpoint.
That can happen when the endpoint to be reset has index smaller than the
current last valid endpoint. In that case the last valid endpoint will end up
being updated with a smaller value and if there are valid endpoints with index
higher than the index of the reset endpoint, the xHC will consider them as
invalid and the transactions to these endpoints will break.

This patch updates the last valid endpoint with the index of the first not
disabled endpoint, starting from the current last valid endpoint and skipping
the dropped endpoint.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index e6300b5..97670f5 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1547,7 +1547,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct 
usb_device *udev,
struct xhci_container_ctx *in_ctx, *out_ctx;
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_slot_ctx *slot_ctx;
-   unsigned int last_ctx;
+   unsigned int last_ep_index;
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
u32 drop_flag;
@@ -1598,13 +1598,21 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct 
usb_device *udev,
ctrl_ctx-add_flags = cpu_to_le32(~drop_flag);
new_add_flags = le32_to_cpu(ctrl_ctx-add_flags);
 
-   last_ctx = xhci_last_valid_endpoint(le32_to_cpu(ctrl_ctx-add_flags));
+   slot_ctx = xhci_get_slot_ctx(xhci, out_ctx);
+   last_ep_index = LAST_CTX_TO_EP_NUM(le32_to_cpu(slot_ctx-dev_info));
slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
-   /* Update the last valid endpoint context, if we deleted the last one */
-   if ((le32_to_cpu(slot_ctx-dev_info)  LAST_CTX_MASK) 
-   LAST_CTX(last_ctx)) {
-   slot_ctx-dev_info = cpu_to_le32(~LAST_CTX_MASK);
-   slot_ctx-dev_info |= cpu_to_le32(LAST_CTX(last_ctx));
+   for (; last_ep_index = 0; --last_ep_index) {
+   /* skip the dropped endpoint's index */
+   if (last_ep_index == ep_index)
+   continue;
+   ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, last_ep_index);
+   if ((ep_ctx-ep_info  cpu_to_le32(EP_STATE_MASK)) !=
+   cpu_to_le32(EP_STATE_DISABLED)) {
+   slot_ctx-dev_info = cpu_to_le32(~LAST_CTX_MASK);
+   slot_ctx-dev_info |=
+   cpu_to_le32(LAST_CTX(last_ep_index + 1));
+   break;
+   }
}
new_slot_info = le32_to_cpu(slot_ctx-dev_info);
 
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] xhci: fix reset for not halted endpoints

2013-10-07 Thread Xenia Ragiadakou
If a Reset Endpoint command is issued for an endpoint that is not in
the Halted state, xHC does nothing. Since the current implementation of
xhci_endpoint_reset() aborts any resets that address not halted endpoints,
the synchronization between the host-side and device-side toggle or sequence
number is lost.
This patch attempts to fix this issue by dropping and readding the endpoint
in order to enforce xHC to reset its internal toggle/sequence number.

Four new functions have been introduced to prevent xhci_endpoint_reset() from
becoming huge.

xhci_unlink_urbs(xhci, ring):
unlinks the urbs from the endpoint's rings

xhci_stop_endpoint_for_config(xhci, udev, ep index):
brings the endpoint to the Stopped state and calls xhci_unlink_urbs
to unlink any queued urbs

xhci_reset_ep0(xhci, udev, ep):
calls xhci_stop_endpoint_for_config to stop the endpoint and then
reinitializes the ring and input context for the default control
endpoint and issues an Evaluate Context command to reset xHC toggle

xhci_reset_not_halted_ep(xhci, udev, ep):
calls xhci_stop_endpoint_for_config and if the endpoint to be reset is
the endpoint 0 calls xhci_reset_ep0, otherwise reinitializes the
endpoint rings and input context and then drops and readds the endpoint
issueing a Configure Endpoint

Also, this patch introduces a new trace event for debugging output contexts
during the process of resetting the endpoint. At this early stage, it is
useful for debugging the xhci_reset_not_halted_ep() and it may be removed
later when further testing and revisioning show that the function works as
expected.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

This patch needs to be tested further because I did not find a satisfying
way to test it. I would appreciate if the device driver writers that had
problems with the xhci reset endpoint in the past could test it and let me
know if it fixes the problem or not.

 drivers/usb/host/xhci-ring.c  |  17 +++-
 drivers/usb/host/xhci-trace.h |   6 ++
 drivers/usb/host/xhci.c   | 210 +-
 drivers/usb/host/xhci.h   |   3 +
 4 files changed, 233 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index faff6fc..f62131b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -433,6 +433,10 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd 
*xhci,
 
ep = xhci-devs[slot_id]-eps[ep_index];
 
+   /* If there is a pending configuration, don't ring the doorbell yet */
+   if (ep-ep_state  EP_CONFIG_PENDING)
+   return;
+
/* A ring has pending URBs if its TD list is not empty */
if (!(ep-ep_state  EP_HAS_STREAMS)) {
if (ep-ring  !(list_empty(ep-ring-td_list)))
@@ -715,8 +719,8 @@ static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd 
*xhci,
 }
 
 /* Must be called with xhci-lock held in interrupt context */
-static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
-   struct xhci_td *cur_td, int status)
+void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, struct xhci_td *cur_td,
+   int status)
 {
struct usb_hcd *hcd;
struct urb  *urb;
@@ -788,6 +792,8 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, 
int slot_id,
xhci_stop_watchdog_timer_in_irq(xhci, ep);
ep-stopped_td = NULL;
ep-stopped_trb = NULL;
+   if (ep-ep_state  EP_CONFIG_PENDING)
+   goto signal_completion;
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
return;
}
@@ -881,6 +887,13 @@ remove_finished_td:
return;
} while (cur_td != last_unlinked_td);
 
+signal_completion:
+   /* signal the completion for the Stop Endpoint command */
+   if (ep-ep_state  EP_CONFIG_PENDING) {
+   virt_dev = xhci-devs[slot_id];
+   handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
+   }
+
/* Return to the event handler with xhci-lock re-acquired */
 }
 
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 132abda..1f8b3fb 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -113,6 +113,12 @@ DEFINE_EVENT(xhci_log_ctx, xhci_address_ctx,
TP_ARGS(xhci, ctx, ep_num)
 );
 
+DEFINE_EVENT(xhci_log_ctx, xhci_resetep_ctx,
+   TP_PROTO(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx,
+unsigned int ep_num),
+   TP_ARGS(xhci, ctx, ep_num)
+);
+
 DECLARE_EVENT_CLASS(xhci_log_event,
TP_PROTO(void *trb_va, struct xhci_generic_trb *ev),
TP_ARGS(trb_va, ev),
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9f22ddf..e6300b5 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2873,6 +2873,210 @@ void

Re: New USB core API to change interval and max packet size

2013-10-01 Thread Xenia Ragiadakou

On 10/01/2013 11:45 PM, Sarah Sharp wrote:

On Tue, Oct 01, 2013 at 10:01:08PM +0300, Xenia Ragiadakou wrote:

Hi Sarah,

I read the mail on 'possible conflict between xhci_hcd and a patched
usbhid'.

For reference to others:
http://marc.info/?l=linux-usbm=138064948726038w=2
http://marc.info/?l=linux-usbm=138065201426880w=2


I looked in xhci and the problem arises in xhci_queue_intr_tx() when
if (xhci_interval != ep_interval) {
 ...
 urb-interval = xhci_interval;
}

right?

Yes.  The underlying problem is that the xHCI host sets up the endpoint
contexts during the Configure Endpoint command, using the interval from
the device's endpoint descriptors.  It also uses the endpoint descriptor
wMaxPacketSize, which can be wrong as well.  If the device driver wants
to use a different urb-interval than is in the endpoint descriptor, the
xHCI driver will simply ignore it.

(I'm Ccing the linux-media list, as I've discussed some of these devices
with broken descriptors before.)


When you say a new API, what do you mean? New functions in usbcore
to be used by usb device drivers?

Yes.  You would export the function in the USB core, and put a prototype
in a USB include file (probably in include/linux/usb.h).  Let's say that
function is called usb_change_ep_bandwidth.

Drivers could call into that function when they needed to change either
the bInterval or wMaxPacketSize of a particular endpoint.  This could be
during the driver's probe function, or before switching alternate
interface settings, or even after the alt setting is in place, but
userspace dictates the driver use a different bandwidth.

Drivers should pass usb_change_ep_bandwidth a pointer to the endpoint
they need to change, along with the bInterval and wMaxPacketSize values
they would like the endpoint to have.  Those values could be stored as
new values in struct usb_host_endpoint.

usb_change_ep_bandwidth would then call into the xHCI driver to drop the
endpoint, re-add it, and then issue a bandwidth change.  The xHCI driver
would have to be changed to look at the new fields in usb_host_endpoint,
and set up the endpoint contexts with the interval and packet size from
those fields, instead of the endpoint descriptor.

We should probably set the new values in usb_host_endpoint to zero after
the driver unbinds from the device.  Not sure if they should be reset
after the driver switches interfaces.  I would have to see the use cases
in the driver.


Here, it is needed to change the endpoint descriptors with the new
value in urb so that xhci takes the correct value?
I mean the fix should be made in usbcore and xhci shall remain intact?

No, we need to fix both the xHCI driver and the USB core.


I have time to work on that but i 'm not sure that i understood.

Sure.  I would actually suggest you first finish up the patch to issue a
configure endpoint if userspace wants to clear a halt, but the endpoint
isn't actually halted.  Did your most current patch work?  I can't
remember what the status was.

Sarah Sharp


Thanks for the clarification, I understand better now.
As far as concerns the reset endpoint fix, I am not sure if it works I 
have to send an RFC so that it can be further tested but I have a lot of 
pending RFCs for xhci on the mailing list so i was waiting for those to 
be reviewed before sending new ones. Or it is not necessary to wait and 
just send the RFC based on current usb-next tree?


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] xhci: fix write to USB3_PSSEN and XUSB2PRM pci config registers

2013-09-23 Thread Xenia Ragiadakou

On 09/23/2013 07:45 PM, Sarah Sharp wrote:

On Fri, Sep 20, 2013 at 07:45:53PM +0300, Xenia Ragiadakou wrote:

The function pci_write_config_dword() sets the appropriate byteordering
internally so the value argument should not be converted to little-endian.
This bug was found by sparse.

Can you give the exact error or warning message that sparse gave?


Yes, sure.

drivers/usb/host/pci-quirks.c:802:25: warning: incorrect type in 
argument 3 (different base types)
drivers/usb/host/pci-quirks.c:802:25:expected unsigned int 
[unsigned] [usertype] val
drivers/usb/host/pci-quirks.c:802:25:got restricted __le32 
[usertype] noident
drivers/usb/host/pci-quirks.c:824:25: warning: incorrect type in 
argument 3 (different base types)
drivers/usb/host/pci-quirks.c:824:25:expected unsigned int 
[unsigned] [usertype] val
drivers/usb/host/pci-quirks.c:824:25:got restricted __le32 
[usertype] noident




I ask because this description sounded odd to Greg and I when we met
last week at LinuxCon North America.  I've tried to track this down to
see where the code might be converting the value from CPU format to
little endian, and I don't see it.

AFAICT, pci_write_config_dword() is defined in include/linux/pci.h, and
calls pci_bus_write_config_dword():

static inline int pci_write_config_dword(const struct pci_dev *dev, int where,
  u32 val)
{
 return pci_bus_write_config_dword(dev-bus, dev-devfn, where, val);
}

pci_bus_write_config_dword is defined as a macro in drivers/pci/access.h:

#define PCI_OP_WRITE(size,type,len) \
int pci_bus_write_config_##size \
 (struct pci_bus *bus, unsigned int devfn, int pos, type value)  \
{   \
 int res;\
 unsigned long flags;\
 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;   \
 raw_spin_lock_irqsave(pci_lock, flags);\
 res = bus-ops-write(bus, devfn, pos, len, value); \
 raw_spin_unlock_irqrestore(pci_lock, flags);   \
 return res; \
}

That macro simply calls the write function for whatever PCI bus driver
is installed.  Note that bus driver can be different than the standard
bus driver.  I don't see any conversion to little endian here, so that
means each bus driver would have to convert it.

I can dig deeper into each .write function, but if the conversion isn't
done at the upper layers, it's possible someone will create a .write
function without the conversion to little endian.

Am I missing something?


I had in mind that the pci_ops .read and .write defined by the PCI 
driver will take care of consistent byteorder access to the 
configuration registers. At least, that was what i understood after 
reading the
chapter on PCI of Linux Device Drivers (more specifically for 
pci_write_config_* functions, it states that The word and dword 
functions convert the value to little-endian before writing to the 
peripheral device.).


regards,
ksenia


Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
  drivers/usb/host/pci-quirks.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 2c76ef1..08ef282 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -799,7 +799,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
 * switchable ports.
 */
pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
-   cpu_to_le32(ports_available));
+   ports_available);
  
  	pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,

ports_available);
@@ -821,7 +821,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
 * host.
 */
pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
-   cpu_to_le32(ports_available));
+   ports_available);
  
  	pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,

ports_available);
--
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] xhci: fix write to USB3_PSSEN and XUSB2PRM pci config registers

2013-09-20 Thread Xenia Ragiadakou
The function pci_write_config_dword() sets the appropriate byteordering
internally so the value argument should not be converted to little-endian.
This bug was found by sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/pci-quirks.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 2c76ef1..08ef282 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -799,7 +799,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
 * switchable ports.
 */
pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
-   cpu_to_le32(ports_available));
+   ports_available);
 
pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
ports_available);
@@ -821,7 +821,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
 * host.
 */
pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
-   cpu_to_le32(ports_available));
+   ports_available);
 
pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
ports_available);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 10/21] xhci: replace xhci_readl() with readl() in xhci-dbg.c

2013-09-13 Thread Xenia Ragiadakou

On 09/13/2013 06:49 AM, Pratyush Anand wrote:

On Tue, Sep 10, 2013 at 02:03:15AM +0800, Xenia Ragiadakou wrote:

Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci-dbg.c.
This is done so that xhci_readl() can be removed completely and code can
become more straight-forward.

Its fine that this replacement would simplify it. But, I have
experienced that sometime such way of reading/writing a peripheral
registers is quite helpful. I was able to find several issues in dwc3
gadget isoc handling quickly because of the availability of dwc3_readl
dwc3_writel.

With such peripheral specific exerciser one can log all register
read/write in sequential order with timestamp with a little effort,
which can further help in debugging critical issues. Sometime, they
might be even helpful in diagnosis of hardware issues. Same sequence
can be extracted and provided to hardware engineer for analysing the
behaviour of device in simulation.

Regards
Pratyush


Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com


Hi Pratyush,

The truth is that I did not think of that. What tool do you use to trace 
read/write operations for a specific peripheral? I think that you can 
trace them using mmiotrace and then filter the output (so that the 
address lie within the mmio address space of the particular device you 
are interested in).
Mmiotrace reports whether it is read/write, the address, the width in 
bytes, the value etc, so you can apply filters to tune your search.
In that case there is no need for a wrapper function around 
readl()/writel(), but maybe you have another tool in mind so the wrapper 
function will suit better, don't know.


best regards,
ksenia

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 10/21] xhci: replace xhci_readl() with readl() in xhci-dbg.c

2013-09-13 Thread Xenia Ragiadakou

On 09/13/2013 12:28 PM, Pratyush Anand wrote:

Hi ksenia,

On Fri, Sep 13, 2013 at 04:45:23PM +0800, Xenia Ragiadakou wrote:

On 09/13/2013 06:49 AM, Pratyush Anand wrote:

On Tue, Sep 10, 2013 at 02:03:15AM +0800, Xenia Ragiadakou wrote:

Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci-dbg.c.
This is done so that xhci_readl() can be removed completely and code can
become more straight-forward.

Its fine that this replacement would simplify it. But, I have
experienced that sometime such way of reading/writing a peripheral
registers is quite helpful. I was able to find several issues in dwc3
gadget isoc handling quickly because of the availability of dwc3_readl
dwc3_writel.

With such peripheral specific exerciser one can log all register
read/write in sequential order with timestamp with a little effort,
which can further help in debugging critical issues. Sometime, they
might be even helpful in diagnosis of hardware issues. Same sequence
can be extracted and provided to hardware engineer for analysing the
behaviour of device in simulation.

Regards
Pratyush


Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com

Hi Pratyush,

The truth is that I did not think of that. What tool do you use to trace
read/write operations for a specific peripheral? I think that you can
trace them using mmiotrace and then filter the output (so that the
address lie within the mmio address space of the particular device you
are interested in).
Mmiotrace reports whether it is read/write, the address, the width in
bytes, the value etc, so you can apply filters to tune your search.
In that case there is no need for a wrapper function around
readl()/writel(), but maybe you have another tool in mind so the wrapper
function will suit better, don't know.

But Mmiotrace is supported by x86 arch only. Do you know similar tool
for ARM?

Regards
Pratyush



best regards,
ksenia


Nope :). There is still Kumar 's patch that keeps the wrappers, so it 
can be applied instead of mine. But you did not tell me which tool you 
use currently to log the mmio operations? it is useful to know.


thx,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v4 06/19] xhci: use completion event's slot id rather than dig it out of command

2013-09-09 Thread Xenia Ragiadakou

On 09/04/2013 08:39 AM, Xenia Ragiadakou wrote:

Since the slot id retrieved from the command TRB matches the one in Slot ID
field of the command completion event, which is available, there is no need
to determine it again.
This patch removes the uneccessary reassignment to slot id and adds a WARN_ON
in case the two Slot ID fields differ.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-the above change is performed now in a separate patch
-a warning is triggered in case the slot id reported in event trb is
  different from the slot id renoted in command trb

  drivers/usb/host/xhci-ring.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f00d9ef..f68a1f0 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1444,6 +1444,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
}
}
  
+	WARN_ON(slot_id != TRB_TO_SLOT_ID(

+   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])));
+
switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
@@ -1528,8 +1531,6 @@ bandwidth_change:
break;
case TRB_TYPE(TRB_RESET_DEV):
xhci_dbg(xhci, Completed reset device command.\n);
-   slot_id = TRB_TO_SLOT_ID(
-   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);


In this patch i did the stupid thing to place the WARN_ON() in the wrong 
place, since the Slot ID field of the Command TRB and the Slot ID field 
of the Command Completion Event TRB may differ for other commands. So, I 
will fix this and I will resend the patchset.


ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 02/19] xhci: rename existing Command Completion Event handlers

2013-09-09 Thread Xenia Ragiadakou
This patch renames the function handlers of a triggered Command Completion
Event that correspond to each command type into 'xhci_handle_cmd_type'.
That is done to give a consistent naming space to all the functions that
handle Command Completion Events and that will permit the code reader to
reference to them more easily.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ddbda35..ffd224c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -755,7 +755,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
  *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the 
chain
  * bit cleared) so that the HW will skip over them.
  */
-static void handle_stopped_endpoint(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
union xhci_trb *trb, struct xhci_event_cmd *event)
 {
unsigned int slot_id;
@@ -1063,9 +1063,8 @@ static void update_ring_for_set_deq_completion(struct 
xhci_hcd *xhci,
  * endpoint doorbell to restart the ring, but only if there aren't more
  * cancellations pending.
  */
-static void handle_set_deq_completion(struct xhci_hcd *xhci,
-   struct xhci_event_cmd *event,
-   union xhci_trb *trb)
+static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
+   struct xhci_event_cmd *event, union xhci_trb *trb)
 {
unsigned int slot_id;
unsigned int ep_index;
@@ -1157,9 +1156,8 @@ static void handle_set_deq_completion(struct xhci_hcd 
*xhci,
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
-static void handle_reset_ep_completion(struct xhci_hcd *xhci,
-   struct xhci_event_cmd *event,
-   union xhci_trb *trb)
+static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci,
+   struct xhci_event_cmd *event, union xhci_trb *trb)
 {
int slot_id;
unsigned int ep_index;
@@ -1497,15 +1495,15 @@ bandwidth_change:
complete(xhci-addr_dev);
break;
case TRB_TYPE(TRB_STOP_RING):
-   handle_stopped_endpoint(xhci, xhci-cmd_ring-dequeue, event);
+   xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
break;
case TRB_TYPE(TRB_SET_DEQ):
-   handle_set_deq_completion(xhci, event, xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_set_deq(xhci, event, xhci-cmd_ring-dequeue);
break;
case TRB_TYPE(TRB_CMD_NOOP):
break;
case TRB_TYPE(TRB_RESET_EP):
-   handle_reset_ep_completion(xhci, event, 
xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_reset_ep(xhci, event, xhci-cmd_ring-dequeue);
break;
case TRB_TYPE(TRB_RESET_DEV):
xhci_dbg(xhci, Completed reset device command.\n);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 13/19] xhci: add variable 'cmd_trb' in handle_cmd_completion()

2013-09-09 Thread Xenia Ragiadakou
This patch adds a new variable 'cmd_trb' to hold the address of the
command TRB, that is associated with the command completion event,
and to replace repetitions of xhci-cmd_ring-dequeue into the code.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index dbf2051..1df73c9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1506,10 +1506,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
u32 cmd_comp_code;
+   union xhci_trb *cmd_trb;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
+   cmd_trb = xhci-cmd_ring-dequeue;
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci-cmd_ring-deq_seg,
-   xhci-cmd_ring-dequeue);
+   cmd_trb);
/* Is the command ring deq ptr out of sync with the deq seg ptr? */
if (cmd_dequeue_dma == 0) {
xhci-error_bitmask |= 1  4;
@@ -1521,8 +1523,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
return;
}
 
-   trace_xhci_cmd_completion(xhci-cmd_ring-dequeue-generic,
-   (struct xhci_generic_trb *) event);
+   trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
 
cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event-status));
if (cmd_comp_code == COMP_CMD_ABORT || cmd_comp_code == COMP_CMD_STOP) {
@@ -1538,7 +1539,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
}
}
 
-   switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
+   switch (le32_to_cpu(cmd_trb-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
@@ -1556,19 +1557,19 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
case TRB_TYPE(TRB_STOP_RING):
-   xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
+   xhci_handle_cmd_stop_ep(xhci, cmd_trb, event);
break;
case TRB_TYPE(TRB_SET_DEQ):
-   xhci_handle_cmd_set_deq(xhci, event, xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_set_deq(xhci, event, cmd_trb);
break;
case TRB_TYPE(TRB_CMD_NOOP):
break;
case TRB_TYPE(TRB_RESET_EP):
-   xhci_handle_cmd_reset_ep(xhci, event, xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_reset_ep(xhci, event, cmd_trb);
break;
case TRB_TYPE(TRB_RESET_DEV):
WARN_ON(slot_id != TRB_TO_SLOT_ID(
-   
le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])));
+   le32_to_cpu(cmd_trb-generic.field[3])));
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;
case TRB_TYPE(TRB_NEC_GET_FW):
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 10/19] xhci: remove unused 'ep_ring' variable in handle_cmd_completion()

2013-09-09 Thread Xenia Ragiadakou
This patch removes the variable 'ep_ring' that is assigned in
TRB_CONFIG_EP switch case but never used.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 08ed322..195c6e7 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1448,7 +1448,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_virt_device *virt_dev;
unsigned int ep_index;
-   struct xhci_ring *ep_ring;
unsigned int ep_state;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
@@ -1522,7 +1521,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
ep_index != (unsigned int) -1 
le32_to_cpu(ctrl_ctx-add_flags) - SLOT_FLAG ==
le32_to_cpu(ctrl_ctx-drop_flags)) {
-   ep_ring = xhci-devs[slot_id]-eps[ep_index].ring;
ep_state = xhci-devs[slot_id]-eps[ep_index].ep_state;
if (!(ep_state  EP_HALTED))
goto bandwidth_change;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 07/19] xhci: refactor TRB_RESET_DEV case into function

2013-09-09 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_RESET_DEV switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_reset_dev().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 8a74002..829ede8 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1400,6 +1400,20 @@ static void xhci_handle_cmd_addr_dev(struct xhci_hcd 
*xhci, int slot_id,
complete(xhci-addr_dev);
 }
 
+static void xhci_handle_cmd_reset_dev(struct xhci_hcd *xhci, int slot_id,
+   struct xhci_event_cmd *event)
+{
+   struct xhci_virt_device *virt_dev;
+
+   xhci_dbg(xhci, Completed reset device command.\n);
+   virt_dev = xhci-devs[slot_id];
+   if (virt_dev)
+   handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
+   else
+   xhci_warn(xhci, Reset device command completion 
+   for disabled slot %u\n, slot_id);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1529,13 +1543,7 @@ bandwidth_change:
case TRB_TYPE(TRB_RESET_DEV):
WARN_ON(slot_id != TRB_TO_SLOT_ID(

le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])));
-   xhci_dbg(xhci, Completed reset device command.\n);
-   virt_dev = xhci-devs[slot_id];
-   if (virt_dev)
-   handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
-   else
-   xhci_warn(xhci, Reset device command completion 
-   for disabled slot %u\n, slot_id);
+   xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;
case TRB_TYPE(TRB_NEC_GET_FW):
if (!(xhci-quirks  XHCI_NEC_HOST)) {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 19/19] xhci: add trace for missed periodic transfers

2013-09-09 Thread Xenia Ragiadakou
There are situations under which xHC is unable to service an isochronous
endpoint within its service interval. For an IN isoc endpoint, this is the case
when its ring is full, while for an OUT isoc endpoint when its ring is empty.
This patch adds a trace event to the class 'xhci_log_msg', called
'xhci_dbg_missed_periodic_tx', to trace the debug statements related to
missed periodic transfers.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-make changelog more clear
-add two additional tracepoints

 drivers/usb/host/xhci-ring.c  | 26 --
 drivers/usb/host/xhci-trace.h |  5 +
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 8eb3118..af9bbac 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2493,18 +2493,22 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 * a Ring Overrun Event for IN Isoch endpoint or Ring
 * Underrun Event for OUT Isoch endpoint.
 */
-   xhci_dbg(xhci, underrun event on endpoint\n);
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   underrun event on endpoint);
if (!list_empty(ep_ring-td_list))
-   xhci_dbg(xhci, Underrun Event for slot %d ep %d 
-   still with TDs queued?\n,
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   Underrun Event for slot %d ep %d 
+   still with TDs queued?,
 TRB_TO_SLOT_ID(le32_to_cpu(event-flags)),
 ep_index);
goto cleanup;
case COMP_OVERRUN:
-   xhci_dbg(xhci, overrun event on endpoint\n);
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   overrun event on endpoint);
if (!list_empty(ep_ring-td_list))
-   xhci_dbg(xhci, Overrun Event for slot %d ep %d 
-   still with TDs queued?\n,
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   Overrun Event for slot %d ep %d 
+   still with TDs queued?,
 TRB_TO_SLOT_ID(le32_to_cpu(event-flags)),
 ep_index);
goto cleanup;
@@ -2520,7 +2524,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 * short transfer when process the ep_ring next time.
 */
ep-skip = true;
-   xhci_dbg(xhci, Miss service interval error, set skip flag\n);
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   Miss service interval error, set skip flag);
goto cleanup;
default:
if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
@@ -2564,8 +2569,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* We've skipped all the TDs on the ep ring when ep-skip set */
if (ep-skip  td_num == 0) {
ep-skip = false;
-   xhci_dbg(xhci, All tds on the ep_ring skipped. 
-   Clear skip flag.\n);
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   All tds on ep_ring skipped. Clear skip flag.);
ret = 0;
goto cleanup;
}
@@ -2620,7 +2625,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
ep_ring-last_td_was_short = false;
 
if (ep-skip) {
-   xhci_dbg(xhci, Found td. Clear skip flag.\n);
+   xhci_dbg_trace(xhci, trace_xhci_dbg_missed_periodic_tx,
+   Found td. Clear skip flag.);
ep-skip = false;
}
 
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 20364cc..c156685 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -67,6 +67,11 @@ DEFINE_EVENT(xhci_log_msg, xhci_dbg_ring_expansion,
TP_ARGS(vaf)
 );
 
+DEFINE_EVENT(xhci_log_msg, xhci_dbg_missed_periodic_tx,
+   TP_PROTO(struct va_format *vaf),
+   TP_ARGS(vaf)
+);
+
 DECLARE_EVENT_CLASS(xhci_log_ctx,
TP_PROTO(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx,
 unsigned int ep_num),
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 12/19] xhci: add variable 'cmd_comp_code' in handle_cmd_completion()

2013-09-09 Thread Xenia Ragiadakou
This patch adds a new variable 'cmd_comp_code' to hold the command completion
status code aiming to reduce code duplication and to improve code readability.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6dc582e..dbf2051 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1505,6 +1505,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event-flags));
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
+   u32 cmd_comp_code;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci-cmd_ring-deq_seg,
@@ -1523,16 +1524,15 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
trace_xhci_cmd_completion(xhci-cmd_ring-dequeue-generic,
(struct xhci_generic_trb *) event);
 
-   if ((GET_COMP_CODE(le32_to_cpu(event-status)) == COMP_CMD_ABORT) ||
-   (GET_COMP_CODE(le32_to_cpu(event-status)) == COMP_CMD_STOP)) {
+   cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event-status));
+   if (cmd_comp_code == COMP_CMD_ABORT || cmd_comp_code == COMP_CMD_STOP) {
/* If the return value is 0, we think the trb pointed by
 * command ring dequeue pointer is a good trb. The good
 * trb means we don't want to cancel the trb, but it have
 * been stopped by host. So we should handle it normally.
 * Otherwise, driver should invoke inc_deq() and return.
 */
-   if (handle_stopped_cmd_ring(xhci,
-   GET_COMP_CODE(le32_to_cpu(event-status {
+   if (handle_stopped_cmd_ring(xhci, cmd_comp_code)) {
inc_deq(xhci, xhci-cmd_ring);
return;
}
@@ -1541,23 +1541,19 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
-   xhci_handle_cmd_enable_slot(xhci, slot_id,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
-   xhci_handle_cmd_config_ep(xhci, slot_id, event,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_config_ep(xhci, slot_id, event, cmd_comp_code);
break;
case TRB_TYPE(TRB_EVAL_CONTEXT):
-   xhci_handle_cmd_eval_ctx(xhci, slot_id, event,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_eval_ctx(xhci, slot_id, event, cmd_comp_code);
break;
case TRB_TYPE(TRB_ADDR_DEV):
-   xhci_handle_cmd_addr_dev(xhci, slot_id,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
case TRB_TYPE(TRB_STOP_RING):
xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 04/19] xhci: refactor TRB_DISABLE_SLOT case into function

2013-09-09 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_DISABLE_SLOT switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_disable_slot().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0abf88c..f9c380e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1380,6 +1380,19 @@ static void xhci_handle_cmd_enable_slot(struct xhci_hcd 
*xhci, int slot_id,
complete(xhci-addr_dev);
 }
 
+static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
+{
+   struct xhci_virt_device *virt_dev;
+
+   virt_dev = xhci-devs[slot_id];
+   if (!virt_dev)
+   return;
+   if (xhci-quirks  XHCI_EP_LIMIT_QUIRK)
+   /* Delete default control endpoint resources */
+   xhci_free_device_endpoint_resources(xhci, virt_dev, true);
+   xhci_free_virt_device(xhci, slot_id);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1431,13 +1444,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
-   if (xhci-devs[slot_id]) {
-   if (xhci-quirks  XHCI_EP_LIMIT_QUIRK)
-   /* Delete default control endpoint resources */
-   xhci_free_device_endpoint_resources(xhci,
-   xhci-devs[slot_id], true);
-   xhci_free_virt_device(xhci, slot_id);
-   }
+   xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
virt_dev = xhci-devs[slot_id];
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 16/19] xhci: add argument 'slot_id' in stop_ep, set_deq and reset_ep cmd handlers

2013-09-09 Thread Xenia Ragiadakou
Since the Slot ID field in the command completion event matches the Slot ID
field in the associated command TRB for the Stop Endpoint, Set Dequeue Pointer
and Reset Endpoint commands, this patch adds in the handlers of their
completion events a 'slot_id' argument and removes the slot id calculation
in each of them.
Also, a WARN_ON() was added in case the slot ids reported by command TRB and
event TRB differ (although according to xhci spec rev1.0 that should not happen)

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v4:

-add a WARN_ON() in case the two slot id fields differ

 drivers/usb/host/xhci-ring.c | 25 -
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ece06b2..46652da 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -755,10 +755,9 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
  *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the 
chain
  * bit cleared) so that the HW will skip over them.
  */
-static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
union xhci_trb *trb, struct xhci_event_cmd *event)
 {
-   unsigned int slot_id;
unsigned int ep_index;
struct xhci_virt_device *virt_dev;
struct xhci_ring *ep_ring;
@@ -770,7 +769,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
struct xhci_dequeue_state deq_state;
 
if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb-generic.field[3] {
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev,
@@ -783,7 +781,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
}
 
memset(deq_state, 0, sizeof(deq_state));
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb-generic.field[3]));
ep = xhci-devs[slot_id]-eps[ep_index];
 
@@ -1061,10 +1058,9 @@ static void update_ring_for_set_deq_completion(struct 
xhci_hcd *xhci,
  * endpoint doorbell to restart the ring, but only if there aren't more
  * cancellations pending.
  */
-static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event, union xhci_trb *trb)
 {
-   unsigned int slot_id;
unsigned int ep_index;
unsigned int stream_id;
struct xhci_ring *ep_ring;
@@ -1072,7 +1068,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
struct xhci_ep_ctx *ep_ctx;
struct xhci_slot_ctx *slot_ctx;
 
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb-generic.field[3]));
stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb-generic.field[2]));
dev = xhci-devs[slot_id];
@@ -1154,13 +1149,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci,
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
-static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event, union xhci_trb *trb)
 {
-   int slot_id;
unsigned int ep_index;
 
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb-generic.field[3]));
/* This command will only fail if the endpoint wasn't halted,
 * but we don't care.
@@ -1556,15 +1549,21 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
case TRB_STOP_RING:
-   xhci_handle_cmd_stop_ep(xhci, cmd_trb, event);
+   WARN_ON(slot_id != TRB_TO_SLOT_ID(
+   le32_to_cpu(cmd_trb-generic.field[3])));
+   xhci_handle_cmd_stop_ep(xhci, slot_id, cmd_trb, event);
break;
case TRB_SET_DEQ:
-   xhci_handle_cmd_set_deq(xhci, event, cmd_trb);
+   WARN_ON(slot_id != TRB_TO_SLOT_ID(
+   le32_to_cpu(cmd_trb-generic.field[3])));
+   xhci_handle_cmd_set_deq(xhci, slot_id, event, cmd_trb);
break;
case TRB_CMD_NOOP:
break;
case TRB_RESET_EP:
-   xhci_handle_cmd_reset_ep(xhci, event, cmd_trb);
+   WARN_ON(slot_id != TRB_TO_SLOT_ID(
+   le32_to_cpu(cmd_trb-generic.field[3])));
+   xhci_handle_cmd_reset_ep(xhci, slot_id, event, cmd_trb);
break;
case TRB_RESET_DEV

[RFC v5 06/19] xhci: use completion event's slot id rather than dig it out of command

2013-09-09 Thread Xenia Ragiadakou
Since the slot id retrieved from the Reset Device TRB matches the slot id in
the command completion event, which is available, there is no need to determine
it again.
This patch removes the uneccessary reassignment to slot id and adds a WARN_ON
in case the two Slot ID fields differ (although according xhci spec rev1.0
they should not differ).

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-the above change is performed now in a separate patch
-a warning is triggered in case the slot id reported in event trb is
 different from the slot id renoted in command trb

Differences from v4:

-the warning was placed inside the TRB_RESET_DEV case statement, since
 for other type of commands, the slot id values may differ.
 The line overflow introduced by the change will be corrected by a follow on
 patch of this patchset

 drivers/usb/host/xhci-ring.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f00d9ef..8a74002 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1527,9 +1527,9 @@ bandwidth_change:
xhci_handle_cmd_reset_ep(xhci, event, xhci-cmd_ring-dequeue);
break;
case TRB_TYPE(TRB_RESET_DEV):
+   WARN_ON(slot_id != TRB_TO_SLOT_ID(
+   
le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])));
xhci_dbg(xhci, Completed reset device command.\n);
-   slot_id = TRB_TO_SLOT_ID(
-   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 05/19] xhci: refactor TRB_ADDR_DEV case into function

2013-09-09 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_ADDR_DEV switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_addr_dev().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f9c380e..f00d9ef 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1393,6 +1393,13 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd 
*xhci, int slot_id)
xhci_free_virt_device(xhci, slot_id);
 }
 
+static void xhci_handle_cmd_addr_dev(struct xhci_hcd *xhci, int slot_id,
+   u32 cmd_comp_code)
+{
+   xhci-devs[slot_id]-cmd_status = cmd_comp_code;
+   complete(xhci-addr_dev);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1505,8 +1512,8 @@ bandwidth_change:
complete(xhci-devs[slot_id]-cmd_completion);
break;
case TRB_TYPE(TRB_ADDR_DEV):
-   xhci-devs[slot_id]-cmd_status = 
GET_COMP_CODE(le32_to_cpu(event-status));
-   complete(xhci-addr_dev);
+   xhci_handle_cmd_addr_dev(xhci, slot_id,
+   GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_STOP_RING):
xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 14/19] xhci: add variable 'cmd_type' in handle_cmd_completion()

2013-09-09 Thread Xenia Ragiadakou
This patch adds a new variable 'cmd_type' to hold the command type so that
switch cases can be simplified by removing TRB_TYPE() macro improving
code readability.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

update changelog to report the reason for such change

 drivers/usb/host/xhci-ring.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 1df73c9..605c327 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1507,6 +1507,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
dma_addr_t cmd_dequeue_dma;
u32 cmd_comp_code;
union xhci_trb *cmd_trb;
+   u32 cmd_type;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
cmd_trb = xhci-cmd_ring-dequeue;
@@ -1539,40 +1540,40 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
}
}
 
-   switch (le32_to_cpu(cmd_trb-generic.field[3])
-TRB_TYPE_BITMASK) {
-   case TRB_TYPE(TRB_ENABLE_SLOT):
+   cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb-generic.field[3]));
+   switch (cmd_type) {
+   case TRB_ENABLE_SLOT:
xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_DISABLE_SLOT):
+   case TRB_DISABLE_SLOT:
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
-   case TRB_TYPE(TRB_CONFIG_EP):
+   case TRB_CONFIG_EP:
xhci_handle_cmd_config_ep(xhci, slot_id, event, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_EVAL_CONTEXT):
+   case TRB_EVAL_CONTEXT:
xhci_handle_cmd_eval_ctx(xhci, slot_id, event, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_ADDR_DEV):
+   case TRB_ADDR_DEV:
xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_STOP_RING):
+   case TRB_STOP_RING:
xhci_handle_cmd_stop_ep(xhci, cmd_trb, event);
break;
-   case TRB_TYPE(TRB_SET_DEQ):
+   case TRB_SET_DEQ:
xhci_handle_cmd_set_deq(xhci, event, cmd_trb);
break;
-   case TRB_TYPE(TRB_CMD_NOOP):
+   case TRB_CMD_NOOP:
break;
-   case TRB_TYPE(TRB_RESET_EP):
+   case TRB_RESET_EP:
xhci_handle_cmd_reset_ep(xhci, event, cmd_trb);
break;
-   case TRB_TYPE(TRB_RESET_DEV):
+   case TRB_RESET_DEV:
WARN_ON(slot_id != TRB_TO_SLOT_ID(
le32_to_cpu(cmd_trb-generic.field[3])));
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;
-   case TRB_TYPE(TRB_NEC_GET_FW):
+   case TRB_NEC_GET_FW:
xhci_handle_cmd_nec_get_fw(xhci, event);
break;
default:
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 09/19] xhci: refactor TRB_EVAL_CONTEXT case into function

2013-09-09 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_EVAL_CONTEXT switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_eval_ctx().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b8b63f8..08ed322 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1393,6 +1393,18 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd 
*xhci, int slot_id)
xhci_free_virt_device(xhci, slot_id);
 }
 
+static void xhci_handle_cmd_eval_ctx(struct xhci_hcd *xhci, int slot_id,
+   struct xhci_event_cmd *event, u32 cmd_comp_code)
+{
+   struct xhci_virt_device *virt_dev;
+
+   virt_dev = xhci-devs[slot_id];
+   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
+   return;
+   virt_dev-cmd_status = cmd_comp_code;
+   complete(virt_dev-cmd_completion);
+}
+
 static void xhci_handle_cmd_addr_dev(struct xhci_hcd *xhci, int slot_id,
u32 cmd_comp_code)
 {
@@ -1532,11 +1544,8 @@ bandwidth_change:
complete(xhci-devs[slot_id]-cmd_completion);
break;
case TRB_TYPE(TRB_EVAL_CONTEXT):
-   virt_dev = xhci-devs[slot_id];
-   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
-   break;
-   xhci-devs[slot_id]-cmd_status = 
GET_COMP_CODE(le32_to_cpu(event-status));
-   complete(xhci-devs[slot_id]-cmd_completion);
+   xhci_handle_cmd_eval_ctx(xhci, slot_id, event,
+   GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_ADDR_DEV):
xhci_handle_cmd_addr_dev(xhci, slot_id,
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 15/19] xhci: replace 'xhci-cmd_ring-dequeue' with 'trb' in stop_ep cmd handler

2013-09-09 Thread Xenia Ragiadakou
This patch replaces 'xhci-cmd_ring-dequeue' with 'trb', the address of
the command TRB, since it is available to reduce line length.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 605c327..ece06b2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -769,10 +769,8 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
 
struct xhci_dequeue_state deq_state;
 
-   if (unlikely(TRB_TO_SUSPEND_PORT(
-
le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3] {
-   slot_id = TRB_TO_SLOT_ID(
-   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3]));
+   if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb-generic.field[3] {
+   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev,
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 11/19] xhci: refactor TRB_CONFIG_EP case into function

2013-09-09 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_CONFIG_EP switch case, in
handle_cmd_completion(), into a fuction named xhci_handle_cmd_config_ep().

There were added two additional variables, 'add_flags' and 'drop_flags',
to reduce line length below 80 chars and improve code readability.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-add reason for new function creation in change log
-add a couple of newlines for clarity

 drivers/usb/host/xhci-ring.c | 114 +++
 1 file changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 195c6e7..6dc582e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1393,6 +1393,66 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd 
*xhci, int slot_id)
xhci_free_virt_device(xhci, slot_id);
 }
 
+static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
+   struct xhci_event_cmd *event, u32 cmd_comp_code)
+{
+   struct xhci_virt_device *virt_dev;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   unsigned int ep_index;
+   unsigned int ep_state;
+   u32 add_flags, drop_flags;
+
+   virt_dev = xhci-devs[slot_id];
+   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
+   return;
+   /*
+* Configure endpoint commands can come from the USB core
+* configuration or alt setting changes, or because the HW
+* needed an extra configure endpoint command after a reset
+* endpoint command or streams were being configured.
+* If the command was for a halted endpoint, the xHCI driver
+* is not waiting on the configure endpoint command.
+*/
+   ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev-in_ctx);
+   if (!ctrl_ctx) {
+   xhci_warn(xhci, Could not get input context, bad type.\n);
+   return;
+   }
+
+   add_flags = le32_to_cpu(ctrl_ctx-add_flags);
+   drop_flags = le32_to_cpu(ctrl_ctx-drop_flags);
+   /* Input ctx add_flags are the endpoint index plus one */
+   ep_index = xhci_last_valid_endpoint(add_flags) - 1;
+
+   /* A usb_set_interface() call directly after clearing a halted
+* condition may race on this quirky hardware.  Not worth
+* worrying about, since this is prototype hardware.  Not sure
+* if this will work for streams, but streams support was
+* untested on this prototype.
+*/
+   if (xhci-quirks  XHCI_RESET_EP_QUIRK 
+   ep_index != (unsigned int) -1 
+   add_flags - SLOT_FLAG == drop_flags) {
+   ep_state = virt_dev-eps[ep_index].ep_state;
+   if (!(ep_state  EP_HALTED))
+   goto bandwidth_change;
+   xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+   Completed config ep cmd - 
+   last ep index = %d, state = %d,
+   ep_index, ep_state);
+   /* Clear internal halted state and restart ring(s) */
+   virt_dev-eps[ep_index].ep_state = ~EP_HALTED;
+   ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+   return;
+   }
+bandwidth_change:
+   xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
+   Completed config ep cmd);
+   virt_dev-cmd_status = cmd_comp_code;
+   complete(virt_dev-cmd_completion);
+   return;
+}
+
 static void xhci_handle_cmd_eval_ctx(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event, u32 cmd_comp_code)
 {
@@ -1445,10 +1505,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event-flags));
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
-   struct xhci_input_control_ctx *ctrl_ctx;
-   struct xhci_virt_device *virt_dev;
-   unsigned int ep_index;
-   unsigned int ep_state;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci-cmd_ring-deq_seg,
@@ -1492,54 +1548,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
-   virt_dev = xhci-devs[slot_id];
-   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
-   break;
-   /*
-* Configure endpoint commands can come from the USB core
-* configuration or alt setting changes, or because the HW
-* needed an extra configure endpoint command after a reset

[RFC v5 03/19] xhci: refactor TRB_ENABLE_SLOT case into function

2013-09-09 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_ENABLE_SLOT switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_enable_slot().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ffd224c..0abf88c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1370,6 +1370,16 @@ static int handle_stopped_cmd_ring(struct xhci_hcd *xhci,
return cur_trb_is_good;
 }
 
+static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
+   u32 cmd_comp_code)
+{
+   if (cmd_comp_code == COMP_SUCCESS)
+   xhci-slot_id = slot_id;
+   else
+   xhci-slot_id = 0;
+   complete(xhci-addr_dev);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1417,11 +1427,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
-   if (GET_COMP_CODE(le32_to_cpu(event-status)) == COMP_SUCCESS)
-   xhci-slot_id = slot_id;
-   else
-   xhci-slot_id = 0;
-   complete(xhci-addr_dev);
+   xhci_handle_cmd_enable_slot(xhci, slot_id,
+   GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
if (xhci-devs[slot_id]) {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 18/19] xhci: add label 'update_ring' in handle_cmd_completion()

2013-09-09 Thread Xenia Ragiadakou
This patch adds the label 'update_ring' for the common code path:
inc_deq(xhci, xhci-cmd_ring);
return;

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-remove return statement

 drivers/usb/host/xhci-ring.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 57769c5..8eb3118 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1524,10 +1524,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 * been stopped by host. So we should handle it normally.
 * Otherwise, driver should invoke inc_deq() and return.
 */
-   if (handle_stopped_cmd_ring(xhci, cmd_comp_code)) {
-   inc_deq(xhci, xhci-cmd_ring);
-   return;
-   }
+   if (handle_stopped_cmd_ring(xhci, cmd_comp_code))
+   goto update_ring;
}
 
cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb-generic.field[3]));
@@ -1577,6 +1575,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci-error_bitmask |= 1  6;
break;
}
+update_ring:
inc_deq(xhci, xhci-cmd_ring);
 }
 
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v5 17/19] xhci: replace 'event' with 'cmd_comp_code' in set_deq and reset_ep handlers

2013-09-09 Thread Xenia Ragiadakou
This patch replaces the 'event' argument of xhci_handle_cmd_set_deq() and
xhci_handle_cmd_reset_ep(), which is used to retrieve the command completion
status code, with the cmd_comp_code directly, since it is available.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 46652da..57769c5 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1059,7 +1059,7 @@ static void update_ring_for_set_deq_completion(struct 
xhci_hcd *xhci,
  * cancellations pending.
  */
 static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
-   struct xhci_event_cmd *event, union xhci_trb *trb)
+   union xhci_trb *trb, u32 cmd_comp_code)
 {
unsigned int ep_index;
unsigned int stream_id;
@@ -1085,11 +1085,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci, int slot_id,
ep_ctx = xhci_get_ep_ctx(xhci, dev-out_ctx, ep_index);
slot_ctx = xhci_get_slot_ctx(xhci, dev-out_ctx);
 
-   if (GET_COMP_CODE(le32_to_cpu(event-status)) != COMP_SUCCESS) {
+   if (cmd_comp_code != COMP_SUCCESS) {
unsigned int ep_state;
unsigned int slot_state;
 
-   switch (GET_COMP_CODE(le32_to_cpu(event-status))) {
+   switch (cmd_comp_code) {
case COMP_TRB_ERR:
xhci_warn(xhci, WARN Set TR Deq Ptr cmd invalid 
because 
of stream ID configuration\n);
@@ -1112,7 +1112,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci, int slot_id,
default:
xhci_warn(xhci, WARN Set TR Deq Ptr cmd with unknown 
completion code of %u.\n,
- GET_COMP_CODE(le32_to_cpu(event-status)));
+ cmd_comp_code);
break;
}
/* OK what do we do now?  The endpoint state is hosed, and we
@@ -1150,7 +1150,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci, int slot_id,
 }
 
 static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
-   struct xhci_event_cmd *event, union xhci_trb *trb)
+   union xhci_trb *trb, u32 cmd_comp_code)
 {
unsigned int ep_index;
 
@@ -1159,8 +1159,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd 
*xhci, int slot_id,
 * but we don't care.
 */
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
-   Ignoring reset ep completion code of %u,
-GET_COMP_CODE(le32_to_cpu(event-status)));
+   Ignoring reset ep completion code of %u, cmd_comp_code);
 
/* HW with the reset endpoint quirk needs to have a configure endpoint
 * command complete before the endpoint can be used.  Queue that here
@@ -1556,14 +1555,14 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
case TRB_SET_DEQ:
WARN_ON(slot_id != TRB_TO_SLOT_ID(
le32_to_cpu(cmd_trb-generic.field[3])));
-   xhci_handle_cmd_set_deq(xhci, slot_id, event, cmd_trb);
+   xhci_handle_cmd_set_deq(xhci, slot_id, cmd_trb, cmd_comp_code);
break;
case TRB_CMD_NOOP:
break;
case TRB_RESET_EP:
WARN_ON(slot_id != TRB_TO_SLOT_ID(
le32_to_cpu(cmd_trb-generic.field[3])));
-   xhci_handle_cmd_reset_ep(xhci, slot_id, event, cmd_trb);
+   xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code);
break;
case TRB_RESET_DEV:
WARN_ON(slot_id != TRB_TO_SLOT_ID(
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 07/21] xhci: fix sparse warning in xhci-trace.h

2013-09-09 Thread Xenia Ragiadakou
This patch fixes the following sparse warnings:
drivers/usb/host/./xhci-trace.h:116:1: warning: cast to restricted __le32
drivers/usb/host/./xhci-trace.h:116:1: warning: cast to restricted __le32
drivers/usb/host/./xhci-trace.h:116:1: warning: restricted __le32 degrades to
integer
drivers/usb/host/./xhci-trace.h:116:1: warning: restricted __le32 degrades to
integer

by converting the field 'trb' of the trace buffer entry structure from array
with elements of type __le32 to an array with elements of type u8.
Into the trb array are copied the contents of the TRB that generated the event.
The trace-cmd tool with the help of plugin_xhci.py will use this field to
parse the TRB contents in a human readable way.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-trace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 59a0b03..132abda 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -121,7 +121,7 @@ DECLARE_EVENT_CLASS(xhci_log_event,
__field(u64, dma)
__field(u32, status)
__field(u32, flags)
-   __dynamic_array(__le32, trb, 4)
+   __dynamic_array(u8, trb, sizeof(struct xhci_generic_trb))
),
TP_fast_assign(
__entry-va = trb_va;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 03/21] xhci: fix incorrect type in assignment in xhci_address_device()

2013-09-09 Thread Xenia Ragiadakou
The field 'dev_info' in struct xhci_slot_ctx has type __le32 and it needs
to be converted to CPU byteorder for the correct retrieval of its subfield
'Context Entries'. This field is used by the trace event 'xhci_address_ctx'
to trace only the contexts of valid endpoints.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index bda0cdf..9f22ddf 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3762,7 +3762,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
xhci_dbg(xhci, Slot ID %d Input Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-in_ctx, 2);
trace_xhci_address_ctx(xhci, virt_dev-in_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
 
spin_lock_irqsave(xhci-lock, flags);
cmd_trb = xhci-cmd_ring-dequeue;
@@ -3841,7 +3841,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
xhci_dbg(xhci, Slot ID %d Input Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-in_ctx, 2);
trace_xhci_address_ctx(xhci, virt_dev-in_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
xhci_dbg(xhci, Slot ID %d Output Context:\n, udev-slot_id);
xhci_dbg_ctx(xhci, virt_dev-out_ctx, 2);
/*
@@ -3850,7 +3850,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
 */
slot_ctx = xhci_get_slot_ctx(xhci, virt_dev-out_ctx);
trace_xhci_address_ctx(xhci, virt_dev-out_ctx,
-   slot_ctx-dev_info  27);
+   le32_to_cpu(slot_ctx-dev_info)  27);
/* Use kernel assigned address for devices; store xHC assigned
 * address locally. */
virt_dev-address = (le32_to_cpu(slot_ctx-dev_state)  DEV_ADDR_MASK)
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 15/21] xhci: replace xhci_writel() with writel() in xhci.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_writel() is used to write a 32bit value in xHC registers residing
in MMIO address space. It takes as first argument a pointer to the xhci_hcd
although it does not use it because internally it simply calls writel().
This creates an illusion that xhci_writel() is an xhci specific function that
has to be called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_writel() with calls to writel() in xhci.c.
This is done so that xhci_writel() can be removed completely and code can
become more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.c | 53 +++--
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6f47c2b..63ccb21 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -88,7 +88,7 @@ void xhci_quiesce(struct xhci_hcd *xhci)
 
cmd = readl(xhci-op_regs-command);
cmd = mask;
-   xhci_writel(xhci, cmd, xhci-op_regs-command);
+   writel(cmd, xhci-op_regs-command);
 }
 
 /*
@@ -128,7 +128,7 @@ static int xhci_start(struct xhci_hcd *xhci)
temp |= (CMD_RUN);
xhci_dbg_trace(xhci, trace_xhci_dbg_init, // Turn on HC, cmd = 0x%x.,
temp);
-   xhci_writel(xhci, temp, xhci-op_regs-command);
+   writel(temp, xhci-op_regs-command);
 
/*
 * Wait for the HCHalted Status bit to be 0 to indicate the host is
@@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci)
xhci_dbg_trace(xhci, trace_xhci_dbg_init, // Reset the HC);
command = readl(xhci-op_regs-command);
command |= CMD_RESET;
-   xhci_writel(xhci, command, xhci-op_regs-command);
+   writel(command, xhci-op_regs-command);
 
ret = xhci_handshake(xhci, xhci-op_regs-command,
CMD_RESET, 0, 10 * 1000 * 1000);
@@ -614,21 +614,20 @@ int xhci_run(struct usb_hcd *hcd)
temp = readl(xhci-ir_set-irq_control);
temp = ~ER_IRQ_INTERVAL_MASK;
temp |= (u32) 160;
-   xhci_writel(xhci, temp, xhci-ir_set-irq_control);
+   writel(temp, xhci-ir_set-irq_control);
 
/* Set the HCD state before we enable the irqs */
temp = readl(xhci-op_regs-command);
temp |= (CMD_EIE);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Enable interrupts, cmd = 0x%x., temp);
-   xhci_writel(xhci, temp, xhci-op_regs-command);
+   writel(temp, xhci-op_regs-command);
 
temp = readl(xhci-ir_set-irq_pending);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Enabling event ring interrupter %p by writing 0x%x 
to irq_pending,
xhci-ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
-   xhci_writel(xhci, ER_IRQ_ENABLE(temp),
-   xhci-ir_set-irq_pending);
+   writel(ER_IRQ_ENABLE(temp), xhci-ir_set-irq_pending);
xhci_print_ir_set(xhci, 0);
 
if (xhci-quirks  XHCI_NEC_HOST)
@@ -699,10 +698,9 @@ void xhci_stop(struct usb_hcd *hcd)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Disabling event ring interrupts);
temp = readl(xhci-op_regs-status);
-   xhci_writel(xhci, temp  ~STS_EINT, xhci-op_regs-status);
+   writel(temp  ~STS_EINT, xhci-op_regs-status);
temp = readl(xhci-ir_set-irq_pending);
-   xhci_writel(xhci, ER_IRQ_DISABLE(temp),
-   xhci-ir_set-irq_pending);
+   writel(ER_IRQ_DISABLE(temp), xhci-ir_set-irq_pending);
xhci_print_ir_set(xhci, 0);
 
xhci_dbg_trace(xhci, trace_xhci_dbg_init, cleaning up memory);
@@ -755,15 +753,15 @@ static void xhci_save_registers(struct xhci_hcd *xhci)
 
 static void xhci_restore_registers(struct xhci_hcd *xhci)
 {
-   xhci_writel(xhci, xhci-s3.command, xhci-op_regs-command);
-   xhci_writel(xhci, xhci-s3.dev_nt, xhci-op_regs-dev_notification);
+   writel(xhci-s3.command, xhci-op_regs-command);
+   writel(xhci-s3.dev_nt, xhci-op_regs-dev_notification);
xhci_write_64(xhci, xhci-s3.dcbaa_ptr, xhci-op_regs-dcbaa_ptr);
-   xhci_writel(xhci, xhci-s3.config_reg, xhci-op_regs-config_reg);
-   xhci_writel(xhci, xhci-s3.erst_size, xhci-ir_set-erst_size);
+   writel(xhci-s3.config_reg, xhci-op_regs-config_reg);
+   writel(xhci-s3.erst_size, xhci-ir_set-erst_size);
xhci_write_64(xhci, xhci-s3.erst_base, xhci-ir_set-erst_base);
xhci_write_64(xhci, xhci-s3.erst_dequeue, xhci-ir_set-erst_dequeue);
-   xhci_writel(xhci, xhci-s3.irq_pending, xhci-ir_set-irq_pending);
-   xhci_writel(xhci, xhci-s3.irq_control, xhci-ir_set-irq_control);
+   writel(xhci-s3.irq_pending, xhci-ir_set-irq_pending);
+   writel(xhci-s3.irq_control, xhci-ir_set-irq_control);
 }
 
 static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
@@ -860,7 +858,7 @@ int xhci_suspend(struct xhci_hcd *xhci

[RFC 06/21] xhci: fix derivation of TRB's DMA address in xhci_log_event Trace Event Class

2013-09-09 Thread Xenia Ragiadakou
This patch fixes the retrieval of the DMA address of the TRB that generated
the event by converting the field[0] (low address bits) and field[1] (high
address bits) to CPU byteorder and then typecasting field[1] to u64 so that
the bitshift will not lead to overflow.
In the original code, the typecasting of le32 to u64 was incorrect and the
subsequent conversion to le64 reverts the low and high address parts.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-trace.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index c156685..59a0b03 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -125,8 +125,8 @@ DECLARE_EVENT_CLASS(xhci_log_event,
),
TP_fast_assign(
__entry-va = trb_va;
-   __entry-dma = le64_to_cpu(((u64)ev-field[1])  32 |
-   ev-field[0]);
+   __entry-dma = ((u64)le32_to_cpu(ev-field[1]))  32 |
+   le32_to_cpu(ev-field[0]);
__entry-status = le32_to_cpu(ev-field[2]);
__entry-flags = le32_to_cpu(ev-field[3]);
memcpy(__get_dynamic_array(trb), trb_va,
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 18/21] xhci: replace xhci_writel() with writel() in xhci-ring.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_writel() is used to write a 32bit value in xHC registers residing
in MMIO address space. It takes as first argument a pointer to the xhci_hcd
although it does not use it because internally it simply calls writel().
This creates an illusion that xhci_writel() is an xhci specific function that
has to be called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_writel() with calls to writel() in
xhci-ring.c.
This is done so that xhci_writel() can be removed completely and code can
become more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5c36c5b..9b50a54 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -285,7 +285,7 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci)
return;
 
xhci_dbg(xhci, // Ding dong!\n);
-   xhci_writel(xhci, DB_VALUE_HOST, xhci-dba-doorbell[0]);
+   writel(DB_VALUE_HOST, xhci-dba-doorbell[0]);
/* Flush PCI posted writes */
readl(xhci-dba-doorbell[0]);
 }
@@ -417,7 +417,7 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
if ((ep_state  EP_HALT_PENDING) || (ep_state  SET_DEQ_PENDING) ||
(ep_state  EP_HALTED))
return;
-   xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr);
+   writel(DB_VALUE(ep_index, stream_id), db_addr);
/* The CPU has better things to do at this point than wait for a
 * write-posting flush.  It'll get there soon enough.
 */
@@ -2825,7 +2825,7 @@ hw_died:
 * Write 1 to clear the interrupt status.
 */
status |= STS_EINT;
-   xhci_writel(xhci, status, xhci-op_regs-status);
+   writel(status, xhci-op_regs-status);
/* FIXME when MSI-X is supported and there are multiple vectors */
/* Clear the MSI-X event interrupt status */
 
@@ -2834,7 +2834,7 @@ hw_died:
/* Acknowledge the PCI interrupt */
irq_pending = readl(xhci-ir_set-irq_pending);
irq_pending |= IMAN_IP;
-   xhci_writel(xhci, irq_pending, xhci-ir_set-irq_pending);
+   writel(irq_pending, xhci-ir_set-irq_pending);
}
 
if (xhci-xhc_state  XHCI_STATE_DYING) {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 14/21] xhci: remove xhci_readl()

2013-09-09 Thread Xenia Ragiadakou
This patch removes xhci_readl() because it has been replaced with readl()
and it is not used anymore.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 9575088..6349044 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1586,11 +1586,6 @@ static inline struct usb_hcd *xhci_to_hcd(struct 
xhci_hcd *xhci)
 
 /* TODO: copied from ehci.h - can be refactored? */
 /* xHCI spec says all registers are little endian */
-static inline unsigned int xhci_readl(const struct xhci_hcd *xhci,
-   __le32 __iomem *regs)
-{
-   return readl(regs);
-}
 static inline void xhci_writel(struct xhci_hcd *xhci,
const unsigned int val, __le32 __iomem *regs)
 {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 04/21] xhci: convert TRB_CYCLE to le32 before using it to set Link TRB's cycle bit

2013-09-09 Thread Xenia Ragiadakou
This patch converts TRB_CYCLE to le32 to update correctly the Cycle Bit in
'control' field of the link TRB.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-mem.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index f201990..37ae98f 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -57,7 +57,7 @@ static struct xhci_segment *xhci_segment_alloc(struct 
xhci_hcd *xhci,
/* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */
if (cycle_state == 0) {
for (i = 0; i  TRBS_PER_SEGMENT; i++)
-   seg-trbs[i].link.control |= TRB_CYCLE;
+   seg-trbs[i].link.control |= cpu_to_le32(TRB_CYCLE);
}
seg-dma = dma;
seg-next = NULL;
@@ -308,7 +308,8 @@ static void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
sizeof(union xhci_trb)*TRBS_PER_SEGMENT);
if (cycle_state == 0) {
for (i = 0; i  TRBS_PER_SEGMENT; i++)
-   seg-trbs[i].link.control |= TRB_CYCLE;
+   seg-trbs[i].link.control |=
+   cpu_to_le32(TRB_CYCLE);
}
/* All endpoint rings have link TRBs */
xhci_link_segments(xhci, seg, seg-next, type);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 16/21] xhci: replace xhci_writel() with writel() in xhci-hub.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_writel() is used to write a 32bit value in xHC registers residing
in MMIO address space. It takes as first argument a pointer to the xhci_hcd
although it does not use it because internally it simply calls writel().
This creates an illusion that xhci_writel() is an xhci specific function that
has to be called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_writel() with calls to writel() in xhci-hub.c.
This is done so that xhci_writel() can be removed completely and code can
become more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-hub.c | 39 ++-
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index e1896ac..e31ea6a 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -342,7 +342,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
}
 
/* Write 1 to disable the port */
-   xhci_writel(xhci, port_status | PORT_PE, addr);
+   writel(port_status | PORT_PE, addr);
port_status = readl(addr);
xhci_dbg(xhci, disable port, actual port %d status  = 0x%x\n,
wIndex, port_status);
@@ -388,7 +388,7 @@ static void xhci_clear_port_change_bit(struct xhci_hcd 
*xhci, u16 wValue,
return;
}
/* Change bits are all write 1 to clear */
-   xhci_writel(xhci, port_status | status, addr);
+   writel(port_status | status, addr);
port_status = readl(addr);
xhci_dbg(xhci, clear port %s change, actual port %d status  = 0x%x\n,
port_change_bit, wIndex, port_status);
@@ -419,7 +419,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
temp = xhci_port_state_to_neutral(temp);
temp = ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
-   xhci_writel(xhci, temp, port_array[port_id]);
+   writel(temp, port_array[port_id]);
 }
 
 static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
@@ -445,7 +445,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
else
temp = ~PORT_WKOC_E;
 
-   xhci_writel(xhci, temp, port_array[port_id]);
+   writel(temp, port_array[port_id]);
 }
 
 /* Test and clear port RWC bit */
@@ -458,7 +458,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
if (temp  port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
-   xhci_writel(xhci, temp, port_array[port_id]);
+   writel(temp, port_array[port_id]);
}
 }
 
@@ -813,8 +813,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
temp |= PORT_CSC | PORT_PEC | PORT_WRC |
PORT_OCC | PORT_RC | PORT_PLC |
PORT_CEC;
-   xhci_writel(xhci, temp | PORT_PE,
-   port_array[wIndex]);
+   writel(temp | PORT_PE, port_array[wIndex]);
temp = readl(port_array[wIndex]);
break;
}
@@ -869,8 +868,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
 * However, khubd will ignore the roothub events until
 * the roothub is registered.
 */
-   xhci_writel(xhci, temp | PORT_POWER,
-   port_array[wIndex]);
+   writel(temp | PORT_POWER, port_array[wIndex]);
 
temp = readl(port_array[wIndex]);
xhci_dbg(xhci, set port power, actual port %d status  
= 0x%x\n, wIndex, temp);
@@ -885,7 +883,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
-   xhci_writel(xhci, temp, port_array[wIndex]);
+   writel(temp, port_array[wIndex]);
 
temp = readl(port_array[wIndex]);
xhci_dbg(xhci, set port reset, actual port %d status  
= 0x%x\n, wIndex, temp);
@@ -900,7 +898,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
-   xhci_writel(xhci, temp, port_array[wIndex]);
+   writel(temp, port_array[wIndex]);
 
temp = readl(port_array[wIndex]);
break;
@@ -910,7 +908,7 @@ int xhci_hub_control(struct usb_hcd

[RFC 11/21] xhci: replace xhci_readl() with readl() in xhci-hub.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci-hub.c.
This is done so that xhci_readl() can be removed completely and code can
become more straightforward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-hub.c | 72 ++---
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index fae697e..e1896ac 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -94,7 +94,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, 
struct xhci_hcd *xhci,
 */
memset(port_removable, 0, sizeof(port_removable));
for (i = 0; i  ports; i++) {
-   portsc = xhci_readl(xhci, xhci-usb2_ports[i]);
+   portsc = readl(xhci-usb2_ports[i]);
/* If a device is removable, PORTSC reports a 0, same as in the
 * hub descriptor DeviceRemovable bits.
 */
@@ -148,7 +148,7 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, 
struct xhci_hcd *xhci,
port_removable = 0;
/* bit 0 is reserved, bit 1 is for port 1, etc. */
for (i = 0; i  ports; i++) {
-   portsc = xhci_readl(xhci, xhci-usb3_ports[i]);
+   portsc = readl(xhci-usb3_ports[i]);
if (portsc  PORT_DEV_REMOVE)
port_removable |= 1  (i + 1);
}
@@ -343,7 +343,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
 
/* Write 1 to disable the port */
xhci_writel(xhci, port_status | PORT_PE, addr);
-   port_status = xhci_readl(xhci, addr);
+   port_status = readl(addr);
xhci_dbg(xhci, disable port, actual port %d status  = 0x%x\n,
wIndex, port_status);
 }
@@ -389,7 +389,7 @@ static void xhci_clear_port_change_bit(struct xhci_hcd 
*xhci, u16 wValue,
}
/* Change bits are all write 1 to clear */
xhci_writel(xhci, port_status | status, addr);
-   port_status = xhci_readl(xhci, addr);
+   port_status = readl(addr);
xhci_dbg(xhci, clear port %s change, actual port %d status  = 0x%x\n,
port_change_bit, wIndex, port_status);
 }
@@ -415,7 +415,7 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
 {
u32 temp;
 
-   temp = xhci_readl(xhci, port_array[port_id]);
+   temp = readl(port_array[port_id]);
temp = xhci_port_state_to_neutral(temp);
temp = ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
@@ -427,7 +427,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
 {
u32 temp;
 
-   temp = xhci_readl(xhci, port_array[port_id]);
+   temp = readl(port_array[port_id]);
temp = xhci_port_state_to_neutral(temp);
 
if (wake_mask  USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
@@ -454,7 +454,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
 {
u32 temp;
 
-   temp = xhci_readl(xhci, port_array[port_id]);
+   temp = readl(port_array[port_id]);
if (temp  port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
@@ -707,12 +707,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
/* Set the U1 and U2 exit latencies. */
memcpy(buf, usb_bos_descriptor,
USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE);
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params3);
+   temp = readl(xhci-cap_regs-hcs_params3);
buf[12] = HCS_U1_LATENCY(temp);
put_unaligned_le16(HCS_U2_LATENCY(temp), buf[13]);
 
/* Indicate whether the host has LTM support. */
-   temp = xhci_readl(xhci, xhci-cap_regs-hcc_params);
+   temp = readl(xhci-cap_regs-hcc_params);
if (HCC_LTC(temp))
buf[8] |= USB_LTM_SUPPORT;
 
@@ -722,7 +722,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
if (!wIndex || wIndex  max_ports)
goto error;
wIndex--;
-   temp = xhci_readl(xhci, port_array[wIndex]);
+   temp = readl(port_array[wIndex]);
if (temp == 0x) {
retval = -ENODEV;
break;
@@ -749,7 +749,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
if (!wIndex

[RFC 12/21] xhci: replace xhci_readl() with readl() in xhci-mem.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci-mem.c.
This is done so that xhci_readl() can be removed completely and code can
become more straightforward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-mem.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index e1c4b79..af6576c 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1996,7 +1996,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, 
unsigned int num_ports,
}
 
/* Port offset and count in the third dword, see section 7.2 */
-   temp = xhci_readl(xhci, addr + 2);
+   temp = readl(addr + 2);
port_offset = XHCI_EXT_PORT_OFF(temp);
port_count = XHCI_EXT_PORT_COUNT(temp);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
@@ -2079,7 +2079,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, 
gfp_t flags)
int cap_count = 0;
 
addr = xhci-cap_regs-hcc_params;
-   offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
+   offset = XHCI_HCC_EXT_CAPS(readl(addr));
if (offset == 0) {
xhci_err(xhci, No Extended Capability registers, 
unable to set up roothub.\n);
@@ -2116,7 +2116,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, 
gfp_t flags)
/* count extended protocol capability entries for later caching */
do {
u32 cap_id;
-   cap_id = xhci_readl(xhci, tmp_addr);
+   cap_id = readl(tmp_addr);
if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
cap_count++;
tmp_offset = XHCI_EXT_CAPS_NEXT(cap_id);
@@ -2130,7 +2130,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, 
gfp_t flags)
while (1) {
u32 cap_id;
 
-   cap_id = xhci_readl(xhci, addr);
+   cap_id = readl(addr);
if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
xhci_add_in_port(xhci, num_ports, addr,
(u8) XHCI_EXT_PORT_MAJOR(cap_id),
@@ -2235,7 +2235,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
INIT_LIST_HEAD(xhci-lpm_failed_devs);
INIT_LIST_HEAD(xhci-cancel_cmd_list);
 
-   page_size = xhci_readl(xhci, xhci-op_regs-page_size);
+   page_size = readl(xhci-op_regs-page_size);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
Supported page size register = 0x%x, page_size);
i = ffs(page_size  0x) - 1;
@@ -2254,10 +2254,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 * Program the Number of Device Slots Enabled field in the CONFIG
 * register with the max value of slots the HC can handle.
 */
-   val = HCS_MAX_SLOTS(xhci_readl(xhci, xhci-cap_regs-hcs_params1));
+   val = HCS_MAX_SLOTS(readl(xhci-cap_regs-hcs_params1));
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// xHC can handle at most %d device slots., val);
-   val2 = xhci_readl(xhci, xhci-op_regs-config_reg);
+   val2 = readl(xhci-op_regs-config_reg);
val |= (val2  ~HCS_SLOTS_MASK);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Setting Max device slots reg = 0x%x., val);
@@ -2338,7 +2338,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 */
xhci-cmd_ring_reserved_trbs++;
 
-   val = xhci_readl(xhci, xhci-cap_regs-db_off);
+   val = readl(xhci-cap_regs-db_off);
val = DBOFF_MASK;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Doorbell array is located at offset 0x%x
@@ -2389,7 +2389,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
}
 
/* set ERST count with the number of entries in the segment table */
-   val = xhci_readl(xhci, xhci-ir_set-erst_size);
+   val = readl(xhci-ir_set-erst_size);
val = ERST_SIZE_MASK;
val |= ERST_NUM_SEGS;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
@@ -2436,7 +2436,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 * is necessary for allowing USB 3.0 devices to do remote wakeup from
 * U3 (device suspend).
 */
-   temp = xhci_readl(xhci, xhci-op_regs-dev_notification);
+   temp = readl(xhci-op_regs-dev_notification);
temp = ~DEV_NOTE_MASK;
temp |= DEV_NOTE_FWAKE;
xhci_writel(xhci, temp, xhci-op_regs

[RFC 01/21] xhci: fix incorrect type in assignment in xhci_count_num_new_endpoints()

2013-09-09 Thread Xenia Ragiadakou
The fields 'add_flags' and 'drop_flags' in struct xhci_input_control_ctx
have type __le32 and need to be converted to CPU byteorder before being
used to derive the number of added endpoints.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 787076e..617d568 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1880,8 +1880,8 @@ static u32 xhci_count_num_new_endpoints(struct xhci_hcd 
*xhci,
 * (bit 1).  The default control endpoint is added during the Address
 * Device command and is never removed until the slot is disabled.
 */
-   valid_add_flags = ctrl_ctx-add_flags  2;
-   valid_drop_flags = ctrl_ctx-drop_flags  2;
+   valid_add_flags = le32_to_cpu(ctrl_ctx-add_flags)  2;
+   valid_drop_flags = le32_to_cpu(ctrl_ctx-drop_flags)  2;
 
/* Use hweight32 to count the number of ones in the add flags, or
 * number of endpoints added.  Don't count endpoints that are changed
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 08/21] xhci: use ffs() for page size's calculation in xhci_mem_init()

2013-09-09 Thread Xenia Ragiadakou
The first 16 bits of Page Size Register report the page size supported by xHC.
If bit i is set, then xHC supports a page size of 2^(i+12).
This patch replaces the code that does the lookup for the first set bit with
a call to ffs() because using ffs() the code can benefit from architecture
specific instructions that implement this computation more efficiently.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-mem.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 37ae98f..e1c4b79 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -25,6 +25,7 @@
 #include linux/slab.h
 #include linux/dmapool.h
 #include linux/dma-mapping.h
+#include linux/bitops.h
 
 #include xhci.h
 #include xhci-trace.h
@@ -2237,12 +2238,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
page_size = xhci_readl(xhci, xhci-op_regs-page_size);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
Supported page size register = 0x%x, page_size);
-   for (i = 0; i  16; i++) {
-   if ((0x1  page_size) != 0)
-   break;
-   page_size = page_size  1;
-   }
-   if (i  16)
+   i = ffs(page_size  0x) - 1;
+   if (i  -1)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
Supported page size of %iK, (1  (i+12)) / 1024);
else
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 10/21] xhci: replace xhci_readl() with readl() in xhci-dbg.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci-dbg.c.
This is done so that xhci_readl() can be removed completely and code can
become more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-dbg.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 73503a8..eb009a4 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -32,7 +32,7 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)
 
xhci_dbg(xhci, // xHCI capability registers at %p:\n,
xhci-cap_regs);
-   temp = xhci_readl(xhci, xhci-cap_regs-hc_capbase);
+   temp = readl(xhci-cap_regs-hc_capbase);
xhci_dbg(xhci, // @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n,
xhci-cap_regs-hc_capbase, temp);
xhci_dbg(xhci, //   CAPLENGTH: 0x%x\n,
@@ -44,13 +44,13 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)
 
xhci_dbg(xhci, // xHCI operational registers at %p:\n, xhci-op_regs);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-run_regs_off);
+   temp = readl(xhci-cap_regs-run_regs_off);
xhci_dbg(xhci, // @%p = 0x%x RTSOFF\n,
xhci-cap_regs-run_regs_off,
(unsigned int) temp  RTSOFF_MASK);
xhci_dbg(xhci, // xHCI runtime registers at %p:\n, xhci-run_regs);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-db_off);
+   temp = readl(xhci-cap_regs-db_off);
xhci_dbg(xhci, // @%p = 0x%x DBOFF\n, xhci-cap_regs-db_off, temp);
xhci_dbg(xhci, // Doorbell array at %p:\n, xhci-dba);
 }
@@ -61,7 +61,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
 
xhci_dbg(xhci, xHCI capability registers at %p:\n, xhci-cap_regs);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hc_capbase);
+   temp = readl(xhci-cap_regs-hc_capbase);
xhci_dbg(xhci, CAPLENGTH AND HCIVERSION 0x%x:\n,
(unsigned int) temp);
xhci_dbg(xhci, CAPLENGTH: 0x%x\n,
@@ -69,7 +69,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci, HCIVERSION: 0x%x\n,
(unsigned int) HC_VERSION(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params1);
+   temp = readl(xhci-cap_regs-hcs_params1);
xhci_dbg(xhci, HCSPARAMS 1: 0x%x\n,
(unsigned int) temp);
xhci_dbg(xhci,   Max device slots: %u\n,
@@ -79,7 +79,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci,   Max ports: %u\n,
(unsigned int) HCS_MAX_PORTS(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params2);
+   temp = readl(xhci-cap_regs-hcs_params2);
xhci_dbg(xhci, HCSPARAMS 2: 0x%x\n,
(unsigned int) temp);
xhci_dbg(xhci,   Isoc scheduling threshold: %u\n,
@@ -87,7 +87,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci,   Maximum allowed segments in event ring: %u\n,
(unsigned int) HCS_ERST_MAX(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcs_params3);
+   temp = readl(xhci-cap_regs-hcs_params3);
xhci_dbg(xhci, HCSPARAMS 3 0x%x:\n,
(unsigned int) temp);
xhci_dbg(xhci,   Worst case U1 device exit latency: %u\n,
@@ -95,14 +95,14 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
xhci_dbg(xhci,   Worst case U2 device exit latency: %u\n,
(unsigned int) HCS_U2_LATENCY(temp));
 
-   temp = xhci_readl(xhci, xhci-cap_regs-hcc_params);
+   temp = readl(xhci-cap_regs-hcc_params);
xhci_dbg(xhci, HCC PARAMS 0x%x:\n, (unsigned int) temp);
xhci_dbg(xhci,   HC generates %s bit addresses\n,
HCC_64BIT_ADDR(temp) ? 64 : 32);
/* FIXME */
xhci_dbg(xhci,   FIXME: more HCCPARAMS debugging\n);
 
-   temp = xhci_readl(xhci, xhci-cap_regs-run_regs_off);
+   temp = readl(xhci-cap_regs-run_regs_off);
xhci_dbg(xhci, RTSOFF 0x%x:\n, temp  RTSOFF_MASK);
 }
 
@@ -110,7 +110,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)
 {
u32 temp;
 
-   temp = xhci_readl(xhci, xhci-op_regs-command);
+   temp = readl(xhci-op_regs-command);
xhci_dbg(xhci, USBCMD 0x%x:\n, temp);
xhci_dbg(xhci,   HC is %s\n,
(temp  CMD_RUN) ? running : being stopped);
@@ -128,7 +128,7 @@ static void xhci_print_status(struct xhci_hcd *xhci)
 {
u32 temp

[RFC 09/21] xhci: replace xhci_readl() with readl() in xhci.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci.c.
This is done so that xhci_readl() can be removed completely and code can
become more straightforward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.c | 92 -
 1 file changed, 46 insertions(+), 46 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9f22ddf..6f47c2b 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -60,7 +60,7 @@ int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 result;
 
do {
-   result = xhci_readl(xhci, ptr);
+   result = readl(ptr);
if (result == ~(u32)0)  /* card removed */
return -ENODEV;
result = mask;
@@ -82,11 +82,11 @@ void xhci_quiesce(struct xhci_hcd *xhci)
u32 mask;
 
mask = ~(XHCI_IRQS);
-   halted = xhci_readl(xhci, xhci-op_regs-status)  STS_HALT;
+   halted = readl(xhci-op_regs-status)  STS_HALT;
if (!halted)
mask = ~CMD_RUN;
 
-   cmd = xhci_readl(xhci, xhci-op_regs-command);
+   cmd = readl(xhci-op_regs-command);
cmd = mask;
xhci_writel(xhci, cmd, xhci-op_regs-command);
 }
@@ -124,7 +124,7 @@ static int xhci_start(struct xhci_hcd *xhci)
u32 temp;
int ret;
 
-   temp = xhci_readl(xhci, xhci-op_regs-command);
+   temp = readl(xhci-op_regs-command);
temp |= (CMD_RUN);
xhci_dbg_trace(xhci, trace_xhci_dbg_init, // Turn on HC, cmd = 0x%x.,
temp);
@@ -158,14 +158,14 @@ int xhci_reset(struct xhci_hcd *xhci)
u32 state;
int ret, i;
 
-   state = xhci_readl(xhci, xhci-op_regs-status);
+   state = readl(xhci-op_regs-status);
if ((state  STS_HALT) == 0) {
xhci_warn(xhci, Host controller not halted, aborting 
reset.\n);
return 0;
}
 
xhci_dbg_trace(xhci, trace_xhci_dbg_init, // Reset the HC);
-   command = xhci_readl(xhci, xhci-op_regs-command);
+   command = readl(xhci-op_regs-command);
command |= CMD_RESET;
xhci_writel(xhci, command, xhci-op_regs-command);
 
@@ -422,7 +422,7 @@ static void compliance_mode_recovery(unsigned long arg)
xhci = (struct xhci_hcd *)arg;
 
for (i = 0; i  xhci-num_usb3_ports; i++) {
-   temp = xhci_readl(xhci, xhci-usb3_ports[i]);
+   temp = readl(xhci-usb3_ports[i]);
if ((temp  PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
/*
 * Compliance Mode Detected. Letting USB Core
@@ -611,19 +611,19 @@ int xhci_run(struct usb_hcd *hcd)
 
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Set the interrupt modulation register);
-   temp = xhci_readl(xhci, xhci-ir_set-irq_control);
+   temp = readl(xhci-ir_set-irq_control);
temp = ~ER_IRQ_INTERVAL_MASK;
temp |= (u32) 160;
xhci_writel(xhci, temp, xhci-ir_set-irq_control);
 
/* Set the HCD state before we enable the irqs */
-   temp = xhci_readl(xhci, xhci-op_regs-command);
+   temp = readl(xhci-op_regs-command);
temp |= (CMD_EIE);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Enable interrupts, cmd = 0x%x., temp);
xhci_writel(xhci, temp, xhci-op_regs-command);
 
-   temp = xhci_readl(xhci, xhci-ir_set-irq_pending);
+   temp = readl(xhci-ir_set-irq_pending);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Enabling event ring interrupter %p by writing 0x%x 
to irq_pending,
xhci-ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
@@ -698,9 +698,9 @@ void xhci_stop(struct usb_hcd *hcd)
 
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Disabling event ring interrupts);
-   temp = xhci_readl(xhci, xhci-op_regs-status);
+   temp = readl(xhci-op_regs-status);
xhci_writel(xhci, temp  ~STS_EINT, xhci-op_regs-status);
-   temp = xhci_readl(xhci, xhci-ir_set-irq_pending);
+   temp = readl(xhci-ir_set-irq_pending);
xhci_writel(xhci, ER_IRQ_DISABLE(temp),
xhci-ir_set-irq_pending);
xhci_print_ir_set(xhci, 0);
@@ -709,7 +709,7 @@ void xhci_stop(struct usb_hcd *hcd)
xhci_mem_cleanup(xhci);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
xhci_stop completed - status = %x,
-   xhci_readl(xhci, xhci-op_regs

[RFC 17/21] xhci: replace xhci_writel() with writel() in xhci-mem.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_writel() is used to write a 32bit value in xHC registers residing
in MMIO address space. It takes as first argument a pointer to the xhci_hcd
although it does not use it because internally it simply calls writel().
This creates an illusion that xhci_writel() is an xhci specific function that
has to be called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_writel() with calls to writel() in xhci-mem.c.
This is done so that xhci_writel() can be removed completely and code can
become more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-mem.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index af6576c..f9873fa 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2261,7 +2261,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
val |= (val2  ~HCS_SLOTS_MASK);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Setting Max device slots reg = 0x%x., val);
-   xhci_writel(xhci, val, xhci-op_regs-config_reg);
+   writel(val, xhci-op_regs-config_reg);
 
/*
 * Section 5.4.8 - doorbell array must be
@@ -2395,7 +2395,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Write ERST size = %i to ir_set 0 (some bits 
preserved),
val);
-   xhci_writel(xhci, val, xhci-ir_set-erst_size);
+   writel(val, xhci-ir_set-erst_size);
 
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Set ERST entries to point to event ring.);
@@ -2439,7 +2439,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
temp = readl(xhci-op_regs-dev_notification);
temp = ~DEV_NOTE_MASK;
temp |= DEV_NOTE_FWAKE;
-   xhci_writel(xhci, temp, xhci-op_regs-dev_notification);
+   writel(temp, xhci-op_regs-dev_notification);
 
return 0;
 
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 13/21] xhci: replace xhci_readl() with readl() in xhci-ring.c

2013-09-09 Thread Xenia Ragiadakou
Function xhci_readl() is used to read 32bit xHC registers residing in MMIO
address space. It takes as first argument a pointer to the xhci_hcd although
it does not use it because internally it simply calls readl. This creates
an illusion that xhci_readl() is an xhci specific function that has to be
called in a context where a pointer to xhci_hcd is available.
This patch replaces calls to xhci_readl() with calls to readl() in xhci-ring.c.
This is done so that xhci_readl() can be removed completely and code can
become more straight-forward.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index faff6fc..5c36c5b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -287,7 +287,7 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci)
xhci_dbg(xhci, // Ding dong!\n);
xhci_writel(xhci, DB_VALUE_HOST, xhci-dba-doorbell[0]);
/* Flush PCI posted writes */
-   xhci_readl(xhci, xhci-dba-doorbell[0]);
+   readl(xhci-dba-doorbell[0]);
 }
 
 static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
@@ -1718,7 +1718,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci,
port_id);
 
-   temp = xhci_readl(xhci, port_array[faked_port_index]);
+   temp = readl(port_array[faked_port_index]);
if (hcd-state == HC_STATE_SUSPENDED) {
xhci_dbg(xhci, resume root hub\n);
usb_hcd_resume_root_hub(hcd);
@@ -1727,7 +1727,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
if ((temp  PORT_PLC)  (temp  PORT_PLS_MASK) == XDEV_RESUME) {
xhci_dbg(xhci, port resume event for port %d\n, port_id);
 
-   temp1 = xhci_readl(xhci, xhci-op_regs-command);
+   temp1 = readl(xhci-op_regs-command);
if (!(temp1  CMD_RUN)) {
xhci_warn(xhci, xHC is not running.\n);
goto cleanup;
@@ -2803,7 +2803,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
 
spin_lock(xhci-lock);
/* Check if the xHC generated the interrupt, or the irq is shared */
-   status = xhci_readl(xhci, xhci-op_regs-status);
+   status = readl(xhci-op_regs-status);
if (status == 0x)
goto hw_died;
 
@@ -2832,7 +2832,7 @@ hw_died:
if (hcd-irq) {
u32 irq_pending;
/* Acknowledge the PCI interrupt */
-   irq_pending = xhci_readl(xhci, xhci-ir_set-irq_pending);
+   irq_pending = readl(xhci-ir_set-irq_pending);
irq_pending |= IMAN_IP;
xhci_writel(xhci, irq_pending, xhci-ir_set-irq_pending);
}
@@ -3907,7 +3907,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, 
gfp_t mem_flags,
if (ret)
return ret;
 
-   start_frame = xhci_readl(xhci, xhci-run_regs-microframe_index);
+   start_frame = readl(xhci-run_regs-microframe_index);
start_frame = 0x3fff;
 
urb-start_frame = start_frame;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 05/21] xhci: fix incorrect type in assignment in handle_device_notification()

2013-09-09 Thread Xenia Ragiadakou
This patch converts Event TRB's 3rd field, which has type le32, to CPU
byteorder before using it to retrieve the Slot ID with TRB_TO_SLOT_ID macro.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index af9bbac..faff6fc 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1634,7 +1634,7 @@ static void handle_device_notification(struct xhci_hcd 
*xhci,
u32 slot_id;
struct usb_device *udev;
 
-   slot_id = TRB_TO_SLOT_ID(event-generic.field[3]);
+   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event-generic.field[3]));
if (!xhci-devs[slot_id]) {
xhci_warn(xhci, Device Notification event for 
unused slot %u\n, slot_id);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 02/21] xhci: fix incorrect type in assignment in xhci_count_num_dropped_endpoints()

2013-09-09 Thread Xenia Ragiadakou
The fields 'add_flags' and 'drop_flags' in struct xhci_input_control_ctx
have type __le32 and need to be converted to CPU byteorder before being
used to derive the number of dropped endpoints.
This bug was found using sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 617d568..bda0cdf 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1897,8 +1897,8 @@ static unsigned int 
xhci_count_num_dropped_endpoints(struct xhci_hcd *xhci,
u32 valid_add_flags;
u32 valid_drop_flags;
 
-   valid_add_flags = ctrl_ctx-add_flags  2;
-   valid_drop_flags = ctrl_ctx-drop_flags  2;
+   valid_add_flags = le32_to_cpu(ctrl_ctx-add_flags)  2;
+   valid_drop_flags = le32_to_cpu(ctrl_ctx-drop_flags)  2;
 
return hweight32(valid_drop_flags) -
hweight32(valid_add_flags  valid_drop_flags);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 19/21] xhci: remove xhci_writel()

2013-09-09 Thread Xenia Ragiadakou
This patch removes xhci_writel() since its calls has been replaced with
writel() and it is not used anymore.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6349044..2a2ab62 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1584,14 +1584,6 @@ static inline struct usb_hcd *xhci_to_hcd(struct 
xhci_hcd *xhci)
 #define xhci_warn_ratelimited(xhci, fmt, args...) \
dev_warn_ratelimited(xhci_to_hcd(xhci)-self.controller , fmt , ## args)
 
-/* TODO: copied from ehci.h - can be refactored? */
-/* xHCI spec says all registers are little endian */
-static inline void xhci_writel(struct xhci_hcd *xhci,
-   const unsigned int val, __le32 __iomem *regs)
-{
-   writel(val, regs);
-}
-
 /*
  * Registers should always be accessed with double word or quad word accesses.
  *
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 21/21] xhci: replace xhci_write_64() with writeq() and remove xhci_write_64()

2013-09-09 Thread Xenia Ragiadakou
Function xhci_write_64() is used to write an 64bit value in xHC registers,
residing in MMIO.
On 32bit systems, xHC registers should be read/written with 32bit accesses by
reading/writing the low 32bits first and then the high 32bits second.
Since asm-generic/io-64-nonatomic-lo-hi.h header file was included in xhci.h
with the previous patch, if the system is not 64bit, writeq() will write
64bit registers in low-high order.
This patch replaces all calls to xhci_write_64() with calls to writeq()
and removes xhci_write_64().
This is done to reduce code duplication since 64bit register write operation
is already implemented.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-mem.c  |  8 
 drivers/usb/host/xhci-ring.c |  8 +++-
 drivers/usb/host/xhci.c  |  8 
 drivers/usb/host/xhci.h  | 30 ++
 4 files changed, 21 insertions(+), 33 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index dae8a39..54faa1f 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1977,7 +1977,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Write event ring dequeue pointer, 
preserving EHB bit);
-   xhci_write_64(xhci, ((u64) deq  (u64) ~ERST_PTR_MASK) | temp,
+   writeq(((u64) deq  (u64) ~ERST_PTR_MASK) | temp,
xhci-ir_set-erst_dequeue);
 }
 
@@ -2276,7 +2276,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Device context base array address = 0x%llx (DMA), 
%p (virt),
(unsigned long long)xhci-dcbaa-dma, xhci-dcbaa);
-   xhci_write_64(xhci, dma, xhci-op_regs-dcbaa_ptr);
+   writeq(dma, xhci-op_regs-dcbaa_ptr);
 
/*
 * Initialize the ring segment pool.  The ring must be a contiguous
@@ -2325,7 +2325,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci-cmd_ring-cycle_state;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Setting command ring address to 0x%x, val);
-   xhci_write_64(xhci, val_64, xhci-op_regs-cmd_ring);
+   writeq(val_64, xhci-op_regs-cmd_ring);
xhci_dbg_cmd_ptrs(xhci);
 
xhci-lpm_command = xhci_alloc_command(xhci, true, true, flags);
@@ -2406,7 +2406,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
val_64 = readq(xhci-ir_set-erst_base);
val_64 = ERST_PTR_MASK;
val_64 |= (xhci-erst.erst_dma_addr  (u64) ~ERST_PTR_MASK);
-   xhci_write_64(xhci, val_64, xhci-ir_set-erst_base);
+   writeq(val_64, xhci-ir_set-erst_base);
 
/* Set the event ring dequeue address */
xhci_set_hc_event_deq(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5192170..7e26c0e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -309,8 +309,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
return 0;
}
xhci-cmd_ring_state = CMD_RING_STATE_ABORTED;
-   xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
-   xhci-op_regs-cmd_ring);
+   writeq(temp_64 | CMD_RING_ABORT, xhci-op_regs-cmd_ring);
 
/* Section 4.6.1.2 of xHCI 1.0 spec says software should
 * time the completion od all xHCI commands, including
@@ -2844,8 +2843,7 @@ hw_died:
 * the event ring should be empty.
 */
temp_64 = readq(xhci-ir_set-erst_dequeue);
-   xhci_write_64(xhci, temp_64 | ERST_EHB,
-   xhci-ir_set-erst_dequeue);
+   writeq(temp_64 | ERST_EHB, xhci-ir_set-erst_dequeue);
spin_unlock(xhci-lock);
 
return IRQ_HANDLED;
@@ -2872,7 +2870,7 @@ hw_died:
 
/* Clear the event handler busy flag (RW1C); event ring is empty. */
temp_64 |= ERST_EHB;
-   xhci_write_64(xhci, temp_64, xhci-ir_set-erst_dequeue);
+   writeq(temp_64, xhci-ir_set-erst_dequeue);
 
spin_unlock(xhci-lock);
 
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index c56cf1f..af08443 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -755,11 +755,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
 {
writel(xhci-s3.command, xhci-op_regs-command);
writel(xhci-s3.dev_nt, xhci-op_regs-dev_notification);
-   xhci_write_64(xhci, xhci-s3.dcbaa_ptr, xhci-op_regs-dcbaa_ptr);
+   writeq(xhci-s3.dcbaa_ptr, xhci-op_regs-dcbaa_ptr);
writel(xhci-s3.config_reg, xhci-op_regs-config_reg);
writel(xhci-s3.erst_size, xhci-ir_set-erst_size);
-   xhci_write_64(xhci, xhci-s3.erst_base, xhci-ir_set-erst_base);
-   xhci_write_64(xhci, xhci-s3.erst_dequeue, xhci-ir_set-erst_dequeue);
+   writeq(xhci

[RFC 20/21] xhci: replace xhci_read_64() with readq() and remove xhci_read_64()

2013-09-09 Thread Xenia Ragiadakou
Function xhci_read_64() is used to read 64bit xHC registers residing in MMIO.
On 32bit systems, registers should be read/written with 32bit accesses by
reading/writing the low 32bits first and then the high 32bits second.
This patch adds asm-generic/io-64-nonatomic-lo-hi.h header file in xhci.h
so that if the system is not 64bit, readq() will read registers in low-high
order. Also, it replaces all calls to xhci_read_64() with calls to readq()
and removes xhci_read_64().
This is done to reduce code duplication since 64bit register read operation
is already implemented.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-dbg.c  |  6 +++---
 drivers/usb/host/xhci-mem.c  |  6 +++---
 drivers/usb/host/xhci-ring.c |  6 +++---
 drivers/usb/host/xhci.c  | 12 ++--
 drivers/usb/host/xhci.h  |  9 +
 5 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index eb009a4..b016d38 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -203,12 +203,12 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num)
addr, (unsigned int)temp);
 
addr = ir_set-erst_base;
-   temp_64 = xhci_read_64(xhci, addr);
+   temp_64 = readq(addr);
xhci_dbg(xhci,   %p: ir_set.erst_base = @%08llx\n,
addr, temp_64);
 
addr = ir_set-erst_dequeue;
-   temp_64 = xhci_read_64(xhci, addr);
+   temp_64 = readq(addr);
xhci_dbg(xhci,   %p: ir_set.erst_dequeue = @%08llx\n,
addr, temp_64);
 }
@@ -412,7 +412,7 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
 {
u64 val;
 
-   val = xhci_read_64(xhci, xhci-op_regs-cmd_ring);
+   val = readq(xhci-op_regs-cmd_ring);
xhci_dbg(xhci, // xHC command ring deq ptr low bits + flags = @%08x\n,
lower_32_bits(val));
xhci_dbg(xhci, // xHC command ring deq ptr high bits = @%08x\n,
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index f9873fa..dae8a39 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1968,7 +1968,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
xhci_warn(xhci, WARN something wrong with SW event ring 
dequeue ptr.\n);
/* Update HC event ring dequeue pointer */
-   temp = xhci_read_64(xhci, xhci-ir_set-erst_dequeue);
+   temp = readq(xhci-ir_set-erst_dequeue);
temp = ERST_PTR_MASK;
/* Don't clear the EHB bit (which is RW1C) because
 * there might be more events to service.
@@ -2319,7 +2319,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
(unsigned long long)xhci-cmd_ring-first_seg-dma);
 
/* Set the address in the Command Ring Control register */
-   val_64 = xhci_read_64(xhci, xhci-op_regs-cmd_ring);
+   val_64 = readq(xhci-op_regs-cmd_ring);
val_64 = (val_64  (u64) CMD_RING_RSVD_BITS) |
(xhci-cmd_ring-first_seg-dma  (u64) ~CMD_RING_RSVD_BITS) |
xhci-cmd_ring-cycle_state;
@@ -2403,7 +2403,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
// Set ERST base address for ir_set 0 = 0x%llx,
(unsigned long long)xhci-erst.erst_dma_addr);
-   val_64 = xhci_read_64(xhci, xhci-ir_set-erst_base);
+   val_64 = readq(xhci-ir_set-erst_base);
val_64 = ERST_PTR_MASK;
val_64 |= (xhci-erst.erst_dma_addr  (u64) ~ERST_PTR_MASK);
xhci_write_64(xhci, val_64, xhci-ir_set-erst_base);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9b50a54..5192170 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -303,7 +303,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
return 0;
}
 
-   temp_64 = xhci_read_64(xhci, xhci-op_regs-cmd_ring);
+   temp_64 = readq(xhci-op_regs-cmd_ring);
if (!(temp_64  CMD_RING_RUNNING)) {
xhci_dbg(xhci, Command ring had been stopped\n);
return 0;
@@ -2843,7 +2843,7 @@ hw_died:
/* Clear the event handler busy flag (RW1C);
 * the event ring should be empty.
 */
-   temp_64 = xhci_read_64(xhci, xhci-ir_set-erst_dequeue);
+   temp_64 = readq(xhci-ir_set-erst_dequeue);
xhci_write_64(xhci, temp_64 | ERST_EHB,
xhci-ir_set-erst_dequeue);
spin_unlock(xhci-lock);
@@ -2857,7 +2857,7 @@ hw_died:
 */
while (xhci_handle_event(xhci)  0) {}
 
-   temp_64 = xhci_read_64(xhci, xhci-ir_set-erst_dequeue);
+   temp_64 = readq(xhci-ir_set-erst_dequeue);
/* If necessary, update the HW's version of the event ring deq ptr

Re: [PATCH v3] usbcore: check usb device's state before sending a Set SEL control transfer

2013-09-06 Thread Xenia Ragiadakou

On 09/04/2013 09:25 PM, Martin MOKREJŠ wrote:

Hi Xenia,
   thank you. I tested this patch on 3.11 kernel and the messages don't appear 
anymore
upon LPM-capable device disconnect (tested with ASMedia AS2105 devices).
Not much to show here, there is just no error/warning related to LPM
while handling these devices.

Probably better test is with Prolific-based device for which I get during 
connect:
[  999.906164] usb 4-2.1: new SuperSpeed USB device number 20 using xhci_hcd
[  999.928475] usb 4-2.1: New USB device found, idVendor=067b, idProduct=2773
[  999.928488] usb 4-2.1: New USB device strings: Mfr=1, Product=2, 
SerialNumber=3
[  999.928495] usb 4-2.1: Product: USB-SATA Bridge
[  999.928501] usb 4-2.1: Manufacturer: Prolific Technology Inc.
[  999.928506] usb 4-2.1: SerialNumber: PROLIFICMP7
[  999.929633] usb 4-2.1: Set SEL for device-initiated U1 failed.
[  999.930008] usb 4-2.1: Set SEL for device-initiated U2 failed.
[  999.930114] usb-storage 4-2.1:1.0: USB Mass Storage device detected
[  999.930178] scsi22 : usb-storage 4-2.1:1.0
[  999.930804] usb 4-2.1: Set SEL for device-initiated U1 failed.
[  999.931681] usb 4-2.1: Set SEL for device-initiated U2 failed.

and during disconnect kernel is also quiet and doesn't complain anymore about 
the
LPM of already disconnected device:
[ 1582.039612] usb 4-2.1: USB disconnect, device number 20

   I think your patch works correctly and has shutdown the bogus/annoying 
message. ;-)
Thank you.
Martin




Hi Martin,

that 's great! if you notice anything else pls let me know :)

ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] usbcore: check usb device's state before sending a Set SEL control transfer

2013-09-04 Thread Xenia Ragiadakou
Set SEL control urbs cannot be sent to a device in unconfigured state.
This patch adds a check in usb_req_set_sel() to ensure the usb device's
state is USB_STATE_CONFIGURED.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Reported-by: Martin MOKREJS mmokr...@gmail.com
Suggested-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---

Differences from v2:

-push the check on device's state down to usb_req_set_sel()
-check only that the device is in configured state
-update commit title and changelog

 drivers/usb/core/hub.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fe8d95d..cc468f8 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3424,6 +3424,9 @@ static int usb_req_set_sel(struct usb_device *udev, enum 
usb3_link_state state)
unsigned long long u2_pel;
int ret;
 
+   if (udev-state != USB_STATE_CONFIGURED)
+   return 0;
+
/* Convert SEL and PEL stored in ns to us */
u1_sel = DIV_ROUND_UP(udev-u1_params.sel, 1000);
u1_pel = DIV_ROUND_UP(udev-u1_params.pel, 1000);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 13/19] xhci: add variable 'cmd_trb' in handle_cmd_completion()

2013-09-03 Thread Xenia Ragiadakou
This patch adds a new variable 'cmd_trb' to hold the address of the
command TRB, that is associated with the command completion event,
and to replace repetitions of xhci-cmd_ring-dequeue into the code.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index dee663a..778c04b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1506,10 +1506,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
u32 cmd_comp_code;
+   union xhci_trb *cmd_trb;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
+   cmd_trb = xhci-cmd_ring-dequeue;
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci-cmd_ring-deq_seg,
-   xhci-cmd_ring-dequeue);
+   cmd_trb);
/* Is the command ring deq ptr out of sync with the deq seg ptr? */
if (cmd_dequeue_dma == 0) {
xhci-error_bitmask |= 1  4;
@@ -1521,8 +1523,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
return;
}
 
-   trace_xhci_cmd_completion(xhci-cmd_ring-dequeue-generic,
-   (struct xhci_generic_trb *) event);
+   trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
 
cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event-status));
if (cmd_comp_code == COMP_CMD_ABORT || cmd_comp_code == COMP_CMD_STOP) {
@@ -1539,9 +1540,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
}
 
WARN_ON(slot_id != TRB_TO_SLOT_ID(
-   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])));
+   le32_to_cpu(cmd_trb-generic.field[3])));
 
-   switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
+   switch (le32_to_cpu(cmd_trb-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
@@ -1559,15 +1560,15 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
case TRB_TYPE(TRB_STOP_RING):
-   xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
+   xhci_handle_cmd_stop_ep(xhci, cmd_trb, event);
break;
case TRB_TYPE(TRB_SET_DEQ):
-   xhci_handle_cmd_set_deq(xhci, event, xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_set_deq(xhci, event, cmd_trb);
break;
case TRB_TYPE(TRB_CMD_NOOP):
break;
case TRB_TYPE(TRB_RESET_EP):
-   xhci_handle_cmd_reset_ep(xhci, event, xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_reset_ep(xhci, event, cmd_trb);
break;
case TRB_TYPE(TRB_RESET_DEV):
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 11/19] xhci: refactor TRB_CONFIG_EP case into function

2013-09-03 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_CONFIG_EP switch case, in
handle_cmd_completion(), into a fuction named xhci_handle_cmd_config_ep().

There were added two additional variables, 'add_flags' and 'drop_flags',
to reduce line length below 80 chars and improve code readability.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-add reason for new function creation in change log
-add a couple of newlines for clarity

 drivers/usb/host/xhci-ring.c | 114 +++
 1 file changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 8450fa2..ec6bd3e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1393,6 +1393,66 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd 
*xhci, int slot_id)
xhci_free_virt_device(xhci, slot_id);
 }
 
+static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
+   struct xhci_event_cmd *event, u32 cmd_comp_code)
+{
+   struct xhci_virt_device *virt_dev;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   unsigned int ep_index;
+   unsigned int ep_state;
+   u32 add_flags, drop_flags;
+
+   virt_dev = xhci-devs[slot_id];
+   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
+   return;
+   /*
+* Configure endpoint commands can come from the USB core
+* configuration or alt setting changes, or because the HW
+* needed an extra configure endpoint command after a reset
+* endpoint command or streams were being configured.
+* If the command was for a halted endpoint, the xHCI driver
+* is not waiting on the configure endpoint command.
+*/
+   ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev-in_ctx);
+   if (!ctrl_ctx) {
+   xhci_warn(xhci, Could not get input context, bad type.\n);
+   return;
+   }
+
+   add_flags = le32_to_cpu(ctrl_ctx-add_flags);
+   drop_flags = le32_to_cpu(ctrl_ctx-drop_flags);
+   /* Input ctx add_flags are the endpoint index plus one */
+   ep_index = xhci_last_valid_endpoint(add_flags) - 1;
+
+   /* A usb_set_interface() call directly after clearing a halted
+* condition may race on this quirky hardware.  Not worth
+* worrying about, since this is prototype hardware.  Not sure
+* if this will work for streams, but streams support was
+* untested on this prototype.
+*/
+   if (xhci-quirks  XHCI_RESET_EP_QUIRK 
+   ep_index != (unsigned int) -1 
+   add_flags - SLOT_FLAG == drop_flags) {
+   ep_state = virt_dev-eps[ep_index].ep_state;
+   if (!(ep_state  EP_HALTED))
+   goto bandwidth_change;
+   xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+   Completed config ep cmd - 
+   last ep index = %d, state = %d,
+   ep_index, ep_state);
+   /* Clear internal halted state and restart ring(s) */
+   virt_dev-eps[ep_index].ep_state = ~EP_HALTED;
+   ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+   return;
+   }
+bandwidth_change:
+   xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
+   Completed config ep cmd);
+   virt_dev-cmd_status = cmd_comp_code;
+   complete(virt_dev-cmd_completion);
+   return;
+}
+
 static void xhci_handle_cmd_eval_ctx(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event, u32 cmd_comp_code)
 {
@@ -1445,10 +1505,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event-flags));
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
-   struct xhci_input_control_ctx *ctrl_ctx;
-   struct xhci_virt_device *virt_dev;
-   unsigned int ep_index;
-   unsigned int ep_state;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci-cmd_ring-deq_seg,
@@ -1495,54 +1551,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
-   virt_dev = xhci-devs[slot_id];
-   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
-   break;
-   /*
-* Configure endpoint commands can come from the USB core
-* configuration or alt setting changes, or because the HW
-* needed an extra configure endpoint command after a reset

[RFC v4 18/19] xhci: add label 'update_ring' in handle_cmd_completion()

2013-09-03 Thread Xenia Ragiadakou
This patch adds the label 'update_ring' for the common code path:
inc_deq(xhci, xhci-cmd_ring);
return;

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

remove return statement

 drivers/usb/host/xhci-ring.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c7fe489..4af43ab 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1524,10 +1524,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 * been stopped by host. So we should handle it normally.
 * Otherwise, driver should invoke inc_deq() and return.
 */
-   if (handle_stopped_cmd_ring(xhci, cmd_comp_code)) {
-   inc_deq(xhci, xhci-cmd_ring);
-   return;
-   }
+   if (handle_stopped_cmd_ring(xhci, cmd_comp_code))
+   goto update_ring;
}
 
WARN_ON(slot_id != TRB_TO_SLOT_ID(
@@ -1572,6 +1570,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci-error_bitmask |= 1  6;
break;
}
+update_ring:
inc_deq(xhci, xhci-cmd_ring);
 }
 
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 04/19] xhci: refactor TRB_DISABLE_SLOT case into function

2013-09-03 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_DISABLE_SLOT switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_disable_slot().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0abf88c..f9c380e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1380,6 +1380,19 @@ static void xhci_handle_cmd_enable_slot(struct xhci_hcd 
*xhci, int slot_id,
complete(xhci-addr_dev);
 }
 
+static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
+{
+   struct xhci_virt_device *virt_dev;
+
+   virt_dev = xhci-devs[slot_id];
+   if (!virt_dev)
+   return;
+   if (xhci-quirks  XHCI_EP_LIMIT_QUIRK)
+   /* Delete default control endpoint resources */
+   xhci_free_device_endpoint_resources(xhci, virt_dev, true);
+   xhci_free_virt_device(xhci, slot_id);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1431,13 +1444,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
-   if (xhci-devs[slot_id]) {
-   if (xhci-quirks  XHCI_EP_LIMIT_QUIRK)
-   /* Delete default control endpoint resources */
-   xhci_free_device_endpoint_resources(xhci,
-   xhci-devs[slot_id], true);
-   xhci_free_virt_device(xhci, slot_id);
-   }
+   xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
virt_dev = xhci-devs[slot_id];
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 02/19] xhci: rename existing Command Completion Event handlers

2013-09-03 Thread Xenia Ragiadakou
This patch renames the function handlers of a triggered Command Completion
Event that correspond to each command type into 'xhci_handle_cmd_type'.
That is done to give a consistent naming space to all the functions that
handle Command Completion Events and that will permit the code reader to
reference to them more easily.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ddbda35..ffd224c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -755,7 +755,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
  *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the 
chain
  * bit cleared) so that the HW will skip over them.
  */
-static void handle_stopped_endpoint(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
union xhci_trb *trb, struct xhci_event_cmd *event)
 {
unsigned int slot_id;
@@ -1063,9 +1063,8 @@ static void update_ring_for_set_deq_completion(struct 
xhci_hcd *xhci,
  * endpoint doorbell to restart the ring, but only if there aren't more
  * cancellations pending.
  */
-static void handle_set_deq_completion(struct xhci_hcd *xhci,
-   struct xhci_event_cmd *event,
-   union xhci_trb *trb)
+static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
+   struct xhci_event_cmd *event, union xhci_trb *trb)
 {
unsigned int slot_id;
unsigned int ep_index;
@@ -1157,9 +1156,8 @@ static void handle_set_deq_completion(struct xhci_hcd 
*xhci,
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
-static void handle_reset_ep_completion(struct xhci_hcd *xhci,
-   struct xhci_event_cmd *event,
-   union xhci_trb *trb)
+static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci,
+   struct xhci_event_cmd *event, union xhci_trb *trb)
 {
int slot_id;
unsigned int ep_index;
@@ -1497,15 +1495,15 @@ bandwidth_change:
complete(xhci-addr_dev);
break;
case TRB_TYPE(TRB_STOP_RING):
-   handle_stopped_endpoint(xhci, xhci-cmd_ring-dequeue, event);
+   xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
break;
case TRB_TYPE(TRB_SET_DEQ):
-   handle_set_deq_completion(xhci, event, xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_set_deq(xhci, event, xhci-cmd_ring-dequeue);
break;
case TRB_TYPE(TRB_CMD_NOOP):
break;
case TRB_TYPE(TRB_RESET_EP):
-   handle_reset_ep_completion(xhci, event, 
xhci-cmd_ring-dequeue);
+   xhci_handle_cmd_reset_ep(xhci, event, xhci-cmd_ring-dequeue);
break;
case TRB_TYPE(TRB_RESET_DEV):
xhci_dbg(xhci, Completed reset device command.\n);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 10/19] xhci: remove unused 'ep_ring' variable in handle_cmd_completion()

2013-09-03 Thread Xenia Ragiadakou
This patch removes the variable 'ep_ring' that is assigned in
TRB_CONFIG_EP switch case but never used.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f9d377a..8450fa2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1448,7 +1448,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_virt_device *virt_dev;
unsigned int ep_index;
-   struct xhci_ring *ep_ring;
unsigned int ep_state;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
@@ -1525,7 +1524,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
ep_index != (unsigned int) -1 
le32_to_cpu(ctrl_ctx-add_flags) - SLOT_FLAG ==
le32_to_cpu(ctrl_ctx-drop_flags)) {
-   ep_ring = xhci-devs[slot_id]-eps[ep_index].ring;
ep_state = xhci-devs[slot_id]-eps[ep_index].ep_state;
if (!(ep_state  EP_HALTED))
goto bandwidth_change;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 16/19] xhci: add argument 'slot_id' in stop_ep, set_deq and reset_ep cmd handlers

2013-09-03 Thread Xenia Ragiadakou
Since the Slot ID field in the command completion event matches the Slot ID
field in the associated command TRB for the Stop Endpoint, Set Dequeue Pointer
and Reset Endpoint commands, this patch adds in the handlers of their
completion events a 'slot_id' argument and removes the slot id calculation
in each of them.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/xhci-ring.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 485ce5c..9cb0f42 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -755,10 +755,9 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
  *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the 
chain
  * bit cleared) so that the HW will skip over them.
  */
-static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
union xhci_trb *trb, struct xhci_event_cmd *event)
 {
-   unsigned int slot_id;
unsigned int ep_index;
struct xhci_virt_device *virt_dev;
struct xhci_ring *ep_ring;
@@ -770,7 +769,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
struct xhci_dequeue_state deq_state;
 
if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb-generic.field[3] {
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev,
@@ -783,7 +781,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
}
 
memset(deq_state, 0, sizeof(deq_state));
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb-generic.field[3]));
ep = xhci-devs[slot_id]-eps[ep_index];
 
@@ -1061,10 +1058,9 @@ static void update_ring_for_set_deq_completion(struct 
xhci_hcd *xhci,
  * endpoint doorbell to restart the ring, but only if there aren't more
  * cancellations pending.
  */
-static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event, union xhci_trb *trb)
 {
-   unsigned int slot_id;
unsigned int ep_index;
unsigned int stream_id;
struct xhci_ring *ep_ring;
@@ -1072,7 +1068,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
struct xhci_ep_ctx *ep_ctx;
struct xhci_slot_ctx *slot_ctx;
 
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb-generic.field[3]));
stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb-generic.field[2]));
dev = xhci-devs[slot_id];
@@ -1154,13 +1149,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci,
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
-static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
struct xhci_event_cmd *event, union xhci_trb *trb)
 {
-   int slot_id;
unsigned int ep_index;
 
-   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb-generic.field[3]));
/* This command will only fail if the endpoint wasn't halted,
 * but we don't care.
@@ -1559,15 +1552,15 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
case TRB_STOP_RING:
-   xhci_handle_cmd_stop_ep(xhci, cmd_trb, event);
+   xhci_handle_cmd_stop_ep(xhci, slot_id, cmd_trb, event);
break;
case TRB_SET_DEQ:
-   xhci_handle_cmd_set_deq(xhci, event, cmd_trb);
+   xhci_handle_cmd_set_deq(xhci, slot_id, event, cmd_trb);
break;
case TRB_CMD_NOOP:
break;
case TRB_RESET_EP:
-   xhci_handle_cmd_reset_ep(xhci, event, cmd_trb);
+   xhci_handle_cmd_reset_ep(xhci, slot_id, event, cmd_trb);
break;
case TRB_RESET_DEV:
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 15/19] xhci: replace 'xhci-cmd_ring-dequeue' with 'trb' in stop_ep cmd handler

2013-09-03 Thread Xenia Ragiadakou
This patch replaces 'xhci-cmd_ring-dequeue' with 'trb', the address of
the command TRB, since it is available to reduce line length.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 829bd88..485ce5c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -769,10 +769,8 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
 
struct xhci_dequeue_state deq_state;
 
-   if (unlikely(TRB_TO_SUSPEND_PORT(
-
le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3] {
-   slot_id = TRB_TO_SLOT_ID(
-   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3]));
+   if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb-generic.field[3] {
+   slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev,
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 08/19] xhci: refactor TRB_NEC_GET_FW case into function

2013-09-03 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_NEC_GET_FW switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_nec_get_fw().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index fb5ba0d..c598d88 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1414,6 +1414,19 @@ static void xhci_handle_cmd_reset_dev(struct xhci_hcd 
*xhci, int slot_id,
for disabled slot %u\n, slot_id);
 }
 
+static void xhci_handle_cmd_nec_get_fw(struct xhci_hcd *xhci,
+   struct xhci_event_cmd *event)
+{
+   if (!(xhci-quirks  XHCI_NEC_HOST)) {
+   xhci-error_bitmask |= 1  6;
+   return;
+   }
+   xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+   NEC firmware version %2x.%02x,
+   NEC_FW_MAJOR(le32_to_cpu(event-status)),
+   NEC_FW_MINOR(le32_to_cpu(event-status)));
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1547,14 +1560,7 @@ bandwidth_change:
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;
case TRB_TYPE(TRB_NEC_GET_FW):
-   if (!(xhci-quirks  XHCI_NEC_HOST)) {
-   xhci-error_bitmask |= 1  6;
-   break;
-   }
-   xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
-   NEC firmware version %2x.%02x,
-NEC_FW_MAJOR(le32_to_cpu(event-status)),
-NEC_FW_MINOR(le32_to_cpu(event-status)));
+   xhci_handle_cmd_nec_get_fw(xhci, event);
break;
default:
/* Skip over unknown commands on the event ring */
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 07/19] xhci: refactor TRB_RESET_DEV case into function

2013-09-03 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_RESET_DEV switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_reset_dev().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f68a1f0..fb5ba0d 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1400,6 +1400,20 @@ static void xhci_handle_cmd_addr_dev(struct xhci_hcd 
*xhci, int slot_id,
complete(xhci-addr_dev);
 }
 
+static void xhci_handle_cmd_reset_dev(struct xhci_hcd *xhci, int slot_id,
+   struct xhci_event_cmd *event)
+{
+   struct xhci_virt_device *virt_dev;
+
+   xhci_dbg(xhci, Completed reset device command.\n);
+   virt_dev = xhci-devs[slot_id];
+   if (virt_dev)
+   handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
+   else
+   xhci_warn(xhci, Reset device command completion 
+   for disabled slot %u\n, slot_id);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1530,13 +1544,7 @@ bandwidth_change:
xhci_handle_cmd_reset_ep(xhci, event, xhci-cmd_ring-dequeue);
break;
case TRB_TYPE(TRB_RESET_DEV):
-   xhci_dbg(xhci, Completed reset device command.\n);
-   virt_dev = xhci-devs[slot_id];
-   if (virt_dev)
-   handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
-   else
-   xhci_warn(xhci, Reset device command completion 
-   for disabled slot %u\n, slot_id);
+   xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;
case TRB_TYPE(TRB_NEC_GET_FW):
if (!(xhci-quirks  XHCI_NEC_HOST)) {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 14/19] xhci: add variable 'cmd_type' in handle_cmd_completion()

2013-09-03 Thread Xenia Ragiadakou
This patch adds a new variable 'cmd_type' to hold the command type so that
switch cases can be simplified by removing TRB_TYPE() macro improving
code readability.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

update changelog to report the reason for such change

 drivers/usb/host/xhci-ring.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 778c04b..829bd88 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1507,6 +1507,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
dma_addr_t cmd_dequeue_dma;
u32 cmd_comp_code;
union xhci_trb *cmd_trb;
+   u32 cmd_type;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
cmd_trb = xhci-cmd_ring-dequeue;
@@ -1542,38 +1543,38 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
WARN_ON(slot_id != TRB_TO_SLOT_ID(
le32_to_cpu(cmd_trb-generic.field[3])));
 
-   switch (le32_to_cpu(cmd_trb-generic.field[3])
-TRB_TYPE_BITMASK) {
-   case TRB_TYPE(TRB_ENABLE_SLOT):
+   cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb-generic.field[3]));
+   switch (cmd_type) {
+   case TRB_ENABLE_SLOT:
xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_DISABLE_SLOT):
+   case TRB_DISABLE_SLOT:
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
-   case TRB_TYPE(TRB_CONFIG_EP):
+   case TRB_CONFIG_EP:
xhci_handle_cmd_config_ep(xhci, slot_id, event, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_EVAL_CONTEXT):
+   case TRB_EVAL_CONTEXT:
xhci_handle_cmd_eval_ctx(xhci, slot_id, event, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_ADDR_DEV):
+   case TRB_ADDR_DEV:
xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
-   case TRB_TYPE(TRB_STOP_RING):
+   case TRB_STOP_RING:
xhci_handle_cmd_stop_ep(xhci, cmd_trb, event);
break;
-   case TRB_TYPE(TRB_SET_DEQ):
+   case TRB_SET_DEQ:
xhci_handle_cmd_set_deq(xhci, event, cmd_trb);
break;
-   case TRB_TYPE(TRB_CMD_NOOP):
+   case TRB_CMD_NOOP:
break;
-   case TRB_TYPE(TRB_RESET_EP):
+   case TRB_RESET_EP:
xhci_handle_cmd_reset_ep(xhci, event, cmd_trb);
break;
-   case TRB_TYPE(TRB_RESET_DEV):
+   case TRB_RESET_DEV:
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
break;
-   case TRB_TYPE(TRB_NEC_GET_FW):
+   case TRB_NEC_GET_FW:
xhci_handle_cmd_nec_get_fw(xhci, event);
break;
default:
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 09/19] xhci: refactor TRB_EVAL_CONTEXT case into function

2013-09-03 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_EVAL_CONTEXT switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_eval_ctx().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c598d88..f9d377a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1393,6 +1393,18 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd 
*xhci, int slot_id)
xhci_free_virt_device(xhci, slot_id);
 }
 
+static void xhci_handle_cmd_eval_ctx(struct xhci_hcd *xhci, int slot_id,
+   struct xhci_event_cmd *event, u32 cmd_comp_code)
+{
+   struct xhci_virt_device *virt_dev;
+
+   virt_dev = xhci-devs[slot_id];
+   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
+   return;
+   virt_dev-cmd_status = cmd_comp_code;
+   complete(virt_dev-cmd_completion);
+}
+
 static void xhci_handle_cmd_addr_dev(struct xhci_hcd *xhci, int slot_id,
u32 cmd_comp_code)
 {
@@ -1535,11 +1547,8 @@ bandwidth_change:
complete(xhci-devs[slot_id]-cmd_completion);
break;
case TRB_TYPE(TRB_EVAL_CONTEXT):
-   virt_dev = xhci-devs[slot_id];
-   if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
-   break;
-   xhci-devs[slot_id]-cmd_status = 
GET_COMP_CODE(le32_to_cpu(event-status));
-   complete(xhci-devs[slot_id]-cmd_completion);
+   xhci_handle_cmd_eval_ctx(xhci, slot_id, event,
+   GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_ADDR_DEV):
xhci_handle_cmd_addr_dev(xhci, slot_id,
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 12/19] xhci: add variable 'cmd_comp_code' in handle_cmd_completion()

2013-09-03 Thread Xenia Ragiadakou
This patch adds a new variable 'cmd_comp_code' to hold the command completion
status code aiming to reduce code duplication and to improve code readability.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ec6bd3e..dee663a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1505,6 +1505,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event-flags));
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
+   u32 cmd_comp_code;
 
cmd_dma = le64_to_cpu(event-cmd_trb);
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci-cmd_ring-deq_seg,
@@ -1523,16 +1524,15 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
trace_xhci_cmd_completion(xhci-cmd_ring-dequeue-generic,
(struct xhci_generic_trb *) event);
 
-   if ((GET_COMP_CODE(le32_to_cpu(event-status)) == COMP_CMD_ABORT) ||
-   (GET_COMP_CODE(le32_to_cpu(event-status)) == COMP_CMD_STOP)) {
+   cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event-status));
+   if (cmd_comp_code == COMP_CMD_ABORT || cmd_comp_code == COMP_CMD_STOP) {
/* If the return value is 0, we think the trb pointed by
 * command ring dequeue pointer is a good trb. The good
 * trb means we don't want to cancel the trb, but it have
 * been stopped by host. So we should handle it normally.
 * Otherwise, driver should invoke inc_deq() and return.
 */
-   if (handle_stopped_cmd_ring(xhci,
-   GET_COMP_CODE(le32_to_cpu(event-status {
+   if (handle_stopped_cmd_ring(xhci, cmd_comp_code)) {
inc_deq(xhci, xhci-cmd_ring);
return;
}
@@ -1544,23 +1544,19 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
-   xhci_handle_cmd_enable_slot(xhci, slot_id,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
-   xhci_handle_cmd_config_ep(xhci, slot_id, event,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_config_ep(xhci, slot_id, event, cmd_comp_code);
break;
case TRB_TYPE(TRB_EVAL_CONTEXT):
-   xhci_handle_cmd_eval_ctx(xhci, slot_id, event,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_eval_ctx(xhci, slot_id, event, cmd_comp_code);
break;
case TRB_TYPE(TRB_ADDR_DEV):
-   xhci_handle_cmd_addr_dev(xhci, slot_id,
-   GET_COMP_CODE(le32_to_cpu(event-status)));
+   xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
break;
case TRB_TYPE(TRB_STOP_RING):
xhci_handle_cmd_stop_ep(xhci, xhci-cmd_ring-dequeue, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 17/19] xhci: replace 'event' with 'cmd_comp_code' in set_deq and reset_ep handlers

2013-09-03 Thread Xenia Ragiadakou
This patch replaces the 'event' argument of xhci_handle_cmd_set_deq() and
xhci_handle_cmd_reset_ep(), which is used to retrieve the command completion
status code, with the cmd_comp_code directly, since it is available.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9cb0f42..c7fe489 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1059,7 +1059,7 @@ static void update_ring_for_set_deq_completion(struct 
xhci_hcd *xhci,
  * cancellations pending.
  */
 static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
-   struct xhci_event_cmd *event, union xhci_trb *trb)
+   union xhci_trb *trb, u32 cmd_comp_code)
 {
unsigned int ep_index;
unsigned int stream_id;
@@ -1085,11 +1085,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci, int slot_id,
ep_ctx = xhci_get_ep_ctx(xhci, dev-out_ctx, ep_index);
slot_ctx = xhci_get_slot_ctx(xhci, dev-out_ctx);
 
-   if (GET_COMP_CODE(le32_to_cpu(event-status)) != COMP_SUCCESS) {
+   if (cmd_comp_code != COMP_SUCCESS) {
unsigned int ep_state;
unsigned int slot_state;
 
-   switch (GET_COMP_CODE(le32_to_cpu(event-status))) {
+   switch (cmd_comp_code) {
case COMP_TRB_ERR:
xhci_warn(xhci, WARN Set TR Deq Ptr cmd invalid 
because 
of stream ID configuration\n);
@@ -1112,7 +1112,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci, int slot_id,
default:
xhci_warn(xhci, WARN Set TR Deq Ptr cmd with unknown 
completion code of %u.\n,
- GET_COMP_CODE(le32_to_cpu(event-status)));
+ cmd_comp_code);
break;
}
/* OK what do we do now?  The endpoint state is hosed, and we
@@ -1150,7 +1150,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd 
*xhci, int slot_id,
 }
 
 static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
-   struct xhci_event_cmd *event, union xhci_trb *trb)
+   union xhci_trb *trb, u32 cmd_comp_code)
 {
unsigned int ep_index;
 
@@ -1159,8 +1159,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd 
*xhci, int slot_id,
 * but we don't care.
 */
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
-   Ignoring reset ep completion code of %u,
-GET_COMP_CODE(le32_to_cpu(event-status)));
+   Ignoring reset ep completion code of %u, cmd_comp_code);
 
/* HW with the reset endpoint quirk needs to have a configure endpoint
 * command complete before the endpoint can be used.  Queue that here
@@ -1555,12 +1554,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_stop_ep(xhci, slot_id, cmd_trb, event);
break;
case TRB_SET_DEQ:
-   xhci_handle_cmd_set_deq(xhci, slot_id, event, cmd_trb);
+   xhci_handle_cmd_set_deq(xhci, slot_id, cmd_trb, cmd_comp_code);
break;
case TRB_CMD_NOOP:
break;
case TRB_RESET_EP:
-   xhci_handle_cmd_reset_ep(xhci, slot_id, event, cmd_trb);
+   xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code);
break;
case TRB_RESET_DEV:
xhci_handle_cmd_reset_dev(xhci, slot_id, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 01/19] xhci: remove unused argument from xhci_giveback_urb_in_irq()

2013-09-03 Thread Xenia Ragiadakou
This patch removes the adjective argument from xhci_giveback_urb_in_irq(),
since it is not used in the function anymore.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Acked-by: Sarah Sharp sarah.a.sh...@linux.intel.com
---
 drivers/usb/host/xhci-ring.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7b35af1..ddbda35 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -716,7 +716,7 @@ static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd 
*xhci,
 
 /* Must be called with xhci-lock held in interrupt context */
 static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
-   struct xhci_td *cur_td, int status, char *adjective)
+   struct xhci_td *cur_td, int status)
 {
struct usb_hcd *hcd;
struct urb  *urb;
@@ -877,7 +877,7 @@ remove_finished_td:
/* Doesn't matter what we pass for status, since the core will
 * just overwrite it (because the URB has been unlinked).
 */
-   xhci_giveback_urb_in_irq(xhci, cur_td, 0, cancelled);
+   xhci_giveback_urb_in_irq(xhci, cur_td, 0);
 
/* Stop processing the cancelled list if the watchdog timer is
 * running.
@@ -987,7 +987,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
if (!list_empty(cur_td-cancelled_td_list))

list_del_init(cur_td-cancelled_td_list);
xhci_giveback_urb_in_irq(xhci, cur_td,
-   -ESHUTDOWN, killed);
+   -ESHUTDOWN);
}
while (!list_empty(temp_ep-cancelled_td_list)) {
cur_td = list_first_entry(
@@ -996,7 +996,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
cancelled_td_list);
list_del_init(cur_td-cancelled_td_list);
xhci_giveback_urb_in_irq(xhci, cur_td,
-   -ESHUTDOWN, killed);
+   -ESHUTDOWN);
}
}
}
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 03/19] xhci: refactor TRB_ENABLE_SLOT case into function

2013-09-03 Thread Xenia Ragiadakou
The function that handles xHCI command completion is much too long and
there is need to be broken up into individual functions for each command
completion to improve code readablity.
This patch refactors the code in TRB_ENABLE_SLOT switch case in
handle_cmd_completion() into a fuction named xhci_handle_cmd_enable_slot().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

add reason for new function creation in change log

 drivers/usb/host/xhci-ring.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ffd224c..0abf88c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1370,6 +1370,16 @@ static int handle_stopped_cmd_ring(struct xhci_hcd *xhci,
return cur_trb_is_good;
 }
 
+static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
+   u32 cmd_comp_code)
+{
+   if (cmd_comp_code == COMP_SUCCESS)
+   xhci-slot_id = slot_id;
+   else
+   xhci-slot_id = 0;
+   complete(xhci-addr_dev);
+}
+
 static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
 {
@@ -1417,11 +1427,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
-   if (GET_COMP_CODE(le32_to_cpu(event-status)) == COMP_SUCCESS)
-   xhci-slot_id = slot_id;
-   else
-   xhci-slot_id = 0;
-   complete(xhci-addr_dev);
+   xhci_handle_cmd_enable_slot(xhci, slot_id,
+   GET_COMP_CODE(le32_to_cpu(event-status)));
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
if (xhci-devs[slot_id]) {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4 06/19] xhci: use completion event's slot id rather than dig it out of command

2013-09-03 Thread Xenia Ragiadakou
Since the slot id retrieved from the command TRB matches the one in Slot ID
field of the command completion event, which is available, there is no need
to determine it again.
This patch removes the uneccessary reassignment to slot id and adds a WARN_ON
in case the two Slot ID fields differ.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Differences from v3:

-the above change is performed now in a separate patch
-a warning is triggered in case the slot id reported in event trb is
 different from the slot id renoted in command trb

 drivers/usb/host/xhci-ring.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f00d9ef..f68a1f0 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1444,6 +1444,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
}
}
 
+   WARN_ON(slot_id != TRB_TO_SLOT_ID(
+   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])));
+
switch (le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3])
 TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_ENABLE_SLOT):
@@ -1528,8 +1531,6 @@ bandwidth_change:
break;
case TRB_TYPE(TRB_RESET_DEV):
xhci_dbg(xhci, Completed reset device command.\n);
-   slot_id = TRB_TO_SLOT_ID(
-   le32_to_cpu(xhci-cmd_ring-dequeue-generic.field[3]));
virt_dev = xhci-devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] usbcore: set lpm_capable field for LPM capable root hubs

2013-09-01 Thread Xenia Ragiadakou

On 09/01/2013 06:04 AM, Greg KH wrote:

On Sun, Sep 01, 2013 at 02:56:42AM +0200, Martin MOKREJŠ wrote:


Martin MOKREJŠ wrote:

Hi Xenia,
   I tried these 3 patches and ... I will rather leave it up to you to decide
if everything went right. Attached is a diff of dmesg from unpatched and patched
3.10.9 kernel. USB3 devices were connected before cold bootup, sadly in latter 
test
the ordering changed a bit so that added to the length of the diff. Can't say
what those Prolific-related messages mean. Just in case you need more info
I attach lsub -v as well.

One more addition. When I disconnected the external hard drives from the 
external
HUB I got:

[ 1677.615301] usb 4-1.1: USB disconnect, device number 4
[ 1677.619345] usb 4-1.1: Set SEL for device-initiated U1 failed.
[ 1677.619369] usb 4-1.1: Set SEL for device-initiated U2 failed.

I'm seeing these on the 3.10 kernels, and it's really starting to annoy
me...

greg k-h


I think this message is generated because usb_disable_device() calls 
usb_enable_lpm() (through a call to usb_disable_lpm()) that submits a 
USB_REQ_SET_SEL request to the device which fails since the device state 
has been already set (before the call to usb_disable_device()) to the 
NOTATTACHED state. So maybe we should not call usb_disable_lpm() if the 
device is not attached.


ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usbcore: add check on usb device's state before trying to disable lpm

2013-09-01 Thread Xenia Ragiadakou
This patch adds a check to ensure that the device's state is not NOTATTACHED,
ATTACHED, POWERED or RECONNECTING before trying to disable lpm, because if
the device is in one of those states the control transfer to disable
device-initiated LPM will fail (as well as any transfer, since usb_submit_urb()
will fail).

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/core/hub.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fe8d95d..a6c10f0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3716,7 +3716,7 @@ int usb_disable_lpm(struct usb_device *udev)
 {
struct usb_hcd *hcd;
 
-   if (!udev || !udev-parent ||
+   if (!udev || udev-state  USB_STATE_UNAUTHENTICATED || !udev-parent ||
udev-speed != USB_SPEED_SUPER ||
!udev-lpm_capable)
return 0;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] usbcore: add check on usb device's state before trying to disable lpm

2013-09-01 Thread Xenia Ragiadakou
This patch adds a check to ensure that the device's state is not NOTATTACHED,
ATTACHED, POWERED or RECONNECTING before trying to disable lpm, because if
the device is in one of those states the control transfer to disable
device-initiated LPM will fail (as well as any transfer, since usb_submit_urb()
will fail).

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Reported-by: Martin MOKREJS mmokr...@gmail.com
---
 drivers/usb/core/hub.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fe8d95d..a6c10f0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3716,7 +3716,7 @@ int usb_disable_lpm(struct usb_device *udev)
 {
struct usb_hcd *hcd;
 
-   if (!udev || !udev-parent ||
+   if (!udev || udev-state  USB_STATE_UNAUTHENTICATED || !udev-parent ||
udev-speed != USB_SPEED_SUPER ||
!udev-lpm_capable)
return 0;
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] usbcore: compare and release one bos descriptor in usb_reset_and_verify_device()

2013-08-31 Thread Xenia Ragiadakou

On 08/31/2013 07:52 AM, Greg KH wrote:

On Sat, Aug 31, 2013 at 04:52:47AM +0300, Xenia Ragiadakou wrote:

On 08/31/2013 04:25 AM, Greg KH wrote:

On Sat, Aug 31, 2013 at 04:20:09AM +0300, Xenia Ragiadakou wrote:

In usb_reset_and_verify_device(), hub_port_init() allocates a new bos
descriptor to hold the value read by the device. The new bos descriptor
has to be compared with the old one in order to figure out if device 's
firmware has changed in which case the device has to be reenumerated.
In the original code, none of the two descriptors was deallocated leading
to memory leaks.

This patch compares the old bos descriptor with the new one to detect change
in firmware and releases the newly allocated bos descriptor to prevent memory
leak.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Reported-by: Martin MOKREJS mmokr...@gmail.com
Tested-by: Martin MOKREJS mmokr...@gmail.com
Suggested-by: Alan Stern st...@rowland.harvard.edu
---

Differences from v2:

fix incorrect type in assignment ('le16' was assigned to 'unsigned int')

I don't want to revert your previous patch, as it's already in my tree,
so can you just send a single patch that fixes the issue, giving the
proper Reported-by: mark for the person who told you about this
problem.

thanks,.

greg k-h

By the way the other incorrect assignments in core/hub.c reported by the
robot probably is a bug.
Because bU2DevExitLat is __le16 in struct usb_ss_cap_descriptor and it
needs to be converted to
cpu byteorder before assigned to the usb device's lpm parameters.

And since it is reported by robot i suspect it has not been fixed right?

Does sparse complain about it?  If you build the kernel with:
make C=1


Yes, when run with endian check on. It complains about some other stuff.
I will send a fixing patch.


sparse is run on the files before gcc, and it catches these types of
things.  Don't rely on the 0-day buildbot for finding all of the
problems :)

thanks,

greg k-h


I installed sparse and i will use it in the future before submitting 
patches.


thanks,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] usbcore: set lpm_capable field for LPM capable root hubs

2013-08-31 Thread Xenia Ragiadakou
This patch sets the lpm_capable field for root hubs with LPM capabilities.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Reported-by: Martin MOKREJS mmokr...@gmail.com
Suggested-by: Alan Stern st...@rowland.harvard.edu
---
 drivers/usb/core/hcd.c | 1 +
 drivers/usb/core/hub.c | 7 ++-
 drivers/usb/core/usb.h | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 19ad3d2..36598e4 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1038,6 +1038,7 @@ static int register_root_hub(struct usb_hcd *hcd)
dev_name(usb_dev-dev), retval);
return retval;
}
+   usb_dev-lpm_capable = usb_device_supports_lpm(usb_dev);
}
 
retval = usb_new_device (usb_dev);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 46ce3aa..14371f8 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -135,7 +135,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
return usb_get_intfdata(hdev-actconfig-interface[0]);
 }
 
-static int usb_device_supports_lpm(struct usb_device *udev)
+int usb_device_supports_lpm(struct usb_device *udev)
 {
/* USB 2.1 (and greater) devices indicate LPM support through
 * their USB 2.0 Extended Capabilities BOS descriptor.
@@ -156,6 +156,11 @@ static int usb_device_supports_lpm(struct usb_device *udev)
Power management will be impacted.\n);
return 0;
}
+
+   /* udev is root hub */
+   if (!udev-parent)
+   return 1;
+
if (udev-parent-lpm_capable)
return 1;
 
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 8238577..c493836 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -35,6 +35,7 @@ extern int usb_get_device_descriptor(struct usb_device *dev,
unsigned int size);
 extern int usb_get_bos_descriptor(struct usb_device *dev);
 extern void usb_release_bos_descriptor(struct usb_device *dev);
+extern int usb_device_supports_lpm(struct usb_device *udev);
 extern char *usb_cache_string(struct usb_device *udev, int index);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 extern int usb_choose_configuration(struct usb_device *udev);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] usbcore: fix read of usbdevfs_ctrltransfer fields in proc_control()

2013-08-31 Thread Xenia Ragiadakou
Urb fields are stored in struct usbdevfs_ctrltransfer in CPU byteorder
and not in little endian, so there is no need to be converted.
This bug was reported by sparse.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/core/devio.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 737e3c1..f4f2300 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -898,10 +898,8 @@ static int proc_control(struct dev_state *ps, void __user 
*arg)
snoop(dev-dev, control urb: bRequestType=%02x 
bRequest=%02x wValue=%04x 
wIndex=%04x wLength=%04x\n,
-   ctrl.bRequestType, ctrl.bRequest,
-   __le16_to_cpup(ctrl.wValue),
-   __le16_to_cpup(ctrl.wIndex),
-   __le16_to_cpup(ctrl.wLength));
+   ctrl.bRequestType, ctrl.bRequest, ctrl.wValue,
+   ctrl.wIndex, ctrl.wLength);
if (ctrl.bRequestType  0x80) {
if (ctrl.wLength  !access_ok(VERIFY_WRITE, ctrl.data,
   ctrl.wLength)) {
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] usbcore: fix incorrect type in assignment in usb_set_lpm_parameters()

2013-08-31 Thread Xenia Ragiadakou
In the bos usb_ss_cap_descriptor structure, bU2DevExitLat is of type __le16.
This value is used as it is, without being first converted to the CPU
byteorder, for the setup of usb device's usb3_lpm_parameters.
This patch fixes that by converting bU2DevExitLat field to the CPU byteorder
before the assignmenment to [udev/hub]_u2_del variables.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Reported-by: kbuild test robot fengguang...@intel.com
---
 drivers/usb/core/hub.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 14371f8..fe8d95d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -315,9 +315,9 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
return;
 
udev_u1_del = udev-bos-ss_cap-bU1devExitLat;
-   udev_u2_del = udev-bos-ss_cap-bU2DevExitLat;
+   udev_u2_del = le16_to_cpu(udev-bos-ss_cap-bU2DevExitLat);
hub_u1_del = udev-parent-bos-ss_cap-bU1devExitLat;
-   hub_u2_del = udev-parent-bos-ss_cap-bU2DevExitLat;
+   hub_u2_del = le16_to_cpu(udev-parent-bos-ss_cap-bU2DevExitLat);
 
usb_set_lpm_mel(udev, udev-u1_params, udev_u1_del,
hub, udev-parent-u1_params, hub_u1_del);
-- 
1.8.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Include parent hub number in current warning message Parent hub missing LPM exit latency info

2013-08-30 Thread Xenia Ragiadakou

On 08/29/2013 04:31 PM, Martin MOKREJŠ wrote:

Actually, there is some new bug I haven't seen before (this is 3.10.9 kernel).
First of all, I see my TI XHCI controller does not use MSI-X anymore, will have
to check my .config why is it so.


Why are you saying that xhci does not use MSI-X?
Can you send me the entire lspci -vv output for your xhci host controllers?
The lines that interest me are the Capabilities: MSI: and Capabilities: 
MSI-X: so you can send just those.
If there is a '+' near to Enabled then that means that your xhci uses 
MSI or MSI-X accordingly.
If you have one xhci host controller (and not two), from your 
/proc/interrupts output i think that it uses MSI-X because if it didn't 
there could not had been assigned two irqs to it. I say that, because 
the xhci (as i saw from the implementation of xhci_setup_msi()) it would 
have requested one irq if xhci driver had falled back to MSI after a 
failure to setup MSI-X.



Second, it should have IRQ 45 and 46 according to dmesg. But lspci reports
IRQ 16 is used by TI XHCI controller. Funny! I would say this is linux-pci issue
but provided XHCI_HCD is special and manages interrupts somewhat on its own you 
may
look into that first before we ask linux-pci developers.


Maybe here lspci code had to check if MSI is enabled and in that case 
print the irq numbers of the msi descriptors and not the irq field of 
the pci_dev structure.




0b:00.0 USB controller: Texas Instruments TUSB73x0 SuperSpeed USB 3.0 xHCI Host 
Controller (rev 02) (prog-if 30 [XHCI])
 Subsystem: Dell Device 04b3
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast TAbort- TAbort- 
MAbort- SERR- PERR- INTx-
 Latency: 0, Cache Line Size: 64 bytes
 Interrupt: pin A routed to IRQ 16


# cat /proc/interrupts
CPU0
   0: 22   IO-APIC-edge  timer
   1: 16   IO-APIC-edge  i8042
   8: 55   IO-APIC-edge  rtc0
   9:  0   IO-APIC-fasteoi   acpi
  12:5090314   IO-APIC-edge  i8042
  16: 66   IO-APIC-fasteoi   ehci_hcd:usb1
  23:  28835   IO-APIC-fasteoi   ehci_hcd:usb2
  40:  0   PCI-MSI-edge  pciehp
  41:  15985   PCI-MSI-edge  i915
  42: 14   PCI-MSI-edge  mei_me
  43: 227029   PCI-MSI-edge  ahci
  44: 208160   PCI-MSI-edge  enp5s0
  45: 729889   PCI-MSI-edge  xhci_hcd
  46:  0   PCI-MSI-edge  xhci_hcd
  47:940   PCI-MSI-edge  snd_hda_intel
  48:  1   PCI-MSI-edge  iwlwifi
NMI:  21635   Non-maskable interrupts
LOC:7545378   Local timer interrupts
SPU:  0   Spurious interrupts
PMI:  21635   Performance monitoring interrupts
IWI:1583914   IRQ work interrupts
RTR:  0   APIC ICR read retries
RES:  0   Rescheduling interrupts
CAL:  0   Function call interrupts
TLB:  0   TLB shootdowns
TRM:  0   Thermal event interrupts
THR:  0   Threshold APIC interrupts
MCE:  0   Machine check exceptions
MCP:254   Machine check polls
ERR:  0
MIS:  0
# dmesg | head -n 2
[0.00] Linux version 3.10.9-default-pciehp (root@vostro) (gcc version 
4.6.3 (Gentoo 4.6.3 p1.8, pie-0.5.2) ) #8 SMP Tue Aug 27 01:37:03 MEST 2013
[0.00] Command line: root=/dev/sda5 slub_debug=AFPZ 
pciehp.pciehp_debug=1 pciehp_debug=1


Martin


regards,
ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] usbcore: compare and release one bos descriptor in usb_reset_and_verify_device()

2013-08-30 Thread Xenia Ragiadakou

On 08/31/2013 04:25 AM, Greg KH wrote:

On Sat, Aug 31, 2013 at 04:20:09AM +0300, Xenia Ragiadakou wrote:

In usb_reset_and_verify_device(), hub_port_init() allocates a new bos
descriptor to hold the value read by the device. The new bos descriptor
has to be compared with the old one in order to figure out if device 's
firmware has changed in which case the device has to be reenumerated.
In the original code, none of the two descriptors was deallocated leading
to memory leaks.

This patch compares the old bos descriptor with the new one to detect change
in firmware and releases the newly allocated bos descriptor to prevent memory
leak.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
Reported-by: Martin MOKREJS mmokr...@gmail.com
Tested-by: Martin MOKREJS mmokr...@gmail.com
Suggested-by: Alan Stern st...@rowland.harvard.edu
---

Differences from v2:

fix incorrect type in assignment ('le16' was assigned to 'unsigned int')

I don't want to revert your previous patch, as it's already in my tree,
so can you just send a single patch that fixes the issue, giving the
proper Reported-by: mark for the person who told you about this
problem.

thanks,.

greg k-h


By the way the other incorrect assignments in core/hub.c reported by the 
robot probably is a bug.
Because bU2DevExitLat is __le16 in struct usb_ss_cap_descriptor and it 
needs to be converted to

cpu byteorder before assigned to the usb device's lpm parameters.

And since it is reported by robot i suspect it has not been fixed right?

ksenia
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] ehci: remove ehci_vdbg() verbose debugging statements

2013-08-29 Thread Xenia Ragiadakou
This patch removes ehci_vdbg debugging statements from EHCI host controller
driver because they produce too much information, lowering the signal to noise
ratio when debugging, and because they are not used anymore.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/ehci-hub.c   |  6 -
 drivers/usb/host/ehci-q.c |  7 --
 drivers/usb/host/ehci-sched.c | 56 ++-
 drivers/usb/host/ehci.h   |  5 
 4 files changed, 7 insertions(+), 67 deletions(-)

diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 3bf9f48..835fc08 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -211,8 +211,6 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd 
*ehci,
else
t2 |= PORT_WKOC_E | PORT_WKCONN_E;
}
-   ehci_vdbg(ehci, port %d, %08x - %08x\n,
-   port + 1, t1, t2);
ehci_writel(ehci, t2, reg);
}
 
@@ -302,8 +300,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
}
 
if (t1 != t2) {
-   ehci_vdbg (ehci, port %d, %08x - %08x\n,
-   port + 1, t1, t2);
ehci_writel(ehci, t2, reg);
changed = 1;
}
@@ -483,7 +479,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
if (test_bit(i, resume_needed)) {
temp = ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME);
ehci_writel(ehci, temp, ehci-regs-port_status [i]);
-   ehci_vdbg (ehci, resumed port %d\n, i + 1);
}
}
 
@@ -1204,7 +1199,6 @@ static int ehci_hub_control (
wIndex + 1);
temp |= PORT_OWNER;
} else {
-   ehci_vdbg (ehci, port %d reset\n, wIndex + 1);
temp |= PORT_RESET;
temp = ~PORT_PE;
 
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 687..cf9f2fb 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -240,13 +240,6 @@ static int qtd_copy_status (
} else {/* unknown */
status = -EPROTO;
}
-
-   ehci_vdbg (ehci,
-   dev%d ep%d%s qtd token %08x -- status %d\n,
-   usb_pipedevice (urb-pipe),
-   usb_pipeendpoint (urb-pipe),
-   usb_pipein (urb-pipe) ? in : out,
-   token, status);
}
 
return status;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 6631089..833c35c 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -327,17 +327,8 @@ static int tt_available (
 
periodic_tt_usecs (ehci, dev, frame, tt_usecs);
 
-   ehci_vdbg(ehci, tt frame %d check %d usecs start uframe %d in
-schedule %d/%d/%d/%d/%d/%d/%d/%d\n,
-   frame, usecs, uframe,
-   tt_usecs[0], tt_usecs[1], tt_usecs[2], tt_usecs[3],
-   tt_usecs[4], tt_usecs[5], tt_usecs[6], tt_usecs[7]);
-
-   if (max_tt_usecs[uframe] = tt_usecs[uframe]) {
-   ehci_vdbg(ehci, frame %d uframe %d fully scheduled\n,
-   frame, uframe);
+   if (max_tt_usecs[uframe] = tt_usecs[uframe])
return 0;
-   }
 
/* special case for isoc transfers larger than 125us:
 * the first and each subsequent fully used uframe
@@ -348,13 +339,8 @@ static int tt_available (
int ufs = (usecs / 125);
int i;
for (i = uframe; i  (uframe + ufs)  i  8; i++)
-   if (0  tt_usecs[i]) {
-   ehci_vdbg(ehci,
-   multi-uframe xfer can't fit 
-   in frame %d uframe %d\n,
-   frame, i);
+   if (0  tt_usecs[i])
return 0;
-   }
}
 
tt_usecs[uframe] += usecs;
@@ -362,12 +348,8 @@ static int tt_available (
carryover_tt_bandwidth(tt_usecs);
 
/* fail if the carryover pushed bw past the last uframe's limit 
*/
-   if (max_tt_usecs[7]  tt_usecs[7]) {
-   ehci_vdbg(ehci,
-   tt unavailable usecs %d frame %d uframe %d\n,
-   usecs, frame

[PATCH 4/4] ehci: enable debugging code when CONFIG_DYNAMIC_DEBUG is set

2013-08-29 Thread Xenia Ragiadakou
The debugging code for ehci is enabled to run if the DEBUG flag is defined.
This patch enables the debugging code also when the kernel is configured
with dynamic debugging on.

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---
 drivers/usb/host/ehci-dbg.c   | 8 
 drivers/usb/host/ehci-fsl.c   | 2 +-
 drivers/usb/host/ehci-hcd.c   | 6 +++---
 drivers/usb/host/ehci-q.c | 4 ++--
 drivers/usb/host/ehci-sched.c | 2 +-
 drivers/usb/host/ehci.h   | 8 
 6 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index c2f4489..aa5b603 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -18,7 +18,7 @@
 
 /* this file is part of ehci-hcd.c */
 
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
 
 /* check the values in the HCSPARAMS register
  * (host controller _Structural_ parameters)
@@ -62,7 +62,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, 
char *label) {}
 
 #endif
 
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
 
 /* check the values in the HCCPARAMS register
  * (host controller _Capability_ parameters)
@@ -101,7 +101,7 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, 
char *label) {}
 
 #endif
 
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
 
 static void __maybe_unused
 dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
@@ -301,7 +301,7 @@ static inline int __maybe_unused
 dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
 { return 0; }
 
-#endif /* DEBUG */
+#endif /* DEBUG || CONFIG_DYNAMIC_DEBUG */
 
 /* functions have the wrong filename when they're output... */
 #define dbg_status(ehci, label, status) { \
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index e44f442..947b009 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -418,7 +418,7 @@ static int ehci_fsl_mpc512x_drv_suspend(struct device *dev)
struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev);
u32 tmp;
 
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
u32 mode = ehci_readl(ehci, hcd-regs + FSL_SOC_USB_USBMODE);
mode = USBMODE_CM_MASK;
tmp = ehci_readl(ehci, hcd-regs + 0x140);  /* usbcmd */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 09a01fb..5d6022f 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1292,7 +1292,7 @@ static int __init ehci_hcd_init(void)
 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
 
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
ehci_debug_root = debugfs_create_dir(ehci, usb_debug_root);
if (!ehci_debug_root) {
retval = -ENOENT;
@@ -1341,7 +1341,7 @@ clean2:
platform_driver_unregister(PLATFORM_DRIVER);
 clean0:
 #endif
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
debugfs_remove(ehci_debug_root);
ehci_debug_root = NULL;
 err_debug:
@@ -1365,7 +1365,7 @@ static void __exit ehci_hcd_cleanup(void)
 #ifdef PS3_SYSTEM_BUS_DRIVER
ps3_ehci_driver_unregister(PS3_SYSTEM_BUS_DRIVER);
 #endif
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
debugfs_remove(ehci_debug_root);
 #endif
clear_bit(USB_EHCI_LOADED, usb_hcds_loaded);
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index cf9f2fb..e321804 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -168,13 +168,13 @@ static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, 
struct ehci_qh *qh,
 * Note: this routine is never called for Isochronous transfers.
 */
if (urb-dev-tt  !usb_pipeint(urb-pipe)  !qh-clearing_tt) {
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
struct usb_device *tt = urb-dev-tt-hub;
dev_dbg(tt-dev,
clear tt buffer port %d, a%d ep%d t%08x\n,
urb-dev-ttport, urb-dev-devnum,
usb_pipeendpoint(urb-pipe), token);
-#endif /* DEBUG */
+#endif /* DEBUG || CONFIG_DYNAMIC_DEBUG */
if (!ehci_is_TDI(ehci)
|| urb-dev-tt-hub !=
   ehci_to_hcd(ehci)-self.root_hub) {
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 833c35c..85dd24e 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -169,7 +169,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, 
unsigned uframe)
break;
}
}
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
if (usecs  ehci-uframe_periodic_max)
ehci_err (ehci, uframe %d sched overrun: %d

  1   2   >