This is the 4.4.131 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlrp0PgACgkQONu9yGCS
 aT4ikQ/9GJKsYALJ0C+f/7Cm8xLrOusNZz+TId24aTkD++31DIbJ1413yS4earzE
 q7x69N1/5qfCSxSlw9m8ZiZegv572Jd+sLoEY31lcdazdxlh9KwVDZafWwiacDDO
 7b6un6sZYMDxa/vKhqlnehsPRM4Xaz7Dhp/16N09C0Xbfxl8Emh3EEfU7lAObY9U
 avKM6q58sbPvDfHoOVhcdN6NW+Br/P8LfkkZfs3fhlT6lPjJmPv833yX9VPdHMMW
 iYxJR1bbILR5g0X0xWhVtFqvjMyXsb4iM0TqORrleh3C7iQWv91NZQXpXu7v+JMn
 euoZukbchn+3j3Dkd9uAAw1p9dJwB8alCyNq3regJu7WPUQ0VAmE0Z6CbC9q4YwZ
 iNua9KGjFlU3iIxrSe6kVlMM4hh72uONiPC2NAv9pkyg/AWV1YPj+TgUR6AZPw0S
 3BhlVYueXoaR2FHCpR2wfpUB6zyYKJaGPIrk3/XnEUhizWwXeLcncPNvaMkYDibY
 kb64sQAyKSJoWkPhjtszwvzgZkqk1dce5SepmvYgmA6moJjnDmv1IdA9WiNKCbv4
 KWmz5TSZhz0h+MSXtrFJH+9iqNxN0kZUb1ZjVI8WLN7+Z8QY20tdXS0lkERXbgSo
 2qoWQ1PNckrGZZZCl8eK+J/iSvSgZiUkiPFlsRBsa+D7u+K3ulQ=
 =donq
 -----END PGP SIGNATURE-----

Merge 4.4.131 into android-4.4

Changes in 4.4.131
	ext4: prevent right-shifting extents beyond EXT_MAX_BLOCKS
	ext4: set h_journal if there is a failure starting a reserved handle
	ext4: add validity checks for bitmap block numbers
	ext4: fix bitmap position validation
	usbip: usbip_host: fix to hold parent lock for device_attach() calls
	usbip: vhci_hcd: Fix usb device and sockfd leaks
	USB: serial: simple: add libtransistor console
	USB: serial: ftdi_sio: use jtag quirk for Arrow USB Blaster
	USB: serial: cp210x: add ID for NI USB serial console
	usb: core: Add quirk for HP v222w 16GB Mini
	USB: Increment wakeup count on remote wakeup.
	ALSA: usb-audio: Skip broken EU on Dell dock USB-audio
	virtio: add ability to iterate over vqs
	virtio_console: free buffers after reset
	drm/virtio: fix vq wait_event condition
	tty: Don't call panic() at tty_ldisc_init()
	tty: n_gsm: Fix long delays with control frame timeouts in ADM mode
	tty: n_gsm: Fix DLCI handling for ADM mode if debug & 2 is not set
	tty: Use __GFP_NOFAIL for tty_ldisc_get()
	ALSA: opl3: Hardening for potential Spectre v1
	ALSA: asihpi: Hardening for potential Spectre v1
	ALSA: hdspm: Hardening for potential Spectre v1
	ALSA: rme9652: Hardening for potential Spectre v1
	ALSA: control: Hardening for potential Spectre v1
	ALSA: core: Report audio_tstamp in snd_pcm_sync_ptr
	ALSA: seq: oss: Fix unbalanced use lock for synth MIDI device
	ALSA: seq: oss: Hardening for potential Spectre v1
	ALSA: hda: Hardening for potential Spectre v1
	ALSA: hda/realtek - Add some fixes for ALC233
	mtd: cfi: cmdset_0001: Do not allow read/write to suspend erase block.
	mtd: cfi: cmdset_0001: Workaround Micron Erase suspend bug.
	mtd: cfi: cmdset_0002: Do not allow read/write to suspend erase block.
	kobject: don't use WARN for registration failures
	scsi: sd: Defer spinning up drive while SANITIZE is in progress
	ARM: amba: Make driver_override output consistent with other buses
	ARM: amba: Fix race condition with driver_override
	ARM: amba: Don't read past the end of sysfs "driver_override" buffer
	ASoC: fsl_esai: Fix divisor calculation failure at lower ratio
	libceph: validate con->state at the top of try_write()
	x86/ipc: Fix x32 version of shmid64_ds and msqid64_ds
	x86/smpboot: Don't use mwait_play_dead() on AMD systems
	serial: mctrl_gpio: export mctrl_gpio_disable_ms and mctrl_gpio_init
	serial: mctrl_gpio: Add missing module license
	Linux 4.4.131

Change-Id: I8be9780b3f588b6ca9499b2f31ee4be0dbc9ef77
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2018-05-02 11:10:46 -07:00
commit d5d6526965
47 changed files with 393 additions and 134 deletions

View file

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

View file

@ -1 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __ASM_X64_MSGBUF_H
#define __ASM_X64_MSGBUF_H
#if !defined(__x86_64__) || !defined(__ILP32__)
#include <asm-generic/msgbuf.h> #include <asm-generic/msgbuf.h>
#else
/*
* The msqid64_ds structure for x86 architecture with x32 ABI.
*
* On x86-32 and x86-64 we can just use the generic definition, but
* x32 uses the same binary layout as x86_64, which is differnet
* from other 32-bit architectures.
*/
struct msqid64_ds {
struct ipc64_perm msg_perm;
__kernel_time_t msg_stime; /* last msgsnd time */
__kernel_time_t msg_rtime; /* last msgrcv time */
__kernel_time_t msg_ctime; /* last change time */
__kernel_ulong_t msg_cbytes; /* current number of bytes on queue */
__kernel_ulong_t msg_qnum; /* number of messages in queue */
__kernel_ulong_t msg_qbytes; /* max number of bytes on queue */
__kernel_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_pid_t msg_lrpid; /* last receive pid */
__kernel_ulong_t __unused4;
__kernel_ulong_t __unused5;
};
#endif
#endif /* __ASM_GENERIC_MSGBUF_H */

View file

@ -1 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __ASM_X86_SHMBUF_H
#define __ASM_X86_SHMBUF_H
#if !defined(__x86_64__) || !defined(__ILP32__)
#include <asm-generic/shmbuf.h> #include <asm-generic/shmbuf.h>
#else
/*
* The shmid64_ds structure for x86 architecture with x32 ABI.
*
* On x86-32 and x86-64 we can just use the generic definition, but
* x32 uses the same binary layout as x86_64, which is differnet
* from other 32-bit architectures.
*/
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
size_t shm_segsz; /* size of segment (bytes) */
__kernel_time_t shm_atime; /* last attach time */
__kernel_time_t shm_dtime; /* last detach time */
__kernel_time_t shm_ctime; /* last change time */
__kernel_pid_t shm_cpid; /* pid of creator */
__kernel_pid_t shm_lpid; /* pid of last operator */
__kernel_ulong_t shm_nattch; /* no. of current attaches */
__kernel_ulong_t __unused4;
__kernel_ulong_t __unused5;
};
struct shminfo64 {
__kernel_ulong_t shmmax;
__kernel_ulong_t shmmin;
__kernel_ulong_t shmmni;
__kernel_ulong_t shmseg;
__kernel_ulong_t shmall;
__kernel_ulong_t __unused1;
__kernel_ulong_t __unused2;
__kernel_ulong_t __unused3;
__kernel_ulong_t __unused4;
};
#endif
#endif /* __ASM_X86_SHMBUF_H */

View file

@ -1442,6 +1442,8 @@ static inline void mwait_play_dead(void)
void *mwait_ptr; void *mwait_ptr;
int i; int i;
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
return;
if (!this_cpu_has(X86_FEATURE_MWAIT)) if (!this_cpu_has(X86_FEATURE_MWAIT))
return; return;
if (!this_cpu_has(X86_FEATURE_CLFLUSH)) if (!this_cpu_has(X86_FEATURE_CLFLUSH))

View file

@ -68,11 +68,12 @@ static ssize_t driver_override_show(struct device *_dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct amba_device *dev = to_amba_device(_dev); struct amba_device *dev = to_amba_device(_dev);
ssize_t len;
if (!dev->driver_override) device_lock(_dev);
return 0; len = sprintf(buf, "%s\n", dev->driver_override);
device_unlock(_dev);
return sprintf(buf, "%s\n", dev->driver_override); return len;
} }
static ssize_t driver_override_store(struct device *_dev, static ssize_t driver_override_store(struct device *_dev,
@ -80,7 +81,7 @@ static ssize_t driver_override_store(struct device *_dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct amba_device *dev = to_amba_device(_dev); struct amba_device *dev = to_amba_device(_dev);
char *driver_override, *old = dev->driver_override, *cp; char *driver_override, *old, *cp;
/* We need to keep extra room for a newline */ /* We need to keep extra room for a newline */
if (count >= (PAGE_SIZE - 1)) if (count >= (PAGE_SIZE - 1))
@ -94,12 +95,15 @@ static ssize_t driver_override_store(struct device *_dev,
if (cp) if (cp)
*cp = '\0'; *cp = '\0';
device_lock(_dev);
old = dev->driver_override;
if (strlen(driver_override)) { if (strlen(driver_override)) {
dev->driver_override = driver_override; dev->driver_override = driver_override;
} else { } else {
kfree(driver_override); kfree(driver_override);
dev->driver_override = NULL; dev->driver_override = NULL;
} }
device_unlock(_dev);
kfree(old); kfree(old);

View file

@ -1399,7 +1399,6 @@ static int add_port(struct ports_device *portdev, u32 id)
{ {
char debugfs_name[16]; char debugfs_name[16];
struct port *port; struct port *port;
struct port_buffer *buf;
dev_t devt; dev_t devt;
unsigned int nr_added_bufs; unsigned int nr_added_bufs;
int err; int err;
@ -1510,8 +1509,6 @@ static int add_port(struct ports_device *portdev, u32 id)
return 0; return 0;
free_inbufs: free_inbufs:
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
free_buf(buf, true);
free_device: free_device:
device_destroy(pdrvdata.class, port->dev->devt); device_destroy(pdrvdata.class, port->dev->devt);
free_cdev: free_cdev:
@ -1536,34 +1533,14 @@ static void remove_port(struct kref *kref)
static void remove_port_data(struct port *port) static void remove_port_data(struct port *port)
{ {
struct port_buffer *buf;
spin_lock_irq(&port->inbuf_lock); spin_lock_irq(&port->inbuf_lock);
/* Remove unused data this port might have received. */ /* Remove unused data this port might have received. */
discard_port_data(port); discard_port_data(port);
spin_unlock_irq(&port->inbuf_lock); spin_unlock_irq(&port->inbuf_lock);
/* Remove buffers we queued up for the Host to send us data in. */
do {
spin_lock_irq(&port->inbuf_lock);
buf = virtqueue_detach_unused_buf(port->in_vq);
spin_unlock_irq(&port->inbuf_lock);
if (buf)
free_buf(buf, true);
} while (buf);
spin_lock_irq(&port->outvq_lock); spin_lock_irq(&port->outvq_lock);
reclaim_consumed_buffers(port); reclaim_consumed_buffers(port);
spin_unlock_irq(&port->outvq_lock); spin_unlock_irq(&port->outvq_lock);
/* Free pending buffers from the out-queue. */
do {
spin_lock_irq(&port->outvq_lock);
buf = virtqueue_detach_unused_buf(port->out_vq);
spin_unlock_irq(&port->outvq_lock);
if (buf)
free_buf(buf, true);
} while (buf);
} }
/* /*
@ -1788,13 +1765,24 @@ static void control_work_handler(struct work_struct *work)
spin_unlock(&portdev->c_ivq_lock); spin_unlock(&portdev->c_ivq_lock);
} }
static void flush_bufs(struct virtqueue *vq, bool can_sleep)
{
struct port_buffer *buf;
unsigned int len;
while ((buf = virtqueue_get_buf(vq, &len)))
free_buf(buf, can_sleep);
}
static void out_intr(struct virtqueue *vq) static void out_intr(struct virtqueue *vq)
{ {
struct port *port; struct port *port;
port = find_port_by_vq(vq->vdev->priv, vq); port = find_port_by_vq(vq->vdev->priv, vq);
if (!port) if (!port) {
flush_bufs(vq, false);
return; return;
}
wake_up_interruptible(&port->waitqueue); wake_up_interruptible(&port->waitqueue);
} }
@ -1805,8 +1793,10 @@ static void in_intr(struct virtqueue *vq)
unsigned long flags; unsigned long flags;
port = find_port_by_vq(vq->vdev->priv, vq); port = find_port_by_vq(vq->vdev->priv, vq);
if (!port) if (!port) {
flush_bufs(vq, false);
return; return;
}
spin_lock_irqsave(&port->inbuf_lock, flags); spin_lock_irqsave(&port->inbuf_lock, flags);
port->inbuf = get_inbuf(port); port->inbuf = get_inbuf(port);
@ -1981,6 +1971,15 @@ static const struct file_operations portdev_fops = {
static void remove_vqs(struct ports_device *portdev) static void remove_vqs(struct ports_device *portdev)
{ {
struct virtqueue *vq;
virtio_device_for_each_vq(portdev->vdev, vq) {
struct port_buffer *buf;
flush_bufs(vq, true);
while ((buf = virtqueue_detach_unused_buf(vq)))
free_buf(buf, true);
}
portdev->vdev->config->del_vqs(portdev->vdev); portdev->vdev->config->del_vqs(portdev->vdev);
kfree(portdev->in_vqs); kfree(portdev->in_vqs);
kfree(portdev->out_vqs); kfree(portdev->out_vqs);

View file

@ -324,7 +324,7 @@ retry:
ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC); ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC);
if (ret == -ENOSPC) { if (ret == -ENOSPC) {
spin_unlock(&vgdev->ctrlq.qlock); spin_unlock(&vgdev->ctrlq.qlock);
wait_event(vgdev->ctrlq.ack_queue, vq->num_free); wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt);
spin_lock(&vgdev->ctrlq.qlock); spin_lock(&vgdev->ctrlq.qlock);
goto retry; goto retry;
} else { } else {
@ -399,7 +399,7 @@ retry:
ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC); ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC);
if (ret == -ENOSPC) { if (ret == -ENOSPC) {
spin_unlock(&vgdev->cursorq.qlock); spin_unlock(&vgdev->cursorq.qlock);
wait_event(vgdev->cursorq.ack_queue, vq->num_free); wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt);
spin_lock(&vgdev->cursorq.qlock); spin_lock(&vgdev->cursorq.qlock);
goto retry; goto retry;
} else { } else {

View file

@ -45,6 +45,7 @@
#define I82802AB 0x00ad #define I82802AB 0x00ad
#define I82802AC 0x00ac #define I82802AC 0x00ac
#define PF38F4476 0x881c #define PF38F4476 0x881c
#define M28F00AP30 0x8963
/* STMicroelectronics chips */ /* STMicroelectronics chips */
#define M50LPW080 0x002F #define M50LPW080 0x002F
#define M50FLW080A 0x0080 #define M50FLW080A 0x0080
@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
extp->MinorVersion = '1'; extp->MinorVersion = '1';
} }
static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
{
/*
* Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
* Erase Supend for their small Erase Blocks(0x8000)
*/
if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
return 1;
return 0;
}
static inline struct cfi_pri_intelext * static inline struct cfi_pri_intelext *
read_pri_intelext(struct map_info *map, __u16 adr) read_pri_intelext(struct map_info *map, __u16 adr)
{ {
@ -825,21 +837,30 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
(mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
goto sleep; goto sleep;
/* Do not allow suspend iff read/write to EB address */
if ((adr & chip->in_progress_block_mask) ==
chip->in_progress_block_addr)
goto sleep;
/* do not suspend small EBs, buggy Micron Chips */
if (cfi_is_micron_28F00AP30(cfi, chip) &&
(chip->in_progress_block_mask == ~(0x8000-1)))
goto sleep;
/* Erase suspend */ /* Erase suspend */
map_write(map, CMD(0xB0), adr); map_write(map, CMD(0xB0), chip->in_progress_block_addr);
/* If the flash has finished erasing, then 'erase suspend' /* If the flash has finished erasing, then 'erase suspend'
* appears to make some (28F320) flash devices switch to * appears to make some (28F320) flash devices switch to
* 'read' mode. Make sure that we switch to 'read status' * 'read' mode. Make sure that we switch to 'read status'
* mode so we get the right data. --rmk * mode so we get the right data. --rmk
*/ */
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), chip->in_progress_block_addr);
chip->oldstate = FL_ERASING; chip->oldstate = FL_ERASING;
chip->state = FL_ERASE_SUSPENDING; chip->state = FL_ERASE_SUSPENDING;
chip->erase_suspended = 1; chip->erase_suspended = 1;
for (;;) { for (;;) {
status = map_read(map, adr); status = map_read(map, chip->in_progress_block_addr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
@ -1035,8 +1056,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
sending the 0x70 (Read Status) command to an erasing sending the 0x70 (Read Status) command to an erasing
chip and expecting it to be ignored, that's what we chip and expecting it to be ignored, that's what we
do. */ do. */
map_write(map, CMD(0xd0), adr); map_write(map, CMD(0xd0), chip->in_progress_block_addr);
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), chip->in_progress_block_addr);
chip->oldstate = FL_READY; chip->oldstate = FL_READY;
chip->state = FL_ERASING; chip->state = FL_ERASING;
break; break;
@ -1927,6 +1948,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0xD0), adr); map_write(map, CMD(0xD0), adr);
chip->state = FL_ERASING; chip->state = FL_ERASING;
chip->erase_suspended = 0; chip->erase_suspended = 0;
chip->in_progress_block_addr = adr;
chip->in_progress_block_mask = ~(len - 1);
ret = INVAL_CACHE_AND_WAIT(map, chip, adr, ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len, adr, len,

View file

@ -814,9 +814,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
(mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
goto sleep; goto sleep;
/* We could check to see if we're trying to access the sector /* Do not allow suspend iff read/write to EB address */
* that is currently being erased. However, no user will try if ((adr & chip->in_progress_block_mask) ==
* anything like that so we just wait for the timeout. */ chip->in_progress_block_addr)
goto sleep;
/* Erase suspend */ /* Erase suspend */
/* It's harmless to issue the Erase-Suspend and Erase-Resume /* It's harmless to issue the Erase-Suspend and Erase-Resume
@ -2265,6 +2266,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
chip->state = FL_ERASING; chip->state = FL_ERASING;
chip->erase_suspended = 0; chip->erase_suspended = 0;
chip->in_progress_block_addr = adr; chip->in_progress_block_addr = adr;
chip->in_progress_block_mask = ~(map->size - 1);
INVALIDATE_CACHE_UDELAY(map, chip, INVALIDATE_CACHE_UDELAY(map, chip,
adr, map->size, adr, map->size,
@ -2354,6 +2356,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
chip->state = FL_ERASING; chip->state = FL_ERASING;
chip->erase_suspended = 0; chip->erase_suspended = 0;
chip->in_progress_block_addr = adr; chip->in_progress_block_addr = adr;
chip->in_progress_block_mask = ~(len - 1);
INVALIDATE_CACHE_UDELAY(map, chip, INVALIDATE_CACHE_UDELAY(map, chip,
adr, len, adr, len,

View file

@ -1929,6 +1929,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
break; /* standby */ break; /* standby */
if (sshdr.asc == 4 && sshdr.ascq == 0xc) if (sshdr.asc == 4 && sshdr.ascq == 0xc)
break; /* unavailable */ break; /* unavailable */
if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
break; /* sanitize in progress */
/* /*
* Issue command to spin up drive when not ready * Issue command to spin up drive when not ready
*/ */

View file

@ -137,6 +137,9 @@ struct gsm_dlci {
struct mutex mutex; struct mutex mutex;
/* Link layer */ /* Link layer */
int mode;
#define DLCI_MODE_ABM 0 /* Normal Asynchronous Balanced Mode */
#define DLCI_MODE_ADM 1 /* Asynchronous Disconnected Mode */
spinlock_t lock; /* Protects the internal state */ spinlock_t lock; /* Protects the internal state */
struct timer_list t1; /* Retransmit timer for SABM and UA */ struct timer_list t1; /* Retransmit timer for SABM and UA */
int retries; int retries;
@ -1380,7 +1383,13 @@ retry:
ctrl->data = data; ctrl->data = data;
ctrl->len = clen; ctrl->len = clen;
gsm->pending_cmd = ctrl; gsm->pending_cmd = ctrl;
gsm->cretries = gsm->n2;
/* If DLCI0 is in ADM mode skip retries, it won't respond */
if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
gsm->cretries = 1;
else
gsm->cretries = gsm->n2;
mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100); mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
gsm_control_transmit(gsm, ctrl); gsm_control_transmit(gsm, ctrl);
spin_unlock_irqrestore(&gsm->control_lock, flags); spin_unlock_irqrestore(&gsm->control_lock, flags);
@ -1488,6 +1497,7 @@ static void gsm_dlci_t1(unsigned long data)
if (debug & 8) if (debug & 8)
pr_info("DLCI %d opening in ADM mode.\n", pr_info("DLCI %d opening in ADM mode.\n",
dlci->addr); dlci->addr);
dlci->mode = DLCI_MODE_ADM;
gsm_dlci_open(dlci); gsm_dlci_open(dlci);
} else { } else {
gsm_dlci_close(dlci); gsm_dlci_close(dlci);
@ -2881,11 +2891,22 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
static int gsm_carrier_raised(struct tty_port *port) static int gsm_carrier_raised(struct tty_port *port)
{ {
struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
struct gsm_mux *gsm = dlci->gsm;
/* Not yet open so no carrier info */ /* Not yet open so no carrier info */
if (dlci->state != DLCI_OPEN) if (dlci->state != DLCI_OPEN)
return 0; return 0;
if (debug & 2) if (debug & 2)
return 1; return 1;
/*
* Basic mode with control channel in ADM mode may not respond
* to CMD_MSC at all and modem_rx is empty.
*/
if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM &&
!dlci->modem_rx)
return 1;
return dlci->modem_rx & TIOCM_CD; return dlci->modem_rx & TIOCM_CD;
} }

View file

@ -20,6 +20,7 @@
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/termios.h> #include <linux/termios.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/module.h>
#include "serial_mctrl_gpio.h" #include "serial_mctrl_gpio.h"
@ -193,6 +194,7 @@ struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx)
return gpios; return gpios;
} }
EXPORT_SYMBOL_GPL(mctrl_gpio_init);
void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios)
{ {
@ -247,3 +249,6 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios)
disable_irq(gpios->irq[i]); disable_irq(gpios->irq[i]);
} }
} }
EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms);
MODULE_LICENSE("GPL");

View file

@ -3154,7 +3154,10 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
kref_init(&tty->kref); kref_init(&tty->kref);
tty->magic = TTY_MAGIC; tty->magic = TTY_MAGIC;
tty_ldisc_init(tty); if (tty_ldisc_init(tty)) {
kfree(tty);
return NULL;
}
tty->session = NULL; tty->session = NULL;
tty->pgrp = NULL; tty->pgrp = NULL;
mutex_init(&tty->legacy_mutex); mutex_init(&tty->legacy_mutex);

View file

@ -168,12 +168,11 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
return ERR_CAST(ldops); return ERR_CAST(ldops);
} }
ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL); /*
if (ld == NULL) { * There is no way to handle allocation failure of only 16 bytes.
put_ldops(ldops); * Let's simplify error handling and save more memory.
return ERR_PTR(-ENOMEM); */
} ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
ld->ops = ldops; ld->ops = ldops;
ld->tty = tty; ld->tty = tty;
@ -804,12 +803,13 @@ void tty_ldisc_release(struct tty_struct *tty)
* the tty structure is not completely set up when this call is made. * the tty structure is not completely set up when this call is made.
*/ */
void tty_ldisc_init(struct tty_struct *tty) int tty_ldisc_init(struct tty_struct *tty)
{ {
struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY); struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
if (IS_ERR(ld)) if (IS_ERR(ld))
panic("n_tty: init_tty"); return PTR_ERR(ld);
tty->ldisc = ld; tty->ldisc = ld;
return 0;
} }
/** /**

View file

@ -2339,6 +2339,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
spin_lock_irqsave (&hcd_root_hub_lock, flags); spin_lock_irqsave (&hcd_root_hub_lock, flags);
if (hcd->rh_registered) { if (hcd->rh_registered) {
pm_wakeup_event(&hcd->self.root_hub->dev, 0);
set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
queue_work(pm_wq, &hcd->wakeup_work); queue_work(pm_wq, &hcd->wakeup_work);
} }

View file

@ -632,12 +632,17 @@ void usb_wakeup_notification(struct usb_device *hdev,
unsigned int portnum) unsigned int portnum)
{ {
struct usb_hub *hub; struct usb_hub *hub;
struct usb_port *port_dev;
if (!hdev) if (!hdev)
return; return;
hub = usb_hub_to_struct_hub(hdev); hub = usb_hub_to_struct_hub(hdev);
if (hub) { if (hub) {
port_dev = hub->ports[portnum - 1];
if (port_dev && port_dev->child)
pm_wakeup_event(&port_dev->child->dev, 0);
set_bit(portnum, hub->wakeup_bits); set_bit(portnum, hub->wakeup_bits);
kick_hub_wq(hub); kick_hub_wq(hub);
} }
@ -3361,8 +3366,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
/* Skip the initial Clear-Suspend step for a remote wakeup */ /* Skip the initial Clear-Suspend step for a remote wakeup */
status = hub_port_status(hub, port1, &portstatus, &portchange); status = hub_port_status(hub, port1, &portstatus, &portchange);
if (status == 0 && !port_is_suspended(hub, portstatus)) if (status == 0 && !port_is_suspended(hub, portstatus)) {
if (portchange & USB_PORT_STAT_C_SUSPEND)
pm_wakeup_event(&udev->dev, 0);
goto SuspendCleared; goto SuspendCleared;
}
/* see 7.1.7.7; affects power usage, but not budgeting */ /* see 7.1.7.7; affects power usage, but not budgeting */
if (hub_is_superspeed(hub->hdev)) if (hub_is_superspeed(hub->hdev))

View file

@ -45,6 +45,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = { USB_DEVICE(0x03f0, 0x0701), .driver_info =
USB_QUIRK_STRING_FETCH_255 }, USB_QUIRK_STRING_FETCH_255 },
/* HP v222w 16GB Mini USB Drive */
{ USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
/* Creative SB Audigy 2 NX */ /* Creative SB Audigy 2 NX */
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },

View file

@ -62,6 +62,7 @@ config USB_SERIAL_SIMPLE
- Fundamental Software dongle. - Fundamental Software dongle.
- Google USB serial devices - Google USB serial devices
- HP4x calculators - HP4x calculators
- Libtransistor USB console
- a number of Motorola phones - a number of Motorola phones
- Motorola Tetra devices - Motorola Tetra devices
- Novatel Wireless GPS receivers - Novatel Wireless GPS receivers

View file

@ -210,6 +210,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3923, 0x7A0B) }, /* National Instruments USB Serial Console */
{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
{ } /* Terminating Entry */ { } /* Terminating Entry */
}; };

View file

@ -1911,7 +1911,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
return ftdi_jtag_probe(serial); return ftdi_jtag_probe(serial);
if (udev->product && if (udev->product &&
(!strcmp(udev->product, "BeagleBone/XDS100V2") || (!strcmp(udev->product, "Arrow USB Blaster") ||
!strcmp(udev->product, "BeagleBone/XDS100V2") ||
!strcmp(udev->product, "SNAP Connect E10"))) !strcmp(udev->product, "SNAP Connect E10")))
return ftdi_jtag_probe(serial); return ftdi_jtag_probe(serial);

View file

@ -66,6 +66,11 @@ DEVICE(flashloader, FLASHLOADER_IDS);
0x01) } 0x01) }
DEVICE(google, GOOGLE_IDS); DEVICE(google, GOOGLE_IDS);
/* Libtransistor USB console */
#define LIBTRANSISTOR_IDS() \
{ USB_DEVICE(0x1209, 0x8b00) }
DEVICE(libtransistor, LIBTRANSISTOR_IDS);
/* ViVOpay USB Serial Driver */ /* ViVOpay USB Serial Driver */
#define VIVOPAY_IDS() \ #define VIVOPAY_IDS() \
{ USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */
@ -113,6 +118,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
&funsoft_device, &funsoft_device,
&flashloader_device, &flashloader_device,
&google_device, &google_device,
&libtransistor_device,
&vivopay_device, &vivopay_device,
&moto_modem_device, &moto_modem_device,
&motorola_tetra_device, &motorola_tetra_device,
@ -129,6 +135,7 @@ static const struct usb_device_id id_table[] = {
FUNSOFT_IDS(), FUNSOFT_IDS(),
FLASHLOADER_IDS(), FLASHLOADER_IDS(),
GOOGLE_IDS(), GOOGLE_IDS(),
LIBTRANSISTOR_IDS(),
VIVOPAY_IDS(), VIVOPAY_IDS(),
MOTO_IDS(), MOTO_IDS(),
MOTOROLA_TETRA_IDS(), MOTOROLA_TETRA_IDS(),

View file

@ -201,7 +201,12 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf,
if (!bid) if (!bid)
return -ENODEV; return -ENODEV;
/* device_attach() callers should hold parent lock for USB */
if (bid->udev->dev.parent)
device_lock(bid->udev->dev.parent);
ret = device_attach(&bid->udev->dev); ret = device_attach(&bid->udev->dev);
if (bid->udev->dev.parent)
device_unlock(bid->udev->dev.parent);
if (ret < 0) { if (ret < 0) {
dev_err(&bid->udev->dev, "rebind failed\n"); dev_err(&bid->udev->dev, "rebind failed\n");
return ret; return ret;

View file

@ -248,7 +248,7 @@ enum usbip_side {
#define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) #define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
#define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) #define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE) #define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
#define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) #define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
#define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) #define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
#define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)

View file

@ -320,6 +320,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_grpblk_t offset; ext4_grpblk_t offset;
ext4_grpblk_t next_zero_bit; ext4_grpblk_t next_zero_bit;
ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb);
ext4_fsblk_t blk; ext4_fsblk_t blk;
ext4_fsblk_t group_first_block; ext4_fsblk_t group_first_block;
@ -337,20 +338,25 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
/* check whether block bitmap block number is set */ /* check whether block bitmap block number is set */
blk = ext4_block_bitmap(sb, desc); blk = ext4_block_bitmap(sb, desc);
offset = blk - group_first_block; offset = blk - group_first_block;
if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
/* bad block bitmap */ /* bad block bitmap */
return blk; return blk;
/* check whether the inode bitmap block number is set */ /* check whether the inode bitmap block number is set */
blk = ext4_inode_bitmap(sb, desc); blk = ext4_inode_bitmap(sb, desc);
offset = blk - group_first_block; offset = blk - group_first_block;
if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
/* bad block bitmap */ /* bad block bitmap */
return blk; return blk;
/* check whether the inode table block number is set */ /* check whether the inode table block number is set */
blk = ext4_inode_table(sb, desc); blk = ext4_inode_table(sb, desc);
offset = blk - group_first_block; offset = blk - group_first_block;
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit)
return blk;
next_zero_bit = ext4_find_next_zero_bit(bh->b_data, next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
EXT4_B2C(sbi, offset + EXT4_SB(sb)->s_itb_per_group), EXT4_B2C(sbi, offset + EXT4_SB(sb)->s_itb_per_group),
EXT4_B2C(sbi, offset)); EXT4_B2C(sbi, offset));
@ -416,6 +422,7 @@ struct buffer_head *
ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
{ {
struct ext4_group_desc *desc; struct ext4_group_desc *desc;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct buffer_head *bh; struct buffer_head *bh;
ext4_fsblk_t bitmap_blk; ext4_fsblk_t bitmap_blk;
int err; int err;
@ -424,6 +431,12 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
if (!desc) if (!desc)
return ERR_PTR(-EFSCORRUPTED); return ERR_PTR(-EFSCORRUPTED);
bitmap_blk = ext4_block_bitmap(sb, desc); bitmap_blk = ext4_block_bitmap(sb, desc);
if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
(bitmap_blk >= ext4_blocks_count(sbi->s_es))) {
ext4_error(sb, "Invalid block bitmap block %llu in "
"block_group %u", bitmap_blk, block_group);
return ERR_PTR(-EFSCORRUPTED);
}
bh = sb_getblk(sb, bitmap_blk); bh = sb_getblk(sb, bitmap_blk);
if (unlikely(!bh)) { if (unlikely(!bh)) {
ext4_error(sb, "Cannot get buffer for block bitmap - " ext4_error(sb, "Cannot get buffer for block bitmap - "

View file

@ -5380,8 +5380,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
stop = le32_to_cpu(extent->ee_block); stop = le32_to_cpu(extent->ee_block);
/* /*
* In case of left shift, Don't start shifting extents until we make * For left shifts, make sure the hole on the left is big enough to
* sure the hole is big enough to accommodate the shift. * accommodate the shift. For right shifts, make sure the last extent
* won't be shifted beyond EXT_MAX_BLOCKS.
*/ */
if (SHIFT == SHIFT_LEFT) { if (SHIFT == SHIFT_LEFT) {
path = ext4_find_extent(inode, start - 1, &path, path = ext4_find_extent(inode, start - 1, &path,
@ -5401,9 +5402,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
if ((start == ex_start && shift > ex_start) || if ((start == ex_start && shift > ex_start) ||
(shift > start - ex_end)) { (shift > start - ex_end)) {
ext4_ext_drop_refs(path); ret = -EINVAL;
kfree(path); goto out;
return -EINVAL; }
} else {
if (shift > EXT_MAX_BLOCKS -
(stop + ext4_ext_get_actual_len(extent))) {
ret = -EINVAL;
goto out;
} }
} }

View file

@ -119,6 +119,7 @@ static struct buffer_head *
ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
{ {
struct ext4_group_desc *desc; struct ext4_group_desc *desc;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
ext4_fsblk_t bitmap_blk; ext4_fsblk_t bitmap_blk;
int err; int err;
@ -128,6 +129,12 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
return ERR_PTR(-EFSCORRUPTED); return ERR_PTR(-EFSCORRUPTED);
bitmap_blk = ext4_inode_bitmap(sb, desc); bitmap_blk = ext4_inode_bitmap(sb, desc);
if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
(bitmap_blk >= ext4_blocks_count(sbi->s_es))) {
ext4_error(sb, "Invalid inode bitmap blk %llu in "
"block_group %u", bitmap_blk, block_group);
return ERR_PTR(-EFSCORRUPTED);
}
bh = sb_getblk(sb, bitmap_blk); bh = sb_getblk(sb, bitmap_blk);
if (unlikely(!bh)) { if (unlikely(!bh)) {
ext4_error(sb, "Cannot read inode bitmap - " ext4_error(sb, "Cannot read inode bitmap - "

View file

@ -527,6 +527,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
*/ */
ret = start_this_handle(journal, handle, GFP_NOFS); ret = start_this_handle(journal, handle, GFP_NOFS);
if (ret < 0) { if (ret < 0) {
handle->h_journal = journal;
jbd2_journal_free_reserved(handle); jbd2_journal_free_reserved(handle);
return ret; return ret;
} }

View file

@ -85,6 +85,7 @@ struct flchip {
unsigned int write_suspended:1; unsigned int write_suspended:1;
unsigned int erase_suspended:1; unsigned int erase_suspended:1;
unsigned long in_progress_block_addr; unsigned long in_progress_block_addr;
unsigned long in_progress_block_mask;
struct mutex mutex; struct mutex mutex;
wait_queue_head_t wq; /* Wait on here when we're waiting for the chip wait_queue_head_t wq; /* Wait on here when we're waiting for the chip

View file

@ -586,7 +586,7 @@ extern int tty_unregister_ldisc(int disc);
extern int tty_set_ldisc(struct tty_struct *tty, int ldisc); extern int tty_set_ldisc(struct tty_struct *tty, int ldisc);
extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
extern void tty_ldisc_release(struct tty_struct *tty); extern void tty_ldisc_release(struct tty_struct *tty);
extern void tty_ldisc_init(struct tty_struct *tty); extern int __must_check tty_ldisc_init(struct tty_struct *tty);
extern void tty_ldisc_deinit(struct tty_struct *tty); extern void tty_ldisc_deinit(struct tty_struct *tty);
extern void tty_ldisc_begin(void); extern void tty_ldisc_begin(void);

View file

@ -124,6 +124,9 @@ int virtio_device_freeze(struct virtio_device *dev);
int virtio_device_restore(struct virtio_device *dev); int virtio_device_restore(struct virtio_device *dev);
#endif #endif
#define virtio_device_for_each_vq(vdev, vq) \
list_for_each_entry(vq, &vdev->vqs, list)
/** /**
* virtio_driver - operations for a virtio I/O driver * virtio_driver - operations for a virtio I/O driver
* @driver: underlying device driver (populate name and owner). * @driver: underlying device driver (populate name and owner).

View file

@ -22,6 +22,7 @@
* *
*/ */
#include <linux/nospec.h>
#include <sound/asound.h> #include <sound/asound.h>
#define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data) #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
@ -147,12 +148,14 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
{ {
return id->numid - kctl->id.numid; unsigned int ioff = id->numid - kctl->id.numid;
return array_index_nospec(ioff, kctl->count);
} }
static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
{ {
return id->index - kctl->id.index; unsigned int ioff = id->index - kctl->id.index;
return array_index_nospec(ioff, kctl->count);
} }
static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)

View file

@ -234,14 +234,12 @@ static int kobject_add_internal(struct kobject *kobj)
/* be noisy on error issues */ /* be noisy on error issues */
if (error == -EEXIST) if (error == -EEXIST)
WARN(1, "%s failed for %s with " pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
"-EEXIST, don't try to register things with " __func__, kobject_name(kobj));
"the same name in the same directory.\n",
__func__, kobject_name(kobj));
else else
WARN(1, "%s failed for %s (error: %d parent: %s)\n", pr_err("%s failed for %s (error: %d parent: %s)\n",
__func__, kobject_name(kobj), error, __func__, kobject_name(kobj), error,
parent ? kobject_name(parent) : "'none'"); parent ? kobject_name(parent) : "'none'");
} else } else
kobj->state_in_sysfs = 1; kobj->state_in_sysfs = 1;

View file

@ -2531,6 +2531,11 @@ static int try_write(struct ceph_connection *con)
int ret = 1; int ret = 1;
dout("try_write start %p state %lu\n", con, con->state); dout("try_write start %p state %lu\n", con, con->state);
if (con->state != CON_STATE_PREOPEN &&
con->state != CON_STATE_CONNECTING &&
con->state != CON_STATE_NEGOTIATING &&
con->state != CON_STATE_OPEN)
return 0;
more: more:
dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes); dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
@ -2556,6 +2561,8 @@ more:
} }
more_kvec: more_kvec:
BUG_ON(!con->sock);
/* kvec data queued? */ /* kvec data queued? */
if (con->out_kvec_left) { if (con->out_kvec_left) {
ret = write_partial_kvec(con); ret = write_partial_kvec(con);

View file

@ -2727,6 +2727,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
sync_ptr.s.status.hw_ptr = status->hw_ptr; sync_ptr.s.status.hw_ptr = status->hw_ptr;
sync_ptr.s.status.tstamp = status->tstamp; sync_ptr.s.status.tstamp = status->tstamp;
sync_ptr.s.status.suspended_state = status->suspended_state; sync_ptr.s.status.suspended_state = status->suspended_state;
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr))) if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
return -EFAULT; return -EFAULT;

View file

@ -26,6 +26,7 @@
#include <sound/seq_oss_legacy.h> #include <sound/seq_oss_legacy.h>
#include "seq_oss_readq.h" #include "seq_oss_readq.h"
#include "seq_oss_writeq.h" #include "seq_oss_writeq.h"
#include <linux/nospec.h>
/* /*
@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
{ {
struct seq_oss_synthinfo *info; struct seq_oss_synthinfo *info;
if (!snd_seq_oss_synth_is_valid(dp, dev)) info = snd_seq_oss_synth_info(dp, dev);
if (!info)
return -ENXIO; return -ENXIO;
info = &dp->synths[dev];
switch (info->arg.event_passing) { switch (info->arg.event_passing) {
case SNDRV_SEQ_OSS_PROCESS_EVENTS: case SNDRV_SEQ_OSS_PROCESS_EVENTS:
if (! info->ch || ch < 0 || ch >= info->nr_voices) { if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
} }
ch = array_index_nospec(ch, info->nr_voices);
if (note == 255 && info->ch[ch].note >= 0) { if (note == 255 && info->ch[ch].note >= 0) {
/* volume control */ /* volume control */
int type; int type;
@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
{ {
struct seq_oss_synthinfo *info; struct seq_oss_synthinfo *info;
if (!snd_seq_oss_synth_is_valid(dp, dev)) info = snd_seq_oss_synth_info(dp, dev);
if (!info)
return -ENXIO; return -ENXIO;
info = &dp->synths[dev];
switch (info->arg.event_passing) { switch (info->arg.event_passing) {
case SNDRV_SEQ_OSS_PROCESS_EVENTS: case SNDRV_SEQ_OSS_PROCESS_EVENTS:
if (! info->ch || ch < 0 || ch >= info->nr_voices) { if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
} }
ch = array_index_nospec(ch, info->nr_voices);
if (info->ch[ch].note >= 0) { if (info->ch[ch].note >= 0) {
note = info->ch[ch].note; note = info->ch[ch].note;
info->ch[ch].vel = 0; info->ch[ch].vel = 0;
@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
static int static int
set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev) set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
{ {
if (! snd_seq_oss_synth_is_valid(dp, dev)) if (!snd_seq_oss_synth_info(dp, dev))
return -ENXIO; return -ENXIO;
ev->type = type; ev->type = type;
@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note,
static int static int
set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev) set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
{ {
if (! snd_seq_oss_synth_is_valid(dp, dev)) if (!snd_seq_oss_synth_info(dp, dev))
return -ENXIO; return -ENXIO;
ev->type = type; ev->type = type;

View file

@ -29,6 +29,7 @@
#include "../seq_lock.h" #include "../seq_lock.h"
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/nospec.h>
/* /*
@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp, int dev)
{ {
if (dev < 0 || dev >= dp->max_mididev) if (dev < 0 || dev >= dp->max_mididev)
return NULL; return NULL;
dev = array_index_nospec(dev, dp->max_mididev);
return get_mdev(dev); return get_mdev(dev);
} }

View file

@ -26,6 +26,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/nospec.h>
/* /*
* constants * constants
@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
dp->max_synthdev = 0; dp->max_synthdev = 0;
} }
/* static struct seq_oss_synthinfo *
* check if the specified device is MIDI mapped device get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev)
*/
static int
is_midi_dev(struct seq_oss_devinfo *dp, int dev)
{ {
if (dev < 0 || dev >= dp->max_synthdev) if (dev < 0 || dev >= dp->max_synthdev)
return 0; return NULL;
if (dp->synths[dev].is_midi) dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS);
return 1; return &dp->synths[dev];
return 0;
} }
/* /*
@ -359,14 +356,20 @@ static struct seq_oss_synth *
get_synthdev(struct seq_oss_devinfo *dp, int dev) get_synthdev(struct seq_oss_devinfo *dp, int dev)
{ {
struct seq_oss_synth *rec; struct seq_oss_synth *rec;
if (dev < 0 || dev >= dp->max_synthdev) struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
if (!info)
return NULL; return NULL;
if (! dp->synths[dev].opened) if (!info->opened)
return NULL;
if (dp->synths[dev].is_midi)
return &midi_synth_dev;
if ((rec = get_sdev(dev)) == NULL)
return NULL; return NULL;
if (info->is_midi) {
rec = &midi_synth_dev;
snd_use_lock_use(&rec->use_lock);
} else {
rec = get_sdev(dev);
if (!rec)
return NULL;
}
if (! rec->opened) { if (! rec->opened) {
snd_use_lock_free(&rec->use_lock); snd_use_lock_free(&rec->use_lock);
return NULL; return NULL;
@ -402,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
struct seq_oss_synth *rec; struct seq_oss_synth *rec;
struct seq_oss_synthinfo *info; struct seq_oss_synthinfo *info;
if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev)) info = get_synthinfo_nospec(dp, dev);
return; if (!info || !info->opened)
info = &dp->synths[dev];
if (! info->opened)
return; return;
if (info->sysex) if (info->sysex)
info->sysex->len = 0; /* reset sysex */ info->sysex->len = 0; /* reset sysex */
@ -454,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
const char __user *buf, int p, int c) const char __user *buf, int p, int c)
{ {
struct seq_oss_synth *rec; struct seq_oss_synth *rec;
struct seq_oss_synthinfo *info;
int rc; int rc;
if (dev < 0 || dev >= dp->max_synthdev) info = get_synthinfo_nospec(dp, dev);
if (!info)
return -ENXIO; return -ENXIO;
if (is_midi_dev(dp, dev)) if (info->is_midi)
return 0; return 0;
if ((rec = get_synthdev(dp, dev)) == NULL) if ((rec = get_synthdev(dp, dev)) == NULL)
return -ENXIO; return -ENXIO;
@ -467,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
if (rec->oper.load_patch == NULL) if (rec->oper.load_patch == NULL)
rc = -ENXIO; rc = -ENXIO;
else else
rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c); rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
snd_use_lock_free(&rec->use_lock); snd_use_lock_free(&rec->use_lock);
return rc; return rc;
} }
/* /*
* check if the device is valid synth device * check if the device is valid synth device and return the synth info
*/ */
int struct seq_oss_synthinfo *
snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev) snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
{ {
struct seq_oss_synth *rec; struct seq_oss_synth *rec;
rec = get_synthdev(dp, dev); rec = get_synthdev(dp, dev);
if (rec) { if (rec) {
snd_use_lock_free(&rec->use_lock); snd_use_lock_free(&rec->use_lock);
return 1; return get_synthinfo_nospec(dp, dev);
} }
return 0; return NULL;
} }
@ -499,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
int i, send; int i, send;
unsigned char *dest; unsigned char *dest;
struct seq_oss_synth_sysex *sysex; struct seq_oss_synth_sysex *sysex;
struct seq_oss_synthinfo *info;
if (! snd_seq_oss_synth_is_valid(dp, dev)) info = snd_seq_oss_synth_info(dp, dev);
if (!info)
return -ENXIO; return -ENXIO;
sysex = dp->synths[dev].sysex; sysex = info->sysex;
if (sysex == NULL) { if (sysex == NULL) {
sysex = kzalloc(sizeof(*sysex), GFP_KERNEL); sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
if (sysex == NULL) if (sysex == NULL)
return -ENOMEM; return -ENOMEM;
dp->synths[dev].sysex = sysex; info->sysex = sysex;
} }
send = 0; send = 0;
@ -553,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
int int
snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev) snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
{ {
if (! snd_seq_oss_synth_is_valid(dp, dev)) struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev);
if (!info)
return -EINVAL; return -EINVAL;
snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client, snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client,
dp->synths[dev].arg.addr.port); info->arg.addr.port);
return 0; return 0;
} }
@ -568,16 +576,18 @@ int
snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr) snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
{ {
struct seq_oss_synth *rec; struct seq_oss_synth *rec;
struct seq_oss_synthinfo *info;
int rc; int rc;
if (is_midi_dev(dp, dev)) info = get_synthinfo_nospec(dp, dev);
if (!info || info->is_midi)
return -ENXIO; return -ENXIO;
if ((rec = get_synthdev(dp, dev)) == NULL) if ((rec = get_synthdev(dp, dev)) == NULL)
return -ENXIO; return -ENXIO;
if (rec->oper.ioctl == NULL) if (rec->oper.ioctl == NULL)
rc = -ENXIO; rc = -ENXIO;
else else
rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr); rc = rec->oper.ioctl(&info->arg, cmd, addr);
snd_use_lock_free(&rec->use_lock); snd_use_lock_free(&rec->use_lock);
return rc; return rc;
} }
@ -589,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u
int int
snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev) snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
{ {
if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev)) struct seq_oss_synthinfo *info;
info = snd_seq_oss_synth_info(dp, dev);
if (!info || info->is_midi)
return -ENXIO; return -ENXIO;
ev->type = SNDRV_SEQ_EVENT_OSS; ev->type = SNDRV_SEQ_EVENT_OSS;
memcpy(ev->data.raw8.d, data, 8); memcpy(ev->data.raw8.d, data, 8);

View file

@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp);
void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev); void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt, int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
const char __user *buf, int p, int c); const char __user *buf, int p, int c);
int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev); struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp,
int dev);
int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
struct snd_seq_event *ev); struct snd_seq_event *ev);
int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev); int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);

View file

@ -21,6 +21,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/nospec.h>
#include <sound/opl3.h> #include <sound/opl3.h>
#include <sound/asound_fm.h> #include <sound/asound_fm.h>
@ -448,7 +449,7 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
{ {
unsigned short reg_side; unsigned short reg_side;
unsigned char op_offset; unsigned char op_offset;
unsigned char voice_offset; unsigned char voice_offset, voice_op;
unsigned short opl3_reg; unsigned short opl3_reg;
unsigned char reg_val; unsigned char reg_val;
@ -473,7 +474,9 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
voice_offset = voice->voice - MAX_OPL2_VOICES; voice_offset = voice->voice - MAX_OPL2_VOICES;
} }
/* Get register offset of operator */ /* Get register offset of operator */
op_offset = snd_opl3_regmap[voice_offset][voice->op]; voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES);
voice_op = array_index_nospec(voice->op, 4);
op_offset = snd_opl3_regmap[voice_offset][voice_op];
reg_val = 0x00; reg_val = 0x00;
/* Set amplitude modulation (tremolo) effect */ /* Set amplitude modulation (tremolo) effect */

View file

@ -23,6 +23,7 @@
#include "hpi_internal.h" #include "hpi_internal.h"
#include "hpimsginit.h" #include "hpimsginit.h"
#include <linux/nospec.h>
/* The actual message size for each object type */ /* The actual message size for each object type */
static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
@ -39,10 +40,12 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
{ {
u16 size; u16 size;
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
size = msg_size[object]; size = msg_size[object];
else } else {
size = sizeof(*phm); size = sizeof(*phm);
}
memset(phm, 0, size); memset(phm, 0, size);
phm->size = size; phm->size = size;
@ -66,10 +69,12 @@ void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
{ {
u16 size; u16 size;
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
size = res_size[object]; size = res_size[object];
else } else {
size = sizeof(*phr); size = sizeof(*phr);
}
memset(phr, 0, sizeof(*phr)); memset(phr, 0, sizeof(*phr));
phr->size = size; phr->size = size;

View file

@ -33,6 +33,7 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/nospec.h>
#ifdef MODULE_FIRMWARE #ifdef MODULE_FIRMWARE
MODULE_FIRMWARE("asihpi/dsp5000.bin"); MODULE_FIRMWARE("asihpi/dsp5000.bin");
@ -182,7 +183,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct hpi_adapter *pa = NULL; struct hpi_adapter *pa = NULL;
if (hm->h.adapter_index < ARRAY_SIZE(adapters)) if (hm->h.adapter_index < ARRAY_SIZE(adapters))
pa = &adapters[hm->h.adapter_index]; pa = &adapters[array_index_nospec(hm->h.adapter_index,
ARRAY_SIZE(adapters))];
if (!pa || !pa->adapter || !pa->adapter->type) { if (!pa || !pa->adapter || !pa->adapter->type) {
hpi_init_response(&hr->r0, hm->h.object, hpi_init_response(&hr->r0, hm->h.object,

View file

@ -21,6 +21,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/nospec.h>
#include <sound/core.h> #include <sound/core.h>
#include "hda_codec.h" #include "hda_codec.h"
#include "hda_local.h" #include "hda_local.h"
@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_codec *codec,
if (get_user(verb, &arg->verb)) if (get_user(verb, &arg->verb))
return -EFAULT; return -EFAULT;
res = get_wcaps(codec, verb >> 24); /* open-code get_wcaps(verb>>24) with nospec */
verb >>= 24;
if (verb < codec->core.start_nid ||
verb >= codec->core.start_nid + codec->core.num_nodes) {
res = 0;
} else {
verb -= codec->core.start_nid;
verb = array_index_nospec(verb, codec->core.num_nodes);
res = codec->wcaps[verb];
}
if (put_user(res, &arg->res)) if (put_user(res, &arg->res))
return -EFAULT; return -EFAULT;
return 0; return 0;

View file

@ -329,6 +329,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
break; break;
case 0x10ec0225: case 0x10ec0225:
case 0x10ec0233: case 0x10ec0233:
case 0x10ec0235:
case 0x10ec0236: case 0x10ec0236:
case 0x10ec0255: case 0x10ec0255:
case 0x10ec0256: case 0x10ec0256:
@ -6296,6 +6297,7 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0298: case 0x10ec0298:
spec->codec_variant = ALC269_TYPE_ALC298; spec->codec_variant = ALC269_TYPE_ALC298;
break; break;
case 0x10ec0235:
case 0x10ec0255: case 0x10ec0255:
spec->codec_variant = ALC269_TYPE_ALC255; spec->codec_variant = ALC269_TYPE_ALC255;
break; break;

View file

@ -137,6 +137,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/nospec.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
@ -5692,40 +5693,43 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
struct snd_pcm_channel_info *info) struct snd_pcm_channel_info *info)
{ {
struct hdspm *hdspm = snd_pcm_substream_chip(substream); struct hdspm *hdspm = snd_pcm_substream_chip(substream);
unsigned int channel = info->channel;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) { if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
dev_info(hdspm->card->dev, dev_info(hdspm->card->dev,
"snd_hdspm_channel_info: output channel out of range (%d)\n", "snd_hdspm_channel_info: output channel out of range (%d)\n",
info->channel); channel);
return -EINVAL; return -EINVAL;
} }
if (hdspm->channel_map_out[info->channel] < 0) { channel = array_index_nospec(channel, hdspm->max_channels_out);
if (hdspm->channel_map_out[channel] < 0) {
dev_info(hdspm->card->dev, dev_info(hdspm->card->dev,
"snd_hdspm_channel_info: output channel %d mapped out\n", "snd_hdspm_channel_info: output channel %d mapped out\n",
info->channel); channel);
return -EINVAL; return -EINVAL;
} }
info->offset = hdspm->channel_map_out[info->channel] * info->offset = hdspm->channel_map_out[channel] *
HDSPM_CHANNEL_BUFFER_BYTES; HDSPM_CHANNEL_BUFFER_BYTES;
} else { } else {
if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) { if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
dev_info(hdspm->card->dev, dev_info(hdspm->card->dev,
"snd_hdspm_channel_info: input channel out of range (%d)\n", "snd_hdspm_channel_info: input channel out of range (%d)\n",
info->channel); channel);
return -EINVAL; return -EINVAL;
} }
if (hdspm->channel_map_in[info->channel] < 0) { channel = array_index_nospec(channel, hdspm->max_channels_in);
if (hdspm->channel_map_in[channel] < 0) {
dev_info(hdspm->card->dev, dev_info(hdspm->card->dev,
"snd_hdspm_channel_info: input channel %d mapped out\n", "snd_hdspm_channel_info: input channel %d mapped out\n",
info->channel); channel);
return -EINVAL; return -EINVAL;
} }
info->offset = hdspm->channel_map_in[info->channel] * info->offset = hdspm->channel_map_in[channel] *
HDSPM_CHANNEL_BUFFER_BYTES; HDSPM_CHANNEL_BUFFER_BYTES;
} }

View file

@ -26,6 +26,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/nospec.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
@ -2036,9 +2037,10 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS)) if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
return -EINVAL; return -EINVAL;
if ((chn = rme9652->channel_map[info->channel]) < 0) { chn = rme9652->channel_map[array_index_nospec(info->channel,
RME9652_NCHANNELS)];
if (chn < 0)
return -EINVAL; return -EINVAL;
}
info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES; info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
info->first = 0; info->first = 0;

View file

@ -143,6 +143,13 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8; psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
/* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
if (ratio <= 256) {
pm = ratio;
fp = 1;
goto out;
}
/* Set the max fluctuation -- 0.1% of the max devisor */ /* Set the max fluctuation -- 0.1% of the max devisor */
savesub = (psr ? 1 : 8) * 256 * maxfp / 1000; savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;

View file

@ -351,8 +351,11 @@ static struct usbmix_name_map bose_companion5_map[] = {
/* /*
* Dell usb dock with ALC4020 codec had a firmware problem where it got * Dell usb dock with ALC4020 codec had a firmware problem where it got
* screwed up when zero volume is passed; just skip it as a workaround * screwed up when zero volume is passed; just skip it as a workaround
*
* Also the extension unit gives an access error, so skip it as well.
*/ */
static const struct usbmix_name_map dell_alc4020_map[] = { static const struct usbmix_name_map dell_alc4020_map[] = {
{ 4, NULL }, /* extension unit */
{ 16, NULL }, { 16, NULL },
{ 19, NULL }, { 19, NULL },
{ 0 } { 0 }