Merge 4.9.221 into android-4.9-q
Changes in 4.9.221
ext4: fix extent_status fragmentation for plain files
net: ipv4: emulate READ_ONCE() on ->hdrincl bit-field in raw_sendmsg()
net: ipv4: avoid unused variable warning for sysctl
drm/msm: Use the correct dma_sync calls harder
crypto: mxs-dcp - make symbols 'sha1_null_hash' and 'sha256_null_hash' static
vti4: removed duplicate log message.
watchdog: reset last_hw_keepalive time at start
scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login
ceph: return ceph_mdsc_do_request() errors from __get_parent()
ceph: don't skip updating wanted caps when cap is stale
pwm: rcar: Fix late Runtime PM enablement
scsi: iscsi: Report unbind session event when the target has been removed
ASoC: Intel: atom: Take the drv->lock mutex before calling sst_send_slot_map()
kernel/gcov/fs.c: gcov_seq_next() should increase position index
ipc/util.c: sysvipc_find_ipc() should increase position index
s390/cio: avoid duplicated 'ADD' uevents
pwm: renesas-tpu: Fix late Runtime PM enablement
pwm: bcm2835: Dynamically allocate base
PCI/ASPM: Allow re-enabling Clock PM
ipv6: fix restrict IPV6_ADDRFORM operation
macsec: avoid to set wrong mtu
macvlan: fix null dereference in macvlan_device_event()
net: netrom: Fix potential nr_neigh refcnt leak in nr_add_node
net/x25: Fix x25_neigh refcnt leak when receiving frame
tcp: cache line align MAX_TCP_HEADER
team: fix hang in team_mode_get()
net: dsa: b53: Fix ARL register definitions
xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish
ALSA: hda: Remove ASUS ROG Zenith from the blacklist
iio: xilinx-xadc: Fix ADC-B powerdown
iio: xilinx-xadc: Fix clearing interrupt when enabling trigger
iio: xilinx-xadc: Fix sequencer configuration for aux channels in simultaneous mode
fs/namespace.c: fix mountpoint reference counter race
USB: sisusbvga: Change port variable from signed to unsigned
USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE
USB: core: Fix free-while-in-use bug in the USB S-Glibrary
USB: hub: Fix handling of connect changes during sleep
overflow.h: Add arithmetic shift helper
vmalloc: fix remap_vmalloc_range() bounds checks
ALSA: usx2y: Fix potential NULL dereference
ALSA: usb-audio: Fix usb audio refcnt leak when getting spdif
ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
tpm/tpm_tis: Free IRQ if probing fails
KVM: Check validity of resolved slot when searching memslots
KVM: VMX: Enable machine check support for 32bit targets
tty: hvc: fix buffer overflow during hvc_alloc().
tty: rocket, avoid OOB access
usb-storage: Add unusual_devs entry for JMicron JMS566
audit: check the length of userspace generated audit records
ASoC: dapm: fixup dapm kcontrol widget
ARM: imx: provide v7_cpu_resume() only on ARM_CPU_SUSPEND=y
staging: comedi: dt2815: fix writing hi byte of analog output
staging: comedi: Fix comedi_device refcnt leak in comedi_open
staging: vt6656: Fix drivers TBTT timing counter.
staging: vt6656: Power save stop wake_up_count wrap around.
UAS: no use logging any details in case of ENODEV
UAS: fix deadlock in error handling and PM flushing work
usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset()
remoteproc: Fix wrong rvring index computation
fuse: fix possibly missed wake-up after abort
mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer
usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete
nfsd: memory corruption in nfsd4_lock()
net/cxgb4: Check the return from t4_query_params properly
perf/core: fix parent pid/tid in task exit events
bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B
xfs: fix partially uninitialized structure in xfs_reflink_remap_extent
scsi: target: fix PR IN / READ FULL STATUS for FC
objtool: Fix CONFIG_UBSAN_TRAP unreachable warnings
objtool: Support Clang non-section symbols in ORC dump
xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status
ext4: convert BUG_ON's to WARN_ON's in mballoc.c
hwmon: (jc42) Fix name to have no illegal characters
ext4: avoid declaring fs inconsistent due to invalid file handles
ext4: protect journal inode's blocks using block_validity
ext4: don't perform block validity checks on the journal inode
ext4: fix block validity checks for journal inodes using indirect blocks
ext4: unsigned int compared against zero
ext4: check for non-zero journal inum in ext4_calculate_overhead
propagate_one(): mnt_set_mountpoint() needs mount_lock
Linux 4.9.221
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ica420bdbb6c18fff9d0e6abffc180beefff0c5b9
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 220
|
||||
SUBLEVEL = 221
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -86,8 +86,10 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
|
||||
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
|
||||
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
|
||||
endif
|
||||
ifeq ($(CONFIG_ARM_CPU_SUSPEND),y)
|
||||
AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
|
||||
obj-$(CONFIG_SOC_IMX6) += resume-imx6.o
|
||||
endif
|
||||
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
|
||||
|
||||
obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
|
||||
|
||||
@@ -5785,7 +5785,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
|
||||
*/
|
||||
static void kvm_machine_check(void)
|
||||
{
|
||||
#if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_64)
|
||||
#if defined(CONFIG_X86_MCE)
|
||||
struct pt_regs regs = {
|
||||
.cs = 3, /* Fake ring 3 no matter what the guest ran on */
|
||||
.flags = X86_EFLAGS_IF,
|
||||
|
||||
@@ -150,6 +150,19 @@ static bool is_ereg(u32 reg)
|
||||
BIT(BPF_REG_AX));
|
||||
}
|
||||
|
||||
/*
|
||||
* is_ereg_8l() == true if BPF register 'reg' is mapped to access x86-64
|
||||
* lower 8-bit registers dil,sil,bpl,spl,r8b..r15b, which need extra byte
|
||||
* of encoding. al,cl,dl,bl have simpler encoding.
|
||||
*/
|
||||
static bool is_ereg_8l(u32 reg)
|
||||
{
|
||||
return is_ereg(reg) ||
|
||||
(1 << reg) & (BIT(BPF_REG_1) |
|
||||
BIT(BPF_REG_2) |
|
||||
BIT(BPF_REG_FP));
|
||||
}
|
||||
|
||||
/* add modifiers if 'reg' maps to x64 registers r8..r15 */
|
||||
static u8 add_1mod(u8 byte, u32 reg)
|
||||
{
|
||||
@@ -771,9 +784,8 @@ st: if (is_imm8(insn->off))
|
||||
/* STX: *(u8*)(dst_reg + off) = src_reg */
|
||||
case BPF_STX | BPF_MEM | BPF_B:
|
||||
/* emit 'mov byte ptr [rax + off], al' */
|
||||
if (is_ereg(dst_reg) || is_ereg(src_reg) ||
|
||||
/* have to add extra byte for x86 SIL, DIL regs */
|
||||
src_reg == BPF_REG_1 || src_reg == BPF_REG_2)
|
||||
if (is_ereg(dst_reg) || is_ereg_8l(src_reg))
|
||||
/* Add extra byte for eregs or SIL,DIL,BPL in src_reg */
|
||||
EMIT2(add_2mod(0x40, dst_reg, src_reg), 0x88);
|
||||
else
|
||||
EMIT1(0x88);
|
||||
|
||||
@@ -329,6 +329,9 @@ static void disable_interrupts(struct tpm_chip *chip)
|
||||
u32 intmask;
|
||||
int rc;
|
||||
|
||||
if (priv->irq == 0)
|
||||
return;
|
||||
|
||||
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
|
||||
if (rc < 0)
|
||||
intmask = 0;
|
||||
@@ -786,9 +789,12 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
if (irq) {
|
||||
tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
|
||||
irq);
|
||||
if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
|
||||
if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
|
||||
dev_err(&chip->dev, FW_BUG
|
||||
"TPM interrupt not working, polling instead\n");
|
||||
|
||||
disable_interrupts(chip);
|
||||
}
|
||||
} else {
|
||||
tpm_tis_probe_irq(chip, intmask);
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
* Null hashes to align with hw behavior on imx6sl and ull
|
||||
* these are flipped for consistency with hw output
|
||||
*/
|
||||
const uint8_t sha1_null_hash[] =
|
||||
static const uint8_t sha1_null_hash[] =
|
||||
"\x09\x07\xd8\xaf\x90\x18\x60\x95\xef\xbf"
|
||||
"\x55\x32\x0d\x4b\x6b\x5e\xee\xa3\x39\xda";
|
||||
|
||||
const uint8_t sha256_null_hash[] =
|
||||
static const uint8_t sha256_null_hash[] =
|
||||
"\x55\xb8\x52\x78\x1b\x99\x95\xa4"
|
||||
"\x4c\x93\x9b\x64\xe4\x41\xae\x27"
|
||||
"\x24\xb9\x6f\x99\xc8\xf4\xfb\x9a"
|
||||
|
||||
@@ -58,7 +58,7 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
|
||||
{
|
||||
struct device *dev = msm_obj->base.dev->dev;
|
||||
|
||||
if (get_dma_ops(dev)) {
|
||||
if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
|
||||
dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
|
||||
msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
|
||||
} else {
|
||||
@@ -71,7 +71,7 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
|
||||
{
|
||||
struct device *dev = msm_obj->base.dev->dev;
|
||||
|
||||
if (get_dma_ops(dev)) {
|
||||
if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
|
||||
dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
|
||||
msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
|
||||
} else {
|
||||
|
||||
@@ -508,7 +508,7 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
}
|
||||
data->config = config;
|
||||
|
||||
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
|
||||
hwmon_dev = devm_hwmon_device_register_with_info(dev, "jc42",
|
||||
data, &jc42_chip_info,
|
||||
NULL);
|
||||
return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||
|
||||
@@ -660,7 +660,7 @@ static int xadc_trigger_set_state(struct iio_trigger *trigger, bool state)
|
||||
|
||||
spin_lock_irqsave(&xadc->lock, flags);
|
||||
xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
|
||||
xadc_write_reg(xadc, XADC_AXI_REG_IPISR, val & XADC_AXI_INT_EOS);
|
||||
xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS);
|
||||
if (state)
|
||||
val |= XADC_AXI_INT_EOS;
|
||||
else
|
||||
@@ -709,13 +709,14 @@ static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
/* Powerdown the ADC-B when it is not needed. */
|
||||
switch (seq_mode) {
|
||||
case XADC_CONF1_SEQ_SIMULTANEOUS:
|
||||
case XADC_CONF1_SEQ_INDEPENDENT:
|
||||
val = XADC_CONF2_PD_ADC_B;
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
val = XADC_CONF2_PD_ADC_B;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -784,6 +785,16 @@ static int xadc_preenable(struct iio_dev *indio_dev)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* In simultaneous mode the upper and lower aux channels are samples at
|
||||
* the same time. In this mode the upper 8 bits in the sequencer
|
||||
* register are don't care and the lower 8 bits control two channels
|
||||
* each. As such we must set the bit if either the channel in the lower
|
||||
* group or the upper group is enabled.
|
||||
*/
|
||||
if (seq_mode == XADC_CONF1_SEQ_SIMULTANEOUS)
|
||||
scan_mask = ((scan_mask >> 8) | scan_mask) & 0xff0000;
|
||||
|
||||
ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@@ -1879,7 +1879,11 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (time_after(jiffies, timeo) && !chip_ready(map, adr))
|
||||
/*
|
||||
* We check "time_after" and "!chip_good" before checking "chip_good" to avoid
|
||||
* the failure due to scheduling.
|
||||
*/
|
||||
if (time_after(jiffies, timeo) && !chip_good(map, adr, datum))
|
||||
break;
|
||||
|
||||
if (chip_good(map, adr, datum)) {
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
*
|
||||
* BCM5325 and BCM5365 share most definitions below
|
||||
*/
|
||||
#define B53_ARLTBL_MAC_VID_ENTRY(n) (0x10 * (n))
|
||||
#define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10)
|
||||
#define ARLTBL_MAC_MASK 0xffffffffffffULL
|
||||
#define ARLTBL_VID_S 48
|
||||
#define ARLTBL_VID_MASK_25 0xff
|
||||
@@ -273,7 +273,7 @@
|
||||
#define ARLTBL_VALID_25 BIT(63)
|
||||
|
||||
/* ARL Table Data Entry N Registers (32 bit) */
|
||||
#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x08)
|
||||
#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18)
|
||||
#define ARLTBL_DATA_PORT_ID_MASK 0x1ff
|
||||
#define ARLTBL_TC(tc) ((3 & tc) << 11)
|
||||
#define ARLTBL_AGE BIT(14)
|
||||
|
||||
@@ -3400,7 +3400,7 @@ int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver)
|
||||
FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_VERSION));
|
||||
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
|
||||
¶m, &val);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
return ret;
|
||||
*phy_fw_ver = val;
|
||||
return 0;
|
||||
|
||||
@@ -3209,11 +3209,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
|
||||
struct nlattr *tb[], struct nlattr *data[])
|
||||
{
|
||||
struct macsec_dev *macsec = macsec_priv(dev);
|
||||
struct net_device *real_dev;
|
||||
int err;
|
||||
sci_t sci;
|
||||
u8 icv_len = DEFAULT_ICV_LEN;
|
||||
rx_handler_func_t *rx_handler;
|
||||
u8 icv_len = DEFAULT_ICV_LEN;
|
||||
struct net_device *real_dev;
|
||||
int err, mtu;
|
||||
sci_t sci;
|
||||
|
||||
if (!tb[IFLA_LINK])
|
||||
return -EINVAL;
|
||||
@@ -3229,7 +3229,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
|
||||
|
||||
if (data && data[IFLA_MACSEC_ICV_LEN])
|
||||
icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]);
|
||||
dev->mtu = real_dev->mtu - icv_len - macsec_extra_len(true);
|
||||
mtu = real_dev->mtu - icv_len - macsec_extra_len(true);
|
||||
if (mtu < 0)
|
||||
dev->mtu = 0;
|
||||
else
|
||||
dev->mtu = mtu;
|
||||
|
||||
rx_handler = rtnl_dereference(real_dev->rx_handler);
|
||||
if (rx_handler && rx_handler != macsec_handle_frame)
|
||||
|
||||
@@ -1607,7 +1607,7 @@ static int macvlan_device_event(struct notifier_block *unused,
|
||||
struct macvlan_dev,
|
||||
list);
|
||||
|
||||
if (macvlan_sync_address(vlan->dev, dev->dev_addr))
|
||||
if (vlan && macvlan_sync_address(vlan->dev, dev->dev_addr))
|
||||
return NOTIFY_BAD;
|
||||
|
||||
break;
|
||||
|
||||
@@ -480,6 +480,9 @@ static const struct team_mode *team_mode_get(const char *kind)
|
||||
struct team_mode_item *mitem;
|
||||
const struct team_mode *mode = NULL;
|
||||
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return NULL;
|
||||
|
||||
spin_lock(&mode_list_lock);
|
||||
mitem = __find_mode(kind);
|
||||
if (!mitem) {
|
||||
@@ -495,6 +498,7 @@ static const struct team_mode *team_mode_get(const char *kind)
|
||||
}
|
||||
|
||||
spin_unlock(&mode_list_lock);
|
||||
module_put(THIS_MODULE);
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ struct pcie_link_state {
|
||||
u32 clkpm_capable:1; /* Clock PM capable? */
|
||||
u32 clkpm_enabled:1; /* Current Clock PM state */
|
||||
u32 clkpm_default:1; /* Default Clock PM state by BIOS */
|
||||
u32 clkpm_disable:1; /* Clock PM disabled */
|
||||
|
||||
/* Exit latencies */
|
||||
struct aspm_latency latency_up; /* Upstream direction exit latency */
|
||||
@@ -138,8 +139,11 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
|
||||
|
||||
static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
|
||||
{
|
||||
/* Don't enable Clock PM if the link is not Clock PM capable */
|
||||
if (!link->clkpm_capable)
|
||||
/*
|
||||
* Don't enable Clock PM if the link is not Clock PM capable
|
||||
* or Clock PM is disabled
|
||||
*/
|
||||
if (!link->clkpm_capable || link->clkpm_disable)
|
||||
enable = 0;
|
||||
/* Need nothing if the specified equals to current state */
|
||||
if (link->clkpm_enabled == enable)
|
||||
@@ -169,7 +173,8 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
|
||||
}
|
||||
link->clkpm_enabled = enabled;
|
||||
link->clkpm_default = enabled;
|
||||
link->clkpm_capable = (blacklist) ? 0 : capable;
|
||||
link->clkpm_capable = capable;
|
||||
link->clkpm_disable = blacklist ? 1 : 0;
|
||||
}
|
||||
|
||||
static bool pcie_retrain_link(struct pcie_link_state *link)
|
||||
@@ -773,10 +778,9 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
link->aspm_disable |= ASPM_STATE_L1;
|
||||
pcie_config_aspm_link(link, policy_to_aspm_state(link));
|
||||
|
||||
if (state & PCIE_LINK_STATE_CLKPM) {
|
||||
link->clkpm_capable = 0;
|
||||
pcie_set_clkpm(link, 0);
|
||||
}
|
||||
if (state & PCIE_LINK_STATE_CLKPM)
|
||||
link->clkpm_disable = 1;
|
||||
pcie_set_clkpm(link, policy_to_clkpm_state(link));
|
||||
mutex_unlock(&aspm_lock);
|
||||
if (sem)
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
@@ -166,6 +166,7 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
|
||||
|
||||
pc->chip.dev = &pdev->dev;
|
||||
pc->chip.ops = &bcm2835_pwm_ops;
|
||||
pc->chip.base = -1;
|
||||
pc->chip.npwm = 2;
|
||||
|
||||
platform_set_drvdata(pdev, pc);
|
||||
|
||||
@@ -236,24 +236,28 @@ static int rcar_pwm_probe(struct platform_device *pdev)
|
||||
rcar_pwm->chip.base = -1;
|
||||
rcar_pwm->chip.npwm = 1;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = pwmchip_add(&rcar_pwm->chip);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_pwm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
ret = pwmchip_remove(&rcar_pwm->chip);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return pwmchip_remove(&rcar_pwm->chip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id rcar_pwm_of_table[] = {
|
||||
|
||||
@@ -423,16 +423,17 @@ static int tpu_probe(struct platform_device *pdev)
|
||||
tpu->chip.base = -1;
|
||||
tpu->chip.npwm = TPU_CHANNEL_MAX;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = pwmchip_add(&tpu->chip);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to register PWM chip\n");
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -442,12 +443,10 @@ static int tpu_remove(struct platform_device *pdev)
|
||||
int ret;
|
||||
|
||||
ret = pwmchip_remove(&tpu->chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
@@ -284,7 +284,7 @@ void rproc_free_vring(struct rproc_vring *rvring)
|
||||
{
|
||||
int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
|
||||
struct rproc *rproc = rvring->rvdev->rproc;
|
||||
int idx = rvring->rvdev->vring - rvring;
|
||||
int idx = rvring - rvring->rvdev->vring;
|
||||
struct fw_rsc_vdev *rsc;
|
||||
|
||||
dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
|
||||
|
||||
@@ -868,8 +868,10 @@ static void io_subchannel_register(struct ccw_device *cdev)
|
||||
* Now we know this subchannel will stay, we can throw
|
||||
* our delayed uevent.
|
||||
*/
|
||||
dev_set_uevent_suppress(&sch->dev, 0);
|
||||
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
|
||||
if (dev_get_uevent_suppress(&sch->dev)) {
|
||||
dev_set_uevent_suppress(&sch->dev, 0);
|
||||
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
|
||||
}
|
||||
/* make it known to the system */
|
||||
ret = ccw_device_add(cdev);
|
||||
if (ret) {
|
||||
@@ -1077,8 +1079,11 @@ static int io_subchannel_probe(struct subchannel *sch)
|
||||
* Throw the delayed uevent for the subchannel, register
|
||||
* the ccw_device and exit.
|
||||
*/
|
||||
dev_set_uevent_suppress(&sch->dev, 0);
|
||||
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
|
||||
if (dev_get_uevent_suppress(&sch->dev)) {
|
||||
/* should always be the case for the console */
|
||||
dev_set_uevent_suppress(&sch->dev, 0);
|
||||
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
|
||||
}
|
||||
cdev = sch_get_cdev(sch);
|
||||
rc = ccw_device_add(cdev);
|
||||
if (rc) {
|
||||
|
||||
@@ -2210,6 +2210,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
!pmb->u.mb.mbxStatus) {
|
||||
rpi = pmb->u.mb.un.varWords[0];
|
||||
vpi = pmb->u.mb.un.varRegLogin.vpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
vpi -= phba->sli4_hba.max_cfg_param.vpi_base;
|
||||
lpfc_unreg_login(phba, vpi, rpi, pmb);
|
||||
pmb->vport = vport;
|
||||
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
|
||||
@@ -2016,7 +2016,7 @@ static void __iscsi_unbind_session(struct work_struct *work)
|
||||
if (session->target_id == ISCSI_MAX_TARGET) {
|
||||
spin_unlock_irqrestore(&session->lock, flags);
|
||||
mutex_unlock(&ihost->mutex);
|
||||
return;
|
||||
goto unbind_session_exit;
|
||||
}
|
||||
|
||||
target_id = session->target_id;
|
||||
@@ -2028,6 +2028,8 @@ static void __iscsi_unbind_session(struct work_struct *work)
|
||||
ida_simple_remove(&iscsi_sess_ida, target_id);
|
||||
|
||||
scsi_remove_target(&session->dev);
|
||||
|
||||
unbind_session_exit:
|
||||
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
|
||||
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
|
||||
}
|
||||
|
||||
@@ -2592,8 +2592,10 @@ static int comedi_open(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
cfp = kzalloc(sizeof(*cfp), GFP_KERNEL);
|
||||
if (!cfp)
|
||||
if (!cfp) {
|
||||
comedi_dev_put(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cfp->dev = dev;
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
/* FIXME: lo bit 0 chooses voltage output or current output */
|
||||
lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
|
||||
hi = (data[i] & 0xff0) >> 4;
|
||||
|
||||
@@ -114,6 +115,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
outb(hi, dev->iobase + DT2815_DATA);
|
||||
|
||||
devpriv->ao_readback[chan] = data[i];
|
||||
}
|
||||
return i;
|
||||
|
||||
@@ -153,7 +153,8 @@ void vnt_int_process_data(struct vnt_private *priv)
|
||||
priv->wake_up_count =
|
||||
priv->hw->conf.listen_interval;
|
||||
|
||||
--priv->wake_up_count;
|
||||
if (priv->wake_up_count)
|
||||
--priv->wake_up_count;
|
||||
|
||||
/* Turn on wake up to listen next beacon */
|
||||
if (priv->wake_up_count == 1)
|
||||
|
||||
@@ -755,12 +755,15 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
|
||||
vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL,
|
||||
TFTCTL_TSFCNTREN);
|
||||
|
||||
vnt_adjust_tsf(priv, conf->beacon_rate->hw_value,
|
||||
conf->sync_tsf, priv->current_tsf);
|
||||
|
||||
vnt_mac_set_beacon_interval(priv, conf->beacon_int);
|
||||
|
||||
vnt_reset_next_tbtt(priv, conf->beacon_int);
|
||||
|
||||
vnt_adjust_tsf(priv, conf->beacon_rate->hw_value,
|
||||
conf->sync_tsf, priv->current_tsf);
|
||||
|
||||
vnt_update_next_tbtt(priv,
|
||||
conf->sync_tsf, conf->beacon_int);
|
||||
} else {
|
||||
vnt_clear_current_tsf(priv);
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ static int fc_get_pr_transport_id(
|
||||
* encoded TransportID.
|
||||
*/
|
||||
ptr = &se_nacl->initiatorname[0];
|
||||
for (i = 0; i < 24; ) {
|
||||
for (i = 0; i < 23; ) {
|
||||
if (!strncmp(&ptr[i], ":", 1)) {
|
||||
i++;
|
||||
continue;
|
||||
|
||||
@@ -289,10 +289,6 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
|
||||
vtermnos[index] = vtermno;
|
||||
cons_ops[index] = ops;
|
||||
|
||||
/* reserve all indices up to and including this index */
|
||||
if (last_hvc < index)
|
||||
last_hvc = index;
|
||||
|
||||
/* check if we need to re-register the kernel console */
|
||||
hvc_check_console(index);
|
||||
|
||||
@@ -896,13 +892,22 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
|
||||
cons_ops[i] == hp->ops)
|
||||
break;
|
||||
|
||||
/* no matching slot, just use a counter */
|
||||
if (i >= MAX_NR_HVC_CONSOLES)
|
||||
i = ++last_hvc;
|
||||
if (i >= MAX_NR_HVC_CONSOLES) {
|
||||
|
||||
/* find 'empty' slot for console */
|
||||
for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) {
|
||||
}
|
||||
|
||||
/* no matching slot, just use a counter */
|
||||
if (i == MAX_NR_HVC_CONSOLES)
|
||||
i = ++last_hvc + MAX_NR_HVC_CONSOLES;
|
||||
}
|
||||
|
||||
hp->index = i;
|
||||
cons_ops[i] = ops;
|
||||
vtermnos[i] = vtermno;
|
||||
if (i < MAX_NR_HVC_CONSOLES) {
|
||||
cons_ops[i] = ops;
|
||||
vtermnos[i] = vtermno;
|
||||
}
|
||||
|
||||
list_add_tail(&(hp->next), &hvc_structs);
|
||||
spin_unlock(&hvc_structs_lock);
|
||||
|
||||
@@ -645,18 +645,21 @@ init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
|
||||
tty_port_init(&info->port);
|
||||
info->port.ops = &rocket_port_ops;
|
||||
info->flags &= ~ROCKET_MODE_MASK;
|
||||
switch (pc104[board][line]) {
|
||||
case 422:
|
||||
info->flags |= ROCKET_MODE_RS422;
|
||||
break;
|
||||
case 485:
|
||||
info->flags |= ROCKET_MODE_RS485;
|
||||
break;
|
||||
case 232:
|
||||
default:
|
||||
if (board < ARRAY_SIZE(pc104) && line < ARRAY_SIZE(pc104_1))
|
||||
switch (pc104[board][line]) {
|
||||
case 422:
|
||||
info->flags |= ROCKET_MODE_RS422;
|
||||
break;
|
||||
case 485:
|
||||
info->flags |= ROCKET_MODE_RS485;
|
||||
break;
|
||||
case 232:
|
||||
default:
|
||||
info->flags |= ROCKET_MODE_RS232;
|
||||
break;
|
||||
}
|
||||
else
|
||||
info->flags |= ROCKET_MODE_RS232;
|
||||
break;
|
||||
}
|
||||
|
||||
info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
|
||||
if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
|
||||
|
||||
@@ -1191,6 +1191,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
||||
#ifdef CONFIG_PM
|
||||
udev->reset_resume = 1;
|
||||
#endif
|
||||
/* Don't set the change_bits when the device
|
||||
* was powered off.
|
||||
*/
|
||||
if (test_bit(port1, hub->power_bits))
|
||||
set_bit(port1, hub->change_bits);
|
||||
|
||||
} else {
|
||||
/* The power session is gone; tell hub_wq */
|
||||
@@ -2991,6 +2996,15 @@ static int check_port_resume_type(struct usb_device *udev,
|
||||
if (portchange & USB_PORT_STAT_C_ENABLE)
|
||||
usb_clear_port_feature(hub->hdev, port1,
|
||||
USB_PORT_FEAT_C_ENABLE);
|
||||
|
||||
/*
|
||||
* Whatever made this reset-resume necessary may have
|
||||
* turned on the port1 bit in hub->change_bits. But after
|
||||
* a successful reset-resume we want the bit to be clear;
|
||||
* if it was on it would indicate that something happened
|
||||
* following the reset-resume.
|
||||
*/
|
||||
clear_bit(port1, hub->change_bits);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -585,12 +585,13 @@ void usb_sg_cancel(struct usb_sg_request *io)
|
||||
int i, retval;
|
||||
|
||||
spin_lock_irqsave(&io->lock, flags);
|
||||
if (io->status) {
|
||||
if (io->status || io->count == 0) {
|
||||
spin_unlock_irqrestore(&io->lock, flags);
|
||||
return;
|
||||
}
|
||||
/* shut everything down */
|
||||
io->status = -ECONNRESET;
|
||||
io->count++; /* Keep the request alive until we're done */
|
||||
spin_unlock_irqrestore(&io->lock, flags);
|
||||
|
||||
for (i = io->entries - 1; i >= 0; --i) {
|
||||
@@ -604,6 +605,12 @@ void usb_sg_cancel(struct usb_sg_request *io)
|
||||
dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&io->lock, flags);
|
||||
io->count--;
|
||||
if (!io->count)
|
||||
complete(&io->complete);
|
||||
spin_unlock_irqrestore(&io->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_sg_cancel);
|
||||
|
||||
|
||||
@@ -272,6 +272,10 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* Corsair K70 LUX */
|
||||
{ USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Corsair K70 RGB RAPDIFIRE */
|
||||
{ USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
|
||||
USB_QUIRK_DELAY_CTRL_MSG },
|
||||
|
||||
/* MIDI keyboard WORLDE MINI */
|
||||
{ USB_DEVICE(0x1c75, 0x0204), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
@@ -1701,6 +1701,10 @@ static void ffs_data_reset(struct ffs_data *ffs)
|
||||
ffs->state = FFS_READ_DESCRIPTORS;
|
||||
ffs->setup_state = FFS_NO_SETUP;
|
||||
ffs->flags = 0;
|
||||
|
||||
ffs->ms_os_descs_ext_prop_count = 0;
|
||||
ffs->ms_os_descs_ext_prop_name_len = 0;
|
||||
ffs->ms_os_descs_ext_prop_data_len = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req,
|
||||
{
|
||||
struct bdc *bdc = ep->bdc;
|
||||
|
||||
if (req == NULL || &req->queue == NULL || &req->usb_req == NULL)
|
||||
if (req == NULL)
|
||||
return;
|
||||
|
||||
dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);
|
||||
|
||||
@@ -1200,18 +1200,18 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
|
||||
/* High level: Gfx (indexed) register access */
|
||||
|
||||
#ifdef INCL_SISUSB_CON
|
||||
int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data)
|
||||
int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data)
|
||||
{
|
||||
return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
|
||||
}
|
||||
|
||||
int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data)
|
||||
int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data)
|
||||
{
|
||||
return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
|
||||
int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 index, u8 data)
|
||||
{
|
||||
int ret;
|
||||
@@ -1221,7 +1221,7 @@ int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
|
||||
int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 index, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
@@ -1231,7 +1231,7 @@ int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
|
||||
int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx,
|
||||
u8 myand, u8 myor)
|
||||
{
|
||||
int ret;
|
||||
@@ -1246,7 +1246,7 @@ int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
|
||||
}
|
||||
|
||||
static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
|
||||
int port, u8 idx, u8 data, u8 mask)
|
||||
u32 port, u8 idx, u8 data, u8 mask)
|
||||
{
|
||||
int ret;
|
||||
u8 tmp;
|
||||
@@ -1259,13 +1259,13 @@ static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
|
||||
int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 index, u8 myor)
|
||||
{
|
||||
return sisusb_setidxregandor(sisusb, port, index, 0xff, myor);
|
||||
}
|
||||
|
||||
int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
|
||||
int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 idx, u8 myand)
|
||||
{
|
||||
return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00);
|
||||
@@ -2796,8 +2796,8 @@ static loff_t sisusb_lseek(struct file *file, loff_t offset, int orig)
|
||||
static int sisusb_handle_command(struct sisusb_usb_data *sisusb,
|
||||
struct sisusb_command *y, unsigned long arg)
|
||||
{
|
||||
int retval, port, length;
|
||||
u32 address;
|
||||
int retval, length;
|
||||
u32 port, address;
|
||||
|
||||
/* All our commands require the device
|
||||
* to be initialized.
|
||||
|
||||
@@ -811,17 +811,17 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] = {
|
||||
int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
|
||||
int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
|
||||
|
||||
extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data);
|
||||
extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data);
|
||||
extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
|
||||
extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data);
|
||||
extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data);
|
||||
extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 index, u8 data);
|
||||
extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
|
||||
extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 index, u8 * data);
|
||||
extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port,
|
||||
extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 idx, u8 myand, u8 myor);
|
||||
extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
|
||||
extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 index, u8 myor);
|
||||
extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
|
||||
extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
|
||||
u8 idx, u8 myand);
|
||||
|
||||
void sisusb_delete(struct kref *kref);
|
||||
|
||||
@@ -82,6 +82,19 @@ static void uas_free_streams(struct uas_dev_info *devinfo);
|
||||
static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
|
||||
int status);
|
||||
|
||||
/*
|
||||
* This driver needs its own workqueue, as we need to control memory allocation.
|
||||
*
|
||||
* In the course of error handling and power management uas_wait_for_pending_cmnds()
|
||||
* needs to flush pending work items. In these contexts we cannot allocate memory
|
||||
* by doing block IO as we would deadlock. For the same reason we cannot wait
|
||||
* for anything allocating memory not heeding these constraints.
|
||||
*
|
||||
* So we have to control all work items that can be on the workqueue we flush.
|
||||
* Hence we cannot share a queue and need our own.
|
||||
*/
|
||||
static struct workqueue_struct *workqueue;
|
||||
|
||||
static void uas_do_work(struct work_struct *work)
|
||||
{
|
||||
struct uas_dev_info *devinfo =
|
||||
@@ -110,7 +123,7 @@ static void uas_do_work(struct work_struct *work)
|
||||
if (!err)
|
||||
cmdinfo->state &= ~IS_IN_WORK_LIST;
|
||||
else
|
||||
schedule_work(&devinfo->work);
|
||||
queue_work(workqueue, &devinfo->work);
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&devinfo->lock, flags);
|
||||
@@ -135,7 +148,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
|
||||
|
||||
lockdep_assert_held(&devinfo->lock);
|
||||
cmdinfo->state |= IS_IN_WORK_LIST;
|
||||
schedule_work(&devinfo->work);
|
||||
queue_work(workqueue, &devinfo->work);
|
||||
}
|
||||
|
||||
static void uas_zap_pending(struct uas_dev_info *devinfo, int result)
|
||||
@@ -191,6 +204,9 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
|
||||
struct uas_cmd_info *ci = (void *)&cmnd->SCp;
|
||||
struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
|
||||
|
||||
if (status == -ENODEV) /* too late */
|
||||
return;
|
||||
|
||||
scmd_printk(KERN_INFO, cmnd,
|
||||
"%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ",
|
||||
prefix, status, cmdinfo->uas_tag,
|
||||
@@ -1233,7 +1249,31 @@ static struct usb_driver uas_driver = {
|
||||
.id_table = uas_usb_ids,
|
||||
};
|
||||
|
||||
module_usb_driver(uas_driver);
|
||||
static int __init uas_init(void)
|
||||
{
|
||||
int rv;
|
||||
|
||||
workqueue = alloc_workqueue("uas", WQ_MEM_RECLAIM, 0);
|
||||
if (!workqueue)
|
||||
return -ENOMEM;
|
||||
|
||||
rv = usb_register(&uas_driver);
|
||||
if (rv) {
|
||||
destroy_workqueue(workqueue);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit uas_exit(void)
|
||||
{
|
||||
usb_deregister(&uas_driver);
|
||||
destroy_workqueue(workqueue);
|
||||
}
|
||||
|
||||
module_init(uas_init);
|
||||
module_exit(uas_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR(
|
||||
|
||||
@@ -2342,6 +2342,13 @@ UNUSUAL_DEV( 0x3340, 0xffff, 0x0000, 0x0000,
|
||||
USB_SC_DEVICE,USB_PR_DEVICE,NULL,
|
||||
US_FL_MAX_SECTORS_64 ),
|
||||
|
||||
/* Reported by Cyril Roelandt <tipecaml@gmail.com> */
|
||||
UNUSUAL_DEV( 0x357d, 0x7788, 0x0114, 0x0114,
|
||||
"JMicron",
|
||||
"USB to ATA/ATAPI Bridge",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_BROKEN_FUA ),
|
||||
|
||||
/* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
|
||||
UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100,
|
||||
"iRiver",
|
||||
|
||||
@@ -237,6 +237,7 @@ static int watchdog_start(struct watchdog_device *wdd)
|
||||
if (err == 0) {
|
||||
set_bit(WDOG_ACTIVE, &wdd->status);
|
||||
wd_data->last_keepalive = started_at;
|
||||
wd_data->last_hw_keepalive = started_at;
|
||||
watchdog_update_worker(wdd);
|
||||
}
|
||||
|
||||
|
||||
@@ -469,7 +469,14 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
|
||||
int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs,
|
||||
unsigned int nr_grefs, void **vaddr)
|
||||
{
|
||||
return ring_ops->map(dev, gnt_refs, nr_grefs, vaddr);
|
||||
int err;
|
||||
|
||||
err = ring_ops->map(dev, gnt_refs, nr_grefs, vaddr);
|
||||
/* Some hypervisors are buggy and can return 1. */
|
||||
if (err > 0)
|
||||
err = GNTST_general_error;
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
|
||||
|
||||
|
||||
@@ -1764,8 +1764,12 @@ retry_locked:
|
||||
}
|
||||
|
||||
/* want more caps from mds? */
|
||||
if (want & ~(cap->mds_wanted | cap->issued))
|
||||
goto ack;
|
||||
if (want & ~cap->mds_wanted) {
|
||||
if (want & ~(cap->mds_wanted | cap->issued))
|
||||
goto ack;
|
||||
if (!__cap_is_valid(cap))
|
||||
goto ack;
|
||||
}
|
||||
|
||||
/* things we might delay */
|
||||
if ((cap->issued & ~retain) == 0 &&
|
||||
|
||||
@@ -157,6 +157,11 @@ static struct dentry *__get_parent(struct super_block *sb,
|
||||
|
||||
req->r_num_caps = 1;
|
||||
err = ceph_mdsc_do_request(mdsc, NULL, req);
|
||||
if (err) {
|
||||
ceph_mdsc_put_request(req);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
inode = req->r_target_inode;
|
||||
if (inode)
|
||||
ihold(inode);
|
||||
|
||||
@@ -136,6 +136,49 @@ static void debug_print_tree(struct ext4_sb_info *sbi)
|
||||
printk(KERN_CONT "\n");
|
||||
}
|
||||
|
||||
static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
||||
struct ext4_map_blocks map;
|
||||
u32 i = 0, num;
|
||||
int err = 0, n;
|
||||
|
||||
if ((ino < EXT4_ROOT_INO) ||
|
||||
(ino > le32_to_cpu(sbi->s_es->s_inodes_count)))
|
||||
return -EINVAL;
|
||||
inode = ext4_iget(sb, ino, EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
num = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
|
||||
while (i < num) {
|
||||
map.m_lblk = i;
|
||||
map.m_len = num - i;
|
||||
n = ext4_map_blocks(NULL, inode, &map, 0);
|
||||
if (n < 0) {
|
||||
err = n;
|
||||
break;
|
||||
}
|
||||
if (n == 0) {
|
||||
i++;
|
||||
} else {
|
||||
if (!ext4_data_block_valid(sbi, map.m_pblk, n)) {
|
||||
ext4_error(sb, "blocks %llu-%llu from inode %u "
|
||||
"overlap system zone", map.m_pblk,
|
||||
map.m_pblk + map.m_len - 1, ino);
|
||||
err = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
err = add_system_zone(sbi, map.m_pblk, n);
|
||||
if (err < 0)
|
||||
break;
|
||||
i += n;
|
||||
}
|
||||
}
|
||||
iput(inode);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ext4_setup_system_zone(struct super_block *sb)
|
||||
{
|
||||
ext4_group_t ngroups = ext4_get_groups_count(sb);
|
||||
@@ -170,6 +213,12 @@ int ext4_setup_system_zone(struct super_block *sb)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (ext4_has_feature_journal(sb) && sbi->s_es->s_journal_inum) {
|
||||
ret = ext4_protect_reserved_inode(sb,
|
||||
le32_to_cpu(sbi->s_es->s_journal_inum));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (test_opt(sb, DEBUG))
|
||||
debug_print_tree(EXT4_SB(sb));
|
||||
@@ -226,6 +275,11 @@ int ext4_check_blockref(const char *function, unsigned int line,
|
||||
__le32 *bref = p;
|
||||
unsigned int blk;
|
||||
|
||||
if (ext4_has_feature_journal(inode->i_sb) &&
|
||||
(inode->i_ino ==
|
||||
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
||||
return 0;
|
||||
|
||||
while (bref < p+max) {
|
||||
blk = le32_to_cpu(*bref++);
|
||||
if (blk &&
|
||||
|
||||
@@ -2460,8 +2460,19 @@ int do_journal_get_write_access(handle_t *handle,
|
||||
#define FALL_BACK_TO_NONDELALLOC 1
|
||||
#define CONVERT_INLINE_DATA 2
|
||||
|
||||
extern struct inode *ext4_iget(struct super_block *, unsigned long);
|
||||
extern struct inode *ext4_iget_normal(struct super_block *, unsigned long);
|
||||
typedef enum {
|
||||
EXT4_IGET_NORMAL = 0,
|
||||
EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */
|
||||
EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */
|
||||
} ext4_iget_flags;
|
||||
|
||||
extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
|
||||
ext4_iget_flags flags, const char *function,
|
||||
unsigned int line);
|
||||
|
||||
#define ext4_iget(sb, ino, flags) \
|
||||
__ext4_iget((sb), (ino), (flags), __func__, __LINE__)
|
||||
|
||||
extern int ext4_write_inode(struct inode *, struct writeback_control *);
|
||||
extern int ext4_setattr(struct dentry *, struct iattr *);
|
||||
extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
|
||||
@@ -510,6 +510,30 @@ int ext4_ext_check_inode(struct inode *inode)
|
||||
return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode), 0);
|
||||
}
|
||||
|
||||
static void ext4_cache_extents(struct inode *inode,
|
||||
struct ext4_extent_header *eh)
|
||||
{
|
||||
struct ext4_extent *ex = EXT_FIRST_EXTENT(eh);
|
||||
ext4_lblk_t prev = 0;
|
||||
int i;
|
||||
|
||||
for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) {
|
||||
unsigned int status = EXTENT_STATUS_WRITTEN;
|
||||
ext4_lblk_t lblk = le32_to_cpu(ex->ee_block);
|
||||
int len = ext4_ext_get_actual_len(ex);
|
||||
|
||||
if (prev && (prev != lblk))
|
||||
ext4_es_cache_extent(inode, prev, lblk - prev, ~0,
|
||||
EXTENT_STATUS_HOLE);
|
||||
|
||||
if (ext4_ext_is_unwritten(ex))
|
||||
status = EXTENT_STATUS_UNWRITTEN;
|
||||
ext4_es_cache_extent(inode, lblk, len,
|
||||
ext4_ext_pblock(ex), status);
|
||||
prev = lblk + len;
|
||||
}
|
||||
}
|
||||
|
||||
static struct buffer_head *
|
||||
__read_extent_tree_block(const char *function, unsigned int line,
|
||||
struct inode *inode, ext4_fsblk_t pblk, int depth,
|
||||
@@ -530,36 +554,21 @@ __read_extent_tree_block(const char *function, unsigned int line,
|
||||
}
|
||||
if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE))
|
||||
return bh;
|
||||
err = __ext4_ext_check(function, line, inode,
|
||||
ext_block_hdr(bh), depth, pblk);
|
||||
if (err)
|
||||
goto errout;
|
||||
if (!ext4_has_feature_journal(inode->i_sb) ||
|
||||
(inode->i_ino !=
|
||||
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) {
|
||||
err = __ext4_ext_check(function, line, inode,
|
||||
ext_block_hdr(bh), depth, pblk);
|
||||
if (err)
|
||||
goto errout;
|
||||
}
|
||||
set_buffer_verified(bh);
|
||||
/*
|
||||
* If this is a leaf block, cache all of its entries
|
||||
*/
|
||||
if (!(flags & EXT4_EX_NOCACHE) && depth == 0) {
|
||||
struct ext4_extent_header *eh = ext_block_hdr(bh);
|
||||
struct ext4_extent *ex = EXT_FIRST_EXTENT(eh);
|
||||
ext4_lblk_t prev = 0;
|
||||
int i;
|
||||
|
||||
for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) {
|
||||
unsigned int status = EXTENT_STATUS_WRITTEN;
|
||||
ext4_lblk_t lblk = le32_to_cpu(ex->ee_block);
|
||||
int len = ext4_ext_get_actual_len(ex);
|
||||
|
||||
if (prev && (prev != lblk))
|
||||
ext4_es_cache_extent(inode, prev,
|
||||
lblk - prev, ~0,
|
||||
EXTENT_STATUS_HOLE);
|
||||
|
||||
if (ext4_ext_is_unwritten(ex))
|
||||
status = EXTENT_STATUS_UNWRITTEN;
|
||||
ext4_es_cache_extent(inode, lblk, len,
|
||||
ext4_ext_pblock(ex), status);
|
||||
prev = lblk + len;
|
||||
}
|
||||
ext4_cache_extents(inode, eh);
|
||||
}
|
||||
return bh;
|
||||
errout:
|
||||
@@ -907,6 +916,8 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
|
||||
path[0].p_bh = NULL;
|
||||
|
||||
i = depth;
|
||||
if (!(flags & EXT4_EX_NOCACHE) && depth == 0)
|
||||
ext4_cache_extents(inode, eh);
|
||||
/* walk through the tree */
|
||||
while (i) {
|
||||
ext_debug("depth %d: num %d, max %d\n",
|
||||
|
||||
@@ -1162,7 +1162,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
|
||||
if (!ext4_test_bit(bit, bitmap_bh->b_data))
|
||||
goto bad_orphan;
|
||||
|
||||
inode = ext4_iget(sb, ino);
|
||||
inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
|
||||
|
||||
@@ -375,6 +375,10 @@ static int __check_block_validity(struct inode *inode, const char *func,
|
||||
unsigned int line,
|
||||
struct ext4_map_blocks *map)
|
||||
{
|
||||
if (ext4_has_feature_journal(inode->i_sb) &&
|
||||
(inode->i_ino ==
|
||||
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
||||
return 0;
|
||||
if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk,
|
||||
map->m_len)) {
|
||||
ext4_error_inode(inode, func, line, map->m_pblk,
|
||||
@@ -4524,7 +4528,9 @@ int ext4_get_projid(struct inode *inode, kprojid_t *projid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
|
||||
ext4_iget_flags flags, const char *function,
|
||||
unsigned int line)
|
||||
{
|
||||
struct ext4_iloc iloc;
|
||||
struct ext4_inode *raw_inode;
|
||||
@@ -4538,6 +4544,18 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
gid_t i_gid;
|
||||
projid_t i_projid;
|
||||
|
||||
if (((flags & EXT4_IGET_NORMAL) &&
|
||||
(ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) ||
|
||||
(ino < EXT4_ROOT_INO) ||
|
||||
(ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) {
|
||||
if (flags & EXT4_IGET_HANDLE)
|
||||
return ERR_PTR(-ESTALE);
|
||||
__ext4_error(sb, function, line,
|
||||
"inode #%lu: comm %s: iget: illegal inode #",
|
||||
ino, current->comm);
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
}
|
||||
|
||||
inode = iget_locked(sb, ino);
|
||||
if (!inode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@@ -4553,11 +4571,18 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
raw_inode = ext4_raw_inode(&iloc);
|
||||
|
||||
if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
|
||||
EXT4_ERROR_INODE(inode, "root inode unallocated");
|
||||
ext4_error_inode(inode, function, line, 0,
|
||||
"iget: root inode unallocated");
|
||||
ret = -EFSCORRUPTED;
|
||||
goto bad_inode;
|
||||
}
|
||||
|
||||
if ((flags & EXT4_IGET_HANDLE) &&
|
||||
(raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) {
|
||||
ret = -ESTALE;
|
||||
goto bad_inode;
|
||||
}
|
||||
|
||||
if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
|
||||
ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
|
||||
if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
|
||||
@@ -4584,7 +4609,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
}
|
||||
|
||||
if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
|
||||
EXT4_ERROR_INODE(inode, "checksum invalid");
|
||||
ext4_error_inode(inode, function, line, 0,
|
||||
"iget: checksum invalid");
|
||||
ret = -EFSBADCRC;
|
||||
goto bad_inode;
|
||||
}
|
||||
@@ -4640,7 +4666,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
|
||||
inode->i_size = ext4_isize(raw_inode);
|
||||
if ((size = i_size_read(inode)) < 0) {
|
||||
EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size);
|
||||
ext4_error_inode(inode, function, line, 0,
|
||||
"iget: bad i_size value: %lld", size);
|
||||
ret = -EFSCORRUPTED;
|
||||
goto bad_inode;
|
||||
}
|
||||
@@ -4723,7 +4750,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
ret = 0;
|
||||
if (ei->i_file_acl &&
|
||||
!ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
|
||||
EXT4_ERROR_INODE(inode, "bad extended attribute block %llu",
|
||||
ext4_error_inode(inode, function, line, 0,
|
||||
"iget: bad extended attribute block %llu",
|
||||
ei->i_file_acl);
|
||||
ret = -EFSCORRUPTED;
|
||||
goto bad_inode;
|
||||
@@ -4778,7 +4806,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
make_bad_inode(inode);
|
||||
} else {
|
||||
ret = -EFSCORRUPTED;
|
||||
EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
|
||||
ext4_error_inode(inode, function, line, 0,
|
||||
"iget: bogus i_mode (%o)", inode->i_mode);
|
||||
goto bad_inode;
|
||||
}
|
||||
brelse(iloc.bh);
|
||||
@@ -4792,13 +4821,6 @@ bad_inode:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
return ext4_iget(sb, ino);
|
||||
}
|
||||
|
||||
static int ext4_inode_blocks_set(handle_t *handle,
|
||||
struct ext4_inode *raw_inode,
|
||||
struct ext4_inode_info *ei)
|
||||
|
||||
@@ -104,7 +104,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
|
||||
if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO);
|
||||
inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(inode_bl))
|
||||
return PTR_ERR(inode_bl);
|
||||
ei_bl = EXT4_I(inode_bl);
|
||||
|
||||
@@ -1944,7 +1944,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
|
||||
int free;
|
||||
|
||||
free = e4b->bd_info->bb_free;
|
||||
BUG_ON(free <= 0);
|
||||
if (WARN_ON(free <= 0))
|
||||
return;
|
||||
|
||||
i = e4b->bd_info->bb_first_free;
|
||||
|
||||
@@ -1965,7 +1966,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
|
||||
}
|
||||
|
||||
mb_find_extent(e4b, i, ac->ac_g_ex.fe_len, &ex);
|
||||
BUG_ON(ex.fe_len <= 0);
|
||||
if (WARN_ON(ex.fe_len <= 0))
|
||||
break;
|
||||
if (free < ex.fe_len) {
|
||||
ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
|
||||
"%d free clusters as per "
|
||||
|
||||
@@ -1586,7 +1586,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
|
||||
dentry);
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
}
|
||||
inode = ext4_iget_normal(dir->i_sb, ino);
|
||||
inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL);
|
||||
if (inode == ERR_PTR(-ESTALE)) {
|
||||
EXT4_ERROR_INODE(dir,
|
||||
"deleted inode referenced: %u",
|
||||
@@ -1628,7 +1628,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
}
|
||||
|
||||
return d_obtain_alias(ext4_iget_normal(child->d_sb, ino));
|
||||
return d_obtain_alias(ext4_iget(child->d_sb, ino, EXT4_IGET_NORMAL));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1649,7 +1649,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
|
||||
"No reserved GDT blocks, can't resize");
|
||||
return -EPERM;
|
||||
}
|
||||
inode = ext4_iget(sb, EXT4_RESIZE_INO);
|
||||
inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(inode)) {
|
||||
ext4_warning(sb, "Error opening resize inode");
|
||||
return PTR_ERR(inode);
|
||||
@@ -1977,7 +1977,8 @@ retry:
|
||||
}
|
||||
|
||||
if (!resize_inode)
|
||||
resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
|
||||
resize_inode = ext4_iget(sb, EXT4_RESIZE_INO,
|
||||
EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(resize_inode)) {
|
||||
ext4_warning(sb, "Error opening resize inode");
|
||||
return PTR_ERR(resize_inode);
|
||||
|
||||
@@ -1047,20 +1047,11 @@ static struct inode *ext4_nfs_get_inode(struct super_block *sb,
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
|
||||
return ERR_PTR(-ESTALE);
|
||||
if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))
|
||||
return ERR_PTR(-ESTALE);
|
||||
|
||||
/* iget isn't really right if the inode is currently unallocated!!
|
||||
*
|
||||
* ext4_read_inode will return a bad_inode if the inode had been
|
||||
* deleted, so we should be safe.
|
||||
*
|
||||
/*
|
||||
* Currently we don't know the generation for parent directory, so
|
||||
* a generation of 0 means "accept any"
|
||||
*/
|
||||
inode = ext4_iget_normal(sb, ino);
|
||||
inode = ext4_iget(sb, ino, EXT4_IGET_HANDLE);
|
||||
if (IS_ERR(inode))
|
||||
return ERR_CAST(inode);
|
||||
if (generation && inode->i_generation != generation) {
|
||||
@@ -3350,7 +3341,8 @@ int ext4_calculate_overhead(struct super_block *sb)
|
||||
*/
|
||||
if (sbi->s_journal && !sbi->journal_bdev)
|
||||
overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
|
||||
else if (ext4_has_feature_journal(sb) && !sbi->s_journal) {
|
||||
else if (ext4_has_feature_journal(sb) && !sbi->s_journal && j_inum) {
|
||||
/* j_inum for internal journal is non-zero */
|
||||
j_inode = ext4_get_journal_inode(sb, j_inum);
|
||||
if (j_inode) {
|
||||
j_blocks = j_inode->i_size >> sb->s_blocksize_bits;
|
||||
@@ -4201,7 +4193,7 @@ no_journal:
|
||||
* so we can safely mount the rest of the filesystem now.
|
||||
*/
|
||||
|
||||
root = ext4_iget(sb, EXT4_ROOT_INO);
|
||||
root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(root)) {
|
||||
ext4_msg(sb, KERN_ERR, "get root inode failed");
|
||||
ret = PTR_ERR(root);
|
||||
@@ -4448,7 +4440,7 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb,
|
||||
* happen if we iget() an unused inode, as the subsequent iput()
|
||||
* will try to delete it.
|
||||
*/
|
||||
journal_inode = ext4_iget(sb, journal_inum);
|
||||
journal_inode = ext4_iget(sb, journal_inum, EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(journal_inode)) {
|
||||
ext4_msg(sb, KERN_ERR, "no journal found");
|
||||
return NULL;
|
||||
@@ -5477,7 +5469,7 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
|
||||
if (!qf_inums[type])
|
||||
return -EPERM;
|
||||
|
||||
qf_inode = ext4_iget(sb, qf_inums[type]);
|
||||
qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL);
|
||||
if (IS_ERR(qf_inode)) {
|
||||
ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]);
|
||||
return PTR_ERR(qf_inode);
|
||||
|
||||
@@ -134,9 +134,13 @@ static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
|
||||
|
||||
static void fuse_drop_waiting(struct fuse_conn *fc)
|
||||
{
|
||||
if (fc->connected) {
|
||||
atomic_dec(&fc->num_waiting);
|
||||
} else if (atomic_dec_and_test(&fc->num_waiting)) {
|
||||
/*
|
||||
* lockess check of fc->connected is okay, because atomic_dec_and_test()
|
||||
* provides a memory barrier mached with the one in fuse_wait_aborted()
|
||||
* to ensure no wake-up is missed.
|
||||
*/
|
||||
if (atomic_dec_and_test(&fc->num_waiting) &&
|
||||
!READ_ONCE(fc->connected)) {
|
||||
/* wake up aborters */
|
||||
wake_up_all(&fc->blocked_waitq);
|
||||
}
|
||||
@@ -2174,6 +2178,8 @@ EXPORT_SYMBOL_GPL(fuse_abort_conn);
|
||||
|
||||
void fuse_wait_aborted(struct fuse_conn *fc)
|
||||
{
|
||||
/* matches implicit memory barrier in fuse_drop_waiting() */
|
||||
smp_mb();
|
||||
wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -3208,8 +3208,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||
/* make certain new is below the root */
|
||||
if (!is_path_reachable(new_mnt, new.dentry, &root))
|
||||
goto out4;
|
||||
root_mp->m_count++; /* pin it so it won't go away */
|
||||
lock_mount_hash();
|
||||
root_mp->m_count++; /* pin it so it won't go away */
|
||||
detach_mnt(new_mnt, &parent_path);
|
||||
detach_mnt(root_mnt, &root_parent);
|
||||
if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
|
||||
|
||||
@@ -246,6 +246,8 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
|
||||
if (!nbl) {
|
||||
nbl= kmalloc(sizeof(*nbl), GFP_KERNEL);
|
||||
if (nbl) {
|
||||
INIT_LIST_HEAD(&nbl->nbl_list);
|
||||
INIT_LIST_HEAD(&nbl->nbl_lru);
|
||||
fh_copy_shallow(&nbl->nbl_fh, fh);
|
||||
locks_init_lock(&nbl->nbl_lock);
|
||||
nfsd4_init_cb(&nbl->nbl_cb, lo->lo_owner.so_client,
|
||||
|
||||
@@ -268,14 +268,13 @@ static int propagate_one(struct mount *m)
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
child->mnt.mnt_flags &= ~MNT_LOCKED;
|
||||
read_seqlock_excl(&mount_lock);
|
||||
mnt_set_mountpoint(m, mp, child);
|
||||
if (m->mnt_master != dest_master)
|
||||
SET_MNT_MARK(m->mnt_master);
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
last_dest = m;
|
||||
last_source = child;
|
||||
if (m->mnt_master != dest_master) {
|
||||
read_seqlock_excl(&mount_lock);
|
||||
SET_MNT_MARK(m->mnt_master);
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
}
|
||||
hlist_add_head(&child->mnt_hash, list);
|
||||
return count_mounts(m->mnt_ns, child);
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ static int mmap_vmcore(struct file *file, struct vm_area_struct *vma)
|
||||
tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)start, size);
|
||||
kaddr = elfnotes_buf + start - elfcorebuf_sz;
|
||||
if (remap_vmalloc_range_partial(vma, vma->vm_start + len,
|
||||
kaddr, tsz))
|
||||
kaddr, 0, tsz))
|
||||
goto fail;
|
||||
size -= tsz;
|
||||
start += tsz;
|
||||
|
||||
@@ -1162,6 +1162,7 @@ xfs_reflink_remap_extent(
|
||||
uirec.br_startblock = irec->br_startblock + rlen;
|
||||
uirec.br_startoff = irec->br_startoff + rlen;
|
||||
uirec.br_blockcount = unmap_len - rlen;
|
||||
uirec.br_state = irec->br_state;
|
||||
unmap_len = rlen;
|
||||
|
||||
/* If this isn't a real mapping, we're done. */
|
||||
|
||||
@@ -914,7 +914,7 @@ search_memslots(struct kvm_memslots *slots, gfn_t gfn)
|
||||
start = slot + 1;
|
||||
}
|
||||
|
||||
if (gfn >= memslots[start].base_gfn &&
|
||||
if (start < slots->used_slots && gfn >= memslots[start].base_gfn &&
|
||||
gfn < memslots[start].base_gfn + memslots[start].npages) {
|
||||
atomic_set(&slots->lru_slot, start);
|
||||
return &memslots[start];
|
||||
|
||||
@@ -275,4 +275,35 @@ static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c)
|
||||
sizeof(*(p)->member) + __must_be_array((p)->member),\
|
||||
sizeof(*(p)))
|
||||
|
||||
/** check_shl_overflow() - Calculate a left-shifted value and check overflow
|
||||
*
|
||||
* @a: Value to be shifted
|
||||
* @s: How many bits left to shift
|
||||
* @d: Pointer to where to store the result
|
||||
*
|
||||
* Computes *@d = (@a << @s)
|
||||
*
|
||||
* Returns true if '*d' cannot hold the result or when 'a << s' doesn't
|
||||
* make sense. Example conditions:
|
||||
* - 'a << s' causes bits to be lost when stored in *d.
|
||||
* - 's' is garbage (e.g. negative) or so large that the result of
|
||||
* 'a << s' is guaranteed to be 0.
|
||||
* - 'a' is negative.
|
||||
* - 'a << s' sets the sign bit, if any, in '*d'.
|
||||
*
|
||||
* '*d' will hold the results of the attempted shift, but is not
|
||||
* considered "safe for use" if false is returned.
|
||||
*/
|
||||
#define check_shl_overflow(a, s, d) ({ \
|
||||
typeof(a) _a = a; \
|
||||
typeof(s) _s = s; \
|
||||
typeof(d) _d = d; \
|
||||
u64 _a_full = _a; \
|
||||
unsigned int _to_shift = \
|
||||
_s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \
|
||||
*_d = (_a_full << _to_shift); \
|
||||
(_to_shift != _s || *_d < 0 || _a < 0 || \
|
||||
(*_d >> _to_shift) != _a); \
|
||||
})
|
||||
|
||||
#endif /* __LINUX_OVERFLOW_H */
|
||||
|
||||
@@ -89,7 +89,7 @@ extern void vunmap(const void *addr);
|
||||
|
||||
extern int remap_vmalloc_range_partial(struct vm_area_struct *vma,
|
||||
unsigned long uaddr, void *kaddr,
|
||||
unsigned long size);
|
||||
unsigned long pgoff, unsigned long size);
|
||||
|
||||
extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
|
||||
unsigned long pgoff);
|
||||
|
||||
@@ -51,7 +51,7 @@ extern struct inet_hashinfo tcp_hashinfo;
|
||||
extern struct percpu_counter tcp_orphan_count;
|
||||
void tcp_time_wait(struct sock *sk, int state, int timeo);
|
||||
|
||||
#define MAX_TCP_HEADER (128 + MAX_HEADER)
|
||||
#define MAX_TCP_HEADER L1_CACHE_ALIGN(128 + MAX_HEADER)
|
||||
#define MAX_TCP_OPTION_SPACE 40
|
||||
#define TCP_MIN_SND_MSS 48
|
||||
#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE)
|
||||
|
||||
@@ -751,13 +751,13 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
|
||||
total++;
|
||||
}
|
||||
|
||||
*new_pos = pos + 1;
|
||||
if (total >= ids->in_use)
|
||||
return NULL;
|
||||
|
||||
for (; pos < IPCMNI; pos++) {
|
||||
ipc = idr_find(&ids->ipcs_idr, pos);
|
||||
if (ipc != NULL) {
|
||||
*new_pos = pos + 1;
|
||||
rcu_read_lock();
|
||||
ipc_lock_object(ipc);
|
||||
return ipc;
|
||||
|
||||
@@ -941,6 +941,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
|
||||
if (!audit_enabled && msg_type != AUDIT_USER_AVC)
|
||||
return 0;
|
||||
/* exit early if there isn't at least one character to print */
|
||||
if (data_len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
err = audit_filter(msg_type, AUDIT_FILTER_USER);
|
||||
if (err == 1) { /* match or error */
|
||||
|
||||
@@ -6436,10 +6436,17 @@ static void perf_event_task_output(struct perf_event *event,
|
||||
goto out;
|
||||
|
||||
task_event->event_id.pid = perf_event_pid(event, task);
|
||||
task_event->event_id.ppid = perf_event_pid(event, current);
|
||||
|
||||
task_event->event_id.tid = perf_event_tid(event, task);
|
||||
task_event->event_id.ptid = perf_event_tid(event, current);
|
||||
|
||||
if (task_event->event_id.header.type == PERF_RECORD_EXIT) {
|
||||
task_event->event_id.ppid = perf_event_pid(event,
|
||||
task->real_parent);
|
||||
task_event->event_id.ptid = perf_event_pid(event,
|
||||
task->real_parent);
|
||||
} else { /* PERF_RECORD_FORK */
|
||||
task_event->event_id.ppid = perf_event_pid(event, current);
|
||||
task_event->event_id.ptid = perf_event_tid(event, current);
|
||||
}
|
||||
|
||||
task_event->event_id.time = perf_event_clock(event);
|
||||
|
||||
|
||||
@@ -108,9 +108,9 @@ static void *gcov_seq_next(struct seq_file *seq, void *data, loff_t *pos)
|
||||
{
|
||||
struct gcov_iterator *iter = data;
|
||||
|
||||
(*pos)++;
|
||||
if (gcov_iter_next(iter))
|
||||
return NULL;
|
||||
(*pos)++;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
16
mm/vmalloc.c
16
mm/vmalloc.c
@@ -31,6 +31,7 @@
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/llist.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/tlbflush.h>
|
||||
@@ -2173,6 +2174,7 @@ finished:
|
||||
* @vma: vma to cover
|
||||
* @uaddr: target user address to start at
|
||||
* @kaddr: virtual address of vmalloc kernel memory
|
||||
* @pgoff: offset from @kaddr to start at
|
||||
* @size: size of map area
|
||||
*
|
||||
* Returns: 0 for success, -Exxx on failure
|
||||
@@ -2185,9 +2187,15 @@ finished:
|
||||
* Similar to remap_pfn_range() (see mm/memory.c)
|
||||
*/
|
||||
int remap_vmalloc_range_partial(struct vm_area_struct *vma, unsigned long uaddr,
|
||||
void *kaddr, unsigned long size)
|
||||
void *kaddr, unsigned long pgoff,
|
||||
unsigned long size)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
unsigned long off;
|
||||
unsigned long end_index;
|
||||
|
||||
if (check_shl_overflow(pgoff, PAGE_SHIFT, &off))
|
||||
return -EINVAL;
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
@@ -2201,8 +2209,10 @@ int remap_vmalloc_range_partial(struct vm_area_struct *vma, unsigned long uaddr,
|
||||
if (!(area->flags & VM_USERMAP))
|
||||
return -EINVAL;
|
||||
|
||||
if (kaddr + size > area->addr + get_vm_area_size(area))
|
||||
if (check_add_overflow(size, off, &end_index) ||
|
||||
end_index > get_vm_area_size(area))
|
||||
return -EINVAL;
|
||||
kaddr += off;
|
||||
|
||||
do {
|
||||
struct page *page = vmalloc_to_page(kaddr);
|
||||
@@ -2241,7 +2251,7 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
|
||||
unsigned long pgoff)
|
||||
{
|
||||
return remap_vmalloc_range_partial(vma, vma->vm_start,
|
||||
addr + (pgoff << PAGE_SHIFT),
|
||||
addr, pgoff,
|
||||
vma->vm_end - vma->vm_start);
|
||||
}
|
||||
EXPORT_SYMBOL(remap_vmalloc_range);
|
||||
|
||||
@@ -696,10 +696,8 @@ static int __init vti_init(void)
|
||||
|
||||
msg = "ipip tunnel";
|
||||
err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
|
||||
if (err < 0) {
|
||||
pr_info("%s: cant't register tunnel\n",__func__);
|
||||
if (err < 0)
|
||||
goto xfrm_tunnel_failed;
|
||||
}
|
||||
|
||||
msg = "netlink interface";
|
||||
err = rtnl_link_register(&vti_link_ops);
|
||||
|
||||
@@ -509,9 +509,11 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
goto out;
|
||||
|
||||
/* hdrincl should be READ_ONCE(inet->hdrincl)
|
||||
* but READ_ONCE() doesn't work with bit fields
|
||||
* but READ_ONCE() doesn't work with bit fields.
|
||||
* Doing this indirectly yields the same result.
|
||||
*/
|
||||
hdrincl = inet->hdrincl;
|
||||
hdrincl = READ_ONCE(hdrincl);
|
||||
/*
|
||||
* Check the flags.
|
||||
*/
|
||||
|
||||
@@ -131,8 +131,6 @@ static int ip_rt_min_advmss __read_mostly = 256;
|
||||
|
||||
static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT;
|
||||
|
||||
static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU;
|
||||
|
||||
/*
|
||||
* Interface to generic destination cache.
|
||||
*/
|
||||
@@ -2730,6 +2728,7 @@ void ip_rt_multicast_event(struct in_device *in_dev)
|
||||
static int ip_rt_gc_interval __read_mostly = 60 * HZ;
|
||||
static int ip_rt_gc_min_interval __read_mostly = HZ / 2;
|
||||
static int ip_rt_gc_elasticity __read_mostly = 8;
|
||||
static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU;
|
||||
|
||||
static int ipv4_sysctl_rtcache_flush(struct ctl_table *__ctl, int write,
|
||||
void __user *buffer,
|
||||
|
||||
@@ -75,9 +75,7 @@ int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
|
||||
#ifdef CONFIG_NETFILTER
|
||||
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
|
||||
#endif
|
||||
|
||||
return xfrm_output(sk, skb);
|
||||
}
|
||||
|
||||
@@ -184,15 +184,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
retv = -EBUSY;
|
||||
break;
|
||||
}
|
||||
} else if (sk->sk_protocol == IPPROTO_TCP) {
|
||||
if (sk->sk_prot != &tcpv6_prot) {
|
||||
retv = -EBUSY;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
if (sk->sk_protocol == IPPROTO_TCP &&
|
||||
sk->sk_prot != &tcpv6_prot) {
|
||||
retv = -EBUSY;
|
||||
break;
|
||||
}
|
||||
if (sk->sk_protocol != IPPROTO_TCP)
|
||||
break;
|
||||
if (sk->sk_state != TCP_ESTABLISHED) {
|
||||
retv = -ENOTCONN;
|
||||
break;
|
||||
|
||||
@@ -125,9 +125,7 @@ int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
|
||||
#ifdef CONFIG_NETFILTER
|
||||
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
|
||||
#endif
|
||||
|
||||
return xfrm_output(sk, skb);
|
||||
}
|
||||
|
||||
@@ -199,6 +199,7 @@ static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
|
||||
/* refcount initialized at 1 */
|
||||
spin_unlock_bh(&nr_node_list_lock);
|
||||
|
||||
nr_neigh_put(nr_neigh);
|
||||
return 0;
|
||||
}
|
||||
nr_node_lock(nr_node);
|
||||
|
||||
@@ -120,8 +120,10 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (!pskb_may_pull(skb, 1))
|
||||
if (!pskb_may_pull(skb, 1)) {
|
||||
x25_neigh_put(nb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (skb->data[0]) {
|
||||
|
||||
|
||||
@@ -1967,7 +1967,6 @@ static const struct hdac_io_ops pci_hda_io_ops = {
|
||||
* should be ignored from the beginning.
|
||||
*/
|
||||
static const struct snd_pci_quirk driver_blacklist[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x874f, "ASUS ROG Zenith II / Strix", 0),
|
||||
SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0),
|
||||
SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0),
|
||||
{}
|
||||
|
||||
@@ -976,7 +976,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w,
|
||||
dev_dbg(c->dev, "Enter: widget=%s\n", w->name);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
mutex_lock(&drv->lock);
|
||||
ret = sst_send_slot_map(drv);
|
||||
mutex_unlock(&drv->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = sst_send_pipe_module_params(w, k);
|
||||
|
||||
@@ -384,7 +384,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
|
||||
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.reg = e->reg;
|
||||
template.mask = e->mask << e->shift_l;
|
||||
template.mask = e->mask;
|
||||
template.shift = e->shift_l;
|
||||
template.off_val = snd_soc_enum_item_to_val(e, 0);
|
||||
template.on_val = template.off_val;
|
||||
@@ -510,8 +510,22 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
|
||||
if (data->value == value)
|
||||
return false;
|
||||
|
||||
if (data->widget)
|
||||
data->widget->on_val = value;
|
||||
if (data->widget) {
|
||||
switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) {
|
||||
case snd_soc_dapm_switch:
|
||||
case snd_soc_dapm_mixer:
|
||||
case snd_soc_dapm_mixer_named_ctl:
|
||||
data->widget->on_val = value & data->widget->mask;
|
||||
break;
|
||||
case snd_soc_dapm_demux:
|
||||
case snd_soc_dapm_mux:
|
||||
data->widget->on_val = value >> data->widget->shift;
|
||||
break;
|
||||
default:
|
||||
data->widget->on_val = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data->value = value;
|
||||
|
||||
|
||||
@@ -220,6 +220,52 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Many Focusrite devices supports a limited set of sampling rates per
|
||||
* altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
|
||||
* descriptor which has a non-standard bLength = 10.
|
||||
*/
|
||||
static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
|
||||
struct audioformat *fp,
|
||||
unsigned int rate)
|
||||
{
|
||||
struct usb_interface *iface;
|
||||
struct usb_host_interface *alts;
|
||||
unsigned char *fmt;
|
||||
unsigned int max_rate;
|
||||
|
||||
iface = usb_ifnum_to_if(chip->dev, fp->iface);
|
||||
if (!iface)
|
||||
return true;
|
||||
|
||||
alts = &iface->altsetting[fp->altset_idx];
|
||||
fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen,
|
||||
NULL, UAC_FORMAT_TYPE);
|
||||
if (!fmt)
|
||||
return true;
|
||||
|
||||
if (fmt[0] == 10) { /* bLength */
|
||||
max_rate = combine_quad(&fmt[6]);
|
||||
|
||||
/* Validate max rate */
|
||||
if (max_rate != 48000 &&
|
||||
max_rate != 96000 &&
|
||||
max_rate != 192000 &&
|
||||
max_rate != 384000) {
|
||||
|
||||
usb_audio_info(chip,
|
||||
"%u:%d : unexpected max rate: %u\n",
|
||||
fp->iface, fp->altsetting, max_rate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return rate <= max_rate;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to walk the array of sample rate triplets reported by
|
||||
* the device. The problem is that we need to parse whole array first to
|
||||
@@ -256,6 +302,11 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
|
||||
}
|
||||
|
||||
for (rate = min; rate <= max; rate += res) {
|
||||
/* Filter out invalid rates on Focusrite devices */
|
||||
if (USB_ID_VENDOR(chip->usb_id) == 0x1235 &&
|
||||
!focusrite_valid_sample_rate(chip, fp, rate))
|
||||
goto skip_rate;
|
||||
|
||||
if (fp->rate_table)
|
||||
fp->rate_table[nr_rates] = rate;
|
||||
if (!fp->rate_min || rate < fp->rate_min)
|
||||
@@ -270,6 +321,7 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
|
||||
break;
|
||||
}
|
||||
|
||||
skip_rate:
|
||||
/* avoid endless loop */
|
||||
if (res == 0)
|
||||
break;
|
||||
|
||||
@@ -1519,11 +1519,15 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
|
||||
|
||||
/* use known values for that card: interface#1 altsetting#1 */
|
||||
iface = usb_ifnum_to_if(chip->dev, 1);
|
||||
if (!iface || iface->num_altsetting < 2)
|
||||
return -EINVAL;
|
||||
if (!iface || iface->num_altsetting < 2) {
|
||||
err = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
alts = &iface->altsetting[1];
|
||||
if (get_iface_desc(alts)->bNumEndpoints < 1)
|
||||
return -EINVAL;
|
||||
if (get_iface_desc(alts)->bNumEndpoints < 1) {
|
||||
err = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
ep = get_endpoint(alts, 0)->bEndpointAddress;
|
||||
|
||||
err = snd_usb_ctl_msg(chip->dev,
|
||||
|
||||
@@ -691,6 +691,8 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
|
||||
us->submitted = 2*NOOF_SETRATE_URBS;
|
||||
for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
|
||||
struct urb *urb = us->urb[i];
|
||||
if (!urb)
|
||||
continue;
|
||||
if (urb->status) {
|
||||
if (!err)
|
||||
err = -ENODEV;
|
||||
|
||||
@@ -2035,14 +2035,27 @@ static bool ignore_unreachable_insn(struct instruction *insn)
|
||||
!strcmp(insn->sec->name, ".altinstr_aux"))
|
||||
return true;
|
||||
|
||||
if (!insn->func)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* CONFIG_UBSAN_TRAP inserts a UD2 when it sees
|
||||
* __builtin_unreachable(). The BUG() macro has an unreachable() after
|
||||
* the UD2, which causes GCC's undefined trap logic to emit another UD2
|
||||
* (or occasionally a JMP to UD2).
|
||||
*/
|
||||
if (list_prev_entry(insn, list)->dead_end &&
|
||||
(insn->type == INSN_BUG ||
|
||||
(insn->type == INSN_JUMP_UNCONDITIONAL &&
|
||||
insn->jump_dest && insn->jump_dest->type == INSN_BUG)))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Check if this (or a subsequent) instruction is related to
|
||||
* CONFIG_UBSAN or CONFIG_KASAN.
|
||||
*
|
||||
* End the search at 5 instructions to avoid going into the weeds.
|
||||
*/
|
||||
if (!insn->func)
|
||||
return false;
|
||||
for (i = 0; i < 5; i++) {
|
||||
|
||||
if (is_kasan_insn(insn) || is_ubsan_insn(insn))
|
||||
|
||||
@@ -78,7 +78,7 @@ int orc_dump(const char *_objname)
|
||||
char *name;
|
||||
size_t nr_sections;
|
||||
Elf64_Addr orc_ip_addr = 0;
|
||||
size_t shstrtab_idx;
|
||||
size_t shstrtab_idx, strtab_idx = 0;
|
||||
Elf *elf;
|
||||
Elf_Scn *scn;
|
||||
GElf_Shdr sh;
|
||||
@@ -139,6 +139,8 @@ int orc_dump(const char *_objname)
|
||||
|
||||
if (!strcmp(name, ".symtab")) {
|
||||
symtab = data;
|
||||
} else if (!strcmp(name, ".strtab")) {
|
||||
strtab_idx = i;
|
||||
} else if (!strcmp(name, ".orc_unwind")) {
|
||||
orc = data->d_buf;
|
||||
orc_size = sh.sh_size;
|
||||
@@ -150,7 +152,7 @@ int orc_dump(const char *_objname)
|
||||
}
|
||||
}
|
||||
|
||||
if (!symtab || !orc || !orc_ip)
|
||||
if (!symtab || !strtab_idx || !orc || !orc_ip)
|
||||
return 0;
|
||||
|
||||
if (orc_size % sizeof(*orc) != 0) {
|
||||
@@ -171,21 +173,29 @@ int orc_dump(const char *_objname)
|
||||
return -1;
|
||||
}
|
||||
|
||||
scn = elf_getscn(elf, sym.st_shndx);
|
||||
if (!scn) {
|
||||
WARN_ELF("elf_getscn");
|
||||
return -1;
|
||||
}
|
||||
if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) {
|
||||
scn = elf_getscn(elf, sym.st_shndx);
|
||||
if (!scn) {
|
||||
WARN_ELF("elf_getscn");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!gelf_getshdr(scn, &sh)) {
|
||||
WARN_ELF("gelf_getshdr");
|
||||
return -1;
|
||||
}
|
||||
if (!gelf_getshdr(scn, &sh)) {
|
||||
WARN_ELF("gelf_getshdr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
|
||||
if (!name || !*name) {
|
||||
WARN_ELF("elf_strptr");
|
||||
return -1;
|
||||
name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
|
||||
if (!name) {
|
||||
WARN_ELF("elf_strptr");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
name = elf_strptr(elf, strtab_idx, sym.st_name);
|
||||
if (!name) {
|
||||
WARN_ELF("elf_strptr");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s+%llx:", name, (unsigned long long)rela.r_addend);
|
||||
|
||||
Reference in New Issue
Block a user