Commit 29af915c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some small fixes for 5.3-rc2. All of these resolve some
  reported issues, some more than others :)

  Included in here is:

   - xhci fix for an annoying issue with odd devices

   - reversion of some usb251xb patches that should not have been merged

   - usb pci quirk additions and fixups

   - usb storage fix

   - usb host controller error test fix

  All of these have been in linux-next with no reported issues"

* tag 'usb-5.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  xhci: Fix crash if scatter gather is used with Immediate Data Transfer (IDT).
  usb: usb251xb: Reallow swap-dx-lanes to apply to the upstream port
  Revert "usb: usb251xb: Add US port lanes inversion property"
  Revert "usb: usb251xb: Add US lanes inversion dts-bindings"
  usb: wusbcore: fix unbalanced get/put cluster_id
  usb/hcd: Fix a NULL vs IS_ERR() bug in usb_hcd_setup_local_mem()
  usb-storage: Add a limitation for blk_queue_max_hw_sectors()
  usb: pci-quirks: Minor cleanup for AMD PLL quirk
  usb: pci-quirks: Correct AMD PLL quirk detection
parents 5bb575bc d39b5bad
......@@ -64,10 +64,8 @@ Optional properties :
- power-on-time-ms : Specifies the time it takes from the time the host
initiates the power-on sequence to a port until the port has adequate
power. The value is given in ms in a 0 - 510 range (default is 100ms).
- swap-dx-lanes : Specifies the downstream ports which will swap the
differential-pair (D+/D-), default is not-swapped.
- swap-us-lanes : Selects the upstream port differential-pair (D+/D-)
swapping (boolean, default is not-swapped)
- swap-dx-lanes : Specifies the ports which will swap the differential-pair
(D+/D-), default is not-swapped.
Examples:
usb2512b@2c {
......
......@@ -3052,8 +3052,8 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
local_mem = devm_memremap(hcd->self.sysdev, phys_addr,
size, MEMREMAP_WC);
if (!local_mem)
return -ENOMEM;
if (IS_ERR(local_mem))
return PTR_ERR(local_mem);
/*
* Here we pass a dma_addr_t but the arg type is a phys_addr_t.
......
......@@ -149,7 +149,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
case PCI_VENDOR_ID_AMD:
/* AMD PLL quirk */
if (usb_amd_find_chipset_info())
if (usb_amd_quirk_pll_check())
ehci->amd_pll_fix = 1;
/* AMD8111 EHCI doesn't work, according to AMD errata */
if (pdev->device == 0x7463) {
......@@ -186,7 +186,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
case PCI_VENDOR_ID_ATI:
/* AMD PLL quirk */
if (usb_amd_find_chipset_info())
if (usb_amd_quirk_pll_check())
ehci->amd_pll_fix = 1;
/*
......
......@@ -159,7 +159,7 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd)
return result;
error_set_cluster_id:
wusb_cluster_id_put(wusbhc->cluster_id);
wusb_cluster_id_put(addr);
error_cluster_id_get:
goto out;
......
......@@ -152,7 +152,7 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
if (usb_amd_find_chipset_info())
if (usb_amd_quirk_pll_check())
ohci->flags |= OHCI_QUIRK_AMD_PLL;
/* SB800 needs pre-fetch fix */
......
......@@ -132,7 +132,7 @@ static struct amd_chipset_info {
struct amd_chipset_type sb_type;
int isoc_reqs;
int probe_count;
int probe_result;
bool need_pll_quirk;
} amd_chipset;
static DEFINE_SPINLOCK(amd_lock);
......@@ -201,11 +201,11 @@ void sb800_prefetch(struct device *dev, int on)
}
EXPORT_SYMBOL_GPL(sb800_prefetch);
int usb_amd_find_chipset_info(void)
static void usb_amd_find_chipset_info(void)
{
unsigned long flags;
struct amd_chipset_info info;
int ret;
info.need_pll_quirk = 0;
spin_lock_irqsave(&amd_lock, flags);
......@@ -213,27 +213,34 @@ int usb_amd_find_chipset_info(void)
if (amd_chipset.probe_count > 0) {
amd_chipset.probe_count++;
spin_unlock_irqrestore(&amd_lock, flags);
return amd_chipset.probe_result;
return;
}
memset(&info, 0, sizeof(info));
spin_unlock_irqrestore(&amd_lock, flags);
if (!amd_chipset_sb_type_init(&info)) {
ret = 0;
goto commit;
}
/* Below chipset generations needn't enable AMD PLL quirk */
if (info.sb_type.gen == AMD_CHIPSET_UNKNOWN ||
info.sb_type.gen == AMD_CHIPSET_SB600 ||
info.sb_type.gen == AMD_CHIPSET_YANGTZE ||
(info.sb_type.gen == AMD_CHIPSET_SB700 &&
info.sb_type.rev > 0x3b)) {
switch (info.sb_type.gen) {
case AMD_CHIPSET_SB700:
info.need_pll_quirk = info.sb_type.rev <= 0x3B;
break;
case AMD_CHIPSET_SB800:
case AMD_CHIPSET_HUDSON2:
case AMD_CHIPSET_BOLTON:
info.need_pll_quirk = 1;
break;
default:
info.need_pll_quirk = 0;
break;
}
if (!info.need_pll_quirk) {
if (info.smbus_dev) {
pci_dev_put(info.smbus_dev);
info.smbus_dev = NULL;
}
ret = 0;
goto commit;
}
......@@ -252,7 +259,6 @@ int usb_amd_find_chipset_info(void)
}
}
ret = info.probe_result = 1;
printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n");
commit:
......@@ -263,7 +269,6 @@ int usb_amd_find_chipset_info(void)
/* Mark that we where here */
amd_chipset.probe_count++;
ret = amd_chipset.probe_result;
spin_unlock_irqrestore(&amd_lock, flags);
......@@ -276,10 +281,7 @@ int usb_amd_find_chipset_info(void)
amd_chipset = info;
spin_unlock_irqrestore(&amd_lock, flags);
}
return ret;
}
EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info);
int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
{
......@@ -315,6 +317,13 @@ bool usb_amd_prefetch_quirk(void)
}
EXPORT_SYMBOL_GPL(usb_amd_prefetch_quirk);
bool usb_amd_quirk_pll_check(void)
{
usb_amd_find_chipset_info();
return amd_chipset.need_pll_quirk;
}
EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_check);
/*
* The hardware normally enables the A-link power management feature, which
* lets the system lower the power consumption in idle states.
......@@ -520,7 +529,7 @@ void usb_amd_dev_put(void)
amd_chipset.nb_type = 0;
memset(&amd_chipset.sb_type, 0, sizeof(amd_chipset.sb_type));
amd_chipset.isoc_reqs = 0;
amd_chipset.probe_result = 0;
amd_chipset.need_pll_quirk = 0;
spin_unlock_irqrestore(&amd_lock, flags);
......
......@@ -5,11 +5,11 @@
#ifdef CONFIG_USB_PCI
void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
int usb_amd_find_chipset_info(void);
int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
bool usb_amd_hang_symptom_quirk(void);
bool usb_amd_prefetch_quirk(void);
void usb_amd_dev_put(void);
bool usb_amd_quirk_pll_check(void);
void usb_amd_quirk_pll_disable(void);
void usb_amd_quirk_pll_enable(void);
void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
......
......@@ -130,7 +130,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_AMD_0x96_HOST;
/* AMD PLL quirk */
if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_quirk_pll_check())
xhci->quirks |= XHCI_AMD_PLL_FIX;
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
......
......@@ -2175,7 +2175,8 @@ static inline bool xhci_urb_suitable_for_idt(struct urb *urb)
if (!usb_endpoint_xfer_isoc(&urb->ep->desc) && usb_urb_dir_out(urb) &&
usb_endpoint_maxp(&urb->ep->desc) >= TRB_IDT_MAX_SIZE &&
urb->transfer_buffer_length <= TRB_IDT_MAX_SIZE &&
!(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
!(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) &&
!urb->num_sgs)
return true;
return false;
......
......@@ -375,7 +375,8 @@ static int usb251xb_connect(struct usb251xb *hub)
#ifdef CONFIG_OF
static void usb251xb_get_ports_field(struct usb251xb *hub,
const char *prop_name, u8 port_cnt, u8 *fld)
const char *prop_name, u8 port_cnt,
bool ds_only, u8 *fld)
{
struct device *dev = hub->dev;
struct property *prop;
......@@ -383,7 +384,7 @@ static void usb251xb_get_ports_field(struct usb251xb *hub,
u32 port;
of_property_for_each_u32(dev->of_node, prop_name, prop, p, port) {
if ((port >= 1) && (port <= port_cnt))
if ((port >= ds_only ? 1 : 0) && (port <= port_cnt))
*fld |= BIT(port);
else
dev_warn(dev, "port %u doesn't exist\n", port);
......@@ -501,15 +502,15 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
hub->non_rem_dev = USB251XB_DEF_NON_REMOVABLE_DEVICES;
usb251xb_get_ports_field(hub, "non-removable-ports", data->port_cnt,
&hub->non_rem_dev);
true, &hub->non_rem_dev);
hub->port_disable_sp = USB251XB_DEF_PORT_DISABLE_SELF;
usb251xb_get_ports_field(hub, "sp-disabled-ports", data->port_cnt,
&hub->port_disable_sp);
true, &hub->port_disable_sp);
hub->port_disable_bp = USB251XB_DEF_PORT_DISABLE_BUS;
usb251xb_get_ports_field(hub, "bp-disabled-ports", data->port_cnt,
&hub->port_disable_bp);
true, &hub->port_disable_bp);
hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF;
if (!of_property_read_u32(np, "sp-max-total-current-microamp",
......@@ -573,9 +574,7 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
*/
hub->port_swap = USB251XB_DEF_PORT_SWAP;
usb251xb_get_ports_field(hub, "swap-dx-lanes", data->port_cnt,
&hub->port_swap);
if (of_get_property(np, "swap-us-lanes", NULL))
hub->port_swap |= BIT(0);
false, &hub->port_swap);
/* The following parameters are currently not exposed to devicetree, but
* may be as soon as needed.
......
......@@ -28,6 +28,8 @@
* status of a command.
*/
#include <linux/blkdev.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/mutex.h>
......@@ -99,6 +101,7 @@ static int slave_alloc (struct scsi_device *sdev)
static int slave_configure(struct scsi_device *sdev)
{
struct us_data *us = host_to_us(sdev->host);
struct device *dev = us->pusb_dev->bus->sysdev;
/*
* Many devices have trouble transferring more than 32KB at a time,
......@@ -128,6 +131,14 @@ static int slave_configure(struct scsi_device *sdev)
blk_queue_max_hw_sectors(sdev->request_queue, 2048);
}
/*
* The max_hw_sectors should be up to maximum size of a mapping for
* the device. Otherwise, a DMA API might fail on swiotlb environment.
*/
blk_queue_max_hw_sectors(sdev->request_queue,
min_t(size_t, queue_max_hw_sectors(sdev->request_queue),
dma_max_mapping_size(dev) >> SECTOR_SHIFT));
/*
* Some USB host controllers can't do DMA; they have to use PIO.
* They indicate this by setting their dma_mask to NULL. For
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment