Skip to content

Commit

Permalink
Merge tag 'usb-5.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
Linus Torvalds committed Jul 28, 2019
2 parents 5bb575b + d39b5ba commit 29af915
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 39 deletions.
6 changes: 2 additions & 4 deletions Documentation/devicetree/bindings/usb/usb251xb.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/host/ehci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/hwa-hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
45 changes: 27 additions & 18 deletions drivers/usb/host/pci-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -201,39 +201,46 @@ 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);

/* probe only once */
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;
}

Expand All @@ -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:
Expand All @@ -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);

Expand All @@ -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)
{
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/pci-quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 7 additions & 8 deletions drivers/usb/misc/usb251xb.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,15 +375,16 @@ 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;
const __be32 *p;
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);
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions drivers/usb/storage/scsiglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 29af915

Please sign in to comment.