xHCI patches for 3.8

Hi Greg,
 
 Here's some xHCI bug fixes.  There's nothing major in here that can't
 wait for 3.8.  The NULL pointer deref that commit 68e5254 fixes hasn't
 ever been reported in the three years that the xHCI driver has been
 available, so it can wait a few more weeks.
 
 There's two quirk updates, one for Fresco Logic (commit bba18e3) and one
 for xHCI hosts with the TI redriver (commit b0e4e60).  Commit 4525c0a
 makes the xHCI driver work correctly on the SiBridge xHCI host (and
 perhaps other 1.0 xHCI host controllers).  Commit 392a07a fixes a bug in
 the Intel Panther Point xHCI host bandwidth checking checking.
 
 Commits 2611bd1 and 77b8476 are trivial cleanup patches.
 
 Sarah Sharp
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJQoWZQAAoJEBMGWMLi1Gc53l8P/R05/ZTz+2VsdiotzqOnvJVJ
 b3h2ja4YLy5rtcU5nyn8yEISJVKVowt4w+J9lEVWj8ZtbLptAvQlUjM+2HCdgrTr
 RF5p4Y+5Wa0BHosqya4YPkQFu2ZMEDqgkpbfNU4q0hjrJEwUiB8XNfN2CqoO9RNk
 wQhEISQzhL2bmlgoKejlaU+csW4F1RZ1778SIWS/mj6zqtwc5JBn5J8o/DavJehk
 b2BGCRTKTtVnnP+N5LcWuJQg1tdi48ngigqo0VOqxjFTZ/w5YMLDZfXOBy/91lTI
 8i6hKwU1/LH5hPQf+e8K9H3TbiVUg3TAe7UovstPd9UrVS0xbNgKydjhP0y6/Ozy
 4TnmaQK4IQEGUVwzYLwIKCRrEZ32CNPIzm+ZU82MsMJH2rB0pP4yp1Gcu/IXTQJg
 wAyRNeheKiz6HqYeWE5ZuGK8h8Sodd+LJQeMl+ma/mlx6LvI/wpas8U13qTyOXsV
 E2UzqP4LrnMWtF8sEVnHa85hLvpdYLJDHMGrHHCb2OIgBuVmmf+U+xq7bZBIdeHZ
 iF66czS3ltdgXzimZfHpdTU/i12j3wGQ+si+b5d5GjjgBPJsQTecZD0GtOX4kQ5d
 3roFyW8JY7IEVT8dNRtJsi5sG+DOmtFWycCxA0BicTqa1VVahQoBCQY6UYtce5yD
 b0F5ZWeaGmee9zXSgpWD
 =aiNz
 -----END PGP SIGNATURE-----

Merge tag 'for-usb-next-2012-11-12' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-next

XHCI patches from Sarah:

 "xHCI patches for 3.8

  Hi Greg,

  Here's some xHCI bug fixes.  There's nothing major in here that can't
  wait for 3.8.  The NULL pointer deref that commit 68e5254 fixes hasn't
  ever been reported in the three years that the xHCI driver has been
  available, so it can wait a few more weeks.

  There's two quirk updates, one for Fresco Logic (commit bba18e3) and one
  for xHCI hosts with the TI redriver (commit b0e4e60).  Commit 4525c0a
  makes the xHCI driver work correctly on the SiBridge xHCI host (and
  perhaps other 1.0 xHCI host controllers).  Commit 392a07a fixes a bug in
  the Intel Panther Point xHCI host bandwidth checking checking.

  Commits 2611bd1 and 77b8476 are trivial cleanup patches.

  Sarah Sharp"
This commit is contained in:
Greg Kroah-Hartman 2012-11-12 15:09:46 -08:00
commit 51f1206f60
5 changed files with 53 additions and 40 deletions

View File

@ -205,7 +205,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
next = xhci_segment_alloc(xhci, cycle_state, flags);
if (!next) {
xhci_free_segments_for_ring(xhci, *first);
prev = *first;
while (prev) {
next = prev->next;
xhci_segment_free(xhci, prev);
prev = next;
}
return -ENOMEM;
}
xhci_link_segments(xhci, prev, next, type);
@ -258,7 +263,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
return ring;
fail:
xhci_ring_free(xhci, ring);
kfree(ring);
return NULL;
}

View File

@ -29,6 +29,7 @@
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400
#define PCI_VENDOR_ID_ETRON 0x1b6f
#define PCI_DEVICE_ID_ASROCK_P67 0x7023
@ -58,8 +59,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
/* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
if (pdev->revision == 0x0) {
(pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK ||
pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) {
if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
pdev->revision == 0x0) {
xhci->quirks |= XHCI_RESET_EP_QUIRK;
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n");
@ -218,15 +221,8 @@ static void xhci_pci_remove(struct pci_dev *dev)
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int retval = 0;
if (hcd->state != HC_STATE_SUSPENDED ||
xhci->shared_hcd->state != HC_STATE_SUSPENDED)
return -EINVAL;
retval = xhci_suspend(xhci);
return retval;
return xhci_suspend(xhci);
}
static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)

View File

@ -318,7 +318,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
* seconds), then it should assume that the there are
* larger problems with the xHC and assert HCRST.
*/
ret = handshake(xhci, &xhci->op_regs->cmd_ring,
ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
if (ret < 0) {
xhci_err(xhci, "Stopped the command ring failed, "
@ -3071,11 +3071,11 @@ static u32 xhci_td_remainder(unsigned int remainder)
}
/*
* For xHCI 1.0 host controllers, TD size is the number of packets remaining in
* the TD (*not* including this TRB).
* For xHCI 1.0 host controllers, TD size is the number of max packet sized
* packets remaining in the TD (*not* including this TRB).
*
* Total TD packet count = total_packet_count =
* roundup(TD size in bytes / wMaxPacketSize)
* DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
*
* Packets transferred up to and including this TRB = packets_transferred =
* rounddown(total bytes transferred including this TRB / wMaxPacketSize)
@ -3083,15 +3083,16 @@ static u32 xhci_td_remainder(unsigned int remainder)
* TD size = total_packet_count - packets_transferred
*
* It must fit in bits 21:17, so it can't be bigger than 31.
* The last TRB in a TD must have the TD size set to zero.
*/
static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
unsigned int total_packet_count, struct urb *urb)
unsigned int total_packet_count, struct urb *urb,
unsigned int num_trbs_left)
{
int packets_transferred;
/* One TRB with a zero-length data packet. */
if (running_total == 0 && trb_buff_len == 0)
if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
return 0;
/* All the TRB queueing functions don't count the current TRB in
@ -3100,7 +3101,9 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
packets_transferred = (running_total + trb_buff_len) /
usb_endpoint_maxp(&urb->ep->desc);
return xhci_td_remainder(total_packet_count - packets_transferred);
if ((total_packet_count - packets_transferred) > 31)
return 31 << 17;
return (total_packet_count - packets_transferred) << 17;
}
static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
@ -3127,7 +3130,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
num_trbs = count_sg_trbs_needed(xhci, urb);
num_sgs = urb->num_mapped_sgs;
total_packet_count = roundup(urb->transfer_buffer_length,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
@ -3210,7 +3213,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
trb_buff_len, total_packet_count, urb);
trb_buff_len, total_packet_count, urb,
num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
@ -3318,7 +3322,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
start_cycle = ep_ring->cycle_state;
running_total = 0;
total_packet_count = roundup(urb->transfer_buffer_length,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
/* How much data is in the first TRB? */
addr = (u64) urb->transfer_dma;
@ -3364,7 +3368,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
trb_buff_len, total_packet_count, urb);
trb_buff_len, total_packet_count, urb,
num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
@ -3627,7 +3632,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
addr = start_addr + urb->iso_frame_desc[i].offset;
td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len;
total_packet_count = roundup(td_len,
total_packet_count = DIV_ROUND_UP(td_len,
usb_endpoint_maxp(&urb->ep->desc));
/* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0)
@ -3706,7 +3711,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
} else {
remainder = xhci_v1_0_td_remainder(
running_total, trb_buff_len,
total_packet_count, urb);
total_packet_count, urb,
(trbs_per_td - j - 1));
}
length_field = TRB_LEN(trb_buff_len) |
remainder |

View File

@ -40,7 +40,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
/* TODO: copied from ehci-hcd.c - can this be refactored? */
/*
* handshake - spin reading hc until handshake completes or fails
* xhci_handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
* @mask: bits to look at in result of read
* @done: value of those bits when handshake succeeds
@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
* handshake done). There are two failure modes: "usec" have passed (major
* hardware flakeout), or the register reads as all-ones (hardware removed).
*/
int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec)
{
u32 result;
@ -103,7 +103,7 @@ int xhci_halt(struct xhci_hcd *xhci)
xhci_dbg(xhci, "// Halt the HC\n");
xhci_quiesce(xhci);
ret = handshake(xhci, &xhci->op_regs->status,
ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
if (!ret) {
xhci->xhc_state |= XHCI_STATE_HALTED;
@ -132,7 +132,7 @@ static int xhci_start(struct xhci_hcd *xhci)
* Wait for the HCHalted Status bit to be 0 to indicate the host is
* running.
*/
ret = handshake(xhci, &xhci->op_regs->status,
ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, 0, XHCI_MAX_HALT_USEC);
if (ret == -ETIMEDOUT)
xhci_err(xhci, "Host took too long to start, "
@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci)
command |= CMD_RESET;
xhci_writel(xhci, command, &xhci->op_regs->command);
ret = handshake(xhci, &xhci->op_regs->command,
ret = xhci_handshake(xhci, &xhci->op_regs->command,
CMD_RESET, 0, 10 * 1000 * 1000);
if (ret)
return ret;
@ -177,7 +177,7 @@ int xhci_reset(struct xhci_hcd *xhci)
* xHCI cannot write to any doorbells or operational registers other
* than status until the "Controller Not Ready" flag is cleared.
*/
ret = handshake(xhci, &xhci->op_regs->status,
ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_CNR, 0, 10 * 1000 * 1000);
for (i = 0; i < 2; ++i) {
@ -480,7 +480,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
if (strstr(dmi_product_name, "Z420") ||
strstr(dmi_product_name, "Z620") ||
strstr(dmi_product_name, "Z820") ||
strstr(dmi_product_name, "Z1"))
strstr(dmi_product_name, "Z1 Workstation"))
return true;
return false;
@ -880,6 +880,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 command;
if (hcd->state != HC_STATE_SUSPENDED ||
xhci->shared_hcd->state != HC_STATE_SUSPENDED)
return -EINVAL;
spin_lock_irq(&xhci->lock);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
@ -890,7 +894,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
command = xhci_readl(xhci, &xhci->op_regs->command);
command &= ~CMD_RUN;
xhci_writel(xhci, command, &xhci->op_regs->command);
if (handshake(xhci, &xhci->op_regs->status,
if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) {
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
spin_unlock_irq(&xhci->lock);
@ -905,7 +909,8 @@ int xhci_suspend(struct xhci_hcd *xhci)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_CSS;
xhci_writel(xhci, command, &xhci->op_regs->command);
if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) {
if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_SAVE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC save state timeout\n");
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
@ -967,7 +972,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_CRS;
xhci_writel(xhci, command, &xhci->op_regs->command);
if (handshake(xhci, &xhci->op_regs->status,
if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_RESTORE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC restore state timeout\n");
spin_unlock_irq(&xhci->lock);
@ -1035,7 +1040,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_RUN;
xhci_writel(xhci, command, &xhci->op_regs->command);
handshake(xhci, &xhci->op_regs->status, STS_HALT,
xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT,
0, 250 * 1000);
/* step 5: walk topology and initialize portsc,
@ -2254,7 +2259,7 @@ static bool xhci_is_async_ep(unsigned int ep_type)
static bool xhci_is_sync_in_ep(unsigned int ep_type)
{
return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP);
return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP);
}
static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw)
@ -3874,7 +3879,8 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
spin_lock_irqsave(&xhci->lock, flags);
/* Check L1 Status */
ret = handshake(xhci, pm_addr, PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
ret = xhci_handshake(xhci, pm_addr,
PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
if (ret != -ETIMEDOUT) {
/* enter L1 successfully */
temp = xhci_readl(xhci, addr);

View File

@ -1720,7 +1720,7 @@ static inline void xhci_unregister_plat(void)
/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);