This is the 4.4.68 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlkYQIMACgkQONu9yGCS
 aT6lQRAAx+GV9h6oAE5s6ehb/soIXrgvq/veRM52HRpECKvNOjp8p7rf2V9jLKy4
 HV/6n5Q7CClHgKkyfSvFput6iMzzzJWHl2cCFwiZ3e7eq3yCzIV4+Px0CD9SH5S7
 ukYSdmR5zU5oOoMvbW9op1GlUvyNlCtBqWLkXAhopyAuFG7aqvjprPRoJXNVsDqy
 QooRFbGilztrLTKXvnKlz2y0CDxrrHERRdVwRCpzeOpN0rEDoJfdNO6IoXph5vDj
 T2ZWH8WmL+2RPDUFA3fQ2pRKSZribk7Bw4BUDZGNKnXYGSwBWS4r0+1UkCyXGRda
 gLLajv0EIciXvNglkvZ6mzlCcucyJu1mhjFwh778HlFdzvgayxaXQMqFN72OPF8K
 SRsEZnBs4QiflLf4kI9WjiIBAL2uIrP6p9dFq8yHs5yEzRWGtXyODfFYRBnhW7ka
 KbJ47j+MMYvjyu82W+Zzw7qKFXluzLdQKzmY1HUiqegQEtwqjDr/jOL+uC0CkSBb
 OWSmo9/JZUcKn40epenP+ojgDkhJVoKeN5Cy1vWeDUV1pWjK+ErZ5GQZ9F9fNuvV
 MNaFjgQy+bZ4MQ1TgetZzvDKVnNHvuDwKKX6yIK1PHSMsBI4f7M1KLfwDi5WeUmg
 BeF3wDSQEhLGFhiwn3UzhK6VGjfaRsXXv8AhrELrgpnhWkZkg/A=
 =czqa
 -----END PGP SIGNATURE-----

Merge 4.4.68 into android-4.4

Changes in 4.4.68
	9p: fix a potential acl leak
	ARM: 8452/3: PJ4: make coprocessor access sequences buildable in Thumb2 mode
	cpupower: Fix turbo frequency reporting for pre-Sandy Bridge cores
	powerpc/powernv: Fix opal_exit tracepoint opcode
	power: supply: bq24190_charger: Fix irq trigger to IRQF_TRIGGER_FALLING
	power: supply: bq24190_charger: Call set_mode_host() on pm_resume()
	power: supply: bq24190_charger: Install irq_handler_thread() at end of probe()
	power: supply: bq24190_charger: Call power_supply_changed() for relevant component
	power: supply: bq24190_charger: Don't read fault register outside irq_handle_thread()
	power: supply: bq24190_charger: Handle fault before status on interrupt
	leds: ktd2692: avoid harmless maybe-uninitialized warning
	ARM: OMAP5 / DRA7: Fix HYP mode boot for thumb2 build
	mwifiex: debugfs: Fix (sometimes) off-by-1 SSID print
	mwifiex: remove redundant dma padding in AMSDU
	mwifiex: Avoid skipping WEP key deletion for AP
	x86/ioapic: Restore IO-APIC irq_chip retrigger callback
	x86/pci-calgary: Fix iommu_free() comparison of unsigned expression >= 0
	clk: Make x86/ conditional on CONFIG_COMMON_CLK
	kprobes/x86: Fix kernel panic when certain exception-handling addresses are probed
	x86/platform/intel-mid: Correct MSI IRQ line for watchdog device
	Revert "KVM: nested VMX: disable perf cpuid reporting"
	KVM: nVMX: initialize PML fields in vmcs02
	KVM: nVMX: do not leak PML full vmexit to L1
	usb: host: ehci-exynos: Decrese node refcount on exynos_ehci_get_phy() error paths
	usb: host: ohci-exynos: Decrese node refcount on exynos_ehci_get_phy() error paths
	usb: chipidea: Only read/write OTGSC from one place
	usb: chipidea: Handle extcon events properly
	USB: serial: keyspan_pda: fix receive sanity checks
	USB: serial: digi_acceleport: fix incomplete rx sanity check
	USB: serial: ssu100: fix control-message error handling
	USB: serial: io_edgeport: fix epic-descriptor handling
	USB: serial: ti_usb_3410_5052: fix control-message error handling
	USB: serial: ark3116: fix open error handling
	USB: serial: ftdi_sio: fix latency-timer error handling
	USB: serial: quatech2: fix control-message error handling
	USB: serial: mct_u232: fix modem-status error handling
	USB: serial: io_edgeport: fix descriptor error handling
	phy: qcom-usb-hs: Add depends on EXTCON
	serial: 8250_omap: Fix probe and remove for PM runtime
	scsi: mac_scsi: Fix MAC_SCSI=m option when SCSI=m
	MIPS: R2-on-R6 MULTU/MADDU/MSUBU emulation bugfix
	brcmfmac: Ensure pointer correctly set if skb data location changes
	brcmfmac: Make skb header writable before use
	staging: wlan-ng: add missing byte order conversion
	staging: emxx_udc: remove incorrect __init annotations
	ALSA: hda - Fix deadlock of controller device lock at unbinding
	tcp: do not underestimate skb->truesize in tcp_trim_head()
	bpf, arm64: fix jit branch offset related to ldimm64
	tcp: fix wraparound issue in tcp_lp
	tcp: do not inherit fastopen_req from parent
	ipv4, ipv6: ensure raw socket message is big enough to hold an IP header
	rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string
	ipv6: initialize route null entry in addrconf_init()
	ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
	bnxt_en: allocate enough space for ->ntp_fltr_bmap
	f2fs: sanity check segment count
	drm/ttm: fix use-after-free races in vm fault handling
	block: get rid of blk_integrity_revalidate()
	Linux 4.4.68

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2017-05-15 09:25:05 +02:00
commit 285c13770a
63 changed files with 511 additions and 335 deletions

View file

@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
SUBLEVEL = 67
SUBLEVEL = 68
EXTRAVERSION =
NAME = Blurry Fish Butt

View file

@ -73,7 +73,6 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \
perf_event_v7.o
CFLAGS_pj4-cp0.o := -marm
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_VDSO) += vdso.o

View file

@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
__asm__ __volatile__ (
"mcr p15, 0, %1, c1, c0, 2\n\t"
#ifdef CONFIG_THUMB2_KERNEL
"isb\n\t"
#else
"mrc p15, 0, %0, c1, c0, 2\n\t"
"mov %0, %0\n\t"
"sub pc, pc, #4\n\t"
#endif
: "=r" (temp) : "r" (value));
}

View file

@ -17,6 +17,7 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
#include "omap44xx.h"
@ -56,7 +57,7 @@ wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
cmp r0, r4
bne wait_2
ldr r12, =API_HYP_ENTRY
adr r0, hyp_boot
badr r0, hyp_boot
smc #0
hyp_boot:
b secondary_startup

View file

@ -728,14 +728,14 @@ static int build_body(struct jit_ctx *ctx)
int ret;
ret = build_insn(insn, ctx);
if (ctx->image == NULL)
ctx->offset[i] = ctx->idx;
if (ret > 0) {
i++;
if (ctx->image == NULL)
ctx->offset[i] = ctx->idx;
continue;
}
if (ctx->image == NULL)
ctx->offset[i] = ctx->idx;
if (ret)
return ret;
}

View file

@ -434,8 +434,8 @@ static int multu_func(struct pt_regs *regs, u32 ir)
rs = regs->regs[MIPSInst_RS(ir)];
res = (u64)rt * (u64)rs;
rt = res;
regs->lo = (s64)rt;
regs->hi = (s64)(res >> 32);
regs->lo = (s64)(s32)rt;
regs->hi = (s64)(s32)(res >> 32);
MIPS_R2_STATS(muls);
@ -671,9 +671,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir)
res += ((((s64)rt) << 32) | (u32)rs);
rt = res;
regs->lo = (s64)rt;
regs->lo = (s64)(s32)rt;
rs = res >> 32;
regs->hi = (s64)rs;
regs->hi = (s64)(s32)rs;
MIPS_R2_STATS(dsps);
@ -729,9 +729,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir)
res = ((((s64)rt) << 32) | (u32)rs) - res;
rt = res;
regs->lo = (s64)rt;
regs->lo = (s64)(s32)rt;
rs = res >> 32;
regs->hi = (s64)rs;
regs->hi = (s64)(s32)rs;
MIPS_R2_STATS(dsps);

View file

@ -148,7 +148,7 @@ opal_tracepoint_entry:
opal_tracepoint_return:
std r3,STK_REG(R31)(r1)
mr r4,r3
ld r0,STK_REG(R23)(r1)
ld r3,STK_REG(R23)(r1)
bl __trace_opal_exit
ld r3,STK_REG(R31)(r1)
addi r1,r1,STACKFRAMESIZE

View file

@ -1875,6 +1875,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
.irq_ack = irq_chip_ack_parent,
.irq_eoi = ioapic_ack_level,
.irq_set_affinity = ioapic_set_affinity,
.irq_retrigger = irq_chip_retrigger_hierarchy,
.flags = IRQCHIP_SKIP_SET_WAKE,
};
@ -1886,6 +1887,7 @@ static struct irq_chip ioapic_ir_chip __read_mostly = {
.irq_ack = irq_chip_ack_parent,
.irq_eoi = ioapic_ir_ack_level,
.irq_set_affinity = ioapic_set_affinity,
.irq_retrigger = irq_chip_retrigger_hierarchy,
.flags = IRQCHIP_SKIP_SET_WAKE,
};

View file

@ -67,7 +67,7 @@
#endif
/* Ensure if the instruction can be boostable */
extern int can_boost(kprobe_opcode_t *instruction);
extern int can_boost(kprobe_opcode_t *instruction, void *addr);
/* Recover instruction if given address is probed */
extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
unsigned long addr);

View file

@ -163,12 +163,12 @@ NOKPROBE_SYMBOL(skip_prefixes);
* Returns non-zero if opcode is boostable.
* RIP relative instructions are adjusted at copying time in 64 bits mode
*/
int can_boost(kprobe_opcode_t *opcodes)
int can_boost(kprobe_opcode_t *opcodes, void *addr)
{
kprobe_opcode_t opcode;
kprobe_opcode_t *orig_opcodes = opcodes;
if (search_exception_tables((unsigned long)opcodes))
if (search_exception_tables((unsigned long)addr))
return 0; /* Page fault may occur on this address. */
retry:
@ -413,7 +413,7 @@ static int arch_copy_kprobe(struct kprobe *p)
* __copy_instruction can modify the displacement of the instruction,
* but it doesn't affect boostable check.
*/
if (can_boost(p->ainsn.insn))
if (can_boost(p->ainsn.insn, p->addr))
p->ainsn.boostable = 0;
else
p->ainsn.boostable = -1;

View file

@ -177,7 +177,7 @@ static int copy_optimized_instructions(u8 *dest, u8 *src)
while (len < RELATIVEJUMP_SIZE) {
ret = __copy_instruction(dest + len, src + len);
if (!ret || !can_boost(dest + len))
if (!ret || !can_boost(dest + len, src + len))
return -EINVAL;
len += ret;
}

View file

@ -296,7 +296,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
/* were we called with bad_dma_address? */
badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
if (unlikely(dma_addr < badend)) {
WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
"address 0x%Lx\n", dma_addr);
return;

View file

@ -818,12 +818,6 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
if (!best)
best = check_cpuid_limit(vcpu, function, index);
/*
* Perfmon not yet supported for L2 guest.
*/
if (is_guest_mode(vcpu) && function == 0xa)
best = NULL;
if (best) {
*eax = best->eax;
*ebx = best->ebx;

View file

@ -7754,8 +7754,6 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
case EXIT_REASON_TASK_SWITCH:
return true;
case EXIT_REASON_CPUID:
if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa)
return false;
return true;
case EXIT_REASON_HLT:
return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING);
@ -7840,6 +7838,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES);
case EXIT_REASON_PCOMMIT:
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_PCOMMIT);
case EXIT_REASON_PML_FULL:
/* We don't expose PML support to L1. */
return false;
default:
return true;
}
@ -9759,6 +9760,18 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
}
if (enable_pml) {
/*
* Conceptually we want to copy the PML address and index from
* vmcs01 here, and then back to vmcs01 on nested vmexit. But,
* since we always flush the log on each vmexit, this happens
* to be equivalent to simply resetting the fields in vmcs02.
*/
ASSERT(vmx->pml_pg);
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
}
if (nested_cpu_has_ept(vmcs12)) {
kvm_mmu_unload(vcpu);
nested_ept_init_mmu_context(vcpu);

View file

@ -17,7 +17,7 @@
#include <asm/intel-mid.h>
#include <asm/io_apic.h>
#define TANGIER_EXT_TIMER0_MSI 15
#define TANGIER_EXT_TIMER0_MSI 12
static struct platform_device wdt_dev = {
.name = "intel_mid_wdt",

View file

@ -417,7 +417,7 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
bi->tuple_size = template->tuple_size;
bi->tag_size = template->tag_size;
blk_integrity_revalidate(disk);
disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
}
EXPORT_SYMBOL(blk_integrity_register);
@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register);
*/
void blk_integrity_unregister(struct gendisk *disk)
{
blk_integrity_revalidate(disk);
disk->queue->backing_dev_info.capabilities &= ~BDI_CAP_STABLE_WRITES;
memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
}
EXPORT_SYMBOL(blk_integrity_unregister);
void blk_integrity_revalidate(struct gendisk *disk)
{
struct blk_integrity *bi = &disk->queue->integrity;
if (!(disk->flags & GENHD_FL_UP))
return;
if (bi->profile)
disk->queue->backing_dev_info.capabilities |=
BDI_CAP_STABLE_WRITES;
else
disk->queue->backing_dev_info.capabilities &=
~BDI_CAP_STABLE_WRITES;
}
void blk_integrity_add(struct gendisk *disk)
{
if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,

View file

@ -446,7 +446,6 @@ rescan:
if (disk->fops->revalidate_disk)
disk->fops->revalidate_disk(disk);
blk_integrity_revalidate(disk);
check_disk_size_change(disk, bdev);
bdev->bd_invalidated = 0;
if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))

View file

@ -78,7 +78,9 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_X86) += x86/
endif
obj-$(CONFIG_ARCH_ZX) += zte/
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
obj-$(CONFIG_H8300) += h8300/

View file

@ -66,8 +66,11 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
goto out_unlock;
ttm_bo_reference(bo);
up_read(&vma->vm_mm->mmap_sem);
(void) ttm_bo_wait(bo, false, true, false);
ttm_bo_unreserve(bo);
ttm_bo_unref(&bo);
goto out_unlock;
}
@ -114,8 +117,10 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
ttm_bo_reference(bo);
up_read(&vma->vm_mm->mmap_sem);
(void) ttm_bo_wait_unreserved(bo);
ttm_bo_unref(&bo);
}
return VM_FAULT_RETRY;
@ -160,6 +165,13 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
if (unlikely(ret != 0)) {
retval = ret;
if (retval == VM_FAULT_RETRY &&
!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
/* The BO has already been unreserved. */
return retval;
}
goto out_unlock;
}

View file

@ -296,15 +296,15 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
return -ENXIO;
led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);
if (IS_ERR(led->ctrl_gpio)) {
ret = PTR_ERR(led->ctrl_gpio);
ret = PTR_ERR_OR_ZERO(led->ctrl_gpio);
if (ret) {
dev_err(dev, "cannot get ctrl-gpios %d\n", ret);
return ret;
}
led->aux_gpio = devm_gpiod_get(dev, "aux", GPIOD_ASIS);
if (IS_ERR(led->aux_gpio)) {
ret = PTR_ERR(led->aux_gpio);
ret = PTR_ERR_OR_ZERO(led->aux_gpio);
if (ret) {
dev_err(dev, "cannot get aux-gpios %d\n", ret);
return ret;
}

View file

@ -2473,7 +2473,8 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
INIT_HLIST_HEAD(&bp->ntp_fltr_hash_tbl[i]);
bp->ntp_fltr_count = 0;
bp->ntp_fltr_bmap = kzalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR),
bp->ntp_fltr_bmap = kcalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR),
sizeof(long),
GFP_KERNEL);
if (!bp->ntp_fltr_bmap)

View file

@ -211,7 +211,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
int ret;
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = ifp->drvr;
struct ethhdr *eh = (struct ethhdr *)(skb->data);
struct ethhdr *eh;
brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
@ -232,22 +232,13 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
goto done;
}
/* Make sure there's enough room for any header */
if (skb_headroom(skb) < drvr->hdrlen) {
struct sk_buff *skb2;
brcmf_dbg(INFO, "%s: insufficient headroom\n",
/* Make sure there's enough writable headroom*/
ret = skb_cow_head(skb, drvr->hdrlen);
if (ret < 0) {
brcmf_err("%s: skb_cow_head failed\n",
brcmf_ifname(drvr, ifp->bssidx));
drvr->bus_if->tx_realloc++;
skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
dev_kfree_skb(skb);
skb = skb2;
if (skb == NULL) {
brcmf_err("%s: skb_realloc_headroom failed\n",
brcmf_ifname(drvr, ifp->bssidx));
ret = -ENOMEM;
goto done;
}
goto done;
}
/* validate length for ether packet */
@ -257,6 +248,8 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
goto done;
}
eh = (struct ethhdr *)(skb->data);
if (eh->h_proto == htons(ETH_P_PAE))
atomic_inc(&ifp->pend_8021x_cnt);

View file

@ -101,13 +101,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
{
struct txpd *local_tx_pd;
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
unsigned int pad;
int headroom = (priv->adapter->iface_type ==
MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
pad = ((void *)skb->data - sizeof(*local_tx_pd) -
headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
skb_push(skb, pad);
skb_push(skb, sizeof(*local_tx_pd));
@ -121,12 +114,10 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
local_tx_pd->bss_num = priv->bss_num;
local_tx_pd->bss_type = priv->bss_type;
/* Always zero as the data is followed by struct txpd */
local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) +
pad);
local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
sizeof(*local_tx_pd) -
pad);
sizeof(*local_tx_pd));
if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
@ -190,7 +181,11 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
ra_list_flags);
return -1;
}
skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN);
/* skb_aggr->data already 64 byte align, just reserve bus interface
* header and txpd.
*/
skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));

View file

@ -115,7 +115,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
p += sprintf(p, "multicast_count=\"%d\"\n",
netdev_mc_count(netdev));
p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len,
info.ssid.ssid);
p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
p += sprintf(p, "country_code = \"%s\"\n", info.country_code);

View file

@ -1098,8 +1098,6 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
encrypt_key.is_rx_seq_valid = true;
}
} else {
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
return 0;
encrypt_key.key_disable = true;
if (mac_addr)
memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);

View file

@ -368,6 +368,7 @@ config PHY_QCOM_UFS
config PHY_TUSB1210
tristate "TI TUSB1210 ULPI PHY module"
depends on USB_ULPI_BUS
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
select GENERIC_PHY
help
Support for TI TUSB1210 USB ULPI PHY.

View file

@ -144,10 +144,7 @@
* so the first read after a fault returns the latched value and subsequent
* reads return the current value. In order to return the fault status
* to the user, have the interrupt handler save the reg's value and retrieve
* it in the appropriate health/status routine. Each routine has its own
* flag indicating whether it should use the value stored by the last run
* of the interrupt handler or do an actual reg read. That way each routine
* can report back whatever fault may have occured.
* it in the appropriate health/status routine.
*/
struct bq24190_dev_info {
struct i2c_client *client;
@ -159,10 +156,6 @@ struct bq24190_dev_info {
unsigned int gpio_int;
unsigned int irq;
struct mutex f_reg_lock;
bool first_time;
bool charger_health_valid;
bool battery_health_valid;
bool battery_status_valid;
u8 f_reg;
u8 ss_reg;
u8 watchdog;
@ -636,21 +629,11 @@ static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
union power_supply_propval *val)
{
u8 v;
int health, ret;
int health;
mutex_lock(&bdi->f_reg_lock);
if (bdi->charger_health_valid) {
v = bdi->f_reg;
bdi->charger_health_valid = false;
mutex_unlock(&bdi->f_reg_lock);
} else {
mutex_unlock(&bdi->f_reg_lock);
ret = bq24190_read(bdi, BQ24190_REG_F, &v);
if (ret < 0)
return ret;
}
v = bdi->f_reg;
mutex_unlock(&bdi->f_reg_lock);
if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
/*
@ -937,18 +920,8 @@ static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
int status, ret;
mutex_lock(&bdi->f_reg_lock);
if (bdi->battery_status_valid) {
chrg_fault = bdi->f_reg;
bdi->battery_status_valid = false;
mutex_unlock(&bdi->f_reg_lock);
} else {
mutex_unlock(&bdi->f_reg_lock);
ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault);
if (ret < 0)
return ret;
}
chrg_fault = bdi->f_reg;
mutex_unlock(&bdi->f_reg_lock);
chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
@ -996,21 +969,11 @@ static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
union power_supply_propval *val)
{
u8 v;
int health, ret;
int health;
mutex_lock(&bdi->f_reg_lock);
if (bdi->battery_health_valid) {
v = bdi->f_reg;
bdi->battery_health_valid = false;
mutex_unlock(&bdi->f_reg_lock);
} else {
mutex_unlock(&bdi->f_reg_lock);
ret = bq24190_read(bdi, BQ24190_REG_F, &v);
if (ret < 0)
return ret;
}
v = bdi->f_reg;
mutex_unlock(&bdi->f_reg_lock);
if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
@ -1197,9 +1160,12 @@ static const struct power_supply_desc bq24190_battery_desc = {
static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
{
struct bq24190_dev_info *bdi = data;
bool alert_userspace = false;
const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
| BQ24190_REG_F_NTC_FAULT_MASK;
bool alert_charger = false, alert_battery = false;
u8 ss_reg = 0, f_reg = 0;
int ret;
int i, ret;
pm_runtime_get_sync(bdi->dev);
@ -1209,6 +1175,32 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
goto out;
}
i = 0;
do {
ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
if (ret < 0) {
dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
goto out;
}
} while (f_reg && ++i < 2);
if (f_reg != bdi->f_reg) {
dev_info(bdi->dev,
"Fault: boost %d, charge %d, battery %d, ntc %d\n",
!!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
!!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
!!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
!!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
mutex_lock(&bdi->f_reg_lock);
if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
alert_battery = true;
if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
alert_charger = true;
bdi->f_reg = f_reg;
mutex_unlock(&bdi->f_reg_lock);
}
if (ss_reg != bdi->ss_reg) {
/*
* The device is in host mode so when PG_STAT goes from 1->0
@ -1225,47 +1217,17 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
ret);
}
if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
alert_battery = true;
if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
alert_charger = true;
bdi->ss_reg = ss_reg;
alert_userspace = true;
}
mutex_lock(&bdi->f_reg_lock);
ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
if (ret < 0) {
mutex_unlock(&bdi->f_reg_lock);
dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
goto out;
}
if (f_reg != bdi->f_reg) {
bdi->f_reg = f_reg;
bdi->charger_health_valid = true;
bdi->battery_health_valid = true;
bdi->battery_status_valid = true;
alert_userspace = true;
}
mutex_unlock(&bdi->f_reg_lock);
/*
* Sometimes bq24190 gives a steady trickle of interrupts even
* though the watchdog timer is turned off and neither the STATUS
* nor FAULT registers have changed. Weed out these sprurious
* interrupts so userspace isn't alerted for no reason.
* In addition, the chip always generates an interrupt after
* register reset so we should ignore that one (the very first
* interrupt received).
*/
if (alert_userspace) {
if (!bdi->first_time) {
power_supply_changed(bdi->charger);
power_supply_changed(bdi->battery);
} else {
bdi->first_time = false;
}
}
if (alert_charger)
power_supply_changed(bdi->charger);
if (alert_battery)
power_supply_changed(bdi->battery);
out:
pm_runtime_put_sync(bdi->dev);
@ -1300,6 +1262,10 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
goto out;
ret = bq24190_set_mode_host(bdi);
if (ret < 0)
goto out;
ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
out:
pm_runtime_put_sync(bdi->dev);
return ret;
@ -1375,10 +1341,8 @@ static int bq24190_probe(struct i2c_client *client,
bdi->model = id->driver_data;
strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
mutex_init(&bdi->f_reg_lock);
bdi->first_time = true;
bdi->charger_health_valid = false;
bdi->battery_health_valid = false;
bdi->battery_status_valid = false;
bdi->f_reg = 0;
bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
i2c_set_clientdata(client, bdi);
@ -1392,22 +1356,13 @@ static int bq24190_probe(struct i2c_client *client,
return -EINVAL;
}
ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
bq24190_irq_handler_thread,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"bq24190-charger", bdi);
if (ret < 0) {
dev_err(dev, "Can't set up irq handler\n");
goto out1;
}
pm_runtime_enable(dev);
pm_runtime_resume(dev);
ret = bq24190_hw_init(bdi);
if (ret < 0) {
dev_err(dev, "Hardware init failed\n");
goto out2;
goto out1;
}
charger_cfg.drv_data = bdi;
@ -1418,7 +1373,7 @@ static int bq24190_probe(struct i2c_client *client,
if (IS_ERR(bdi->charger)) {
dev_err(dev, "Can't register charger\n");
ret = PTR_ERR(bdi->charger);
goto out2;
goto out1;
}
battery_cfg.drv_data = bdi;
@ -1427,24 +1382,34 @@ static int bq24190_probe(struct i2c_client *client,
if (IS_ERR(bdi->battery)) {
dev_err(dev, "Can't register battery\n");
ret = PTR_ERR(bdi->battery);
goto out3;
goto out2;
}
ret = bq24190_sysfs_create_group(bdi);
if (ret) {
dev_err(dev, "Can't create sysfs entries\n");
goto out3;
}
ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
bq24190_irq_handler_thread,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"bq24190-charger", bdi);
if (ret < 0) {
dev_err(dev, "Can't set up irq handler\n");
goto out4;
}
return 0;
out4:
power_supply_unregister(bdi->battery);
bq24190_sysfs_remove_group(bdi);
out3:
power_supply_unregister(bdi->charger);
power_supply_unregister(bdi->battery);
out2:
pm_runtime_disable(dev);
power_supply_unregister(bdi->charger);
out1:
pm_runtime_disable(dev);
if (bdi->gpio_int)
gpio_free(bdi->gpio_int);
@ -1488,12 +1453,13 @@ static int bq24190_pm_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
bdi->charger_health_valid = false;
bdi->battery_health_valid = false;
bdi->battery_status_valid = false;
bdi->f_reg = 0;
bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
pm_runtime_get_sync(bdi->dev);
bq24190_register_reset(bdi);
bq24190_set_mode_host(bdi);
bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
pm_runtime_put_sync(bdi->dev);
/* Things may have changed while suspended so alert upper layer */

View file

@ -1637,7 +1637,7 @@ config ATARI_SCSI_RESET_BOOT
config MAC_SCSI
tristate "Macintosh NCR5380 SCSI"
depends on MAC && SCSI=y
depends on MAC && SCSI
select SCSI_SPI_ATTRS
help
This is the NCR 5380 SCSI controller included on most of the 68030

View file

@ -3181,7 +3181,7 @@ static const struct {
};
/*-------------------------------------------------------------------------*/
static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
static void nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
{
int i;
@ -3211,7 +3211,7 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
/*-------------------------------------------------------------------------*/
/* platform_driver */
static int __init nbu2ss_drv_contest_init(
static int nbu2ss_drv_contest_init(
struct platform_device *pdev,
struct nbu2ss_udc *udc)
{

View file

@ -232,7 +232,7 @@ static int p80211_convert_to_ether(wlandevice_t *wlandev, struct sk_buff *skb)
struct p80211_hdr_a3 *hdr;
hdr = (struct p80211_hdr_a3 *) skb->data;
if (p80211_rx_typedrop(wlandev, hdr->fc))
if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->fc)))
return CONV_TO_ETHER_SKIPPED;
/* perform mcast filtering: allow my local address through but reject

View file

@ -1235,7 +1235,8 @@ static int omap8250_probe(struct platform_device *pdev)
pm_runtime_put_autosuspend(&pdev->dev);
return 0;
err:
pm_runtime_put(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return ret;
}
@ -1244,6 +1245,7 @@ static int omap8250_remove(struct platform_device *pdev)
{
struct omap8250_priv *priv = platform_get_drvdata(pdev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
serial8250_unregister_port(priv->line);
@ -1343,6 +1345,10 @@ static int omap8250_runtime_suspend(struct device *dev)
struct omap8250_priv *priv = dev_get_drvdata(dev);
struct uart_8250_port *up;
/* In case runtime-pm tries this before we are setup */
if (!priv)
return 0;
up = serial8250_get_port(priv->line);
/*
* When using 'no_console_suspend', the console UART must not be

View file

@ -428,9 +428,6 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
u8 hw_port_test_get(struct ci_hdrc *ci);
int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
u32 value, unsigned int timeout_ms);
void ci_platform_configure(struct ci_hdrc *ci);
#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */

View file

@ -518,38 +518,6 @@ int hw_device_reset(struct ci_hdrc *ci)
return 0;
}
/**
* hw_wait_reg: wait the register value
*
* Sometimes, it needs to wait register value before going on.
* Eg, when switch to device mode, the vbus value should be lower
* than OTGSC_BSV before connects to host.
*
* @ci: the controller
* @reg: register index
* @mask: mast bit
* @value: the bit value to wait
* @timeout_ms: timeout in millisecond
*
* This function returns an error code if timeout
*/
int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
u32 value, unsigned int timeout_ms)
{
unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
while (hw_read(ci, reg, mask) != value) {
if (time_after(jiffies, elapse)) {
dev_err(ci->dev, "timeout waiting for %08x in %d\n",
mask, reg);
return -ETIMEDOUT;
}
msleep(20);
}
return 0;
}
static irqreturn_t ci_irq(int irq, void *data)
{
struct ci_hdrc *ci = data;

View file

@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
else
val &= ~OTGSC_BSVIS;
cable->changed = false;
if (cable->state)
val |= OTGSC_BSV;
else
val &= ~OTGSC_BSV;
if (cable->enabled)
val |= OTGSC_BSVIE;
else
val &= ~OTGSC_BSVIE;
}
cable = &ci->platdata->id_extcon;
@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
else
val &= ~OTGSC_IDIS;
cable->changed = false;
if (cable->state)
val |= OTGSC_ID;
else
val &= ~OTGSC_ID;
if (cable->enabled)
val |= OTGSC_IDIE;
else
val &= ~OTGSC_IDIE;
}
return val;
return val & mask;
}
/**
@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
*/
void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
{
struct ci_hdrc_cable *cable;
cable = &ci->platdata->vbus_extcon;
if (!IS_ERR(cable->edev)) {
if (data & mask & OTGSC_BSVIS)
cable->changed = false;
/* Don't enable vbus interrupt if using external notifier */
if (data & mask & OTGSC_BSVIE) {
cable->enabled = true;
data &= ~OTGSC_BSVIE;
} else if (mask & OTGSC_BSVIE) {
cable->enabled = false;
}
}
cable = &ci->platdata->id_extcon;
if (!IS_ERR(cable->edev)) {
if (data & mask & OTGSC_IDIS)
cable->changed = false;
/* Don't enable id interrupt if using external notifier */
if (data & mask & OTGSC_IDIE) {
cable->enabled = true;
data &= ~OTGSC_IDIE;
} else if (mask & OTGSC_IDIE) {
cable->enabled = false;
}
}
hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
}
@ -104,7 +140,31 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
usb_gadget_vbus_disconnect(&ci->gadget);
}
#define CI_VBUS_STABLE_TIMEOUT_MS 5000
/**
* When we switch to device mode, the vbus value should be lower
* than OTGSC_BSV before connecting to host.
*
* @ci: the controller
*
* This function returns an error code if timeout
*/
static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci)
{
unsigned long elapse = jiffies + msecs_to_jiffies(5000);
u32 mask = OTGSC_BSV;
while (hw_read_otgsc(ci, mask)) {
if (time_after(jiffies, elapse)) {
dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
mask);
return -ETIMEDOUT;
}
msleep(20);
}
return 0;
}
static void ci_handle_id_switch(struct ci_hdrc *ci)
{
enum ci_role role = ci_otg_role(ci);
@ -116,9 +176,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
ci_role_stop(ci);
if (role == CI_ROLE_GADGET)
/* wait vbus lower than OTGSC_BSV */
hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
CI_VBUS_STABLE_TIMEOUT_MS);
/*
* wait vbus lower than OTGSC_BSV before connecting
* to host
*/
hw_wait_vbus_lower_bsv(ci);
ci_role_start(ci, role);
}

View file

@ -77,10 +77,12 @@ static int exynos_ehci_get_phy(struct device *dev,
if (IS_ERR(phy)) {
ret = PTR_ERR(phy);
if (ret == -EPROBE_DEFER) {
of_node_put(child);
return ret;
} else if (ret != -ENOSYS && ret != -ENODEV) {
dev_err(dev,
"Error retrieving usb2 phy: %d\n", ret);
of_node_put(child);
return ret;
}
}

View file

@ -66,10 +66,12 @@ static int exynos_ohci_get_phy(struct device *dev,
if (IS_ERR(phy)) {
ret = PTR_ERR(phy);
if (ret == -EPROBE_DEFER) {
of_node_put(child);
return ret;
} else if (ret != -ENOSYS && ret != -ENODEV) {
dev_err(dev,
"Error retrieving usb2 phy: %d\n", ret);
of_node_put(child);
return ret;
}
}

View file

@ -373,23 +373,29 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
dev_dbg(&port->dev,
"%s - usb_serial_generic_open failed: %d\n",
__func__, result);
goto err_out;
goto err_free;
}
/* remove any data still left: also clears error state */
ark3116_read_reg(serial, UART_RX, buf);
/* read modem status */
priv->msr = ark3116_read_reg(serial, UART_MSR, buf);
result = ark3116_read_reg(serial, UART_MSR, buf);
if (result < 0)
goto err_close;
priv->msr = *buf;
/* read line status */
priv->lsr = ark3116_read_reg(serial, UART_LSR, buf);
result = ark3116_read_reg(serial, UART_LSR, buf);
if (result < 0)
goto err_close;
priv->lsr = *buf;
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result) {
dev_err(&port->dev, "submit irq_in urb failed %d\n",
result);
ark3116_close(port);
goto err_out;
goto err_close;
}
/* activate interrupts */
@ -402,8 +408,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
if (tty)
ark3116_set_termios(tty, port, NULL);
err_out:
kfree(buf);
return 0;
err_close:
usb_serial_generic_close(port);
err_free:
kfree(buf);
return result;
}

View file

@ -1399,25 +1399,30 @@ static int digi_read_inb_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct digi_port *priv = usb_get_serial_port_data(port);
int opcode = ((unsigned char *)urb->transfer_buffer)[0];
int len = ((unsigned char *)urb->transfer_buffer)[1];
int port_status = ((unsigned char *)urb->transfer_buffer)[2];
unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
unsigned char *buf = urb->transfer_buffer;
int opcode;
int len;
int port_status;
unsigned char *data;
int flag, throttled;
int status = urb->status;
/* do not process callbacks on closed ports */
/* but do continue the read chain */
if (urb->status == -ENOENT)
return 0;
/* short/multiple packet check */
if (urb->actual_length < 2) {
dev_warn(&port->dev, "short packet received\n");
return -1;
}
opcode = buf[0];
len = buf[1];
if (urb->actual_length != len + 2) {
dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, "
"status=%d, port=%d, opcode=%d, len=%d, "
"actual_length=%d, status=%d\n", __func__, status,
priv->dp_port_num, opcode, len, urb->actual_length,
port_status);
dev_err(&port->dev, "malformed packet received: port=%d, opcode=%d, len=%d, actual_length=%u\n",
priv->dp_port_num, opcode, len, urb->actual_length);
return -1;
}
if (opcode == DIGI_CMD_RECEIVE_DATA && len < 1) {
dev_err(&port->dev, "malformed data packet received\n");
return -1;
}
@ -1431,6 +1436,9 @@ static int digi_read_inb_callback(struct urb *urb)
/* receive data */
if (opcode == DIGI_CMD_RECEIVE_DATA) {
port_status = buf[2];
data = &buf[3];
/* get flag from port_status */
flag = 0;

View file

@ -1439,10 +1439,13 @@ static int read_latency_timer(struct usb_serial_port *port)
FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
0, priv->interface,
buf, 1, WDR_TIMEOUT);
if (rv < 0)
if (rv < 1) {
dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
else
if (rv >= 0)
rv = -EIO;
} else {
priv->latency = buf[0];
}
kfree(buf);

View file

@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
int result;
struct usb_serial *serial = ep->serial;
struct edgeport_product_info *product_info = &ep->product_info;
struct edge_compatibility_descriptor *epic = &ep->epic_descriptor;
struct edge_compatibility_descriptor *epic;
struct edge_compatibility_bits *bits;
struct device *dev = &serial->dev->dev;
ep->is_epic = 0;
epic = kmalloc(sizeof(*epic), GFP_KERNEL);
if (!epic)
return -ENOMEM;
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
USB_REQUEST_ION_GET_EPIC_DESC,
0xC0, 0x00, 0x00,
&ep->epic_descriptor,
sizeof(struct edge_compatibility_descriptor),
epic, sizeof(*epic),
300);
if (result > 0) {
if (result == sizeof(*epic)) {
ep->is_epic = 1;
memcpy(&ep->epic_descriptor, epic, sizeof(*epic));
memset(product_info, 0, sizeof(struct edgeport_product_info));
product_info->NumPorts = epic->NumPorts;
@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE");
dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE");
dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE");
result = 0;
} else if (result >= 0) {
dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n",
result);
result = -EIO;
}
kfree(epic);
return result;
}
@ -2097,8 +2109,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
* rom_read
* reads a number of bytes from the Edgeport device starting at the given
* address.
* If successful returns the number of bytes read, otherwise it returns
* a negative error number of the problem.
* Returns zero on success or a negative error number.
****************************************************************************/
static int rom_read(struct usb_serial *serial, __u16 extAddr,
__u16 addr, __u16 length, __u8 *data)
@ -2123,12 +2134,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr,
USB_REQUEST_ION_READ_ROM,
0xC0, addr, extAddr, transfer_buffer,
current_length, 300);
if (result < 0)
if (result < current_length) {
if (result >= 0)
result = -EIO;
break;
}
memcpy(data, transfer_buffer, current_length);
length -= current_length;
addr += current_length;
data += current_length;
result = 0;
}
kfree(transfer_buffer);
@ -2585,9 +2601,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial)
EDGE_MANUF_DESC_LEN,
(__u8 *)(&edge_serial->manuf_descriptor));
if (response < 1)
dev_err(dev, "error in getting manufacturer descriptor\n");
else {
if (response < 0) {
dev_err(dev, "error in getting manufacturer descriptor: %d\n",
response);
} else {
char string[30];
dev_dbg(dev, "**Manufacturer Descriptor\n");
dev_dbg(dev, " RomSize: %dK\n",
@ -2644,9 +2661,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial)
EDGE_BOOT_DESC_LEN,
(__u8 *)(&edge_serial->boot_descriptor));
if (response < 1)
dev_err(dev, "error in getting boot descriptor\n");
else {
if (response < 0) {
dev_err(dev, "error in getting boot descriptor: %d\n",
response);
} else {
dev_dbg(dev, "**Boot Descriptor:\n");
dev_dbg(dev, " BootCodeLength: %d\n",
le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
@ -2789,7 +2807,7 @@ static int edge_startup(struct usb_serial *serial)
dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
/* Read the epic descriptor */
if (get_epic_descriptor(edge_serial) <= 0) {
if (get_epic_descriptor(edge_serial) < 0) {
/* memcpy descriptor to Supports structures */
memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
sizeof(struct edge_compatibility_bits));

View file

@ -139,6 +139,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
unsigned int len = urb->actual_length;
int retval;
int status = urb->status;
struct keyspan_pda_private *priv;
@ -159,18 +160,26 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
goto exit;
}
if (len < 1) {
dev_warn(&port->dev, "short message received\n");
goto exit;
}
/* see if the message is data or a status interrupt */
switch (data[0]) {
case 0:
/* rest of message is rx data */
if (urb->actual_length) {
tty_insert_flip_string(&port->port, data + 1,
urb->actual_length - 1);
tty_flip_buffer_push(&port->port);
}
if (len < 2)
break;
tty_insert_flip_string(&port->port, data + 1, len - 1);
tty_flip_buffer_push(&port->port);
break;
case 1:
/* status interrupt */
if (len < 3) {
dev_warn(&port->dev, "short interrupt message received\n");
break;
}
dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]);
switch (data[1]) {
case 1: /* modemline change */

View file

@ -322,8 +322,12 @@ static int mct_u232_get_modem_stat(struct usb_serial_port *port,
MCT_U232_GET_REQUEST_TYPE,
0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
WDR_TIMEOUT);
if (rc < 0) {
if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
if (rc >= 0)
rc = -EIO;
*msr = 0;
} else {
*msr = buf[0];

View file

@ -188,22 +188,22 @@ static inline int qt2_setdevice(struct usb_device *dev, u8 *data)
}
static inline int qt2_getdevice(struct usb_device *dev, u8 *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_DEVICE, 0xc0, 0, 0,
data, 3, QT2_USB_TIMEOUT);
}
static inline int qt2_getregister(struct usb_device *dev,
u8 uart,
u8 reg,
u8 *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), QT2_USB_TIMEOUT);
int ret;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), QT2_USB_TIMEOUT);
if (ret < sizeof(*data)) {
if (ret >= 0)
ret = -EIO;
}
return ret;
}
static inline int qt2_setregister(struct usb_device *dev,
@ -372,9 +372,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
0xc0, 0,
device_port, data, 2, QT2_USB_TIMEOUT);
if (status < 0) {
if (status < 2) {
dev_err(&port->dev, "%s - open port failed %i\n", __func__,
status);
if (status >= 0)
status = -EIO;
kfree(data);
return status;
}

View file

@ -80,9 +80,17 @@ static inline int ssu100_setdevice(struct usb_device *dev, u8 *data)
static inline int ssu100_getdevice(struct usb_device *dev, u8 *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_DEVICE, 0xc0, 0, 0,
data, 3, 300);
int ret;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_DEVICE, 0xc0, 0, 0,
data, 3, 300);
if (ret < 3) {
if (ret >= 0)
ret = -EIO;
}
return ret;
}
static inline int ssu100_getregister(struct usb_device *dev,
@ -90,10 +98,17 @@ static inline int ssu100_getregister(struct usb_device *dev,
unsigned short reg,
u8 *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), 300);
int ret;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), 300);
if (ret < sizeof(*data)) {
if (ret >= 0)
ret = -EIO;
}
return ret;
}
@ -289,8 +304,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
QT_OPEN_CLOSE_CHANNEL,
QT_TRANSFER_IN, 0x01,
0, data, 2, 300);
if (result < 0) {
if (result < 2) {
dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result);
if (result >= 0)
result = -EIO;
kfree(data);
return result;
}

View file

@ -1352,13 +1352,10 @@ static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
value, moduleid, data, size, 1000);
if (status == size)
status = 0;
if (status < 0)
return status;
if (status > 0)
status = -ECOMM;
return status;
return 0;
}
@ -1374,8 +1371,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
if (status == size)
status = 0;
if (status > 0)
else if (status >= 0)
status = -ECOMM;
return status;

View file

@ -1098,7 +1098,6 @@ int revalidate_disk(struct gendisk *disk)
if (disk->fops->revalidate_disk)
ret = disk->fops->revalidate_disk(disk);
blk_integrity_revalidate(disk);
bdev = bdget_disk(disk, 0);
if (!bdev)
return ret;

View file

@ -1059,6 +1059,13 @@ static int sanity_check_raw_super(struct super_block *sb,
return 1;
}
if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) {
f2fs_msg(sb, KERN_INFO,
"Invalid segment count (%u)",
le32_to_cpu(raw_super->segment_count));
return 1;
}
/* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
if (sanity_check_area_boundary(sb, raw_super))
return 1;

View file

@ -283,6 +283,12 @@ struct f2fs_nat_block {
#define SIT_VBLOCK_MAP_SIZE 64
#define SIT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_sit_entry))
/*
* F2FS uses 4 bytes to represent block address. As a result, supported size of
* disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
*/
#define F2FS_MAX_SEGMENT ((16 * 1024 * 1024) / 2)
/*
* Note that f2fs_sit_entry->vblocks has the following bit-field information.
* [15:10] : allocation type such as CURSEG_XXXX_TYPE

View file

@ -742,11 +742,9 @@ static inline void part_nr_sects_write(struct hd_struct *part, sector_t size)
#if defined(CONFIG_BLK_DEV_INTEGRITY)
extern void blk_integrity_add(struct gendisk *);
extern void blk_integrity_del(struct gendisk *);
extern void blk_integrity_revalidate(struct gendisk *);
#else /* CONFIG_BLK_DEV_INTEGRITY */
static inline void blk_integrity_add(struct gendisk *disk) { }
static inline void blk_integrity_del(struct gendisk *disk) { }
static inline void blk_integrity_revalidate(struct gendisk *disk) { }
#endif /* CONFIG_BLK_DEV_INTEGRITY */
#else /* CONFIG_BLOCK */

View file

@ -14,6 +14,7 @@ struct ci_hdrc;
* struct ci_hdrc_cable - structure for external connector cable state tracking
* @state: current state of the line
* @changed: set to true when extcon event happen
* @enabled: set to true if we've enabled the vbus or id interrupt
* @edev: device which generate events
* @ci: driver state of the chipidea device
* @nb: hold event notification callback
@ -22,6 +23,7 @@ struct ci_hdrc;
struct ci_hdrc_cable {
bool state;
bool changed;
bool enabled;
struct extcon_dev *edev;
struct ci_hdrc *ci;
struct notifier_block nb;

View file

@ -20,6 +20,8 @@
#define ADDRCONF_TIMER_FUZZ (HZ / 4)
#define ADDRCONF_TIMER_FUZZ_MAX (HZ)
#define ADDRCONF_NOTIFY_PRIORITY 0
#include <linux/in.h>
#include <linux/in6.h>

View file

@ -77,6 +77,7 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
int flags);
void ip6_route_init_special_entries(void);
int ip6_route_init(void);
void ip6_route_cleanup(void);

View file

@ -4315,6 +4315,51 @@ static struct bpf_test tests[] = {
{ },
{ { 0, 1 } },
},
{
/* Mainly testing JIT + imm64 here. */
"JMP_JGE_X: ldimm64 test 1",
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0),
BPF_LD_IMM64(R1, 3),
BPF_LD_IMM64(R2, 2),
BPF_JMP_REG(BPF_JGE, R1, R2, 2),
BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
BPF_EXIT_INSN(),
},
INTERNAL,
{ },
{ { 0, 0xeeeeeeeeU } },
},
{
"JMP_JGE_X: ldimm64 test 2",
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0),
BPF_LD_IMM64(R1, 3),
BPF_LD_IMM64(R2, 2),
BPF_JMP_REG(BPF_JGE, R1, R2, 0),
BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
BPF_EXIT_INSN(),
},
INTERNAL,
{ },
{ { 0, 0xffffffffU } },
},
{
"JMP_JGE_X: ldimm64 test 3",
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 1),
BPF_LD_IMM64(R1, 3),
BPF_LD_IMM64(R2, 2),
BPF_JMP_REG(BPF_JGE, R1, R2, 4),
BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
BPF_EXIT_INSN(),
},
INTERNAL,
{ },
{ { 0, 1 } },
},
/* BPF_JMP | BPF_JNE | BPF_X */
{
"JMP_JNE_X: if (3 != 2) return 1",

View file

@ -1018,7 +1018,7 @@ static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev)
return err;
}
if (nla_put(skb, IFLA_PHYS_PORT_NAME, strlen(name), name))
if (nla_put_string(skb, IFLA_PHYS_PORT_NAME, name))
return -EMSGSIZE;
return 0;

View file

@ -354,6 +354,9 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
rt->dst.dev->mtu);
return -EMSGSIZE;
}
if (length < sizeof(struct iphdr))
return -EINVAL;
if (flags&MSG_PROBE)
goto out;

View file

@ -264,13 +264,15 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, s32 rtt_us)
{
struct tcp_sock *tp = tcp_sk(sk);
struct lp *lp = inet_csk_ca(sk);
u32 delta;
if (rtt_us > 0)
tcp_lp_rtt_sample(sk, rtt_us);
/* calc inference */
if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
delta = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
if ((s32)delta > 0)
lp->inference = 3 * delta;
/* test if within inference */
if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))

View file

@ -547,6 +547,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len;
newtp->rx_opt.mss_clamp = req->mss;
tcp_ecn_openreq_child(newtp, req);
newtp->fastopen_req = NULL;
newtp->fastopen_rsk = NULL;
newtp->syn_data_acked = 0;
newtp->rack.mstamp.v64 = 0;

View file

@ -1221,7 +1221,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
* eventually). The difference is that pulled data not copied, but
* immediately discarded.
*/
static void __pskb_trim_head(struct sk_buff *skb, int len)
static int __pskb_trim_head(struct sk_buff *skb, int len)
{
struct skb_shared_info *shinfo;
int i, k, eat;
@ -1231,7 +1231,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
__skb_pull(skb, eat);
len -= eat;
if (!len)
return;
return 0;
}
eat = len;
k = 0;
@ -1257,23 +1257,28 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
skb_reset_tail_pointer(skb);
skb->data_len -= len;
skb->len = skb->data_len;
return len;
}
/* Remove acked data from a packet in the transmit queue. */
int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
{
u32 delta_truesize;
if (skb_unclone(skb, GFP_ATOMIC))
return -ENOMEM;
__pskb_trim_head(skb, len);
delta_truesize = __pskb_trim_head(skb, len);
TCP_SKB_CB(skb)->seq += len;
skb->ip_summed = CHECKSUM_PARTIAL;
skb->truesize -= len;
sk->sk_wmem_queued -= len;
sk_mem_uncharge(sk, len);
sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
if (delta_truesize) {
skb->truesize -= delta_truesize;
sk->sk_wmem_queued -= delta_truesize;
sk_mem_uncharge(sk, delta_truesize);
sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
}
/* Any change of skb->len requires recalculation of tso factor. */
if (tcp_skb_pcount(skb) > 1)

View file

@ -3358,6 +3358,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
*/
static struct notifier_block ipv6_dev_notf = {
.notifier_call = addrconf_notify,
.priority = ADDRCONF_NOTIFY_PRIORITY,
};
static void addrconf_type_change(struct net_device *dev, unsigned long event)
@ -6022,6 +6023,8 @@ int __init addrconf_init(void)
goto errlo;
}
ip6_route_init_special_entries();
for (i = 0; i < IN6_ADDR_HSIZE; i++)
INIT_HLIST_HEAD(&inet6_addr_lst[i]);

View file

@ -630,6 +630,8 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
return -EMSGSIZE;
}
if (length < sizeof(struct ipv6hdr))
return -EINVAL;
if (flags&MSG_PROBE)
goto out;

View file

@ -3361,7 +3361,10 @@ static int ip6_route_dev_notify(struct notifier_block *this,
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net *net = dev_net(dev);
if (event == NETDEV_REGISTER && (dev->flags & IFF_LOOPBACK)) {
if (!(dev->flags & IFF_LOOPBACK))
return NOTIFY_OK;
if (event == NETDEV_REGISTER) {
net->ipv6.ip6_null_entry->dst.dev = dev;
net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@ -3369,6 +3372,12 @@ static int ip6_route_dev_notify(struct notifier_block *this,
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
} else if (event == NETDEV_UNREGISTER) {
in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev);
in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev);
#endif
}
@ -3676,9 +3685,24 @@ static struct pernet_operations ip6_route_net_late_ops = {
static struct notifier_block ip6_route_dev_notifier = {
.notifier_call = ip6_route_dev_notify,
.priority = 0,
.priority = ADDRCONF_NOTIFY_PRIORITY - 10,
};
void __init ip6_route_init_special_entries(void)
{
/* Registering of the loopback is done before this portion of code,
* the loopback reference in rt6_info will not be taken, do it
* manually for init_net */
init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#endif
}
int __init ip6_route_init(void)
{
int ret;
@ -3705,17 +3729,6 @@ int __init ip6_route_init(void)
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
/* Registering of the loopback is done before this portion of code,
* the loopback reference in rt6_info will not be taken, do it
* manually for init_net */
init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#endif
ret = fib6_init();
if (ret)
goto out_register_subsys;

View file

@ -2166,7 +2166,20 @@ static void azx_remove(struct pci_dev *pci)
/* cancel the pending probing work */
chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
/* FIXME: below is an ugly workaround.
* Both device_release_driver() and driver_probe_device()
* take *both* the device's and its parent's lock before
* calling the remove() and probe() callbacks. The codec
* probe takes the locks of both the codec itself and its
* parent, i.e. the PCI controller dev. Meanwhile, when
* the PCI controller is unbound, it takes its lock, too
* ==> ouch, a deadlock!
* As a workaround, we unlock temporarily here the controller
* device during cancel_work_sync() call.
*/
device_unlock(&pci->dev);
cancel_work_sync(&hda->probe_work);
device_lock(&pci->dev);
snd_card_free(card);
}

View file

@ -156,6 +156,7 @@ out:
*/
case 0x2C: /* Westmere EP - Gulftown */
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
break;
case 0x2A: /* SNB */
case 0x2D: /* SNB Xeon */
case 0x3A: /* IVB */