Commit 926008c938 "USB: xhci: simplify logic
of skipping missed isoc TDs" added a small endian bug. This patch
fixes skip_isoc_td() to read the DMA pointer correctly.
Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The Panther Point chipset has an xHCI host controller that has a limit to
the number of active endpoints it can handle. Ideally, it would signal
that it can't handle anymore endpoints by returning a Resource Error for
the Configure Endpoint command, but they don't. Instead it needs software
to keep track of the number of active endpoints, across configure endpoint
commands, reset device commands, disable slot commands, and address device
commands.
Add a new endpoint context counter, xhci_hcd->num_active_eps, and use it
to track the number of endpoints the xHC has active. This gets a little
tricky, because commands to change the number of active endpoints can
fail. This patch adds a new xHCI quirk for these Intel hosts, and the new
code should not have any effect on other xHCI host controllers.
Fail a new device allocation if we don't have room for the new default
control endpoint. Use the endpoint ring pointers to determine what
endpoints were active before a Reset Device command or a Disable Slot
command, and drop those once the command completes.
Fail a configure endpoint command if it would add too many new endpoints.
We have to be a bit over zealous here, and only count the number of new
endpoints to be added, without subtracting the number of dropped
endpoints. That's because a second configure endpoint command for a
different device could sneak in before we know if the first command is
completed. If the first command dropped resources, the host controller
fails the command for some reason, and we're nearing the limit of
endpoints, we could end up oversubscribing the host.
To fix this race condition, when evaluating whether a configure endpoint
command will fix in our bandwidth budget, only add the new endpoints to
xhci->num_active_eps, and don't subtract the dropped endpoints. Ignore
changed endpoints (ones that are dropped and then re-added), as that
shouldn't effect the host's endpoint resources. When the configure
endpoint command completes, subtract off the dropped endpoints.
This may mean some configuration changes may temporarily fail, but it's
always better to under-subscribe than over-subscribe resources.
(Originally my plan had been to push the resource allocation down into the
ring allocation functions. However, that would cause us to allocate
unnecessary resources when endpoints were changed, because the xHCI driver
allocates a new ring for the changed endpoint, and only deletes the old
ring once the Configure Endpoint command succeeds. A further complication
would have been dealing with the per-device endpoint ring cache.)
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The xHCI host controller in the Panther Point chipset sometimes produces
spurious events on the event ring. If it receives a short packet, it
first puts a Transfer Event with a short transfer completion code on the
event ring. Then it puts a Transfer Event with a successful completion
code on the ring for the same TD. The xHCI driver correctly processes the
short transfer completion code, gives the URB back to the driver, and then
prints a warning in dmesg about the spurious event. These warning
messages really fill up dmesg when an HD webcam is plugged into xHCI.
This spurious successful event behavior isn't technically disallowed by
the xHCI specification, so make the xHCI driver just ignore the spurious
completion event.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Unsurprisingly, URBs get submitted and completed a lot in the xHCI
driver. If we have to print 10 lines of debug for every URB submitted
or completed, then that can cause the whole system to stay in the
interrupt handler too long, and can cause Missed Service completion
codes for isochronous transfers.
Cut down the debugging in the URB submission and completion paths:
- Don't squawk about successful transfers, only unsuccessful ones.
- Only print the number of bytes transferred if this was a short
transfer.
- Don't print the endpoint index for successful transfers (will add
more debug to failed transfers to show endpoint index there later).
- Stop printing MMIO writes. This debugging shows up when the endpoint
doorbell is rung a to start a transfer (basically for every URB).
- Don't print out the ring enqueue and dequeue pointers
- Stop printing when we're pointing to a link TRB.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Stop printing out the event ring dequeue pointer and status register in
the operational register set. The host will report an OK status 99% of
the time the interrupt handler is called, and usually when it's really
hosed, a host controller won't even call the interrupt handler. So the
line is really useless.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Remove unnecessary debugging from the xHCI driver. We don't need to
know what function we're calling or returning from. Now I know how to
use markup-oops.pl to de-mystify stack dumps of crashes.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
When an URB is cancelled, the xHCI driver issues a Stop Endpoint command
so that it can manipulate the ring and remove the transfer. The xHC
hardware then places a transfer event with the completion code "Stopped"
or "Stopped Invalid" to let the driver know what TD it was in the middle
of processing. This TD and TRB is stored in ep->stopped_td and
ep->stopped_trb. These pointers are also used in handling stalled
endpoints.
By design, the Stop Endpoint command can race with URB completion. By
the time the Stop Endpoint command is handled, the URBs to be cancelled
may have been given back to the driver. Unfortunately, the stopped_td
and stopped_trb pointers were not getting cleared in this case.
The USB core unconditionally tries to reset the toggle bits on any
endpoints when a new alternate interface setting is installed. When the
xHCI driver saw that ep->stopped_td was still set from the Stop Endpoint
command, xhci_reset_endpoint assumed the endpoint was actually stalled,
and attempted to clean up the endpoint rings. This would manifest
itself in a failed Reset Endpoint command and failed Set TR dequeue
Pointer command after a successful Configure Endpoint command. It may
have also been causing driver oops when the stopped_td was accessed.
This patch should be backported to stable kernels since 2.6.31. Before
2.6.33, stopped_td was found in the xhci_endpoint_ring, not the
xhci_virt_ep.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
When the xHCI driver attempts to cancel a transfer, it issues a Stop
Endpoint command and waits for the host controller to indicate which TRB
it was in the middle of processing. The host will put an event TRB with
completion code COMP_STOP on the event ring if it stops on a control
transfer TRB (or other types of transfer TRBs). The ring handling code
is supposed to set ep->stopped_trb to the TRB that the host stopped on
when this happens.
Unfortunately, there is a long-standing bug in the control transfer
completion code. It doesn't actually check to see if COMP_STOP is set
before attempting to process the transfer based on which part of the
control TD completed. So when we get an event on the data phase of the
control TRB with COMP_STOP set, it thinks it's a normal completion of
the transfer and doesn't set ep->stopped_td or ep->stopped_trb.
When the ring handling code goes on to process the completion of the Stop
Endpoint command, it sees that ep->stopped_trb is not a part of the TD
it's trying to cancel. It thinks the hardware has its enqueue pointer
somewhere further up in the ring, and thinks it's safe to turn the control
TRBs into no-op TRBs. Since the hardware was in the middle of the control
TRBs to be cancelled, the proper software behavior is to issue a Set TR
dequeue pointer command.
It turns out that the NEC host controllers can handle active TRBs being
set to no-op TRBs after a stop endpoint command, but other host
controllers have issues with this out-of-spec software behavior. Fix this
behavior.
This patch should be backported to kernels as far back as 2.6.31, but it
may be a bit challenging, since process_ctrl_td() was introduced in some
refactoring done in 2.6.36, and some endian-safe patches added in 2.6.40
that touch the same lines.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: stable@kernel.org
Currently an isoc URB is divided into multiple TDs, and every TD will
trigger an interrupt when it's processed. However, software can schedule
multiple TDs at a time, and it only needs an interrupt every URB.
xHCI 1.0 introduces the Block Event Interrupt(BEI) flag which allows Normal
and Isoch Transfer TRBs to place an Event TRB on an Event Ring but not
assert an intrrupt to the host, and the interrupt rate is significantly
reduced and the system performance is improved.
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Setup Stage Transfer Type field is added to indicate the presence and the
direction of the Data Stage TD, and determines the direction of the Status
Stage TD so the wLength length field should be ignored by the xHC.
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The xHCI 1.0 specification defines a new isochronous TRB field, called
transfer burst last packet count (TBLPC). This field defines the number
of packets in the last "burst" of packets in a TD. Only SuperSpeed
endpoints can handle more than one burst, so this is set to the number for
packets in a TD for all non-SuperSpeed devices (minus one, since the field
is zero based).
This patch should have no effect on host controllers that don't advertise
the xHCI 1.0 (0x100) version number in their hci_version field.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The xHCI 1.0 specification adds a new field to the fourth dword in an
isochronous TRB: the transfer burst count (TBC). This field is only
non-zero for SuperSpeed devices. Each SS endpoint sets the bMaxBurst
field in the SuperSpeed endpoint companion descriptor, which indicates how
many max-packet-sized "bursts" it can handle in one service interval. The
device driver may choose to burst less max packet sized chunks each
service interval (which is defined by one TD). The xHCI driver indicates
to the host controller how many bursts it needs to schedule through the
transfer burst count field.
This patch will only effect xHCI hosts that advertise 1.0 support (0x100)
in the HCI version field of their capabilities register.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The xHCI 1.0 specification changes the format of the TD size field in
Normal and Isochronous TRBs. The field in control TRBs is still set to
reserved zero. Instead of representing the number of bytes left to
transfer in the TD (including the current TRB's buffer), it now represents
the number of packets left to transfer (*not* including this TRB).
See section 4.11.2.4 of the xHCI 1.0 specification for details. The math
is basically copied straight from there.
Create a new function, xhci_v1_0_td_remainder(), that should be called for
all xHCI 1.0 host controllers. The field location and maximum value is
still the same, so reuse the old function, xhci_td_remainder(), to handle
the bit shifting.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
It doesn't make sense to set the interrupt on short packet (TRB_ISP) flag
for TRBs queued to endpoints that only receive packets from the host
controller (i.e. OUT endpoints). Packets can only be short when they are
sent from a USB device. Plus, the xHCI 1.0 specification forbids setting
the flag for anything but IN endpoints.
While we're at it, remove some of my snide remarks about the inefficiency
of event data TRBs.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Make the caller loop while there are events to handle, instead.
Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
On weakly-ordered systems, the reading of an event's content must occur
after reading the event's validity.
Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
This patch changes the struct members defining access to xHCI device-visible
memory to use __le32/__le64 where appropriate, and then adds swaps where
required. Checked with sparse that all accesses are correct.
MMIO accesses use readl/writel so already are performed LE, but prototypes
now reflect this with __le*.
There were a couple of (debug) instances of DMA pointers being truncated to
32bits which have been fixed too.
Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
This patch disable the optional PM feature inside the Hudson3 platform under
the following conditions:
1. If an isochronous device is connected to xHCI port and is active;
2. Optional PM feature that powers down the internal Bus PLL when the link is
in low power state is enabled.
The PM feature needs to be disabled to eliminate PLL startup delays when the
link comes out of low power state. The performance of DMA data transfer could
be impacted if system delay were encountered and in addition to the PLL start
up delays. Disabling the PM would leave room for unpredictable system delays
in order to guarantee uninterrupted data transfer to isochronous audio or
video stream devices that require time sensitive information. If data in an
audio/video stream was interrupted then erratic audio or video performance
may be encountered.
AMD PLL quirk is already implemented in OHCI/EHCI driver. After moving the
quirk code to pci-quirks.c and export them, xHCI driver can call it directly
without having the quirk implementation in itself.
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
When we get a port status change event, we need to figure out what type of
port it came from: a USB 3.0 port, or a USB 2.0/1.1 port. We can't know
which usb_hcd to use until that point, so hcd will be NULL for part of the
function. Unfortunately, if any of the sanity checks fail, we'll jump to
the cleanup label before hcd is set to a valid pointer, and then we'll
attempt to tell the USB core to kick the hcd, which is NULL.
Skip kicking the roothub if the sanity checks fail.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The logic of the handling Missed Service Error Events was pretty
confusing as we were checking the same condition several times.
In addition, it caused compiler warning since the compiler could
not figure out that event_trb is actually unused in case we are
skipping current TD.
Fix that by rearranging "skip" condition checks, and factor out
skip_isoc_td() so that it is called explicitly.
Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Remove 'inline' markings from file-local functions and let compiler
do its job and inline what makes sense for given architecture.
Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
There were some places that compared port_speed == -1 where port_speed
is a u8. This doesn't work unless we cast the -1 to u8. Some places
did it correctly.
Instead of using -1 directly, I've created a DUPLICATE_ENTRY define
which does the cast and is more descriptive as well.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (172 commits)
USB: Add support for SuperSpeed isoc endpoints
xhci: Clean up cycle bit math used during stalls.
xhci: Fix cycle bit calculation during stall handling.
xhci: Update internal dequeue pointers after stalls.
USB: Disable auto-suspend for USB 3.0 hubs.
USB: Remove bogus USB_PORT_STAT_SUPER_SPEED symbol.
xhci: Return canceled URBs immediately when host is halted.
xhci: Fixes for suspend/resume of shared HCDs.
xhci: Fix re-init on power loss after resume.
xhci: Make roothub functions deal with device removal.
xhci: Limit roothub ports to 15 USB3 & 31 USB2 ports.
xhci: Return a USB 3.0 hub descriptor for USB3 roothub.
xhci: Register second xHCI roothub.
xhci: Change xhci_find_slot_id_by_port() API.
xhci: Refactor bus suspend state into a struct.
xhci: Index with a port array instead of PORTSC addresses.
USB: Set usb_hcd->state and flags for shared roothubs.
usb: Make core allocate resources per PCI-device.
usb: Store bus type in usb_hcd, not in driver flags.
usb: Change usb_hcd->bandwidth_mutex to a pointer.
...
Use XOR to invert the cycle bit, instead of a more complicated
calculation. Eliminate a check for the link TRB type in find_trb_seg().
We know that there will always be a link TRB at the end of a segment, so
xhci_segment->trbs[TRBS_PER_SEGMENT - 1] will always have a link TRB type.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Takashi Iwai <tiwai@suse.de>
When an endpoint stalls, we need to update the xHCI host's internal
dequeue pointer to move it past the stalled transfer. This includes
updating the cycle bit (TRB ownership bit) if we have moved the dequeue
pointer past a link TRB with the toggle cycle bit set.
When we're trying to find the new dequeue segment, find_trb_seg() is
supposed to keep track of whether we've passed any link TRBs with the
toggle cycle bit set. However, this while loop's body
while (cur_seg->trbs > trb ||
&cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) {
Will never get executed if the ring only contains one segment.
find_trb_seg() will return immediately, without updating the new cycle
bit. Since find_trb_seg() has no idea where in the segment the TD that
stalled was, make the caller, xhci_find_new_dequeue_state(), check for
this special case and update the cycle bit accordingly.
This patch should be queued to kernels all the way back to 2.6.31.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Takashi Iwai <tiwai@suse.de>
Cc: stable@kernel.org
When an endpoint stalls, the xHCI driver must move the endpoint ring's
dequeue pointer past the stalled transfer. To do that, the driver issues
a Set TR Dequeue Pointer command, which will complete some time later.
Takashi was having issues with USB 1.1 audio devices that stalled, and his
analysis of the code was that the old code would not update the xHCI
driver's ring dequeue pointer after the command completes. However, the
dequeue pointer is set in xhci_find_new_dequeue_state(), just before the
set command is issued to the hardware.
Setting the dequeue pointer before the Set TR Dequeue Pointer command
completes is a dangerous thing to do, since the xHCI hardware can fail the
command. Instead, store the new dequeue pointer in the xhci_virt_ep
structure, and update the ring's dequeue pointer when the Set TR dequeue
pointer command completes.
While we're at it, make sure we can't queue another Set TR Dequeue Command
while the first one is still being processed. This just won't work with
the internal xHCI state code. I'm still not sure if this is the right
thing to do, since we might have a case where a driver queues multiple
URBs to a control ring, one of the URBs Stalls, and then the driver tries
to cancel the second URB. There may be a race condition there where the
xHCI driver might try to issue multiple Set TR Dequeue Pointer commands,
but I would have to think very hard about how the Stop Endpoint and
cancellation code works. Keep the fix simple until when/if we run into
that case.
This patch should be queued to kernels all the way back to 2.6.31.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Takashi Iwai <tiwai@suse.de>
Cc: stable@kernel.org
Make sure the HCD_FLAG_HW_ACCESSIBLE flag is mirrored by both roothubs,
since it refers to whether the shared hardware is accessible. Make sure
each bus is marked as suspended by setting usb_hcd->state to
HC_STATE_SUSPENDED when the PCI host controller is resumed.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
This patch changes the xHCI driver to allocate two roothubs. This touches
the driver initialization and shutdown paths, roothub emulation code, and
port status change event handlers. This is a rather large patch, but it
can't be broken up, or it would break git-bisect.
Make the xHCI driver register its own PCI probe function. This will call
the USB core to create the USB 2.0 roothub, and then create the USB 3.0
roothub. This gets the code for registering a shared roothub out of the
USB core, and allows other HCDs later to decide if and how many shared
roothubs they want to allocate.
Make sure the xHCI's reset method marks the xHCI host controller's primary
roothub as the USB 2.0 roothub. This ensures that the high speed bus will
be processed first when the PCI device is resumed, and any USB 3.0 devices
that have migrated over to high speed will migrate back after being reset.
This ensures that USB persist works with these odd devices.
The reset method will also mark the xHCI USB2 roothub as having an
integrated TT. Like EHCI host controllers with a "rate matching hub" the
xHCI USB 2.0 roothub doesn't have an OHCI or UHCI companion controller.
It doesn't really have a TT, but we'll lie and say it has an integrated
TT. We need to do this because the USB core will reject LS/FS devices
under a HS hub without a TT.
Other details:
-------------
The roothub emulation code is changed to return the correct number of
ports for the two roothubs. For the USB 3.0 roothub, it only reports the
USB 3.0 ports. For the USB 2.0 roothub, it reports all the LS/FS/HS
ports. The code to disable a port now checks the speed of the roothub,
and refuses to disable SuperSpeed ports under the USB 3.0 roothub.
The code for initializing a new device context must be changed to set the
proper roothub port number. Since we've split the xHCI host into two
roothubs, we can't just use the port number in the ancestor hub. Instead,
we loop through the array of hardware port status register speeds and find
the Nth port with a similar speed.
The port status change event handler is updated to figure out whether the
port that reported the change is a USB 3.0 port, or a non-SuperSpeed port.
Once it figures out the port speed, it kicks the proper roothub.
The function to find a slot ID based on the port index is updated to take
into account that the two roothubs will have over-lapping port indexes.
It checks that the virtual device with a matching port index is the same
speed as the passed in roothub.
There's also changes to the driver initialization and shutdown paths:
1. Make sure that the xhci_hcd pointer is shared across the two
usb_hcd structures. The xhci_hcd pointer is allocated and the
registers are mapped in when xhci_pci_setup() is called with the
primary HCD. When xhci_pci_setup() is called with the non-primary
HCD, the xhci_hcd pointer is stored.
2. Make sure to set the sg_tablesize for both usb_hcd structures. Set
the PCI DMA mask for the non-primary HCD to allow for 64-bit or 32-bit
DMA. (The PCI DMA mask is set from the primary HCD further down in
the xhci_pci_setup() function.)
3. Ensure that the host controller doesn't start kicking khubd in
response to port status changes before both usb_hcd structures are
registered. xhci_run() only starts the xHC running once it has been
called with the non-primary roothub. Similarly, the xhci_stop()
function only halts the host controller when it is called with the
non-primary HCD. Then on the second call, it resets and cleans up the
MSI-X irqs.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
xhci_find_slot_id_by_port() tries to map the port index to the slot ID for
the USB device. In the future, there will be two xHCI roothubs, and their
port indices will overlap. Therefore, xhci_find_slot_id_by_port() will
need to use information in the roothub's usb_hcd structure to map the port
index and roothub speed to the right slot ID.
Add a new parameter to xhci_find_slot_id_by_port(), in order to pass in
the roothub's usb_hcd structure.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
There are several variables in the xhci_hcd structure that are related to
bus suspend and resume state. There are a couple different port status
arrays that are accessed by port index. Move those variables into a
separate structure, xhci_bus_state. Stash that structure in xhci_hcd.
When we have two roothhubs that can be suspended and resumed separately,
we can have two xhci_bus_states, and index into the port arrays in each
structure with the fake roothub port index (not the real hardware port
index).
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
In the upcoming patches, the roothub emulation code will need to return
port status and port change buffers based on whether they are called with
the xHCI USB 2.0 or USB 3.0 roothub. To facilitate that, make the roothub
code index into an array of port addresses with wIndex, rather than
calculating the address using the offset and the address of the PORTSC
registers. Later we can set the port array to be the array of USB 3.0
port addresses, or the USB 2.0 port addresses, depending on the roothub
passed in.
Create a temporary (statically sized) port array and fill it in with both
USB 3.0 and USB 2.0 port addresses. This is inefficient to do for every
roothub call, but this is needed for git bisect compatibility. The
temporary port array will be deleted in a subsequent patch.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The hcd->flags are in a sorry state. Some of them are clearly specific to
the particular roothub (HCD_POLL_RH, HCD_POLL_PENDING, and
HCD_WAKEUP_PENDING), but some flags are related to PCI device state
(HCD_HW_ACCESSIBLE and HCD_SAW_IRQ). This is an issue when one PCI device
can have two roothubs that share the same IRQ line and hardware.
Make sure to set HCD_FLAG_SAW_IRQ for both roothubs when an interrupt is
serviced, or an URB is unlinked without an interrupt. (We can't tell if
the host actually serviced an interrupt for a particular bus, but we can
tell it serviced some interrupt.)
HCD_HW_ACCESSIBLE is set once by usb_add_hcd(), which is set for both
roothubs as they are added, so it doesn't need to be modified.
HCD_POLL_RH and HCD_POLL_PENDING are only checked by the USB core, and
they are never set by the xHCI driver, since the roothub never needs to be
polled.
The usb_hcd's state field is a similar mess. Sometimes the state applies
to the underlying hardware: HC_STATE_HALT, HC_STATE_RUNNING, and
HC_STATE_QUIESCING. But sometimes the state refers to the roothub state:
HC_STATE_RESUMING and HC_STATE_SUSPENDED.
Alan Stern recently made the USB core not rely on the hcd->state variable.
Internally, the xHCI driver still checks for HC_STATE_SUSPENDED, so leave
that code in. Remove all references to HC_STATE_HALT, since the xHCI
driver only sets and doesn't test those variables. We still have to set
HC_STATE_RUNNING, since Alan's patch has a bug that means the roothub
won't get registered if we don't set that.
Alan's patch made the USB core check a different variable when trying to
determine whether to suspend a roothub. The xHCI host has a split
roothub, where two buses are registered for one PCI device. Each bus in
the xHCI split roothub can be suspended separately, but both buses must be
suspended before the PCI device can be suspended. Therefore, make sure
that the USB core checks HCD_RH_RUNNING() for both roothubs before
suspending the PCI host.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Make sure to call into the USB core's link, unlink, and giveback URB
functions with the usb_hcd pointer found by using urb->dev->bus. This
will avoid confusion later, when the xHCI driver will deal with URBs from
two separate buses (the USB 3.0 roothub and the faked USB 2.0 roothub).
Assume xhci_urb_dequeue() will be called with the proper usb_hcd.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The xHCI driver doesn't ever test hcd->state for HC_STATE_HALT. The USB
core recently stopped using it internally, so there's no point in setting
it in the driver. We still need to set HC_STATE_RUNNING in order to make
it past the USB core's hcd->state check in register_roothub().
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The xhci_bus_suspend() and xhci_bus_resume() functions are a bit hard to
read, because they have an ambiguously named variable "port". Rename it
to "port_index". Introduce a new temporary variable, "max_ports" that
holds the maximum number of roothub ports the host controller supports.
This will reduce the number of register reads, and make it easy to change
the maximum number of ports when there are two roothubs.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The test of placing a number of command no-ops on the command ring and
counting the number of no-op events that were generated was only used
during the initial xHCI driver bring up. This test is no longer used, so
delete it.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The expression
while (running_total < sg_dma_len(sg))
does not take into account that the remaining data length can be less
than sg_dma_len(sg). In that case, running_total can end up being
greater than the total data length, so an extra TRB is counted.
Changing the expression to
while (running_total < sg_dma_len(sg) && running_total < temp)
fixes that.
This patch should be queued for stable kernels back to 2.6.31.
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@kernel.org
Calculations like
running_total = TRB_MAX_BUFF_SIZE -
(sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1));
if (running_total != 0)
num_trbs++;
are incorrect, because running_total can never be zero, so the if()
expression will never be true. I think the intention was that
running_total be in the range of 0 to TRB_MAX_BUFF_SIZE-1, not 1
to TRB_MAX_BUFF_SIZE. So adding a
running_total &= TRB_MAX_BUFF_SIZE - 1;
fixes the problem.
This patch should be queued for stable kernels back to 2.6.31.
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@kernel.org
This makes it easier to spot some problems, which will be fixed by the
next patch in the series. Also change dev_dbg to dev_err in
check_trb_math(), so any math errors will be visible even when running
with debug disabled.
Note: This patch changes the expressions containing
"((1 << TRB_MAX_BUFF_SHIFT) - 1)" to use the equivalent
"(TRB_MAX_BUFF_SIZE - 1)". No change in behavior is intended for
those expressions.
This patch should be queued for stable kernels back to 2.6.31.
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@kernel.org
Change the BUGs in xhci_find_new_dequeue_state() to WARN_ONs, to avoid
bringing down the box if one of them is hit
This patch should be queued for stable kernels back to 2.6.31.
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@kernel.org
The unused space in the doorbell is now marked as RsvdZ, not RsvdP, so
we can avoid reading the doorbell before writing it.
Update the doorbell-related defines to produce the entire doorbell value
from a single macro. Document the doorbell format in a comment.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
dev_dbg() is used to print ordinary transfer messages in xhci-ring.c.
System log messages will be flushed if CONFIG_USB_DEBUG is set. Replace the
dev_dbg() with xhci_dbg().
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
giveback_first_trb() controls the cycle bit set of the start_trb, to ensure
that the start_trb is written last and the host controller will receive a
whole td at a time.
However, if the ring is wrapped and cycle bit is toggled to zero, then
giveback_first_trb() will be of no effect. In this case, set the cycle bit of
start_trb to 1 at the beginning and clear it in giveback_first_trb().
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Parameter *td is not used in giveback_first_trb(). Remove it.
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Fix the more_trbs_coming field of queue_trb() in isoc transfer.
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
The original code that resumed the USB bus on a port status change would
only do so when there was a device connected to the port. If a device was
just disconnected, the event would be queued for khubd, but khubd wouldn't
run. That would leave the connect status change (CSC) bit set.
If a USB device was plugged into that same port, the xHCI host controller
would set the current connect status (CCS) bit. But since the CSC bit was
already set, it would not generate an interrupt for a port status change
event. That would mean the user could "Safely Remove" a device, have the
bus suspend, disconnect the device, re-plug it in, and then the device
would never be enumerated.
Plugging in a different device on another port would cause the bus to
resume, and khubd would notice the re-connected device. Running lsusb
would also resume the bus, leading users to report the problem "went away"
when using diagnostic tools.
The solution is to resume the bus when a port status change event is
received, regardless of the port status.
Thank you very much to Maddog for helping me track down this Heisenbug.
This patch should be queued for the 2.6.37 stable tree.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Reported-by: Jon 'maddog' Hall <maddog@li.org>
Tested-by: Andiry Xu <andiry.xu@amd.com>
Cc: stable@kernel.org
If the xHCI host controller shares an interrupt line with another device,
the xHCI driver needs to check if the interrupt was generated by its
hardware. Unfortunately, the user will see a ton of "Spurious interrupt."
lines if the other hardware interrupts often. Lawrence found his dmesg
output cluttered with this output when the xHCI host shared an interrupt
with his i915 hardware.
Remove the warning, as sharing an interrupt is a normal thing.
This should be applied to the 2.6.36 stable tree.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Reported-by: Lawrence Rust <lvr@softsystem.co.uk>
Cc: stable@kernel.org
This commit implements port remote wakeup.
When a port is in U3 state and resume signaling is detected from a device,
the port transitions to the Resume state, and the xHC generates a Port Status
Change Event.
For USB3 port, software write a '0' to the PLS field to complete the resume
signaling. For USB2 port, the resume should be signaling for at least 20ms,
irq handler set a timer for port remote wakeup, and then finishes process in
hub_control GetPortStatus.
Some codes are borrowed from EHCI code.
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Add software trigger USB device suspend resume function hook.
Do port suspend & resume in terms of xHCI spec.
Port Suspend:
Stop all endpoints via Stop Endpoint Command with Suspend (SP) flag set.
Place individual ports into suspend mode by writing '3' for Port Link State
(PLS) field into PORTSC register. This can only be done when the port is in
Enabled state. When writing, the Port Link State Write Strobe (LWS) bit shall
be set to '1'.
Allocate an xhci_command and stash it in xhci_virt_device to wait completion for
the last Stop Endpoint Command. Use the Suspend bit in TRB to indicate the Stop
Endpoint Command is for port suspend. Based on Sarah's suggestion.
Port Resume:
Write '0' in PLS field, device will transition to running state.
Ring an endpoints' doorbell to restart it.
Ref: USB device remote wake need another patch to implement. For details of
how USB subsystem do power management, please see:
Documentation/usb/power-management.txt
Signed-off-by: Crane Cai <crane.cai@amd.com>
Signed-off-by: Libin Yang <libin.yang@amd.com>
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>