This is the 4.19.243 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmKBO2wACgkQONu9yGCS aT51ixAAipdVLdSm5lZl4eBJgNBQlchtLA+uhVpRkTQxT7CK5o2HKOiAo5DQMbQ6 XRlgwheicUkk/sKMXFAoKsoas5/mPvlYjEZIs32T2XkOyVstw4dNUwLropjzlqLc ZagHrvY/mB1hLe/0UK/3VHURoF9euu0U8SpGSGKF7FbuQKU28FEecI73sDAoWcJe B5p9vg6ta9bHfepJDVaa28TLSE0XrYA6BSr5kJqHlYE5vp21cYCULSj6TvIIh5Qo /jfDrR/BZrVakbqyGPv5sdrQwm2i4qETlnRESpLcYtCY9O0fONUA2Qw39qe3R2s9 z9yCub//1WHfCWLZwy5Vmnt4jmw6EJoGiLhrw2bB4+s9545SeAzH+NUowcQLTpPn zzOtVcrt52COyA3x78h1yvO97DwXtCUBcG0GxutpxygYD/gevVhNSGBKtkmArM6r 7lFzLSciQZlesVF18lAmonOFylPuxD2pc5Z9P32vXxuJKPHwZ1nnsU2ZopvYRLF/ veeeiliTcqI2YwGaJl7HS+Ws4b3p1zj+X+rtBmWtUsLax1xpEIysWgJB49yXSIgg ggvq7jIpSA+UFer3525lp2+y/oyk28YLJyh1UhKgYHbiMfwTJe3a7o+43of2Bw13 mm542/a5Bgwj2xZc/xDV+7Bsjb/lBRmxBLiHHiR+oo2YA78xxvY= =rGPN -----END PGP SIGNATURE----- Merge 4.19.243 into android-4.19-stable Changes in 4.19.243 MIPS: Use address-of operator on section symbols block: drbd: drbd_nl: Make conversion to 'enum drbd_ret_code' explicit drm/amd/display/dc/gpio/gpio_service: Pass around correct dce_{version, environment} types nfp: bpf: silence bitwise vs. logical OR warning can: grcan: grcan_probe(): fix broken system id check for errata workaround needs can: grcan: only use the NAPI poll budget for RX Bluetooth: Fix the creation of hdev->name ALSA: pcm: Fix races among concurrent hw_params and hw_free calls ALSA: pcm: Fix races among concurrent read/write and buffer changes ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls ALSA: pcm: Fix races among concurrent prealloc proc writes ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock mm: hugetlb: fix missing cache flush in copy_huge_page_from_user() mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and __mcopy_atomic() VFS: Fix memory leak caused by concurrently mounting fs with subtype Linux 4.19.243 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I44b9e3ce71b3902ba330f785918ab2d8f0f2b7c6
This commit is contained in:
commit
b4b59322a5
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 19
|
PATCHLEVEL = 19
|
||||||
SUBLEVEL = 242
|
SUBLEVEL = 243
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = "People's Front"
|
NAME = "People's Front"
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ void __init plat_mem_setup(void)
|
|||||||
dtb = phys_to_virt(fw_arg2);
|
dtb = phys_to_virt(fw_arg2);
|
||||||
else if (fw_passed_dtb) /* UHI interface */
|
else if (fw_passed_dtb) /* UHI interface */
|
||||||
dtb = (void *)fw_passed_dtb;
|
dtb = (void *)fw_passed_dtb;
|
||||||
else if (__dtb_start != __dtb_end)
|
else if (&__dtb_start != &__dtb_end)
|
||||||
dtb = (void *)__dtb_start;
|
dtb = (void *)__dtb_start;
|
||||||
else
|
else
|
||||||
panic("no dtb found");
|
panic("no dtb found");
|
||||||
|
@ -81,7 +81,7 @@ void __init plat_mem_setup(void)
|
|||||||
|
|
||||||
if (fw_passed_dtb) /* UHI interface */
|
if (fw_passed_dtb) /* UHI interface */
|
||||||
dtb = (void *)fw_passed_dtb;
|
dtb = (void *)fw_passed_dtb;
|
||||||
else if (__dtb_start != __dtb_end)
|
else if (&__dtb_start != &__dtb_end)
|
||||||
dtb = (void *)__dtb_start;
|
dtb = (void *)__dtb_start;
|
||||||
else
|
else
|
||||||
panic("no dtb found");
|
panic("no dtb found");
|
||||||
|
@ -36,7 +36,7 @@ static ulong get_fdtaddr(void)
|
|||||||
if (fw_passed_dtb && !fw_arg2 && !fw_arg3)
|
if (fw_passed_dtb && !fw_arg2 && !fw_arg3)
|
||||||
return (ulong)fw_passed_dtb;
|
return (ulong)fw_passed_dtb;
|
||||||
|
|
||||||
if (__dtb_start < __dtb_end)
|
if (&__dtb_start < &__dtb_end)
|
||||||
ftaddr = (ulong)__dtb_start;
|
ftaddr = (ulong)__dtb_start;
|
||||||
|
|
||||||
return ftaddr;
|
return ftaddr;
|
||||||
|
@ -79,7 +79,7 @@ void __init plat_mem_setup(void)
|
|||||||
*/
|
*/
|
||||||
if (fw_passed_dtb)
|
if (fw_passed_dtb)
|
||||||
dtb = (void *)fw_passed_dtb;
|
dtb = (void *)fw_passed_dtb;
|
||||||
else if (__dtb_start != __dtb_end)
|
else if (&__dtb_start != &__dtb_end)
|
||||||
dtb = (void *)__dtb_start;
|
dtb = (void *)__dtb_start;
|
||||||
|
|
||||||
__dt_setup_arch(dtb);
|
__dt_setup_arch(dtb);
|
||||||
|
@ -774,9 +774,11 @@ int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info)
|
|||||||
mutex_lock(&adm_ctx.resource->adm_mutex);
|
mutex_lock(&adm_ctx.resource->adm_mutex);
|
||||||
|
|
||||||
if (info->genlhdr->cmd == DRBD_ADM_PRIMARY)
|
if (info->genlhdr->cmd == DRBD_ADM_PRIMARY)
|
||||||
retcode = drbd_set_role(adm_ctx.device, R_PRIMARY, parms.assume_uptodate);
|
retcode = (enum drbd_ret_code)drbd_set_role(adm_ctx.device,
|
||||||
|
R_PRIMARY, parms.assume_uptodate);
|
||||||
else
|
else
|
||||||
retcode = drbd_set_role(adm_ctx.device, R_SECONDARY, 0);
|
retcode = (enum drbd_ret_code)drbd_set_role(adm_ctx.device,
|
||||||
|
R_SECONDARY, 0);
|
||||||
|
|
||||||
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
||||||
genl_lock();
|
genl_lock();
|
||||||
@ -1941,7 +1943,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
|
|||||||
drbd_flush_workqueue(&connection->sender_work);
|
drbd_flush_workqueue(&connection->sender_work);
|
||||||
|
|
||||||
rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE);
|
rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE);
|
||||||
retcode = rv; /* FIXME: Type mismatch. */
|
retcode = (enum drbd_ret_code)rv;
|
||||||
drbd_resume_io(device);
|
drbd_resume_io(device);
|
||||||
if (rv < SS_SUCCESS)
|
if (rv < SS_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -2671,7 +2673,8 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
|
|||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
retcode = conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE);
|
retcode = (enum drbd_ret_code)conn_request_state(connection,
|
||||||
|
NS(conn, C_UNCONNECTED), CS_VERBOSE);
|
||||||
|
|
||||||
conn_reconfig_done(connection);
|
conn_reconfig_done(connection);
|
||||||
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
||||||
@ -2777,7 +2780,7 @@ int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info)
|
|||||||
mutex_lock(&adm_ctx.resource->adm_mutex);
|
mutex_lock(&adm_ctx.resource->adm_mutex);
|
||||||
rv = conn_try_disconnect(connection, parms.force_disconnect);
|
rv = conn_try_disconnect(connection, parms.force_disconnect);
|
||||||
if (rv < SS_SUCCESS)
|
if (rv < SS_SUCCESS)
|
||||||
retcode = rv; /* FIXME: Type mismatch. */
|
retcode = (enum drbd_ret_code)rv;
|
||||||
else
|
else
|
||||||
retcode = NO_ERROR;
|
retcode = NO_ERROR;
|
||||||
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
||||||
|
@ -51,8 +51,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct gpio_service *dal_gpio_service_create(
|
struct gpio_service *dal_gpio_service_create(
|
||||||
enum dce_version dce_version_major,
|
enum dce_version dce_version,
|
||||||
enum dce_version dce_version_minor,
|
enum dce_environment dce_environment,
|
||||||
struct dc_context *ctx)
|
struct dc_context *ctx)
|
||||||
{
|
{
|
||||||
struct gpio_service *service;
|
struct gpio_service *service;
|
||||||
@ -66,14 +66,14 @@ struct gpio_service *dal_gpio_service_create(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dal_hw_translate_init(&service->translate, dce_version_major,
|
if (!dal_hw_translate_init(&service->translate, dce_version,
|
||||||
dce_version_minor)) {
|
dce_environment)) {
|
||||||
BREAK_TO_DEBUGGER();
|
BREAK_TO_DEBUGGER();
|
||||||
goto failure_1;
|
goto failure_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dal_hw_factory_init(&service->factory, dce_version_major,
|
if (!dal_hw_factory_init(&service->factory, dce_version,
|
||||||
dce_version_minor)) {
|
dce_environment)) {
|
||||||
BREAK_TO_DEBUGGER();
|
BREAK_TO_DEBUGGER();
|
||||||
goto failure_1;
|
goto failure_1;
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ void dal_gpio_destroy(
|
|||||||
struct gpio **ptr);
|
struct gpio **ptr);
|
||||||
|
|
||||||
struct gpio_service *dal_gpio_service_create(
|
struct gpio_service *dal_gpio_service_create(
|
||||||
enum dce_version dce_version_major,
|
enum dce_version dce_version,
|
||||||
enum dce_version dce_version_minor,
|
enum dce_environment dce_environment,
|
||||||
struct dc_context *ctx);
|
struct dc_context *ctx);
|
||||||
|
|
||||||
struct gpio *dal_gpio_service_create_irq(
|
struct gpio *dal_gpio_service_create_irq(
|
||||||
|
@ -245,7 +245,7 @@ struct grcan_device_config {
|
|||||||
.rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \
|
.rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
|
#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 4100
|
||||||
#define GRLIB_VERSION_MASK 0xffff
|
#define GRLIB_VERSION_MASK 0xffff
|
||||||
|
|
||||||
/* GRCAN private data structure */
|
/* GRCAN private data structure */
|
||||||
@ -1141,7 +1141,7 @@ static int grcan_close(struct net_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int grcan_transmit_catch_up(struct net_device *dev, int budget)
|
static void grcan_transmit_catch_up(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct grcan_priv *priv = netdev_priv(dev);
|
struct grcan_priv *priv = netdev_priv(dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -1149,7 +1149,7 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget)
|
|||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
|
||||||
work_done = catch_up_echo_skb(dev, budget, true);
|
work_done = catch_up_echo_skb(dev, -1, true);
|
||||||
if (work_done) {
|
if (work_done) {
|
||||||
if (!priv->resetting && !priv->closing &&
|
if (!priv->resetting && !priv->closing &&
|
||||||
!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
|
!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
|
||||||
@ -1163,8 +1163,6 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
return work_done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int grcan_receive(struct net_device *dev, int budget)
|
static int grcan_receive(struct net_device *dev, int budget)
|
||||||
@ -1246,19 +1244,13 @@ static int grcan_poll(struct napi_struct *napi, int budget)
|
|||||||
struct net_device *dev = priv->dev;
|
struct net_device *dev = priv->dev;
|
||||||
struct grcan_registers __iomem *regs = priv->regs;
|
struct grcan_registers __iomem *regs = priv->regs;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int tx_work_done, rx_work_done;
|
int work_done;
|
||||||
int rx_budget = budget / 2;
|
|
||||||
int tx_budget = budget - rx_budget;
|
|
||||||
|
|
||||||
/* Half of the budget for receiveing messages */
|
work_done = grcan_receive(dev, budget);
|
||||||
rx_work_done = grcan_receive(dev, rx_budget);
|
|
||||||
|
|
||||||
/* Half of the budget for transmitting messages as that can trigger echo
|
grcan_transmit_catch_up(dev);
|
||||||
* frames being received
|
|
||||||
*/
|
|
||||||
tx_work_done = grcan_transmit_catch_up(dev, tx_budget);
|
|
||||||
|
|
||||||
if (rx_work_done < rx_budget && tx_work_done < tx_budget) {
|
if (work_done < budget) {
|
||||||
napi_complete(napi);
|
napi_complete(napi);
|
||||||
|
|
||||||
/* Guarantee no interference with a running reset that otherwise
|
/* Guarantee no interference with a running reset that otherwise
|
||||||
@ -1275,7 +1267,7 @@ static int grcan_poll(struct napi_struct *napi, int budget)
|
|||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rx_work_done + tx_work_done;
|
return work_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Work tx bug by waiting while for the risky situation to clear. If that fails,
|
/* Work tx bug by waiting while for the risky situation to clear. If that fails,
|
||||||
@ -1660,6 +1652,7 @@ exit_free_candev:
|
|||||||
static int grcan_probe(struct platform_device *ofdev)
|
static int grcan_probe(struct platform_device *ofdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = ofdev->dev.of_node;
|
struct device_node *np = ofdev->dev.of_node;
|
||||||
|
struct device_node *sysid_parent;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
u32 sysid, ambafreq;
|
u32 sysid, ambafreq;
|
||||||
int irq, err;
|
int irq, err;
|
||||||
@ -1669,10 +1662,15 @@ static int grcan_probe(struct platform_device *ofdev)
|
|||||||
/* Compare GRLIB version number with the first that does not
|
/* Compare GRLIB version number with the first that does not
|
||||||
* have the tx bug (see start_xmit)
|
* have the tx bug (see start_xmit)
|
||||||
*/
|
*/
|
||||||
err = of_property_read_u32(np, "systemid", &sysid);
|
sysid_parent = of_find_node_by_path("/ambapp0");
|
||||||
if (!err && ((sysid & GRLIB_VERSION_MASK)
|
if (sysid_parent) {
|
||||||
>= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
|
of_node_get(sysid_parent);
|
||||||
txbug = false;
|
err = of_property_read_u32(sysid_parent, "systemid", &sysid);
|
||||||
|
if (!err && ((sysid & GRLIB_VERSION_MASK) >=
|
||||||
|
GRCAN_TXBUG_SAFE_GRLIB_VERSION))
|
||||||
|
txbug = false;
|
||||||
|
of_node_put(sysid_parent);
|
||||||
|
}
|
||||||
|
|
||||||
err = of_property_read_u32(np, "freq", &ambafreq);
|
err = of_property_read_u32(np, "freq", &ambafreq);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -226,7 +226,7 @@ int swreg_to_unrestricted(swreg dst, swreg lreg, swreg rreg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
reg->dst_lmextn = swreg_lmextn(dst);
|
reg->dst_lmextn = swreg_lmextn(dst);
|
||||||
reg->src_lmextn = swreg_lmextn(lreg) | swreg_lmextn(rreg);
|
reg->src_lmextn = swreg_lmextn(lreg) || swreg_lmextn(rreg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
reg->dst_lmextn = swreg_lmextn(dst);
|
reg->dst_lmextn = swreg_lmextn(dst);
|
||||||
reg->src_lmextn = swreg_lmextn(lreg) | swreg_lmextn(rreg);
|
reg->src_lmextn = swreg_lmextn(lreg) || swreg_lmextn(rreg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2514,9 +2514,12 @@ static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
mnt = vfs_kern_mount(type, sb_flags, name, data);
|
mnt = vfs_kern_mount(type, sb_flags, name, data);
|
||||||
if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
|
if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE)) {
|
||||||
!mnt->mnt_sb->s_subtype)
|
down_write(&mnt->mnt_sb->s_umount);
|
||||||
mnt = fs_set_subtype(mnt, fstype);
|
if (!mnt->mnt_sb->s_subtype)
|
||||||
|
mnt = fs_set_subtype(mnt, fstype);
|
||||||
|
up_write(&mnt->mnt_sb->s_umount);
|
||||||
|
}
|
||||||
|
|
||||||
put_filesystem(type);
|
put_filesystem(type);
|
||||||
if (IS_ERR(mnt))
|
if (IS_ERR(mnt))
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
/* HCI priority */
|
/* HCI priority */
|
||||||
#define HCI_PRIO_MAX 7
|
#define HCI_PRIO_MAX 7
|
||||||
|
|
||||||
|
/* HCI maximum id value */
|
||||||
|
#define HCI_MAX_ID 10000
|
||||||
|
|
||||||
/* HCI Core structures */
|
/* HCI Core structures */
|
||||||
struct inquiry_data {
|
struct inquiry_data {
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
|
@ -421,6 +421,8 @@ struct snd_pcm_runtime {
|
|||||||
wait_queue_head_t sleep; /* poll sleep */
|
wait_queue_head_t sleep; /* poll sleep */
|
||||||
wait_queue_head_t tsleep; /* transfer sleep */
|
wait_queue_head_t tsleep; /* transfer sleep */
|
||||||
struct fasync_struct *fasync;
|
struct fasync_struct *fasync;
|
||||||
|
struct mutex buffer_mutex; /* protect for buffer changes */
|
||||||
|
atomic_t buffer_accessing; /* >0: in r/w operation, <0: blocked */
|
||||||
|
|
||||||
/* -- private section -- */
|
/* -- private section -- */
|
||||||
void *private_data;
|
void *private_data;
|
||||||
|
@ -5001,6 +5001,8 @@ long copy_huge_page_from_user(struct page *dst_page,
|
|||||||
if (rc)
|
if (rc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
flush_dcache_page(subpage);
|
||||||
|
|
||||||
cond_resched();
|
cond_resched();
|
||||||
}
|
}
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
@ -55,6 +55,8 @@ static int mcopy_atomic_pte(struct mm_struct *dst_mm,
|
|||||||
/* don't free the page */
|
/* don't free the page */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_dcache_page(page);
|
||||||
} else {
|
} else {
|
||||||
page = *pagep;
|
page = *pagep;
|
||||||
*pagep = NULL;
|
*pagep = NULL;
|
||||||
@ -574,6 +576,7 @@ retry:
|
|||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
flush_dcache_page(page);
|
||||||
goto retry;
|
goto retry;
|
||||||
} else
|
} else
|
||||||
BUG_ON(page);
|
BUG_ON(page);
|
||||||
|
@ -3180,10 +3180,10 @@ int hci_register_dev(struct hci_dev *hdev)
|
|||||||
*/
|
*/
|
||||||
switch (hdev->dev_type) {
|
switch (hdev->dev_type) {
|
||||||
case HCI_PRIMARY:
|
case HCI_PRIMARY:
|
||||||
id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
|
id = ida_simple_get(&hci_index_ida, 0, HCI_MAX_ID, GFP_KERNEL);
|
||||||
break;
|
break;
|
||||||
case HCI_AMP:
|
case HCI_AMP:
|
||||||
id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
|
id = ida_simple_get(&hci_index_ida, 1, HCI_MAX_ID, GFP_KERNEL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -3192,7 +3192,7 @@ int hci_register_dev(struct hci_dev *hdev)
|
|||||||
if (id < 0)
|
if (id < 0)
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
sprintf(hdev->name, "hci%d", id);
|
snprintf(hdev->name, sizeof(hdev->name), "hci%d", id);
|
||||||
hdev->id = id;
|
hdev->id = id;
|
||||||
|
|
||||||
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
|
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
|
||||||
|
@ -1039,6 +1039,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||||||
init_waitqueue_head(&runtime->tsleep);
|
init_waitqueue_head(&runtime->tsleep);
|
||||||
|
|
||||||
runtime->status->state = SNDRV_PCM_STATE_OPEN;
|
runtime->status->state = SNDRV_PCM_STATE_OPEN;
|
||||||
|
mutex_init(&runtime->buffer_mutex);
|
||||||
|
atomic_set(&runtime->buffer_accessing, 0);
|
||||||
|
|
||||||
substream->runtime = runtime;
|
substream->runtime = runtime;
|
||||||
substream->private_data = pcm->private_data;
|
substream->private_data = pcm->private_data;
|
||||||
@ -1070,6 +1072,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
|
|||||||
substream->runtime = NULL;
|
substream->runtime = NULL;
|
||||||
if (substream->timer)
|
if (substream->timer)
|
||||||
spin_unlock_irq(&substream->timer->lock);
|
spin_unlock_irq(&substream->timer->lock);
|
||||||
|
mutex_destroy(&runtime->buffer_mutex);
|
||||||
kfree(runtime);
|
kfree(runtime);
|
||||||
put_pid(substream->pid);
|
put_pid(substream->pid);
|
||||||
substream->pid = NULL;
|
substream->pid = NULL;
|
||||||
|
@ -2224,10 +2224,15 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
|
|||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (!atomic_inc_unless_negative(&runtime->buffer_accessing)) {
|
||||||
|
err = -EBUSY;
|
||||||
|
goto _end_unlock;
|
||||||
|
}
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
err = writer(substream, appl_ofs, data, offset, frames,
|
err = writer(substream, appl_ofs, data, offset, frames,
|
||||||
transfer);
|
transfer);
|
||||||
snd_pcm_stream_lock_irq(substream);
|
snd_pcm_stream_lock_irq(substream);
|
||||||
|
atomic_dec(&runtime->buffer_accessing);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto _end_unlock;
|
goto _end_unlock;
|
||||||
err = pcm_accessible_state(runtime);
|
err = pcm_accessible_state(runtime);
|
||||||
|
@ -160,19 +160,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
|||||||
size_t size;
|
size_t size;
|
||||||
struct snd_dma_buffer new_dmab;
|
struct snd_dma_buffer new_dmab;
|
||||||
|
|
||||||
|
mutex_lock(&substream->pcm->open_mutex);
|
||||||
if (substream->runtime) {
|
if (substream->runtime) {
|
||||||
buffer->error = -EBUSY;
|
buffer->error = -EBUSY;
|
||||||
return;
|
goto unlock;
|
||||||
}
|
}
|
||||||
if (!snd_info_get_line(buffer, line, sizeof(line))) {
|
if (!snd_info_get_line(buffer, line, sizeof(line))) {
|
||||||
snd_info_get_str(str, line, sizeof(str));
|
snd_info_get_str(str, line, sizeof(str));
|
||||||
size = simple_strtoul(str, NULL, 10) * 1024;
|
size = simple_strtoul(str, NULL, 10) * 1024;
|
||||||
if ((size != 0 && size < 8192) || size > substream->dma_max) {
|
if ((size != 0 && size < 8192) || size > substream->dma_max) {
|
||||||
buffer->error = -EINVAL;
|
buffer->error = -EINVAL;
|
||||||
return;
|
goto unlock;
|
||||||
}
|
}
|
||||||
if (substream->dma_buffer.bytes == size)
|
if (substream->dma_buffer.bytes == size)
|
||||||
return;
|
goto unlock;
|
||||||
memset(&new_dmab, 0, sizeof(new_dmab));
|
memset(&new_dmab, 0, sizeof(new_dmab));
|
||||||
new_dmab.dev = substream->dma_buffer.dev;
|
new_dmab.dev = substream->dma_buffer.dev;
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
@ -180,7 +181,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
|||||||
substream->dma_buffer.dev.dev,
|
substream->dma_buffer.dev.dev,
|
||||||
size, &new_dmab) < 0) {
|
size, &new_dmab) < 0) {
|
||||||
buffer->error = -ENOMEM;
|
buffer->error = -ENOMEM;
|
||||||
return;
|
goto unlock;
|
||||||
}
|
}
|
||||||
substream->buffer_bytes_max = size;
|
substream->buffer_bytes_max = size;
|
||||||
} else {
|
} else {
|
||||||
@ -192,6 +193,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
|||||||
} else {
|
} else {
|
||||||
buffer->error = -EINVAL;
|
buffer->error = -EINVAL;
|
||||||
}
|
}
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&substream->pcm->open_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
|
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
|
||||||
|
@ -666,6 +666,30 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* acquire buffer_mutex; if it's in r/w operation, return -EBUSY, otherwise
|
||||||
|
* block the further r/w operations
|
||||||
|
*/
|
||||||
|
static int snd_pcm_buffer_access_lock(struct snd_pcm_runtime *runtime)
|
||||||
|
{
|
||||||
|
if (!atomic_dec_unless_positive(&runtime->buffer_accessing))
|
||||||
|
return -EBUSY;
|
||||||
|
mutex_lock(&runtime->buffer_mutex);
|
||||||
|
return 0; /* keep buffer_mutex, unlocked by below */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release buffer_mutex and clear r/w access flag */
|
||||||
|
static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
|
||||||
|
{
|
||||||
|
mutex_unlock(&runtime->buffer_mutex);
|
||||||
|
atomic_inc(&runtime->buffer_accessing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
||||||
|
#define is_oss_stream(substream) ((substream)->oss.oss)
|
||||||
|
#else
|
||||||
|
#define is_oss_stream(substream) false
|
||||||
|
#endif
|
||||||
|
|
||||||
static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_hw_params *params)
|
struct snd_pcm_hw_params *params)
|
||||||
{
|
{
|
||||||
@ -677,22 +701,25 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||||||
if (PCM_RUNTIME_CHECK(substream))
|
if (PCM_RUNTIME_CHECK(substream))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
|
err = snd_pcm_buffer_access_lock(runtime);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
snd_pcm_stream_lock_irq(substream);
|
snd_pcm_stream_lock_irq(substream);
|
||||||
switch (runtime->status->state) {
|
switch (runtime->status->state) {
|
||||||
case SNDRV_PCM_STATE_OPEN:
|
case SNDRV_PCM_STATE_OPEN:
|
||||||
case SNDRV_PCM_STATE_SETUP:
|
case SNDRV_PCM_STATE_SETUP:
|
||||||
case SNDRV_PCM_STATE_PREPARED:
|
case SNDRV_PCM_STATE_PREPARED:
|
||||||
|
if (!is_oss_stream(substream) &&
|
||||||
|
atomic_read(&substream->mmap_count))
|
||||||
|
err = -EBADFD;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
err = -EBADFD;
|
||||||
return -EBADFD;
|
break;
|
||||||
}
|
}
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
if (err)
|
||||||
if (!substream->oss.oss)
|
goto unlock;
|
||||||
#endif
|
|
||||||
if (atomic_read(&substream->mmap_count))
|
|
||||||
return -EBADFD;
|
|
||||||
|
|
||||||
params->rmask = ~0U;
|
params->rmask = ~0U;
|
||||||
err = snd_pcm_hw_refine(substream, params);
|
err = snd_pcm_hw_refine(substream, params);
|
||||||
@ -769,14 +796,19 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||||||
if ((usecs = period_to_usecs(runtime)) >= 0)
|
if ((usecs = period_to_usecs(runtime)) >= 0)
|
||||||
pm_qos_add_request(&substream->latency_pm_qos_req,
|
pm_qos_add_request(&substream->latency_pm_qos_req,
|
||||||
PM_QOS_CPU_DMA_LATENCY, usecs);
|
PM_QOS_CPU_DMA_LATENCY, usecs);
|
||||||
return 0;
|
err = 0;
|
||||||
_error:
|
_error:
|
||||||
/* hardware might be unusable from this time,
|
if (err) {
|
||||||
so we force application to retry to set
|
/* hardware might be unusable from this time,
|
||||||
the correct hardware parameter settings */
|
* so we force application to retry to set
|
||||||
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
* the correct hardware parameter settings
|
||||||
if (substream->ops->hw_free != NULL)
|
*/
|
||||||
substream->ops->hw_free(substream);
|
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
||||||
|
if (substream->ops->hw_free != NULL)
|
||||||
|
substream->ops->hw_free(substream);
|
||||||
|
}
|
||||||
|
unlock:
|
||||||
|
snd_pcm_buffer_access_unlock(runtime);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,22 +841,29 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
|
|||||||
if (PCM_RUNTIME_CHECK(substream))
|
if (PCM_RUNTIME_CHECK(substream))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
|
result = snd_pcm_buffer_access_lock(runtime);
|
||||||
|
if (result < 0)
|
||||||
|
return result;
|
||||||
snd_pcm_stream_lock_irq(substream);
|
snd_pcm_stream_lock_irq(substream);
|
||||||
switch (runtime->status->state) {
|
switch (runtime->status->state) {
|
||||||
case SNDRV_PCM_STATE_SETUP:
|
case SNDRV_PCM_STATE_SETUP:
|
||||||
case SNDRV_PCM_STATE_PREPARED:
|
case SNDRV_PCM_STATE_PREPARED:
|
||||||
|
if (atomic_read(&substream->mmap_count))
|
||||||
|
result = -EBADFD;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
result = -EBADFD;
|
||||||
return -EBADFD;
|
break;
|
||||||
}
|
}
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
if (atomic_read(&substream->mmap_count))
|
if (result)
|
||||||
return -EBADFD;
|
goto unlock;
|
||||||
if (substream->ops->hw_free)
|
if (substream->ops->hw_free)
|
||||||
result = substream->ops->hw_free(substream);
|
result = substream->ops->hw_free(substream);
|
||||||
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
||||||
pm_qos_remove_request(&substream->latency_pm_qos_req);
|
pm_qos_remove_request(&substream->latency_pm_qos_req);
|
||||||
|
unlock:
|
||||||
|
snd_pcm_buffer_access_unlock(runtime);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1061,15 +1100,17 @@ struct action_ops {
|
|||||||
*/
|
*/
|
||||||
static int snd_pcm_action_group(const struct action_ops *ops,
|
static int snd_pcm_action_group(const struct action_ops *ops,
|
||||||
struct snd_pcm_substream *substream,
|
struct snd_pcm_substream *substream,
|
||||||
int state, int do_lock)
|
int state, int stream_lock)
|
||||||
{
|
{
|
||||||
struct snd_pcm_substream *s = NULL;
|
struct snd_pcm_substream *s = NULL;
|
||||||
struct snd_pcm_substream *s1;
|
struct snd_pcm_substream *s1;
|
||||||
int res = 0, depth = 1;
|
int res = 0, depth = 1;
|
||||||
|
|
||||||
snd_pcm_group_for_each_entry(s, substream) {
|
snd_pcm_group_for_each_entry(s, substream) {
|
||||||
if (do_lock && s != substream) {
|
if (s != substream) {
|
||||||
if (s->pcm->nonatomic)
|
if (!stream_lock)
|
||||||
|
mutex_lock_nested(&s->runtime->buffer_mutex, depth);
|
||||||
|
else if (s->pcm->nonatomic)
|
||||||
mutex_lock_nested(&s->self_group.mutex, depth);
|
mutex_lock_nested(&s->self_group.mutex, depth);
|
||||||
else
|
else
|
||||||
spin_lock_nested(&s->self_group.lock, depth);
|
spin_lock_nested(&s->self_group.lock, depth);
|
||||||
@ -1097,18 +1138,18 @@ static int snd_pcm_action_group(const struct action_ops *ops,
|
|||||||
ops->post_action(s, state);
|
ops->post_action(s, state);
|
||||||
}
|
}
|
||||||
_unlock:
|
_unlock:
|
||||||
if (do_lock) {
|
/* unlock streams */
|
||||||
/* unlock streams */
|
snd_pcm_group_for_each_entry(s1, substream) {
|
||||||
snd_pcm_group_for_each_entry(s1, substream) {
|
if (s1 != substream) {
|
||||||
if (s1 != substream) {
|
if (!stream_lock)
|
||||||
if (s1->pcm->nonatomic)
|
mutex_unlock(&s1->runtime->buffer_mutex);
|
||||||
mutex_unlock(&s1->self_group.mutex);
|
else if (s1->pcm->nonatomic)
|
||||||
else
|
mutex_unlock(&s1->self_group.mutex);
|
||||||
spin_unlock(&s1->self_group.lock);
|
else
|
||||||
}
|
spin_unlock(&s1->self_group.lock);
|
||||||
if (s1 == s) /* end */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (s1 == s) /* end */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1189,10 +1230,15 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
down_read(&snd_pcm_link_rwsem);
|
down_read(&snd_pcm_link_rwsem);
|
||||||
|
res = snd_pcm_buffer_access_lock(substream->runtime);
|
||||||
|
if (res < 0)
|
||||||
|
goto unlock;
|
||||||
if (snd_pcm_stream_linked(substream))
|
if (snd_pcm_stream_linked(substream))
|
||||||
res = snd_pcm_action_group(ops, substream, state, 0);
|
res = snd_pcm_action_group(ops, substream, state, 0);
|
||||||
else
|
else
|
||||||
res = snd_pcm_action_single(ops, substream, state);
|
res = snd_pcm_action_single(ops, substream, state);
|
||||||
|
snd_pcm_buffer_access_unlock(substream->runtime);
|
||||||
|
unlock:
|
||||||
up_read(&snd_pcm_link_rwsem);
|
up_read(&snd_pcm_link_rwsem);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user