Commit graph

12 commits

Author SHA1 Message Date
Sarah Sharp
23e3be113f USB: xhci: Avoid global namespace pollution.
Make all globally visible functions start with xhci_ and mark functions as
static if they're only called within the same C file.  Fix some long lines
while we're at it.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:50 -07:00
Sarah Sharp
3841d56ebb USB: xhci: Fix register write order.
The 0.95 xHCI spec says that if the xHCI HW support 64-bit addressing, you
must write the whole 64-bit address as one atomic operation, or write the
low 32 bits, and then the high 32 bits.  I had the register writes
swapped in some places.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:50 -07:00
Greg Kroah-Hartman
700e2052c6 USB: xhci: fix lots of compiler warnings.
Turns out someone never built this code on a 64bit platform.

Someone owes me a beer...

Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:50 -07:00
Sarah Sharp
ae63674714 USB: xhci: URB cancellation support.
Add URB cancellation support to the xHCI host controller driver.  This
currently supports cancellation for endpoints that do not have streams
enabled.

An URB is represented by a number of Transaction Request Buffers (TRBs),
that are chained together to make one (or more) Transaction Descriptors
(TDs) on an endpoint ring.  The ring is comprised of contiguous segments,
linked together with Link TRBs (which may or may not be chained into a TD).

To cancel an URB, we must stop the endpoint ring, make the hardware skip
over the TDs in the URB (either by turning them into No-op TDs, or by
moving the hardware's ring dequeue pointer past the last TRB in the last
TD), and then restart the ring.

There are times when we must drop the xHCI lock during this process, like
when we need to complete cancelled URBs.  We must ensure that additional
URBs can be marked as cancelled, and that new URBs can be enqueued (since
the URB completion handlers can do either).  The new endpoint ring
variables cancels_pending and state (which can only be modified while
holding the xHCI lock) ensure that future cancellation and enqueueing do
not interrupt any pending cancellation code.

To facilitate cancellation, we must keep track of the starting ring
segment, first TRB, and last TRB for each URB.  We also need to keep track
of the list of TDs that have been marked as cancelled, separate from the
list of TDs that are queued for this endpoint.  The new variables and
cancellation list are stored in the xhci_td structure.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:49 -07:00
Sarah Sharp
b10de14211 USB: xhci: Bulk transfer support
Allow device drivers to submit URBs to bulk endpoints on devices under an
xHCI host controller.  Share code between the control and bulk enqueueing
functions when it makes sense.

To get the best performance out of bulk transfers, SuperSpeed devices must
have the bMaxBurst size copied from their endpoint companion controller
into the xHCI device context.  This allows the host controller to "burst"
up to 16 packets before it has to wait for the device to acknowledge the
first packet.

The buffers in Transfer Request Blocks (TRBs) can cross page boundaries,
but they cannot cross 64KB boundaries.  The buffer must be broken into
multiple TRBs if a 64KB boundary is crossed.

The sum of buffer lengths in all the TRBs in a Transfer Descriptor (TD)
cannot exceed 64MB.  To work around this, the enqueueing code must enqueue
multiple TDs.  The transfer event handler may incorrectly give back the
URB in this case, if it gets a transfer event that points somewhere in the
first TD.  FIXME later.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:49 -07:00
Sarah Sharp
f94e018631 USB: xhci: Bandwidth allocation support
Since the xHCI host controller hardware (xHC) has an internal schedule, it
needs a better representation of what devices are consuming bandwidth on
the bus.  Each device is represented by a device context, with data about
the device, endpoints, and pointers to each endpoint ring.

We need to update the endpoint information for a device context before a
new configuration or alternate interface setting is selected.  We setup an
input device context with modified endpoint information and newly
allocated endpoint rings, and then submit a Configure Endpoint Command to
the hardware.

The host controller can reject the new configuration if it exceeds the bus
bandwidth, or the host controller doesn't have enough internal resources
for the configuration.  If the command fails, we still have the older
device context with the previous configuration.  If the command succeeds,
we free the old endpoint rings.

The root hub isn't a real device, so always say yes to any bandwidth
changes for it.

The USB core will enable, disable, and then enable endpoint 0 several
times during the initialization sequence.  The device will always have an
endpoint ring for endpoint 0 and bandwidth allocated for that, unless the
device is disconnected or gets a SetAddress 0 request.  So we don't pay
attention for when xhci_check_bandwidth() is called for a re-add of
endpoint 0.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:49 -07:00
Sarah Sharp
d0e96f5a71 USB: xhci: Control transfer support.
Allow device drivers to enqueue URBs to control endpoints on devices under
an xHCI host controller.  Each control transfer is represented by a
series of Transfer Descriptors (TDs) written to an endpoint ring.  There
is one TD for the Setup phase, (optionally) one TD for the Data phase, and
one TD for the Status phase.

Enqueue these TDs onto the endpoint ring that represents the control
endpoint.  The host controller hardware will return an event on the event
ring that points to the (DMA) address of one of the TDs on the endpoint
ring.  If the transfer was successful, the transfer event TRB will have a
completion code of success, and it will point to the Status phase TD.
Anything else is considered an error.

This should work for control endpoints besides the default endpoint, but
that hasn't been tested.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:49 -07:00
Sarah Sharp
3ffbba9511 USB: xhci: Allocate and address USB devices
xHCI needs to get a "Slot ID" from the host controller and allocate other
data structures for every USB device.  Make usb_alloc_dev() and
usb_release_dev() allocate and free these device structures.  After
setting up the xHC device structures, usb_alloc_dev() must wait for the
hardware to respond to an Enable Slot command.  usb_alloc_dev() fires off
a Disable Slot command and does not wait for it to complete.

When the USB core wants to choose an address for the device, the xHCI
driver must issue a Set Address command and wait for an event for that
command.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:49 -07:00
Sarah Sharp
7f84eef0da USB: xhci: No-op command queueing and irq handler.
xHCI host controllers can optionally implement a no-op test.  This
simple test ensures the OS has correctly setup all basic data structures
and can correctly respond to interrupts from the host controller
hardware.

There are two rings exercised by the no-op test:  the command ring, and
the event ring.

The host controller driver writes a no-op command TRB to the command
ring, and rings the doorbell for the command ring (the first entry in
the doorbell array).  The hardware receives this event, places a command
completion event on the event ring, and fires an interrupt.

The host controller driver sees the interrupt, and checks the event ring
for TRBs it can process, and sees the command completion event.  (See
the rules in xhci-ring.c for who "owns" a TRB.  This is a simplified set
of rules, and may not contain all the details that are in the xHCI 0.95
spec.)

A timer fires every 60 seconds to debug the state of the hardware and
command and event rings.  This timer only runs if
CONFIG_USB_XHCI_HCD_DEBUGGING is 'y'.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:48 -07:00
Sarah Sharp
a74588f946 USB: xhci: Device context array allocation.
Instead of keeping a "frame list" like older host controllers, the xHCI
host controller keeps internal representations of the USB devices, with a
transfer ring per endpoint.  The host controller queues Transfer Request
Blocks (TRBs) to the endpoint ring, and then "rings the doorbell" for that
device.  The host controller processes the transfer, places a transfer
completion event on the event ring, and interrupts the system.

The device context base address array must be allocated by the xHCI host
controller driver, along with the device contexts it points to.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:48 -07:00
Sarah Sharp
0ebbab3742 USB: xhci: Ring allocation and initialization.
Allocate basic xHCI host controller data structures.  For every xHC, there
is a command ring, an event ring, and a doorbell array.

The doorbell array is used to notify the host controller that work has
been enqueued onto one of the rings.  The host controller driver enqueues
commands on the command ring.  The HW enqueues command completion events
on the event ring and interrupts the system (currently using PCI
interrupts, although the xHCI HW will use MSI interrupts eventually).

All rings and the doorbell array must be allocated by the xHCI host
controller driver.

Each ring is comprised of one or more segments, which consists of 16-byte
Transfer Request Blocks (TRBs) that can be chained to form a Transfer
Descriptor (TD) that represents a multiple-buffer request.  Segments are
linked into a ring using Link TRBs, which means they are dynamically
growable.

The producer of the ring enqueues a TD by writing one or more TRBs in the
ring and toggling the TRB cycle bit for each TRB.  The consumer knows it
can process the TRB when the cycle bit matches its internal consumer cycle
state for the ring.  The consumer cycle state is toggled an odd amount of
times in the ring.

An example ring (a ring must have a minimum of 16 TRBs on it, but that's
too big to draw in ASCII art):

              chain  cycle
               bit    bit
 ------------------------
| TD A TRB 1 |  1  |  1  |<-------------  <-- consumer dequeue ptr
 ------------------------               |     consumer cycle state = 1
| TD A TRB 2 |  1  |  1  |              |
 ------------------------               |
| TD A TRB 3 |  0  |  1  |  segment 1   |
 ------------------------               |
| TD B TRB 1 |  1  |  1  |              |
 ------------------------               |
| TD B TRB 2 |  0  |  1  |              |
 ------------------------               |
| Link TRB   |  0  |  1  |-----         |
 ------------------------     |         |
                              |         |
              chain  cycle    |         |
               bit    bit     |         |
 ------------------------     |         |
| TD C TRB 1 |  0  |  1  |<----         |
 ------------------------               |
| TD D TRB 1 |  1  |  1  |              |
 ------------------------               |
| TD D TRB 2 |  1  |  1  |   segment 2  |
 ------------------------               |
| TD D TRB 3 |  1  |  1  |              |
 ------------------------               |
| TD D TRB 4 |  1  |  1  |              |
 ------------------------               |
| Link TRB   |  1  |  1  |-----         |
 ------------------------     |         |
                              |         |
              chain  cycle    |         |
               bit    bit     |         |
 ------------------------     |         |
| TD D TRB 5 |  1  |  1  |<----         |
 ------------------------               |
| TD D TRB 6 |  0  |  1  |              |
 ------------------------               |
| TD E TRB 1 |  0  |  1  |   segment 3  |
 ------------------------               |
|            |  0  |  0  |              | <-- producer enqueue ptr
 ------------------------               |
|            |  0  |  0  |              |
 ------------------------               |
| Link TRB   |  0  |  0  |---------------
 ------------------------

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:48 -07:00
Sarah Sharp
66d4eadd8d USB: xhci: BIOS handoff and HW initialization.
Add PCI initialization code to take control of the xHCI host controller
away from the BIOS, halt, and reset the host controller.  The xHCI spec
says that BIOSes must give up the host controller within 5 seconds.

Add some host controller glue functions to handle hardware initialization
and memory allocation for the host controller.  The current xHCI
prototypes use PCI interrupts, but the xHCI spec requires MSI-X
interrupts.  Add code to support MSI-X interrupts, but use the PCI
interrupts for now.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-06-15 21:44:48 -07:00