mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
Merge tag 'v4.9.19' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidxu4-4.9.y
This is the 4.9.19 stable release
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 18
|
||||
SUBLEVEL = 19
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
};
|
||||
|
||||
usb1: ohci@00400000 {
|
||||
compatible = "atmel,sama5d2-ohci", "usb-ohci";
|
||||
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
|
||||
reg = <0x00400000 0x100000>;
|
||||
interrupts = <41 IRQ_TYPE_LEVEL_HIGH 2>;
|
||||
clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
|
||||
|
||||
@@ -289,6 +289,22 @@ static void at91_ddr_standby(void)
|
||||
at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
|
||||
}
|
||||
|
||||
static void sama5d3_ddr_standby(void)
|
||||
{
|
||||
u32 lpr0;
|
||||
u32 saved_lpr0;
|
||||
|
||||
saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
|
||||
lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
|
||||
lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN;
|
||||
|
||||
at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
|
||||
|
||||
cpu_do_idle();
|
||||
|
||||
at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
|
||||
}
|
||||
|
||||
/* We manage both DDRAM/SDRAM controllers, we need more than one value to
|
||||
* remember.
|
||||
*/
|
||||
@@ -323,7 +339,7 @@ static const struct of_device_id const ramc_ids[] __initconst = {
|
||||
{ .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
|
||||
{ .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
|
||||
{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
|
||||
{ .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
|
||||
{ .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
|
||||
{ /*sentinel*/ }
|
||||
};
|
||||
|
||||
|
||||
@@ -131,11 +131,15 @@ u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
|
||||
/*
|
||||
* The kernel Image should not extend across a 1GB/32MB/512MB alignment
|
||||
* boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
|
||||
* happens, increase the KASLR offset by the size of the kernel image.
|
||||
* happens, increase the KASLR offset by the size of the kernel image
|
||||
* rounded up by SWAPPER_BLOCK_SIZE.
|
||||
*/
|
||||
if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) !=
|
||||
(((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT))
|
||||
offset = (offset + (u64)(_end - _text)) & mask;
|
||||
(((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) {
|
||||
u64 kimg_sz = _end - _text;
|
||||
offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE))
|
||||
& mask;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_KASAN))
|
||||
/*
|
||||
|
||||
@@ -439,9 +439,23 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
|
||||
_GLOBAL(pnv_wakeup_tb_loss)
|
||||
ld r1,PACAR1(r13)
|
||||
/*
|
||||
* Before entering any idle state, the NVGPRs are saved in the stack
|
||||
* and they are restored before switching to the process context. Hence
|
||||
* until they are restored, they are free to be used.
|
||||
* Before entering any idle state, the NVGPRs are saved in the stack.
|
||||
* If there was a state loss, or PACA_NAPSTATELOST was set, then the
|
||||
* NVGPRs are restored. If we are here, it is likely that state is lost,
|
||||
* but not guaranteed -- neither ISA207 nor ISA300 tests to reach
|
||||
* here are the same as the test to restore NVGPRS:
|
||||
* PACA_THREAD_IDLE_STATE test for ISA207, PSSCR test for ISA300,
|
||||
* and SRR1 test for restoring NVGPRs.
|
||||
*
|
||||
* We are about to clobber NVGPRs now, so set NAPSTATELOST to
|
||||
* guarantee they will always be restored. This might be tightened
|
||||
* with careful reading of specs (particularly for ISA300) but this
|
||||
* is already a slow wakeup path and it's simpler to be safe.
|
||||
*/
|
||||
li r0,1
|
||||
stb r0,PACA_NAPSTATELOST(r13)
|
||||
|
||||
/*
|
||||
*
|
||||
* Save SRR1 and LR in NVGPRs as they might be clobbered in
|
||||
* opal_call() (called in CHECK_HMI_INTERRUPT). SRR1 is required
|
||||
|
||||
@@ -629,17 +629,8 @@ static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
|
||||
{
|
||||
struct blk_mq_timeout_data *data = priv;
|
||||
|
||||
if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) {
|
||||
/*
|
||||
* If a request wasn't started before the queue was
|
||||
* marked dying, kill it here or it'll go unnoticed.
|
||||
*/
|
||||
if (unlikely(blk_queue_dying(rq->q))) {
|
||||
rq->errors = -EIO;
|
||||
blk_mq_end_request(rq, rq->errors);
|
||||
}
|
||||
if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags))
|
||||
return;
|
||||
}
|
||||
|
||||
if (time_after_eq(jiffies, rq->deadline)) {
|
||||
if (!blk_mark_rq_complete(rq))
|
||||
|
||||
@@ -245,7 +245,7 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags)
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct hash_ctx *ctx = ask->private;
|
||||
struct ahash_request *req = &ctx->req;
|
||||
char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))];
|
||||
char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req)) ? : 1];
|
||||
struct sock *sk2;
|
||||
struct alg_sock *ask2;
|
||||
struct hash_ctx *ctx2;
|
||||
|
||||
@@ -218,6 +218,7 @@ static const struct of_device_id img_ascii_lcd_matches[] = {
|
||||
{ .compatible = "img,boston-lcd", .data = &boston_config },
|
||||
{ .compatible = "mti,malta-lcd", .data = &malta_config },
|
||||
{ .compatible = "mti,sead3-lcd", .data = &sead3_config },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,6 +55,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
|
||||
struct amd768_priv {
|
||||
void __iomem *iobase;
|
||||
struct pci_dev *pcidev;
|
||||
u32 pmbase;
|
||||
};
|
||||
|
||||
static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
@@ -148,33 +149,58 @@ found:
|
||||
if (pmbase == 0)
|
||||
return -EIO;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!devm_request_region(&pdev->dev, pmbase + PMBASE_OFFSET,
|
||||
PMBASE_SIZE, DRV_NAME)) {
|
||||
if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) {
|
||||
dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
|
||||
pmbase + 0xF0);
|
||||
return -EBUSY;
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
priv->iobase = devm_ioport_map(&pdev->dev, pmbase + PMBASE_OFFSET,
|
||||
PMBASE_SIZE);
|
||||
priv->iobase = ioport_map(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
if (!priv->iobase) {
|
||||
pr_err(DRV_NAME "Cannot map ioport\n");
|
||||
return -ENOMEM;
|
||||
err = -EINVAL;
|
||||
goto err_iomap;
|
||||
}
|
||||
|
||||
amd_rng.priv = (unsigned long)priv;
|
||||
priv->pmbase = pmbase;
|
||||
priv->pcidev = pdev;
|
||||
|
||||
pr_info(DRV_NAME " detected\n");
|
||||
return devm_hwrng_register(&pdev->dev, &amd_rng);
|
||||
err = hwrng_register(&amd_rng);
|
||||
if (err) {
|
||||
pr_err(DRV_NAME " registering failed (%d)\n", err);
|
||||
goto err_hwrng;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_hwrng:
|
||||
ioport_unmap(priv->iobase);
|
||||
err_iomap:
|
||||
release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
out:
|
||||
kfree(priv);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit mod_exit(void)
|
||||
{
|
||||
struct amd768_priv *priv;
|
||||
|
||||
priv = (struct amd768_priv *)amd_rng.priv;
|
||||
|
||||
hwrng_unregister(&amd_rng);
|
||||
|
||||
ioport_unmap(priv->iobase);
|
||||
|
||||
release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
module_init(mod_init);
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
#define GEODE_RNG_DATA_REG 0x50
|
||||
#define GEODE_RNG_STATUS_REG 0x54
|
||||
|
||||
@@ -82,6 +85,7 @@ static struct hwrng geode_rng = {
|
||||
|
||||
static int __init mod_init(void)
|
||||
{
|
||||
int err = -ENODEV;
|
||||
struct pci_dev *pdev = NULL;
|
||||
const struct pci_device_id *ent;
|
||||
void __iomem *mem;
|
||||
@@ -89,27 +93,43 @@ static int __init mod_init(void)
|
||||
|
||||
for_each_pci_dev(pdev) {
|
||||
ent = pci_match_id(pci_tbl, pdev);
|
||||
if (ent) {
|
||||
rng_base = pci_resource_start(pdev, 0);
|
||||
if (rng_base == 0)
|
||||
return -ENODEV;
|
||||
|
||||
mem = devm_ioremap(&pdev->dev, rng_base, 0x58);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
geode_rng.priv = (unsigned long)mem;
|
||||
|
||||
pr_info("AMD Geode RNG detected\n");
|
||||
return devm_hwrng_register(&pdev->dev, &geode_rng);
|
||||
}
|
||||
if (ent)
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* Device not found. */
|
||||
return -ENODEV;
|
||||
goto out;
|
||||
|
||||
found:
|
||||
rng_base = pci_resource_start(pdev, 0);
|
||||
if (rng_base == 0)
|
||||
goto out;
|
||||
err = -ENOMEM;
|
||||
mem = ioremap(rng_base, 0x58);
|
||||
if (!mem)
|
||||
goto out;
|
||||
geode_rng.priv = (unsigned long)mem;
|
||||
|
||||
pr_info("AMD Geode RNG detected\n");
|
||||
err = hwrng_register(&geode_rng);
|
||||
if (err) {
|
||||
pr_err(PFX "RNG registering failed (%d)\n",
|
||||
err);
|
||||
goto err_unmap;
|
||||
}
|
||||
out:
|
||||
return err;
|
||||
|
||||
err_unmap:
|
||||
iounmap(mem);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void __exit mod_exit(void)
|
||||
{
|
||||
void __iomem *mem = (void __iomem *)geode_rng.priv;
|
||||
|
||||
hwrng_unregister(&geode_rng);
|
||||
iounmap(mem);
|
||||
}
|
||||
|
||||
module_init(mod_init);
|
||||
|
||||
@@ -608,7 +608,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
|
||||
0x150, 0, 4, 24, 2, BIT(31),
|
||||
CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(31), 0);
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
|
||||
|
||||
|
||||
@@ -85,6 +85,10 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
|
||||
unsigned int m, p;
|
||||
u32 reg;
|
||||
|
||||
/* Adjust parent_rate according to pre-dividers */
|
||||
ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux,
|
||||
-1, &parent_rate);
|
||||
|
||||
reg = readl(cmp->common.base + cmp->common.reg);
|
||||
|
||||
m = reg >> cmp->m.shift;
|
||||
@@ -114,6 +118,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned int m, p;
|
||||
u32 reg;
|
||||
|
||||
/* Adjust parent_rate according to pre-dividers */
|
||||
ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux,
|
||||
-1, &parent_rate);
|
||||
|
||||
max_m = cmp->m.max ?: 1 << cmp->m.width;
|
||||
max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
|
||||
|
||||
|
||||
@@ -1190,6 +1190,9 @@ static int cpufreq_online(unsigned int cpu)
|
||||
for_each_cpu(j, policy->related_cpus)
|
||||
per_cpu(cpufreq_cpu_data, j) = policy;
|
||||
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
||||
} else {
|
||||
policy->min = policy->user_policy.min;
|
||||
policy->max = policy->user_policy.max;
|
||||
}
|
||||
|
||||
if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
|
||||
|
||||
@@ -283,11 +283,14 @@ EXPORT_SYMBOL_GPL(ccp_version);
|
||||
*/
|
||||
int ccp_enqueue_cmd(struct ccp_cmd *cmd)
|
||||
{
|
||||
struct ccp_device *ccp = ccp_get_device();
|
||||
struct ccp_device *ccp;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* Some commands might need to be sent to a specific device */
|
||||
ccp = cmd->ccp ? cmd->ccp : ccp_get_device();
|
||||
|
||||
if (!ccp)
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
@@ -390,6 +390,7 @@ static struct ccp_dma_desc *ccp_create_desc(struct dma_chan *dma_chan,
|
||||
goto err;
|
||||
|
||||
ccp_cmd = &cmd->ccp_cmd;
|
||||
ccp_cmd->ccp = chan->ccp;
|
||||
ccp_pt = &ccp_cmd->u.passthru_nomap;
|
||||
ccp_cmd->flags = CCP_CMD_MAY_BACKLOG;
|
||||
ccp_cmd->flags |= CCP_CMD_PASSTHRU_NO_DMA_MAP;
|
||||
|
||||
@@ -334,6 +334,7 @@ static int __dax_dev_fault(struct dax_dev *dax_dev, struct vm_area_struct *vma,
|
||||
int rc = VM_FAULT_SIGBUS;
|
||||
phys_addr_t phys;
|
||||
pfn_t pfn;
|
||||
unsigned int fault_size = PAGE_SIZE;
|
||||
|
||||
if (check_vma(dax_dev, vma, __func__))
|
||||
return VM_FAULT_SIGBUS;
|
||||
@@ -344,6 +345,9 @@ static int __dax_dev_fault(struct dax_dev *dax_dev, struct vm_area_struct *vma,
|
||||
return VM_FAULT_SIGBUS;
|
||||
}
|
||||
|
||||
if (fault_size != dax_region->align)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE);
|
||||
if (phys == -1) {
|
||||
dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__,
|
||||
@@ -389,6 +393,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev,
|
||||
phys_addr_t phys;
|
||||
pgoff_t pgoff;
|
||||
pfn_t pfn;
|
||||
unsigned int fault_size = PMD_SIZE;
|
||||
|
||||
if (check_vma(dax_dev, vma, __func__))
|
||||
return VM_FAULT_SIGBUS;
|
||||
@@ -405,6 +410,16 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev,
|
||||
return VM_FAULT_SIGBUS;
|
||||
}
|
||||
|
||||
if (fault_size < dax_region->align)
|
||||
return VM_FAULT_SIGBUS;
|
||||
else if (fault_size > dax_region->align)
|
||||
return VM_FAULT_FALLBACK;
|
||||
|
||||
/* if we are outside of the VMA */
|
||||
if (pmd_addr < vma->vm_start ||
|
||||
(pmd_addr + PMD_SIZE) > vma->vm_end)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
pgoff = linear_page_index(vma, pmd_addr);
|
||||
phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE);
|
||||
if (phys == -1) {
|
||||
|
||||
@@ -3507,9 +3507,13 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
|
||||
max_mclk = 80000;
|
||||
}
|
||||
} else if (adev->asic_type == CHIP_OLAND) {
|
||||
if ((adev->pdev->device == 0x6604) &&
|
||||
(adev->pdev->subsystem_vendor == 0x1028) &&
|
||||
(adev->pdev->subsystem_device == 0x066F)) {
|
||||
if ((adev->pdev->revision == 0xC7) ||
|
||||
(adev->pdev->revision == 0x80) ||
|
||||
(adev->pdev->revision == 0x81) ||
|
||||
(adev->pdev->revision == 0x83) ||
|
||||
(adev->pdev->revision == 0x87) ||
|
||||
(adev->pdev->device == 0x6604) ||
|
||||
(adev->pdev->device == 0x6605)) {
|
||||
max_sclk = 75000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,6 +1382,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
phy_power_on(dp->phy);
|
||||
|
||||
analogix_dp_init_dp(dp);
|
||||
@@ -1414,9 +1415,15 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
|
||||
goto err_disable_pm_runtime;
|
||||
}
|
||||
|
||||
phy_power_off(dp->phy);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_pm_runtime:
|
||||
|
||||
phy_power_off(dp->phy);
|
||||
pm_runtime_put(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1382,6 +1382,15 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock)
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
void release_crtc_commit(struct completion *completion)
|
||||
{
|
||||
struct drm_crtc_commit *commit = container_of(completion,
|
||||
typeof(*commit),
|
||||
flip_done);
|
||||
|
||||
drm_crtc_commit_put(commit);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_setup_commit - setup possibly nonblocking commit
|
||||
* @state: new modeset state to be committed
|
||||
@@ -1474,6 +1483,8 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
|
||||
}
|
||||
|
||||
crtc_state->event->base.completion = &commit->flip_done;
|
||||
crtc_state->event->base.completion_release = release_crtc_commit;
|
||||
drm_crtc_commit_get(commit);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -686,8 +686,8 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
|
||||
assert_spin_locked(&dev->event_lock);
|
||||
|
||||
if (e->completion) {
|
||||
/* ->completion might disappear as soon as it signalled. */
|
||||
complete_all(e->completion);
|
||||
e->completion_release(e->completion);
|
||||
e->completion = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -506,12 +506,15 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
|
||||
|
||||
wait_for_completion(&info->waitevent);
|
||||
|
||||
if (channel->rescind) {
|
||||
ret = -ENODEV;
|
||||
goto post_msg_err;
|
||||
}
|
||||
|
||||
post_msg_err:
|
||||
/*
|
||||
* If the channel has been rescinded;
|
||||
* we will be awakened by the rescind
|
||||
* handler; set the error code to zero so we don't leak memory.
|
||||
*/
|
||||
if (channel->rescind)
|
||||
ret = 0;
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
@@ -779,6 +779,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
|
||||
/* Allocate the channel object and save this offer. */
|
||||
newchannel = alloc_channel();
|
||||
if (!newchannel) {
|
||||
vmbus_release_relid(offer->child_relid);
|
||||
pr_err("Unable to allocate channel object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,8 +218,10 @@ static int intel_th_output_activate(struct intel_th_device *thdev)
|
||||
else
|
||||
intel_th_trace_enable(thdev);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pm_runtime_put(&thdev->dev);
|
||||
module_put(thdrv->driver.owner);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,9 @@ static irqreturn_t tiadc_irq_h(int irq, void *private)
|
||||
{
|
||||
struct iio_dev *indio_dev = private;
|
||||
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||
unsigned int status, config;
|
||||
unsigned int status, config, adc_fsm;
|
||||
unsigned short count = 0;
|
||||
|
||||
status = tiadc_readl(adc_dev, REG_IRQSTATUS);
|
||||
|
||||
/*
|
||||
@@ -165,6 +167,15 @@ static irqreturn_t tiadc_irq_h(int irq, void *private)
|
||||
tiadc_writel(adc_dev, REG_CTRL, config);
|
||||
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
|
||||
| IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
|
||||
|
||||
/* wait for idle state.
|
||||
* ADC needs to finish the current conversion
|
||||
* before disabling the module
|
||||
*/
|
||||
do {
|
||||
adc_fsm = tiadc_readl(adc_dev, REG_ADCFSM);
|
||||
} while (adc_fsm != 0x10 && count++ < 100);
|
||||
|
||||
tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
|
||||
return IRQ_HANDLED;
|
||||
} else if (status & IRQENB_FIFO1THRES) {
|
||||
|
||||
@@ -51,8 +51,6 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
|
||||
st->report_state.report_id,
|
||||
st->report_state.index,
|
||||
HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
|
||||
|
||||
poll_value = hid_sensor_read_poll_value(st);
|
||||
} else {
|
||||
int val;
|
||||
|
||||
@@ -89,7 +87,9 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
|
||||
sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
|
||||
st->power_state.index,
|
||||
sizeof(state_val), &state_val);
|
||||
if (state && poll_value)
|
||||
if (state)
|
||||
poll_value = hid_sensor_read_poll_value(st);
|
||||
if (poll_value > 0)
|
||||
msleep_interruptible(poll_value * 2);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -767,7 +767,7 @@ power_off:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __exit ak8974_remove(struct i2c_client *i2c)
|
||||
static int ak8974_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
|
||||
struct ak8974 *ak8974 = iio_priv(indio_dev);
|
||||
@@ -849,7 +849,7 @@ static struct i2c_driver ak8974_driver = {
|
||||
.of_match_table = of_match_ptr(ak8974_of_match),
|
||||
},
|
||||
.probe = ak8974_probe,
|
||||
.remove = __exit_p(ak8974_remove),
|
||||
.remove = ak8974_remove,
|
||||
.id_table = ak8974_id,
|
||||
};
|
||||
module_i2c_driver(ak8974_driver);
|
||||
|
||||
@@ -141,6 +141,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 2)
|
||||
return -ENODEV;
|
||||
|
||||
epirq = &interface->endpoint[0].desc;
|
||||
epout = &interface->endpoint[1].desc;
|
||||
|
||||
|
||||
@@ -700,6 +700,10 @@ static int cm109_usb_probe(struct usb_interface *intf,
|
||||
int error = -ENOMEM;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
|
||||
if (!usb_endpoint_is_int_in(endpoint))
|
||||
|
||||
@@ -1667,6 +1667,10 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
|
||||
return -EINVAL;
|
||||
|
||||
alt = pcu->ctrl_intf->cur_altsetting;
|
||||
|
||||
if (alt->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
pcu->ep_ctrl = &alt->endpoint[0].desc;
|
||||
pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
|
||||
|
||||
|
||||
@@ -875,6 +875,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
int ret, pipe, i;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
if (!usb_endpoint_is_int_in(endpoint))
|
||||
return -ENODEV;
|
||||
|
||||
@@ -1290,10 +1290,8 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
|
||||
/* handle buttons */
|
||||
if (pkt_id == SS4_PACKET_ID_STICK) {
|
||||
f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
}
|
||||
f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
} else {
|
||||
f->left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
@@ -2461,14 +2459,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
|
||||
int num_y_electrode;
|
||||
int x_pitch, y_pitch, x_phys, y_phys;
|
||||
|
||||
num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
|
||||
num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id)) {
|
||||
num_x_electrode =
|
||||
SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
|
||||
num_y_electrode =
|
||||
SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
|
||||
|
||||
priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
priv->x_max =
|
||||
(num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
|
||||
priv->y_max =
|
||||
(num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
|
||||
|
||||
x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
|
||||
y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
|
||||
|
||||
} else {
|
||||
num_x_electrode =
|
||||
SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
|
||||
num_y_electrode =
|
||||
SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
|
||||
|
||||
priv->x_max =
|
||||
(num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
priv->y_max =
|
||||
(num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
|
||||
x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
}
|
||||
|
||||
x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
|
||||
y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
|
||||
@@ -2484,7 +2502,10 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
|
||||
{
|
||||
unsigned char is_btnless;
|
||||
|
||||
is_btnless = (otp[1][1] >> 3) & 0x01;
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id))
|
||||
is_btnless = (otp[1][0] >> 1) & 0x01;
|
||||
else
|
||||
is_btnless = (otp[1][1] >> 3) & 0x01;
|
||||
|
||||
if (is_btnless)
|
||||
priv->flags |= ALPS_BUTTONPAD;
|
||||
@@ -2492,6 +2513,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
|
||||
struct alps_data *priv)
|
||||
{
|
||||
bool is_dual = false;
|
||||
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id))
|
||||
is_dual = (otp[0][0] >> 4) & 0x01;
|
||||
|
||||
if (is_dual)
|
||||
priv->flags |= ALPS_DUALPOINT |
|
||||
ALPS_DUALPOINT_WITH_PRESSURE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
|
||||
struct alps_data *priv)
|
||||
{
|
||||
@@ -2507,6 +2543,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
|
||||
|
||||
alps_update_btn_info_ss4_v2(otp, priv);
|
||||
|
||||
alps_update_dual_info_ss4_v2(otp, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2752,10 +2790,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
|
||||
if (alps_set_defaults_ss4_v2(psmouse, priv))
|
||||
return -EIO;
|
||||
|
||||
if (priv->fw_ver[1] == 0x1)
|
||||
priv->flags |= ALPS_DUALPOINT |
|
||||
ALPS_DUALPOINT_WITH_PRESSURE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2826,10 +2860,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
||||
ec[2] >= 0x90 && ec[2] <= 0x9d) {
|
||||
protocol = &alps_v3_protocol_data;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
|
||||
e7[2] == 0x14 && ec[1] == 0x02) {
|
||||
protocol = &alps_v8_protocol_data;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
|
||||
e7[2] == 0x28 && ec[1] == 0x01) {
|
||||
(e7[2] == 0x14 || e7[2] == 0x28)) {
|
||||
protocol = &alps_v8_protocol_data;
|
||||
} else {
|
||||
psmouse_dbg(psmouse,
|
||||
@@ -2839,7 +2870,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
||||
}
|
||||
|
||||
if (priv) {
|
||||
/* Save the Firmware version */
|
||||
/* Save Device ID and Firmware version */
|
||||
memcpy(priv->dev_id, e7, 3);
|
||||
memcpy(priv->fw_ver, ec, 3);
|
||||
error = alps_set_protocol(psmouse, priv, protocol);
|
||||
if (error)
|
||||
|
||||
@@ -54,6 +54,16 @@ enum SS4_PACKET_ID {
|
||||
|
||||
#define SS4_MASK_NORMAL_BUTTONS 0x07
|
||||
|
||||
#define SS4PLUS_COUNT_PER_ELECTRODE 128
|
||||
#define SS4PLUS_NUMSENSOR_XOFFSET 16
|
||||
#define SS4PLUS_NUMSENSOR_YOFFSET 5
|
||||
#define SS4PLUS_MIN_PITCH_MM 37
|
||||
|
||||
#define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \
|
||||
((_b[1]) == 0x03) && \
|
||||
((_b[2]) == 0x28) \
|
||||
)
|
||||
|
||||
#define SS4_1F_X_V2(_b) ((_b[0] & 0x0007) | \
|
||||
((_b[1] << 3) & 0x0078) | \
|
||||
((_b[1] << 2) & 0x0380) | \
|
||||
@@ -263,6 +273,7 @@ struct alps_data {
|
||||
int addr_command;
|
||||
u16 proto_version;
|
||||
u8 byte0, mask0;
|
||||
u8 dev_id[3];
|
||||
u8 fw_ver[3];
|
||||
int flags;
|
||||
int x_max;
|
||||
|
||||
@@ -218,17 +218,19 @@ static int elan_query_product(struct elan_tp_data *data)
|
||||
|
||||
static int elan_check_ASUS_special_fw(struct elan_tp_data *data)
|
||||
{
|
||||
if (data->ic_type != 0x0E)
|
||||
return false;
|
||||
|
||||
switch (data->product_id) {
|
||||
case 0x05 ... 0x07:
|
||||
case 0x09:
|
||||
case 0x13:
|
||||
if (data->ic_type == 0x0E) {
|
||||
switch (data->product_id) {
|
||||
case 0x05 ... 0x07:
|
||||
case 0x09:
|
||||
case 0x13:
|
||||
return true;
|
||||
}
|
||||
} else if (data->ic_type == 0x08 && data->product_id == 0x26) {
|
||||
/* ASUS EeeBook X205TA */
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __elan_initialize(struct elan_tp_data *data)
|
||||
|
||||
@@ -119,6 +119,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Dell Embedded Box PC 3000 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* OQO Model 01 */
|
||||
.matches = {
|
||||
|
||||
@@ -340,6 +340,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
int error;
|
||||
int i;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!hanwang || !input_dev) {
|
||||
|
||||
@@ -122,6 +122,9 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
struct input_dev *input_dev;
|
||||
int error = -ENOMEM;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!kbtab || !input_dev)
|
||||
|
||||
@@ -527,6 +527,9 @@ static int sur40_probe(struct usb_interface *interface,
|
||||
if (iface_desc->desc.bInterfaceClass != 0xFF)
|
||||
return -ENODEV;
|
||||
|
||||
if (iface_desc->desc.bNumEndpoints < 5)
|
||||
return -ENODEV;
|
||||
|
||||
/* Use endpoint #4 (0x86). */
|
||||
endpoint = &iface_desc->endpoint[4].desc;
|
||||
if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)
|
||||
|
||||
@@ -915,7 +915,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
|
||||
* which we used for the IOMMU lookup. Strictly speaking
|
||||
* we could do this for all PCI devices; we only need to
|
||||
* get the BDF# from the scope table for ACPI matches. */
|
||||
if (pdev->is_virtfn)
|
||||
if (pdev && pdev->is_virtfn)
|
||||
goto got_pdev;
|
||||
|
||||
*bus = drhd->devices[i].bus;
|
||||
|
||||
@@ -28,13 +28,9 @@
|
||||
#include "sdhci-pltfm.h"
|
||||
#include <linux/of.h>
|
||||
|
||||
#define SDHCI_ARASAN_CLK_CTRL_OFFSET 0x2c
|
||||
#define SDHCI_ARASAN_VENDOR_REGISTER 0x78
|
||||
|
||||
#define VENDOR_ENHANCED_STROBE BIT(0)
|
||||
#define CLK_CTRL_TIMEOUT_SHIFT 16
|
||||
#define CLK_CTRL_TIMEOUT_MASK (0xf << CLK_CTRL_TIMEOUT_SHIFT)
|
||||
#define CLK_CTRL_TIMEOUT_MIN_EXP 13
|
||||
|
||||
#define PHY_CLK_TOO_SLOW_HZ 400000
|
||||
|
||||
@@ -163,15 +159,15 @@ static int sdhci_arasan_syscon_write(struct sdhci_host *host,
|
||||
|
||||
static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
|
||||
{
|
||||
u32 div;
|
||||
unsigned long freq;
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
|
||||
div = readl(host->ioaddr + SDHCI_ARASAN_CLK_CTRL_OFFSET);
|
||||
div = (div & CLK_CTRL_TIMEOUT_MASK) >> CLK_CTRL_TIMEOUT_SHIFT;
|
||||
/* SDHCI timeout clock is in kHz */
|
||||
freq = DIV_ROUND_UP(clk_get_rate(pltfm_host->clk), 1000);
|
||||
|
||||
freq = clk_get_rate(pltfm_host->clk);
|
||||
freq /= 1 << (CLK_CTRL_TIMEOUT_MIN_EXP + div);
|
||||
/* or in MHz */
|
||||
if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
|
||||
freq = DIV_ROUND_UP(freq, 1000);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
@@ -85,11 +85,30 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
|
||||
}
|
||||
|
||||
/*
|
||||
* In this specific implementation of the SDHCI controller, the power register
|
||||
* needs to have a valid voltage set even when the power supply is managed by
|
||||
* an external regulator.
|
||||
*/
|
||||
static void sdhci_at91_set_power(struct sdhci_host *host, unsigned char mode,
|
||||
unsigned short vdd)
|
||||
{
|
||||
if (!IS_ERR(host->mmc->supply.vmmc)) {
|
||||
struct mmc_host *mmc = host->mmc;
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
|
||||
spin_lock_irq(&host->lock);
|
||||
}
|
||||
sdhci_set_power_noreg(host, mode, vdd);
|
||||
}
|
||||
|
||||
static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
|
||||
.set_clock = sdhci_at91_set_clock,
|
||||
.set_bus_width = sdhci_set_bus_width,
|
||||
.reset = sdhci_reset,
|
||||
.set_uhs_signaling = sdhci_set_uhs_signaling,
|
||||
.set_power = sdhci_at91_set_power,
|
||||
};
|
||||
|
||||
static const struct sdhci_pltfm_data soc_data_sama5d2 = {
|
||||
|
||||
@@ -412,6 +412,8 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
|
||||
if (mode == MMC_POWER_OFF)
|
||||
return;
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
|
||||
/*
|
||||
* Bus power might not enable after D3 -> D0 transition due to the
|
||||
* present state not yet having propagated. Retry for up to 2ms.
|
||||
@@ -424,6 +426,8 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
|
||||
reg |= SDHCI_POWER_ON;
|
||||
sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
|
||||
}
|
||||
|
||||
spin_lock_irq(&host->lock);
|
||||
}
|
||||
|
||||
static const struct sdhci_ops sdhci_intel_byt_ops = {
|
||||
|
||||
@@ -1371,7 +1371,9 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
return;
|
||||
}
|
||||
timeout--;
|
||||
mdelay(1);
|
||||
spin_unlock_irq(&host->lock);
|
||||
usleep_range(900, 1100);
|
||||
spin_lock_irq(&host->lock);
|
||||
}
|
||||
|
||||
clk |= SDHCI_CLOCK_CARD_EN;
|
||||
|
||||
@@ -426,6 +426,9 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
struct ushc_data *ushc;
|
||||
int ret;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
|
||||
if (mmc == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -917,8 +917,8 @@
|
||||
#define RX_PACKET_ATTRIBUTES_CSUM_DONE_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 1
|
||||
#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX 2
|
||||
#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_LAST_INDEX 2
|
||||
#define RX_PACKET_ATTRIBUTES_LAST_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_INDEX 3
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_CONTEXT_INDEX 4
|
||||
@@ -927,6 +927,8 @@
|
||||
#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_RSS_HASH_INDEX 6
|
||||
#define RX_PACKET_ATTRIBUTES_RSS_HASH_WIDTH 1
|
||||
#define RX_PACKET_ATTRIBUTES_FIRST_INDEX 7
|
||||
#define RX_PACKET_ATTRIBUTES_FIRST_WIDTH 1
|
||||
|
||||
#define RX_NORMAL_DESC0_OVT_INDEX 0
|
||||
#define RX_NORMAL_DESC0_OVT_WIDTH 16
|
||||
|
||||
@@ -1721,10 +1721,15 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
|
||||
|
||||
/* Get the header length */
|
||||
if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD)) {
|
||||
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
|
||||
FIRST, 1);
|
||||
rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2,
|
||||
RX_NORMAL_DESC2, HL);
|
||||
if (rdata->rx.hdr_len)
|
||||
pdata->ext_stats.rx_split_header_packets++;
|
||||
} else {
|
||||
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
|
||||
FIRST, 0);
|
||||
}
|
||||
|
||||
/* Get the RSS hash */
|
||||
@@ -1747,19 +1752,16 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the packet length */
|
||||
rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
|
||||
|
||||
if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) {
|
||||
/* Not all the data has been transferred for this packet */
|
||||
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
|
||||
INCOMPLETE, 1);
|
||||
/* Not all the data has been transferred for this packet */
|
||||
if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is the last of the data for this packet */
|
||||
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
|
||||
INCOMPLETE, 0);
|
||||
LAST, 1);
|
||||
|
||||
/* Get the packet length */
|
||||
rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
|
||||
|
||||
/* Set checksum done indicator as appropriate */
|
||||
if (netdev->features & NETIF_F_RXCSUM)
|
||||
|
||||
@@ -1752,13 +1752,12 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 *packet;
|
||||
unsigned int copy_len;
|
||||
|
||||
skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
/* Start with the header buffer which may contain just the header
|
||||
/* Pull in the header buffer which may contain just the header
|
||||
* or the header plus data
|
||||
*/
|
||||
dma_sync_single_range_for_cpu(pdata->dev, rdata->rx.hdr.dma_base,
|
||||
@@ -1767,30 +1766,49 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
|
||||
|
||||
packet = page_address(rdata->rx.hdr.pa.pages) +
|
||||
rdata->rx.hdr.pa.pages_offset;
|
||||
copy_len = (rdata->rx.hdr_len) ? rdata->rx.hdr_len : len;
|
||||
copy_len = min(rdata->rx.hdr.dma_len, copy_len);
|
||||
skb_copy_to_linear_data(skb, packet, copy_len);
|
||||
skb_put(skb, copy_len);
|
||||
|
||||
len -= copy_len;
|
||||
if (len) {
|
||||
/* Add the remaining data as a frag */
|
||||
dma_sync_single_range_for_cpu(pdata->dev,
|
||||
rdata->rx.buf.dma_base,
|
||||
rdata->rx.buf.dma_off,
|
||||
rdata->rx.buf.dma_len,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
|
||||
rdata->rx.buf.pa.pages,
|
||||
rdata->rx.buf.pa.pages_offset,
|
||||
len, rdata->rx.buf.dma_len);
|
||||
rdata->rx.buf.pa.pages = NULL;
|
||||
}
|
||||
skb_copy_to_linear_data(skb, packet, len);
|
||||
skb_put(skb, len);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static unsigned int xgbe_rx_buf1_len(struct xgbe_ring_data *rdata,
|
||||
struct xgbe_packet_data *packet)
|
||||
{
|
||||
/* Always zero if not the first descriptor */
|
||||
if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, FIRST))
|
||||
return 0;
|
||||
|
||||
/* First descriptor with split header, return header length */
|
||||
if (rdata->rx.hdr_len)
|
||||
return rdata->rx.hdr_len;
|
||||
|
||||
/* First descriptor but not the last descriptor and no split header,
|
||||
* so the full buffer was used
|
||||
*/
|
||||
if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, LAST))
|
||||
return rdata->rx.hdr.dma_len;
|
||||
|
||||
/* First descriptor and last descriptor and no split header, so
|
||||
* calculate how much of the buffer was used
|
||||
*/
|
||||
return min_t(unsigned int, rdata->rx.hdr.dma_len, rdata->rx.len);
|
||||
}
|
||||
|
||||
static unsigned int xgbe_rx_buf2_len(struct xgbe_ring_data *rdata,
|
||||
struct xgbe_packet_data *packet,
|
||||
unsigned int len)
|
||||
{
|
||||
/* Always the full buffer if not the last descriptor */
|
||||
if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, LAST))
|
||||
return rdata->rx.buf.dma_len;
|
||||
|
||||
/* Last descriptor so calculate how much of the buffer was used
|
||||
* for the last bit of data
|
||||
*/
|
||||
return rdata->rx.len - len;
|
||||
}
|
||||
|
||||
static int xgbe_tx_poll(struct xgbe_channel *channel)
|
||||
{
|
||||
struct xgbe_prv_data *pdata = channel->pdata;
|
||||
@@ -1873,8 +1891,8 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
|
||||
struct napi_struct *napi;
|
||||
struct sk_buff *skb;
|
||||
struct skb_shared_hwtstamps *hwtstamps;
|
||||
unsigned int incomplete, error, context_next, context;
|
||||
unsigned int len, rdesc_len, max_len;
|
||||
unsigned int last, error, context_next, context;
|
||||
unsigned int len, buf1_len, buf2_len, max_len;
|
||||
unsigned int received = 0;
|
||||
int packet_count = 0;
|
||||
|
||||
@@ -1884,7 +1902,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
|
||||
if (!ring)
|
||||
return 0;
|
||||
|
||||
incomplete = 0;
|
||||
last = 0;
|
||||
context_next = 0;
|
||||
|
||||
napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi;
|
||||
@@ -1918,9 +1936,8 @@ read_again:
|
||||
received++;
|
||||
ring->cur++;
|
||||
|
||||
incomplete = XGMAC_GET_BITS(packet->attributes,
|
||||
RX_PACKET_ATTRIBUTES,
|
||||
INCOMPLETE);
|
||||
last = XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
|
||||
LAST);
|
||||
context_next = XGMAC_GET_BITS(packet->attributes,
|
||||
RX_PACKET_ATTRIBUTES,
|
||||
CONTEXT_NEXT);
|
||||
@@ -1929,7 +1946,7 @@ read_again:
|
||||
CONTEXT);
|
||||
|
||||
/* Earlier error, just drain the remaining data */
|
||||
if ((incomplete || context_next) && error)
|
||||
if ((!last || context_next) && error)
|
||||
goto read_again;
|
||||
|
||||
if (error || packet->errors) {
|
||||
@@ -1941,16 +1958,22 @@ read_again:
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
/* Length is cumulative, get this descriptor's length */
|
||||
rdesc_len = rdata->rx.len - len;
|
||||
len += rdesc_len;
|
||||
/* Get the data length in the descriptor buffers */
|
||||
buf1_len = xgbe_rx_buf1_len(rdata, packet);
|
||||
len += buf1_len;
|
||||
buf2_len = xgbe_rx_buf2_len(rdata, packet, len);
|
||||
len += buf2_len;
|
||||
|
||||
if (rdesc_len && !skb) {
|
||||
if (!skb) {
|
||||
skb = xgbe_create_skb(pdata, napi, rdata,
|
||||
rdesc_len);
|
||||
if (!skb)
|
||||
buf1_len);
|
||||
if (!skb) {
|
||||
error = 1;
|
||||
} else if (rdesc_len) {
|
||||
goto skip_data;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf2_len) {
|
||||
dma_sync_single_range_for_cpu(pdata->dev,
|
||||
rdata->rx.buf.dma_base,
|
||||
rdata->rx.buf.dma_off,
|
||||
@@ -1960,13 +1983,14 @@ read_again:
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
|
||||
rdata->rx.buf.pa.pages,
|
||||
rdata->rx.buf.pa.pages_offset,
|
||||
rdesc_len,
|
||||
buf2_len,
|
||||
rdata->rx.buf.dma_len);
|
||||
rdata->rx.buf.pa.pages = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (incomplete || context_next)
|
||||
skip_data:
|
||||
if (!last || context_next)
|
||||
goto read_again;
|
||||
|
||||
if (!skb)
|
||||
@@ -2024,7 +2048,7 @@ next_packet:
|
||||
}
|
||||
|
||||
/* Check if we need to save state before leaving */
|
||||
if (received && (incomplete || context_next)) {
|
||||
if (received && (!last || context_next)) {
|
||||
rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
|
||||
rdata->state_saved = 1;
|
||||
rdata->state.skb = skb;
|
||||
|
||||
@@ -3402,7 +3402,8 @@ static int bcmgenet_suspend(struct device *d)
|
||||
|
||||
bcmgenet_netif_stop(dev);
|
||||
|
||||
phy_suspend(priv->phydev);
|
||||
if (!device_may_wakeup(d))
|
||||
phy_suspend(priv->phydev);
|
||||
|
||||
netif_device_detach(dev);
|
||||
|
||||
@@ -3499,7 +3500,8 @@ static int bcmgenet_resume(struct device *d)
|
||||
|
||||
netif_device_attach(dev);
|
||||
|
||||
phy_resume(priv->phydev);
|
||||
if (!device_may_wakeup(d))
|
||||
phy_resume(priv->phydev);
|
||||
|
||||
if (priv->eee.eee_enabled)
|
||||
bcmgenet_eee_enable_set(dev, true);
|
||||
|
||||
@@ -220,20 +220,6 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
|
||||
udelay(60);
|
||||
}
|
||||
|
||||
static void bcmgenet_internal_phy_setup(struct net_device *dev)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
u32 reg;
|
||||
|
||||
/* Power up PHY */
|
||||
bcmgenet_phy_power_set(dev, true);
|
||||
/* enable APD */
|
||||
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
|
||||
reg |= EXT_PWR_DN_EN_LD;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
bcmgenet_mii_reset(dev);
|
||||
}
|
||||
|
||||
static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
|
||||
{
|
||||
u32 reg;
|
||||
@@ -281,7 +267,6 @@ int bcmgenet_mii_config(struct net_device *dev)
|
||||
|
||||
if (priv->internal_phy) {
|
||||
phy_name = "internal PHY";
|
||||
bcmgenet_internal_phy_setup(dev);
|
||||
} else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
|
||||
phy_name = "MoCA";
|
||||
bcmgenet_moca_phy_setup(priv);
|
||||
|
||||
@@ -367,6 +367,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
|
||||
case MLX5_CMD_OP_QUERY_VPORT_COUNTER:
|
||||
case MLX5_CMD_OP_ALLOC_Q_COUNTER:
|
||||
case MLX5_CMD_OP_QUERY_Q_COUNTER:
|
||||
case MLX5_CMD_OP_SET_RATE_LIMIT:
|
||||
case MLX5_CMD_OP_QUERY_RATE_LIMIT:
|
||||
case MLX5_CMD_OP_ALLOC_PD:
|
||||
case MLX5_CMD_OP_ALLOC_UAR:
|
||||
case MLX5_CMD_OP_CONFIG_INT_MODERATION:
|
||||
@@ -500,6 +502,8 @@ const char *mlx5_command_str(int command)
|
||||
MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER);
|
||||
MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER);
|
||||
MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER);
|
||||
MLX5_COMMAND_STR_CASE(SET_RATE_LIMIT);
|
||||
MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT);
|
||||
MLX5_COMMAND_STR_CASE(ALLOC_PD);
|
||||
MLX5_COMMAND_STR_CASE(DEALLOC_PD);
|
||||
MLX5_COMMAND_STR_CASE(ALLOC_UAR);
|
||||
|
||||
@@ -602,6 +602,10 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
|
||||
if (lro_num_seg > 1) {
|
||||
mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
|
||||
skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg);
|
||||
/* Subtract one since we already counted this as one
|
||||
* "regular" packet in mlx5e_complete_rx_cqe()
|
||||
*/
|
||||
rq->stats.packets += lro_num_seg - 1;
|
||||
rq->stats.lro_packets++;
|
||||
rq->stats.lro_bytes += cqe_bcnt;
|
||||
}
|
||||
|
||||
@@ -427,14 +427,16 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
|
||||
}
|
||||
|
||||
if (is_tcf_vlan(a)) {
|
||||
if (tcf_vlan_action(a) == VLAN_F_POP) {
|
||||
if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
|
||||
attr->action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
|
||||
} else if (tcf_vlan_action(a) == VLAN_F_PUSH) {
|
||||
} else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
|
||||
if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
attr->action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
|
||||
attr->vlan = tcf_vlan_push_vid(a);
|
||||
} else { /* action is TCA_VLAN_ACT_MODIFY */
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -272,15 +272,18 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_sq *sq, struct sk_buff *skb)
|
||||
sq->stats.tso_bytes += skb->len - ihs;
|
||||
}
|
||||
|
||||
sq->stats.packets += skb_shinfo(skb)->gso_segs;
|
||||
num_bytes = skb->len + (skb_shinfo(skb)->gso_segs - 1) * ihs;
|
||||
} else {
|
||||
bf = sq->bf_budget &&
|
||||
!skb->xmit_more &&
|
||||
!skb_shinfo(skb)->nr_frags;
|
||||
ihs = mlx5e_get_inline_hdr_size(sq, skb, bf);
|
||||
sq->stats.packets++;
|
||||
num_bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
|
||||
}
|
||||
|
||||
sq->stats.bytes += num_bytes;
|
||||
wi->num_bytes = num_bytes;
|
||||
|
||||
if (skb_vlan_tag_present(skb)) {
|
||||
@@ -377,8 +380,6 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_sq *sq, struct sk_buff *skb)
|
||||
if (bf)
|
||||
sq->bf_budget--;
|
||||
|
||||
sq->stats.packets++;
|
||||
sq->stats.bytes += num_bytes;
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
dma_unmap_wqe_err:
|
||||
|
||||
@@ -87,7 +87,7 @@ static struct mlx5_profile profile[] = {
|
||||
[2] = {
|
||||
.mask = MLX5_PROF_MASK_QP_SIZE |
|
||||
MLX5_PROF_MASK_MR_CACHE,
|
||||
.log_max_qp = 17,
|
||||
.log_max_qp = 18,
|
||||
.mr_cache[0] = {
|
||||
.size = 500,
|
||||
.limit = 250
|
||||
|
||||
@@ -924,6 +924,8 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
|
||||
{QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */
|
||||
{QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */
|
||||
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
|
||||
{QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */
|
||||
{QMI_FIXED_INTF(0x1e0e, 0x9001, 5)}, /* SIMCom 7230E */
|
||||
|
||||
@@ -467,8 +467,10 @@ static void vrf_rt6_release(struct net_device *dev, struct net_vrf *vrf)
|
||||
}
|
||||
|
||||
if (rt6_local) {
|
||||
if (rt6_local->rt6i_idev)
|
||||
if (rt6_local->rt6i_idev) {
|
||||
in6_dev_put(rt6_local->rt6i_idev);
|
||||
rt6_local->rt6i_idev = NULL;
|
||||
}
|
||||
|
||||
dst = &rt6_local->dst;
|
||||
dev_put(dst->dev);
|
||||
|
||||
@@ -2700,6 +2700,21 @@ static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
|
||||
schedule_work(&pcie_work);
|
||||
}
|
||||
|
||||
static void mwifiex_pcie_free_buffers(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
struct pcie_service_card *card = adapter->card;
|
||||
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
|
||||
|
||||
if (reg->sleep_cookie)
|
||||
mwifiex_pcie_delete_sleep_cookie_buf(adapter);
|
||||
|
||||
mwifiex_pcie_delete_cmdrsp_buf(adapter);
|
||||
mwifiex_pcie_delete_evtbd_ring(adapter);
|
||||
mwifiex_pcie_delete_rxbd_ring(adapter);
|
||||
mwifiex_pcie_delete_txbd_ring(adapter);
|
||||
card->cmdrsp_buf = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function initializes the PCI-E host memory space, WCB rings, etc.
|
||||
*
|
||||
@@ -2812,13 +2827,6 @@ err_enable_dev:
|
||||
|
||||
/*
|
||||
* This function cleans up the allocated card buffers.
|
||||
*
|
||||
* The following are freed by this function -
|
||||
* - TXBD ring buffers
|
||||
* - RXBD ring buffers
|
||||
* - Event BD ring buffers
|
||||
* - Command response ring buffer
|
||||
* - Sleep cookie buffer
|
||||
*/
|
||||
static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
@@ -2834,6 +2842,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
|
||||
"Failed to write driver not-ready signature\n");
|
||||
}
|
||||
|
||||
mwifiex_pcie_free_buffers(adapter);
|
||||
|
||||
if (pdev) {
|
||||
pci_iounmap(pdev, card->pci_mmap);
|
||||
pci_iounmap(pdev, card->pci_mmap1);
|
||||
@@ -3080,10 +3090,7 @@ err_cre_txbd:
|
||||
pci_iounmap(pdev, card->pci_mmap1);
|
||||
}
|
||||
|
||||
/* This function cleans up the PCI-E host memory space.
|
||||
* Some code is extracted from mwifiex_unregister_dev()
|
||||
*
|
||||
*/
|
||||
/* This function cleans up the PCI-E host memory space. */
|
||||
static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
struct pcie_service_card *card = adapter->card;
|
||||
@@ -3095,16 +3102,8 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
|
||||
adapter->seq_num = 0;
|
||||
adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
|
||||
|
||||
if (card) {
|
||||
if (reg->sleep_cookie)
|
||||
mwifiex_pcie_delete_sleep_cookie_buf(adapter);
|
||||
|
||||
mwifiex_pcie_delete_cmdrsp_buf(adapter);
|
||||
mwifiex_pcie_delete_evtbd_ring(adapter);
|
||||
mwifiex_pcie_delete_rxbd_ring(adapter);
|
||||
mwifiex_pcie_delete_txbd_ring(adapter);
|
||||
card->cmdrsp_buf = NULL;
|
||||
}
|
||||
if (card)
|
||||
mwifiex_pcie_free_buffers(adapter);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -939,8 +939,10 @@ parport_register_dev_model(struct parport *port, const char *name,
|
||||
* pardevice fields. -arca
|
||||
*/
|
||||
port->ops->init_state(par_dev, par_dev->state);
|
||||
port->proc_device = par_dev;
|
||||
parport_device_proc_register(par_dev);
|
||||
if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) {
|
||||
port->proc_device = par_dev;
|
||||
parport_device_proc_register(par_dev);
|
||||
}
|
||||
|
||||
return par_dev;
|
||||
|
||||
|
||||
@@ -1380,7 +1380,7 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
|
||||
dev_dbg(&intf->dev, "%s called\n", __func__);
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1443,6 +1443,13 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data->bulk_out || !data->bulk_in) {
|
||||
dev_err(&intf->dev, "bulk endpoints not found\n");
|
||||
retcode = -ENODEV;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
/* Find int endpoint */
|
||||
for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
|
||||
endpoint = &iface_desc->endpoint[n].desc;
|
||||
@@ -1468,8 +1475,10 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
if (data->iin_ep_present) {
|
||||
/* allocate int urb */
|
||||
data->iin_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!data->iin_urb)
|
||||
if (!data->iin_urb) {
|
||||
retcode = -ENOMEM;
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
/* will reference data in int urb */
|
||||
kref_get(&data->kref);
|
||||
@@ -1477,8 +1486,10 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
/* allocate buffer for interrupt in */
|
||||
data->iin_buffer = kmalloc(data->iin_wMaxPacketSize,
|
||||
GFP_KERNEL);
|
||||
if (!data->iin_buffer)
|
||||
if (!data->iin_buffer) {
|
||||
retcode = -ENOMEM;
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
/* fill interrupt urb */
|
||||
usb_fill_int_urb(data->iin_urb, data->usb_dev,
|
||||
@@ -1511,6 +1522,7 @@ error_register:
|
||||
sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
|
||||
sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
|
||||
usbtmc_free_int(data);
|
||||
err_put:
|
||||
kref_put(&data->kref, usbtmc_delete);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
@@ -275,6 +275,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
||||
|
||||
/*
|
||||
* Adjust bInterval for quirked devices.
|
||||
*/
|
||||
/*
|
||||
* This quirk fixes bIntervals reported in ms.
|
||||
*/
|
||||
if (to_usb_device(ddev)->quirks &
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
|
||||
n = clamp(fls(d->bInterval) + 3, i, j);
|
||||
i = j = n;
|
||||
}
|
||||
/*
|
||||
* This quirk fixes bIntervals reported in
|
||||
* linear microframes.
|
||||
*/
|
||||
|
||||
@@ -4266,7 +4266,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
|
||||
struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
|
||||
int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
|
||||
|
||||
if (!udev->usb2_hw_lpm_capable)
|
||||
if (!udev->usb2_hw_lpm_capable || !udev->bos)
|
||||
return;
|
||||
|
||||
if (hub)
|
||||
|
||||
@@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* M-Systems Flash Disk Pioneers */
|
||||
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Baum Vario Ultra */
|
||||
{ USB_DEVICE(0x0904, 0x6101), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
{ USB_DEVICE(0x0904, 0x6102), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
|
||||
/* Keytouch QWERTY Panel keyboard */
|
||||
{ USB_DEVICE(0x0926, 0x3333), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
@@ -535,13 +535,15 @@ static int acm_notify_serial_state(struct f_acm *acm)
|
||||
{
|
||||
struct usb_composite_dev *cdev = acm->port.func.config->cdev;
|
||||
int status;
|
||||
__le16 serial_state;
|
||||
|
||||
spin_lock(&acm->lock);
|
||||
if (acm->notify_req) {
|
||||
dev_dbg(&cdev->gadget->dev, "acm ttyGS%d serial state %04x\n",
|
||||
acm->port_num, acm->serial_state);
|
||||
serial_state = cpu_to_le16(acm->serial_state);
|
||||
status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE,
|
||||
0, &acm->serial_state, sizeof(acm->serial_state));
|
||||
0, &serial_state, sizeof(acm->serial_state));
|
||||
} else {
|
||||
acm->pending = true;
|
||||
status = 0;
|
||||
|
||||
@@ -625,7 +625,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
|
||||
uvc_ss_streaming_comp.wBytesPerInterval =
|
||||
cpu_to_le16(max_packet_size * max_packet_mult *
|
||||
opts->streaming_maxburst);
|
||||
(opts->streaming_maxburst + 1));
|
||||
|
||||
/* Allocate endpoints. */
|
||||
ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
|
||||
|
||||
@@ -346,6 +346,9 @@ static int idmouse_probe(struct usb_interface *interface,
|
||||
if (iface_desc->desc.bInterfaceClass != 0x0A)
|
||||
return -ENODEV;
|
||||
|
||||
if (iface_desc->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
/* allocate memory for our device state and initialize it */
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (dev == NULL)
|
||||
|
||||
@@ -366,6 +366,10 @@ static int lvs_rh_probe(struct usb_interface *intf,
|
||||
|
||||
hdev = interface_to_usbdev(intf);
|
||||
desc = intf->cur_altsetting;
|
||||
|
||||
if (desc->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &desc->endpoint[0].desc;
|
||||
|
||||
/* valid only for SS root hub */
|
||||
|
||||
@@ -708,6 +708,11 @@ static int uss720_probe(struct usb_interface *intf,
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 3) {
|
||||
usb_put_dev(usbdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate parport interface
|
||||
*/
|
||||
|
||||
@@ -232,8 +232,27 @@ static void cppi41_dma_callback(void *private_data)
|
||||
transferred < cppi41_channel->packet_sz)
|
||||
cppi41_channel->prog_len = 0;
|
||||
|
||||
if (cppi41_channel->is_tx)
|
||||
empty = musb_is_tx_fifo_empty(hw_ep);
|
||||
if (cppi41_channel->is_tx) {
|
||||
u8 type;
|
||||
|
||||
if (is_host_active(musb))
|
||||
type = hw_ep->out_qh->type;
|
||||
else
|
||||
type = hw_ep->ep_in.type;
|
||||
|
||||
if (type == USB_ENDPOINT_XFER_ISOC)
|
||||
/*
|
||||
* Don't use the early-TX-interrupt workaround below
|
||||
* for Isoch transfter. Since Isoch are periodic
|
||||
* transfer, by the time the next transfer is
|
||||
* scheduled, the current one should be done already.
|
||||
*
|
||||
* This avoids audio playback underrun issue.
|
||||
*/
|
||||
empty = true;
|
||||
else
|
||||
empty = musb_is_tx_fifo_empty(hw_ep);
|
||||
}
|
||||
|
||||
if (!cppi41_channel->is_tx || empty) {
|
||||
cppi41_trans_done(cppi41_channel);
|
||||
|
||||
@@ -233,6 +233,14 @@ static void option_instat_callback(struct urb *urb);
|
||||
#define BANDRICH_PRODUCT_1012 0x1012
|
||||
|
||||
#define QUALCOMM_VENDOR_ID 0x05C6
|
||||
/* These Quectel products use Qualcomm's vendor ID */
|
||||
#define QUECTEL_PRODUCT_UC20 0x9003
|
||||
#define QUECTEL_PRODUCT_UC15 0x9090
|
||||
|
||||
#define QUECTEL_VENDOR_ID 0x2c7c
|
||||
/* These Quectel products use Quectel's vendor ID */
|
||||
#define QUECTEL_PRODUCT_EC21 0x0121
|
||||
#define QUECTEL_PRODUCT_EC25 0x0125
|
||||
|
||||
#define CMOTECH_VENDOR_ID 0x16d8
|
||||
#define CMOTECH_PRODUCT_6001 0x6001
|
||||
@@ -1161,7 +1169,14 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
|
||||
/* Quectel products using Qualcomm vendor ID */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
/* Quectel products using Quectel vendor ID */
|
||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
|
||||
|
||||
@@ -169,6 +169,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81b1)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
|
||||
{DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */
|
||||
{DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */
|
||||
|
||||
/* Huawei devices */
|
||||
{DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
|
||||
|
||||
@@ -39,6 +39,9 @@ int wa_create(struct wahc *wa, struct usb_interface *iface,
|
||||
int result;
|
||||
struct device *dev = &iface->dev;
|
||||
|
||||
if (iface->cur_altsetting->desc.bNumEndpoints < 3)
|
||||
return -ENODEV;
|
||||
|
||||
result = wa_rpipes_create(wa);
|
||||
if (result < 0)
|
||||
goto error_rpipes_create;
|
||||
|
||||
@@ -823,6 +823,9 @@ static int hwarc_probe(struct usb_interface *iface,
|
||||
struct hwarc *hwarc;
|
||||
struct device *dev = &iface->dev;
|
||||
|
||||
if (iface->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
result = -ENOMEM;
|
||||
uwb_rc = uwb_rc_alloc();
|
||||
if (uwb_rc == NULL) {
|
||||
|
||||
@@ -362,6 +362,9 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
|
||||
result);
|
||||
}
|
||||
|
||||
if (iface->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
result = -ENOMEM;
|
||||
i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL);
|
||||
if (i1480_usb == NULL) {
|
||||
|
||||
@@ -1167,6 +1167,8 @@ static void fbcon_free_font(struct display *p, bool freefont)
|
||||
p->userfont = 0;
|
||||
}
|
||||
|
||||
static void set_vc_hi_font(struct vc_data *vc, bool set);
|
||||
|
||||
static void fbcon_deinit(struct vc_data *vc)
|
||||
{
|
||||
struct display *p = &fb_display[vc->vc_num];
|
||||
@@ -1202,6 +1204,9 @@ finished:
|
||||
if (free_font)
|
||||
vc->vc_font.data = NULL;
|
||||
|
||||
if (vc->vc_hi_font_mask)
|
||||
set_vc_hi_font(vc, false);
|
||||
|
||||
if (!con_is_bound(&fb_con))
|
||||
fbcon_exit();
|
||||
|
||||
@@ -2438,32 +2443,10 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
||||
const u8 * data, int userfont)
|
||||
/* set/clear vc_hi_font_mask and update vc attrs accordingly */
|
||||
static void set_vc_hi_font(struct vc_data *vc, bool set)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct display *p = &fb_display[vc->vc_num];
|
||||
int resize;
|
||||
int cnt;
|
||||
char *old_data = NULL;
|
||||
|
||||
if (con_is_visible(vc) && softback_lines)
|
||||
fbcon_set_origin(vc);
|
||||
|
||||
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
|
||||
if (p->userfont)
|
||||
old_data = vc->vc_font.data;
|
||||
if (userfont)
|
||||
cnt = FNTCHARCNT(data);
|
||||
else
|
||||
cnt = 256;
|
||||
vc->vc_font.data = (void *)(p->fontdata = data);
|
||||
if ((p->userfont = userfont))
|
||||
REFCOUNT(data)++;
|
||||
vc->vc_font.width = w;
|
||||
vc->vc_font.height = h;
|
||||
if (vc->vc_hi_font_mask && cnt == 256) {
|
||||
if (!set) {
|
||||
vc->vc_hi_font_mask = 0;
|
||||
if (vc->vc_can_do_color) {
|
||||
vc->vc_complement_mask >>= 1;
|
||||
@@ -2486,7 +2469,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
||||
((c & 0xfe00) >> 1) | (c & 0xff);
|
||||
vc->vc_attr >>= 1;
|
||||
}
|
||||
} else if (!vc->vc_hi_font_mask && cnt == 512) {
|
||||
} else {
|
||||
vc->vc_hi_font_mask = 0x100;
|
||||
if (vc->vc_can_do_color) {
|
||||
vc->vc_complement_mask <<= 1;
|
||||
@@ -2518,8 +2501,38 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
||||
} else
|
||||
vc->vc_video_erase_char = c & ~0x100;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
||||
const u8 * data, int userfont)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct display *p = &fb_display[vc->vc_num];
|
||||
int resize;
|
||||
int cnt;
|
||||
char *old_data = NULL;
|
||||
|
||||
if (con_is_visible(vc) && softback_lines)
|
||||
fbcon_set_origin(vc);
|
||||
|
||||
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
|
||||
if (p->userfont)
|
||||
old_data = vc->vc_font.data;
|
||||
if (userfont)
|
||||
cnt = FNTCHARCNT(data);
|
||||
else
|
||||
cnt = 256;
|
||||
vc->vc_font.data = (void *)(p->fontdata = data);
|
||||
if ((p->userfont = userfont))
|
||||
REFCOUNT(data)++;
|
||||
vc->vc_font.width = w;
|
||||
vc->vc_font.height = h;
|
||||
if (vc->vc_hi_font_mask && cnt == 256)
|
||||
set_vc_hi_font(vc, false);
|
||||
else if (!vc->vc_hi_font_mask && cnt == 512)
|
||||
set_vc_hi_font(vc, true);
|
||||
|
||||
if (resize) {
|
||||
int cols, rows;
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/processor.h>
|
||||
#include <xen/xen.h>
|
||||
#include <xen/xen-ops.h>
|
||||
#include <xen/interface/platform.h>
|
||||
#include <asm/xen/hypercall.h>
|
||||
|
||||
@@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(void)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int xen_acpi_processor_resume(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
static void xen_acpi_processor_resume_worker(struct work_struct *dummy)
|
||||
{
|
||||
int rc;
|
||||
|
||||
bitmap_zero(acpi_ids_done, nr_acpi_bits);
|
||||
return xen_upload_processor_pm_data();
|
||||
|
||||
rc = xen_upload_processor_pm_data();
|
||||
if (rc != 0)
|
||||
pr_info("ACPI data upload failed, error = %d\n", rc);
|
||||
}
|
||||
|
||||
struct notifier_block xen_acpi_processor_resume_nb = {
|
||||
.notifier_call = xen_acpi_processor_resume,
|
||||
static void xen_acpi_processor_resume(void)
|
||||
{
|
||||
static DECLARE_WORK(wq, xen_acpi_processor_resume_worker);
|
||||
|
||||
/*
|
||||
* xen_upload_processor_pm_data() calls non-atomic code.
|
||||
* However, the context for xen_acpi_processor_resume is syscore
|
||||
* with only the boot CPU online and in an atomic context.
|
||||
*
|
||||
* So defer the upload for some point safer.
|
||||
*/
|
||||
schedule_work(&wq);
|
||||
}
|
||||
|
||||
static struct syscore_ops xap_syscore_ops = {
|
||||
.resume = xen_acpi_processor_resume,
|
||||
};
|
||||
|
||||
static int __init xen_acpi_processor_init(void)
|
||||
@@ -527,7 +545,7 @@ static int __init xen_acpi_processor_init(void)
|
||||
if (rc)
|
||||
goto err_unregister;
|
||||
|
||||
xen_resume_notifier_register(&xen_acpi_processor_resume_nb);
|
||||
register_syscore_ops(&xap_syscore_ops);
|
||||
|
||||
return 0;
|
||||
err_unregister:
|
||||
@@ -544,7 +562,7 @@ static void __exit xen_acpi_processor_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb);
|
||||
unregister_syscore_ops(&xap_syscore_ops);
|
||||
kfree(acpi_ids_done);
|
||||
kfree(acpi_id_present);
|
||||
kfree(acpi_id_cst_present);
|
||||
|
||||
@@ -1157,10 +1157,9 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
|
||||
set_buffer_uptodate(dir_block);
|
||||
err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
|
||||
if (err)
|
||||
goto out;
|
||||
return err;
|
||||
set_buffer_verified(dir_block);
|
||||
out:
|
||||
return err;
|
||||
return ext4_mark_inode_dirty(handle, inode);
|
||||
}
|
||||
|
||||
static int ext4_convert_inline_data_nolock(handle_t *handle,
|
||||
|
||||
@@ -131,31 +131,26 @@ static __le32 ext4_xattr_block_csum(struct inode *inode,
|
||||
}
|
||||
|
||||
static int ext4_xattr_block_csum_verify(struct inode *inode,
|
||||
sector_t block_nr,
|
||||
struct ext4_xattr_header *hdr)
|
||||
struct buffer_head *bh)
|
||||
{
|
||||
if (ext4_has_metadata_csum(inode->i_sb) &&
|
||||
(hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr)))
|
||||
return 0;
|
||||
return 1;
|
||||
struct ext4_xattr_header *hdr = BHDR(bh);
|
||||
int ret = 1;
|
||||
|
||||
if (ext4_has_metadata_csum(inode->i_sb)) {
|
||||
lock_buffer(bh);
|
||||
ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
|
||||
bh->b_blocknr, hdr));
|
||||
unlock_buffer(bh);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ext4_xattr_block_csum_set(struct inode *inode,
|
||||
sector_t block_nr,
|
||||
struct ext4_xattr_header *hdr)
|
||||
struct buffer_head *bh)
|
||||
{
|
||||
if (!ext4_has_metadata_csum(inode->i_sb))
|
||||
return;
|
||||
|
||||
hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr);
|
||||
}
|
||||
|
||||
static inline int ext4_handle_dirty_xattr_block(handle_t *handle,
|
||||
struct inode *inode,
|
||||
struct buffer_head *bh)
|
||||
{
|
||||
ext4_xattr_block_csum_set(inode, bh->b_blocknr, BHDR(bh));
|
||||
return ext4_handle_dirty_metadata(handle, inode, bh);
|
||||
if (ext4_has_metadata_csum(inode->i_sb))
|
||||
BHDR(bh)->h_checksum = ext4_xattr_block_csum(inode,
|
||||
bh->b_blocknr, BHDR(bh));
|
||||
}
|
||||
|
||||
static inline const struct xattr_handler *
|
||||
@@ -218,7 +213,7 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
|
||||
if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
|
||||
BHDR(bh)->h_blocks != cpu_to_le32(1))
|
||||
return -EFSCORRUPTED;
|
||||
if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh)))
|
||||
if (!ext4_xattr_block_csum_verify(inode, bh))
|
||||
return -EFSBADCRC;
|
||||
error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
|
||||
bh->b_data);
|
||||
@@ -601,23 +596,22 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
|
||||
}
|
||||
}
|
||||
|
||||
ext4_xattr_block_csum_set(inode, bh);
|
||||
/*
|
||||
* Beware of this ugliness: Releasing of xattr block references
|
||||
* from different inodes can race and so we have to protect
|
||||
* from a race where someone else frees the block (and releases
|
||||
* its journal_head) before we are done dirtying the buffer. In
|
||||
* nojournal mode this race is harmless and we actually cannot
|
||||
* call ext4_handle_dirty_xattr_block() with locked buffer as
|
||||
* call ext4_handle_dirty_metadata() with locked buffer as
|
||||
* that function can call sync_dirty_buffer() so for that case
|
||||
* we handle the dirtying after unlocking the buffer.
|
||||
*/
|
||||
if (ext4_handle_valid(handle))
|
||||
error = ext4_handle_dirty_xattr_block(handle, inode,
|
||||
bh);
|
||||
error = ext4_handle_dirty_metadata(handle, inode, bh);
|
||||
unlock_buffer(bh);
|
||||
if (!ext4_handle_valid(handle))
|
||||
error = ext4_handle_dirty_xattr_block(handle, inode,
|
||||
bh);
|
||||
error = ext4_handle_dirty_metadata(handle, inode, bh);
|
||||
if (IS_SYNC(inode))
|
||||
ext4_handle_sync(handle);
|
||||
dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
|
||||
@@ -846,13 +840,14 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
|
||||
ext4_xattr_cache_insert(ext4_mb_cache,
|
||||
bs->bh);
|
||||
}
|
||||
ext4_xattr_block_csum_set(inode, bs->bh);
|
||||
unlock_buffer(bs->bh);
|
||||
if (error == -EFSCORRUPTED)
|
||||
goto bad_block;
|
||||
if (!error)
|
||||
error = ext4_handle_dirty_xattr_block(handle,
|
||||
inode,
|
||||
bs->bh);
|
||||
error = ext4_handle_dirty_metadata(handle,
|
||||
inode,
|
||||
bs->bh);
|
||||
if (error)
|
||||
goto cleanup;
|
||||
goto inserted;
|
||||
@@ -950,10 +945,11 @@ inserted:
|
||||
ce->e_reusable = 0;
|
||||
ea_bdebug(new_bh, "reusing; refcount now=%d",
|
||||
ref);
|
||||
ext4_xattr_block_csum_set(inode, new_bh);
|
||||
unlock_buffer(new_bh);
|
||||
error = ext4_handle_dirty_xattr_block(handle,
|
||||
inode,
|
||||
new_bh);
|
||||
error = ext4_handle_dirty_metadata(handle,
|
||||
inode,
|
||||
new_bh);
|
||||
if (error)
|
||||
goto cleanup_dquot;
|
||||
}
|
||||
@@ -1003,11 +999,12 @@ getblk_failed:
|
||||
goto getblk_failed;
|
||||
}
|
||||
memcpy(new_bh->b_data, s->base, new_bh->b_size);
|
||||
ext4_xattr_block_csum_set(inode, new_bh);
|
||||
set_buffer_uptodate(new_bh);
|
||||
unlock_buffer(new_bh);
|
||||
ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
|
||||
error = ext4_handle_dirty_xattr_block(handle,
|
||||
inode, new_bh);
|
||||
error = ext4_handle_dirty_metadata(handle, inode,
|
||||
new_bh);
|
||||
if (error)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -1125,10 +1125,8 @@ static journal_t *journal_init_common(struct block_device *bdev,
|
||||
|
||||
/* Set up a default-sized revoke table for the new mount. */
|
||||
err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH);
|
||||
if (err) {
|
||||
kfree(journal);
|
||||
return NULL;
|
||||
}
|
||||
if (err)
|
||||
goto err_cleanup;
|
||||
|
||||
spin_lock_init(&journal->j_history_lock);
|
||||
|
||||
@@ -1145,23 +1143,25 @@ static journal_t *journal_init_common(struct block_device *bdev,
|
||||
journal->j_wbufsize = n;
|
||||
journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *),
|
||||
GFP_KERNEL);
|
||||
if (!journal->j_wbuf) {
|
||||
kfree(journal);
|
||||
return NULL;
|
||||
}
|
||||
if (!journal->j_wbuf)
|
||||
goto err_cleanup;
|
||||
|
||||
bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize);
|
||||
if (!bh) {
|
||||
pr_err("%s: Cannot get buffer for journal superblock\n",
|
||||
__func__);
|
||||
kfree(journal->j_wbuf);
|
||||
kfree(journal);
|
||||
return NULL;
|
||||
goto err_cleanup;
|
||||
}
|
||||
journal->j_sb_buffer = bh;
|
||||
journal->j_superblock = (journal_superblock_t *)bh->b_data;
|
||||
|
||||
return journal;
|
||||
|
||||
err_cleanup:
|
||||
kfree(journal->j_wbuf);
|
||||
jbd2_journal_destroy_revoke(journal);
|
||||
kfree(journal);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* jbd2_journal_init_dev and jbd2_journal_init_inode:
|
||||
|
||||
@@ -280,6 +280,7 @@ int jbd2_journal_init_revoke(journal_t *journal, int hash_size)
|
||||
|
||||
fail1:
|
||||
jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]);
|
||||
journal->j_revoke_table[0] = NULL;
|
||||
fail0:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -361,6 +361,7 @@ struct drm_ioctl_desc {
|
||||
/* Event queued up for userspace to read */
|
||||
struct drm_pending_event {
|
||||
struct completion *completion;
|
||||
void (*completion_release)(struct completion *completion);
|
||||
struct drm_event *event;
|
||||
struct fence *fence;
|
||||
struct list_head link;
|
||||
|
||||
@@ -556,7 +556,7 @@ enum ccp_engine {
|
||||
* struct ccp_cmd - CPP operation request
|
||||
* @entry: list element (ccp driver use only)
|
||||
* @work: work element used for callbacks (ccp driver use only)
|
||||
* @ccp: CCP device to be run on (ccp driver use only)
|
||||
* @ccp: CCP device to be run on
|
||||
* @ret: operation return code (ccp driver use only)
|
||||
* @flags: cmd processing flags
|
||||
* @engine: CCP operation to perform
|
||||
|
||||
@@ -62,7 +62,7 @@ void iio_swd_group_init_type_name(struct iio_sw_device *d,
|
||||
const char *name,
|
||||
struct config_item_type *type)
|
||||
{
|
||||
#ifdef CONFIG_CONFIGFS_FS
|
||||
#if IS_ENABLED(CONFIG_CONFIGFS_FS)
|
||||
config_group_init_type_name(&d->group, name, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -50,4 +50,10 @@
|
||||
/* device can't handle Link Power Management */
|
||||
#define USB_QUIRK_NO_LPM BIT(10)
|
||||
|
||||
/*
|
||||
* Device reports its bInterval as linear frames instead of the
|
||||
* USB 2.0 calculation.
|
||||
*/
|
||||
#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11)
|
||||
|
||||
#endif /* __LINUX_USB_QUIRKS_H */
|
||||
|
||||
@@ -1334,7 +1334,6 @@ static int decode_new_up_state_weight(void **p, void *end,
|
||||
if ((map->osd_state[osd] & CEPH_OSD_EXISTS) &&
|
||||
(xorstate & CEPH_OSD_EXISTS)) {
|
||||
pr_info("osd%d does not exist\n", osd);
|
||||
map->osd_weight[osd] = CEPH_OSD_IN;
|
||||
ret = set_primary_affinity(map, osd,
|
||||
CEPH_OSD_DEFAULT_PRIMARY_AFFINITY);
|
||||
if (ret)
|
||||
|
||||
@@ -69,27 +69,17 @@ static int update_classid_sock(const void *v, struct file *file, unsigned n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_classid(struct cgroup_subsys_state *css, void *v)
|
||||
{
|
||||
struct css_task_iter it;
|
||||
struct task_struct *p;
|
||||
|
||||
css_task_iter_start(css, &it);
|
||||
while ((p = css_task_iter_next(&it))) {
|
||||
task_lock(p);
|
||||
iterate_fd(p->files, 0, update_classid_sock, v);
|
||||
task_unlock(p);
|
||||
}
|
||||
css_task_iter_end(&it);
|
||||
}
|
||||
|
||||
static void cgrp_attach(struct cgroup_taskset *tset)
|
||||
{
|
||||
struct cgroup_subsys_state *css;
|
||||
struct task_struct *p;
|
||||
|
||||
cgroup_taskset_first(tset, &css);
|
||||
update_classid(css,
|
||||
(void *)(unsigned long)css_cls_state(css)->classid);
|
||||
cgroup_taskset_for_each(p, css, tset) {
|
||||
task_lock(p);
|
||||
iterate_fd(p->files, 0, update_classid_sock,
|
||||
(void *)(unsigned long)css_cls_state(css)->classid);
|
||||
task_unlock(p);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
|
||||
@@ -101,12 +91,22 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
|
||||
u64 value)
|
||||
{
|
||||
struct cgroup_cls_state *cs = css_cls_state(css);
|
||||
struct css_task_iter it;
|
||||
struct task_struct *p;
|
||||
|
||||
cgroup_sk_alloc_disable();
|
||||
|
||||
cs->classid = (u32)value;
|
||||
|
||||
update_classid(css, (void *)(unsigned long)cs->classid);
|
||||
css_task_iter_start(css, &it);
|
||||
while ((p = css_task_iter_next(&it))) {
|
||||
task_lock(p);
|
||||
iterate_fd(p->files, 0, update_classid_sock,
|
||||
(void *)(unsigned long)cs->classid);
|
||||
task_unlock(p);
|
||||
}
|
||||
css_task_iter_end(&it);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1437,6 +1437,11 @@ static void __sk_destruct(struct rcu_head *head)
|
||||
pr_debug("%s: optmem leakage (%d bytes) detected\n",
|
||||
__func__, atomic_read(&sk->sk_omem_alloc));
|
||||
|
||||
if (sk->sk_frag.page) {
|
||||
put_page(sk->sk_frag.page);
|
||||
sk->sk_frag.page = NULL;
|
||||
}
|
||||
|
||||
if (sk->sk_peer_cred)
|
||||
put_cred(sk->sk_peer_cred);
|
||||
put_pid(sk->sk_peer_pid);
|
||||
@@ -1533,6 +1538,12 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
|
||||
is_charged = sk_filter_charge(newsk, filter);
|
||||
|
||||
if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
|
||||
/* We need to make sure that we don't uncharge the new
|
||||
* socket if we couldn't charge it in the first place
|
||||
* as otherwise we uncharge the parent's filter.
|
||||
*/
|
||||
if (!is_charged)
|
||||
RCU_INIT_POINTER(newsk->sk_filter, NULL);
|
||||
/* It is still raw copy of parent, so invalidate
|
||||
* destructor and make plain sk_free() */
|
||||
newsk->sk_destruct = NULL;
|
||||
@@ -2738,11 +2749,6 @@ void sk_common_release(struct sock *sk)
|
||||
|
||||
sk_refcnt_debug_release(sk);
|
||||
|
||||
if (sk->sk_frag.page) {
|
||||
put_page(sk->sk_frag.page);
|
||||
sk->sk_frag.page = NULL;
|
||||
}
|
||||
|
||||
sock_put(sk);
|
||||
}
|
||||
EXPORT_SYMBOL(sk_common_release);
|
||||
|
||||
@@ -1081,7 +1081,8 @@ static void nl_fib_input(struct sk_buff *skb)
|
||||
|
||||
net = sock_net(skb->sk);
|
||||
nlh = nlmsg_hdr(skb);
|
||||
if (skb->len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len ||
|
||||
if (skb->len < nlmsg_total_size(sizeof(*frn)) ||
|
||||
skb->len < nlh->nlmsg_len ||
|
||||
nlmsg_len(nlh) < sizeof(*frn))
|
||||
return;
|
||||
|
||||
|
||||
@@ -5571,6 +5571,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
|
||||
tcp_set_state(sk, TCP_ESTABLISHED);
|
||||
icsk->icsk_ack.lrcvtime = tcp_time_stamp;
|
||||
|
||||
if (skb) {
|
||||
icsk->icsk_af_ops->sk_rx_dst_set(sk, skb);
|
||||
@@ -5789,7 +5790,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
|
||||
* to stand against the temptation 8) --ANK
|
||||
*/
|
||||
inet_csk_schedule_ack(sk);
|
||||
icsk->icsk_ack.lrcvtime = tcp_time_stamp;
|
||||
tcp_enter_quickack_mode(sk);
|
||||
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
|
||||
TCP_DELACK_MAX, TCP_RTO_MAX);
|
||||
|
||||
@@ -466,6 +466,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
|
||||
newtp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT);
|
||||
minmax_reset(&newtp->rtt_min, tcp_time_stamp, ~0U);
|
||||
newicsk->icsk_rto = TCP_TIMEOUT_INIT;
|
||||
newicsk->icsk_ack.lrcvtime = tcp_time_stamp;
|
||||
|
||||
newtp->packets_out = 0;
|
||||
newtp->retrans_out = 0;
|
||||
|
||||
@@ -1037,6 +1037,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
ipc6.hlimit = -1;
|
||||
ipc6.tclass = -1;
|
||||
ipc6.dontfrag = -1;
|
||||
sockc.tsflags = sk->sk_tsflags;
|
||||
|
||||
/* destination address check */
|
||||
if (sin6) {
|
||||
@@ -1156,7 +1157,6 @@ do_udp_sendmsg:
|
||||
fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
|
||||
|
||||
fl6.flowi6_mark = sk->sk_mark;
|
||||
sockc.tsflags = sk->sk_tsflags;
|
||||
|
||||
if (msg->msg_controllen) {
|
||||
opt = &opt_space;
|
||||
|
||||
@@ -588,7 +588,7 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
|
||||
ipv4 = true;
|
||||
break;
|
||||
case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
|
||||
SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
|
||||
SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.src,
|
||||
nla_get_in6_addr(a), is_mask);
|
||||
ipv6 = true;
|
||||
break;
|
||||
@@ -649,6 +649,8 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
|
||||
tun_flags |= TUNNEL_VXLAN_OPT;
|
||||
opts_type = type;
|
||||
break;
|
||||
case OVS_TUNNEL_KEY_ATTR_PAD:
|
||||
break;
|
||||
default:
|
||||
OVS_NLERR(log, "Unknown IP tunnel attribute %d",
|
||||
type);
|
||||
|
||||
@@ -146,6 +146,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp)
|
||||
if (s) {
|
||||
struct unix_sock *u = unix_sk(s);
|
||||
|
||||
BUG_ON(!atomic_long_read(&u->inflight));
|
||||
BUG_ON(list_empty(&u->link));
|
||||
|
||||
if (atomic_long_dec_and_test(&u->inflight))
|
||||
@@ -341,6 +342,14 @@ void unix_gc(void)
|
||||
}
|
||||
list_del(&cursor);
|
||||
|
||||
/* Now gc_candidates contains only garbage. Restore original
|
||||
* inflight counters for these as well, and remove the skbuffs
|
||||
* which are creating the cycle(s).
|
||||
*/
|
||||
skb_queue_head_init(&hitlist);
|
||||
list_for_each_entry(u, &gc_candidates, link)
|
||||
scan_children(&u->sk, inc_inflight, &hitlist);
|
||||
|
||||
/* not_cycle_list contains those sockets which do not make up a
|
||||
* cycle. Restore these to the inflight list.
|
||||
*/
|
||||
@@ -350,14 +359,6 @@ void unix_gc(void)
|
||||
list_move_tail(&u->link, &gc_inflight_list);
|
||||
}
|
||||
|
||||
/* Now gc_candidates contains only garbage. Restore original
|
||||
* inflight counters for these as well, and remove the skbuffs
|
||||
* which are creating the cycle(s).
|
||||
*/
|
||||
skb_queue_head_init(&hitlist);
|
||||
list_for_each_entry(u, &gc_candidates, link)
|
||||
scan_children(&u->sk, inc_inflight, &hitlist);
|
||||
|
||||
spin_unlock(&unix_gc_lock);
|
||||
|
||||
/* Here we are. Hitlist is filled. Die. */
|
||||
|
||||
@@ -548,21 +548,17 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
|
||||
{
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (!cb->args[0]) {
|
||||
err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
||||
nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
||||
nl80211_policy);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
return err;
|
||||
|
||||
*wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
|
||||
nl80211_fam.attrbuf);
|
||||
if (IS_ERR(*wdev)) {
|
||||
err = PTR_ERR(*wdev);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (IS_ERR(*wdev))
|
||||
return PTR_ERR(*wdev);
|
||||
*rdev = wiphy_to_rdev((*wdev)->wiphy);
|
||||
/* 0 is the first index - add 1 to parse only once */
|
||||
cb->args[0] = (*rdev)->wiphy_idx + 1;
|
||||
@@ -572,10 +568,8 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
|
||||
struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
|
||||
struct wireless_dev *tmp;
|
||||
|
||||
if (!wiphy) {
|
||||
err = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (!wiphy)
|
||||
return -ENODEV;
|
||||
*rdev = wiphy_to_rdev(wiphy);
|
||||
*wdev = NULL;
|
||||
|
||||
@@ -586,21 +580,11 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
|
||||
}
|
||||
}
|
||||
|
||||
if (!*wdev) {
|
||||
err = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (!*wdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out_unlock:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
/* IE validation */
|
||||
@@ -2584,17 +2568,17 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
|
||||
int filter_wiphy = -1;
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct wireless_dev *wdev;
|
||||
int ret;
|
||||
|
||||
rtnl_lock();
|
||||
if (!cb->args[2]) {
|
||||
struct nl80211_dump_wiphy_state state = {
|
||||
.filter_wiphy = -1,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = nl80211_dump_wiphy_parse(skb, cb, &state);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_unlock;
|
||||
|
||||
filter_wiphy = state.filter_wiphy;
|
||||
|
||||
@@ -2639,12 +2623,14 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
|
||||
wp_idx++;
|
||||
}
|
||||
out:
|
||||
rtnl_unlock();
|
||||
|
||||
cb->args[0] = wp_idx;
|
||||
cb->args[1] = if_idx;
|
||||
|
||||
return skb->len;
|
||||
ret = skb->len;
|
||||
out_unlock:
|
||||
rtnl_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
@@ -4371,9 +4357,10 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
||||
int sta_idx = cb->args[2];
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_err;
|
||||
|
||||
if (!wdev->netdev) {
|
||||
err = -EINVAL;
|
||||
@@ -4408,7 +4395,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
||||
cb->args[2] = sta_idx;
|
||||
err = skb->len;
|
||||
out_err:
|
||||
nl80211_finish_wdev_dump(rdev);
|
||||
rtnl_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -5179,9 +5166,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
||||
int path_idx = cb->args[2];
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_err;
|
||||
|
||||
if (!rdev->ops->dump_mpath) {
|
||||
err = -EOPNOTSUPP;
|
||||
@@ -5214,7 +5202,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
||||
cb->args[2] = path_idx;
|
||||
err = skb->len;
|
||||
out_err:
|
||||
nl80211_finish_wdev_dump(rdev);
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -5374,9 +5362,10 @@ static int nl80211_dump_mpp(struct sk_buff *skb,
|
||||
int path_idx = cb->args[2];
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_err;
|
||||
|
||||
if (!rdev->ops->dump_mpp) {
|
||||
err = -EOPNOTSUPP;
|
||||
@@ -5409,7 +5398,7 @@ static int nl80211_dump_mpp(struct sk_buff *skb,
|
||||
cb->args[2] = path_idx;
|
||||
err = skb->len;
|
||||
out_err:
|
||||
nl80211_finish_wdev_dump(rdev);
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -7556,9 +7545,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int start = cb->args[2], idx = 0;
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
||||
if (err)
|
||||
if (err) {
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
wdev_lock(wdev);
|
||||
spin_lock_bh(&rdev->bss_lock);
|
||||
@@ -7581,7 +7573,7 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
wdev_unlock(wdev);
|
||||
|
||||
cb->args[2] = idx;
|
||||
nl80211_finish_wdev_dump(rdev);
|
||||
rtnl_unlock();
|
||||
|
||||
return skb->len;
|
||||
}
|
||||
@@ -7665,9 +7657,10 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int res;
|
||||
bool radio_stats;
|
||||
|
||||
rtnl_lock();
|
||||
res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
||||
if (res)
|
||||
return res;
|
||||
goto out_err;
|
||||
|
||||
/* prepare_wdev_dump parsed the attributes */
|
||||
radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
|
||||
@@ -7708,7 +7701,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
cb->args[2] = survey_idx;
|
||||
res = skb->len;
|
||||
out_err:
|
||||
nl80211_finish_wdev_dump(rdev);
|
||||
rtnl_unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -11299,17 +11292,13 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
|
||||
void *data = NULL;
|
||||
unsigned int data_len = 0;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (cb->args[0]) {
|
||||
/* subtract the 1 again here */
|
||||
struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
|
||||
struct wireless_dev *tmp;
|
||||
|
||||
if (!wiphy) {
|
||||
err = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (!wiphy)
|
||||
return -ENODEV;
|
||||
*rdev = wiphy_to_rdev(wiphy);
|
||||
*wdev = NULL;
|
||||
|
||||
@@ -11330,13 +11319,11 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
|
||||
nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
||||
nl80211_policy);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
return err;
|
||||
|
||||
if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] ||
|
||||
!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
|
||||
return -EINVAL;
|
||||
|
||||
*wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
|
||||
nl80211_fam.attrbuf);
|
||||
@@ -11345,10 +11332,8 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
|
||||
|
||||
*rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
|
||||
nl80211_fam.attrbuf);
|
||||
if (IS_ERR(*rdev)) {
|
||||
err = PTR_ERR(*rdev);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (IS_ERR(*rdev))
|
||||
return PTR_ERR(*rdev);
|
||||
|
||||
vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]);
|
||||
subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
|
||||
@@ -11361,19 +11346,15 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
|
||||
if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
|
||||
continue;
|
||||
|
||||
if (!vcmd->dumpit) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (!vcmd->dumpit)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
vcmd_idx = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (vcmd_idx < 0) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (vcmd_idx < 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) {
|
||||
data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
@@ -11390,9 +11371,6 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
|
||||
|
||||
/* keep rtnl locked in successful case */
|
||||
return 0;
|
||||
out_unlock:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
|
||||
@@ -11407,9 +11385,10 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
|
||||
int err;
|
||||
struct nlattr *vendor_data;
|
||||
|
||||
rtnl_lock();
|
||||
err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
|
||||
if (err)
|
||||
return err;
|
||||
goto out;
|
||||
|
||||
vcmd_idx = cb->args[2];
|
||||
data = (void *)cb->args[3];
|
||||
@@ -11418,18 +11397,26 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
|
||||
|
||||
if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
|
||||
WIPHY_VENDOR_CMD_NEED_NETDEV)) {
|
||||
if (!wdev)
|
||||
return -EINVAL;
|
||||
if (!wdev) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
|
||||
!wdev->netdev)
|
||||
return -EINVAL;
|
||||
!wdev->netdev) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
|
||||
if (wdev->netdev &&
|
||||
!netif_running(wdev->netdev))
|
||||
return -ENETDOWN;
|
||||
if (!wdev->netdev && !wdev->p2p_started)
|
||||
return -ENETDOWN;
|
||||
!netif_running(wdev->netdev)) {
|
||||
err = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
if (!wdev->netdev && !wdev->p2p_started) {
|
||||
err = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1832,6 +1832,7 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
|
||||
info->output_pool != client->pool->size)) {
|
||||
if (snd_seq_write_pool_allocated(client)) {
|
||||
/* remove all existing cells */
|
||||
snd_seq_pool_mark_closing(client->pool);
|
||||
snd_seq_queue_client_leave_cells(client->number);
|
||||
snd_seq_pool_done(client->pool);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,9 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
|
||||
return;
|
||||
*fifo = NULL;
|
||||
|
||||
if (f->pool)
|
||||
snd_seq_pool_mark_closing(f->pool);
|
||||
|
||||
snd_seq_fifo_clear(f);
|
||||
|
||||
/* wake up clients if any */
|
||||
|
||||
@@ -414,6 +414,18 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* refuse the further insertion to the pool */
|
||||
void snd_seq_pool_mark_closing(struct snd_seq_pool *pool)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (snd_BUG_ON(!pool))
|
||||
return;
|
||||
spin_lock_irqsave(&pool->lock, flags);
|
||||
pool->closing = 1;
|
||||
spin_unlock_irqrestore(&pool->lock, flags);
|
||||
}
|
||||
|
||||
/* remove events */
|
||||
int snd_seq_pool_done(struct snd_seq_pool *pool)
|
||||
{
|
||||
@@ -424,10 +436,6 @@ int snd_seq_pool_done(struct snd_seq_pool *pool)
|
||||
return -EINVAL;
|
||||
|
||||
/* wait for closing all threads */
|
||||
spin_lock_irqsave(&pool->lock, flags);
|
||||
pool->closing = 1;
|
||||
spin_unlock_irqrestore(&pool->lock, flags);
|
||||
|
||||
if (waitqueue_active(&pool->output_sleep))
|
||||
wake_up(&pool->output_sleep);
|
||||
|
||||
@@ -484,6 +492,7 @@ int snd_seq_pool_delete(struct snd_seq_pool **ppool)
|
||||
*ppool = NULL;
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
snd_seq_pool_mark_closing(pool);
|
||||
snd_seq_pool_done(pool);
|
||||
kfree(pool);
|
||||
return 0;
|
||||
|
||||
@@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(struct snd_seq_pool *pool)
|
||||
int snd_seq_pool_init(struct snd_seq_pool *pool);
|
||||
|
||||
/* done pool - free events */
|
||||
void snd_seq_pool_mark_closing(struct snd_seq_pool *pool);
|
||||
int snd_seq_pool_done(struct snd_seq_pool *pool);
|
||||
|
||||
/* create pool */
|
||||
|
||||
@@ -1905,7 +1905,7 @@ static int hw_card_start(struct hw *hw)
|
||||
return err;
|
||||
|
||||
/* Set DMA transfer mask */
|
||||
if (dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
|
||||
if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
|
||||
dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
|
||||
} else {
|
||||
dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
|
||||
|
||||
@@ -6058,6 +6058,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
||||
ALC295_STANDARD_PINS,
|
||||
{0x17, 0x21014040},
|
||||
{0x18, 0x21a19050}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
ALC295_STANDARD_PINS),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
ALC298_STANDARD_PINS,
|
||||
{0x17, 0x90170110}),
|
||||
|
||||
Reference in New Issue
Block a user