mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
Merge 4.19.162 into android-4.19-stable
Changes in 4.19.162 ipv6: addrlabel: fix possible memory leak in ip6addrlbl_net_init net/af_iucv: set correct sk_protocol for child sockets net/tls: missing received data after fast remote close rose: Fix Null pointer dereference in rose_send_frame() sock: set sk_err to ee_errno on dequeue from errq tcp: Set INET_ECN_xmit configuration in tcp_reinit_congestion_control tun: honor IOCB_NOWAIT flag usbnet: ipheth: fix connectivity with iOS 14 net/tls: Protect from calling tls_dev_del for TLS RX twice ibmvnic: fix call_netdevice_notifiers in do_reset i40e: Fix removing driver while bare-metal VFs pass traffic bonding: wait for sysfs kobject destruction before freeing struct slave netfilter: bridge: reset skb->pkt_type after NF_INET_POST_ROUTING traversal ipv4: Fix tos mask in inet_rtm_getroute() ibmvnic: Ensure that SCRQ entry reads are correctly ordered ibmvnic: Fix TX completion error handling geneve: pull IP header before ECN decapsulation net: ip6_gre: set dev->hard_header_len when using header_ops net/x25: prevent a couple of overflows cxgb3: fix error return code in t3_sge_alloc_qset() net: pasemi: fix error return code in pasemi_mac_open() chelsio/chtls: fix a double free in chtls_setkey() net: mvpp2: Fix error return code in mvpp2_open() net/mlx5: Fix wrong address reclaim when command interface is down chelsio/chtls: fix panic during unload reload chtls dt-bindings: net: correct interrupt flags in examples ALSA: usb-audio: US16x08: fix value count for level meters Input: xpad - support Ardwiino Controllers Input: i8042 - add ByteSpeed touchpad to noloop table tracing: Remove WARN_ON in start_thread() RDMA/i40iw: Address an mmap handler exploit in i40iw Linux 4.19.162 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Idb0e720cc744d8499967a25291a6932b2b8388c6
This commit is contained in:
@@ -25,7 +25,7 @@ Example (for ARM-based BeagleBone with NPC100 NFC controller on I2C2):
|
||||
clock-frequency = <100000>;
|
||||
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <29 GPIO_ACTIVE_HIGH>;
|
||||
interrupts = <29 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
enable-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
|
||||
firmware-gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
@@ -25,7 +25,7 @@ Example (for ARM-based BeagleBone with PN544 on I2C2):
|
||||
clock-frequency = <400000>;
|
||||
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <17 GPIO_ACTIVE_HIGH>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
enable-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
|
||||
firmware-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 161
|
||||
SUBLEVEL = 162
|
||||
EXTRAVERSION =
|
||||
NAME = "People's Front"
|
||||
|
||||
|
||||
@@ -1079,6 +1079,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
|
||||
|
||||
oreq->ts_recent = PASS_OPEN_TID_G(ntohl(req->tos_stid));
|
||||
sk_setup_caps(newsk, dst);
|
||||
newsk->sk_prot_creator = lsk->sk_prot_creator;
|
||||
csk->sk = newsk;
|
||||
csk->passive_reap_next = oreq;
|
||||
csk->tx_chan = cxgb4_port_chan(ndev);
|
||||
|
||||
@@ -376,6 +376,7 @@ int chtls_setkey(struct chtls_sock *csk, u32 keylen, u32 optname)
|
||||
csk->wr_unacked += DIV_ROUND_UP(len, 16);
|
||||
enqueue_wr(csk, skb);
|
||||
cxgb4_ofld_send(csk->egress_dev, skb);
|
||||
skb = NULL;
|
||||
|
||||
chtls_set_scmd(csk);
|
||||
/* Clear quiesce for Rx key */
|
||||
|
||||
@@ -54,10 +54,6 @@
|
||||
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
|
||||
__stringify(DRV_VERSION_MINOR) "." __stringify(DRV_VERSION_BUILD)
|
||||
|
||||
static int push_mode;
|
||||
module_param(push_mode, int, 0644);
|
||||
MODULE_PARM_DESC(push_mode, "Low latency mode: 0=disabled (default), 1=enabled)");
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "debug flags: 0=disabled (default), 0x7fffffff=all");
|
||||
@@ -1584,7 +1580,6 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl,
|
||||
if (status)
|
||||
goto exit;
|
||||
iwdev->obj_next = iwdev->obj_mem;
|
||||
iwdev->push_mode = push_mode;
|
||||
|
||||
init_waitqueue_head(&iwdev->vchnl_waitq);
|
||||
init_waitqueue_head(&dev->vf_reqs);
|
||||
|
||||
@@ -201,38 +201,16 @@ static int i40iw_dealloc_ucontext(struct ib_ucontext *context)
|
||||
*/
|
||||
static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
|
||||
{
|
||||
struct i40iw_ucontext *ucontext;
|
||||
u64 db_addr_offset;
|
||||
u64 push_offset;
|
||||
struct i40iw_ucontext *ucontext = to_ucontext(context);
|
||||
u64 dbaddr;
|
||||
|
||||
ucontext = to_ucontext(context);
|
||||
if (ucontext->iwdev->sc_dev.is_pf) {
|
||||
db_addr_offset = I40IW_DB_ADDR_OFFSET;
|
||||
push_offset = I40IW_PUSH_OFFSET;
|
||||
if (vma->vm_pgoff)
|
||||
vma->vm_pgoff += I40IW_PF_FIRST_PUSH_PAGE_INDEX - 1;
|
||||
} else {
|
||||
db_addr_offset = I40IW_VF_DB_ADDR_OFFSET;
|
||||
push_offset = I40IW_VF_PUSH_OFFSET;
|
||||
if (vma->vm_pgoff)
|
||||
vma->vm_pgoff += I40IW_VF_FIRST_PUSH_PAGE_INDEX - 1;
|
||||
}
|
||||
if (vma->vm_pgoff || vma->vm_end - vma->vm_start != PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
vma->vm_pgoff += db_addr_offset >> PAGE_SHIFT;
|
||||
dbaddr = I40IW_DB_ADDR_OFFSET + pci_resource_start(ucontext->iwdev->ldev->pcidev, 0);
|
||||
|
||||
if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) {
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
vma->vm_private_data = ucontext;
|
||||
} else {
|
||||
if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2)
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
else
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
if (io_remap_pfn_range(vma, vma->vm_start,
|
||||
vma->vm_pgoff + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> PAGE_SHIFT),
|
||||
PAGE_SIZE, vma->vm_page_prot))
|
||||
if (io_remap_pfn_range(vma, vma->vm_start, dbaddr >> PAGE_SHIFT, PAGE_SIZE,
|
||||
pgprot_noncached(vma->vm_page_prot)))
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -255,6 +255,7 @@ static const struct xpad_device {
|
||||
{ 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
|
||||
{ 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
|
||||
{ 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
|
||||
{ 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
|
||||
{ 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 },
|
||||
{ 0x12ab, 0x0303, "Mortal Kombat Klassic FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
||||
@@ -432,6 +433,7 @@ static const struct usb_device_id xpad_table[] = {
|
||||
XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
|
||||
XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */
|
||||
XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */
|
||||
XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */
|
||||
XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */
|
||||
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
|
||||
XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
|
||||
|
||||
@@ -223,6 +223,10 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
|
||||
},
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1268,29 +1268,9 @@ static void bond_upper_dev_unlink(struct bonding *bond, struct slave *slave)
|
||||
slave->dev->flags &= ~IFF_SLAVE;
|
||||
}
|
||||
|
||||
static struct slave *bond_alloc_slave(struct bonding *bond)
|
||||
{
|
||||
struct slave *slave = NULL;
|
||||
|
||||
slave = kzalloc(sizeof(*slave), GFP_KERNEL);
|
||||
if (!slave)
|
||||
return NULL;
|
||||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
||||
SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info),
|
||||
GFP_KERNEL);
|
||||
if (!SLAVE_AD_INFO(slave)) {
|
||||
kfree(slave);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work);
|
||||
|
||||
return slave;
|
||||
}
|
||||
|
||||
static void bond_free_slave(struct slave *slave)
|
||||
static void slave_kobj_release(struct kobject *kobj)
|
||||
{
|
||||
struct slave *slave = to_slave(kobj);
|
||||
struct bonding *bond = bond_get_bond_by_slave(slave);
|
||||
|
||||
cancel_delayed_work_sync(&slave->notify_work);
|
||||
@@ -1300,6 +1280,53 @@ static void bond_free_slave(struct slave *slave)
|
||||
kfree(slave);
|
||||
}
|
||||
|
||||
static struct kobj_type slave_ktype = {
|
||||
.release = slave_kobj_release,
|
||||
#ifdef CONFIG_SYSFS
|
||||
.sysfs_ops = &slave_sysfs_ops,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int bond_kobj_init(struct slave *slave)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = kobject_init_and_add(&slave->kobj, &slave_ktype,
|
||||
&(slave->dev->dev.kobj), "bonding_slave");
|
||||
if (err)
|
||||
kobject_put(&slave->kobj);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct slave *bond_alloc_slave(struct bonding *bond,
|
||||
struct net_device *slave_dev)
|
||||
{
|
||||
struct slave *slave = NULL;
|
||||
|
||||
slave = kzalloc(sizeof(*slave), GFP_KERNEL);
|
||||
if (!slave)
|
||||
return NULL;
|
||||
|
||||
slave->bond = bond;
|
||||
slave->dev = slave_dev;
|
||||
|
||||
if (bond_kobj_init(slave))
|
||||
return NULL;
|
||||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
||||
SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info),
|
||||
GFP_KERNEL);
|
||||
if (!SLAVE_AD_INFO(slave)) {
|
||||
kobject_put(&slave->kobj);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work);
|
||||
|
||||
return slave;
|
||||
}
|
||||
|
||||
static void bond_fill_ifbond(struct bonding *bond, struct ifbond *info)
|
||||
{
|
||||
info->bond_mode = BOND_MODE(bond);
|
||||
@@ -1487,14 +1514,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
|
||||
bond->dev->addr_assign_type == NET_ADDR_RANDOM)
|
||||
bond_set_dev_addr(bond->dev, slave_dev);
|
||||
|
||||
new_slave = bond_alloc_slave(bond);
|
||||
new_slave = bond_alloc_slave(bond, slave_dev);
|
||||
if (!new_slave) {
|
||||
res = -ENOMEM;
|
||||
goto err_undo_flags;
|
||||
}
|
||||
|
||||
new_slave->bond = bond;
|
||||
new_slave->dev = slave_dev;
|
||||
/* Set the new_slave's queue_id to be zero. Queue ID mapping
|
||||
* is set via sysfs or module option if desired.
|
||||
*/
|
||||
@@ -1821,7 +1846,7 @@ err_restore_mtu:
|
||||
dev_set_mtu(slave_dev, new_slave->original_mtu);
|
||||
|
||||
err_free:
|
||||
bond_free_slave(new_slave);
|
||||
kobject_put(&new_slave->kobj);
|
||||
|
||||
err_undo_flags:
|
||||
/* Enslave of first slave has failed and we need to fix master's mac */
|
||||
@@ -2009,7 +2034,7 @@ static int __bond_release_one(struct net_device *bond_dev,
|
||||
if (!netif_is_bond_master(slave_dev))
|
||||
slave_dev->priv_flags &= ~IFF_BONDING;
|
||||
|
||||
bond_free_slave(slave);
|
||||
kobject_put(&slave->kobj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,6 @@ static const struct slave_attribute *slave_attrs[] = {
|
||||
};
|
||||
|
||||
#define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr)
|
||||
#define to_slave(obj) container_of(obj, struct slave, kobj)
|
||||
|
||||
static ssize_t slave_show(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf)
|
||||
@@ -136,28 +135,15 @@ static ssize_t slave_show(struct kobject *kobj,
|
||||
return slave_attr->show(slave, buf);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops slave_sysfs_ops = {
|
||||
const struct sysfs_ops slave_sysfs_ops = {
|
||||
.show = slave_show,
|
||||
};
|
||||
|
||||
static struct kobj_type slave_ktype = {
|
||||
#ifdef CONFIG_SYSFS
|
||||
.sysfs_ops = &slave_sysfs_ops,
|
||||
#endif
|
||||
};
|
||||
|
||||
int bond_sysfs_slave_add(struct slave *slave)
|
||||
{
|
||||
const struct slave_attribute **a;
|
||||
int err;
|
||||
|
||||
err = kobject_init_and_add(&slave->kobj, &slave_ktype,
|
||||
&(slave->dev->dev.kobj), "bonding_slave");
|
||||
if (err) {
|
||||
kobject_put(&slave->kobj);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (a = slave_attrs; *a; ++a) {
|
||||
err = sysfs_create_file(&slave->kobj, &((*a)->attr));
|
||||
if (err) {
|
||||
@@ -175,6 +161,4 @@ void bond_sysfs_slave_del(struct slave *slave)
|
||||
|
||||
for (a = slave_attrs; *a; ++a)
|
||||
sysfs_remove_file(&slave->kobj, &((*a)->attr));
|
||||
|
||||
kobject_put(&slave->kobj);
|
||||
}
|
||||
|
||||
@@ -3176,6 +3176,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
|
||||
GFP_KERNEL | __GFP_COMP);
|
||||
if (!avail) {
|
||||
CH_ALERT(adapter, "free list queue 0 initialization failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (avail < q->fl[0].size)
|
||||
|
||||
@@ -1878,8 +1878,10 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
||||
napi_schedule(&adapter->napi[i]);
|
||||
|
||||
if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
|
||||
adapter->reset_reason != VNIC_RESET_CHANGE_PARAM)
|
||||
adapter->reset_reason != VNIC_RESET_CHANGE_PARAM) {
|
||||
call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev);
|
||||
call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev);
|
||||
}
|
||||
|
||||
netif_carrier_on(netdev);
|
||||
|
||||
@@ -2156,6 +2158,12 @@ restart_poll:
|
||||
|
||||
if (!pending_scrq(adapter, adapter->rx_scrq[scrq_num]))
|
||||
break;
|
||||
/* The queue entry at the current index is peeked at above
|
||||
* to determine that there is a valid descriptor awaiting
|
||||
* processing. We want to be sure that the current slot
|
||||
* holds a valid descriptor before reading its contents.
|
||||
*/
|
||||
dma_rmb();
|
||||
next = ibmvnic_next_scrq(adapter, adapter->rx_scrq[scrq_num]);
|
||||
rx_buff =
|
||||
(struct ibmvnic_rx_buff *)be64_to_cpu(next->
|
||||
@@ -2778,13 +2786,18 @@ restart_loop:
|
||||
unsigned int pool = scrq->pool_index;
|
||||
int num_entries = 0;
|
||||
|
||||
/* The queue entry at the current index is peeked at above
|
||||
* to determine that there is a valid descriptor awaiting
|
||||
* processing. We want to be sure that the current slot
|
||||
* holds a valid descriptor before reading its contents.
|
||||
*/
|
||||
dma_rmb();
|
||||
|
||||
next = ibmvnic_next_scrq(adapter, scrq);
|
||||
for (i = 0; i < next->tx_comp.num_comps; i++) {
|
||||
if (next->tx_comp.rcs[i]) {
|
||||
if (next->tx_comp.rcs[i])
|
||||
dev_err(dev, "tx error %x\n",
|
||||
next->tx_comp.rcs[i]);
|
||||
continue;
|
||||
}
|
||||
index = be32_to_cpu(next->tx_comp.correlators[i]);
|
||||
if (index & IBMVNIC_TSO_POOL_MASK) {
|
||||
tx_pool = &adapter->tso_pool[pool];
|
||||
@@ -3174,6 +3187,11 @@ static union sub_crq *ibmvnic_next_scrq(struct ibmvnic_adapter *adapter,
|
||||
}
|
||||
spin_unlock_irqrestore(&scrq->lock, flags);
|
||||
|
||||
/* Ensure that the entire buffer descriptor has been
|
||||
* loaded before reading its contents
|
||||
*/
|
||||
dma_rmb();
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ enum i40e_state_t {
|
||||
__I40E_CLIENT_SERVICE_REQUESTED,
|
||||
__I40E_CLIENT_L2_CHANGE,
|
||||
__I40E_CLIENT_RESET,
|
||||
__I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */
|
||||
/* This must be last as it determines the size of the BITMAP */
|
||||
__I40E_STATE_SIZE__,
|
||||
};
|
||||
|
||||
@@ -3895,8 +3895,16 @@ static irqreturn_t i40e_intr(int irq, void *data)
|
||||
}
|
||||
|
||||
if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) {
|
||||
ena_mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK;
|
||||
set_bit(__I40E_VFLR_EVENT_PENDING, pf->state);
|
||||
/* disable any further VFLR event notifications */
|
||||
if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state)) {
|
||||
u32 reg = rd32(hw, I40E_PFINT_ICR0_ENA);
|
||||
|
||||
reg &= ~I40E_PFINT_ICR0_VFLR_MASK;
|
||||
wr32(hw, I40E_PFINT_ICR0_ENA, reg);
|
||||
} else {
|
||||
ena_mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK;
|
||||
set_bit(__I40E_VFLR_EVENT_PENDING, pf->state);
|
||||
}
|
||||
}
|
||||
|
||||
if (icr0 & I40E_PFINT_ICR0_GRST_MASK) {
|
||||
@@ -14155,6 +14163,11 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||
while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
||||
set_bit(__I40E_VF_RESETS_DISABLED, pf->state);
|
||||
i40e_free_vfs(pf);
|
||||
pf->flags &= ~I40E_FLAG_SRIOV_ENABLED;
|
||||
}
|
||||
/* no more scheduling of any task */
|
||||
set_bit(__I40E_SUSPENDED, pf->state);
|
||||
set_bit(__I40E_DOWN, pf->state);
|
||||
@@ -14168,11 +14181,6 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||
*/
|
||||
i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false);
|
||||
|
||||
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
||||
i40e_free_vfs(pf);
|
||||
pf->flags &= ~I40E_FLAG_SRIOV_ENABLED;
|
||||
}
|
||||
|
||||
i40e_fdir_teardown(pf);
|
||||
|
||||
/* If there is a switch structure or any orphans, remove them.
|
||||
|
||||
@@ -1204,7 +1204,8 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf)
|
||||
* @vf: pointer to the VF structure
|
||||
* @flr: VFLR was issued or not
|
||||
*
|
||||
* Returns true if the VF is reset, false otherwise.
|
||||
* Returns true if the VF is in reset, resets successfully, or resets
|
||||
* are disabled and false otherwise.
|
||||
**/
|
||||
bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
||||
{
|
||||
@@ -1214,11 +1215,14 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state))
|
||||
return true;
|
||||
|
||||
/* If the VFs have been disabled, this means something else is
|
||||
* resetting the VF, so we shouldn't continue.
|
||||
*/
|
||||
if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
i40e_trigger_vf_reset(vf, flr);
|
||||
|
||||
@@ -1382,6 +1386,15 @@ void i40e_free_vfs(struct i40e_pf *pf)
|
||||
|
||||
i40e_notify_client_of_vf_enable(pf, 0);
|
||||
|
||||
/* Disable IOV before freeing resources. This lets any VF drivers
|
||||
* running in the host get themselves cleaned up before we yank
|
||||
* the carpet out from underneath their feet.
|
||||
*/
|
||||
if (!pci_vfs_assigned(pf->pdev))
|
||||
pci_disable_sriov(pf->pdev);
|
||||
else
|
||||
dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n");
|
||||
|
||||
/* Amortize wait time by stopping all VFs at the same time */
|
||||
for (i = 0; i < pf->num_alloc_vfs; i++) {
|
||||
if (test_bit(I40E_VF_STATE_INIT, &pf->vf[i].vf_states))
|
||||
@@ -1397,15 +1410,6 @@ void i40e_free_vfs(struct i40e_pf *pf)
|
||||
i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[i].lan_vsi_idx]);
|
||||
}
|
||||
|
||||
/* Disable IOV before freeing resources. This lets any VF drivers
|
||||
* running in the host get themselves cleaned up before we yank
|
||||
* the carpet out from underneath their feet.
|
||||
*/
|
||||
if (!pci_vfs_assigned(pf->pdev))
|
||||
pci_disable_sriov(pf->pdev);
|
||||
else
|
||||
dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n");
|
||||
|
||||
/* free up VF resources */
|
||||
tmp = pf->num_alloc_vfs;
|
||||
pf->num_alloc_vfs = 0;
|
||||
|
||||
@@ -3363,6 +3363,7 @@ static int mvpp2_open(struct net_device *dev)
|
||||
if (!valid) {
|
||||
netdev_err(port->dev,
|
||||
"invalid configuration: no dt or link IRQ");
|
||||
err = -ENOENT;
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
|
||||
@@ -331,6 +331,24 @@ out_free:
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32 fwp_fill_manage_pages_out(struct fw_page *fwp, u32 *out, u32 index,
|
||||
u32 npages)
|
||||
{
|
||||
u32 pages_set = 0;
|
||||
unsigned int n;
|
||||
|
||||
for_each_clear_bit(n, &fwp->bitmask, MLX5_NUM_4K_IN_PAGE) {
|
||||
MLX5_ARRAY_SET64(manage_pages_out, out, pas, index + pages_set,
|
||||
fwp->addr + (n * MLX5_ADAPTER_PAGE_SIZE));
|
||||
pages_set++;
|
||||
|
||||
if (!--npages)
|
||||
break;
|
||||
}
|
||||
|
||||
return pages_set;
|
||||
}
|
||||
|
||||
static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
|
||||
u32 *in, int in_size, u32 *out, int out_size)
|
||||
{
|
||||
@@ -354,8 +372,7 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
|
||||
if (fwp->func_id != func_id)
|
||||
continue;
|
||||
|
||||
MLX5_ARRAY_SET64(manage_pages_out, out, pas, i, fwp->addr);
|
||||
i++;
|
||||
i += fwp_fill_manage_pages_out(fwp, out, i, npages - i);
|
||||
}
|
||||
|
||||
MLX5_SET(manage_pages_out, out, output_num_entries, i);
|
||||
|
||||
@@ -1089,16 +1089,20 @@ static int pasemi_mac_open(struct net_device *dev)
|
||||
|
||||
mac->tx = pasemi_mac_setup_tx_resources(dev);
|
||||
|
||||
if (!mac->tx)
|
||||
if (!mac->tx) {
|
||||
ret = -ENOMEM;
|
||||
goto out_tx_ring;
|
||||
}
|
||||
|
||||
/* We might already have allocated rings in case mtu was changed
|
||||
* before interface was brought up.
|
||||
*/
|
||||
if (dev->mtu > 1500 && !mac->num_cs) {
|
||||
pasemi_mac_setup_csrings(mac);
|
||||
if (!mac->num_cs)
|
||||
if (!mac->num_cs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_tx_ring;
|
||||
}
|
||||
}
|
||||
|
||||
/* Zero out rmon counters */
|
||||
|
||||
@@ -256,11 +256,21 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
|
||||
skb_dst_set(skb, &tun_dst->dst);
|
||||
|
||||
/* Ignore packet loops (and multicast echo) */
|
||||
if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) {
|
||||
geneve->dev->stats.rx_errors++;
|
||||
goto drop;
|
||||
}
|
||||
if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr))
|
||||
goto rx_error;
|
||||
|
||||
switch (skb_protocol(skb, true)) {
|
||||
case htons(ETH_P_IP):
|
||||
if (pskb_may_pull(skb, sizeof(struct iphdr)))
|
||||
goto rx_error;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
if (pskb_may_pull(skb, sizeof(struct ipv6hdr)))
|
||||
goto rx_error;
|
||||
break;
|
||||
default:
|
||||
goto rx_error;
|
||||
}
|
||||
oiph = skb_network_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
@@ -301,6 +311,8 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
}
|
||||
return;
|
||||
rx_error:
|
||||
geneve->dev->stats.rx_errors++;
|
||||
drop:
|
||||
/* Consume bad packet */
|
||||
kfree_skb(skb);
|
||||
|
||||
@@ -1988,12 +1988,15 @@ static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
struct tun_file *tfile = file->private_data;
|
||||
struct tun_struct *tun = tun_get(tfile);
|
||||
ssize_t result;
|
||||
int noblock = 0;
|
||||
|
||||
if (!tun)
|
||||
return -EBADFD;
|
||||
|
||||
result = tun_get_user(tun, tfile, NULL, from,
|
||||
file->f_flags & O_NONBLOCK, false);
|
||||
if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT))
|
||||
noblock = 1;
|
||||
|
||||
result = tun_get_user(tun, tfile, NULL, from, noblock, false);
|
||||
|
||||
tun_put(tun);
|
||||
return result;
|
||||
@@ -2214,10 +2217,15 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
struct tun_file *tfile = file->private_data;
|
||||
struct tun_struct *tun = tun_get(tfile);
|
||||
ssize_t len = iov_iter_count(to), ret;
|
||||
int noblock = 0;
|
||||
|
||||
if (!tun)
|
||||
return -EBADFD;
|
||||
ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL);
|
||||
|
||||
if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT))
|
||||
noblock = 1;
|
||||
|
||||
ret = tun_do_read(tun, tfile, to, noblock, NULL);
|
||||
ret = min_t(ssize_t, ret, len);
|
||||
if (ret > 0)
|
||||
iocb->ki_pos = ret;
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
#define IPHETH_USBINTF_SUBCLASS 253
|
||||
#define IPHETH_USBINTF_PROTO 1
|
||||
|
||||
#define IPHETH_BUF_SIZE 1516
|
||||
#define IPHETH_BUF_SIZE 1514
|
||||
#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
|
||||
#define IPHETH_TX_TIMEOUT (5 * HZ)
|
||||
|
||||
|
||||
@@ -170,6 +170,11 @@ struct slave {
|
||||
struct rtnl_link_stats64 slave_stats;
|
||||
};
|
||||
|
||||
static inline struct slave *to_slave(struct kobject *kobj)
|
||||
{
|
||||
return container_of(kobj, struct slave, kobj);
|
||||
}
|
||||
|
||||
struct bond_up_slave {
|
||||
unsigned int count;
|
||||
struct rcu_head rcu;
|
||||
@@ -733,6 +738,9 @@ extern struct bond_parm_tbl ad_select_tbl[];
|
||||
/* exported from bond_netlink.c */
|
||||
extern struct rtnl_link_ops bond_link_ops;
|
||||
|
||||
/* exported from bond_sysfs_slave.c */
|
||||
extern const struct sysfs_ops slave_sysfs_ops;
|
||||
|
||||
static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
atomic_long_inc(&dev->tx_dropped);
|
||||
|
||||
@@ -163,6 +163,12 @@ enum {
|
||||
|
||||
enum tls_context_flags {
|
||||
TLS_RX_SYNC_RUNNING = 0,
|
||||
/* tls_dev_del was called for the RX side, device state was released,
|
||||
* but tls_ctx->netdev might still be kept, because TX-side driver
|
||||
* resources might not be released yet. Used to prevent the second
|
||||
* tls_dev_del call in tls_device_down if it happens simultaneously.
|
||||
*/
|
||||
TLS_RX_DEV_CLOSED = 2,
|
||||
};
|
||||
|
||||
struct cipher_context {
|
||||
|
||||
@@ -355,7 +355,7 @@ static int start_kthread(struct trace_array *tr)
|
||||
struct task_struct *kthread;
|
||||
int next_cpu;
|
||||
|
||||
if (WARN_ON(hwlat_kthread))
|
||||
if (hwlat_kthread)
|
||||
return 0;
|
||||
|
||||
/* Just pick the first CPU on first iteration */
|
||||
|
||||
@@ -719,6 +719,11 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
|
||||
mtu_reserved = nf_bridge_mtu_reduction(skb);
|
||||
mtu = skb->dev->mtu;
|
||||
|
||||
if (nf_bridge->pkt_otherhost) {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
nf_bridge->pkt_otherhost = false;
|
||||
}
|
||||
|
||||
if (nf_bridge->frag_max_size && nf_bridge->frag_max_size < mtu)
|
||||
mtu = nf_bridge->frag_max_size;
|
||||
|
||||
@@ -812,8 +817,6 @@ static unsigned int br_nf_post_routing(void *priv,
|
||||
else
|
||||
return NF_ACCEPT;
|
||||
|
||||
/* We assume any code from br_dev_queue_push_xmit onwards doesn't care
|
||||
* about the value of skb->pkt_type. */
|
||||
if (skb->pkt_type == PACKET_OTHERHOST) {
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
nf_bridge->pkt_otherhost = true;
|
||||
|
||||
@@ -4265,7 +4265,7 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
|
||||
if (skb && (skb_next = skb_peek(q))) {
|
||||
icmp_next = is_icmp_err_skb(skb_next);
|
||||
if (icmp_next)
|
||||
sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_origin;
|
||||
sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_errno;
|
||||
}
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
|
||||
|
||||
@@ -2876,7 +2876,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
memset(&fl4, 0, sizeof(fl4));
|
||||
fl4.daddr = dst;
|
||||
fl4.saddr = src;
|
||||
fl4.flowi4_tos = rtm->rtm_tos;
|
||||
fl4.flowi4_tos = rtm->rtm_tos & IPTOS_RT_MASK;
|
||||
fl4.flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0;
|
||||
fl4.flowi4_mark = mark;
|
||||
fl4.flowi4_uid = uid;
|
||||
@@ -2900,8 +2900,9 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
fl4.flowi4_iif = iif; /* for rt_fill_info */
|
||||
skb->dev = dev;
|
||||
skb->mark = mark;
|
||||
err = ip_route_input_rcu(skb, dst, src, rtm->rtm_tos,
|
||||
dev, &res);
|
||||
err = ip_route_input_rcu(skb, dst, src,
|
||||
rtm->rtm_tos & IPTOS_RT_MASK, dev,
|
||||
&res);
|
||||
|
||||
rt = skb_rtable(skb);
|
||||
if (err == 0 && rt->dst.error)
|
||||
|
||||
@@ -196,6 +196,11 @@ static void tcp_reinit_congestion_control(struct sock *sk,
|
||||
icsk->icsk_ca_setsockopt = 1;
|
||||
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
|
||||
|
||||
if (ca->flags & TCP_CONG_NEEDS_ECN)
|
||||
INET_ECN_xmit(sk);
|
||||
else
|
||||
INET_ECN_dontxmit(sk);
|
||||
|
||||
if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
|
||||
tcp_init_congestion_control(sk);
|
||||
}
|
||||
|
||||
@@ -306,7 +306,9 @@ static int ip6addrlbl_del(struct net *net,
|
||||
/* add default label */
|
||||
static int __net_init ip6addrlbl_net_init(struct net *net)
|
||||
{
|
||||
int err = 0;
|
||||
struct ip6addrlbl_entry *p = NULL;
|
||||
struct hlist_node *n;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
ADDRLABEL(KERN_DEBUG "%s\n", __func__);
|
||||
@@ -315,14 +317,20 @@ static int __net_init ip6addrlbl_net_init(struct net *net)
|
||||
INIT_HLIST_HEAD(&net->ipv6.ip6addrlbl_table.head);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
|
||||
int ret = ip6addrlbl_add(net,
|
||||
ip6addrlbl_init_table[i].prefix,
|
||||
ip6addrlbl_init_table[i].prefixlen,
|
||||
0,
|
||||
ip6addrlbl_init_table[i].label, 0);
|
||||
/* XXX: should we free all rules when we catch an error? */
|
||||
if (ret && (!err || err != -ENOMEM))
|
||||
err = ret;
|
||||
err = ip6addrlbl_add(net,
|
||||
ip6addrlbl_init_table[i].prefix,
|
||||
ip6addrlbl_init_table[i].prefixlen,
|
||||
0,
|
||||
ip6addrlbl_init_table[i].label, 0);
|
||||
if (err)
|
||||
goto err_ip6addrlbl_add;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_ip6addrlbl_add:
|
||||
hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) {
|
||||
hlist_del_rcu(&p->list);
|
||||
kfree_rcu(p, rcu);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1140,8 +1140,13 @@ static void ip6gre_tnl_link_config_route(struct ip6_tnl *t, int set_mtu,
|
||||
return;
|
||||
|
||||
if (rt->dst.dev) {
|
||||
dev->needed_headroom = rt->dst.dev->hard_header_len +
|
||||
t_hlen;
|
||||
unsigned short dst_len = rt->dst.dev->hard_header_len +
|
||||
t_hlen;
|
||||
|
||||
if (t->dev->header_ops)
|
||||
dev->hard_header_len = dst_len;
|
||||
else
|
||||
dev->needed_headroom = dst_len;
|
||||
|
||||
if (set_mtu) {
|
||||
dev->mtu = rt->dst.dev->mtu - t_hlen;
|
||||
@@ -1166,7 +1171,12 @@ static int ip6gre_calc_hlen(struct ip6_tnl *tunnel)
|
||||
tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
|
||||
|
||||
t_hlen = tunnel->hlen + sizeof(struct ipv6hdr);
|
||||
tunnel->dev->needed_headroom = LL_MAX_HEADER + t_hlen;
|
||||
|
||||
if (tunnel->dev->header_ops)
|
||||
tunnel->dev->hard_header_len = LL_MAX_HEADER + t_hlen;
|
||||
else
|
||||
tunnel->dev->needed_headroom = LL_MAX_HEADER + t_hlen;
|
||||
|
||||
return t_hlen;
|
||||
}
|
||||
|
||||
|
||||
@@ -1782,7 +1782,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
|
||||
}
|
||||
|
||||
/* Create the new socket */
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0);
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0);
|
||||
if (!nsk) {
|
||||
err = pr_iucv->path_sever(path, user_data);
|
||||
iucv_path_free(path);
|
||||
@@ -1992,7 +1992,7 @@ static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb)
|
||||
goto out;
|
||||
}
|
||||
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0);
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0);
|
||||
bh_lock_sock(sk);
|
||||
if ((sk->sk_state != IUCV_LISTEN) ||
|
||||
sk_acceptq_is_full(sk) ||
|
||||
|
||||
@@ -99,10 +99,19 @@ static void rose_loopback_timer(struct timer_list *unused)
|
||||
}
|
||||
|
||||
if (frametype == ROSE_CALL_REQUEST) {
|
||||
if ((dev = rose_dev_get(dest)) != NULL) {
|
||||
if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
|
||||
kfree_skb(skb);
|
||||
} else {
|
||||
if (!rose_loopback_neigh->dev) {
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
dev = rose_dev_get(dest);
|
||||
if (!dev) {
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) {
|
||||
dev_put(dev);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -955,6 +955,8 @@ void tls_device_offload_cleanup_rx(struct sock *sk)
|
||||
if (tls_ctx->tx_conf != TLS_HW) {
|
||||
dev_put(netdev);
|
||||
tls_ctx->netdev = NULL;
|
||||
} else {
|
||||
set_bit(TLS_RX_DEV_CLOSED, &tls_ctx->flags);
|
||||
}
|
||||
out:
|
||||
up_read(&device_offload_lock);
|
||||
@@ -984,7 +986,8 @@ static int tls_device_down(struct net_device *netdev)
|
||||
if (ctx->tx_conf == TLS_HW)
|
||||
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
|
||||
TLS_OFFLOAD_CTX_DIR_TX);
|
||||
if (ctx->rx_conf == TLS_HW)
|
||||
if (ctx->rx_conf == TLS_HW &&
|
||||
!test_bit(TLS_RX_DEV_CLOSED, &ctx->flags))
|
||||
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
|
||||
TLS_OFFLOAD_CTX_DIR_RX);
|
||||
WRITE_ONCE(ctx->netdev, NULL);
|
||||
|
||||
@@ -630,6 +630,12 @@ static struct sk_buff *tls_wait_data(struct sock *sk, int flags,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!skb_queue_empty(&sk->sk_receive_queue)) {
|
||||
__strp_unpause(&ctx->strp);
|
||||
if (ctx->recv_pkt)
|
||||
return ctx->recv_pkt;
|
||||
}
|
||||
|
||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -680,7 +680,8 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
int len, i, rc = 0;
|
||||
|
||||
if (addr_len != sizeof(struct sockaddr_x25) ||
|
||||
addr->sx25_family != AF_X25) {
|
||||
addr->sx25_family != AF_X25 ||
|
||||
strnlen(addr->sx25_addr.x25_addr, X25_ADDR_LEN) == X25_ADDR_LEN) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -774,7 +775,8 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
|
||||
|
||||
rc = -EINVAL;
|
||||
if (addr_len != sizeof(struct sockaddr_x25) ||
|
||||
addr->sx25_family != AF_X25)
|
||||
addr->sx25_family != AF_X25 ||
|
||||
strnlen(addr->sx25_addr.x25_addr, X25_ADDR_LEN) == X25_ADDR_LEN)
|
||||
goto out;
|
||||
|
||||
rc = -ENETUNREACH;
|
||||
|
||||
@@ -617,7 +617,7 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
|
||||
static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->count = 1;
|
||||
uinfo->count = 34;
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->value.integer.max = 0x7FFF;
|
||||
uinfo->value.integer.min = 0;
|
||||
|
||||
Reference in New Issue
Block a user