Skip to contentSkip to conversation

3.4.87-stable review

PATCH In review Greg Kroah-Hartman 4 participants 141 messages Apr 10, 2014 – Apr 12, 2014

Subsystems (2)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 3.4.87-stable review

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.87-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 3.4.87-rc1

Mikulas Patocka <[email protected]>
powernow-k6: reorder frequencies

Mikulas Patocka <[email protected]>
powernow-k6: correctly initialize default parameters

Mikulas Patocka <[email protected]>
powernow-k6: disable cache when changing frequency

Wei Yongjun <[email protected]>
media: saa7164: fix return value check in saa7164_initdev()

Alexey Khoroshilov <[email protected]>
media: hdpvr: fix iteration over uninitialized lists in hdpvr_probe()

Hans Verkuil <[email protected]>
media: hdpvr: register the video node at the end of probe

Soeren Moch <[email protected]>
media: dmxdev: remove dvb_ringbuffer_flush() on writer side

Al Viro <[email protected]>

    media: omap_vout: find_vma() needs ->mmap_sem held

Laurent Pinchart <[email protected]>
media: v4l: Reset subdev v4l2_dev field to NULL if registration fails

Jacob Schloss <[email protected]>
media: gspca_kinect: add Kinect for Windows USB id

Nithin Sujir <[email protected]>
tg3: Add read dma workaround for 5720

Nithin Sujir <[email protected]>
tg3: Skip powering down function 0 on certain serdes devices

Mauro Carvalho Chehab <[email protected]>
sb_edac: Avoid overflow errors at memory size calculation

Lauri Hintsala <[email protected]>
mmc: mxs-mmc: fix deadlock caused by recursion loop

Grazvydas Ignotas <[email protected]>
OMAPFB: fix framebuffer console colors

Nithin Sujir <[email protected]>
tg3: Wait for boot code to finish after power on

Michael Chan <[email protected]>
tg3: Add New 5719 Read DMA workaround

Dan Carpenter <[email protected]>
hwmon: Prevent some divide by zeros in FAN_TO_REG()

Henrik Rydberg <[email protected]>
hwmon: (applesmc) Always read until end of data

Guenter Roeck <[email protected]>

    hwmon: (coretemp) Add support for Atom CE4110/4150/4170

Guenter Roeck <[email protected]>
hwmon: (coretemp) Improve support for TjMax detection on Atom CPUs

Guenter Roeck <[email protected]>
hwmon: (coretemp) Add support for Atom D2000 and N2000 series CPU models

Jean Delvare <[email protected]>
hwmon: (coretemp) Improve support of recent Atom CPU models

Kailang Yang <[email protected]>
ALSA: hda/realtek - Add support of ALC231 codec

Takashi Iwai <[email protected]>
ALSA: pcsp: Fix the order of input device unregistration

Anssi Hannula <[email protected]>
ALSA: hda - hdmi: Fallback to ALSA allocation when selecting CA

Torsten Schenk <[email protected]>
ALSA: 6fire: make buffers DMA-able (midi)

Torsten Schenk <[email protected]>
ALSA: 6fire: make buffers DMA-able (pcm)

Jussi Kivilinna <[email protected]>
ALSA: 6fire: fix DMA issues with URB transfer_buffer usage

Dan Carpenter <[email protected]>
ALSA: ak4xx-adda: info leak in ak4xxx_capture_source_info()

Torstein Hegge <[email protected]>
ALSA: usb: Parse UAC2 extension unit like for UAC1

Eldad Zack <[email protected]>
ALSA: usb-audio: skip UAC2 EFFECT_UNIT

Aaron Plattner <[email protected]>
ALSA: hda - Add another GPU codec ID to snd-hda

Aaron Plattner <[email protected]>
ALSA: hda - Add new GPU codec ID to snd-hda

Takashi Iwai <[email protected]>
ALSA: hda - Cache the MUX selection for generic HDMI

Takashi Iwai <[email protected]>
xhci: Limit the spurious wakeup fix only to HP machines

Takashi Iwai <[email protected]>
xhci: Fix spurious wakeups after S5 on Haswell

Oliver Neukum <[email protected]>
xhci: quirk for extra long delay for S4

Julius Werner <[email protected]>
usb: hub: Clear Port Reset Change during init/resume

James Ralston <[email protected]>
ahci: Add Device IDs for Intel Wildcat Point-LP

Sarah Sharp <[email protected]>
xhci: Don't enable/disable RWE on bus suspend/resume.

Seth Heasley <[email protected]>
ahci: AHCI-mode SATA patch for Intel Coleto Creek DeviceIDs

James Ralston <[email protected]>
ahci: Add Device IDs for Intel Wellsburg PCH

Colin Leitner <[email protected]>
USB: ftdi_sio: fixed handling of unsupported CSIZE setting

Thomas Pugliese <[email protected]>
usb: wusbcore: change WA_SEGS_MAX to a legal value

Thomas Pugliese <[email protected]>
usb: wusbcore: set the RPIPE wMaxPacketSize value correctly

David Cohen <[email protected]>
usb: dwc3: add support for Merrifield

Heikki Krogerus <[email protected]>
usb: dwc3: pci: add support for BayTrail

Sarah Sharp <[email protected]>
usb: Disable USB 2.0 Link PM before device reset.

Alan Stern <[email protected]>
USB: fix PM config symbol in uhci-hcd, ehci-hcd, and xhci-hcd

Alan Stern <[email protected]>
USB: fix build error when CONFIG_PM_SLEEP isn't enabled

Alan Stern <[email protected]>
USB: OHCI: Allow runtime PM without system sleep

Johan Hovold <[email protected]>
USB: keyspan: fix null-deref at disconnect and release

Johan Hovold <[email protected]>

    USB: ti_usb_3410_5052: fix big-endian firmware handling

Johan Hovold <[email protected]>
USB: adutux: fix big-endian device-type reporting

Johan Hovold <[email protected]>
USB: mos7840: fix race in register handling

Johan Hovold <[email protected]>
USB: mos7840: fix memory leak in open

Johan Hovold <[email protected]>
USB: pl2303: fix device initialisation at open

Johan Hovold <[email protected]>
USB: spcp8x5: fix device initialisation at open

Richard Weinberger <[email protected]>
USB: serial: Add Option GTM681W to qcserial device table.

George Cherian <[email protected]>
usb: dwc3: gadget: free trb pool only from epnum 2

Adrian Thomasset <[email protected]>
USB: ftdi_sio: enable two UART ports on ST Microconnect Lite

Ming Lei <[email protected]>
USB: serial: fix hang when opening port

Johan Hovold <[email protected]>

    USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: ssu100: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: spcp8x5: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: pl2303: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: oti6858: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: mos7840: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: mos7840: fix broken TIOCMIWAIT

Johan Hovold <[email protected]>
USB: mct_u232: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: io_ti: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: io_edgeport: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: ftdi_sio: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: cypress_m8: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: ch341: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: ark3116: fix use-after-free in TIOCMIWAIT

Johan Hovold <[email protected]>
USB: serial: add modem-status-change wait queue

David Henningsson <[email protected]>
ALSA: hda - Fix internal mic for Lenovo Ideapad U300s

Takashi Iwai <[email protected]>
ALSA: hda - Always turn on pins for HDMI/DP

David Henningsson <[email protected]>
Revert "ALSA: hda - Shut up pins at power-saving mode with Conexnat codecs"

Takashi Iwai <[email protected]>
ALSA: hda - Add Conexant CX20751/2/3/4 codec support

Takashi Iwai <[email protected]>
ALSA: hda - Fix non-snoop page handling

Takashi Iwai <[email protected]>
ALSA: aloop: Fix Oops while PM resume

Calvin Owens <[email protected]>
ALSA: usb: Add quirk for 192KHz recording on E-Mu devices

Laurent Pinchart <[email protected]>
usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams

Laurent Pinchart <[email protected]>
usb: Add quirk detection based on interface information

Andreas Fleig <[email protected]>
USB: Add device quirk for Microsoft VX700 webcam

Alan Stern <[email protected]>

    USB: EHCI: bugfix: urb->hcpriv should not be NULL

Rajkumar Manoharan <[email protected]>
ath9k_hw: Enable hw PLL power save for AR9462

Sujith Manoharan <[email protected]>
ath9k_hw: Fix RX gain initvals for AR9485

Felix Fietkau <[email protected]>
ath9k_hw: fix chain swap setting when setting rx chainmask to 5

Felix Fietkau <[email protected]>
ath9k_htc: fix signal strength handling issues

Sujith Manoharan <[email protected]>
ath9k_hw: Assign default xlna config for AR9485

Rajkumar Manoharan <[email protected]>
ath9k: fill channel mode in caldata

Sujith Manoharan <[email protected]>
ath9k: Fix noisefloor calibration

Will Deacon <[email protected]>
ARM: 7791/1: a.out: remove partial a.out support

Nicolas Pitre <[email protected]>
ARM: 7628/1: head.S: map one extra section for the ATAG/DTB area

Arnaud Patard <[email protected]>
ARM: Orion: Set eth packet size csum offload limit

Sergei Ianovich <[email protected]>
ARM: pxa: prevent PXA270 occasional reboot freezes

Russell King <[email protected]>
ARM: footbridge: fix VGA initialisation

Arnd Bergmann <[email protected]>
ARM: 7743/1: compressed/head.S: work around new binutils warning

Arnd Bergmann <[email protected]>
ARM: 7742/1: topology: export cpu_topology

Linus Walleij <[email protected]>
ARM: u300: fix ages old copy/paste bug

Arnd Bergmann <[email protected]>

    ARM: w90x900: fix legacy assembly syntax

Shawn Guo <[email protected]>
ARM: dts: imx51-babbage: fix esdhc cd/wp properties

Manoj Chourasia <[email protected]>
HID: hidraw: correctly deallocate memory on device disconnect

Jiri Kosina <[email protected]>
HID: usbhid: fix build problem

Josh Boyer <[email protected]>
HID: usbhid: quirk for MSI GX680R led panel

Fernando Luis Vazquez Cao <[email protected]>
HID: clean up quirk for Sony RF receivers

Fernando Luis Vazquez Cao <[email protected]>

    HID: add support for Sony RF receiver with USB product id 0x0374

Alexey Kaminsky <[email protected]>
HID: apple: Add Apple wireless keyboard 2011 ANSI PID

Alexey Khoroshilov <[email protected]>
HID: hidraw: improve error handling in hidraw_init()

Matthieu CASTET <[email protected]>

    HID: hidraw: fix list->buffer memleak

Jiri Kosina <[email protected]>
HID: fix return value of hidraw_report_event() when !CONFIG_HIDRAW

Jiri Kosina <[email protected]>
HID: hidraw: add proper error handling to raw event reporting

Benjamin Tissoires <[email protected]>
HID: multitouch: validate indexes details

Benjamin Tissoires <[email protected]>
HID: validate feature and input report details

Nicholas Santos <[email protected]>
HID: usbhid: quirk for Formosa IR receiver

Marek Vasut <[email protected]>
HID: add quirk for Freescale i.MX28 ROM recovery

Konrad Rzeszutek Wilk <[email protected]>
intel_idle: Check cpu_idle_get_driver() for NULL before dereferencing it.

Paul Moore <[email protected]>
selinux: correctly label /proc inodes in use before the policy is loaded

George Spelvin <[email protected]>
pps: Fix a use-after free bug when unregistering a source.

George Spelvin <[email protected]>
pps: Use pps_lookup_dev to reduce ldisc coupling

George Spelvin <[email protected]>
pps: Add pps_lookup_dev() function

Philipp Reisner <[email protected]>
idr: idr_for_each_entry() macro

Mathias Krause <[email protected]>
ipc, msg: fix message length check for negative values

Ingo Molnar <[email protected]>
compiler/gcc4: Add quirk for 'asm goto' miscompilation bug

Daniel Santos <[email protected]>
compiler-gcc.h: Add gcc-recommended GCC_VERSION macro

Tejun Heo <[email protected]>
workqueue: cond_resched() after processing each work item

Bu, Yitian <[email protected]>

    printk: Fix rq->lock vs logbuf_lock unlock lock inversion

Oleg Nesterov <[email protected]>
audit: wait_for_auditd() should use TASK_UNINTERRUPTIBLE

Tejun Heo <[email protected]>
idr: fix top layer handling

Artem Bityutskiy <[email protected]>
proc: pid/status: show all supplementary groups

-------------

Diffstat:

 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   8 +-
 Documentation/hwmon/coretemp                       |  12 +-
 Makefile                                           |   4 +-
 arch/arm/Kconfig                                   |   1 -
 arch/arm/boot/compressed/Makefile                  |   1 -
 arch/arm/boot/compressed/head-sa1100.S             |   1 +
 arch/arm/boot/compressed/head-shark.S              |   1 +
 arch/arm/boot/compressed/head.S                    |   1 +
 arch/arm/boot/dts/imx51-babbage.dts                |   4 +-
 arch/arm/include/asm/a.out-core.h                  |  45 ------
 arch/arm/include/asm/a.out.h                       |  34 -----
 arch/arm/include/asm/processor.h                   |   4 -
 arch/arm/kernel/head.S                             |   3 +
 arch/arm/kernel/topology.c                         |   2 +
 arch/arm/mach-dove/common.c                        |   2 +-
 arch/arm/mach-footbridge/common.c                  |   3 +
 arch/arm/mach-footbridge/dc21285.c                 |   2 -
 arch/arm/mach-kirkwood/common.c                    |   4 +-
 arch/arm/mach-mv78xx0/common.c                     |   6 +-
 arch/arm/mach-orion5x/common.c                     |   3 +-
 arch/arm/mach-pxa/reset.c                          |   8 +-
 arch/arm/mach-u300/include/mach/u300-regs.h        |   2 +-
 arch/arm/mach-w90x900/include/mach/entry-macro.S   |   4 +-
 arch/arm/plat-orion/common.c                       |   8 +-
 arch/arm/plat-orion/include/plat/common.h          |   6 +-
 arch/mips/include/asm/jump_label.h                 |   2 +-
 arch/powerpc/include/asm/jump_label.h              |   2 +-
 arch/s390/include/asm/jump_label.h                 |   2 +-
 arch/sparc/include/asm/jump_label.h                |   2 +-
 arch/x86/include/asm/cpufeature.h                  |   2 +-
 arch/x86/include/asm/jump_label.h                  |   2 +-
 drivers/ata/ahci.c                                 |  13 ++
 drivers/cpufreq/powernow-k6.c                      | 147 ++++++++++++++++----
 drivers/edac/sb_edac.c                             |   7 +-
 drivers/hid/hid-apple.c                            |   3 +
 drivers/hid/hid-core.c                             |  26 ++--
 drivers/hid/hid-ids.h                              |  10 ++
 drivers/hid/hid-input.c                            |  12 +-
 drivers/hid/hid-multitouch.c                       |   4 +-
 drivers/hid/hid-sony.c                             |  18 ++-
 drivers/hid/hidraw.c                               |  98 +++++++------
 drivers/hid/usbhid/hid-quirks.c                    |   3 +
 drivers/hwmon/applesmc.c                           |  13 ++
 drivers/hwmon/coretemp.c                           |  34 ++++-
 drivers/hwmon/lm78.c                               |   2 +
 drivers/hwmon/sis5595.c                            |   2 +
 drivers/hwmon/vt8231.c                             |   2 +-
 drivers/idle/intel_idle.c                          |   3 +-
 drivers/media/dvb/dvb-core/dmxdev.c                |   8 +-
 drivers/media/video/gspca/kinect.c                 |   1 +
 drivers/media/video/hdpvr/hdpvr-core.c             |  22 +--
 drivers/media/video/omap/omap_vout.c               |  12 +-
 drivers/media/video/saa7164/saa7164-core.c         |   4 +-
 drivers/media/video/v4l2-device.c                  |  30 ++--
 drivers/mmc/host/mxs-mmc.c                         |   8 +-
 drivers/net/ethernet/broadcom/tg3.c                |  74 +++++++++-
 drivers/net/ethernet/broadcom/tg3.h                |   8 +-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c     |   8 +-
 drivers/net/wireless/ath/ath9k/ar9003_hw.c         |  15 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.c        |  27 +---
 drivers/net/wireless/ath/ath9k/ar9003_phy.h        |   2 +
 drivers/net/wireless/ath/ath9k/calib.c             |   1 +
 drivers/net/wireless/ath/ath9k/htc.h               |   1 +
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c      |  18 ++-
 drivers/net/wireless/ath/ath9k/hw.c                |   3 +-
 drivers/net/wireless/ath/ath9k/hw.h                |   1 +
 drivers/net/wireless/ath/ath9k/main.c              |   7 -
 drivers/pps/clients/pps-ldisc.c                    |  10 +-
 drivers/pps/pps.c                                  |  47 ++++++-
 drivers/usb/core/driver.c                          |  38 ++++--
 drivers/usb/core/hub.c                             |  21 ++-
 drivers/usb/core/quirks.c                          | 152 ++++++++++++---------
 drivers/usb/core/usb.h                             |   4 +
 drivers/usb/dwc3/dwc3-pci.c                        |   4 +
 drivers/usb/dwc3/gadget.c                          |  15 +-
 drivers/usb/host/ehci-pci.c                        |   2 +-
 drivers/usb/host/ehci-q.c                          |  16 +--
 drivers/usb/host/ehci-sched.c                      |   4 +-
 drivers/usb/host/ohci-pci.c                        |   2 +-
 drivers/usb/host/uhci-pci.c                        |   2 +-
 drivers/usb/host/xhci-hub.c                        |  28 ----
 drivers/usb/host/xhci-pci.c                        |  32 ++++-
 drivers/usb/host/xhci.c                            |  14 +-
 drivers/usb/host/xhci.h                            |   2 +
 drivers/usb/misc/adutux.c                          |   2 +-
 drivers/usb/serial/ark3116.c                       |  10 +-
 drivers/usb/serial/ch341.c                         |  11 +-
 drivers/usb/serial/cypress_m8.c                    |  14 +-
 drivers/usb/serial/ftdi_sio.c                      |  68 +++++----
 drivers/usb/serial/io_edgeport.c                   |  12 +-
 drivers/usb/serial/io_ti.c                         |  12 +-
 drivers/usb/serial/keyspan.c                       |   2 +-
 drivers/usb/serial/mct_u232.c                      |  13 +-
 drivers/usb/serial/mos7840.c                       |  60 +++++---
 drivers/usb/serial/oti6858.c                       |  10 +-
 drivers/usb/serial/pl2303.c                        |  21 +--
 drivers/usb/serial/qcserial.c                      |   1 +
 drivers/usb/serial/spcp8x5.c                       |  19 ++-
 drivers/usb/serial/ssu100.c                        |  12 +-
 drivers/usb/serial/ti_usb_3410_5052.c              |  19 +--
 drivers/usb/serial/usb-serial.c                    |   1 +
 drivers/usb/wusbcore/wa-rpipe.c                    |   5 +-
 drivers/usb/wusbcore/wa-xfer.c                     |   5 +-
 drivers/video/omap2/omapfb/omapfb-main.c           |   2 +-
 fs/proc/array.c                                    |   2 +-
 include/linux/compiler-gcc.h                       |   3 +
 include/linux/compiler-gcc4.h                      |  16 +++
 include/linux/hid.h                                |   2 +-
 include/linux/hidraw.h                             |   4 +-
 include/linux/idr.h                                |  11 ++
 include/linux/msg.h                                |   6 +-
 include/linux/mv643xx_eth.h                        |   2 +
 include/linux/pps_kernel.h                         |  17 ++-
 include/linux/usb/hcd.h                            |   2 +-
 include/linux/usb/serial.h                         |   2 +
 ipc/msgutil.c                                      |  12 +-
 ipc/util.h                                         |   4 +-
 kernel/audit.c                                     |   2 +-
 kernel/printk.c                                    |   2 +-
 kernel/workqueue.c                                 |   9 ++
 lib/idr.c                                          |  36 +++--
 security/selinux/hooks.c                           |  36 +++--
 sound/drivers/aloop.c                              |   5 +-
 sound/drivers/pcsp/pcsp.c                          |   2 +-
 sound/i2c/other/ak4xxx-adda.c                      |   2 +-
 sound/pci/hda/hda_intel.c                          |  40 ++++--
 sound/pci/hda/patch_conexant.c                     | 114 +++++++++++-----
 sound/pci/hda/patch_hdmi.c                         |  35 +++--
 sound/pci/hda/patch_realtek.c                      |   1 +
 sound/usb/6fire/comm.c                             |  38 +++++-
 sound/usb/6fire/comm.h                             |   2 +-
 sound/usb/6fire/midi.c                             |  16 ++-
 sound/usb/6fire/midi.h                             |   6 +-
 sound/usb/6fire/pcm.c                              |  41 +++++-
 sound/usb/6fire/pcm.h                              |   2 +-
 sound/usb/card.h                                   |   1 +
 sound/usb/endpoint.c                               |   3 +-
 sound/usb/mixer.c                                  |  16 ++-
 sound/usb/quirks.c                                 |   1 +
 139 files changed, 1334 insertions(+), 679 deletions(-)
author maintainer
#1 lore raw

PATCH 1/134 proc: pid/status: show all supplementary groups

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Artem Bityutskiy <[email protected]>

commit 8d238027b87e654be552eabdf492042a34c5c300 upstream.

We display a list of supplementary group for each process in /proc/<pid>/status. However, we show only the first 32 groups, not all of them.

Although this is rare, but sometimes processes do have more than 32 supplementary groups, and this kernel limitation breaks user-space apps that rely on the group list in /proc/<pid>/status.

Number 32 comes from the internal NGROUPS_SMALL macro which defines the length for the internal kernel "small" groups buffer. There is no apparent reason to limit to this value.

This patch removes the 32 groups printing limit.

The Linux kernel limits the amount of supplementary groups by NGROUPS_MAX, which is currently set to 65536. And this is the maximum count of groups we may possibly print.

---
 fs/proc/array.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/proc/array.c +1 -1
@@ -204,7 +204,7 @@ static inline void task_state(struct seq
 	group_info = cred->group_info;
 	task_unlock(p);
 
-	for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
+	for (g = 0; g < group_info->ngroups; g++)
 		seq_printf(m, "%d ", GROUP_AT(group_info, g));
 	put_cred(cred);
 
author maintainer
#2 lore raw

PATCH 2/134 idr: fix top layer handling

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tejun Heo <[email protected]>

commit 326cf0f0f308933c10236280a322031f0097205d upstream.

Most functions in idr fail to deal with the high bits when the idr tree grows to the maximum height.

* idr_get_empty_slot() stops growing idr tree once the depth reaches MAX_IDR_LEVEL - 1, which is one depth shallower than necessary to cover the whole range. The function doesn't even notice that it didn't grow the tree enough and ends up allocating the wrong ID given sufficiently high @starting_id.

For example, on 64 bit, if the starting id is 0x7fffff01, idr_get_empty_slot() will grow the tree 5 layer deep, which only covers the 30 bits and then proceed to allocate as if the bit 30 wasn't specified. It ends up allocating 0x3fffff01 without the bit 30 but still returns 0x7fffff01.

* __idr_remove_all() will not remove anything if the tree is fully grown.

* idr_find() can't find anything if the tree is fully grown.

* idr_for_each() and idr_get_next() can't iterate anything if the tree is fully grown.

Fix it by introducing idr_max() which returns the maximum possible ID given the depth of tree and replacing the id limit checks in all affected places.

As the idr_layer pointer array pa[] needs to be 1 larger than the maximum depth, enlarge pa[] arrays by one.

While this plugs the discovered issues, the whole code base is horrible and in desparate need of rewrite. It's fragile like hell,

[bwh: Backported to 3.2:
- Adjust context
- s/MAX_IDR_LEVEL/MAX_LEVEL/; s/MAX_IDR_SHIFT/MAX_ID_SHIFT/
- Drop change to idr_alloc()]

---
 lib/idr.c |   36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)
lib/idr.c +22 -14
@@ -39,6 +39,14 @@
 static struct kmem_cache *idr_layer_cache;
 static DEFINE_SPINLOCK(simple_ida_lock);
 
+/* the maximum ID which can be allocated given idr->layers */
+static int idr_max(int layers)
+{
+	int bits = min_t(int, layers * IDR_BITS, MAX_ID_SHIFT);
+
+	return (1 << bits) - 1;
+}
+
 static struct idr_layer *get_from_free_list(struct idr *idp)
 {
 	struct idr_layer *p;
@@ -223,7 +231,7 @@ build_up:
 	 * Add a new layer to the top of the tree if the requested
 	 * id is larger than the currently allocated space.
 	 */
-	while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
+	while (id > idr_max(layers)) {
 		layers++;
 		if (!p->count) {
 			/* special case: if the tree is currently empty,
@@ -265,7 +273,7 @@ build_up:
 
 static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
 {
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_LEVEL + 1];
 	int id;
 
 	id = idr_get_empty_slot(idp, starting_id, pa);
@@ -357,7 +365,7 @@ static void idr_remove_warning(int id)
 static void sub_remove(struct idr *idp, int shift, int id)
 {
 	struct idr_layer *p = idp->top;
-	struct idr_layer **pa[MAX_LEVEL];
+	struct idr_layer **pa[MAX_LEVEL + 1];
 	struct idr_layer ***paa = &pa[0];
 	struct idr_layer *to_free;
 	int n;
@@ -451,16 +459,16 @@ void idr_remove_all(struct idr *idp)
 	int n, id, max;
 	int bt_mask;
 	struct idr_layer *p;
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_LEVEL + 1];
 	struct idr_layer **paa = &pa[0];
 
 	n = idp->layers * IDR_BITS;
 	p = idp->top;
 	rcu_assign_pointer(idp->top, NULL);
-	max = 1 << n;
+	max = idr_max(idp->layers);
 
 	id = 0;
-	while (id < max) {
+	while (id >= 0 && id <= max) {
 		while (n > IDR_BITS && p) {
 			n -= IDR_BITS;
 			*paa++ = p;
@@ -519,7 +527,7 @@ void *idr_find(struct idr *idp, int id)
 	/* Mask off upper bits we don't use for the search. */
 	id &= MAX_ID_MASK;
 
-	if (id >= (1 << n))
+	if (id > idr_max(p->layer + 1))
 		return NULL;
 	BUG_ON(n == 0);
 
@@ -555,15 +563,15 @@ int idr_for_each(struct idr *idp,
 {
 	int n, id, max, error = 0;
 	struct idr_layer *p;
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_LEVEL + 1];
 	struct idr_layer **paa = &pa[0];
 
 	n = idp->layers * IDR_BITS;
 	p = rcu_dereference_raw(idp->top);
-	max = 1 << n;
+	max = idr_max(idp->layers);
 
 	id = 0;
-	while (id < max) {
+	while (id >= 0 && id <= max) {
 		while (n > 0 && p) {
 			n -= IDR_BITS;
 			*paa++ = p;
@@ -601,7 +609,7 @@ EXPORT_SYMBOL(idr_for_each);
  */
 void *idr_get_next(struct idr *idp, int *nextidp)
 {
-	struct idr_layer *p, *pa[MAX_LEVEL];
+	struct idr_layer *p, *pa[MAX_LEVEL + 1];
 	struct idr_layer **paa = &pa[0];
 	int id = *nextidp;
 	int n, max;
@@ -611,9 +619,9 @@ void *idr_get_next(struct idr *idp, int
 	if (!p)
 		return NULL;
 	n = (p->layer + 1) * IDR_BITS;
-	max = 1 << n;
+	max = idr_max(p->layer + 1);
 
-	while (id < max) {
+	while (id >= 0 && id <= max) {
 		while (n > 0 && p) {
 			n -= IDR_BITS;
 			*paa++ = p;
@@ -787,7 +795,7 @@ EXPORT_SYMBOL(ida_pre_get);
  */
 int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
 {
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_LEVEL + 1];
 	struct ida_bitmap *bitmap;
 	unsigned long flags;
 	int idr_id = starting_id / IDA_BITMAP_BITS;
author maintainer
#3 lore raw

PATCH 3/134 audit: wait_for_auditd() should use TASK_UNINTERRUPTIBLE

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

commit f000cfdde5de4fc15dead5ccf524359c07eadf2b upstream.

audit_log_start() does wait_for_auditd() in a loop until audit_backlog_wait_time passes or audit_skb_queue has a room.

If signal_pending() is true this becomes a busy-wait loop, schedule() in TASK_INTERRUPTIBLE won't block.

Thanks to Guy for fully investigating and explaining the problem.

(akpm: that'll cause the system to lock up on a non-preemptible uniprocessor kernel)

(Guy: "Our customer was in fact running a uniprocessor machine, and they reported a system hang.")

Cc Eric Paris <[email protected]>
Cc Al Viro <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Cc Qiang Huang <[email protected]>
Cc Li Zefan <[email protected]>
Cc Jianguo Wu <[email protected]>
---
 kernel/audit.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/audit.c +1 -1
@@ -1168,7 +1168,7 @@ struct audit_buffer *audit_log_start(str
 
 			/* Wait for auditd to drain the queue a little */
 			DECLARE_WAITQUEUE(wait, current);
-			set_current_state(TASK_INTERRUPTIBLE);
+			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&audit_backlog_wait, &wait);
 
 			if (audit_backlog_limit &&
author maintainer
#4 lore raw

PATCH 4/134 printk: Fix rq->lock vs logbuf_lock unlock lock inversion

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: "Bu, Yitian" <[email protected]>

commit dbda92d16f8655044e082930e4e9d244b87fde77 upstream.

commit 07354eb1a74d1 ("locking printk: Annotate logbuf_lock as raw") reintroduced a lock inversion problem which was fixed in commit 0b5e1c5255 ("printk: Release console_sem after logbuf_lock"). This happened probably when fixing up patch rejects.

Restore the ordering and unlock logbuf_lock before releasing console_sem.

---
 kernel/printk.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/printk.c +1 -1
@@ -822,9 +822,9 @@ static int console_trylock_for_printk(un
 		}
 	}
 	printk_cpu = UINT_MAX;
+	raw_spin_unlock(&logbuf_lock);
 	if (wake)
 		up(&console_sem);
-	raw_spin_unlock(&logbuf_lock);
 	return retval;
 }
 static const char recursion_bug_msg [] =
author maintainer
#5 lore raw

PATCH 5/134 workqueue: cond_resched() after processing each work item

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tejun Heo <[email protected]>

commit b22ce2785d97423846206cceec4efee0c4afd980 upstream.

If !PREEMPT, a kworker running work items back to back can hog CPU. This becomes dangerous when a self-requeueing work item which is waiting for something to happen races against stop_machine. Such self-requeueing work item would requeue itself indefinitely hogging the kworker and CPU it's running on while stop_machine would wait for that CPU to enter stop_machine while preventing anything else from happening on all other CPUs. The two would deadlock.

Jamie Liu reports that this deadlock scenario exists around scsi_requeue_run_queue() and libata port multiplier support, where one port may exclude command processing from other ports. With the right timing, scsi_requeue_run_queue() can end up requeueing itself trying to execute an IO which is asked to be retried while another device has an exclusive access, which in turn can't make forward progress due to stop_machine.

Fix it by invoking cond_resched() after executing each work item.

References: http://thread.gmane.org/gmane.linux.kernel/1552567

[bwh: Backported to 3.2: adjust context]
Cc Qiang Huang <[email protected]>
Cc Li Zefan <[email protected]>
Cc Jianguo Wu <[email protected]>
---
 kernel/workqueue.c |    9 +++++++++
 1 file changed, 9 insertions(+)
kernel/workqueue.c +9 -0
@@ -1922,6 +1922,15 @@ __acquires(&gcwq->lock)
 		dump_stack();
 	}
 
+	/*
+	 * The following prevents a kworker from hogging CPU on !PREEMPT
+	 * kernels, where a requeueing work item waiting for something to
+	 * happen could deadlock with stop_machine as such work item could
+	 * indefinitely requeue itself while all other CPUs are trapped in
+	 * stop_machine.
+	 */
+	cond_resched();
+
 	spin_lock_irq(&gcwq->lock);
 
 	/* clear cpu intensive status */
author maintainer
#6 lore raw

PATCH 6/134 compiler-gcc.h: Add gcc-recommended GCC_VERSION macro

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Santos <[email protected]>

commit 3f3f8d2f48acfd8ed3b8e6b7377935da57b27b16 upstream.

Throughout compiler*.h, many version checks are made. These can be simplified by using the macro that gcc's documentation recommends. However, my primary reason for adding this is that I need bug-check macros that are enabled at certain gcc versions and it's cleaner to use this macro than the tradition method:

  #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ => 2)

If you add patch level, it gets this ugly:

  #if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 2 || \
      __GNUC_MINOR__ == 2 __GNUC_PATCHLEVEL__ >= 1))

As opposed to:

  #if GCC_VERSION >= 40201

While having separate headers for gcc 3 & 4 eliminates some of this verbosity, they can still be cleaned up by this.

See also:

http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

---
 include/linux/compiler-gcc.h |    3 +++
 1 file changed, 3 insertions(+)
include/linux/compiler-gcc.h +3 -0
@@ -5,6 +5,9 @@
 /*
  * Common definitions for all gcc versions go here.
  */
+#define GCC_VERSION (__GNUC__ * 10000 \
+		   + __GNUC_MINOR__ * 100 \
+		   + __GNUC_PATCHLEVEL__)
 
 
 /* Optimization barrier */
author maintainer
#7 lore raw

PATCH 7/134 compiler/gcc4: Add quirk for asm goto miscompilation bug

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ingo Molnar <[email protected]>

commit 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 upstream.

Fengguang Wu, Oleg Nesterov and Peter Zijlstra tracked down a kernel crash to a GCC bug: GCC miscompiles certain 'asm goto' constructs, as outlined here:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670

Implement a workaround suggested by Jakub Jelinek.

---
 arch/mips/include/asm/jump_label.h    |    2 +-
 arch/powerpc/include/asm/jump_label.h |    2 +-
 arch/s390/include/asm/jump_label.h    |    2 +-
 arch/sparc/include/asm/jump_label.h   |    2 +-
 arch/x86/include/asm/cpufeature.h     |    2 +-
 arch/x86/include/asm/jump_label.h     |    2 +-
 include/linux/compiler-gcc4.h         |   16 ++++++++++++++++
 7 files changed, 22 insertions(+), 6 deletions(-)
arch/mips/include/asm/jump_label.h +1 -1
@@ -22,7 +22,7 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key)
 {
-	asm goto("1:\tnop\n\t"
+	asm_volatile_goto("1:\tnop\n\t"
 		"nop\n\t"
 		".pushsection __jump_table,  \"aw\"\n\t"
 		WORD_INSN " 1b, %l[l_yes], %0\n\t"
arch/powerpc/include/asm/jump_label.h +1 -1
@@ -19,7 +19,7 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key)
 {
-	asm goto("1:\n\t"
+	asm_volatile_goto("1:\n\t"
 		 "nop\n\t"
 		 ".pushsection __jump_table,  \"aw\"\n\t"
 		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
arch/s390/include/asm/jump_label.h +1 -1
@@ -15,7 +15,7 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key)
 {
-	asm goto("0:	brcl 0,0\n"
+	asm_volatile_goto("0:	brcl 0,0\n"
 		".pushsection __jump_table, \"aw\"\n"
 		ASM_ALIGN "\n"
 		ASM_PTR " 0b, %l[label], %0\n"
arch/sparc/include/asm/jump_label.h +1 -1
@@ -9,7 +9,7 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key)
 {
-		asm goto("1:\n\t"
+		asm_volatile_goto("1:\n\t"
 			 "nop\n\t"
 			 "nop\n\t"
 			 ".pushsection __jump_table,  \"aw\"\n\t"
arch/x86/include/asm/cpufeature.h +1 -1
@@ -342,7 +342,7 @@ extern const char * const x86_power_flag
 static __always_inline __pure bool __static_cpu_has(u16 bit)
 {
 #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5
-		asm goto("1: jmp %l[t_no]\n"
+		asm_volatile_goto("1: jmp %l[t_no]\n"
 			 "2:\n"
 			 ".section .altinstructions,\"a\"\n"
 			 " .long 1b - .\n"
arch/x86/include/asm/jump_label.h +1 -1
@@ -13,7 +13,7 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key)
 {
-	asm goto("1:"
+	asm_volatile_goto("1:"
 		STATIC_KEY_INITIAL_NOP
 		".pushsection __jump_table,  \"aw\" \n\t"
 		_ASM_ALIGN "\n\t"
include/linux/compiler-gcc4.h +16 -0
@@ -31,6 +31,22 @@
 
 #define __linktime_error(message) __attribute__((__error__(message)))
 
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ * Fixed in GCC 4.8.2 and later versions.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#if GCC_VERSION <= 40801
+# define asm_volatile_goto(x...)	do { asm goto(x); asm (""); } while (0)
+#else
+# define asm_volatile_goto(x...)	do { asm goto(x); } while (0)
+#endif
+
 #if __GNUC_MINOR__ >= 5
 /*
  * Mark a position in code as unreachable.  This can be used to
author maintainer
#8 lore raw

PATCH 8/134 ipc, msg: fix message length check for negative values

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

commit 4e9b45a19241354daec281d7a785739829b52359 upstream.

On 64 bit systems the test for negative message sizes is bogus as the size, which may be positive when evaluated as a long, will get truncated to an int when passed to load_msg(). So a long might very well contain a positive value but when truncated to an int it would become negative.

That in combination with a small negative value of msg_ctlmax (which will be promoted to an unsigned type for the comparison against msgsz, making it a big positive value and therefore make it pass the check) will lead to two problems: 1/ The kmalloc() call in alloc_msg() will allocate a too small buffer as the addition of alen is effectively a subtraction. 2/ The copy_from_user() call in load_msg() will first overflow the buffer with userland data and then, when the userland access generates an access violation, the fixup handler copy_user_handle_tail() will try to fill the remainder with zeros -- roughly 4GB. That almost instantly results in a system crash or reset.

  ,-[ Reproducer (needs to be run as root) ]--
  | #include <sys/stat.h>
  | #include <sys/msg.h>
  | #include <unistd.h>
  | #include <fcntl.h>
  |
  | int main(void) {
  |     long msg = 1;
  |     int fd;
  |
  |     fd = open("/proc/sys/kernel/msgmax", O_WRONLY);
  |     write(fd, "-1", 2);
  |     close(fd);
  |
  |     msgsnd(0, &msg, 0xfffffff0, IPC_NOWAIT);
  |
  |     return 0;
  | }
  '---

Fix the issue by preventing msgsz from getting truncated by consistently using size_t for the message length. This way the size checks in do_msgsnd() could still be passed with a negative value for msg_ctlmax but we would fail on the buffer allocation in that case and error out.

Also change the type of m_ts from int to size_t to avoid similar nastiness in other code paths -- it is used in similar constructs, i.e. signed vs. unsigned checks. It should never become negative under normal circumstances, though.

Setting msg_ctlmax to a negative value is an odd configuration and should be prevented. As that might break existing userland, it will be handled in a separate commit so it could easily be reverted and reworked without reintroducing the above described bug.

Hardening mechanisms for user copy operations would have catched that bug early -- e.g. checking slab object sizes on user copy operations as the usercopy feature of the PaX patch does. Or, for that matter, detect the long vs. int sign change due to truncation, as the size overflow plugin of the very same patch does.

[[email protected]: fix i386 min() warnings]
Cc Pax Team <[email protected]>
Cc Davidlohr Bueso <[email protected]>
Cc Brad Spengler <[email protected]>
Cc Manfred Spraul <[email protected]>

[bwh: Backported to 3.2:
- Adjust context
- Drop changes to alloc_msg() and copy_msg(), which don't exist]

---
 include/linux/msg.h |    6 +++---
 ipc/msgutil.c       |   12 ++++++------
 ipc/util.h          |    4 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)
include/linux/msg.h +3 -3
@@ -76,9 +76,9 @@ struct msginfo {
 
 /* one msg_msg structure for each message */
 struct msg_msg {
-	struct list_head m_list; 
-	long  m_type;          
-	int m_ts;           /* message text size */
+	struct list_head m_list;
+	long m_type;
+	size_t m_ts;		/* message text size */
 	struct msg_msgseg* next;
 	void *security;
 	/* the actual message follows immediately */
ipc/msgutil.c +6 -6
@@ -39,15 +39,15 @@ struct msg_msgseg {
 	/* the next part of the message follows immediately */
 };
 
-#define DATALEN_MSG	(PAGE_SIZE-sizeof(struct msg_msg))
-#define DATALEN_SEG	(PAGE_SIZE-sizeof(struct msg_msgseg))
+#define DATALEN_MSG	((size_t)PAGE_SIZE-sizeof(struct msg_msg))
+#define DATALEN_SEG	((size_t)PAGE_SIZE-sizeof(struct msg_msgseg))
 
-struct msg_msg *load_msg(const void __user *src, int len)
+struct msg_msg *load_msg(const void __user *src, size_t len)
 {
 	struct msg_msg *msg;
 	struct msg_msgseg **pseg;
 	int err;
-	int alen;
+	size_t alen;
 
 	alen = len;
 	if (alen > DATALEN_MSG)
@@ -101,9 +101,9 @@ out_err:
 	return ERR_PTR(err);
 }
 
-int store_msg(void __user *dest, struct msg_msg *msg, int len)
+int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
 {
-	int alen;
+	size_t alen;
 	struct msg_msgseg *seg;
 
 	alen = len;
ipc/util.h +2 -2
@@ -138,8 +138,8 @@ int ipc_parse_version (int *cmd);
 #endif
 
 extern void free_msg(struct msg_msg *msg);
-extern struct msg_msg *load_msg(const void __user *src, int len);
-extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
+extern struct msg_msg *load_msg(const void __user *src, size_t len);
+extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len);
 
 extern void recompute_msgmni(struct ipc_namespace *);
 
author maintainer
#9 lore raw

PATCH 9/134 idr: idr_for_each_entry() macro

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Philipp Reisner <[email protected]>

commit 9749f30f1a387070e6e8351f35aeb829eacc3ab6 upstream.

Inspired by the list_for_each_entry() macro

---
 include/linux/idr.h |   11 +++++++++++
 1 file changed, 11 insertions(+)
include/linux/idr.h +11 -0
@@ -152,4 +152,15 @@ void ida_simple_remove(struct ida *ida,
 
 void __init idr_init_cache(void);
 
+/**
+ * idr_for_each_entry - iterate over an idr's elements of a given type
+ * @idp:     idr handle
+ * @entry:   the type * to use as cursor
+ * @id:      id entry's key
+ */
+#define idr_for_each_entry(idp, entry, id)				\
+	for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \
+	     entry != NULL;                                             \
+	     ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
+
 #endif /* __IDR_H__ */
author maintainer
#10 lore raw

PATCH 10/134 pps: Add pps_lookup_dev() function

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: George Spelvin <[email protected]>

commit 513b032c98b4b9414aa4e9b4a315cb1bf0380101 upstream.

The PPS serial line discipline wants to attach a PPS device to a tty without changing the tty code to add a struct pps_device * pointer.

Since the number of PPS devices in a typical system is generally very low (n=1 is by far the most common), it's practical to search the entire list of allocated pps devices. (We capture the timestamp before the lookup, so the timing isn't affected.)

It is a bit ugly that this function, which is part of the in-kernel PPS API, has to be in pps.c as opposed to kapi,c, but that's not something that affects users.

---
 drivers/pps/pps.c          |   33 +++++++++++++++++++++++++++++++++
 include/linux/pps_kernel.h |   17 ++++++++++++++---
 2 files changed, 47 insertions(+), 3 deletions(-)
drivers/pps/pps.c +33 -0
@@ -350,11 +350,44 @@ free_idr:
 
 void pps_unregister_cdev(struct pps_device *pps)
 {
+	pps->lookup_cookie = NULL;
 	device_destroy(pps_class, pps->dev->devt);
 	cdev_del(&pps->cdev);
 }
 
 /*
+ * Look up a pps device by magic cookie.
+ * The cookie is usually a pointer to some enclosing device, but this
+ * code doesn't care; you should never be dereferencing it.
+ *
+ * This is a bit of a kludge that is currently used only by the PPS
+ * serial line discipline.  It may need to be tweaked when a second user
+ * is found.
+ *
+ * There is no function interface for setting the lookup_cookie field.
+ * It's initialized to NULL when the pps device is created, and if a
+ * client wants to use it, just fill it in afterward.
+ *
+ * The cookie is automatically set to NULL in pps_unregister_source()
+ * so that it will not be used again, even if the pps device cannot
+ * be removed from the idr due to pending references holding the minor
+ * number in use.
+ */
+struct pps_device *pps_lookup_dev(void const *cookie)
+{
+	struct pps_device *pps;
+	unsigned id;
+
+	rcu_read_lock();
+	idr_for_each_entry(&pps_idr, pps, id)
+		if (cookie == pps->lookup_cookie)
+			break;
+	rcu_read_unlock();
+	return pps;
+}
+EXPORT_SYMBOL(pps_lookup_dev);
+
+/*
  * Module stuff
  */
 
include/linux/pps_kernel.h +14 -3
@@ -43,7 +43,7 @@ struct pps_source_info {
 			int event, void *data);	/* PPS echo function */
 
 	struct module *owner;
-	struct device *dev;
+	struct device *dev;		/* Parent device for device_create */
 };
 
 struct pps_event_time {
@@ -69,6 +69,7 @@ struct pps_device {
 	wait_queue_head_t queue;		/* PPS event queue */
 
 	unsigned int id;			/* PPS source unique ID */
+	void const *lookup_cookie;		/* pps_lookup_dev only */
 	struct cdev cdev;
 	struct device *dev;
 	struct fasync_struct *async_queue;	/* fasync method */
@@ -82,16 +83,26 @@ struct pps_device {
 extern struct device_attribute pps_attrs[];
 
 /*
+ * Internal functions.
+ *
+ * These are not actually part of the exported API, but this is a
+ * convenient header file to put them in.
+ */
+
+extern int pps_register_cdev(struct pps_device *pps);
+extern void pps_unregister_cdev(struct pps_device *pps);
+
+/*
  * Exported functions
  */
 
 extern struct pps_device *pps_register_source(
 		struct pps_source_info *info, int default_params);
 extern void pps_unregister_source(struct pps_device *pps);
-extern int pps_register_cdev(struct pps_device *pps);
-extern void pps_unregister_cdev(struct pps_device *pps);
 extern void pps_event(struct pps_device *pps,
 		struct pps_event_time *ts, int event, void *data);
+/* Look up a pps device by magic cookie */
+struct pps_device *pps_lookup_dev(void const *cookie);
 
 static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
 		struct timespec ts)
author maintainer
#11 lore raw

PATCH 11/134 pps: Use pps_lookup_dev to reduce ldisc coupling

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: George Spelvin <[email protected]>

commit 03a7ffe4e542310838bac70ef85acc17536b6d7c upstream.

Now that N_TTY uses tty->disc_data for its private data, 'subclass' ldiscs cannot use ->disc_data for their own private data. (This is a regression is v3.8-rc1)

Use pps_lookup_dev to associate the tty with the pps source instead.

This fixes a crashing regression in 3.8-rc1.

---
 drivers/pps/clients/pps-ldisc.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/pps/clients/pps-ldisc.c +4 -6
@@ -31,7 +31,7 @@
 static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status,
 				struct pps_event_time *ts)
 {
-	struct pps_device *pps = (struct pps_device *)tty->disc_data;
+	struct pps_device *pps = pps_lookup_dev(tty);
 
 	BUG_ON(pps == NULL);
 
@@ -67,9 +67,9 @@ static int pps_tty_open(struct tty_struc
 		pr_err("cannot register PPS source \"%s\"\n", info.path);
 		return -ENOMEM;
 	}
-	tty->disc_data = pps;
+	pps->lookup_cookie = tty;
 
-	/* Should open N_TTY ldisc too */
+	/* Now open the base class N_TTY ldisc */
 	ret = alias_n_tty_open(tty);
 	if (ret < 0) {
 		pr_err("cannot open tty ldisc \"%s\"\n", info.path);
@@ -81,7 +81,6 @@ static int pps_tty_open(struct tty_struc
 	return 0;
 
 err_unregister:
-	tty->disc_data = NULL;
 	pps_unregister_source(pps);
 	return ret;
 }
@@ -90,11 +89,10 @@ static void (*alias_n_tty_close)(struct
 
 static void pps_tty_close(struct tty_struct *tty)
 {
-	struct pps_device *pps = (struct pps_device *)tty->disc_data;
+	struct pps_device *pps = pps_lookup_dev(tty);
 
 	alias_n_tty_close(tty);
 
-	tty->disc_data = NULL;
 	dev_info(pps->dev, "removed\n");
 	pps_unregister_source(pps);
 }
author maintainer
#12 lore raw

PATCH 12/134 pps: Fix a use-after free bug when unregistering a source.

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: George Spelvin <[email protected]>

commit d953e0e837e65ecc1ddaa4f9560f7925878a0de6 upstream.

Remove the cdev from the system (with cdev_del) *before* deallocating it (in pps_device_destruct, called via kobject_put from device_destroy).

Also prevent deallocating a device with open file handles.

A better long-term fix is probably to remove the cdev from the pps_device entirely, and instead have all devices reference one global cdev. Then the deallocation ordering becomes simpler.

But that's more complex and invasive change, so we leave that for later.

---
 drivers/pps/pps.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/pps/pps.c +10 -4
@@ -247,12 +247,15 @@ static int pps_cdev_open(struct inode *i
 	struct pps_device *pps = container_of(inode->i_cdev,
 						struct pps_device, cdev);
 	file->private_data = pps;
-
+	kobject_get(&pps->dev->kobj);
 	return 0;
 }
 
 static int pps_cdev_release(struct inode *inode, struct file *file)
 {
+	struct pps_device *pps = container_of(inode->i_cdev,
+						struct pps_device, cdev);
+	kobject_put(&pps->dev->kobj);
 	return 0;
 }
 
@@ -274,8 +277,10 @@ static void pps_device_destruct(struct d
 {
 	struct pps_device *pps = dev_get_drvdata(dev);
 
-	/* release id here to protect others from using it while it's
-	 * still in use */
+	cdev_del(&pps->cdev);
+
+	/* Now we can release the ID for re-use */
+	pr_debug("deallocating pps%d\n", pps->id);
 	mutex_lock(&pps_idr_lock);
 	idr_remove(&pps_idr, pps->id);
 	mutex_unlock(&pps_idr_lock);
@@ -330,6 +335,7 @@ int pps_register_cdev(struct pps_device
 	if (IS_ERR(pps->dev))
 		goto del_cdev;
 
+	/* Override the release function with our own */
 	pps->dev->release = pps_device_destruct;
 
 	pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
@@ -350,9 +356,9 @@ free_idr:
 
 void pps_unregister_cdev(struct pps_device *pps)
 {
+	pr_debug("unregistering pps%d\n", pps->id);
 	pps->lookup_cookie = NULL;
 	device_destroy(pps_class, pps->dev->devt);
-	cdev_del(&pps->cdev);
 }
 
 /*
author maintainer
#13 lore raw

PATCH 13/134 selinux: correctly label /proc inodes in use before the policy is loaded

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paul Moore <[email protected]>

commit f64410ec665479d7b4b77b7519e814253ed0f686 upstream.

This patch is based on an earlier patch by Eric Paris, he describes the problem below:

"If an inode is accessed before policy load it will get placed on a
list of inodes to be initialized after policy load. After policy load we call inode_doinit() which calls inode_doinit_with_dentry() on all inodes accessed before policy load. In the case of inodes in procfs that means we'll end up at the bottom where it does:

     /* Default to the fs superblock SID. */
     isec->sid = sbsec->sid;

     if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
             if (opt_dentry) {
                     isec->sclass = inode_mode_to_security_class(...)
                     rc = selinux_proc_get_sid(opt_dentry,
                                               isec->sclass,
                                               &sid);
                     if (rc)
                             goto out_unlock;
                     isec->sid = sid;
             }
     }

Since opt_dentry is null, we'll never call selinux_proc_get_sid() and will leave the inode labeled with the label on the superblock. I believe a fix would be to mimic the behavior of xattrs. Look for an alias of the inode. If it can't be found, just leave the inode uninitialized (and pick it up later) if it can be found, we should be able to call selinux_proc_get_sid() ..."

On a system exhibiting this problem, you will notice a lot of files in /proc with the generic "proc_t" type (at least the ones that were accessed early in the boot), for example:

   # ls -Z /proc/sys/kernel/shmmax | awk '{ print $4 " " $5 }'
   system_u:object_r:proc_t:s0 /proc/sys/kernel/shmmax

However, with this patch in place we see the expected result:

   # ls -Z /proc/sys/kernel/shmmax | awk '{ print $4 " " $5 }'
   system_u:object_r:sysctl_kernel_t:s0 /proc/sys/kernel/shmmax
---
 security/selinux/hooks.c |   36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)
security/selinux/hooks.c +27 -9
@@ -1329,15 +1329,33 @@ static int inode_doinit_with_dentry(stru
 		isec->sid = sbsec->sid;
 
 		if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
-			if (opt_dentry) {
-				isec->sclass = inode_mode_to_security_class(inode->i_mode);
-				rc = selinux_proc_get_sid(opt_dentry,
-							  isec->sclass,
-							  &sid);
-				if (rc)
-					goto out_unlock;
-				isec->sid = sid;
-			}
+			/* We must have a dentry to determine the label on
+			 * procfs inodes */
+			if (opt_dentry)
+				/* Called from d_instantiate or
+				 * d_splice_alias. */
+				dentry = dget(opt_dentry);
+			else
+				/* Called from selinux_complete_init, try to
+				 * find a dentry. */
+				dentry = d_find_alias(inode);
+			/*
+			 * This can be hit on boot when a file is accessed
+			 * before the policy is loaded.  When we load policy we
+			 * may find inodes that have no dentry on the
+			 * sbsec->isec_head list.  No reason to complain as
+			 * these will get fixed up the next time we go through
+			 * inode_doinit() with a dentry, before these inodes
+			 * could be used again by userspace.
+			 */
+			if (!dentry)
+				goto out_unlock;
+			isec->sclass = inode_mode_to_security_class(inode->i_mode);
+			rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
+			dput(dentry);
+			if (rc)
+				goto out_unlock;
+			isec->sid = sid;
 		}
 		break;
 	}
author maintainer
#14 lore raw

PATCH 14/134 intel_idle: Check cpu_idle_get_driver() for NULL before dereferencing it.

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Konrad Rzeszutek Wilk <[email protected]>

commit 3735d524da64b70b41c764359da36f88aded3610 upstream.

If the machine is booted without any cpu_idle driver set (b/c disable_cpuidle() has been called) we should follow other users of cpu_idle API and check the return value for NULL before using it.

---
 drivers/idle/intel_idle.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/idle/intel_idle.c +2 -1
@@ -594,8 +594,9 @@ static int __init intel_idle_init(void)
 	intel_idle_cpuidle_driver_init();
 	retval = cpuidle_register_driver(&intel_idle_driver);
 	if (retval) {
+		struct cpuidle_driver *drv = cpuidle_get_driver();
 		printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
-			cpuidle_get_driver()->name);
+			drv ? drv->name : "none");
 		return retval;
 	}
 
author maintainer
#15 lore raw

PATCH 15/134 HID: add quirk for Freescale i.MX28 ROM recovery

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marek Vasut <[email protected]>

commit 2843b673d03421e0e73cf061820d1db328f7c8eb upstream.

The USB recovery mode present in i.MX28 ROM emulates USB HID. It needs this quirk to behave properly.

Cc Chen Peter <[email protected]>
Cc Greg KH <[email protected]>
Cc Jiri Kosina <[email protected]>
[[email protected]: fix alphabetical ordering]
[bwh: Backported to 3.2: adjust context]
[yjw: Backported to 3.4: adjust context]
---
 drivers/hid/hid-ids.h           |    3 +++
 drivers/hid/usbhid/hid-quirks.c |    1 +
 2 files changed, 4 insertions(+)
drivers/hid/hid-ids.h +3 -0
@@ -293,6 +293,9 @@
 #define USB_VENDOR_ID_FRUCTEL	0x25B6
 #define USB_DEVICE_ID_GAMETEL_MT_MODE	0x0002
 
+#define USB_VENDOR_ID_FREESCALE		0x15A2
+#define USB_DEVICE_ID_FREESCALE_MX28	0x004F
+
 #define USB_VENDOR_ID_GAMERON		0x0810
 #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR	0x0001
 #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR	0x0002
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -70,6 +70,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
author maintainer
#16 lore raw

PATCH 16/134 HID: usbhid: quirk for Formosa IR receiver

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nicholas Santos <[email protected]>

commit 320cde19a4e8f122b19d2df7a5c00636e11ca3fb upstream.

Patch to add the Formosa Industrial Computing, Inc. Infrared Receiver [IR605A/Q] to hid-ids.h and hid-quirks.c. This IR receiver causes about a 10 second timeout when the usbhid driver attempts to initialze the device. Adding this device to the quirks list with HID_QUIRK_NO_INIT_REPORTS removes the delay.

---
 drivers/hid/hid-ids.h           |    3 +++
 drivers/hid/usbhid/hid-quirks.c |    1 +
 2 files changed, 4 insertions(+)
drivers/hid/hid-ids.h +3 -0
@@ -293,6 +293,9 @@
 #define USB_VENDOR_ID_FRUCTEL	0x25B6
 #define USB_DEVICE_ID_GAMETEL_MT_MODE	0x0002
 
+#define USB_VENDOR_ID_FORMOSA          0x147a
+#define USB_DEVICE_ID_FORMOSA_IR_RECEIVER      0xe03e
+
 #define USB_VENDOR_ID_FREESCALE		0x15A2
 #define USB_DEVICE_ID_FREESCALE_MX28	0x004F
 
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -70,6 +70,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
author maintainer
#17 lore raw

PATCH 17/134 HID: validate feature and input report details

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Tissoires <[email protected]>

commit cc6b54aa54bf40b762cab45a9fc8aa81653146eb upstream.

When dealing with usage_index, be sure to properly use unsigned instead of int to avoid overflows.

When working on report fields, always validate that their report_counts are in bounds.
Without this, a HID device could report a malicious feature report that could trick the driver into a heap overflow:

[  634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500
...
[  676.469629] BUG kmalloc-192 (Tainted: G        W   ): Redzone overwritten

CVE-2013-2897

[bwh: Backported to 3.2:
- Drop inapplicable changes to hid_usage::usage_index initialisation and to hid_report_raw_event()
- Adjust context in report_features()

[yijingwang: Backported to 3.4: context adjust]
---
 drivers/hid/hid-core.c  |    9 +++++----
 drivers/hid/hid-input.c |   12 +++++++++++-
 2 files changed, 16 insertions(+), 5 deletions(-)
drivers/hid/hid-core.c +5 -4
@@ -222,9 +222,9 @@ static int hid_add_field(struct hid_pars
 {
 	struct hid_report *report;
 	struct hid_field *field;
-	int usages;
+	unsigned usages;
 	unsigned offset;
-	int i;
+	unsigned i;
 
 	report = hid_register_report(parser->device, report_type, parser->global.report_id);
 	if (!report) {
@@ -244,7 +244,8 @@ static int hid_add_field(struct hid_pars
 	if (!parser->local.usage_index) /* Ignore padding fields */
 		return 0;
 
-	usages = max_t(int, parser->local.usage_index, parser->global.report_count);
+	usages = max_t(unsigned, parser->local.usage_index,
+				 parser->global.report_count);
 
 	field = hid_register_field(report, usages, parser->global.report_count);
 	if (!field)
@@ -255,7 +256,7 @@ static int hid_add_field(struct hid_pars
 	field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
 
 	for (i = 0; i < usages; i++) {
-		int j = i;
+		unsigned j = i;
 		/* Duplicate the last usage we parsed if we have excess values */
 		if (i >= parser->local.usage_index)
 			j = parser->local.usage_index - 1;
drivers/hid/hid-input.c +11 -1
@@ -459,6 +459,10 @@ static void hidinput_configure_usage(str
 	if (field->flags & HID_MAIN_ITEM_CONSTANT)
 		goto ignore;
 
+	/* Ignore if report count is out of bounds. */
+	if (field->report_count < 1)
+		goto ignore;
+
 	/* only LED usages are supported in output fields */
 	if (field->report_type == HID_OUTPUT_REPORT &&
 			(usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
@@ -1119,7 +1123,12 @@ static void report_features(struct hid_d
 
 	rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
 	list_for_each_entry(rep, &rep_enum->report_list, list)
-		for (i = 0; i < rep->maxfield; i++)
+		for (i = 0; i < rep->maxfield; i++) {
+
+			/* Ignore if report count is out of bounds. */
+			if (rep->field[i]->report_count < 1)
+				continue;
+
 			for (j = 0; j < rep->field[i]->maxusage; j++) {
 				/* Verify if Battery Strength feature is available */
 				hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]);
@@ -1128,6 +1137,7 @@ static void report_features(struct hid_d
 					drv->feature_mapping(hid, rep->field[i],
 							     rep->field[i]->usage + j);
 			}
+		}
 }
 
 /*
author maintainer
#18 lore raw

PATCH 18/134 HID: multitouch: validate indexes details

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Tissoires <[email protected]>

commit 8821f5dc187bdf16cfb32ef5aa8c3035273fa79a upstream.

When working on report indexes, always validate that they are in bounds. Without this, a HID device could report a malicious feature report that could trick the driver into a heap overflow:

[  634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500
...
[  676.469629] BUG kmalloc-192 (Tainted: G        W   ): Redzone overwritten

Note that we need to change the indexes from s8 to s16 as they can be between -1 and 255.

CVE-2013-2897

[bwh: Backported to 3.2: mt_device::{cc,cc_value,inputmode}_index do not
exist and the corresponding indices do not need to be validated. mt_device::maxcontact_report_id does not exist either. So all we need to do is to widen mt_device::inputmode.]

[yjw: Backport to 3.4: maxcontact_report_id exists,
need to be validated]

---
 drivers/hid/hid-multitouch.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hid/hid-multitouch.c +2 -2
@@ -82,8 +82,8 @@ struct mt_device {
 					   multitouch fields */
 	unsigned last_field_index;	/* last field index of the report */
 	unsigned last_slot_field;	/* the last field of a slot */
-	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */
-	__s8 maxcontact_report_id;	/* Maximum Contact Number HID feature,
+	__s16 inputmode;		/* InputMode HID feature, -1 if non-existent */
+	__s16 maxcontact_report_id;	/* Maximum Contact Number HID feature,
 				   -1 if non-existent */
 	__u8 num_received;	/* how many contacts we received */
 	__u8 num_expected;	/* expected last contact index */
author maintainer
#19 lore raw

PATCH 19/134 HID: hidraw: add proper error handling to raw event reporting

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiri Kosina <[email protected]>

commit b6787242f32700377d3da3b8d788ab3928bab849 upstream.

If kmemdup() in hidraw_report_event() fails, we are not propagating this fact properly.

Let hidraw_report_event() and hid_report_raw_event() return an error value to the caller.

---
 drivers/hid/hid-core.c |   16 +++++++++++-----
 drivers/hid/hidraw.c   |   19 +++++++++++++------
 include/linux/hid.h    |    2 +-
 include/linux/hidraw.h |    4 ++--
 4 files changed, 27 insertions(+), 14 deletions(-)
drivers/hid/hid-core.c +11 -5
@@ -1100,7 +1100,7 @@ static struct hid_report *hid_get_report
 	return report;
 }
 
-void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
 		int interrupt)
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
@@ -1108,10 +1108,11 @@ void hid_report_raw_event(struct hid_dev
 	unsigned int a;
 	int rsize, csize = size;
 	u8 *cdata = data;
+	int ret = 0;
 
 	report = hid_get_report(report_enum, data);
 	if (!report)
-		return;
+		goto out;
 
 	if (report_enum->numbered) {
 		cdata++;
@@ -1131,14 +1132,19 @@ void hid_report_raw_event(struct hid_dev
 
 	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
 		hid->hiddev_report_event(hid, report);
-	if (hid->claimed & HID_CLAIMED_HIDRAW)
-		hidraw_report_event(hid, data, size);
+	if (hid->claimed & HID_CLAIMED_HIDRAW) {
+		ret = hidraw_report_event(hid, data, size);
+		if (ret)
+			goto out;
+	}
 
 	for (a = 0; a < report->maxfield; a++)
 		hid_input_field(hid, report->field[a], cdata, interrupt);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_report_event(hid, report);
+out:
+	return ret;
 }
 EXPORT_SYMBOL_GPL(hid_report_raw_event);
 
@@ -1215,7 +1221,7 @@ nomem:
 		}
 	}
 
-	hid_report_raw_event(hid, type, data, size, interrupt);
+	ret = hid_report_raw_event(hid, type, data, size, interrupt);
 
 unlock:
 	up(&hid->driver_lock);
drivers/hid/hidraw.c +13 -6
@@ -87,11 +87,13 @@ static ssize_t hidraw_read(struct file *
 		len = list->buffer[list->tail].len > count ?
 			count : list->buffer[list->tail].len;
 
-		if (copy_to_user(buffer, list->buffer[list->tail].value, len)) {
-			ret = -EFAULT;
-			goto out;
+		if (list->buffer[list->tail].value) {
+			if (copy_to_user(buffer, list->buffer[list->tail].value, len)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			ret = len;
 		}
-		ret = len;
 
 		kfree(list->buffer[list->tail].value);
 		list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
@@ -437,19 +439,24 @@ static const struct file_operations hidr
 	.llseek =	noop_llseek,
 };
 
-void hidraw_report_event(struct hid_device *hid, u8 *data, int len)
+int hidraw_report_event(struct hid_device *hid, u8 *data, int len)
 {
 	struct hidraw *dev = hid->hidraw;
 	struct hidraw_list *list;
+	int ret = 0;
 
 	list_for_each_entry(list, &dev->list, node) {
-		list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC);
+		if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) {
+			ret = -ENOMEM;
+			break;
+		}
 		list->buffer[list->head].len = len;
 		list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
 		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 	}
 
 	wake_up_interruptible(&dev->wait);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(hidraw_report_event);
 
include/linux/hid.h +1 -1
@@ -902,7 +902,7 @@ static inline int hid_hw_power(struct hi
 	return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0;
 }
 
-void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
 		int interrupt);
 
 extern int hid_generic_init(void);
include/linux/hidraw.h +2 -2
@@ -76,13 +76,13 @@ struct hidraw_list {
 #ifdef CONFIG_HIDRAW
 int hidraw_init(void);
 void hidraw_exit(void);
-void hidraw_report_event(struct hid_device *, u8 *, int);
+int hidraw_report_event(struct hid_device *, u8 *, int);
 int hidraw_connect(struct hid_device *);
 void hidraw_disconnect(struct hid_device *);
 #else
 static inline int hidraw_init(void) { return 0; }
 static inline void hidraw_exit(void) { }
-static inline void hidraw_report_event(struct hid_device *hid, u8 *data, int len) { }
+static inline int hidraw_report_event(struct hid_device *hid, u8 *data, int len) { }
 static inline int hidraw_connect(struct hid_device *hid) { return -1; }
 static inline void hidraw_disconnect(struct hid_device *hid) { }
 #endif
author maintainer
#20 lore raw

PATCH 20/134 HID: fix return value of hidraw_report_event() when !CONFIG_HIDRAW

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiri Kosina <[email protected]>

commit d6d7c873529abd622897cad5e36f1fd7d82f5110 upstream.

Commit b6787242f327 ("HID: hidraw: add proper error handling to raw event reporting") forgot to update the static inline version of hidraw_report_event() for the case when CONFIG_HIDRAW is unset. Fix that up.

---
 include/linux/hidraw.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/hidraw.h +1 -1
@@ -82,7 +82,7 @@ void hidraw_disconnect(struct hid_device
 #else
 static inline int hidraw_init(void) { return 0; }
 static inline void hidraw_exit(void) { }
-static inline int hidraw_report_event(struct hid_device *hid, u8 *data, int len) { }
+static inline int hidraw_report_event(struct hid_device *hid, u8 *data, int len) { return 0; }
 static inline int hidraw_connect(struct hid_device *hid) { return -1; }
 static inline void hidraw_disconnect(struct hid_device *hid) { }
 #endif
author maintainer
#21 lore raw

PATCH 21/134 HID: hidraw: fix list->buffer memleak

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matthieu CASTET <[email protected]>

commit 4c7b417ecb756e85dfc955b0e7a04fd45585533e upstream.

If we don't read fast enough hidraw device, hidraw_report_event will cycle and we will leak list->buffer.
Also list->buffer are not free on release.
After this patch, kmemleak report nothing.

---
 drivers/hid/hidraw.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/hid/hidraw.c +11 -1
@@ -96,6 +96,7 @@ static ssize_t hidraw_read(struct file *
 		}
 
 		kfree(list->buffer[list->tail].value);
+		list->buffer[list->tail].value = NULL;
 		list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
 	}
 out:
@@ -300,6 +301,7 @@ static int hidraw_release(struct inode *
 	struct hidraw *dev;
 	struct hidraw_list *list = file->private_data;
 	int ret;
+	int i;
 
 	mutex_lock(&minors_lock);
 	if (!hidraw_table[minor]) {
@@ -317,6 +319,9 @@ static int hidraw_release(struct inode *
 			kfree(list->hidraw);
 		}
 	}
+
+	for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
+		kfree(list->buffer[i].value);
 	kfree(list);
 	ret = 0;
 unlock:
@@ -446,12 +451,17 @@ int hidraw_report_event(struct hid_devic
 	int ret = 0;
 
 	list_for_each_entry(list, &dev->list, node) {
+		int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
+
+		if (new_head == list->tail)
+			continue;
+
 		if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) {
 			ret = -ENOMEM;
 			break;
 		}
 		list->buffer[list->head].len = len;
-		list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
+		list->head = new_head;
 		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 	}
 
author maintainer
#22 lore raw

PATCH 22/134 HID: hidraw: improve error handling in hidraw_init()

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexey Khoroshilov <[email protected]>

commit bcb4a75bde3821cecb17a71d287abfd6ef9bd68d upstream.

Several improvements in error handling:
- do not report success if alloc_chrdev_region() failed
- check for error code of cdev_add()
- use unregister_chrdev_region() instead of unregister_chrdev() if class_create() failed

Found by Linux Driver Verification project (linuxtesting.org).

---
 drivers/hid/hidraw.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/hid/hidraw.c +11 -4
@@ -559,21 +559,28 @@ int __init hidraw_init(void)
 
 	if (result < 0) {
 		pr_warn("can't get major number\n");
-		result = 0;
 		goto out;
 	}
 
 	hidraw_class = class_create(THIS_MODULE, "hidraw");
 	if (IS_ERR(hidraw_class)) {
 		result = PTR_ERR(hidraw_class);
-		unregister_chrdev(hidraw_major, "hidraw");
-		goto out;
+		goto error_cdev;
 	}
 
         cdev_init(&hidraw_cdev, &hidraw_ops);
-        cdev_add(&hidraw_cdev, dev_id, HIDRAW_MAX_DEVICES);
+	result = cdev_add(&hidraw_cdev, dev_id, HIDRAW_MAX_DEVICES);
+	if (result < 0)
+		goto error_class;
+
 out:
 	return result;
+
+error_class:
+	class_destroy(hidraw_class);
+error_cdev:
+	unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
+	goto out;
 }
 
 void hidraw_exit(void)
author maintainer
#23 lore raw

PATCH 23/134 HID: apple: Add Apple wireless keyboard 2011 ANSI PID

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexey Kaminsky <[email protected]>

commit 0a97e1e9f9a6765e6243030ac42b04694f3f3647 upstream.

[bwh: Backported to 3.2: add the device ID to hid-ids.h]
Cc Yijing Wang <[email protected]>
---
 drivers/hid/hid-apple.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/hid/hid-apple.c +3 -0
@@ -480,6 +480,9 @@ static const struct hid_device_id apple_
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
 			APPLE_ISO_KEYBOARD },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+				USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
+		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
author maintainer
#24 lore raw

PATCH 24/134 HID: add support for Sony RF receiver with USB product id 0x0374

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Fernando Luis Vazquez Cao <[email protected]>

commit a464918419f94a0043d2f549d6defb4c3f69f68a upstream.

Some Vaio desktop computers, among them the VGC-LN51JGB multimedia PC, have a RF receiver, multi-interface USB device 054c:0374, that is used to connect a wireless keyboard and a wireless mouse.

The keyboard works flawlessly, but the mouse (VGP-WMS3 in my case) does not seem to be generating any pointer events. The problem is that the mouse pointer is wrongly declared as a constant non-data variable in the report descriptor (see lsusb and usbhid-dump output below), with the consequence that it is ignored by the HID code.

Add this device to the have-special-driver list and fix up the report descriptor in the Sony-specific driver which happens to already have a fixup for a similar firmware bug.

# lsusb -vd 054C:0374
Bus 003 Device 002: ID 054c:0374 Sony Corp.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x054c Sony Corp.
  idProduct          0x0374
  iSerial                 0
[...]
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              2 RF Receiver
[...]
          Report Descriptor: (length is 100)
[...]
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x30 ] 48
                            Direction-X
            Item(Local ): Usage, data= [ 0x31 ] 49
                            Direction-Y
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Logical Minimum, data= [ 0x81 ] 129
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Main  ): Input, data= [ 0x07 ] 7
                            Constant Variable Relative No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
# usbhid-dump
003:002:001:DESCRIPTOR         1357910009.758544
 05 01 09 02 A1 01 05 01 09 02 A1 02 85 01 09 01
 A1 00 05 09 19 01 29 05 95 05 75 01 15 00 25 01
 81 02 75 03 95 01 81 01 05 01 09 30 09 31 95 02
 75 08 15 81 25 7F 81 07 A1 02 85 01 09 38 35 00
 45 00 15 81 25 7F 95 01 75 08 81 06 C0 A1 02 85
 01 05 0C 15 81 25 7F 95 01 75 08 0A 38 02 81 06
 C0 C0 C0 C0
---
 drivers/hid/hid-core.c |    1 +
 drivers/hid/hid-ids.h  |    1 +
 drivers/hid/hid-sony.c |    4 +++-
 3 files changed, 5 insertions(+), 1 deletion(-)
drivers/hid/hid-core.c +1 -0
@@ -1619,6 +1619,7 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) },
drivers/hid/hid-ids.h +1 -0
@@ -685,6 +685,7 @@
 
 #define USB_VENDOR_ID_SONY			0x054c
 #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE	0x024b
+#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE	0x0374
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
 #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER	0x042f
 
drivers/hid/hid-sony.c +3 -1
@@ -46,7 +46,7 @@ static __u8 *sony_report_fixup(struct hi
 
 	if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
 			*rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
-		hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
+		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
 		rdesc[55] = 0x06;
 	}
 
@@ -218,6 +218,8 @@ static const struct hid_device_id sony_d
 		.driver_data = SIXAXIS_CONTROLLER_BT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
 		.driver_data = VAIO_RDESC_CONSTANT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
+		.driver_data = VAIO_RDESC_CONSTANT },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, sony_devices);
author maintainer
#25 lore raw

PATCH 25/134 HID: clean up quirk for Sony RF receivers

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Fernando Luis Vazquez Cao <[email protected]>

commit 99d249021abd4341771523ed8dd7946276103432 upstream.

Document what the fix-up is does and make it more robust by ensuring that it is only applied to the USB interface that corresponds to the mouse (sony_report_fixup() is called once per interface during probing).

---
 drivers/hid/hid-sony.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/hid/hid-sony.c +12 -2
@@ -44,9 +44,19 @@ static __u8 *sony_report_fixup(struct hi
 {
 	struct sony_sc *sc = hid_get_drvdata(hdev);
 
-	if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
-			*rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
+	/*
+	 * Some Sony RF receivers wrongly declare the mouse pointer as a
+	 * a constant non-data variable.
+	 */
+	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
+	    /* usage page: generic desktop controls */
+	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
+	    /* usage: mouse */
+	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
+	    /* input (usage page for x,y axes): constant, variable, relative */
+	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
+		/* input: data, variable, relative */
 		rdesc[55] = 0x06;
 	}
 
author maintainer
#26 lore raw

PATCH 26/134 HID: usbhid: quirk for MSI GX680R led panel

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Boyer <[email protected]>

commit 620ae90ed8ca8b6e40cb9e10279b4f5ef9f0ab81 upstream.

This keyboard backlight device causes a 10 second delay to boot. Add it to the quirk list with HID_QUIRK_NO_INIT_REPORTS.

This fixes Red Hat bugzilla https://bugzilla.redhat.com/show_bug.cgi?id=907221

[bwh: Backported to 3.2: adjust context]
Cc Yijing Wang <[email protected]>
---
 drivers/hid/hid-ids.h           |    3 +++
 drivers/hid/usbhid/hid-quirks.c |    1 +
 2 files changed, 4 insertions(+)
drivers/hid/hid-ids.h +3 -0
@@ -559,6 +559,9 @@
 #define USB_VENDOR_ID_MONTEREY		0x0566
 #define USB_DEVICE_ID_GENIUS_KB29E	0x3004
 
+#define USB_VENDOR_ID_MSI		0x1770
+#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL	0xff00
+
 #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
 #define USB_DEVICE_ID_N_S_HARMONY	0xc359
 
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -73,6 +73,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+	{ USB_VENDIR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
author maintainer
#27 lore raw

PATCH 27/134 HID: usbhid: fix build problem

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiri Kosina <[email protected]>

commit 570637dc8eeb2faba06228d497ff40bb019bcc93 upstream.

Fix build problem caused by typo introduced by 620ae90ed8 ("HID: usbhid: quirk for MSI GX680R led panel").

Reported-by [email protected]
[bwh: Backported to 3.2: adjust context]
Cc Yijing Wang <[email protected]>
---
 drivers/hid/usbhid/hid-quirks.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/usbhid/hid-quirks.c +1 -1
@@ -73,7 +73,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
-	{ USB_VENDIR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
author maintainer
#28 lore raw

PATCH 28/134 HID: hidraw: correctly deallocate memory on device disconnect

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Manoj Chourasia <[email protected]>

commit 212a871a3934beccf43431608c27ed2e05a476ec upstream.

This changes puts the commit 4fe9f8e203f back in place with the fixes for slab corruption because of the commit.

When a device is unplugged, wait for all processes that have opened the device to close before deallocating the device.

This commit was solving kernel crash because of the corruption in rb tree of vmalloc. The rootcause was the device data pointer was geting excessed after the memory associated with hidraw was freed.

The commit 4fe9f8e203f was buggy as it was also freeing the hidraw first and then calling delete operation on the list associated with that hidraw leading to slab corruption.

---
 drivers/hid/hidraw.c |   60 +++++++++++++++++++++------------------------------
 1 file changed, 25 insertions(+), 35 deletions(-)
drivers/hid/hidraw.c +25 -35
@@ -113,7 +113,7 @@ static ssize_t hidraw_send_report(struct
 	__u8 *buf;
 	int ret = 0;
 
-	if (!hidraw_table[minor]) {
+	if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
 		ret = -ENODEV;
 		goto out;
 	}
@@ -261,7 +261,7 @@ static int hidraw_open(struct inode *ino
 	}
 
 	mutex_lock(&minors_lock);
-	if (!hidraw_table[minor]) {
+	if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
 		err = -ENODEV;
 		goto out_unlock;
 	}
@@ -295,39 +295,38 @@ out:
 
 }
 
+static void drop_ref(struct hidraw *hidraw, int exists_bit)
+{
+	if (exists_bit) {
+		hid_hw_close(hidraw->hid);
+		hidraw->exist = 0;
+		if (hidraw->open)
+			wake_up_interruptible(&hidraw->wait);
+	} else {
+		--hidraw->open;
+	}
+
+	if (!hidraw->open && !hidraw->exist) {
+		device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
+		hidraw_table[hidraw->minor] = NULL;
+		kfree(hidraw);
+	}
+}
+
 static int hidraw_release(struct inode * inode, struct file * file)
 {
 	unsigned int minor = iminor(inode);
-	struct hidraw *dev;
 	struct hidraw_list *list = file->private_data;
-	int ret;
-	int i;
 
 	mutex_lock(&minors_lock);
-	if (!hidraw_table[minor]) {
-		ret = -ENODEV;
-		goto unlock;
-	}
 
 	list_del(&list->node);
-	dev = hidraw_table[minor];
-	if (!--dev->open) {
-		if (list->hidraw->exist) {
-			hid_hw_power(dev->hid, PM_HINT_NORMAL);
-			hid_hw_close(dev->hid);
-		} else {
-			kfree(list->hidraw);
-		}
-	}
-
-	for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
-		kfree(list->buffer[i].value);
 	kfree(list);
-	ret = 0;
-unlock:
-	mutex_unlock(&minors_lock);
 
-	return ret;
+	drop_ref(hidraw_table[minor], 0);
+
+	mutex_unlock(&minors_lock);
+	return 0;
 }
 
 static long hidraw_ioctl(struct file *file, unsigned int cmd,
@@ -531,18 +530,9 @@ void hidraw_disconnect(struct hid_device
 	struct hidraw *hidraw = hid->hidraw;
 
 	mutex_lock(&minors_lock);
-	hidraw->exist = 0;
-
-	device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
 
-	hidraw_table[hidraw->minor] = NULL;
+	drop_ref(hidraw, 1);
 
-	if (hidraw->open) {
-		hid_hw_close(hid);
-		wake_up_interruptible(&hidraw->wait);
-	} else {
-		kfree(hidraw);
-	}
 	mutex_unlock(&minors_lock);
 }
 EXPORT_SYMBOL_GPL(hidraw_disconnect);
author maintainer
#29 lore raw

PATCH 29/134 ARM: dts: imx51-babbage: fix esdhc cd/wp properties

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Shawn Guo <[email protected]>

commit a46d2619d7180bda12bad2bf15bbd0731dfc2dcf upstream.

The binding doc and dts use properties "fsl,{cd,wp}-internal" while esdhc driver uses "fsl,{cd,wp}-controller". Fix binding doc and dts to get them match driver code.

---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt |    8 ++++----
 arch/arm/boot/dts/imx51-babbage.dts                     |    4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)
Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +4 -4
@@ -10,8 +10,8 @@ Required properties:
 
 Optional properties:
 - fsl,card-wired : Indicate the card is wired to host permanently
-- fsl,cd-internal : Indicate to use controller internal card detection
-- fsl,wp-internal : Indicate to use controller internal write protection
+- fsl,cd-controller : Indicate to use controller internal card detection
+- fsl,wp-controller : Indicate to use controller internal write protection
 - cd-gpios : Specify GPIOs for card detection
 - wp-gpios : Specify GPIOs for write protection
 
@@ -21,8 +21,8 @@ esdhc@70004000 {
 	compatible = "fsl,imx51-esdhc";
 	reg = <0x70004000 0x4000>;
 	interrupts = <1>;
-	fsl,cd-internal;
-	fsl,wp-internal;
+	fsl,cd-controller;
+	fsl,wp-controller;
 };
 
 esdhc@70008000 {
arch/arm/boot/dts/imx51-babbage.dts +2 -2
@@ -29,8 +29,8 @@
 		aips@70000000 { /* aips-1 */
 			spba@70000000 {
 				esdhc@70004000 { /* ESDHC1 */
-					fsl,cd-internal;
-					fsl,wp-internal;
+					fsl,cd-controller;
+					fsl,wp-controller;
 					status = "okay";
 				};
 
author maintainer
#30 lore raw

PATCH 30/134 ARM: w90x900: fix legacy assembly syntax

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit fa5ce5f94c0f2bfa41ba68d2d2524298e1fc405e upstream.

New ARM binutils don't allow extraneous whitespace inside of brackets, which causes this error on all mach-w90x900 defconfigs:

arch/arm/kernel/entry-armv.S: Assembler messages:
arch/arm/kernel/entry-armv.S:214: Error: ARM register expected -- ldr r0,[ r6,#(0x10C)]' arch/arm/kernel/entry-armv.S:214: Error: ARM register expected -- ldr r0,[ r6,#(0x110)]' arch/arm/kernel/entry-armv.S:430: Error: ARM register expected -- ldr r0,[ r6,#(0x10C)]' arch/arm/kernel/entry-armv.S:430: Error: ARM register expected -- ldr r0,[ r6,#(0x110)]'

This removes the whitespace in order to build the kernel again.

---
 arch/arm/mach-w90x900/include/mach/entry-macro.S |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-w90x900/include/mach/entry-macro.S +2 -2
@@ -19,8 +19,8 @@
 
 		mov	\base, #AIC_BA
 
-		ldr	\irqnr, [ \base, #AIC_IPER]
-		ldr	\irqnr, [ \base, #AIC_ISNR]
+		ldr	\irqnr, [\base, #AIC_IPER]
+		ldr	\irqnr, [\base, #AIC_ISNR]
 		cmp	\irqnr, #0
 
 	.endm
author maintainer
#31 lore raw

PATCH 31/134 ARM: u300: fix ages old copy/paste bug

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Walleij <[email protected]>

commit 0259d9eb30d003af305626db2d8332805696e60d upstream.

The UART1 is on the fast AHB bridge, not on the slow bus.

---
 arch/arm/mach-u300/include/mach/u300-regs.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-u300/include/mach/u300-regs.h +1 -1
@@ -101,7 +101,7 @@
 
 #ifdef CONFIG_MACH_U300_BS335
 /* Fast UART1 on U335 only */
-#define U300_UART1_BASE			(U300_SLOW_PER_PHYS_BASE+0x7000)
+#define U300_UART1_BASE			(U300_FAST_PER_PHYS_BASE+0x7000)
 #endif
 
 /*
author maintainer
#32 lore raw

PATCH 32/134 ARM: 7742/1: topology: export cpu_topology

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 92bdd3f5eba299b33c2f4407977d6fa2e2a6a0da upstream.

The cpu_topology symbol is required by any driver using the topology interfaces, which leads to a couple of build errors:

ERROR: "cpu_topology" [drivers/net/ethernet/sfc/sfc.ko] undefined!
ERROR: "cpu_topology" [drivers/cpufreq/arm_big_little.ko] undefined!
ERROR: "cpu_topology" [drivers/block/mtip32xx/mtip32xx.ko] undefined!

The obvious solution is to export this symbol.

---
 arch/arm/kernel/topology.c |    2 ++
 1 file changed, 2 insertions(+)
arch/arm/kernel/topology.c +2 -0
@@ -13,6 +13,7 @@
 
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/node.h>
@@ -42,6 +43,7 @@
 #define MPIDR_LEVEL2_SHIFT 16
 
 struct cputopo_arm cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
 
 const struct cpumask *cpu_coregroup_mask(int cpu)
 {
author maintainer
#33 lore raw

PATCH 33/134 ARM: 7743/1: compressed/head.S: work around new binutils warning

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit da94a829305f1c217cfdf6771cb1faca0917e3b9 upstream.

In August 2012, Matthew Gretton-Dann checked a change into binutils labelled "Error on obsolete & warn on deprecated registers", apparently as part of ARMv8 support. Apparently, this was supposed to emit the message "Warning: This coprocessor register access is deprecated in ARMv8" when using certain mcr/mrc instructions and building for ARMv8. Unfortunately, the message that is actually emitted appears to be '(null)', which is less helpful in comparison.

Even more unfortunately, this is biting us on every single kernel build with a new gas, because arch/arm/boot/compressed/head.S and some other files in that directory are built with -march=all since kernel commit 80cec14a8 "[ARM] Add -march=all to assembly file build in arch/arm/boot/compressed" back in v2.6.28.

This patch reverts Russell's nice solution and instead marks the head.S file to be built for armv7-a, which fortunately lets us build all instructions in that file without warnings even on the broken binutils.

Without this patch, building anything results in:

arch/arm/boot/compressed/head.S: Assembler messages:
arch/arm/boot/compressed/head.S:565: Warning: (null) arch/arm/boot/compressed/head.S:676: Warning: (null) arch/arm/boot/compressed/head.S:698: Warning: (null) arch/arm/boot/compressed/head.S:722: Warning: (null) arch/arm/boot/compressed/head.S:726: Warning: (null) arch/arm/boot/compressed/head.S:957: Warning: (null) arch/arm/boot/compressed/head.S:996: Warning: (null) arch/arm/boot/compressed/head.S:997: Warning: (null) arch/arm/boot/compressed/head.S:1027: Warning: (null) arch/arm/boot/compressed/head.S:1035: Warning: (null) arch/arm/boot/compressed/head.S:1046: Warning: (null) arch/arm/boot/compressed/head.S:1060: Warning: (null) arch/arm/boot/compressed/head.S:1092: Warning: (null) arch/arm/boot/compressed/head.S:1094: Warning: (null) arch/arm/boot/compressed/head.S:1095: Warning: (null) arch/arm/boot/compressed/head.S:1102: Warning: (null) arch/arm/boot/compressed/head.S:1134: Warning: (null)

[bwh: Backported to 3.2:
- Adjust context
- Remove definition of asflags-y as it is now empty]

---
 arch/arm/boot/compressed/Makefile      |    1 -
 arch/arm/boot/compressed/head-sa1100.S |    1 +
 arch/arm/boot/compressed/head-shark.S  |    1 +
 arch/arm/boot/compressed/head.S        |    1 +
 4 files changed, 3 insertions(+), 1 deletion(-)
arch/arm/boot/compressed/Makefile +0 -1
@@ -126,7 +126,6 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CF
 endif
 
 ccflags-y := -fpic -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
arch/arm/boot/compressed/head-sa1100.S +1 -0
@@ -11,6 +11,7 @@
 #include <asm/mach-types.h>
 
 		.section        ".start", "ax"
+		.arch	armv4
 
 __SA1100_start:
 
arch/arm/boot/compressed/head-shark.S +1 -0
@@ -18,6 +18,7 @@
 	
 		.section	".start", "ax"
 
+		.arch armv4
 		b	__beginning
 	
 __ofw_data:	.long	0				@ the number of memory blocks
arch/arm/boot/compressed/head.S +1 -0
@@ -10,6 +10,7 @@
  */
 #include <linux/linkage.h>
 
+	.arch	armv7-a
 /*
  * Debugging stuff
  *
author maintainer
#34 lore raw

PATCH 34/134 ARM: footbridge: fix VGA initialisation

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Russell King <[email protected]>

commit 43659222e7a0113912ed02f6b2231550b3e471ac upstream.

It's no good setting vga_base after the VGA console has been initialised, because if we do that we get this:

Unable to handle kernel paging request at virtual address 000b8000
pgd = c0004000
[000b8000] *pgd=07ffc831, *pte=00000000, *ppte=00000000
0Internal error: Oops: 5017 [#1] ARM
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.0+ #49
task: c03e2974 ti: c03d8000 task.ti: c03d8000
PC is at vgacon_startup+0x258/0x39c
LR is at request_resource+0x10/0x1c
pc : [<c01725d0>]    lr : [<c0022b50>]    psr: 60000053

sp : c03d9f68 ip : 000b8000 fp : c03d9f8c
r10: 000055aa r9 : 4401a103 r8 : ffffaa55
r7 : c03e357c r6 : c051b460 r5 : 000000ff r4 : 000c0000 r3 : 000b8000 r2 : c03e0514 r1 : 00000000 r0 : c0304971
Flags: nZCv IRQs on FIQs off Mode SVC_32 ISA ARM Segment kernel

which is an access to the 0xb8000 without the PCI offset required to make it work.

Fixes cc22b4c18540 ("ARM: set vga memory base at run-time")
[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 arch/arm/mach-footbridge/common.c  |    3 +++
 arch/arm/mach-footbridge/dc21285.c |    2 --
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-footbridge/common.c +3 -0
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <video/vga.h>
  
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -198,6 +199,8 @@ void __init footbridge_map_io(void)
 	 */
 	if (footbridge_cfn_mode())
 		iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
+
+	vga_base = PCIMEM_BASE;
 }
 
 void footbridge_restart(char mode, const char *cmd)
arch/arm/mach-footbridge/dc21285.c +0 -2
@@ -18,7 +18,6 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
-#include <video/vga.h>
 
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
@@ -298,7 +297,6 @@ void __init dc21285_preinit(void)
 	int cfn_mode;
 
 	pcibios_min_mem = 0x81000000;
-	vga_base = PCIMEM_BASE;
 
 	mem_size = (unsigned int)high_memory - PAGE_OFFSET;
 	for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
author maintainer
#35 lore raw

PATCH 35/134 ARM: pxa: prevent PXA270 occasional reboot freezes

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sergei Ianovich <[email protected]>

commit ff88b4724fde18056a4c539f7327389aec0f4c2d upstream.

Erratum 71 of PXA270M Processor Family Specification Update (April 19, 2010) explains that watchdog reset time is just 8us insead of 10ms in EMTS.

If SDRAM is not reset, it causes memory bus congestion and the device hangs. We put SDRAM in selfresh mode before watchdog reset, removing potential freezes.

Without this patch PXA270-based ICP DAS LP-8x4x hangs after up to 40 reboots. With this patch it has successfully rebooted 500 times.

---
 arch/arm/mach-pxa/reset.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm/mach-pxa/reset.c +7 -1
@@ -13,6 +13,7 @@
 
 #include <mach/regs-ost.h>
 #include <mach/reset.h>
+#include <mach/smemc.h>
 
 unsigned int reset_status;
 EXPORT_SYMBOL(reset_status);
@@ -80,6 +81,12 @@ static void do_hw_reset(void)
 	OWER = OWER_WME;
 	OSSR = OSSR_M3;
 	OSMR3 = OSCR + 368640;	/* ... in 100 ms */
+	/*
+	 * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71)
+	 * we put SDRAM into self-refresh to prevent that
+	 */
+	while (1)
+		writel_relaxed(MDREFR_SLFRSH, MDREFR);
 }
 
 void pxa_restart(char mode, const char *cmd)
@@ -103,4 +110,3 @@ void pxa_restart(char mode, const char *
 		break;
 	}
 }
-
author maintainer
#36 lore raw

PATCH 36/134 ARM: Orion: Set eth packet size csum offload limit

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: "Arnaud Patard (Rtp)" <[email protected]>

commit 58569aee5a1a5dcc25c34a0a2ed9a377874e6b05 upstream.

The mv643xx ethernet controller limits the packet size for the TX checksum offloading. This patch sets this limits for Kirkwood and Dove which have smaller limits that the default.

As a side note, this patch is an updated version of a patch sent some years
ago: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017320.html
which seems to have been lost.

[bwh: Backported to 3.2: adjust for the extra two parameters of
orion_ge0{0,1}_init()]

[yangyl: Backported to 3.4: Adjust context]
---
 arch/arm/mach-dove/common.c               |    2 +-
 arch/arm/mach-kirkwood/common.c           |    4 ++--
 arch/arm/mach-mv78xx0/common.c            |    6 ++++--
 arch/arm/mach-orion5x/common.c            |    3 ++-
 arch/arm/plat-orion/common.c              |    8 ++++++--
 arch/arm/plat-orion/include/plat/common.h |    6 ++++--
 include/linux/mv643xx_eth.h               |    2 ++
 7 files changed, 21 insertions(+), 10 deletions(-)
arch/arm/mach-dove/common.c +1 -1
@@ -90,7 +90,7 @@ void __init dove_ge00_init(struct mv643x
 {
 	orion_ge00_init(eth_data,
 			DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
-			0, get_tclk());
+			0, get_tclk(), 1600);
 }
 
 /*****************************************************************************
arch/arm/mach-kirkwood/common.c +2 -2
@@ -87,7 +87,7 @@ void __init kirkwood_ge00_init(struct mv
 
 	orion_ge00_init(eth_data,
 			GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
-			IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
+			IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk, 1600);
 }
 
 
@@ -101,7 +101,7 @@ void __init kirkwood_ge01_init(struct mv
 
 	orion_ge01_init(eth_data,
 			GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
-			IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
+			IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk, 1600);
 }
 
 
arch/arm/mach-mv78xx0/common.c +4 -2
@@ -199,7 +199,8 @@ void __init mv78xx0_ge00_init(struct mv6
 {
 	orion_ge00_init(eth_data,
 			GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
-			IRQ_MV78XX0_GE_ERR, get_tclk());
+			IRQ_MV78XX0_GE_ERR, get_tclk(),
+			MV643XX_TX_CSUM_DEFAULT_LIMIT);
 }
 
 
@@ -210,7 +211,8 @@ void __init mv78xx0_ge01_init(struct mv6
 {
 	orion_ge01_init(eth_data,
 			GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
-			NO_IRQ, get_tclk());
+			NO_IRQ, get_tclk(),
+			MV643XX_TX_CSUM_DEFAULT_LIMIT);
 }
 
 
arch/arm/mach-orion5x/common.c +2 -1
@@ -95,7 +95,8 @@ void __init orion5x_eth_init(struct mv64
 {
 	orion_ge00_init(eth_data,
 			ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
-			IRQ_ORION5X_ETH_ERR, orion5x_tclk);
+			IRQ_ORION5X_ETH_ERR, orion5x_tclk,
+			MV643XX_TX_CSUM_DEFAULT_LIMIT);
 }
 
 
arch/arm/plat-orion/common.c +6 -2
@@ -261,10 +261,12 @@ void __init orion_ge00_init(struct mv643
 			    unsigned long mapbase,
 			    unsigned long irq,
 			    unsigned long irq_err,
-			    int tclk)
+			    int tclk,
+			    unsigned int tx_csum_limit)
 {
 	fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
 		       mapbase + 0x2000, SZ_16K - 1, irq_err);
+	orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
 	ge_complete(&orion_ge00_shared_data, tclk,
 		    orion_ge00_resources, irq, &orion_ge00_shared,
 		    eth_data, &orion_ge00);
@@ -314,10 +316,12 @@ void __init orion_ge01_init(struct mv643
 			    unsigned long mapbase,
 			    unsigned long irq,
 			    unsigned long irq_err,
-			    int tclk)
+			    int tclk,
+			    unsigned int tx_csum_limit)
 {
 	fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
 		       mapbase + 0x2000, SZ_16K - 1, irq_err);
+	orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
 	ge_complete(&orion_ge01_shared_data, tclk,
 		    orion_ge01_resources, irq, &orion_ge01_shared,
 		    eth_data, &orion_ge01);
arch/arm/plat-orion/include/plat/common.h +4 -2
@@ -40,13 +40,15 @@ void __init orion_ge00_init(struct mv643
 			    unsigned long mapbase,
 			    unsigned long irq,
 			    unsigned long irq_err,
-			    int tclk);
+			    int tclk,
+			    unsigned int tx_csum_limit);
 
 void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
 			    unsigned long mapbase,
 			    unsigned long irq,
 			    unsigned long irq_err,
-			    int tclk);
+			    int tclk,
+			    unsigned int tx_csum_limit);
 
 void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
 			    unsigned long mapbase,
include/linux/mv643xx_eth.h +2 -0
@@ -15,6 +15,8 @@
 #define MV643XX_ETH_SIZE_REG_4		0x2224
 #define MV643XX_ETH_BASE_ADDR_ENABLE_REG	0x2290
 
+#define MV643XX_TX_CSUM_DEFAULT_LIMIT	0
+
 struct mv643xx_eth_shared_platform_data {
 	struct mbus_dram_target_info	*dram;
 	struct platform_device	*shared_smi;
author maintainer
#37 lore raw

PATCH 37/134 ARM: 7628/1: head.S: map one extra section for the ATAG/DTB area

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nicolas Pitre <[email protected]>

commit 6f16f4998f98e42e3f2dedf663cfb691ff0324af upstream.

We currently use a temporary 1MB section aligned to a 1MB boundary for mapping the provided device tree until the final page table is created. However, if the device tree happens to cross that 1MB boundary, the end of it remains unmapped and the kernel crashes when it attempts to access it. Given no restriction on the location of that DTB, it could end up with only a few bytes mapped at the end of a section.

Solve this issue by mapping two consecutive sections.

[bwh: Backported to 3.2:
- Adjust context
- The mapping is not conditional; drop the 'ne' suffixes]

[yangyl: Backported to 3.4: Adjust context]
---
 arch/arm/kernel/head.S |    3 +++
 1 file changed, 3 insertions(+)
arch/arm/kernel/head.S +3 -0
@@ -254,6 +254,7 @@ __create_page_tables:
 	/*
 	 * Then map boot params address in r2 or the first 1MB (2MB with LPAE)
 	 * of ram if boot params address is not specified.
+	 * We map 2 sections in case the ATAGs/DTB crosses a section boundary.
 	 */
 	mov	r0, r2, lsr #SECTION_SHIFT
 	movs	r0, r0, lsl #SECTION_SHIFT
@@ -262,6 +263,8 @@ __create_page_tables:
 	add	r3, r3, #PAGE_OFFSET
 	add	r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
 	orr	r6, r7, r0
+	str	r6, [r3], #1 << PMD_ORDER
+	add	r6, r6, #1 << SECTION_SHIFT
 	str	r6, [r3]
 
 #ifdef CONFIG_DEBUG_LL
author maintainer
#38 lore raw

PATCH 38/134 ARM: 7791/1: a.out: remove partial a.out support

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Will Deacon <[email protected]>

commit acfdd4b1f7590d02e9bae3b73bdbbc4a31b05d38 upstream.

a.out support on ARM requires that argc, argv and envp are passed in r0-r2 respectively, which requires hacking load_aout_binary to prevent argc being clobbered by the return code. Whilst mainline kernels do set the registers up in start_thread, the aout loader has never carried the hack in mainline.

Initialising the registers in this way actually goes against the libc expectations for ELF binaries, where argc, argv and envp are passed on the stack, with r0 being used to hold a pointer to an exit function for cleaning up after the dynamic linker if required. If the pointer is NULL, then it is ignored. When execing an ELF binary, Linux currently zeroes r0, then sets it to argc and then finally clobbers it with the return value of the execve syscall, so we actually end up with:

	r0 = 0
	stack[0] = argc
	r1 = stack[1] = argv
	r2 = stack[2] = envp

libc treats r1 and r2 as undefined. The clobbering of r0 by sys_execve works for user-spawned threads, but when executing an ELF binary from a kernel thread (via call_usermodehelper), the execve is performed on the ret_from_fork path, which restores r0 from the saved pt_regs, resulting in argc being presented to the C library. This has horrible consequences when the application exits, since we have an exit function registered using argc, resulting in a jump to hyperspace.

This patch solves the problem by removing the partial a.out support from arch/arm/ altogether.

[bwh: Backported to 3.2:
- Adjust context
- Adjust uapi filename]

[yangyl: Backported to 3.4: Adjust context]
---
 arch/arm/Kconfig                  |    1 
 arch/arm/include/asm/a.out-core.h |   45 --------------------------------------
 arch/arm/include/asm/a.out.h      |   34 ----------------------------
 arch/arm/include/asm/processor.h  |    4 ---
 4 files changed, 84 deletions(-)
 delete mode 100644 arch/arm/include/asm/a.out-core.h
 delete mode 100644 arch/arm/include/asm/a.out.h
arch/arm/Kconfig +0 -1
@@ -1,7 +1,6 @@
 config ARM
 	bool
 	default y
-	select HAVE_AOUT
 	select HAVE_DMA_API_DEBUG
 	select HAVE_IDE if PCI || ISA || PCMCIA
 	select HAVE_MEMBLOCK
arch/arm/include/asm/a.out-core.h deleted +0 -45

45 lines not on this page · raw message

arch/arm/include/asm/a.out.h deleted +0 -34
@@ -1,34 +0,0 @@
-#ifndef __ARM_A_OUT_H__
-#define __ARM_A_OUT_H__
-
-#include <linux/personality.h>
-#include <linux/types.h>
-
-struct exec
-{
-  __u32 a_info;		/* Use macros N_MAGIC, etc for access */
-  __u32 a_text;		/* length of text, in bytes */
-  __u32 a_data;		/* length of data, in bytes */
-  __u32 a_bss;		/* length of uninitialized data area for file, in bytes */
-  __u32 a_syms;		/* length of symbol table data in file, in bytes */
-  __u32 a_entry;	/* start address */
-  __u32 a_trsize;	/* length of relocation info for text, in bytes */
-  __u32 a_drsize;	/* length of relocation info for data, in bytes */
-};
-
-/*
- * This is always the same
- */
-#define N_TXTADDR(a)	(0x00008000)
-
-#define N_TRSIZE(a)	((a).a_trsize)
-#define N_DRSIZE(a)	((a).a_drsize)
-#define N_SYMSIZE(a)	((a).a_syms)
-
-#define M_ARM 103
-
-#ifndef LIBRARY_START_TEXT
-#define LIBRARY_START_TEXT	(0x00c00000)
-#endif
-
-#endif /* __A_OUT_GNU_H__ */
arch/arm/include/asm/processor.h +0 -4
@@ -54,7 +54,6 @@ struct thread_struct {
 
 #define start_thread(regs,pc,sp)					\
 ({									\
-	unsigned long *stack = (unsigned long *)sp;			\
 	memset(regs->uregs, 0, sizeof(regs->uregs));			\
 	if (current->personality & ADDR_LIMIT_32BIT)			\
 		regs->ARM_cpsr = USR_MODE;				\
@@ -65,9 +64,6 @@ struct thread_struct {
 	regs->ARM_cpsr |= PSR_ENDSTATE;					\
 	regs->ARM_pc = pc & ~1;		/* pc */			\
 	regs->ARM_sp = sp;		/* sp */			\
-	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
-	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
-	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
 	nommu_start_thread(regs);					\
 })
 
author maintainer
#39 lore raw

PATCH 39/134 ath9k: Fix noisefloor calibration

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sujith Manoharan <[email protected]>

commit 696df78509d1f81b651dd98ecdc1aecab616db6b upstream.

The commits,

"ath9k: Fix regression in channelwidth switch at the same channel" "ath9k: Fix invalid noisefloor reading due to channel update"

attempted to fix noisefloor calibration when a channel switch happens due to HT20/HT40 bandwidth change. This is causing invalid readings resulting in messages like:

"ath: phy16: NF[0] (-45) > MAX (-95), correcting to MAX".

This results in an incorrect noise being used initially for reporting the signal level of received packets, until NF calibration is done and the history buffer is updated via the ANI timer, which happens much later.

When a bandwidth change happens, it is appropriate to reset the internal history data for the channel. Do this correctly in the reset() routine by checking the "chanmode" variable.

Cc Rajkumar Manoharan <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Cc Jianguo Wu <[email protected]>
---
 drivers/net/wireless/ath/ath9k/hw.c   |    3 ++-
 drivers/net/wireless/ath/ath9k/main.c |    7 -------
 2 files changed, 2 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath9k/hw.c +2 -1
@@ -1628,7 +1628,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 	if (caldata &&
 	    (chan->channel != caldata->channel ||
 	     (chan->channelFlags & ~CHANNEL_CW_INT) !=
-	     (caldata->channelFlags & ~CHANNEL_CW_INT))) {
+	     (caldata->channelFlags & ~CHANNEL_CW_INT) ||
+	     chan->chanmode != caldata->chanmode)) {
 		/* Operating channel changed, reset channel calibration data */
 		memset(caldata, 0, sizeof(*caldata));
 		ath9k_init_nfcal_hist_buffer(ah, chan);
drivers/net/wireless/ath/ath9k/main.c +0 -7
@@ -1614,13 +1614,6 @@ static int ath9k_config(struct ieee80211
 		ath_update_survey_stats(sc);
 		spin_unlock_irqrestore(&common->cc_lock, flags);
 
-		/*
-		 * Preserve the current channel values, before updating
-		 * the same channel
-		 */
-		if (ah->curchan && (old_pos == pos))
-			ath9k_hw_getnf(ah, ah->curchan);
-
 		ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
 					  curchan, conf->channel_type);
 
author maintainer
#40 lore raw

PATCH 40/134 ath9k: fill channel mode in caldata

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rajkumar Manoharan <[email protected]>

commit 77d848372875d2e4cbdbf07030f0e08cab5e7f4d upstream.

It is useful to have channel mode in caldata to find out whether operaing channel is in HT40/20 when we are currently on offchannel. It will be used by BTCOEX to enable/disable concurrent tx mechanism later.

---
 drivers/net/wireless/ath/ath9k/calib.c |    1 +
 drivers/net/wireless/ath/ath9k/hw.h    |    1 +
 2 files changed, 2 insertions(+)
drivers/net/wireless/ath/ath9k/calib.c +1 -0
@@ -410,6 +410,7 @@ void ath9k_init_nfcal_hist_buffer(struct
 
 	ah->caldata->channel = chan->channel;
 	ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT;
+	ah->caldata->chanmode = chan->chanmode;
 	h = ah->caldata->nfCalHist;
 	default_nf = ath9k_hw_get_default_nf(ah, chan);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
drivers/net/wireless/ath/ath9k/hw.h +1 -0
@@ -361,6 +361,7 @@ struct ath9k_rtt_hist {
 struct ath9k_hw_cal_data {
 	u16 channel;
 	u32 channelFlags;
+	u32 chanmode;
 	int32_t CalValid;
 	int8_t iCoff;
 	int8_t qCoff;
author maintainer
#41 lore raw

PATCH 41/134 ath9k_hw: Assign default xlna config for AR9485

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sujith Manoharan <[email protected]>

commit 30d5b709da23f4ab9836c7f66d2d2e780a69cf12 upstream.

For AR9485 boards with XLNA, the default gpio config is not set correctly, fix this.

[bwh: Backported to 3.2: adjust context]
Cc Jianguo Wu <[email protected]>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |    8 ++++++--
 drivers/net/wireless/ath/ath9k/ar9003_phy.h    |    2 ++
 2 files changed, 8 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +6 -2
@@ -3592,7 +3592,7 @@ static u16 ar9003_hw_ant_ctrl_chain_get(
 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
 {
 	int chain;
-	u32 regval;
+	u32 regval, value;
 	u32 ant_div_ctl1;
 	static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
 			AR_PHY_SWITCH_CHAIN_0,
@@ -3600,7 +3600,11 @@ static void ar9003_hw_ant_ctrl_apply(str
 			AR_PHY_SWITCH_CHAIN_2,
 	};
 
-	u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+	if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0))
+		ath9k_hw_cfg_output(ah, AR9300_EXT_LNA_CTL_GPIO_AR9485,
+				    AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
+
+	value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
 
 	if (AR_SREV_9462(ah)) {
 		REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
drivers/net/wireless/ath/ath9k/ar9003_phy.h +2 -0
@@ -339,6 +339,8 @@
 
 #define AR_PHY_CCA_NOM_VAL_9330_2GHZ          -118
 
+#define AR9300_EXT_LNA_CTL_GPIO_AR9485 9
+
 /*
  * AGC Field Definitions
  */
author maintainer
#42 lore raw

PATCH 42/134 ath9k_htc: fix signal strength handling issues

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

commit 838f427955dcfd16858b0108ce29029da0d56a4e upstream.

The ath9k commit 2ef167557c0a26c88162ecffb017bfcc51eb7b29 (ath9k: fix signal strength reporting issues) fixed an issue where the reported per-frame signal strength reported to mac80211 was being overwritten with an internal average. The same issue is also present in ath9k_htc.
In addition to preventing the driver from overwriting the value, this commit also ensures that the internal average (which is used for ANI) only tracks beacons of the AP that we're connected to.

[bwh: Backported to 3.2: use compare_ether_addr() instead of
ether_addr_equal(), with opposite sense]

---
 drivers/net/wireless/ath/ath9k/htc.h          |    1 +
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |   18 +++++++++++-------
 2 files changed, 12 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath9k/htc.h +1 -0
@@ -22,6 +22,7 @@
 #include <linux/firmware.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
 #include <net/mac80211.h>
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +11 -7
@@ -1077,15 +1077,19 @@ static bool ath9k_rx_prepare(struct ath9
 
 	last_rssi = priv->rx.last_rssi;
 
-	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-		rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
-						     ATH_RSSI_EP_MULTIPLIER);
+	if (ieee80211_is_beacon(hdr->frame_control) &&
+	    !is_zero_ether_addr(common->curbssid) &&
+	    compare_ether_addr(hdr->addr3, common->curbssid) == 0) {
+		s8 rssi = rxbuf->rxstatus.rs_rssi;
 
-	if (rxbuf->rxstatus.rs_rssi < 0)
-		rxbuf->rxstatus.rs_rssi = 0;
+		if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+			rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
 
-	if (ieee80211_is_beacon(fc))
-		priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
+		if (rssi < 0)
+			rssi = 0;
+
+		priv->ah->stats.avgbrssi = rssi;
+	}
 
 	rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
 	rx_status->band = hw->conf.channel->band;
author maintainer
#43 lore raw

PATCH 43/134 ath9k_hw: fix chain swap setting when setting rx chainmask to 5

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

commit 959f049dfb62b517cbb3dd48ed2fb7d9c713ce16 upstream.

commit 24171dd92096fc370b195f3f6bdc0798855dc3f9 upstream.

Chain swapping should only be enabled when the EEPROM chainmask is set to 5, regardless of what the runtime chainmask is.

[bwh: Backported to 3.2: keep the special case for AR_SREV_9462 here]
Cc Jianguo Wu <[email protected]>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |   27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_phy.c +7 -20
@@ -545,33 +545,20 @@ static void ar9003_hw_init_bb(struct ath
 
 void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
 {
-	switch (rx) {
-	case 0x5:
+	if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
 		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
 			    AR_PHY_SWAP_ALT_CHAIN);
-	case 0x3:
-	case 0x1:
-	case 0x2:
-	case 0x7:
-		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
-		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
-		break;
-	default:
-		break;
-	}
+
+	REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
+	REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
 
 	if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
-		REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
+		tx = 3;
 	else if (AR_SREV_9462(ah))
 		/* xxx only when MCI support is enabled */
-		REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
-	else
-		REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+		tx = 3;
 
-	if (tx == 0x5) {
-		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-			    AR_PHY_SWAP_ALT_CHAIN);
-	}
+	REG_WRITE(ah, AR_SELFGEN_MASK, tx);
 }
 
 /*
author maintainer
#44 lore raw

PATCH 44/134 ath9k_hw: Fix RX gain initvals for AR9485

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sujith Manoharan <[email protected]>

commit a796a1dd5da9645ad77aa687d1a890ecd63ab5a6 upstream.

Populate iniModesRxGain with the correct initvals array for AR9485 v1.1

[bwh: Backported to 3.2:
- Adjust context
- INIT_INI_ARRAY takes additional size and columns arguments]

---
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_hw.c +2 -2
@@ -637,8 +637,8 @@ static void ar9003_rx_gain_table_mode0(s
 				2);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9485Common_wo_xlna_rx_gain_1_1,
-				ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
+			       ar9485_common_rx_gain_1_1,
+			       ARRAY_SIZE(ar9485_common_rx_gain_1_1),
 				2);
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
author maintainer
#45 lore raw

PATCH 45/134 ath9k_hw: Enable hw PLL power save for AR9462

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rajkumar Manoharan <[email protected]>

commit 1680260226a8fd2aab590319da83ad8e610da9bd upstream.

This reduced the power consumption to half in full and network sleep.

[bwh: Backported to 3.2:
- INIT_INI_ARRAY macro requires an explicit size argument
- Remove the now-redundant macro PCIE_PLL_ON_CREQ_DIS_L1_2P0]

---
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |   11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_hw.c +4 -7
@@ -33,9 +33,6 @@
  */
 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
-#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \
-		ar9462_pciephy_pll_on_clkreq_disable_L1_2p0
-
 #define AR9462_BB_CTX_COEFJ(x)	\
 		ar9462_##x##_baseband_core_txfir_coeff_japan_2484
 
@@ -312,13 +309,13 @@ static void ar9003_hw_init_mode_regs(str
 
 		/* Awake -> Sleep Setting */
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-				PCIE_PLL_ON_CREQ_DIS_L1_2P0,
-				ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0),
+				ar9462_pciephy_clkreq_disable_L1_2p0,
+				ARRAY_SIZE(ar9462_pciephy_clkreq_disable_L1_2p0),
 				2);
 		/* Sleep -> Awake Setting */
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				PCIE_PLL_ON_CREQ_DIS_L1_2P0,
-				ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0),
+				ar9462_pciephy_clkreq_disable_L1_2p0,
+				ARRAY_SIZE(ar9462_pciephy_clkreq_disable_L1_2p0),
 				2);
 
 		/* Fast clock modal settings */
author maintainer
#46 lore raw

PATCH 46/134 USB: EHCI: bugfix: urb->hcpriv should not be NULL

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit 2656a9abcf1ec8dd5fee6a75d6997a0f2fa0094e upstream.

This patch (as1632b) fixes a bug in ehci-hcd. The USB core uses urb->hcpriv to determine whether or not an URB is active; host controller drivers are supposed to set this pointer to a non-NULL value when an URB is queued. However ehci-hcd sets it to NULL for isochronous URBs, which defeats the check in usbcore.

In itself this isn't a big deal. But people have recently found that certain sequences of actions will cause the snd-usb-audio driver to reuse URBs without waiting for them to complete. In the absence of proper checking by usbcore, the URBs get added to their endpoint list twice. This leads to list corruption and a system freeze.

The patch makes ehci-hcd assign a meaningful value to urb->hcpriv for isochronous URBs. Improving robustness always helps.

[bwh: Backported to 3.2:
- Adjust context
- Also use usb_pipetype() to work out whether we should call qh_put()]

---
 drivers/usb/host/ehci-q.c     |   16 ++++++----------
 drivers/usb/host/ehci-sched.c |    4 ++--
 2 files changed, 8 insertions(+), 12 deletions(-)
drivers/usb/host/ehci-q.c +6 -10
@@ -264,18 +264,14 @@ ehci_urb_done(struct ehci_hcd *ehci, str
 __releases(ehci->lock)
 __acquires(ehci->lock)
 {
-	if (likely (urb->hcpriv != NULL)) {
-		struct ehci_qh	*qh = (struct ehci_qh *) urb->hcpriv;
-
-		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
-
-			/* ... update hc-wide periodic stats (for usbfs) */
-			ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
-		}
-		qh_put (qh);
+	if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+		/* ... update hc-wide periodic stats */
+		ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
 	}
 
+	if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS)
+		qh_put((struct ehci_qh *) urb->hcpriv);
+
 	if (unlikely(urb->unlinked)) {
 		COUNT(ehci->stats.unlink);
 	} else {
drivers/usb/host/ehci-sched.c +2 -2
@@ -1684,7 +1684,7 @@ itd_link_urb (
 
 	/* don't need that schedule data any more */
 	iso_sched_free (stream, iso_sched);
-	urb->hcpriv = NULL;
+	urb->hcpriv = stream;
 
 	timer_action (ehci, TIMER_IO_WATCHDOG);
 	return enable_periodic(ehci);
@@ -2094,7 +2094,7 @@ sitd_link_urb (
 
 	/* don't need that schedule data any more */
 	iso_sched_free (stream, sched);
-	urb->hcpriv = NULL;
+	urb->hcpriv = stream;
 
 	timer_action (ehci, TIMER_IO_WATCHDOG);
 	return enable_periodic(ehci);
author maintainer
#47 lore raw

PATCH 47/134 USB: Add device quirk for Microsoft VX700 webcam

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andreas Fleig <[email protected]>

commit bc009eca8d539162f7271c2daf0ab5e9e3bb90a0 upstream.

Add device quirk for Microsoft Lifecam VX700 v2.0 webcams. Fixes squeaking noise of the microphone.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/core/quirks.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -38,6 +38,9 @@ static const struct usb_device_id usb_qu
 	/* Creative SB Audigy 2 NX */
 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Microsoft LifeCam-VX700 v2.0 */
+	{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* Logitech Webcam C200 */
 	{ USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME },
 
author maintainer
#48 lore raw

PATCH 48/134 usb: Add quirk detection based on interface information

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Laurent Pinchart <[email protected]>

commit 80da2e0df5af700518611b7d1cc4fc9945bcaf95 upstream.

When a whole class of devices (possibly from a specific vendor, or across multiple vendors) require a quirk, explictly listing all devices in the class make the quirks table unnecessarily large. Fix this by allowing matching devices based on interface information.

---
 drivers/usb/core/driver.c |   38 +++++++++++-------
 drivers/usb/core/hub.c    |   10 +++-
 drivers/usb/core/quirks.c |   93 +++++++++++++++++++++++++++++++++++-----------
 drivers/usb/core/usb.h    |    4 +
 4 files changed, 106 insertions(+), 39 deletions(-)
drivers/usb/core/driver.c +23 -15
@@ -530,22 +530,10 @@ int usb_match_device(struct usb_device *
 }
 
 /* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_interface *interface,
-		     const struct usb_device_id *id)
+int usb_match_one_id_intf(struct usb_device *dev,
+			  struct usb_host_interface *intf,
+			  const struct usb_device_id *id)
 {
-	struct usb_host_interface *intf;
-	struct usb_device *dev;
-
-	/* proc_connectinfo in devio.c may call us with id == NULL. */
-	if (id == NULL)
-		return 0;
-
-	intf = interface->cur_altsetting;
-	dev = interface_to_usbdev(interface);
-
-	if (!usb_match_device(dev, id))
-		return 0;
-
 	/* The interface class, subclass, and protocol should never be
 	 * checked for a match if the device class is Vendor Specific,
 	 * unless the match record specifies the Vendor ID. */
@@ -570,6 +558,26 @@ int usb_match_one_id(struct usb_interfac
 
 	return 1;
 }
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_interface *interface,
+		     const struct usb_device_id *id)
+{
+	struct usb_host_interface *intf;
+	struct usb_device *dev;
+
+	/* proc_connectinfo in devio.c may call us with id == NULL. */
+	if (id == NULL)
+		return 0;
+
+	intf = interface->cur_altsetting;
+	dev = interface_to_usbdev(interface);
+
+	if (!usb_match_device(dev, id))
+		return 0;
+
+	return usb_match_one_id_intf(dev, intf, id);
+}
 EXPORT_SYMBOL_GPL(usb_match_one_id);
 
 /**
drivers/usb/core/hub.c +7 -3
@@ -1916,7 +1916,7 @@ static int usb_enumerate_device(struct u
 		if (err < 0) {
 			dev_err(&udev->dev, "can't read configurations, error %d\n",
 				err);
-			goto fail;
+			return err;
 		}
 	}
 
@@ -1927,8 +1927,12 @@ static int usb_enumerate_device(struct u
 	udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
 
 	err = usb_enumerate_device_otg(udev);
-fail:
-	return err;
+	if (err < 0)
+		return err;
+
+	usb_detect_interface_quirks(udev);
+
+	return 0;
 }
 
 static void set_usb_port_removable(struct usb_device *udev)
drivers/usb/core/quirks.c +72 -21

122 lines not on this page · raw message

drivers/usb/core/usb.h +4 -0
@@ -24,6 +24,7 @@ extern void usb_disable_device(struct us
 extern int usb_deauthorize_device(struct usb_device *);
 extern int usb_authorize_device(struct usb_device *);
 extern void usb_detect_quirks(struct usb_device *udev);
+extern void usb_detect_interface_quirks(struct usb_device *udev);
 extern int usb_remove_device(struct usb_device *udev);
 
 extern int usb_get_device_descriptor(struct usb_device *dev,
@@ -35,6 +36,9 @@ extern int usb_set_configuration(struct
 extern int usb_choose_configuration(struct usb_device *udev);
 
 extern void usb_kick_khubd(struct usb_device *dev);
+extern int usb_match_one_id_intf(struct usb_device *dev,
+				 struct usb_host_interface *intf,
+				 const struct usb_device_id *id);
 extern int usb_match_device(struct usb_device *dev,
 			    const struct usb_device_id *id);
 extern void usb_forced_unbind_intf(struct usb_interface *intf);
author maintainer
#49 lore raw

PATCH 49/134 usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Laurent Pinchart <[email protected]>

commit e387ef5c47ddeaeaa3cbdc54424cdb7a28dae2c0 upstream.

Most Logitech UVC webcams (both early models that don't advertise UVC compatibility and newer UVC-advertised devices) require the RESET_RESUME quirk. Instead of listing each and every model, match the devices based on the UVC interface information.

[bwh: Adjust context to apply after 3.2.38]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/core/quirks.c |   58 ++++++++++++----------------------------------
 1 file changed, 16 insertions(+), 42 deletions(-)
drivers/usb/core/quirks.c +16 -42
@@ -46,53 +46,23 @@ static const struct usb_device_id usb_qu
 	/* Microsoft LifeCam-VX700 v2.0 */
 	{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
 
-	/* Logitech Webcam C200 */
-	{ USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME },
+	/* Logitech Quickcam Fusion */
+	{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
 
-	/* Logitech Webcam C250 */
-	{ USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
+	/* Logitech Quickcam Orbit MP */
+	{ USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME },
 
-	/* Logitech Webcam C300 */
-	{ USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME },
+	/* Logitech Quickcam Pro for Notebook */
+	{ USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME },
 
-	/* Logitech Webcam B/C500 */
-	{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
+	/* Logitech Quickcam Pro 5000 */
+	{ USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME },
 
-	/* Logitech Webcam C600 */
-	{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
+	/* Logitech Quickcam OEM Dell Notebook */
+	{ USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME },
 
-	/* Logitech Webcam Pro 9000 */
-	{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C905 */
-	{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C210 */
-	{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C260 */
-	{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C310 */
-	{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C910 */
-	{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C160 */
-	{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Webcam C270 */
-	{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Quickcam Pro 9000 */
-	{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Quickcam E3500 */
-	{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* Logitech Quickcam Vision Pro */
-	{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
+	/* Logitech Quickcam OEM Cisco VT Camera II */
+	{ USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME },
 
 	/* Logitech Harmony 700-series */
 	{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
@@ -184,6 +154,10 @@ static const struct usb_device_id usb_qu
 };
 
 static const struct usb_device_id usb_interface_quirk_list[] = {
+	/* Logitech UVC Cameras */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0),
+	  .driver_info = USB_QUIRK_RESET_RESUME },
+
 	{ }  /* terminating entry must be last */
 };
 
author maintainer
#50 lore raw

PATCH 50/134 ALSA: usb: Add quirk for 192KHz recording on E-Mu devices

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Calvin Owens <[email protected]>

commit 1539d4f82ad534431cc67935e8e442ccf107d17d upstream.

When recording at 176.2KHz or 192Khz, the device adds a 32-bit length header to the capture packets, which obviously needs to be ignored for recording to work properly.

Userspace expected: L0 L1 L2 R0 R1 R2
...but actually got: R2 L0 L1 L2 R0 R1

Also, the last byte of the length header being interpreted as L0 of the first sample caused spikes every 0.5ms, resulting in a loud 16KHz tone (about the highest 'B' on a piano) being present throughout captures.

Tested at all sample rates on an E-Mu 0404USB, and tested for regressions on a generic USB headset.

[bwh: Backported to 3.2: adjust filenames, context]
Cc Weng Meiling <[email protected]>
---
 sound/usb/card.h     |    1 +
 sound/usb/endpoint.c |    3 ++-
 sound/usb/quirks.c   |    1 +
 3 files changed, 4 insertions(+), 1 deletion(-)
sound/usb/card.h +1 -0
@@ -74,6 +74,7 @@ struct snd_usb_substream {
 	unsigned int fill_max: 1;	/* fill max packet size always */
 	unsigned int txfr_quirk:1;	/* allow sub-frame alignment */
 	unsigned int fmt_type;		/* USB audio format type (1-3) */
+	unsigned int pkt_offset_adj;	/* Bytes to drop from beginning of packets (for non-compliant devices) */
 
 	unsigned int running: 1;	/* running status */
 
sound/usb/endpoint.c +2 -1
@@ -458,7 +458,7 @@ static int retire_capture_urb(struct snd
 	stride = runtime->frame_bits >> 3;
 
 	for (i = 0; i < urb->number_of_packets; i++) {
-		cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+		cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset + subs->pkt_offset_adj;
 		if (urb->iso_frame_desc[i].status && printk_ratelimit()) {
 			snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
 			// continue;
@@ -898,6 +898,7 @@ void snd_usb_init_substream(struct snd_u
 	subs->speed = snd_usb_get_speed(subs->dev);
 	if (subs->speed >= USB_SPEED_HIGH)
 		subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
+	subs->pkt_offset_adj = 0;
 
 	snd_usb_set_pcm_ops(as->pcm, stream);
 
sound/usb/quirks.c +1 -0
@@ -748,6 +748,7 @@ static void set_format_emu_quirk(struct
 		break;
 	}
 	snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
+	subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0;
 }
 
 void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
author maintainer
#51 lore raw

PATCH 51/134 ALSA: aloop: Fix Oops while PM resume

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit edac894389f9c9de2a1368c78809c824b343f3a5 upstream.

snd-aloop driver has no proper PM implementation, thus the PM resume may trigger Oops due to leftover timer instance. This patch adds the missing suspend/resume implementation.

Reported-and-tested-by El boulangero <[email protected]>
[bwh: Backported to 3.2: adjust context]
Cc Weng Meiling <[email protected]>
---
 sound/drivers/aloop.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
sound/drivers/aloop.c +4 -1
@@ -287,12 +287,14 @@ static int loopback_trigger(struct snd_p
 			loopback_active_notify(dpcm);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		spin_lock(&cable->lock);	
 		cable->pause |= stream;
 		spin_unlock(&cable->lock);
 		loopback_timer_stop(dpcm);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		spin_lock(&cable->lock);
 		dpcm->last_jiffies = jiffies;
 		cable->pause &= ~stream;
@@ -552,7 +554,8 @@ static snd_pcm_uframes_t loopback_pointe
 static struct snd_pcm_hardware loopback_pcm_hardware =
 {
 	.info =		(SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
-			 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
+			 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE |
+			 SNDRV_PCM_INFO_RESUME),
 	.formats =	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
 			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
 			 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
author maintainer
#52 lore raw

PATCH 52/134 ALSA: hda - Fix non-snoop page handling

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 9ddf1aeb2134e72275c97a2c6ff2e3eb04f2f27a upstream.

For non-snoop mode, we fiddle with the page attributes of CORB/RIRB and the position buffer, but also the ring buffers. The problem is that the current code blindly assumes that the buffer is contiguous. However, the ring buffers may be SG-buffers, thus a wrong vmapped address is passed there, leading to Oops.

This patch fixes the handling for SG-buffers.

Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=800701

[bwh: Backported to 3.2: open-code snd_pcm_get_dma_buf()]
Cc Weng Meiling <[email protected]>
---
 sound/pci/hda/hda_intel.c |   40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)
sound/pci/hda/hda_intel.c +26 -14
@@ -582,29 +582,43 @@ static char *driver_short_names[] __devi
 #define get_azx_dev(substream) (substream->runtime->private_data)
 
 #ifdef CONFIG_X86
-static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on)
+static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
 {
+	int pages;
+
 	if (azx_snoop(chip))
 		return;
-	if (addr && size) {
-		int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	if (!dmab || !dmab->area || !dmab->bytes)
+		return;
+
+#ifdef CONFIG_SND_DMA_SGBUF
+	if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
+		struct snd_sg_buf *sgbuf = dmab->private_data;
 		if (on)
-			set_memory_wc((unsigned long)addr, pages);
+			set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
 		else
-			set_memory_wb((unsigned long)addr, pages);
+			set_pages_array_wb(sgbuf->page_table, sgbuf->pages);
+		return;
 	}
+#endif
+
+	pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	if (on)
+		set_memory_wc((unsigned long)dmab->area, pages);
+	else
+		set_memory_wb((unsigned long)dmab->area, pages);
 }
 
 static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
 				 bool on)
 {
-	__mark_pages_wc(chip, buf->area, buf->bytes, on);
+	__mark_pages_wc(chip, buf, on);
 }
 static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
-				   struct snd_pcm_runtime *runtime, bool on)
+				   struct snd_pcm_substream *substream, bool on)
 {
 	if (azx_dev->wc_marked != on) {
-		__mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on);
+		__mark_pages_wc(chip, substream->runtime->dma_buffer_p, on);
 		azx_dev->wc_marked = on;
 	}
 }
@@ -615,7 +629,7 @@ static inline void mark_pages_wc(struct
 {
 }
 static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
-				   struct snd_pcm_runtime *runtime, bool on)
+				   struct snd_pcm_substream *substream, bool on)
 {
 }
 #endif
@@ -1772,11 +1786,10 @@ static int azx_pcm_hw_params(struct snd_
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 	struct azx *chip = apcm->chip;
-	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct azx_dev *azx_dev = get_azx_dev(substream);
 	int ret;
 
-	mark_runtime_wc(chip, azx_dev, runtime, false);
+	mark_runtime_wc(chip, azx_dev, substream, false);
 	azx_dev->bufsize = 0;
 	azx_dev->period_bytes = 0;
 	azx_dev->format_val = 0;
@@ -1784,7 +1797,7 @@ static int azx_pcm_hw_params(struct snd_
 					params_buffer_bytes(hw_params));
 	if (ret < 0)
 		return ret;
-	mark_runtime_wc(chip, azx_dev, runtime, true);
+	mark_runtime_wc(chip, azx_dev, substream, true);
 	return ret;
 }
 
@@ -1793,7 +1806,6 @@ static int azx_pcm_hw_free(struct snd_pc
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 	struct azx_dev *azx_dev = get_azx_dev(substream);
 	struct azx *chip = apcm->chip;
-	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
 
 	/* reset BDL address */
@@ -1806,7 +1818,7 @@ static int azx_pcm_hw_free(struct snd_pc
 
 	snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
 
-	mark_runtime_wc(chip, azx_dev, runtime, false);
+	mark_runtime_wc(chip, azx_dev, substream, false);
 	return snd_pcm_lib_free_pages(substream);
 }
 
author maintainer
#53 lore raw

PATCH 53/134 ALSA: hda - Add Conexant CX20751/2/3/4 codec support

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 61d648fb4726f8a89c07cd1904f9c2e11bf26df5 upstream.

These are almost compatible with the older Conexant codecs.

---
 sound/pci/hda/patch_conexant.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/pci/hda/patch_conexant.c +6 -0
@@ -4521,6 +4521,10 @@ static int patch_conexant_auto(struct hd
  */
 
 static const struct hda_codec_preset snd_hda_preset_conexant[] = {
+	{ .id = 0x14f11510, .name = "CX20751/2",
+	  .patch = patch_conexant_auto },
+	{ .id = 0x14f11511, .name = "CX20753/4",
+	  .patch = patch_conexant_auto },
 	{ .id = 0x14f15045, .name = "CX20549 (Venice)",
 	  .patch = patch_cxt5045 },
 	{ .id = 0x14f15047, .name = "CX20551 (Waikiki)",
@@ -4558,6 +4562,8 @@ static const struct hda_codec_preset snd
 	{} /* terminator */
 };
 
+MODULE_ALIAS("snd-hda-codec-id:14f11510");
+MODULE_ALIAS("snd-hda-codec-id:14f11511");
 MODULE_ALIAS("snd-hda-codec-id:14f15045");
 MODULE_ALIAS("snd-hda-codec-id:14f15047");
 MODULE_ALIAS("snd-hda-codec-id:14f15051");
author maintainer
#54 lore raw

PATCH 54/134 Revert "ALSA: hda - Shut up pins at power-saving mode with Conexnat codecs"

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Henningsson <[email protected]>

commit 7ed4165e2d01bdbbb4c1086eb73eadf0f64cbbf0 upstream.

This reverts commit 697c373e34613609cb5450f98b91fefb6e910588.

The original patch was meant to remove clicking, but in fact caused even more clicking instead.

Thanks to c4pp4 for doing most of the work with this bug.

---
 sound/pci/hda/patch_conexant.c |   16 ----------------
 1 file changed, 16 deletions(-)
sound/pci/hda/patch_conexant.c +0 -16
@@ -548,24 +548,12 @@ static int conexant_build_controls(struc
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
-{
-	snd_hda_shutup_pins(codec);
-	return 0;
-}
-#endif
-
 static const struct hda_codec_ops conexant_patch_ops = {
 	.build_controls = conexant_build_controls,
 	.build_pcms = conexant_build_pcms,
 	.init = conexant_init,
 	.free = conexant_free,
 	.set_power_state = conexant_set_power,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	.suspend = conexant_suspend,
-#endif
-	.reboot_notify = snd_hda_shutup_pins,
 };
 
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -4360,10 +4348,6 @@ static const struct hda_codec_ops cx_aut
 	.init = cx_auto_init,
 	.free = conexant_free,
 	.unsol_event = cx_auto_unsol_event,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	.suspend = conexant_suspend,
-#endif
-	.reboot_notify = snd_hda_shutup_pins,
 };
 
 /*
author maintainer
#55 lore raw

PATCH 55/134 ALSA: hda - Always turn on pins for HDMI/DP

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 6169b673618bf0b2518ce413b54925782a603f06 upstream.

We've seen the broken HDMI *video* output on some machines with GM965, and the debugging session pointed that the culprit is the disabled audio output pins. Toggling these pins dynamically on demand caused flickering of HDMI TV.

This patch changes the behavior to keep the pin ON constantly.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=51421

[bwh: Backported to 3.2: adjust context]
Cc Weng Meiling <[email protected]>
---
 sound/pci/hda/patch_hdmi.c |   18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)
sound/pci/hda/patch_hdmi.c +4 -14
@@ -425,9 +425,11 @@ static void hdmi_init_pin(struct hda_cod
 	if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
 		snd_hda_codec_write(codec, pin_nid, 0,
 				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
-	/* Disable pin out until stream is active*/
+	/* Enable pin out: some machines with GM965 gets broken output when
+	 * the pin is disabled or changed while using with HDMI
+	 */
 	snd_hda_codec_write(codec, pin_nid, 0,
-			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
 }
 
 static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
@@ -1152,17 +1154,11 @@ static int generic_hdmi_playback_pcm_pre
 	struct hdmi_spec *spec = codec->spec;
 	int pin_idx = hinfo_to_pin_index(spec, hinfo);
 	hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
-	int pinctl;
 
 	hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
 
 	hdmi_setup_audio_infoframe(codec, pin_idx, substream);
 
-	pinctl = snd_hda_codec_read(codec, pin_nid, 0,
-				    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-	snd_hda_codec_write(codec, pin_nid, 0,
-			    AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT);
-
 	return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
 }
 
@@ -1174,7 +1170,6 @@ static int generic_hdmi_playback_pcm_cle
 	int cvt_idx, pin_idx;
 	struct hdmi_spec_per_cvt *per_cvt;
 	struct hdmi_spec_per_pin *per_pin;
-	int pinctl;
 
 	snd_hda_codec_cleanup_stream(codec, hinfo->nid);
 
@@ -1193,11 +1188,6 @@ static int generic_hdmi_playback_pcm_cle
 			return -EINVAL;
 		per_pin = &spec->pins[pin_idx];
 
-		pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
-					    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-		snd_hda_codec_write(codec, per_pin->pin_nid, 0,
-				    AC_VERB_SET_PIN_WIDGET_CONTROL,
-				    pinctl & ~PIN_OUT);
 		snd_hda_spdif_ctls_unassign(codec, pin_idx);
 	}
 
author maintainer
#56 lore raw

PATCH 56/134 ALSA: hda - Fix internal mic for Lenovo Ideapad U300s

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Henningsson <[email protected]>

commit 18dcd3044e4c4b3ab6341c98e8d0e81e0d58d5e3 upstream.

The internal mic input is phase inverted on one channel. To avoid people in userspace summing the channels together and get zero result, use a separate mixer control for the inverted channel.

[wml: Backported to 3.4:
- Adjust context
- one more enum value CXT_PINCFG_LENOVO_TP410
- Change both invocations of apply_pin_fixup()]

---
 sound/pci/hda/patch_conexant.c |   92 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 15 deletions(-)
sound/pci/hda/patch_conexant.c +77 -15
@@ -141,6 +141,7 @@ struct conexant_spec {
 	unsigned int hp_laptop:1;
 	unsigned int asus:1;
 	unsigned int pin_eapd_ctrls:1;
+	unsigned int fixup_stereo_dmic:1;
 
 	unsigned int adc_switching:1;
 
@@ -4071,9 +4072,9 @@ static int cx_auto_init(struct hda_codec
 
 static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
 			      const char *dir, int cidx,
-			      hda_nid_t nid, int hda_dir, int amp_idx)
+			      hda_nid_t nid, int hda_dir, int amp_idx, int chs)
 {
-	static char name[32];
+	static char name[44];
 	static struct snd_kcontrol_new knew[] = {
 		HDA_CODEC_VOLUME(name, 0, 0, 0),
 		HDA_CODEC_MUTE(name, 0, 0, 0),
@@ -4083,7 +4084,7 @@ static int cx_auto_add_volume_idx(struct
 
 	for (i = 0; i < 2; i++) {
 		struct snd_kcontrol *kctl;
-		knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
+		knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, chs, amp_idx,
 							    hda_dir);
 		knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
 		knew[i].index = cidx;
@@ -4102,7 +4103,7 @@ static int cx_auto_add_volume_idx(struct
 }
 
 #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir)		\
-	cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
+	cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0, 3)
 
 #define cx_auto_add_pb_volume(codec, nid, str, idx)			\
 	cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
@@ -4172,6 +4173,36 @@ static int cx_auto_build_output_controls
 	return 0;
 }
 
+/* Returns zero if this is a normal stereo channel, and non-zero if it should
+   be split in two independent channels.
+   dest_label must be at least 44 characters. */
+static int cx_auto_get_rightch_label(struct hda_codec *codec, const char *label,
+				     char *dest_label, int nid)
+{
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	if (!spec->fixup_stereo_dmic)
+		return 0;
+
+	for (i = 0; i < AUTO_CFG_MAX_INS; i++) {
+		int def_conf;
+		if (spec->autocfg.inputs[i].pin != nid)
+			continue;
+
+		if (spec->autocfg.inputs[i].type != AUTO_PIN_MIC)
+			return 0;
+		def_conf = snd_hda_codec_get_pincfg(codec, nid);
+		if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT)
+			return 0;
+
+		/* Finally found the inverted internal mic! */
+		snprintf(dest_label, 44, "Inverted %s", label);
+		return 1;
+	}
+	return 0;
+}
+
 static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
 				      const char *label, const char *pfx,
 				      int cidx)
@@ -4180,14 +4211,25 @@ static int cx_auto_add_capture_volume(st
 	int i;
 
 	for (i = 0; i < spec->num_adc_nids; i++) {
+		char rightch_label[44];
 		hda_nid_t adc_nid = spec->adc_nids[i];
 		int idx = get_input_connection(codec, adc_nid, nid);
 		if (idx < 0)
 			continue;
 		if (codec->single_adc_amp)
 			idx = 0;
+
+		if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) {
+			/* Make two independent kcontrols for left and right */
+			int err = cx_auto_add_volume_idx(codec, label, pfx,
+						cidx, adc_nid, HDA_INPUT, idx, 1);
+			if (err < 0)
+				return err;
+			return cx_auto_add_volume_idx(codec, rightch_label, pfx,
+							cidx, adc_nid, HDA_INPUT, idx, 2);
+		}
 		return cx_auto_add_volume_idx(codec, label, pfx,
-					      cidx, adc_nid, HDA_INPUT, idx);
+					      cidx, adc_nid, HDA_INPUT, idx, 3);
 	}
 	return 0;
 }
@@ -4200,9 +4242,19 @@ static int cx_auto_add_boost_volume(stru
 	int i, con;
 
 	nid = spec->imux_info[idx].pin;
-	if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
+	if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
+		char rightch_label[44];
+		if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) {
+			int err = cx_auto_add_volume_idx(codec, label, " Boost",
+							 cidx, nid, HDA_INPUT, 0, 1);
+			if (err < 0)
+				return err;
+			return cx_auto_add_volume_idx(codec, rightch_label, " Boost",
+						      cidx, nid, HDA_INPUT, 0, 2);
+		}
 		return cx_auto_add_volume(codec, label, " Boost", cidx,
 					  nid, HDA_INPUT);
+	}
 	con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
 					&mux, false, 0);
 	if (con < 0)
@@ -4365,23 +4417,31 @@ static void apply_pincfg(struct hda_code
 
 }
 
-static void apply_pin_fixup(struct hda_codec *codec,
+enum {
+	CXT_PINCFG_LENOVO_X200,
+	CXT_PINCFG_LENOVO_TP410,
+	CXT_FIXUP_STEREO_DMIC
+};
+
+static void apply_fixup(struct hda_codec *codec,
 			    const struct snd_pci_quirk *quirk,
 			    const struct cxt_pincfg **table)
 {
+	 struct conexant_spec *spec = codec->spec;
+
 	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
-	if (quirk) {
+	if (quirk && table[quirk->value]) {
 		snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n",
 			    quirk->name);
 		apply_pincfg(codec, table[quirk->value]);
 	}
+	if (quirk->value == CXT_FIXUP_STEREO_DMIC) {
+		snd_printdd(KERN_INFO "hda_codec: applying internal mic workaround for %s\n",
+			    quirk->name);
+		spec->fixup_stereo_dmic = 1;
+	}
 }
 
-enum {
-	CXT_PINCFG_LENOVO_X200,
-	CXT_PINCFG_LENOVO_TP410,
-};
-
 /* ThinkPad X200 & co with cxt5051 */
 static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -4402,6 +4462,7 @@ static const struct cxt_pincfg cxt_pincf
 static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
 	[CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
 	[CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
+	[CXT_FIXUP_STEREO_DMIC] = NULL,
 };
 
 static const struct snd_pci_quirk cxt5051_fixups[] = {
@@ -4415,6 +4476,7 @@ static const struct snd_pci_quirk cxt506
 	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
 	{}
 };
 
@@ -4454,11 +4516,11 @@ static int patch_conexant_auto(struct hd
 	case 0x14f15051:
 		add_cx5051_fake_mutes(codec);
 		codec->pin_amp_workaround = 1;
-		apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
+		apply_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
 		break;
 	default:
 		codec->pin_amp_workaround = 1;
-		apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
+		apply_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
 	}
 
 	/* Show mute-led control only on HP laptops
author maintainer
#57 lore raw

PATCH 57/134 USB: serial: add modem-status-change wait queue

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit e5b33dc9d16053c2ae4c2c669cf008829530364b upstream.

Add modem-status-change wait queue to struct usb_serial_port that subdrivers can use to implement TIOCMIWAIT.

Currently subdrivers use a private wait queue which may have been released when waking up after device disconnected.

Note that we're adding a new wait queue rather than reusing the tty-port one as we do not want to get woken up at hangup (yet).

---
 include/linux/usb/serial.h |    2 ++
 1 file changed, 2 insertions(+)
include/linux/usb/serial.h +2 -0
@@ -66,6 +66,7 @@
  *	port.
  * @flags: usb serial port flags
  * @write_wait: a wait_queue_head_t used by the port.
+ * @delta_msr_wait: modem-status-change wait queue
  * @work: work queue entry for the line discipline waking up.
  * @throttled: nonzero if the read urb is inactive to throttle the device
  * @throttle_req: nonzero if the tty wants to throttle us
@@ -112,6 +113,7 @@ struct usb_serial_port {
 
 	unsigned long		flags;
 	wait_queue_head_t	write_wait;
+	wait_queue_head_t	delta_msr_wait;
 	struct work_struct	work;
 	char			throttled;
 	char			throttle_req;
author maintainer
#58 lore raw

PATCH 58/134 USB: ark3116: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 5018860321dc7a9e50a75d5f319bc981298fb5b7 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

---
 drivers/usb/serial/ark3116.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/serial/ark3116.c +6 -4
@@ -68,7 +68,6 @@ static int is_irda(struct usb_serial *se
 }
 
 struct ark3116_private {
-	wait_queue_head_t       delta_msr_wait;
 	struct async_icount	icount;
 	int			irda;	/* 1 for irda device */
 
@@ -148,7 +147,6 @@ static int ark3116_attach(struct usb_ser
 	if (!priv)
 		return -ENOMEM;
 
-	init_waitqueue_head(&priv->delta_msr_wait);
 	mutex_init(&priv->hw_lock);
 	spin_lock_init(&priv->status_lock);
 
@@ -460,10 +458,14 @@ static int ark3116_ioctl(struct tty_stru
 	case TIOCMIWAIT:
 		for (;;) {
 			struct async_icount prev = priv->icount;
-			interruptible_sleep_on(&priv->delta_msr_wait);
+			interruptible_sleep_on(&port->delta_msr_wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			if ((prev.rng == priv->icount.rng) &&
 			    (prev.dsr == priv->icount.dsr) &&
 			    (prev.dcd == priv->icount.dcd) &&
@@ -584,7 +586,7 @@ static void ark3116_update_msr(struct us
 			priv->icount.dcd++;
 		if (msr & UART_MSR_TERI)
 			priv->icount.rng++;
-		wake_up_interruptible(&priv->delta_msr_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 	}
 }
 
author maintainer
#59 lore raw

PATCH 59/134 USB: ch341: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit fa1e11d5231c001c80a479160b5832933c5d35fb upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

---
 drivers/usb/serial/ch341.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/usb/serial/ch341.c +6 -5
@@ -82,7 +82,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
 
 struct ch341_private {
 	spinlock_t lock; /* access lock */
-	wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
 	unsigned baud_rate; /* set baud rate */
 	u8 line_control; /* set line control value RTS/DTR */
 	u8 line_status; /* active status of modem control inputs */
@@ -262,7 +261,6 @@ static int ch341_attach(struct usb_seria
 		return -ENOMEM;
 
 	spin_lock_init(&priv->lock);
-	init_waitqueue_head(&priv->delta_msr_wait);
 	priv->baud_rate = DEFAULT_BAUD_RATE;
 	priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
@@ -299,7 +297,7 @@ static void ch341_dtr_rts(struct usb_ser
 		priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
 	spin_unlock_irqrestore(&priv->lock, flags);
 	ch341_set_handshake(port->serial->dev, priv->line_control);
-	wake_up_interruptible(&priv->delta_msr_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
 }
 
 static void ch341_close(struct usb_serial_port *port)
@@ -502,7 +500,7 @@ static void ch341_read_int_callback(stru
 			tty_kref_put(tty);
 		}
 
-		wake_up_interruptible(&priv->delta_msr_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 	}
 
 exit:
@@ -528,11 +526,14 @@ static int wait_modem_info(struct usb_se
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	while (!multi_change) {
-		interruptible_sleep_on(&priv->delta_msr_wait);
+		interruptible_sleep_on(&port->delta_msr_wait);
 		/* see if a signal did it */
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 
+		if (port->serial->disconnected)
+			return -EIO;
+
 		spin_lock_irqsave(&priv->lock, flags);
 		status = priv->line_status;
 		multi_change = priv->multi_status_change;
author maintainer
#60 lore raw

PATCH 60/134 USB: cypress_m8: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 356050d8b1e526db093e9d2c78daf49d6bf418e3 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

Also remove bogus test for private data pointer being NULL as it is never assigned in the loop.

---
 drivers/usb/serial/cypress_m8.c |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/usb/serial/cypress_m8.c +8 -6
@@ -125,7 +125,6 @@ struct cypress_private {
 	int baud_rate;			   /* stores current baud rate in
 					      integer form */
 	int isthrottled;		   /* if throttled, discard reads */
-	wait_queue_head_t delta_msr_wait;  /* used for TIOCMIWAIT */
 	char prev_status, diff_status;	   /* used for TIOCMIWAIT */
 	/* we pass a pointer to this as the argument sent to
 	   cypress_set_termios old_termios */
@@ -475,7 +474,6 @@ static int generic_startup(struct usb_se
 		kfree(priv);
 		return -ENOMEM;
 	}
-	init_waitqueue_head(&priv->delta_msr_wait);
 
 	/* Skip reset for FRWD device. It is a workaound:
 	   device hangs if it receives SET_CONFIGURE in Configured
@@ -919,12 +917,16 @@ static int cypress_ioctl(struct tty_stru
 	switch (cmd) {
 	/* This code comes from drivers/char/serial.c and ftdi_sio.c */
 	case TIOCMIWAIT:
-		while (priv != NULL) {
-			interruptible_sleep_on(&priv->delta_msr_wait);
+		for (;;) {
+			interruptible_sleep_on(&port->delta_msr_wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
-			else {
+
+			if (port->serial->disconnected)
+				return -EIO;
+
+			{
 				char diff = priv->diff_status;
 				if (diff == 0)
 					return -EIO; /* no change => error */
@@ -1250,7 +1252,7 @@ static void cypress_read_int_callback(st
 	if (priv->current_status != priv->prev_status) {
 		priv->diff_status |= priv->current_status ^
 			priv->prev_status;
-		wake_up_interruptible(&priv->delta_msr_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 		priv->prev_status = priv->current_status;
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
author maintainer
#61 lore raw

PATCH 61/134 USB: ftdi_sio: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 71ccb9b01981fabae27d3c98260ea4613207618e upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

When switching to tty ports, some lifetime assumptions were changed. Specifically, close can now be called before the final tty reference is dropped as part of hangup at device disconnect. Even with the ftdi private-data refcounting this means that the port private data can be freed while a process is sleeping on modem-status changes and thus cannot be relied on to detect disconnects when woken up.

---
 drivers/usb/serial/ftdi_sio.c |   19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/usb/serial/ftdi_sio.c +8 -11
@@ -74,9 +74,7 @@ struct ftdi_private {
 	int flags;		/* some ASYNC_xxxx flags are supported */
 	unsigned long last_dtr_rts;	/* saved modem control outputs */
 	struct async_icount	icount;
-	wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
 	char prev_status;        /* Used for TIOCMIWAIT */
-	bool dev_gone;        /* Used to abort TIOCMIWAIT */
 	char transmit_empty;	/* If transmitter is empty or not */
 	struct usb_serial_port *port;
 	__u16 interface;	/* FT2232C, FT2232H or FT4232H port interface
@@ -1746,10 +1744,8 @@ static int ftdi_sio_port_probe(struct us
 	kref_init(&priv->kref);
 	mutex_init(&priv->cfg_lock);
 	memset(&priv->icount, 0x00, sizeof(priv->icount));
-	init_waitqueue_head(&priv->delta_msr_wait);
 
 	priv->flags = ASYNC_LOW_LATENCY;
-	priv->dev_gone = false;
 
 	if (quirk && quirk->port_probe)
 		quirk->port_probe(priv);
@@ -1908,8 +1904,7 @@ static int ftdi_sio_port_remove(struct u
 
 	dbg("%s", __func__);
 
-	priv->dev_gone = true;
-	wake_up_interruptible_all(&priv->delta_msr_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
 
 	remove_sysfs_attrs(port);
 
@@ -2064,7 +2059,7 @@ static int ftdi_process_packet(struct tt
 		if (diff_status & FTDI_RS0_RLSD)
 			priv->icount.dcd++;
 
-		wake_up_interruptible_all(&priv->delta_msr_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 		priv->prev_status = status;
 	}
 
@@ -2467,11 +2462,15 @@ static int ftdi_ioctl(struct tty_struct
 	 */
 	case TIOCMIWAIT:
 		cprev = priv->icount;
-		while (!priv->dev_gone) {
-			interruptible_sleep_on(&priv->delta_msr_wait);
+		for (;;) {
+			interruptible_sleep_on(&port->delta_msr_wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			cnow = priv->icount;
 			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
 			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
@@ -2481,8 +2480,6 @@ static int ftdi_ioctl(struct tty_struct
 			}
 			cprev = cnow;
 		}
-		return -EIO;
-		break;
 	case TIOCSERGETLSR:
 		return get_lsr_info(port, (struct serial_struct __user *)arg);
 		break;
author maintainer
#62 lore raw

PATCH 62/134 USB: io_edgeport: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 333576255d4cfc53efd056aad438568184b36af6 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

---
 drivers/usb/serial/io_edgeport.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/serial/io_edgeport.c +7 -5
@@ -114,7 +114,6 @@ struct edgeport_port {
 	wait_queue_head_t	wait_chase;		/* for handling sleeping while waiting for chase to finish */
 	wait_queue_head_t	wait_open;		/* for handling sleeping while waiting for open to finish */
 	wait_queue_head_t	wait_command;		/* for handling sleeping while waiting for command to finish */
-	wait_queue_head_t	delta_msr_wait;		/* for handling sleeping while waiting for msr change to happen */
 
 	struct async_icount	icount;
 	struct usb_serial_port	*port;			/* loop back to the owner of this object */
@@ -884,7 +883,6 @@ static int edge_open(struct tty_struct *
 	/* initialize our wait queues */
 	init_waitqueue_head(&edge_port->wait_open);
 	init_waitqueue_head(&edge_port->wait_chase);
-	init_waitqueue_head(&edge_port->delta_msr_wait);
 	init_waitqueue_head(&edge_port->wait_command);
 
 	/* initialize our icount structure */
@@ -1701,13 +1699,17 @@ static int edge_ioctl(struct tty_struct
 		dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
 		cprev = edge_port->icount;
 		while (1) {
-			prepare_to_wait(&edge_port->delta_msr_wait,
+			prepare_to_wait(&port->delta_msr_wait,
 						&wait, TASK_INTERRUPTIBLE);
 			schedule();
-			finish_wait(&edge_port->delta_msr_wait, &wait);
+			finish_wait(&port->delta_msr_wait, &wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			cnow = edge_port->icount;
 			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -2088,7 +2090,7 @@ static void handle_new_msr(struct edgepo
 			icount->dcd++;
 		if (newMsr & EDGEPORT_MSR_DELTA_RI)
 			icount->rng++;
-		wake_up_interruptible(&edge_port->delta_msr_wait);
+		wake_up_interruptible(&edge_port->port->delta_msr_wait);
 	}
 
 	/* Save the new modem status */
author maintainer
#63 lore raw

PATCH 63/134 USB: io_ti: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 7b2459690584f239650a365f3411ba2ec1c6d1e0 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

---
 drivers/usb/serial/io_ti.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/usb/serial/io_ti.c +6 -6
@@ -91,9 +91,6 @@ struct edgeport_port {
 	int close_pending;
 	int lsr_event;
 	struct async_icount	icount;
-	wait_queue_head_t	delta_msr_wait;	/* for handling sleeping while
-						   waiting for msr change to
-						   happen */
 	struct edgeport_serial	*edge_serial;
 	struct usb_serial_port	*port;
 	__u8 bUartMode;		/* Port type, 0: RS232, etc. */
@@ -1549,7 +1546,7 @@ static void handle_new_msr(struct edgepo
 			icount->dcd++;
 		if (msr & EDGEPORT_MSR_DELTA_RI)
 			icount->rng++;
-		wake_up_interruptible(&edge_port->delta_msr_wait);
+		wake_up_interruptible(&edge_port->port->delta_msr_wait);
 	}
 
 	/* Save the new modem status */
@@ -1867,7 +1864,6 @@ static int edge_open(struct tty_struct *
 	dev = port->serial->dev;
 
 	memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
-	init_waitqueue_head(&edge_port->delta_msr_wait);
 
 	/* turn off loopback */
 	status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
@@ -2553,10 +2549,14 @@ static int edge_ioctl(struct tty_struct
 		dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
 		cprev = edge_port->icount;
 		while (1) {
-			interruptible_sleep_on(&edge_port->delta_msr_wait);
+			interruptible_sleep_on(&port->delta_msr_wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			cnow = edge_port->icount;
 			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
author maintainer
#64 lore raw

PATCH 64/134 USB: mct_u232: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit cf1d24443677a0758cfa88ca40f24858b89261c0 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/mct_u232.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/usb/serial/mct_u232.c +7 -6
@@ -126,8 +126,6 @@ struct mct_u232_private {
 	unsigned char	     last_msr;      /* Modem Status Register */
 	unsigned int	     rx_flags;      /* Throttling flags */
 	struct async_icount  icount;
-	wait_queue_head_t    msr_wait;	/* for handling sleeping while waiting
-						for msr change to happen */
 };
 
 #define THROTTLED		0x01
@@ -407,7 +405,6 @@ static int mct_u232_startup(struct usb_s
 	if (!priv)
 		return -ENOMEM;
 	spin_lock_init(&priv->lock);
-	init_waitqueue_head(&priv->msr_wait);
 	usb_set_serial_port_data(serial->port[0], priv);
 
 	init_waitqueue_head(&serial->port[0]->write_wait);
@@ -631,7 +628,7 @@ static void mct_u232_read_int_callback(s
 		tty_kref_put(tty);
 	}
 #endif
-	wake_up_interruptible(&priv->msr_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
 	spin_unlock_irqrestore(&priv->lock, flags);
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -852,13 +849,17 @@ static int  mct_u232_ioctl(struct tty_st
 		cprev = mct_u232_port->icount;
 		spin_unlock_irqrestore(&mct_u232_port->lock, flags);
 		for ( ; ; ) {
-			prepare_to_wait(&mct_u232_port->msr_wait,
+			prepare_to_wait(&port->delta_msr_wait,
 					&wait, TASK_INTERRUPTIBLE);
 			schedule();
-			finish_wait(&mct_u232_port->msr_wait, &wait);
+			finish_wait(&port->delta_msr_wait, &wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			spin_lock_irqsave(&mct_u232_port->lock, flags);
 			cnow = mct_u232_port->icount;
 			spin_unlock_irqrestore(&mct_u232_port->lock, flags);
author maintainer
#65 lore raw

PATCH 65/134 USB: mos7840: fix broken TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit e670c6af12517d08a403487b1122eecf506021cf upstream.

Make sure waiting processes are woken on modem-status changes.

Currently processes are only woken on termios changes regardless of whether the modem status has changed.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/mos7840.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/serial/mos7840.c +3 -2
@@ -453,6 +453,9 @@ static void mos7840_handle_new_msr(struc
 			icount->rng++;
 			smp_wmb();
 		}
+
+		mos7840_port->delta_msr_cond = 1;
+		wake_up_interruptible(&mos7840_port->delta_msr_wait);
 	}
 }
 
@@ -2074,8 +2077,6 @@ static void mos7840_change_port_settings
 			mos7840_port->read_urb_busy = false;
 		}
 	}
-	wake_up(&mos7840_port->delta_msr_wait);
-	mos7840_port->delta_msr_cond = 1;
 	dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x",
 	    mos7840_port->shadowLCR);
 }
author maintainer
#66 lore raw

PATCH 66/134 USB: mos7840: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit a14430db686b8e459e1cf070a6ecf391515c9ab9 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

---
 drivers/usb/serial/mos7840.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/usb/serial/mos7840.c +8 -5
@@ -240,7 +240,6 @@ struct moschip_port {
 	char open;
 	char open_ports;
 	wait_queue_head_t wait_chase;	/* for handling sleeping while waiting for chase to finish */
-	wait_queue_head_t delta_msr_wait;	/* for handling sleeping while waiting for msr change to happen */
 	int delta_msr_cond;
 	struct async_icount icount;
 	struct usb_serial_port *port;	/* loop back to the owner of this object */
@@ -455,7 +454,7 @@ static void mos7840_handle_new_msr(struc
 		}
 
 		mos7840_port->delta_msr_cond = 1;
-		wake_up_interruptible(&mos7840_port->delta_msr_wait);
+		wake_up_interruptible(&port->port->delta_msr_wait);
 	}
 }
 
@@ -1116,7 +1115,6 @@ static int mos7840_open(struct tty_struc
 
 	/* initialize our wait queues */
 	init_waitqueue_head(&mos7840_port->wait_chase);
-	init_waitqueue_head(&mos7840_port->delta_msr_wait);
 
 	/* initialize our icount structure */
 	memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
@@ -2285,13 +2283,18 @@ static int mos7840_ioctl(struct tty_stru
 		while (1) {
 			/* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
 			mos7840_port->delta_msr_cond = 0;
-			wait_event_interruptible(mos7840_port->delta_msr_wait,
-						 (mos7840_port->
+			wait_event_interruptible(port->delta_msr_wait,
+						 (port->serial->disconnected ||
+						  mos7840_port->
 						  delta_msr_cond == 1));
 
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			cnow = mos7840_port->icount;
 			smp_rmb();
 			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
author maintainer
#67 lore raw

PATCH 67/134 USB: oti6858: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 8edfdab37157d2683e51b8be5d3d5697f66a9f7b upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

[bwh: Backported to 3.2: adjust context, indentation]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/oti6858.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/serial/oti6858.c +6 -4
@@ -198,7 +198,6 @@ struct oti6858_private {
 	u8 setup_done;
 	struct delayed_work delayed_setup_work;
 
-	wait_queue_head_t intr_wait;
 	struct usb_serial_port *port;   /* USB port with which associated */
 };
 
@@ -356,7 +355,6 @@ static int oti6858_startup(struct usb_se
 			break;
 
 		spin_lock_init(&priv->lock);
-		init_waitqueue_head(&priv->intr_wait);
 /*		INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
 /*		INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
 		priv->port = port;
@@ -703,11 +701,15 @@ static int wait_modem_info(struct usb_se
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	while (1) {
-		wait_event_interruptible(priv->intr_wait,
+		wait_event_interruptible(port->delta_msr_wait,
+					port->serial->disconnected ||
 					priv->status.pin_state != prev);
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 
+		if (port->serial->disconnected)
+			return -EIO;
+
 		spin_lock_irqsave(&priv->lock, flags);
 		status = priv->status.pin_state & PIN_MASK;
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -819,7 +821,7 @@ static void oti6858_read_int_callback(st
 
 		if (!priv->transient) {
 			if (xs->pin_state != priv->status.pin_state)
-				wake_up_interruptible(&priv->intr_wait);
+				wake_up_interruptible(&port->delta_msr_wait);
 			memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
 		}
 
author maintainer
#68 lore raw

PATCH 68/134 USB: pl2303: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 40509ca982c00c4b70fc00be887509feca0bff15 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

---
 drivers/usb/serial/pl2303.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/usb/serial/pl2303.c +6 -5
@@ -149,7 +149,6 @@ enum pl2303_type {
 
 struct pl2303_private {
 	spinlock_t lock;
-	wait_queue_head_t delta_msr_wait;
 	u8 line_control;
 	u8 line_status;
 	enum pl2303_type type;
@@ -203,7 +202,6 @@ static int pl2303_startup(struct usb_ser
 		if (!priv)
 			goto cleanup;
 		spin_lock_init(&priv->lock);
-		init_waitqueue_head(&priv->delta_msr_wait);
 		priv->type = type;
 		usb_set_serial_port_data(serial->port[i], priv);
 	}
@@ -595,11 +593,14 @@ static int wait_modem_info(struct usb_se
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	while (1) {
-		interruptible_sleep_on(&priv->delta_msr_wait);
+		interruptible_sleep_on(&port->delta_msr_wait);
 		/* see if a signal did it */
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 
+		if (port->serial->disconnected)
+			return -EIO;
+
 		spin_lock_irqsave(&priv->lock, flags);
 		status = priv->line_status;
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -721,7 +722,7 @@ static void pl2303_update_line_status(st
 	spin_unlock_irqrestore(&priv->lock, flags);
 	if (priv->line_status & UART_BREAK_ERROR)
 		usb_serial_handle_break(port);
-	wake_up_interruptible(&priv->delta_msr_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
 
 	tty = tty_port_tty_get(&port->port);
 	if (!tty)
@@ -788,7 +789,7 @@ static void pl2303_process_read_urb(stru
 	line_status = priv->line_status;
 	priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
 	spin_unlock_irqrestore(&priv->lock, flags);
-	wake_up_interruptible(&priv->delta_msr_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
 
 	if (!urb->actual_length)
 		return;
author maintainer
#69 lore raw

PATCH 69/134 USB: spcp8x5: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit d1baabc8006fd238ad8da4d734dc815a8de02362 upstream.

commit dbcea7615d8d7d58f6ff49d2c5568113f70effe9 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

[bwh: Backported to 3.2: adjust context, indentation]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/spcp8x5.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/usb/serial/spcp8x5.c +5 -4
@@ -162,7 +162,6 @@ static struct usb_driver spcp8x5_driver
 struct spcp8x5_private {
 	spinlock_t 	lock;
 	enum spcp8x5_type	type;
-	wait_queue_head_t	delta_msr_wait;
 	u8 			line_control;
 	u8 			line_status;
 };
@@ -196,7 +195,6 @@ static int spcp8x5_startup(struct usb_se
 			goto cleanup;
 
 		spin_lock_init(&priv->lock);
-		init_waitqueue_head(&priv->delta_msr_wait);
 		priv->type = type;
 		usb_set_serial_port_data(serial->port[i] , priv);
 	}
@@ -499,7 +497,7 @@ static void spcp8x5_process_read_urb(str
 	priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
 	spin_unlock_irqrestore(&priv->lock, flags);
 	/* wake up the wait for termios */
-	wake_up_interruptible(&priv->delta_msr_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
 
 	if (!urb->actual_length)
 		return;
@@ -549,12 +547,15 @@ static int spcp8x5_wait_modem_info(struc
 
 	while (1) {
 		/* wake up in bulk read */
-		interruptible_sleep_on(&priv->delta_msr_wait);
+		interruptible_sleep_on(&port->delta_msr_wait);
 
 		/* see if a signal did it */
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 
+		if (port->serial->disconnected)
+			return -EIO;
+
 		spin_lock_irqsave(&priv->lock, flags);
 		status = priv->line_status;
 		spin_unlock_irqrestore(&priv->lock, flags);
author maintainer
#70 lore raw

PATCH 70/134 USB: ssu100: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 43a66b4c417ad15f6d2f632ce67ad195bdf999e8 upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/ssu100.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/serial/ssu100.c +7 -5
@@ -77,7 +77,6 @@ struct ssu100_port_private {
 	spinlock_t status_lock;
 	u8 shadowLSR;
 	u8 shadowMSR;
-	wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
 	struct async_icount icount;
 };
 
@@ -386,8 +385,9 @@ static int wait_modem_info(struct usb_se
 	spin_unlock_irqrestore(&priv->status_lock, flags);
 
 	while (1) {
-		wait_event_interruptible(priv->delta_msr_wait,
-					 ((priv->icount.rng != prev.rng) ||
+		wait_event_interruptible(port->delta_msr_wait,
+					 (port->serial->disconnected ||
+					  (priv->icount.rng != prev.rng) ||
 					  (priv->icount.dsr != prev.dsr) ||
 					  (priv->icount.dcd != prev.dcd) ||
 					  (priv->icount.cts != prev.cts)));
@@ -395,6 +395,9 @@ static int wait_modem_info(struct usb_se
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 
+		if (port->serial->disconnected)
+			return -EIO;
+
 		spin_lock_irqsave(&priv->status_lock, flags);
 		cur = priv->icount;
 		spin_unlock_irqrestore(&priv->status_lock, flags);
@@ -477,7 +480,6 @@ static int ssu100_attach(struct usb_seri
 	}
 
 	spin_lock_init(&priv->status_lock);
-	init_waitqueue_head(&priv->delta_msr_wait);
 	usb_set_serial_port_data(port, priv);
 
 	return ssu100_initdevice(serial->dev);
@@ -563,7 +565,7 @@ static void ssu100_update_msr(struct usb
 			priv->icount.dcd++;
 		if (msr & UART_MSR_TERI)
 			priv->icount.rng++;
-		wake_up_interruptible(&priv->delta_msr_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 	}
 }
 
author maintainer
#71 lore raw

PATCH 71/134 USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 3668b9c17765cacf411effc4fc6e44099ac30800 upstream.

commit fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a upstream.

Use the port wait queue and make sure to check the serial disconnected flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue itself) can be gone when waking up after a disconnect.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/ti_usb_3410_5052.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/serial/ti_usb_3410_5052.c +6 -4
@@ -75,7 +75,6 @@ struct ti_port {
 	int			tp_flags;
 	int			tp_closing_wait;/* in .01 secs */
 	struct async_icount	tp_icount;
-	wait_queue_head_t	tp_msr_wait;	/* wait for msr change */
 	wait_queue_head_t	tp_write_wait;
 	struct ti_device	*tp_tdev;
 	struct usb_serial_port	*tp_port;
@@ -430,7 +429,6 @@ static int ti_startup(struct usb_serial
 		tport->tp_uart_base_addr = (i == 0 ?
 				TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
 		tport->tp_closing_wait = closing_wait;
-		init_waitqueue_head(&tport->tp_msr_wait);
 		init_waitqueue_head(&tport->tp_write_wait);
 		if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
 								GFP_KERNEL)) {
@@ -827,9 +825,13 @@ static int ti_ioctl(struct tty_struct *t
 		dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
 		cprev = tport->tp_icount;
 		while (1) {
-			interruptible_sleep_on(&tport->tp_msr_wait);
+			interruptible_sleep_on(&port->delta_msr_wait);
 			if (signal_pending(current))
 				return -ERESTARTSYS;
+
+			if (port->serial->disconnected)
+				return -EIO;
+
 			cnow = tport->tp_icount;
 			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -1458,7 +1460,7 @@ static void ti_handle_new_msr(struct ti_
 			icount->dcd++;
 		if (msr & TI_MSR_DELTA_RI)
 			icount->rng++;
-		wake_up_interruptible(&tport->tp_msr_wait);
+		wake_up_interruptible(&tport->tp_port->delta_msr_wait);
 		spin_unlock_irqrestore(&tport->tp_lock, flags);
 	}
 
author maintainer
#72 lore raw

PATCH 72/134 USB: serial: fix hang when opening port

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ming Lei <[email protected]>

commit eba0e3c3a0ba7b96f01cbe997680f6a4401a0bfc upstream.

Johan's 'fix use-after-free in TIOCMIWAIT' patchset[1] introduces one bug which can cause kernel hang when opening port.

This patch initialized the 'port->delta_msr_wait' waitqueue head to fix the bug which is introduced in 3.9-rc4.

[1], http://marc.info/?l=linux-usb&m=136368139627876&w=2

---
 drivers/usb/serial/usb-serial.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/usb-serial.c +1 -0
@@ -908,6 +908,7 @@ int usb_serial_probe(struct usb_interfac
 		port->port.ops = &serial_port_ops;
 		port->serial = serial;
 		spin_lock_init(&port->lock);
+		init_waitqueue_head(&port->delta_msr_wait);
 		/* Keep this for private driver use for the moment but
 		   should probably go away */
 		INIT_WORK(&port->work, usb_serial_port_work);
author maintainer
#73 lore raw

PATCH 73/134 USB: ftdi_sio: enable two UART ports on ST Microconnect Lite

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Adrian Thomasset <[email protected]>

commit 71d9a2b95fc9c9474d46d764336efd7a5a805555 upstream.

The FT4232H used in the ST Micro Connect Lite has four hi-speed UART ports. The first two ports are reserved for the JTAG interface.

We enable by default ports 2 and 3 as UARTs (where port 2 is a conventional RS-232 UART)

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/ftdi_sio.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
drivers/usb/serial/ftdi_sio.c +11 -7
@@ -1855,8 +1855,11 @@ static int ftdi_8u2232c_probe(struct usb
 }
 
 /*
- * First and second port on STMCLiteadaptors is reserved for JTAG interface
- * and the forth port for pio
+ * First two ports on JTAG adaptors using an FT4232 such as STMicroelectronics's
+ * ST Micro Connect Lite are reserved for JTAG or other non-UART interfaces and
+ * can be accessed from userspace.
+ * The next two ports are enabled as UARTs by default, where port 2 is
+ * a conventional RS-232 UART.
  */
 static int ftdi_stmclite_probe(struct usb_serial *serial)
 {
@@ -1865,12 +1868,13 @@ static int ftdi_stmclite_probe(struct us
 
 	dbg("%s", __func__);
 
-	if (interface == udev->actconfig->interface[2])
-		return 0;
+	if (interface == udev->actconfig->interface[0] ||
+	    interface == udev->actconfig->interface[1]) {
+		dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n");
+		return -ENODEV;
+	}
 
-	dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n");
-
-	return -ENODEV;
+	return 0;
 }
 
 /*
author maintainer
#74 lore raw

PATCH 74/134 usb: dwc3: gadget: free trb pool only from epnum 2

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: George Cherian <[email protected]>

commit 5bf8fae33d14cc5c3c53a926f9079f92c8b082b0 upstream.

we never allocate a TRB pool for physical endpoints 0 and 1 so trying to free it (a invalid TRB pool pointer) will lead us in a warning while removing dwc3.ko module.

In order to fix the situation, all we have to do is skip dwc3_free_trb_pool() for physical endpoints 0 and 1 just as we while deleting endpoints from the endpoints list.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/dwc3/gadget.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/usb/dwc3/gadget.c +12 -3
@@ -1483,10 +1483,19 @@ static void dwc3_gadget_free_endpoints(s
 
 	for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
 		dep = dwc->eps[epnum];
-		dwc3_free_trb_pool(dep);
-
-		if (epnum != 0 && epnum != 1)
+		/*
+		 * Physical endpoints 0 and 1 are special; they form the
+		 * bi-directional USB endpoint 0.
+		 *
+		 * For those two physical endpoints, we don't allocate a TRB
+		 * pool nor do we add them the endpoints list. Due to that, we
+		 * shouldn't do these two operations otherwise we would end up
+		 * with all sorts of bugs when removing dwc3.ko.
+		 */
+		if (epnum != 0 && epnum != 1) {
+			dwc3_free_trb_pool(dep);
 			list_del(&dep->endpoint.ep_list);
+		}
 
 		kfree(dep);
 	}
author maintainer
#75 lore raw

PATCH 75/134 USB: serial: Add Option GTM681W to qcserial device table.

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Richard Weinberger <[email protected]>

commit 8a2f132a01c2dd4c3905fa560f92019761ed72b1 upstream.

The Option GTM681W uses a qualcomm chip and can be served by the qcserial device driver.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/qcserial.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/qcserial.c +1 -0
@@ -121,6 +121,7 @@ static const struct usb_device_id id_tab
 	{USB_DEVICE(0x1199, 0x9019)},	/* Sierra Wireless Gobi 3000 Modem device */
 	{USB_DEVICE(0x12D1, 0x14F0)},	/* Sony Gobi 3000 QDL */
 	{USB_DEVICE(0x12D1, 0x14F1)},	/* Sony Gobi 3000 Composite */
+	{USB_DEVICE(0x0AF0, 0x8120)},	/* Option GTM681W */
 	{ }				/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
author maintainer
#76 lore raw

PATCH 76/134 USB: spcp8x5: fix device initialisation at open

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 5e4211f1c47560c36a8b3d4544dfd866dcf7ccd0 upstream.

Do not use uninitialised termios data to determine when to configure the device at open.

[bwh: Backported to 3.2: tty_struct::termios is a pointer, not a struct]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/spcp8x5.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/usb/serial/spcp8x5.c +4 -6
@@ -337,7 +337,6 @@ static void spcp8x5_set_termios(struct t
 	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 	unsigned int cflag = tty->termios->c_cflag;
-	unsigned int old_cflag = old_termios->c_cflag;
 	unsigned short uartdata;
 	unsigned char buf[2] = {0, 0};
 	int baud;
@@ -346,15 +345,15 @@ static void spcp8x5_set_termios(struct t
 
 
 	/* check that they really want us to change something */
-	if (!tty_termios_hw_change(tty->termios, old_termios))
+	if (old_termios && !tty_termios_hw_change(tty->termios, old_termios))
 		return;
 
 	/* set DTR/RTS active */
 	spin_lock_irqsave(&priv->lock, flags);
 	control = priv->line_control;
-	if ((old_cflag & CBAUD) == B0) {
+	if (old_termios && (old_termios->c_cflag & CBAUD) == B0) {
 		priv->line_control |= MCR_DTR;
-		if (!(old_cflag & CRTSCTS))
+		if (!(old_termios->c_cflag & CRTSCTS))
 			priv->line_control |= MCR_RTS;
 	}
 	if (control != priv->line_control) {
@@ -442,7 +441,6 @@ static void spcp8x5_set_termios(struct t
  * status of the device. */
 static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
 	int ret;
@@ -465,7 +463,7 @@ static int spcp8x5_open(struct tty_struc
 
 	/* Setup termios */
 	if (tty)
-		spcp8x5_set_termios(tty, port, &tmp_termios);
+		spcp8x5_set_termios(tty, port, NULL);
 
 	spcp8x5_get_msr(serial->dev, &status, priv->type);
 
author maintainer
#77 lore raw

PATCH 77/134 USB: pl2303: fix device initialisation at open

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 2d8f4447b58bba5f8cb895c07690434c02307eaf upstream.

Do not use uninitialised termios data to determine when to configure the device at open.

This also prevents stack data from leaking to userspace in the OOM error path.

[bwh: Backported to 3.2: tty_struct::termios is a pointer, not a struct]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/pl2303.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/usb/serial/pl2303.c +5 -5
@@ -269,7 +269,7 @@ static void pl2303_set_termios(struct tt
 	   serial settings even to the same values as before. Thus
 	   we actually need to filter in this specific case */
 
-	if (!tty_termios_hw_change(tty->termios, old_termios))
+	if (old_termios && !tty_termios_hw_change(tty->termios, old_termios))
 		return;
 
 	cflag = tty->termios->c_cflag;
@@ -278,7 +278,8 @@ static void pl2303_set_termios(struct tt
 	if (!buf) {
 		dev_err(&port->dev, "%s - out of memory.\n", __func__);
 		/* Report back no change occurred */
-		*tty->termios = *old_termios;
+		if (old_termios)
+			*tty->termios = *old_termios;
 		return;
 	}
 
@@ -416,7 +417,7 @@ static void pl2303_set_termios(struct tt
 	control = priv->line_control;
 	if ((cflag & CBAUD) == B0)
 		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
-	else if ((old_termios->c_cflag & CBAUD) == B0)
+	else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
 		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
 	if (control != priv->line_control) {
 		control = priv->line_control;
@@ -477,7 +478,6 @@ static void pl2303_close(struct usb_seri
 
 static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	int result;
@@ -495,7 +495,7 @@ static int pl2303_open(struct tty_struct
 
 	/* Setup termios */
 	if (tty)
-		pl2303_set_termios(tty, port, &tmp_termios);
+		pl2303_set_termios(tty, port, NULL);
 
 	dbg("%s - submitting interrupt urb", __func__);
 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
author maintainer
#78 lore raw

PATCH 78/134 USB: mos7840: fix memory leak in open

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 5f8a2e68b679b41cc8e9b642f2f5aa45dd678641 upstream.

Allocated urbs and buffers were never freed on errors in open.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/mos7840.c |   26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)
drivers/usb/serial/mos7840.c +17 -9
@@ -923,20 +923,20 @@ static int mos7840_open(struct tty_struc
 	status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
 	if (status < 0) {
 		dbg("Reading Spreg failed");
-		return -1;
+		goto err;
 	}
 	Data |= 0x80;
 	status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 	if (status < 0) {
 		dbg("writing Spreg failed");
-		return -1;
+		goto err;
 	}
 
 	Data &= ~0x80;
 	status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 	if (status < 0) {
 		dbg("writing Spreg failed");
-		return -1;
+		goto err;
 	}
 	/* End of block to be checked */
 
@@ -945,7 +945,7 @@ static int mos7840_open(struct tty_struc
 									&Data);
 	if (status < 0) {
 		dbg("Reading Controlreg failed");
-		return -1;
+		goto err;
 	}
 	Data |= 0x08;		/* Driver done bit */
 	Data |= 0x20;		/* rx_disable */
@@ -953,7 +953,7 @@ static int mos7840_open(struct tty_struc
 				mos7840_port->ControlRegOffset, Data);
 	if (status < 0) {
 		dbg("writing Controlreg failed");
-		return -1;
+		goto err;
 	}
 	/* do register settings here */
 	/* Set all regs to the device default values. */
@@ -964,21 +964,21 @@ static int mos7840_open(struct tty_struc
 	status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 	if (status < 0) {
 		dbg("disabling interrupts failed");
-		return -1;
+		goto err;
 	}
 	/* Set FIFO_CONTROL_REGISTER to the default value */
 	Data = 0x00;
 	status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
 	if (status < 0) {
 		dbg("Writing FIFO_CONTROL_REGISTER  failed");
-		return -1;
+		goto err;
 	}
 
 	Data = 0xcf;
 	status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
 	if (status < 0) {
 		dbg("Writing FIFO_CONTROL_REGISTER  failed");
-		return -1;
+		goto err;
 	}
 
 	Data = 0x03;
@@ -1134,7 +1134,15 @@ static int mos7840_open(struct tty_struc
 	dbg ("%s leave", __func__);
 
 	return 0;
-
+err:
+	for (j = 0; j < NUM_URBS; ++j) {
+		urb = mos7840_port->write_urb_pool[j];
+		if (!urb)
+			continue;
+		kfree(urb->transfer_buffer);
+		usb_free_urb(urb);
+	}
+	return status;
 }
 
 /*****************************************************************************
author maintainer
#79 lore raw

PATCH 79/134 USB: mos7840: fix race in register handling

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit d8a083cc746664916d9d36ed9e4d08a29525f245 upstream.

Fix race in mos7840_get_reg which unconditionally manipulated the control urb (which may already be in use) by adding a control-urb busy flag.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/mos7840.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/usb/serial/mos7840.c +16 -2
@@ -185,6 +185,10 @@
 #define URB_TRANSFER_BUFFER_SIZE        32	/* URB Size  */
 
 
+enum mos7840_flag {
+	MOS7840_FLAG_CTRL_BUSY,
+};
+
 static const struct usb_device_id moschip_port_id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
@@ -258,6 +262,8 @@ struct moschip_port {
 	struct urb *write_urb_pool[NUM_URBS];
 	char busy[NUM_URBS];
 	bool read_urb_busy;
+
+	unsigned long flags;
 };
 
 
@@ -519,11 +525,11 @@ static void mos7840_control_callback(str
 		/* this urb is terminated, clean up */
 		dbg("%s - urb shutting down with status: %d", __func__,
 		    status);
-		return;
+		goto out;
 	default:
 		dbg("%s - nonzero urb status received: %d", __func__,
 		    status);
-		return;
+		goto out;
 	}
 
 	dbg("%s urb buffer size is %d", __func__, urb->actual_length);
@@ -536,6 +542,8 @@ static void mos7840_control_callback(str
 		mos7840_handle_new_msr(mos7840_port, regval);
 	else if (mos7840_port->MsrLsr == 1)
 		mos7840_handle_new_lsr(mos7840_port, regval);
+out:
+	clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mos7840_port->flags);
 }
 
 static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
@@ -546,6 +554,9 @@ static int mos7840_get_reg(struct moschi
 	unsigned char *buffer = mcs->ctrl_buf;
 	int ret;
 
+	if (test_and_set_bit_lock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags))
+		return -EBUSY;
+
 	dr->bRequestType = MCS_RD_RTYPE;
 	dr->bRequest = MCS_RDREQ;
 	dr->wValue = cpu_to_le16(Wval);	/* 0 */
@@ -557,6 +568,9 @@ static int mos7840_get_reg(struct moschi
 			     mos7840_control_callback, mcs);
 	mcs->control_urb->transfer_buffer_length = 2;
 	ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
+	if (ret)
+		clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags);
+
 	return ret;
 }
 
author maintainer
#80 lore raw

PATCH 80/134 USB: adutux: fix big-endian device-type reporting

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit d482b9d558602a9cacab063b1c8779f9b5214da7 upstream.

Make sure the reported device-type on big-endian machines is the same as on little-endian ones.

---
 drivers/usb/misc/adutux.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/misc/adutux.c +1 -1
@@ -829,7 +829,7 @@ static int adu_probe(struct usb_interfac
 
 	/* let the user know what node this device is now attached to */
 	dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n",
-		 udev->descriptor.idProduct, dev->serial_number,
+		 le16_to_cpu(udev->descriptor.idProduct), dev->serial_number,
 		 (dev->minor - ADU_MINOR_BASE));
 exit:
 	dbg(2," %s : leave, return value %p (dev)", __func__, dev);
author maintainer
#81 lore raw

PATCH 81/134 USB: ti_usb_3410_5052: fix big-endian firmware handling

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit e877dd2f2581628b7119df707d4cf03d940cff49 upstream.

Fix endianess bugs in firmware handling introduced by commits cb7a7c6a ("ti_usb_3410_5052: add Multi-Tech modem support") and 05a3d905 ("ti_usb_3410_5052: support alternate firmware") which made the driver use the wrong firmware for certain devices on big-endian machines.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/serial/ti_usb_3410_5052.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/usb/serial/ti_usb_3410_5052.c +5 -4
@@ -1687,12 +1687,13 @@ static int ti_download_firmware(struct t
 
 	dbg("%s\n", __func__);
 	/* try ID specific firmware first, then try generic firmware */
-	sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
-	    dev->descriptor.idProduct);
+	sprintf(buf, "ti_usb-v%04x-p%04x.fw",
+			le16_to_cpu(dev->descriptor.idVendor),
+			le16_to_cpu(dev->descriptor.idProduct));
 	if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
 		buf[0] = '\0';
-		if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
-			switch (dev->descriptor.idProduct) {
+		if (le16_to_cpu(dev->descriptor.idVendor) == MTS_VENDOR_ID) {
+			switch (le16_to_cpu(dev->descriptor.idProduct)) {
 			case MTS_CDMA_PRODUCT_ID:
 				strcpy(buf, "mts_cdma.fw");
 				break;
author maintainer
#82 lore raw

PATCH 82/134 USB: keyspan: fix null-deref at disconnect and release

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit ff8a43c10f1440f07a5faca0c1556921259f7f76 upstream.

Make sure to fail properly if the device is not accepted during attach in order to avoid null-pointer derefs (of missing interface private data) at disconnect or release.

---
 drivers/usb/serial/keyspan.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/keyspan.c +1 -1
@@ -2486,7 +2486,7 @@ static int keyspan_startup(struct usb_se
 	if (d_details == NULL) {
 		dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
 		    __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
-		return 1;
+		return -ENODEV;
 	}
 
 	/* Setup private data for serial driver */
author maintainer
#83 lore raw

PATCH 83/134 USB: OHCI: Allow runtime PM without system sleep

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit 69820e01aa756b8d228143d997f71523c1e97984 upstream.

Since ohci-hcd supports runtime PM, the .pm field in its pci_driver structure should be protected by CONFIG_PM rather than CONFIG_PM_SLEEP.

Without this change, OHCI controllers won't do runtime suspend if system suspend or hibernation isn't enabled.

---
 drivers/usb/host/ohci-pci.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/ohci-pci.c +1 -1
@@ -414,7 +414,7 @@ static struct pci_driver ohci_pci_driver
 	.remove =	usb_hcd_pci_remove,
 	.shutdown =	usb_hcd_pci_shutdown,
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 	.driver =	{
 		.pm =	&usb_hcd_pci_pm_ops
 	},
author maintainer
#84 lore raw

PATCH 84/134 USB: fix build error when CONFIG_PM_SLEEP isnt enabled

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit 9d8924297cd9c256c23c02abae40202563452453 upstream.

This patch fixes a build error that occurs when CONFIG_PM is enabled and CONFIG_PM_SLEEP isn't:

Quoted 1 line
Quoted 1 line

drivers/usb/host/ohci-pci.c:294:10: error: 'usb_hcd_pci_pm_ops' undeclared here (not in a function)

      .pm = &usb_hcd_pci_pm_ops

Since the usb_hcd_pci_pm_ops structure is defined and used when CONFIG_PM is enabled, its declaration should not be protected by CONFIG_PM_SLEEP.

---
 include/linux/usb/hcd.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/usb/hcd.h +1 -1
@@ -393,7 +393,7 @@ extern int usb_hcd_pci_probe(struct pci_
 extern void usb_hcd_pci_remove(struct pci_dev *dev);
 extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
 #endif
 #endif /* CONFIG_PCI */
author maintainer
#85 lore raw

PATCH 85/134 USB: fix PM config symbol in uhci-hcd, ehci-hcd, and xhci-hcd

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit f875fdbf344b9fde207f66b392c40845dd7e5aa6 upstream.

Since uhci-hcd, ehci-hcd, and xhci-hcd support runtime PM, the .pm field in their pci_driver structures should be protected by CONFIG_PM rather than CONFIG_PM_SLEEP. The corresponding change has already been made for ohci-hcd.

Without this change, controllers won't do runtime suspend if system suspend or hibernation isn't enabled.

---
 drivers/usb/host/ehci-pci.c |    2 +-
 drivers/usb/host/uhci-pci.c |    2 +-
 drivers/usb/host/xhci-pci.c |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/usb/host/ehci-pci.c +1 -1
@@ -549,7 +549,7 @@ static struct pci_driver ehci_pci_driver
 	.remove =	usb_hcd_pci_remove,
 	.shutdown = 	usb_hcd_pci_shutdown,
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 	.driver =	{
 		.pm =	&usb_hcd_pci_pm_ops
 	},
drivers/usb/host/uhci-pci.c +1 -1
@@ -293,7 +293,7 @@ static struct pci_driver uhci_pci_driver
 	.remove =	usb_hcd_pci_remove,
 	.shutdown =	uhci_shutdown,
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 	.driver =	{
 		.pm =	&usb_hcd_pci_pm_ops
 	},
drivers/usb/host/xhci-pci.c +1 -1
@@ -335,7 +335,7 @@ static struct pci_driver xhci_pci_driver
 	/* suspend and resume implemented later */
 
 	.shutdown = 	usb_hcd_pci_shutdown,
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 	.driver = {
 		.pm = &usb_hcd_pci_pm_ops
 	},
author maintainer
#86 lore raw

PATCH 86/134 usb: Disable USB 2.0 Link PM before device reset.

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sarah Sharp <[email protected]>

commit dcc01c0864823f91c3bf3ffca6613e2351702b87 upstream.

Before the USB core resets a device, we need to disable the L1 timeout for the roothub, if USB 2.0 Link PM is enabled. Otherwise the port may transition into L1 in between descriptor fetches, before we know if the USB device descriptors changed. LPM will be re-enabled after the full device descriptors are fetched, and we can confirm the device still supports USB 2.0 LPM after the reset.

We don't need to wait for the USB device to exit L1 before resetting the device, since the xHCI roothub port diagrams show a transition to the Reset state from any of the Ux states (see Figure 34 in the 2012-08-14 xHCI specification update).

This patch should be backported to kernels as old as 3.2, that contain the commit 65580b4321eb36f16ae8b5987bfa1bb948fc5112 "xHCI: set USB2 hardware LPM". That was the first commit to enable USB 2.0 hardware-driven Link Power Management.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/core/hub.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/core/hub.c +6 -0
@@ -4139,6 +4139,12 @@ static int usb_reset_and_verify_device(s
 	}
 	parent_hub = hdev_to_hub(parent_hdev);
 
+	/* Disable USB2 hardware LPM.
+	 * It will be re-enabled by the enumeration process.
+	 */
+	if (udev->usb2_hw_lpm_enabled == 1)
+		usb_set_usb2_hardware_lpm(udev, 0);
+
 	set_bit(port1, parent_hub->busy_bits);
 	for (i = 0; i < SET_CONFIG_TRIES; ++i) {
 
author maintainer
#87 lore raw

PATCH 87/134 usb: dwc3: pci: add support for BayTrail

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Heikki Krogerus <[email protected]>

commit b62cd96de3161dfb125a769030eec35a4cab3d3a upstream.

Add PCI id for Intel BayTrail.

---
 drivers/usb/dwc3/dwc3-pci.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/dwc3/dwc3-pci.c +2 -0
@@ -47,6 +47,7 @@
 /* FIXME define these in <linux/pci_ids.h> */
 #define PCI_VENDOR_ID_SYNOPSYS		0x16c3
 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
+#define PCI_DEVICE_ID_INTEL_BYT		0x0f37
 
 struct dwc3_pci {
 	struct device		*dev;
@@ -155,6 +156,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_
 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
 	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
 	{  }	/* Terminating Entry */
 };
 MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
author maintainer
#88 lore raw

PATCH 88/134 usb: dwc3: add support for Merrifield

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Cohen <[email protected]>

commit 85601f8cf67c56a561a6dd5e130e65fdc179047d upstream.

Add PCI id for Intel Merrifield

---
 drivers/usb/dwc3/dwc3-pci.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/dwc3/dwc3-pci.c +2 -0
@@ -48,6 +48,7 @@
 #define PCI_VENDOR_ID_SYNOPSYS		0x16c3
 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
 #define PCI_DEVICE_ID_INTEL_BYT		0x0f37
+#define PCI_DEVICE_ID_INTEL_MRFLD	0x119e
 
 struct dwc3_pci {
 	struct device		*dev;
@@ -157,6 +158,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_
 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
 	},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
 	{  }	/* Terminating Entry */
 };
 MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
author maintainer
#89 lore raw

PATCH 89/134 usb: wusbcore: set the RPIPE wMaxPacketSize value correctly

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Pugliese <[email protected]>

commit 7b6bc07ab554e929c85d51b3d5b26cf7f12c6a3b upstream.

For isochronous endpoints, set the RPIPE wMaxPacketSize value using wOverTheAirPacketSize from the endpoint companion descriptor instead of wMaxPacketSize from the normal endpoint descriptor.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/wusbcore/wa-rpipe.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/usb/wusbcore/wa-rpipe.c +4 -1
@@ -332,7 +332,10 @@ static int rpipe_aim(struct wa_rpipe *rp
 	/* FIXME: compute so seg_size > ep->maxpktsize */
 	rpipe->descr.wBlocks = cpu_to_le16(16);		/* given */
 	/* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */
-	rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize);
+	if (usb_endpoint_xfer_isoc(&ep->desc))
+		rpipe->descr.wMaxPacketSize = epcd->wOverTheAirPacketSize;
+	else
+		rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize;
 	rpipe->descr.bHSHubAddress = 0;			/* reserved: zero */
 	rpipe->descr.bHSHubPort = wusb_port_no_to_idx(urb->dev->portnum);
 	/* FIXME: use maximum speed as supported or recommended by device */
author maintainer
#90 lore raw

PATCH 90/134 usb: wusbcore: change WA_SEGS_MAX to a legal value

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Pugliese <[email protected]>

commit f74b75e7f920c700636cccca669c7d16d12e9202 upstream.

change WA_SEGS_MAX to a number that is legal according to the WUSB spec.

[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/wusbcore/wa-xfer.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/wusbcore/wa-xfer.c +3 -2
@@ -90,7 +90,8 @@
 #include "wusbhc.h"
 
 enum {
-	WA_SEGS_MAX = 255,
+	/* [WUSB] section 8.3.3 allocates 7 bits for the segment index. */
+	WA_SEGS_MAX = 128,
 };
 
 enum wa_seg_status {
@@ -444,7 +445,7 @@ static ssize_t __wa_xfer_setup_sizes(str
 	xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
 	xfer->segs = (urb->transfer_buffer_length + xfer->seg_size - 1)
 		/ xfer->seg_size;
-	if (xfer->segs >= WA_SEGS_MAX) {
+	if (xfer->segs > WA_SEGS_MAX) {
 		dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n",
 			(int)(urb->transfer_buffer_length / xfer->seg_size),
 			WA_SEGS_MAX);
author maintainer
#91 lore raw

PATCH 91/134 USB: ftdi_sio: fixed handling of unsupported CSIZE setting

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Colin Leitner <[email protected]>

commit 8704211f65a2106ba01b6ac9727cdaf9ca11594c upstream.

FTDI UARTs support only 7 or 8 data bits. Until now the ftdi_sio driver would only report this limitation for CS6 to dmesg and fail to reflect this fact to tcgetattr.

This patch reverts the unsupported CSIZE setting and reports the fact with less severance to dmesg for both CS5 and CS6.

To test the patch it's sufficient to call

stty -F /dev/ttyUSB0 cs5

which will succeed without the patch and report an error with the patch applied.

As an additional fix this patch ensures that the control request will always include a data bit size.

[bwh: Backported to 3.2:
- Old code is cosmetically different
- s/ddev/\&port->dev/]

---
 drivers/usb/serial/ftdi_sio.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)
drivers/usb/serial/ftdi_sio.c +24 -7
@@ -2201,6 +2201,20 @@ static void ftdi_set_termios(struct tty_
 		termios->c_cflag |= CRTSCTS;
 	}
 
+	/*
+	 * All FTDI UART chips are limited to CS7/8. We won't pretend to
+	 * support CS5/6 and revert the CSIZE setting instead.
+	 */
+	if ((C_CSIZE(tty) != CS8) && (C_CSIZE(tty) != CS7)) {
+		dev_warn(&port->dev, "requested CSIZE setting not supported\n");
+
+		termios->c_cflag &= ~CSIZE;
+		if (old_termios)
+			termios->c_cflag |= old_termios->c_cflag & CSIZE;
+		else
+			termios->c_cflag |= CS8;
+	}
+
 	cflag = termios->c_cflag;
 
 	if (!old_termios)
@@ -2237,13 +2251,16 @@ no_skip:
 	} else {
 		urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE;
 	}
-	if (cflag & CSIZE) {
-		switch (cflag & CSIZE) {
-		case CS7: urb_value |= 7; dbg("Setting CS7"); break;
-		case CS8: urb_value |= 8; dbg("Setting CS8"); break;
-		default:
-			dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n");
-		}
+	switch (cflag & CSIZE) {
+	case CS7:
+		urb_value |= 7;
+		dev_dbg(&port->dev, "Setting CS7\n");
+		break;
+	default:
+	case CS8:
+		urb_value |= 8;
+		dev_dbg(&port->dev, "Setting CS8\n");
+		break;
 	}
 
 	/* This is needed by the break command since it uses the same command
author maintainer
#92 lore raw

PATCH 92/134 ahci: Add Device IDs for Intel Wellsburg PCH

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Ralston <[email protected]>

commit 151743fd8dfb02956c5184b5f4f0f42677eb75bc upstream.

This patch adds the AHCI-mode SATA Device IDs for the Intel Wellsburg PCH

---
 drivers/ata/ahci.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/ata/ahci.c +8 -0
@@ -292,6 +292,14 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
 	{ PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
 	{ PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
+	{ PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
author maintainer
#93 lore raw

PATCH 93/134 ahci: AHCI-mode SATA patch for Intel Coleto Creek DeviceIDs

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Seth Heasley <[email protected]>

commit 1cfc7df3de10c40ed459e13cce6de616023bf41c upstream.

This patch adds the AHCI-mode SATA DeviceIDs for the Intel Coleto Creek PCH.

---
 drivers/ata/ahci.c |    1 +
 1 file changed, 1 insertion(+)
drivers/ata/ahci.c +1 -0
@@ -300,6 +300,7 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
author maintainer
#94 lore raw

PATCH 94/134 xhci: Dont enable/disable RWE on bus suspend/resume.

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sarah Sharp <[email protected]>

commit f217c980ca980e3a645b7485ea5eae9a747f4945 upstream.

The RWE bit of the USB 2.0 PORTPMSC register is supposed to enable remote wakeup for devices in the lower power link state L1. It has nothing to do with the device suspend remote wakeup from L2. The RWE bit is designed to be set once (when USB 2.0 LPM is enabled for the port) and cleared only when USB 2.0 LPM is disabled for the port.

The xHCI bus suspend method was setting the RWE bit erroneously, and the bus resume method was clearing it. The xHCI 1.0 specification with errata up to Aug 12, 2012 says in section 4.23.5.1.1.1 "Hardware Controlled LPM":

"While Hardware USB2 LPM is enabled, software shall not modify the HIRDBESL or RWE fields of the USB2 PORTPMSC register..."

If we have previously enabled USB 2.0 LPM for a device, that means when the USB 2.0 bus is resumed, we violate the xHCI specification by clearing RWE. It also means that after a bus resume, the host would think remote wakeup is disabled from L1 for ports with USB 2.0 Link PM enabled, which is not what we want.

This patch should be backported to kernels as old as 3.2, that contain the commit 65580b4321eb36f16ae8b5987bfa1bb948fc5112 "xHCI: set USB2 hardware LPM". That was the first kernel that supported USB 2.0 Link PM.

[bwh: Backported to 3.2: deleted code was cosmetically different]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/host/xhci-hub.c |   28 ----------------------------
 1 file changed, 28 deletions(-)
drivers/usb/host/xhci-hub.c +0 -28
@@ -1048,20 +1048,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd
 		t1 = xhci_port_state_to_neutral(t1);
 		if (t1 != t2)
 			xhci_writel(xhci, t2, port_array[port_index]);
-
-		if (hcd->speed != HCD_USB3) {
-			/* enable remote wake up for USB 2.0 */
-			__le32 __iomem *addr;
-			u32 tmp;
-
-			/* Add one to the port status register address to get
-			 * the port power control register address.
-			 */
-			addr = port_array[port_index] + 1;
-			tmp = xhci_readl(xhci, addr);
-			tmp |= PORT_RWE;
-			xhci_writel(xhci, tmp, addr);
-		}
 	}
 	hcd->state = HC_STATE_SUSPENDED;
 	bus_state->next_statechange = jiffies + msecs_to_jiffies(10);
@@ -1140,20 +1126,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 				xhci_ring_device(xhci, slot_id);
 		} else
 			xhci_writel(xhci, temp, port_array[port_index]);
-
-		if (hcd->speed != HCD_USB3) {
-			/* disable remote wake up for USB 2.0 */
-			__le32 __iomem *addr;
-			u32 tmp;
-
-			/* Add one to the port status register address to get
-			 * the port power control register address.
-			 */
-			addr = port_array[port_index] + 1;
-			tmp = xhci_readl(xhci, addr);
-			tmp &= ~PORT_RWE;
-			xhci_writel(xhci, tmp, addr);
-		}
 	}
 
 	(void) xhci_readl(xhci, &xhci->op_regs->command);
author maintainer
#95 lore raw

PATCH 95/134 ahci: Add Device IDs for Intel Wildcat Point-LP

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Ralston <[email protected]>

commit 9f961a5f6efc87a79571d7166257b36af28ffcfe upstream.

This patch adds the AHCI-mode SATA Device IDs for the Intel Wildcat Point-LP PCH.

---
 drivers/ata/ahci.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/ata/ahci.c +4 -0
@@ -301,6 +301,10 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
author maintainer
#96 lore raw

PATCH 96/134 usb: hub: Clear Port Reset Change during init/resume

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Julius Werner <[email protected]>

commit e92aee330837e4911553761490a8fb843f2053a6 upstream.

This patch adds the Port Reset Change flag to the set of bits that are preemptively cleared on init/resume of a hub. In theory this bit should never be set unexpectedly... in practice it can still happen if BIOS, SMM or ACPI code plays around with USB devices without cleaning up correctly. This is especially dangerous for XHCI root hubs, which don't generate any more Port Status Change Events until all change bits are cleared, so this is a good precaution to have (similar to how it's already done for the Warm Port Reset Change flag).

[bwh: Backported to 3.2:
- Adjust context
- s/usb_clear_port_feature/clear_port_feature/]

[yangyl: Backported to 3.4: Adjust context]
---
 drivers/usb/core/hub.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/usb/core/hub.c +5 -0
@@ -920,6 +920,11 @@ static void hub_activate(struct usb_hub
 			clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_ENABLE);
 		}
+		if (portchange & USB_PORT_STAT_C_RESET) {
+			need_debounce_delay = true;
+			clear_port_feature(hub->hdev, port1,
+					USB_PORT_FEAT_C_RESET);
+		}
 		if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
 				hub_is_superspeed(hub->hdev)) {
 			need_debounce_delay = true;
author maintainer
#97 lore raw

PATCH 97/134 xhci: quirk for extra long delay for S4

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 455f58925247e8a1a1941e159f3636ad6ee4c90b upstream.

It has been reported that this chipset really cannot sleep without this extraordinary delay.

This patch should be backported, in order to ensure this host functions under stable kernels. The last quirk for Fresco Logic hosts (commit bba18e33f25072ebf70fd8f7f0cdbf8cdb59a746 "xhci: Extend Fresco Logic MSI quirk.") was backported to stable kernels as old as 2.6.36.

[bwh: Backported to 3.2:
- Adjust context
- Use xhci_dbg() instead of xhci_dbg_trace()]

[yangyl: Backported to 3.4: Adjust context]
---
 drivers/usb/host/xhci-pci.c |    8 ++++++++
 drivers/usb/host/xhci.c     |    7 ++++++-
 drivers/usb/host/xhci.h     |    1 +
 3 files changed, 15 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +8 -0
@@ -67,6 +67,14 @@ static void xhci_pci_quirks(struct devic
 			xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
 					" endpoint cmd after reset endpoint\n");
 		}
+		if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
+				pdev->revision == 0x4) {
+			xhci->quirks |= XHCI_SLOW_SUSPEND;
+			xhci_dbg(xhci,
+				"QUIRK: Fresco Logic xHC revision %u"
+				"must be suspended extra slowly",
+				pdev->revision);
+		}
 		/* Fresco Logic confirms: all revisions of this chip do not
 		 * support MSI, even though some of them claim to in their PCI
 		 * capabilities.
drivers/usb/host/xhci.c +6 -1
@@ -886,6 +886,7 @@ static void xhci_clear_command_ring(stru
 int xhci_suspend(struct xhci_hcd *xhci)
 {
 	int			rc = 0;
+	unsigned int		delay = XHCI_MAX_HALT_USEC;
 	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
 	u32			command;
 
@@ -904,8 +905,12 @@ int xhci_suspend(struct xhci_hcd *xhci)
 	command = xhci_readl(xhci, &xhci->op_regs->command);
 	command &= ~CMD_RUN;
 	xhci_writel(xhci, command, &xhci->op_regs->command);
+
+	/* Some chips from Fresco Logic need an extraordinary delay */
+	delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1;
+
 	if (handshake(xhci, &xhci->op_regs->status,
-		      STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) {
+		      STS_HALT, STS_HALT, delay)) {
 		xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
 		spin_unlock_irq(&xhci->lock);
 		return -ETIMEDOUT;
drivers/usb/host/xhci.h +1 -0
@@ -1509,6 +1509,7 @@ struct xhci_hcd {
 #define XHCI_COMP_MODE_QUIRK	(1 << 14)
 #define XHCI_AVOID_BEI		(1 << 15)
 #define XHCI_PLAT		(1 << 16)
+#define XHCI_SLOW_SUSPEND	(1 << 17)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
 	/* There are two roothubs to keep track of bus suspend info for */
author maintainer
#98 lore raw

PATCH 98/134 xhci: Fix spurious wakeups after S5 on Haswell

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 upstream.

Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally).

This patch introduces a new quirk, XHCI_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_reset() in the xhci shutdown ops as done in xhci_stop(), and setting the device to PCI D3 at shutdown and remove ops.

The PCI D3 call is based on the initial fix patch by Oliver Neukum.

[Note: Sarah changed the quirk name from XHCI_HSW_SPURIOUS_WAKEUP to XHCI_SPURIOUS_WAKEUP, since none of the other quirks have system names in them. Sarah also fixed a collision with a quirk submitted around the same time, by changing the xhci->quirks bit from 17 to 18.]

This patch should be backported to kernels as old as 3.0, that contain the commit 1c12443ab8eba71a658fae4572147e56d1f84f66 "xhci: Add Lynx Point to list of Intel switchable hosts."

Cc Oliver Neukum <[email protected]>
[bwh: Backported to 3.2: adjust context]
Cc Yang Yingliang <[email protected]>
---
 drivers/usb/host/xhci-pci.c |   17 +++++++++++++++++
 drivers/usb/host/xhci.c     |    7 +++++++
 drivers/usb/host/xhci.h     |    1 +
 3 files changed, 25 insertions(+)
drivers/usb/host/xhci-pci.c +17 -0
@@ -34,6 +34,9 @@
 #define PCI_VENDOR_ID_ETRON		0x1b6f
 #define PCI_DEVICE_ID_ASROCK_P67	0x7023
 
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31
+
 static const char hcd_name[] = "xhci_hcd";
 
 /* called after powerup, by probe or system-pm "wakeup" */
@@ -111,6 +114,15 @@ static void xhci_pci_quirks(struct devic
 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
 		xhci->quirks |= XHCI_AVOID_BEI;
 	}
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+	    (pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI ||
+	     pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI)) {
+		/* Workaround for occasional spurious wakeups from S5 (or
+		 * any other sleep) on Haswell machines with LPT and LPT-LP
+		 * with the new Intel BIOS
+		 */
+		xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
+	}
 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
 			pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
 		xhci->quirks |= XHCI_RESET_ON_RESUME;
@@ -215,6 +227,11 @@ static void xhci_pci_remove(struct pci_d
 		usb_put_hcd(xhci->shared_hcd);
 	}
 	usb_hcd_pci_remove(dev);
+
+	/* Workaround for spurious wakeups at shutdown with HSW */
+	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+		pci_set_power_state(dev, PCI_D3hot);
+
 	kfree(xhci);
 }
 
drivers/usb/host/xhci.c +7 -0
@@ -779,12 +779,19 @@ void xhci_shutdown(struct usb_hcd *hcd)
 
 	spin_lock_irq(&xhci->lock);
 	xhci_halt(xhci);
+	/* Workaround for spurious wakeups at shutdown with HSW */
+	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+		xhci_reset(xhci);
 	spin_unlock_irq(&xhci->lock);
 
 	xhci_cleanup_msix(xhci);
 
 	xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
 		    xhci_readl(xhci, &xhci->op_regs->status));
+
+	/* Yet another workaround for spurious wakeups at shutdown with HSW */
+	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+		pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);
 }
 
 #ifdef CONFIG_PM
drivers/usb/host/xhci.h +1 -0
@@ -1510,6 +1510,7 @@ struct xhci_hcd {
 #define XHCI_AVOID_BEI		(1 << 15)
 #define XHCI_PLAT		(1 << 16)
 #define XHCI_SLOW_SUSPEND	(1 << 17)
+#define XHCI_SPURIOUS_WAKEUP	(1 << 18)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
 	/* There are two roothubs to keep track of bus suspend info for */
author maintainer
#99 lore raw

PATCH 99/134 xhci: Limit the spurious wakeup fix only to HP machines

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 6962d914f317b119e0db7189199b21ec77a4b3e0 upstream.

We've got regression reports that my previous fix for spurious wakeups after S5 on HP Haswell machines leads to the automatic reboot at shutdown on some machines. It turned out that the fix for one side triggers another BIOS bug in other side. So, it's exclusive.

Since the original S5 wakeups have been confirmed only on HP machines, it'd be safer to apply it only to limited machines. As a wild guess, limiting to machines with HP PCI SSID should suffice.

This patch should be backported to kernels as old as 3.12, that contain the commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 "xhci: Fix spurious wakeups after S5 on Haswell".

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=66171

---
 drivers/usb/host/xhci-pci.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +6 -1
@@ -121,7 +121,12 @@ static void xhci_pci_quirks(struct devic
 		 * any other sleep) on Haswell machines with LPT and LPT-LP
 		 * with the new Intel BIOS
 		 */
-		xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
+		/* Limit the quirk to only known vendors, as this triggers
+		 * yet another BIOS bug on some other machines
+		 * https://bugzilla.kernel.org/show_bug.cgi?id=66171
+		 */
+		if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)
+			xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
 	}
 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
 			pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
author maintainer
#100 lore raw

PATCH 100/134 ALSA: hda - Cache the MUX selection for generic HDMI

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit bddee96b5d0db869f47b195fe48c614ca824203c upstream.

When a selection to a converter MUX is changed in hdmi_pcm_open(), it should be cached so that the given connection can be restored properly at PM resume. We need just to replace the corresponding snd_hda_codec_write() call with snd_hda_codec_write_cache().

---
 sound/pci/hda/patch_hdmi.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/patch_hdmi.c +1 -1
@@ -910,7 +910,7 @@ static int hdmi_pcm_open(struct hda_pcm_
 	per_cvt->assigned = 1;
 	hinfo->nid = per_cvt->cvt_nid;
 
-	snd_hda_codec_write(codec, per_pin->pin_nid, 0,
+	snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
 			    AC_VERB_SET_CONNECT_SEL,
 			    mux_idx);
 	snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
author maintainer
#101 lore raw

PATCH 101/134 ALSA: hda - Add new GPU codec ID to snd-hda

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aaron Plattner <[email protected]>

commit 7ae48b56f8d9c836259bc02f3e2ea4962d6b5d1b upstream.

Vendor ID 0x10de0051 is used by a yet-to-be-named GPU chip.

---
 sound/pci/hda/patch_hdmi.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/hda/patch_hdmi.c +2 -0
@@ -1909,6 +1909,7 @@ static const struct hda_codec_preset snd
 { .id = 0x10de0042, .name = "GPU 42 HDMI/DP",	.patch = patch_generic_hdmi },
 { .id = 0x10de0043, .name = "GPU 43 HDMI/DP",	.patch = patch_generic_hdmi },
 { .id = 0x10de0044, .name = "GPU 44 HDMI/DP",	.patch = patch_generic_hdmi },
+{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP",	.patch = patch_generic_hdmi },
 { .id = 0x10de0067, .name = "MCP67 HDMI",	.patch = patch_nvhdmi_2ch },
 { .id = 0x10de8001, .name = "MCP73 HDMI",	.patch = patch_nvhdmi_2ch },
 { .id = 0x80860054, .name = "IbexPeak HDMI",	.patch = patch_generic_hdmi },
@@ -1955,6 +1956,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041"
 MODULE_ALIAS("snd-hda-codec-id:10de0042");
 MODULE_ALIAS("snd-hda-codec-id:10de0043");
 MODULE_ALIAS("snd-hda-codec-id:10de0044");
+MODULE_ALIAS("snd-hda-codec-id:10de0051");
 MODULE_ALIAS("snd-hda-codec-id:10de0067");
 MODULE_ALIAS("snd-hda-codec-id:10de8001");
 MODULE_ALIAS("snd-hda-codec-id:17e80047");
author maintainer
#102 lore raw

PATCH 102/134 ALSA: hda - Add another GPU codec ID to snd-hda

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aaron Plattner <[email protected]>

commit d52392b1a80458c0510810789c7db4a39b88022a upstream.

Vendor ID 0x10de0060 is used by a yet-to-be-named GPU chip.

---
 sound/pci/hda/patch_hdmi.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/hda/patch_hdmi.c +2 -0
@@ -1910,6 +1910,7 @@ static const struct hda_codec_preset snd
 { .id = 0x10de0043, .name = "GPU 43 HDMI/DP",	.patch = patch_generic_hdmi },
 { .id = 0x10de0044, .name = "GPU 44 HDMI/DP",	.patch = patch_generic_hdmi },
 { .id = 0x10de0051, .name = "GPU 51 HDMI/DP",	.patch = patch_generic_hdmi },
+{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP",	.patch = patch_generic_hdmi },
 { .id = 0x10de0067, .name = "MCP67 HDMI",	.patch = patch_nvhdmi_2ch },
 { .id = 0x10de8001, .name = "MCP73 HDMI",	.patch = patch_nvhdmi_2ch },
 { .id = 0x80860054, .name = "IbexPeak HDMI",	.patch = patch_generic_hdmi },
@@ -1957,6 +1958,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0042"
 MODULE_ALIAS("snd-hda-codec-id:10de0043");
 MODULE_ALIAS("snd-hda-codec-id:10de0044");
 MODULE_ALIAS("snd-hda-codec-id:10de0051");
+MODULE_ALIAS("snd-hda-codec-id:10de0060");
 MODULE_ALIAS("snd-hda-codec-id:10de0067");
 MODULE_ALIAS("snd-hda-codec-id:10de8001");
 MODULE_ALIAS("snd-hda-codec-id:17e80047");
author maintainer
#103 lore raw

PATCH 103/134 ALSA: usb-audio: skip UAC2 EFFECT_UNIT

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eldad Zack <[email protected]>

commit 5dae5fd24071319bb67d3375217d5b0b6d16cb0b upstream.

Current code mishandles the case where the device is a UAC2 and the bDescriptorSubtype is a UAC2 Effect Unit (0x07). It tries to parse it as a Processing Unit (which is similar to two other UAC1 units with overlapping subtypes), but since the structure is different (See: 4.7.2.10, 4.7.2.11 in UAC2 standard), the parsing is done incorrectly and prevents the device from initializing. For now, just ignore the unit.

---
 sound/usb/mixer.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
sound/usb/mixer.c +12 -1
@@ -720,8 +720,19 @@ static int check_input_term(struct mixer
 			return 0;
 		}
 		case UAC1_PROCESSING_UNIT:
-		case UAC1_EXTENSION_UNIT: {
+		case UAC1_EXTENSION_UNIT:
+		/* UAC2_PROCESSING_UNIT_V2 */
+		/* UAC2_EFFECT_UNIT */ {
 			struct uac_processing_unit_descriptor *d = p1;
+
+			if (state->mixer->protocol == UAC_VERSION_2 &&
+				hdr[2] == UAC2_EFFECT_UNIT) {
+				/* UAC2/UAC1 unit IDs overlap here in an
+				 * uncompatible way. Ignore this unit for now.
+				 */
+				return 0;
+			}
+
 			if (d->bNrInPins) {
 				id = d->baSourceID[0];
 				break; /* continue to parse */
author maintainer
#104 lore raw

PATCH 104/134 ALSA: usb: Parse UAC2 extension unit like for UAC1

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Torstein Hegge <[email protected]>

commit 61ac51301e6c6d4ed977d7674ce2b8e713619a9b upstream.

UAC2_EXTENSION_UNIT_V2 differs from UAC1_EXTENSION_UNIT, but can be handled in the same way when parsing the unit. Otherwise parse_audio_unit() fails when it sees an extension unit on a UAC2 device.

UAC2_EXTENSION_UNIT_V2 is outside the range allocated by UAC1.

---
 sound/usb/mixer.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
sound/usb/mixer.c +4 -1
@@ -722,7 +722,8 @@ static int check_input_term(struct mixer
 		case UAC1_PROCESSING_UNIT:
 		case UAC1_EXTENSION_UNIT:
 		/* UAC2_PROCESSING_UNIT_V2 */
-		/* UAC2_EFFECT_UNIT */ {
+		/* UAC2_EFFECT_UNIT */
+		case UAC2_EXTENSION_UNIT_V2: {
 			struct uac_processing_unit_descriptor *d = p1;
 
 			if (state->mixer->protocol == UAC_VERSION_2 &&
@@ -1975,6 +1976,8 @@ static int parse_audio_unit(struct mixer
 			return parse_audio_extension_unit(state, unitid, p1);
 		else /* UAC_VERSION_2 */
 			return parse_audio_processing_unit(state, unitid, p1);
+	case UAC2_EXTENSION_UNIT_V2:
+		return parse_audio_extension_unit(state, unitid, p1);
 	default:
 		snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
 		return -EINVAL;
author maintainer
#105 lore raw

PATCH 105/134 ALSA: ak4xx-adda: info leak in ak4xxx_capture_source_info()

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit bd5fe738e388ceaa32e5171481e0d3ec59f0ccfe upstream.

"idx" is controled by the user and can be a negative offset into the input_names[] array.

---
 sound/i2c/other/ak4xxx-adda.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/i2c/other/ak4xxx-adda.c +1 -1
@@ -571,7 +571,7 @@ static int ak4xxx_capture_source_info(st
 	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
 	const char **input_names;
-	int  num_names, idx;
+	unsigned int num_names, idx;
 
 	num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
 	if (!num_names)
author maintainer
#106 lore raw

PATCH 106/134 ALSA: 6fire: fix DMA issues with URB transfer_buffer usage

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jussi Kivilinna <[email protected]>

commit ddb6b5a964371e8e52e696b2b258bda144c8bd3f upstream.

Patch fixes 6fire not to use stack as URB transfer_buffer. URB buffers need to be DMA-able, which stack is not. Furthermore, transfer_buffer should not be allocated as part of larger device structure because DMA coherency issues and patch fixes this issue too.

---
 sound/usb/6fire/comm.c |   38 +++++++++++++++++++++++++++++++++-----
 sound/usb/6fire/comm.h |    2 +-
 2 files changed, 34 insertions(+), 6 deletions(-)
sound/usb/6fire/comm.c +33 -5
@@ -110,19 +110,37 @@ static int usb6fire_comm_send_buffer(u8
 static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
 		u8 reg, u8 value)
 {
-	u8 buffer[13]; /* 13: maximum length of message */
+	u8 *buffer;
+	int ret;
+
+	/* 13: maximum length of message */
+	buffer = kmalloc(13, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
 
 	usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
-	return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
+	ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
+
+	kfree(buffer);
+	return ret;
 }
 
 static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
 		u8 reg, u8 vl, u8 vh)
 {
-	u8 buffer[13]; /* 13: maximum length of message */
+	u8 *buffer;
+	int ret;
+
+	/* 13: maximum length of message */
+	buffer = kmalloc(13, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
 
 	usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
-	return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
+	ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
+
+	kfree(buffer);
+	return ret;
 }
 
 int __devinit usb6fire_comm_init(struct sfire_chip *chip)
@@ -135,6 +153,12 @@ int __devinit usb6fire_comm_init(struct
 	if (!rt)
 		return -ENOMEM;
 
+	rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
+	if (!rt->receiver_buffer) {
+		kfree(rt);
+		return -ENOMEM;
+	}
+
 	rt->serial = 1;
 	rt->chip = chip;
 	usb_init_urb(urb);
@@ -152,6 +176,7 @@ int __devinit usb6fire_comm_init(struct
 	urb->interval = 1;
 	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret < 0) {
+		kfree(rt->receiver_buffer);
 		kfree(rt);
 		snd_printk(KERN_ERR PREFIX "cannot create comm data receiver.");
 		return ret;
@@ -170,6 +195,9 @@ void usb6fire_comm_abort(struct sfire_ch
 
 void usb6fire_comm_destroy(struct sfire_chip *chip)
 {
-	kfree(chip->comm);
+	struct comm_runtime *rt = chip->comm;
+
+	kfree(rt->receiver_buffer);
+	kfree(rt);
 	chip->comm = NULL;
 }
sound/usb/6fire/comm.h +1 -1
@@ -24,7 +24,7 @@ struct comm_runtime {
 	struct sfire_chip *chip;
 
 	struct urb receiver;
-	u8 receiver_buffer[COMM_RECEIVER_BUFSIZE];
+	u8 *receiver_buffer;
 
 	u8 serial; /* urb serial */
 
author maintainer
#107 lore raw

PATCH 107/134 ALSA: 6fire: make buffers DMA-able (pcm)

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Torsten Schenk <[email protected]>

commit 5ece263f1d93fba8d992e67e3ab8a71acf674db9 upstream.

Patch makes pcm buffers DMA-able by allocating each one separately.

[bwh: Backported to 3.2: adjust context]
Cc Weng Meiling <[email protected]>
---
 sound/usb/6fire/pcm.c |   41 ++++++++++++++++++++++++++++++++++++++++-
 sound/usb/6fire/pcm.h |    2 +-
 2 files changed, 41 insertions(+), 2 deletions(-)
sound/usb/6fire/pcm.c +40 -1
@@ -578,6 +578,33 @@ static void __devinit usb6fire_pcm_init_
 	urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
 }
 
+static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
+{
+	int i;
+
+	for (i = 0; i < PCM_N_URBS; i++) {
+		rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB
+				* PCM_MAX_PACKET_SIZE, GFP_KERNEL);
+		if (!rt->out_urbs[i].buffer)
+			return -ENOMEM;
+		rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB
+				* PCM_MAX_PACKET_SIZE, GFP_KERNEL);
+		if (!rt->in_urbs[i].buffer)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt)
+{
+	int i;
+
+	for (i = 0; i < PCM_N_URBS; i++) {
+		kfree(rt->out_urbs[i].buffer);
+		kfree(rt->in_urbs[i].buffer);
+	}
+}
+
 int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
 {
 	int i;
@@ -589,6 +616,13 @@ int __devinit usb6fire_pcm_init(struct s
 	if (!rt)
 		return -ENOMEM;
 
+	ret = usb6fire_pcm_buffers_init(rt);
+	if (ret) {
+		usb6fire_pcm_buffers_destroy(rt);
+		kfree(rt);
+		return ret;
+	}
+
 	rt->chip = chip;
 	rt->stream_state = STREAM_DISABLED;
 	rt->rate = ARRAY_SIZE(rates);
@@ -610,6 +644,7 @@ int __devinit usb6fire_pcm_init(struct s
 
 	ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
 	if (ret < 0) {
+		usb6fire_pcm_buffers_destroy(rt);
 		kfree(rt);
 		snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
 		return ret;
@@ -625,6 +660,7 @@ int __devinit usb6fire_pcm_init(struct s
 			snd_dma_continuous_data(GFP_KERNEL),
 			MAX_BUFSIZE, MAX_BUFSIZE);
 	if (ret) {
+		usb6fire_pcm_buffers_destroy(rt);
 		kfree(rt);
 		snd_printk(KERN_ERR PREFIX
 				"error preallocating pcm buffers.\n");
@@ -669,6 +705,9 @@ void usb6fire_pcm_abort(struct sfire_chi
 
 void usb6fire_pcm_destroy(struct sfire_chip *chip)
 {
-	kfree(chip->pcm);
+	struct pcm_runtime *rt = chip->pcm;
+
+	usb6fire_pcm_buffers_destroy(rt);
+	kfree(rt);
 	chip->pcm = NULL;
 }
sound/usb/6fire/pcm.h +1 -1
@@ -32,7 +32,7 @@ struct pcm_urb {
 	struct urb instance;
 	struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
 	/* END DO NOT SEPARATE */
-	u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
+	u8 *buffer;
 
 	struct pcm_urb *peer;
 };
author maintainer
#108 lore raw

PATCH 108/134 ALSA: 6fire: make buffers DMA-able (midi)

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Torsten Schenk <[email protected]>

commit 4c2aee0032b70083dafebd733ed9c774633b2fa3 upstream.

Patch makes midi output buffer DMA-able by allocating it separately.

---
 sound/usb/6fire/midi.c |   16 +++++++++++++++-
 sound/usb/6fire/midi.h |    6 +-----
 2 files changed, 16 insertions(+), 6 deletions(-)
sound/usb/6fire/midi.c +15 -1
@@ -19,6 +19,10 @@
 #include "chip.h"
 #include "comm.h"
 
+enum {
+	MIDI_BUFSIZE = 64
+};
+
 static void usb6fire_midi_out_handler(struct urb *urb)
 {
 	struct midi_runtime *rt = urb->context;
@@ -156,6 +160,12 @@ int __devinit usb6fire_midi_init(struct
 	if (!rt)
 		return -ENOMEM;
 
+	rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL);
+	if (!rt->out_buffer) {
+		kfree(rt);
+		return -ENOMEM;
+	}
+
 	rt->chip = chip;
 	rt->in_received = usb6fire_midi_in_received;
 	rt->out_buffer[0] = 0x80; /* 'send midi' command */
@@ -169,6 +179,7 @@ int __devinit usb6fire_midi_init(struct
 
 	ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
 	if (ret < 0) {
+		kfree(rt->out_buffer);
 		kfree(rt);
 		snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
 		return ret;
@@ -197,6 +208,9 @@ void usb6fire_midi_abort(struct sfire_ch
 
 void usb6fire_midi_destroy(struct sfire_chip *chip)
 {
-	kfree(chip->midi);
+	struct midi_runtime *rt = chip->midi;
+
+	kfree(rt->out_buffer);
+	kfree(rt);
 	chip->midi = NULL;
 }
sound/usb/6fire/midi.h +1 -5
@@ -16,10 +16,6 @@
 
 #include "common.h"
 
-enum {
-	MIDI_BUFSIZE = 64
-};
-
 struct midi_runtime {
 	struct sfire_chip *chip;
 	struct snd_rawmidi *instance;
@@ -32,7 +28,7 @@ struct midi_runtime {
 	struct snd_rawmidi_substream *out;
 	struct urb out_urb;
 	u8 out_serial; /* serial number of out packet */
-	u8 out_buffer[MIDI_BUFSIZE];
+	u8 *out_buffer;
 	int buffer_offset;
 
 	void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
author maintainer
#109 lore raw

PATCH 109/134 ALSA: hda - hdmi: Fallback to ALSA allocation when selecting CA

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Anssi Hannula <[email protected]>

commit 18e391862cceaf43ddb8eb5cca05e1a83abdebaa upstream.

hdmi_channel_allocation() tries to find a HDMI channel allocation that matches the number channels in the playback stream and contains only speakers that the HDMI sink has reported as available via EDID. If no such allocation is found, 0 (stereo audio) is used.

Using CA 0 causes the audio causes the sink to discard everything except the first two channels (front left and front right).

However, the sink may be capable of receiving more channels than it has speakers (and then perform downmix or discard the extra channels), in which case it is preferable to use a CA that contains extra channels than to use CA 0 which discards all the non-stereo channels.

Additionally, it seems that HBR (HD) passthrough output does not work on Intel HDMI codecs when CA is set to 0 (possibly the codec zeroes channels not present in CA). This happens with all receivers that report a 5.1 speaker mask since a HBR stream is carried on 8 channels to the codec.

Add a fallback in the CA selection so that the CA channel count at least matches the stream channel count, even if the stream contains channels not present in the sink speaker descriptor.

Thanks to GrimGriefer at OpenELEC forums for discovering that changing the sink speaker mask allowed HBR output.

Reported-by GrimGriefer
Reported-by Ashecrow
[bwh: Backported to 3.2: adjust context]
Cc Weng Meiling <[email protected]>
---
 sound/pci/hda/patch_hdmi.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
sound/pci/hda/patch_hdmi.c +11 -0
@@ -513,6 +513,17 @@ static int hdmi_channel_allocation(struc
 		}
 	}
 
+	if (!ca) {
+		/* if there was no match, select the regular ALSA channel
+		 * allocation with the matching number of channels */
+		for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+			if (channels == channel_allocations[i].channels) {
+				ca = channel_allocations[i].ca_index;
+				break;
+			}
+		}
+	}
+
 	snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
 	snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
 		    ca, channels, buf);
author maintainer
#110 lore raw

PATCH 110/134 ALSA: pcsp: Fix the order of input device unregistration

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 6408eac2665955343cd0e4bcd7d6237ce39611ed upstream.

The current code may access to the already freed object. The input device must be accessed and unregistered before freeing the top level sound object.

[bwh: Backported to 3.2: adjust context]
Cc Weng Meiling <[email protected]>
---
 sound/drivers/pcsp/pcsp.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/drivers/pcsp/pcsp.c +1 -1
@@ -187,8 +187,8 @@ static int __devinit pcsp_probe(struct p
 static int __devexit pcsp_remove(struct platform_device *dev)
 {
 	struct snd_pcsp *chip = platform_get_drvdata(dev);
-	alsa_card_pcsp_exit(chip);
 	pcspkr_input_remove(chip->input_dev);
+	alsa_card_pcsp_exit(chip);
 	platform_set_drvdata(dev, NULL);
 	return 0;
 }
author maintainer
#111 lore raw

PATCH 111/134 ALSA: hda/realtek - Add support of ALC231 codec

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kailang Yang <[email protected]>

commit ba4c4d0a9021ab034554d532a98133d668b87599 upstream.

It's compatible with ALC269.

[bwh: Backported to 3.2: adjust context]
Cc Weng Meiling <[email protected]>
---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -7031,6 +7031,7 @@ static int patch_alc680(struct hda_codec
  */
 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
 	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
+	{ .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
 	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
 	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
 	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
author maintainer
#112 lore raw

PATCH 112/134 hwmon: (coretemp) Improve support of recent Atom CPU models

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jean Delvare <[email protected]>

commit fcc14ac1a86931f38da047cf8fb634c6db7b58bc upstream.

Document the new Atom series (Tunnel Creek and Medfield) as being supported, and list TjMax for the Atom E600 series.

Also enable the Atom tjmax heuristic for these Atom CPU models.

---
 Documentation/hwmon/coretemp |    8 +++++++-
 drivers/hwmon/coretemp.c     |    3 ++-
 2 files changed, 9 insertions(+), 2 deletions(-)
Documentation/hwmon/coretemp +7 -1
@@ -6,7 +6,8 @@ Supported chips:
     Prefix: 'coretemp'
     CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm),
                               0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm),
-                              0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield)
+                              0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield),
+                              0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom)
     Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
                Volume 3A: System Programming Guide
                http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
@@ -65,6 +66,9 @@ Process		Processor					TjMax(C)
 		U3400						105
 		P4505/P4500 					90
 
+32nm		Atom Processors
+		Z2460						90
+
 45nm		Xeon Processors 5400 Quad-Core
 		X5492, X5482, X5472, X5470, X5460, X5450	85
 		E5472, E5462, E5450/40/30/20/10/05		85
@@ -85,6 +89,8 @@ Process		Processor					TjMax(C)
 		N475/470/455/450				100
 		N280/270					90
 		330/230						125
+		E680/660/640/620				90
+		E680T/660T/640T/620T				110
 
 45nm		Core2 Processors
 		Solo ULV SU3500/3300				100
drivers/hwmon/coretemp.c +2 -1
@@ -210,7 +210,8 @@ static int __cpuinit adjust_tjmax(struct
 
 	/* Atom CPUs */
 
-	if (c->x86_model == 0x1c) {
+	if (c->x86_model == 0x1c || c->x86_model == 0x26
+	    || c->x86_model == 0x27) {
 		usemsr_ee = 0;
 
 		host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
author maintainer
#113 lore raw

PATCH 113/134 hwmon: (coretemp) Add support for Atom D2000 and N2000 series CPU models

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guenter Roeck <[email protected]>

commit 5592906f8b01282ea3c2acaf641fd067ad4bb3dc upstream.

Document the Atom series D2000 and N2000 (Cedar Trail) as being supported. List and set TjMax for those series.

---
 Documentation/hwmon/coretemp |    5 ++++-
 drivers/hwmon/coretemp.c     |    3 +++
 2 files changed, 7 insertions(+), 1 deletion(-)
Documentation/hwmon/coretemp +4 -1
@@ -7,7 +7,8 @@ Supported chips:
     CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm),
                               0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm),
                               0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield),
-                              0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom)
+                              0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom),
+                              0x36 (Cedar Trail Atom)
     Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
                Volume 3A: System Programming Guide
                http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
@@ -68,6 +69,8 @@ Process		Processor					TjMax(C)
 
 32nm		Atom Processors
 		Z2460						90
+		D2700/2550/2500					100
+		N2850/2800/2650/2600				100
 
 45nm		Xeon Processors 5400 Quad-Core
 		X5492, X5482, X5472, X5470, X5460, X5450	85
drivers/hwmon/coretemp.c +3 -0
@@ -224,6 +224,9 @@ static int __cpuinit adjust_tjmax(struct
 			tjmax = 90000;
 
 		pci_dev_put(host_bridge);
+	} else if (c->x86_model == 0x36) {
+		usemsr_ee = 0;
+		tjmax = 100000;
 	}
 
 	if (c->x86_model > 0xe && usemsr_ee) {
author maintainer
#114 lore raw

PATCH 114/134 hwmon: (coretemp) Improve support for TjMax detection on Atom CPUs

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guenter Roeck <[email protected]>

commit 41e58a1f2b90c88d94b4bd84beb9927a4c2704e9 upstream.

Atom CPUs don't have a register to retrieve TjMax. Detection so far was incomplete. Use the X86 model ID to improve it.

---
 drivers/hwmon/coretemp.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
drivers/hwmon/coretemp.c +25 -0
@@ -191,6 +191,24 @@ static ssize_t show_temp(struct device *
 	return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN;
 }
 
+struct tjmax {
+	char const *id;
+	int tjmax;
+};
+
+static struct tjmax __cpuinitconst tjmax_table[] = {
+	{ "CPU D410", 100000 },
+	{ "CPU D425", 100000 },
+	{ "CPU D510", 100000 },
+	{ "CPU D525", 100000 },
+	{ "CPU N450", 100000 },
+	{ "CPU N455", 100000 },
+	{ "CPU N470", 100000 },
+	{ "CPU N475", 100000 },
+	{ "CPU  230", 100000 },
+	{ "CPU  330", 125000 },
+};
+
 static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,
 				  struct device *dev)
 {
@@ -202,6 +220,13 @@ static int __cpuinit adjust_tjmax(struct
 	int err;
 	u32 eax, edx;
 	struct pci_dev *host_bridge;
+	int i;
+
+	/* explicit tjmax table entries override heuristics */
+	for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) {
+		if (strstr(c->x86_model_id, tjmax_table[i].id))
+			return tjmax_table[i].tjmax;
+	}
 
 	/* Early chips have no MSR for TjMax */
 
author maintainer
#115 lore raw

PATCH 115/134 hwmon: (coretemp) Add support for Atom CE4110/4150/4170

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guenter Roeck <[email protected]>

commit 1102dcab849313bd5a340b299b5cf61b518fbc0f upstream.

TjMax for the CE4100 series of Atom CPUs was previously reported to be 110 degrees C.

cpuinfo logs on the web show existing CPU types CE4110, CE4150, and CE4170, reported as "model name : Intel(R) Atom(TM) CPU CE41{1|5|7}0 @ 1.{2|6}0GHz" with model 28 (0x1c) and stepping 10 (0x0a). Add the three known variants to the tjmax table.

---
 Documentation/hwmon/coretemp |    1 +
 drivers/hwmon/coretemp.c     |    7 +++++--
 2 files changed, 6 insertions(+), 2 deletions(-)
Documentation/hwmon/coretemp +1 -0
@@ -94,6 +94,7 @@ Process		Processor					TjMax(C)
 		330/230						125
 		E680/660/640/620				90
 		E680T/660T/640T/620T				110
+		CE4170/4150/4110				110
 
 45nm		Core2 Processors
 		Solo ULV SU3500/3300				100
drivers/hwmon/coretemp.c +5 -2
@@ -205,8 +205,11 @@ static struct tjmax __cpuinitconst tjmax
 	{ "CPU N455", 100000 },
 	{ "CPU N470", 100000 },
 	{ "CPU N475", 100000 },
-	{ "CPU  230", 100000 },
-	{ "CPU  330", 125000 },
+	{ "CPU  230", 100000 },		/* Model 0x1c, stepping 2	*/
+	{ "CPU  330", 125000 },		/* Model 0x1c, stepping 2	*/
+	{ "CPU CE4110", 110000 },	/* Model 0x1c, stepping 10	*/
+	{ "CPU CE4150", 110000 },	/* Model 0x1c, stepping 10	*/
+	{ "CPU CE4170", 110000 },	/* Model 0x1c, stepping 10	*/
 };
 
 static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,
author maintainer
#116 lore raw

PATCH 116/134 hwmon: (applesmc) Always read until end of data

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Henrik Rydberg <[email protected]>

commit 25f2bd7f5add608c1d1405938f39c96927b275ca upstream.

The crash reported and investigated in commit 5f4513 turned out to be caused by a change to the read interface on newer (2012) SMCs.

Tests by Chris show that simply reading the data valid line is enough for the problem to go away. Additional tests show that the newer SMCs no longer wait for the number of requested bytes, but start sending data right away. Apparently the number of bytes to read is no longer specified as before, but instead found out by reading until end of data. Failure to read until end of data confuses the state machine, which eventually causes the crash.

As a remedy, assuming bit0 is the read valid line, make sure there is nothing more to read before leaving the read function.

Tested to resolve the original problem, and runtested on MBA3,1, MBP4,1, MBP8,2, MBP10,1, MBP10,2. The patch seems to have no effect on machines before 2012.

---
 drivers/hwmon/applesmc.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/hwmon/applesmc.c +13 -0
@@ -212,6 +212,7 @@ static int send_argument(const char *key
 
 static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
 {
+	u8 status, data = 0;
 	int i;
 
 	if (send_command(cmd) || send_argument(key)) {
@@ -219,6 +220,7 @@ static int read_smc(u8 cmd, const char *
 		return -EIO;
 	}
 
+	/* This has no effect on newer (2012) SMCs */
 	outb(len, APPLESMC_DATA_PORT);
 
 	for (i = 0; i < len; i++) {
@@ -229,6 +231,17 @@ static int read_smc(u8 cmd, const char *
 		buffer[i] = inb(APPLESMC_DATA_PORT);
 	}
 
+	/* Read the data port until bit0 is cleared */
+	for (i = 0; i < 16; i++) {
+		udelay(APPLESMC_MIN_WAIT);
+		status = inb(APPLESMC_CMD_PORT);
+		if (!(status & 0x01))
+			break;
+		data = inb(APPLESMC_DATA_PORT);
+	}
+	if (i)
+		pr_warn("flushed %d bytes, last value is: %d\n", i, data);
+
 	return 0;
 }
 
author maintainer
#117 lore raw

PATCH 117/134 hwmon: Prevent some divide by zeros in FAN_TO_REG()

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 3806b45ba4655147a011df03242cc197ab986c43 upstream.

The "rpm * div" operations can overflow here, so this patch adds an upper limit to rpm to prevent that. Jean Delvare helped me with this patch.

---
 drivers/hwmon/lm78.c    |    2 ++
 drivers/hwmon/sis5595.c |    2 ++
 drivers/hwmon/vt8231.c  |    2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)
drivers/hwmon/lm78.c +2 -0
@@ -94,6 +94,8 @@ static inline u8 FAN_TO_REG(long rpm, in
 {
 	if (rpm <= 0)
 		return 255;
+	if (rpm > 1350000)
+		return 1;
 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
drivers/hwmon/sis5595.c +2 -0
@@ -141,6 +141,8 @@ static inline u8 FAN_TO_REG(long rpm, in
 {
 	if (rpm <= 0)
 		return 255;
+	if (rpm > 1350000)
+		return 1;
 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
drivers/hwmon/vt8231.c +1 -1
@@ -145,7 +145,7 @@ static const u8 regtempmin[] = { 0x3a, 0
  */
 static inline u8 FAN_TO_REG(long rpm, int div)
 {
-	if (rpm == 0)
+	if (rpm <= 0 || rpm > 1310720)
 		return 0;
 	return SENSORS_LIMIT(1310720 / (rpm * div), 1, 255);
 }
author maintainer
#118 lore raw

PATCH 118/134 tg3: Add New 5719 Read DMA workaround

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael Chan <[email protected]>

commit 091f0ea30074bc43f9250961b3247af713024bc6 upstream.

After Power-on-reset, the 5719's TX DMA length registers may contain uninitialized values and cause TX DMA to stall. Check for invalid values and set a register bit to flush the TX channels. The bit needs to be turned off after the DMA channels have been flushed.

---
 drivers/net/ethernet/broadcom/tg3.c |   23 +++++++++++++++++++++++
 drivers/net/ethernet/broadcom/tg3.h |    7 ++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)
drivers/net/ethernet/broadcom/tg3.c +23 -0
@@ -9161,6 +9161,19 @@ static int tg3_reset_hw(struct tg3 *tp,
 	tw32_f(RDMAC_MODE, rdmac_mode);
 	udelay(40);
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+		for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) {
+			if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp))
+				break;
+		}
+		if (i < TG3_NUM_RDMA_CHANNELS) {
+			val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
+			val |= TG3_LSO_RD_DMA_TX_LENGTH_WA;
+			tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
+			tg3_flag_set(tp, 5719_RDMA_BUG);
+		}
+	}
+
 	tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE);
 	if (!tg3_flag(tp, 5705_PLUS))
 		tw32(MBFREE_MODE, MBFREE_MODE_ENABLE);
@@ -9416,6 +9429,16 @@ static void tg3_periodic_fetch_stats(str
 	TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST);
 	TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST);
 	TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST);
+	if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) &&
+		     (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low +
+		      sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) {
+		u32 val;
+
+		val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
+		val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA;
+		tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
+		tg3_flag_clear(tp, 5719_RDMA_BUG);
+	}
 
 	TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS);
 	TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS);
drivers/net/ethernet/broadcom/tg3.h +6 -1
@@ -1376,7 +1376,11 @@
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL	0x00004910
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K	 0x00030000
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K	 0x000c0000
-/* 0x4914 --> 0x4c00 unused */
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA	 0x02000000
+/* 0x4914 --> 0x4be0 unused */
+
+#define TG3_NUM_RDMA_CHANNELS		4
+#define TG3_RDMA_LENGTH			0x00004be0
 
 /* Write DMA control registers */
 #define WDMAC_MODE			0x00004c00
@@ -2924,6 +2928,7 @@ enum TG3_FLAGS {
 	TG3_FLAG_L1PLLPD_EN,
 	TG3_FLAG_APE_HAS_NCSI,
 	TG3_FLAG_4K_FIFO_LIMIT,
+	TG3_FLAG_5719_RDMA_BUG,
 	TG3_FLAG_RESET_TASK_PENDING,
 	TG3_FLAG_5705_PLUS,
 	TG3_FLAG_IS_5788,
author maintainer
#119 lore raw

PATCH 119/134 tg3: Wait for boot code to finish after power on

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nithin Sujir <[email protected]>

commit df465abfe06f7dc4f33f4a96d17f096e9e8ac917 upstream.

Some systems that don't need wake-on-lan may choose to power down the chip on system standby. Upon resume, the power on causes the boot code to startup and initialize the hardware. On one new platform, this is causing the device to go into a bad state due to a race between the driver and boot code, once every several hundred resumes. The same race exists on open since we come up from a power on.

This patch adds a wait for boot code signature at the beginning of tg3_init_hw() which is common to both cases. If there has not been a power-off or the boot code has already completed, the signature will be present and poll_fw() returns immediately. Also return immediately if the device does not have firmware.

---
 drivers/net/ethernet/broadcom/tg3.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/net/ethernet/broadcom/tg3.c +10 -0
@@ -1631,6 +1631,9 @@ static int tg3_poll_fw(struct tg3 *tp)
 	int i;
 	u32 val;
 
+	if (tg3_flag(tp, NO_FWARE_REPORTED))
+		return 0;
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		/* Wait up to 20ms for init done. */
 		for (i = 0; i < 200; i++) {
@@ -9395,6 +9398,13 @@ static int tg3_reset_hw(struct tg3 *tp,
  */
 static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 {
+	/* Chip may have been just powered on. If so, the boot code may still
+	 * be running initialization. Wait for it to finish to avoid races in
+	 * accessing the hardware.
+	 */
+	tg3_enable_register_access(tp);
+	tg3_poll_fw(tp);
+
 	tg3_switch_clocks(tp);
 
 	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
author maintainer
#120 lore raw

PATCH 120/134 OMAPFB: fix framebuffer console colors

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Grazvydas Ignotas <[email protected]>

commit c1c52848cef52e157468b8879fc3cae23b6f3a99 upstream.

omapfb does not currently set pseudo palette correctly for color depths above 16bpp, making red text invisible, command like
echo -e '\e[0;31mRED' > /dev/tty1
will display nothing on framebuffer console in 24bpp mode. This is because temporary variable is declared incorrectly, fix it.

---
 drivers/video/omap2/omapfb/omapfb-main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/omap2/omapfb/omapfb-main.c +1 -1
@@ -1187,7 +1187,7 @@ static int _setcolreg(struct fb_info *fb
 			break;
 
 		if (regno < 16) {
-			u16 pal;
+			u32 pal;
 			pal = ((red >> (16 - var->red.length)) <<
 					var->red.offset) |
 				((green >> (16 - var->green.length)) <<
author maintainer
#121 lore raw

PATCH 121/134 mmc: mxs-mmc: fix deadlock caused by recursion loop

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lauri Hintsala <[email protected]>

commit fc108d24d3a6da63576a460e122fa1df0cbdea20 upstream.

Release the lock before mmc_signal_sdio_irq is called by mxs_mmc_enable_sdio_irq.

Backtrace:
[   65.470000] =============================================
[   65.470000] [ INFO: possible recursive locking detected ]
[   65.470000] 3.5.0-rc5 #2 Not tainted
[   65.470000] ---------------------------------------------
[   65.470000] ksdioirqd/mmc0/73 is trying to acquire lock:
[   65.470000]  (&(&host->lock)->rlock#2){-.-...}, at: [<bf054120>] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]
[   65.470000]
[   65.470000] but task is already holding lock:
[   65.470000]  (&(&host->lock)->rlock#2){-.-...}, at: [<bf054120>] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]
[   65.470000]
[   65.470000] other info that might help us debug this:
[   65.470000]  Possible unsafe locking scenario:
[   65.470000]
[   65.470000]        CPU0
[   65.470000]        ----
[   65.470000]   lock(&(&host->lock)->rlock#2);
[   65.470000]   lock(&(&host->lock)->rlock#2);
[   65.470000]
[   65.470000]  *** DEADLOCK ***
[   65.470000]
[   65.470000]  May be due to missing lock nesting notation
[   65.470000]
[   65.470000] 1 lock held by ksdioirqd/mmc0/73:
[   65.470000]  #0:  (&(&host->lock)->rlock#2){-.-...}, at: [<bf054120>] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]
[   65.470000]
[   65.470000] stack backtrace:
[   65.470000] [<c0014990>] (unwind_backtrace+0x0/0xf4) from [<c005ccb8>] (__lock_acquire+0x14f8/0x1b98)
[   65.470000] [<c005ccb8>] (__lock_acquire+0x14f8/0x1b98) from [<c005d3f8>] (lock_acquire+0xa0/0x108)
[   65.470000] [<c005d3f8>] (lock_acquire+0xa0/0x108) from [<c02f671c>] (_raw_spin_lock_irqsave+0x48/0x5c)
[   65.470000] [<c02f671c>] (_raw_spin_lock_irqsave+0x48/0x5c) from [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc])
[   65.470000] [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) from [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc])
[   65.470000] [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) from [<c0219b38>] (sdio_irq_thread+0x1bc/0x274)
[   65.470000] [<c0219b38>] (sdio_irq_thread+0x1bc/0x274) from [<c003c324>] (kthread+0x8c/0x98)
[   65.470000] [<c003c324>] (kthread+0x8c/0x98) from [<c00101ac>] (kernel_thread_exit+0x0/0x8)
[   65.470000] BUG: spinlock lockup suspected on CPU#0, ksdioirqd/mmc0/73
[   65.470000]  lock: 0xc3358724, .magic: dead4ead, .owner: ksdioirqd/mmc0/73, .owner_cpu: 0
[   65.470000] [<c0014990>] (unwind_backtrace+0x0/0xf4) from [<c01b46b0>] (do_raw_spin_lock+0x100/0x144)
[   65.470000] [<c01b46b0>] (do_raw_spin_lock+0x100/0x144) from [<c02f6724>] (_raw_spin_lock_irqsave+0x50/0x5c)
[   65.470000] [<c02f6724>] (_raw_spin_lock_irqsave+0x50/0x5c) from [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc])
[   65.470000] [<bf054120>] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) from [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc])
[   65.470000] [<bf0541d0>] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) from [<c0219b38>] (sdio_irq_thread+0x1bc/0x274)
[   65.470000] [<c0219b38>] (sdio_irq_thread+0x1bc/0x274) from [<c003c324>] (kthread+0x8c/0x98)
[   65.470000] [<c003c324>] (kthread+0x8c/0x98) from [<c00101ac>] (kernel_thread_exit+0x0/0x8)

[bwh: Backported to 3.2:
- Adjust context
- HW_SSP_STATUS is a simple rather than function-like macro]

---
 drivers/mmc/host/mxs-mmc.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mmc/host/mxs-mmc.c +4 -4
@@ -639,10 +639,6 @@ static void mxs_mmc_enable_sdio_irq(stru
 		       host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
 		       host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
-
-		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
-			mmc_signal_sdio_irq(host->mmc);
-
 	} else {
 		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
 		       host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
@@ -651,6 +647,10 @@ static void mxs_mmc_enable_sdio_irq(stru
 	}
 
 	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (enable && readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
+		mmc_signal_sdio_irq(host->mmc);
+
 }
 
 static const struct mmc_host_ops mxs_mmc_ops = {
author maintainer
#122 lore raw

PATCH 122/134 sb_edac: Avoid overflow errors at memory size calculation

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mauro Carvalho Chehab <[email protected]>

commit deb09ddaff1435f72dd598d38f9b58354c68a5ec upstream.

Sandy bridge EDAC is calculating the memory size with overflow. Basically, the size field and the integer calculation is using 32 bits. More bits are needed, when the DIMM memories have high density.

The net result is that memories are improperly reported there, when high-density DIMMs are used:

EDAC DEBUG: in drivers/edac/sb_edac.c, line at 591: mc#0: channel 0, dimm 0, -16384 Mb (-4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800 EDAC DEBUG: in drivers/edac/sb_edac.c, line at 591: mc#0: channel 1, dimm 0, -16384 Mb (-4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800

As the number of pages value is handled at the EDAC core as unsigned ints, the driver shows the 16 GB memories at sysfs interface as 16760832 MB! The fix is simple: calculate the number of pages as unsigned 64-bits integer.

After the patch, the memory size (16 GB) is properly detected:

EDAC DEBUG: in drivers/edac/sb_edac.c, line at 592: mc#0: channel 0, dimm 0, 16384 Mb (4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800 EDAC DEBUG: in drivers/edac/sb_edac.c, line at 592: mc#0: channel 1, dimm 0, 16384 Mb (4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800

[bwh: Backported to 3.2:
- Adjust context
- Debug log function is debugf0(), not edac_dbg()]

---
 drivers/edac/sb_edac.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/edac/sb_edac.c +4 -3
@@ -555,7 +555,8 @@ static int get_dimm_config(const struct
 {
 	struct sbridge_pvt *pvt = mci->pvt_info;
 	struct csrow_info *csr;
-	int i, j, banks, ranks, rows, cols, size, npages;
+	unsigned i, j, banks, ranks, rows, cols, npages;
+	u64 size;
 	int csrow = 0;
 	unsigned long last_page = 0;
 	u32 reg;
@@ -627,10 +628,10 @@ static int get_dimm_config(const struct
 				cols = numcol(mtr);
 
 				/* DDR3 has 8 I/O banks */
-				size = (rows * cols * banks * ranks) >> (20 - 3);
+				size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
 				npages = MiB_TO_PAGES(size);
 
-				debugf0("mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
+				debugf0("mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
 					pvt->sbridge_dev->mc, i, j,
 					size, npages,
 					banks, ranks, rows, cols);
author maintainer
#123 lore raw

PATCH 123/134 tg3: Skip powering down function 0 on certain serdes devices

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nithin Sujir <[email protected]>

commit 44f3b503c16425c8e9db4bbaa2fc9cd0c9d0ba91 upstream.

On the 5718, 5719 and 5720 serdes devices, powering down function 0 results in all the other ports being powered down. Add code to skip function 0 power down.

v2:
- Modify tg3_phy_power_bug() function to use a switch instead of a complicated if statement. Suggested by Joe Perches.

[bwh: Backported to 3.2:
s/tg3_asic_rev\(tp\)/GET_ASIC_REV(tp->pci_chip_rev_id)/]

[hq: Backported to 3.4: Adjust context]
---
 drivers/net/ethernet/broadcom/tg3.c |   32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +26 -6
@@ -2740,6 +2740,31 @@ static int tg3_5700_link_polarity(struct
 	return 0;
 }
 
+static bool tg3_phy_power_bug(struct tg3 *tp)
+{
+	switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
+	case ASIC_REV_5700:
+	case ASIC_REV_5704:
+		return true;
+	case ASIC_REV_5780:
+		if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
+			return true;
+		return false;
+	case ASIC_REV_5717:
+		if (!tp->pci_fn)
+			return true;
+		return false;
+	case ASIC_REV_5719:
+	case ASIC_REV_5720:
+		if ((tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
+		    !tp->pci_fn)
+			return true;
+		return false;
+	}
+
+	return false;
+}
+
 static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
 	u32 val;
@@ -2796,12 +2821,7 @@ static void tg3_power_down_phy(struct tg
 	/* The PHY should not be powered down on some chips because
 	 * of bugs.
 	 */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
-	     (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) ||
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
-	     !tp->pci_fn))
+	if (tg3_phy_power_bug(tp))
 		return;
 
 	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
author maintainer
#124 lore raw

PATCH 124/134 tg3: Add read dma workaround for 5720

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nithin Sujir <[email protected]>

commit 9bc297ea0622bb2a6b3abfa2fa84f0a3b86ef8c8 upstream.

Commit 091f0ea30074bc43f9250961b3247af713024bc6 "tg3: Add New 5719 Read DMA workaround" added a workaround for TX DMA stall on the 5719. This workaround needs to be applied to the 5720 as well.

[bwh: Backported to 3.2: use GET_ASIC_REV() instead of tg3_asic_rev()]
[hq: Backproted to 3.4: Adjust context]
---
 drivers/net/ethernet/broadcom/tg3.c |   21 +++++++++++++++------
 drivers/net/ethernet/broadcom/tg3.h |    5 +++--
 2 files changed, 18 insertions(+), 8 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +15 -6
@@ -8548,6 +8548,14 @@ static void tg3_rss_write_indir_tbl(stru
 	}
 }
 
+static inline u32 tg3_lso_rd_dma_workaround_bit(struct tg3 *tp)
+{
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+		return TG3_LSO_RD_DMA_TX_LENGTH_WA_5719;
+	else
+		return TG3_LSO_RD_DMA_TX_LENGTH_WA_5720;
+}
+
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
@@ -9184,16 +9192,17 @@ static int tg3_reset_hw(struct tg3 *tp,
 	tw32_f(RDMAC_MODE, rdmac_mode);
 	udelay(40);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
 		for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) {
 			if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp))
 				break;
 		}
 		if (i < TG3_NUM_RDMA_CHANNELS) {
 			val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-			val |= TG3_LSO_RD_DMA_TX_LENGTH_WA;
+			val |= tg3_lso_rd_dma_workaround_bit(tp);
 			tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
-			tg3_flag_set(tp, 5719_RDMA_BUG);
+			tg3_flag_set(tp, 5719_5720_RDMA_BUG);
 		}
 	}
 
@@ -9459,15 +9468,15 @@ static void tg3_periodic_fetch_stats(str
 	TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST);
 	TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST);
 	TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST);
-	if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) &&
+	if (unlikely(tg3_flag(tp, 5719_5720_RDMA_BUG) &&
 		     (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low +
 		      sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) {
 		u32 val;
 
 		val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-		val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA;
+		val &= ~tg3_lso_rd_dma_workaround_bit(tp);
 		tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
-		tg3_flag_clear(tp, 5719_RDMA_BUG);
+		tg3_flag_clear(tp, 5719_5720_RDMA_BUG);
 	}
 
 	TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS);
drivers/net/ethernet/broadcom/tg3.h +3 -2
@@ -1376,7 +1376,8 @@
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL	0x00004910
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K	 0x00030000
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K	 0x000c0000
-#define TG3_LSO_RD_DMA_TX_LENGTH_WA	 0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5719	 0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5720	 0x00200000
 /* 0x4914 --> 0x4be0 unused */
 
 #define TG3_NUM_RDMA_CHANNELS		4
@@ -2928,7 +2929,7 @@ enum TG3_FLAGS {
 	TG3_FLAG_L1PLLPD_EN,
 	TG3_FLAG_APE_HAS_NCSI,
 	TG3_FLAG_4K_FIFO_LIMIT,
-	TG3_FLAG_5719_RDMA_BUG,
+	TG3_FLAG_5719_5720_RDMA_BUG,
 	TG3_FLAG_RESET_TASK_PENDING,
 	TG3_FLAG_5705_PLUS,
 	TG3_FLAG_IS_5788,
author maintainer
#125 lore raw

PATCH 125/134 media: gspca_kinect: add Kinect for Windows USB id

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jacob Schloss <[email protected]>

commit 98fd485795db064d0885150e2c0c7f296d8fe06e upstream.

Add the USB ID for the Kinect for Windows RGB camera so it can be used with the gspca_kinect driver.

---
 drivers/media/video/gspca/kinect.c |    1 +
 1 file changed, 1 insertion(+)
drivers/media/video/gspca/kinect.c +1 -0
@@ -390,6 +390,7 @@ static const struct sd_desc sd_desc = {
 /* -- module initialisation -- */
 static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x045e, 0x02ae)},
+	{USB_DEVICE(0x045e, 0x02bf)},
 	{}
 };
 
author maintainer
#126 lore raw

PATCH 126/134 media: v4l: Reset subdev v4l2_dev field to NULL if registration fails

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Laurent Pinchart <[email protected]>

commit 317efce991620adc589b3005b9baed433dcb2a56 upstream.

When subdev registration fails the subdev v4l2_dev field is left to a non-NULL value. Later calls to v4l2_device_unregister_subdev() will consider the subdev as registered and will module_put() the subdev module without any matching module_get().
Fix this by setting the subdev v4l2_dev field to NULL in v4l2_device_register_subdev() when the function fails.

---
 drivers/media/video/v4l2-device.c |   30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
drivers/media/video/v4l2-device.c +14 -16
@@ -159,31 +159,21 @@ int v4l2_device_register_subdev(struct v
 	sd->v4l2_dev = v4l2_dev;
 	if (sd->internal_ops && sd->internal_ops->registered) {
 		err = sd->internal_ops->registered(sd);
-		if (err) {
-			module_put(sd->owner);
-			return err;
-		}
+		if (err)
+			goto error_module;
 	}
 
 	/* This just returns 0 if either of the two args is NULL */
 	err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
-	if (err) {
-		if (sd->internal_ops && sd->internal_ops->unregistered)
-			sd->internal_ops->unregistered(sd);
-		module_put(sd->owner);
-		return err;
-	}
+	if (err)
+		goto error_unregister;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	/* Register the entity. */
 	if (v4l2_dev->mdev) {
 		err = media_device_register_entity(v4l2_dev->mdev, entity);
-		if (err < 0) {
-			if (sd->internal_ops && sd->internal_ops->unregistered)
-				sd->internal_ops->unregistered(sd);
-			module_put(sd->owner);
-			return err;
-		}
+		if (err < 0)
+			goto error_unregister;
 	}
 #endif
 
@@ -192,6 +182,14 @@ int v4l2_device_register_subdev(struct v
 	spin_unlock(&v4l2_dev->lock);
 
 	return 0;
+
+error_unregister:
+	if (sd->internal_ops && sd->internal_ops->unregistered)
+		sd->internal_ops->unregistered(sd);
+error_module:
+	module_put(sd->owner);
+	sd->v4l2_dev = NULL;
+	return err;
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
 
author maintainer
#127 lore raw

PATCH 127/134 media: omap_vout: find_vma() needs ->mmap_sem held

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <[email protected]>

commit 55ee64b30a38d688232e5eb2860467dddc493573 upstream.

Walking rbtree while it's modified is a Bad Idea(tm); besides, the result of find_vma() can be freed just as it's getting returned to caller. Fortunately, it's easy to fix - just take ->mmap_sem a bit earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET - in that case we don't even look at its result).

While we are at it, what prevents VIDIOC_PREPARE_BUF calling v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() -> __buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() -> find_vma(), AFAICS without having taken ->mmap_sem anywhere in process? The code flow is bloody convoluted and depends on a bunch of things done by initialization, so I certainly might've missed something...

Cc Sakari Ailus <[email protected]>
Cc Laurent Pinchart <[email protected]>
Cc Archit Taneja <[email protected]>
Cc Prabhakar Lad <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Cc Jianguo Wu <[email protected]>
---
 drivers/media/video/omap/omap_vout.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/media/video/omap/omap_vout.c +7 -5
@@ -206,19 +206,21 @@ static u32 omap_vout_uservirt_to_phys(u3
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 
-	vma = find_vma(mm, virtp);
 	/* For kernel direct-mapped memory, take the easy way */
-	if (virtp >= PAGE_OFFSET) {
-		physp = virt_to_phys((void *) virtp);
-	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
+	if (virtp >= PAGE_OFFSET)
+		return virt_to_phys((void *) virtp);
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma(mm, virtp);
+	if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
 		/* this will catch, kernel-allocated, mmaped-to-usermode
 		   addresses */
 		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
+		up_read(&current->mm->mmap_sem);
 	} else {
 		/* otherwise, use get_user_pages() for general userland pages */
 		int res, nr_pages = 1;
 		struct page *pages;
-		down_read(&current->mm->mmap_sem);
 
 		res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
 				0, &pages, NULL);
author maintainer
#128 lore raw

PATCH 128/134 media: dmxdev: remove dvb_ringbuffer_flush() on writer side

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Soeren Moch <[email protected]>

commit 414abbd2cd4c2618895f02ed3a76ec6647281436 upstream.

In dvb_ringbuffer lock-less synchronizationof reader and writer threads is done with separateread and write pointers. Sincedvb_ringbuffer_flush() modifies the read pointer, this function must not be called from the writer thread. This patch removes the dvb_ringbuffer_flush() calls in the dmxdev ringbuffer write functions, this fixes Oopses "Unable to handle kernel paging request" I could observe for the call chaindvb_demux_read ->dvb_dmxdev_buffer_read -> dvb_ringbuffer_read_user -> __copy_to_user (the reader side of the ringbuffer). The flush calls at the write side are not necessary anyway since ringbuffer_flush is also called in dvb_dmxdev_buffer_read() when an error condition is set in the ringbuffer.
This patch should also be applied to stable kernels.

---
 drivers/media/dvb/dvb-core/dmxdev.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/media/dvb/dvb-core/dmxdev.c +2 -6
@@ -379,10 +379,8 @@ static int dvb_dmxdev_section_callback(c
 		ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
 					      buffer2_len);
 	}
-	if (ret < 0) {
-		dvb_ringbuffer_flush(&dmxdevfilter->buffer);
+	if (ret < 0)
 		dmxdevfilter->buffer.error = ret;
-	}
 	if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
 		dmxdevfilter->state = DMXDEV_STATE_DONE;
 	spin_unlock(&dmxdevfilter->dev->lock);
@@ -418,10 +416,8 @@ static int dvb_dmxdev_ts_callback(const
 	ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
 	if (ret == buffer1_len)
 		ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
-	if (ret < 0) {
-		dvb_ringbuffer_flush(buffer);
+	if (ret < 0)
 		buffer->error = ret;
-	}
 	spin_unlock(&dmxdevfilter->dev->lock);
 	wake_up(&buffer->queue);
 	return 0;
author maintainer
#129 lore raw

PATCH 129/134 media: hdpvr: register the video node at the end of probe

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hans Verkuil <[email protected]>

commit 280847b532433ffe7a22795f926327805a127162 upstream.

Video nodes can be used at once after registration, so make sure the full initialization is done before registering them.

[bwh: Backported to 3.2: adjust filename, context]
Cc Jianguo Wu <[email protected]>
---
 drivers/media/video/hdpvr/hdpvr-core.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/media/video/hdpvr/hdpvr-core.c +7 -6
@@ -385,12 +385,6 @@ static int hdpvr_probe(struct usb_interf
 	}
 	mutex_unlock(&dev->io_mutex);
 
-	if (hdpvr_register_videodev(dev, &interface->dev,
-				    video_nr[atomic_inc_return(&dev_nr)])) {
-		v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
-		goto error;
-	}
-
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	retval = hdpvr_register_i2c_adapter(dev);
 	if (retval < 0) {
@@ -411,6 +405,13 @@ static int hdpvr_probe(struct usb_interf
 	}
 #endif
 
+	retval = hdpvr_register_videodev(dev, &interface->dev,
+				    video_nr[atomic_inc_return(&dev_nr)]);
+	if (retval < 0) {
+		v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+		goto error;
+	}
+
 	/* let the user know what node this device is now attached to */
 	v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
 		  video_device_node_name(dev->video_dev));
author maintainer
#130 lore raw

PATCH 130/134 media: hdpvr: fix iteration over uninitialized lists in hdpvr_probe()

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexey Khoroshilov <[email protected]>

commit 2e923a0527ac439e135b9961e58d3acd876bba10 upstream.

free_buff_list and rec_buff_list are initialized in the middle of hdpvr_probe(), but if something bad happens before that, error handling code calls hdpvr_delete(), which contains iteration over the lists (via hdpvr_free_buffers()). The patch moves the lists initialization to the beginning and by the way fixes goto label in error handling of registering videodev.
Found by Linux Driver Verification project (linuxtesting.org).

---
 drivers/media/video/hdpvr/hdpvr-core.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/media/video/hdpvr/hdpvr-core.c +6 -5
@@ -309,6 +309,11 @@ static int hdpvr_probe(struct usb_interf
 
 	dev->workqueue = 0;
 
+	/* init video transfer queues first of all */
+	/* to prevent oops in hdpvr_delete() on error paths */
+	INIT_LIST_HEAD(&dev->free_buff_list);
+	INIT_LIST_HEAD(&dev->rec_buff_list);
+
 	/* register v4l2_device early so it can be used for printks */
 	if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
 		err("v4l2_device_register failed");
@@ -331,10 +336,6 @@ static int hdpvr_probe(struct usb_interf
 	if (!dev->workqueue)
 		goto error;
 
-	/* init video transfer queues */
-	INIT_LIST_HEAD(&dev->free_buff_list);
-	INIT_LIST_HEAD(&dev->rec_buff_list);
-
 	dev->options = hdpvr_default_options;
 
 	if (default_video_input < HDPVR_VIDEO_INPUTS)
@@ -409,7 +410,7 @@ static int hdpvr_probe(struct usb_interf
 				    video_nr[atomic_inc_return(&dev_nr)]);
 	if (retval < 0) {
 		v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
-		goto error;
+		goto reg_fail;
 	}
 
 	/* let the user know what node this device is now attached to */
author maintainer
#131 lore raw

PATCH 131/134 media: saa7164: fix return value check in saa7164_initdev()

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wei Yongjun <[email protected]>

commit 89f4d45b2752df5d222b5f63919ce59e2d8afaf4 upstream.

In case of error, the function kthread_run() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().

---
 drivers/media/video/saa7164/saa7164-core.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/video/saa7164/saa7164-core.c +3 -1
@@ -1386,9 +1386,11 @@ static int __devinit saa7164_initdev(str
 		if (fw_debug) {
 			dev->kthread = kthread_run(saa7164_thread_function, dev,
 				"saa7164 debug");
-			if (!dev->kthread)
+			if (IS_ERR(dev->kthread)) {
+				dev->kthread = NULL;
 				printk(KERN_ERR "%s() Failed to create "
 					"debug kernel thread\n", __func__);
+			}
 		}
 
 	} /* != BOARD_UNKNOWN */
author maintainer
#132 lore raw

PATCH 132/134 powernow-k6: disable cache when changing frequency

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mikulas Patocka <[email protected]>

commit e20e1d0ac02308e2211306fc67abcd0b2668fb8b upstream.

I found out that a system with k6-3+ processor is unstable during network server load. The system locks up or the network card stops receiving. The reason for the instability is the CPU frequency scaling.

During frequency transition the processor is in "EPM Stop Grant" state. The documentation says that the processor doesn't respond to inquiry requests in this state. Consequently, coherency of processor caches and bus master devices is not maintained, causing the system instability.

This patch flushes the cache during frequency transition. It fixes the instability.

Other minor changes:
* u64 invalue changed to unsigned long because the variable is 32-bit
* move the logic to set the multiplier to a separate function powernow_k6_set_cpu_multiplier
* preserve lower 5 bits of the powernow port instead of 4 (the voltage field has 5 bits)
* mask interrupts when reading the multiplier, so that the port is not open during other activity (running other kernel code with the port open shouldn't cause any misbehavior, but we should better be safe and keep the port closed)

This patch should be backported to all stable kernels. If it doesn't apply cleanly, change it, or ask me to change it.

---
 drivers/cpufreq/powernow-k6.c |   56 +++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 17 deletions(-)
drivers/cpufreq/powernow-k6.c +39 -17
@@ -44,23 +44,58 @@ static struct cpufreq_frequency_table cl
 /**
  * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
  *
- *   Returns the current setting of the frequency multiplier. Core clock
+ * Returns the current setting of the frequency multiplier. Core clock
  * speed is frequency of the Front-Side Bus multiplied with this value.
  */
 static int powernow_k6_get_cpu_multiplier(void)
 {
-	u64 invalue = 0;
+	unsigned long invalue = 0;
 	u32 msrval;
 
+	local_irq_disable();
+
 	msrval = POWERNOW_IOPORT + 0x1;
 	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
 	invalue = inl(POWERNOW_IOPORT + 0x8);
 	msrval = POWERNOW_IOPORT + 0x0;
 	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
 
+	local_irq_enable();
+
 	return clock_ratio[(invalue >> 5)&7].index;
 }
 
+static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
+{
+	unsigned long outvalue, invalue;
+	unsigned long msrval;
+	unsigned long cr0;
+
+	/* we now need to transform best_i to the BVC format, see AMD#23446 */
+
+	/*
+	 * The processor doesn't respond to inquiry cycles while changing the
+	 * frequency, so we must disable cache.
+	 */
+	local_irq_disable();
+	cr0 = read_cr0();
+	write_cr0(cr0 | X86_CR0_CD);
+	wbinvd();
+
+	outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
+
+	msrval = POWERNOW_IOPORT + 0x1;
+	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+	invalue = inl(POWERNOW_IOPORT + 0x8);
+	invalue = invalue & 0x1f;
+	outvalue = outvalue | invalue;
+	outl(outvalue, (POWERNOW_IOPORT + 0x8));
+	msrval = POWERNOW_IOPORT + 0x0;
+	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+
+	write_cr0(cr0);
+	local_irq_enable();
+}
 
 /**
  * powernow_k6_set_state - set the PowerNow! multiplier
@@ -70,8 +105,6 @@ static int powernow_k6_get_cpu_multiplie
  */
 static void powernow_k6_set_state(unsigned int best_i)
 {
-	unsigned long outvalue = 0, invalue = 0;
-	unsigned long msrval;
 	struct cpufreq_freqs freqs;
 
 	if (clock_ratio[best_i].index > max_multiplier) {
@@ -85,18 +118,7 @@ static void powernow_k6_set_state(unsign
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
-	/* we now need to transform best_i to the BVC format, see AMD#23446 */
-
-	outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
-
-	msrval = POWERNOW_IOPORT + 0x1;
-	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
-	invalue = inl(POWERNOW_IOPORT + 0x8);
-	invalue = invalue & 0xf;
-	outvalue = outvalue | invalue;
-	outl(outvalue , (POWERNOW_IOPORT + 0x8));
-	msrval = POWERNOW_IOPORT + 0x0;
-	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+	powernow_k6_set_cpu_multiplier(best_i);
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
@@ -164,7 +186,7 @@ static int powernow_k6_cpu_init(struct c
 	}
 
 	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = 200000;
+	policy->cpuinfo.transition_latency = 500000;
 	policy->cur = busfreq * max_multiplier;
 
 	result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
author maintainer
#133 lore raw

PATCH 133/134 powernow-k6: correctly initialize default parameters

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mikulas Patocka <[email protected]>

commit d82b922a4acc1781d368aceac2f9da43b038cab2 upstream.

The powernow-k6 driver used to read the initial multiplier from the powernow register. However, there is a problem with this:

* If there was a frequency transition before, the multiplier read from the register corresponds to the current multiplier.
* If there was no frequency transition since reset, the field in the register always reads as zero, regardless of the current multiplier that is set using switches on the mainboard and that the CPU is running at.

The zero value corresponds to multiplier 4.5, so as a consequence, the powernow-k6 driver always assumes multiplier 4.5.

For example, if we have 550MHz CPU with bus frequency 100MHz and multiplier 5.5, the powernow-k6 driver thinks that the multiplier is 4.5 and bus frequency is 122MHz. The powernow-k6 driver then sets the multiplier to 4.5, underclocking the CPU to 450MHz, but reports the current frequency as 550MHz.

There is no reliable way how to read the initial multiplier. I modified the driver so that it contains a table of known frequencies (based on parameters of existing CPUs and some common overclocking schemes) and sets the multiplier according to the frequency. If the frequency is unknown (because of unusual overclocking or underclocking), the user must supply the bus speed and maximum multiplier as module parameters.

This patch should be backported to all stable kernels. If it doesn't apply cleanly, change it, or ask me to change it.

---
 drivers/cpufreq/powernow-k6.c |   76 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 4 deletions(-)
drivers/cpufreq/powernow-k6.c +72 -4
@@ -26,6 +26,14 @@
 static unsigned int                     busfreq;   /* FSB, in 10 kHz */
 static unsigned int                     max_multiplier;
 
+static unsigned int			param_busfreq = 0;
+static unsigned int			param_max_multiplier = 0;
+
+module_param_named(max_multiplier, param_max_multiplier, uint, S_IRUGO);
+MODULE_PARM_DESC(max_multiplier, "Maximum multiplier (allowed values: 20 30 35 40 45 50 55 60)");
+
+module_param_named(bus_frequency, param_busfreq, uint, S_IRUGO);
+MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz");
 
 /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
 static struct cpufreq_frequency_table clock_ratio[] = {
@@ -40,6 +48,27 @@ static struct cpufreq_frequency_table cl
 	{0, CPUFREQ_TABLE_END}
 };
 
+static const struct {
+	unsigned freq;
+	unsigned mult;
+} usual_frequency_table[] = {
+	{ 400000, 40 },	// 100   * 4
+	{ 450000, 45 }, // 100   * 4.5
+	{ 475000, 50 }, //  95   * 5
+	{ 500000, 50 }, // 100   * 5
+	{ 506250, 45 }, // 112.5 * 4.5
+	{ 533500, 55 }, //  97   * 5.5
+	{ 550000, 55 }, // 100   * 5.5
+	{ 562500, 50 }, // 112.5 * 5
+	{ 570000, 60 }, //  95   * 6
+	{ 600000, 60 }, // 100   * 6
+	{ 618750, 55 }, // 112.5 * 5.5
+	{ 660000, 55 }, // 120   * 5.5
+	{ 675000, 60 }, // 112.5 * 6
+	{ 720000, 60 }, // 120   * 6
+};
+
+#define FREQ_RANGE		3000
 
 /**
  * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
@@ -163,18 +192,57 @@ static int powernow_k6_target(struct cpu
 	return 0;
 }
 
-
 static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
 {
 	unsigned int i, f;
 	int result;
+	unsigned khz;
 
 	if (policy->cpu != 0)
 		return -ENODEV;
 
-	/* get frequencies */
-	max_multiplier = powernow_k6_get_cpu_multiplier();
-	busfreq = cpu_khz / max_multiplier;
+	max_multiplier = 0;
+	khz = cpu_khz;
+	for (i = 0; i < ARRAY_SIZE(usual_frequency_table); i++) {
+		if (khz >= usual_frequency_table[i].freq - FREQ_RANGE &&
+		    khz <= usual_frequency_table[i].freq + FREQ_RANGE) {
+			khz = usual_frequency_table[i].freq;
+			max_multiplier = usual_frequency_table[i].mult;
+			break;
+		}
+	}
+	if (param_max_multiplier) {
+		for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+			if (clock_ratio[i].index == param_max_multiplier) {
+				max_multiplier = param_max_multiplier;
+				goto have_max_multiplier;
+			}
+		}
+		printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n");
+		return -EINVAL;
+	}
+
+	if (!max_multiplier) {
+		printk(KERN_WARNING "powernow-k6: unknown frequency %u, cannot determine current multiplier\n", khz);
+		printk(KERN_WARNING "powernow-k6: use module parameters max_multiplier and bus_frequency\n");
+		return -EOPNOTSUPP;
+	}
+
+have_max_multiplier:
+	param_max_multiplier = max_multiplier;
+
+	if (param_busfreq) {
+		if (param_busfreq >= 50000 && param_busfreq <= 150000) {
+			busfreq = param_busfreq / 10;
+			goto have_busfreq;
+		}
+		printk(KERN_ERR "powernow-k6: invalid bus_frequency parameter, allowed range 50000 - 150000 kHz\n");
+		return -EINVAL;
+	}
+
+	busfreq = khz / max_multiplier;
+have_busfreq:
+	param_busfreq = busfreq * 10;
 
 	/* table init */
 	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
author maintainer
#134 lore raw

PATCH 134/134 powernow-k6: reorder frequencies

In reply to Greg Kroah-Hartman

3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mikulas Patocka <[email protected]>

commit 22c73795b101597051924556dce019385a1e2fa0 upstream.

This patch reorders reported frequencies from the highest to the lowest, just like in other frequency drivers.

---
 drivers/cpufreq/powernow-k6.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/cpufreq/powernow-k6.c +10 -7
@@ -37,17 +37,20 @@ MODULE_PARM_DESC(bus_frequency, "Bus fre
 
 /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
 static struct cpufreq_frequency_table clock_ratio[] = {
-	{45,  /* 000 -> 4.5x */ 0},
+	{60,  /* 110 -> 6.0x */ 0},
+	{55,  /* 011 -> 5.5x */ 0},
 	{50,  /* 001 -> 5.0x */ 0},
+	{45,  /* 000 -> 4.5x */ 0},
 	{40,  /* 010 -> 4.0x */ 0},
-	{55,  /* 011 -> 5.5x */ 0},
-	{20,  /* 100 -> 2.0x */ 0},
-	{30,  /* 101 -> 3.0x */ 0},
-	{60,  /* 110 -> 6.0x */ 0},
 	{35,  /* 111 -> 3.5x */ 0},
+	{30,  /* 101 -> 3.0x */ 0},
+	{20,  /* 100 -> 2.0x */ 0},
 	{0, CPUFREQ_TABLE_END}
 };
 
+static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 };
+static const u8 register_to_index[8] = { 3, 2, 4, 1, 7, 6, 0, 5 };
+
 static const struct {
 	unsigned freq;
 	unsigned mult;
@@ -91,7 +94,7 @@ static int powernow_k6_get_cpu_multiplie
 
 	local_irq_enable();
 
-	return clock_ratio[(invalue >> 5)&7].index;
+	return clock_ratio[register_to_index[(invalue >> 5)&7]].index;
 }
 
 static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
@@ -111,7 +114,7 @@ static void powernow_k6_set_cpu_multipli
 	write_cr0(cr0 | X86_CR0_CD);
 	wbinvd();
 
-	outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
+	outvalue = (1<<12) | (1<<10) | (1<<9) | (index_to_register[best_i]<<5);
 
 	msrval = POWERNOW_IOPORT + 0x1;
 	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
#135 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

Build results:

	total: 119 pass: 97 skipped: 18 fail: 4

Qemu tests all passed.

Results are as expected.

Details are available at http://server.roeck-us.net:8010/builders.
Test scripts are at https://github.com/groeck/linux-build-test.

Guenter

author maintainer
#136 lore raw
Quoted 11 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

Build results:

Quoted 8 lines
	total: 119 pass: 97 skipped: 18 fail: 4

Qemu tests all passed.

Results are as expected.

Details are available at http://server.roeck-us.net:8010/builders.
Test scripts are at https://github.com/groeck/linux-build-test.

Great, thanks for testing and letting me know.

greg k-h

#137 lore raw
In reply to Greg Kroah-Hartman
Quoted 5 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Quoted 7 lines

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.87-rc1.gz

and the diffstat can be found below.

Compiled and booted on my test systems. No dmesg regressions.

-- Shuah

Signature · 4 lines
Shuah Khan
Senior Linux Kernel Developer - Open Source Group
Samsung Research America(Silicon Valley)
[email protected] | (970) 672-0658
author maintainer
#138 lore raw
Quoted 9 lines · Shuah Khan
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

Quoted 6 lines
Quoted 4 lines

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.87-rc1.gz

and the diffstat can be found below.

Compiled and booted on my test systems. No dmesg regressions.

Wonderful, thanks for the testing.

greg k-h

#139 lore raw
In reply to Shuah Khan

At Thu, 10 Apr 2014 13:56:29 -0600,

Quoted 10 lines · Shuah Khan
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

Quoted 6 lines
Quoted 4 lines

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.87-rc1.gz

and the diffstat can be found below.

Compiled and booted on my test systems. No dmesg regressions.

This kernel passed my test.

- Test Cases:
- Build this kernel.
- Boot this kernel.
- Build the latest mainline kernel with this kernel.

- Test Tool:
https://github.com/satoru-takeuchi/test-linux-stable

- Test Result (kernel .config, ktest config and test log):
http://satoru-takeuchi.org/test-linux-stable/results/<version>-<test datetime>.tar.xz

- Build Environment:
- OS: Debian Jessy x86_64
- CPU: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz x 4
- memory: 8GB

- Test Target Environment:
- Debian Jessy x86_64 (KVM guest on the Build Environment)
- # of vCPU: 2
- memory: 2GB

Thanks,
Satoru

author maintainer
#140 lore raw
Quoted 37 lines · Satoru Takeuchi

At Thu, 10 Apr 2014 13:56:29 -0600,

Quoted 10 lines · Shuah Khan
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.4.87 release. There are 134 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat Apr 12 03:22:28 UTC 2014. Anything received after that time might be too late.

Quoted 6 lines
Quoted 4 lines

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.87-rc1.gz

and the diffstat can be found below.

Compiled and booted on my test systems. No dmesg regressions.

This kernel passed my test.

- Test Cases:
- Build this kernel.
- Boot this kernel.
- Build the latest mainline kernel with this kernel.

- Test Tool:
https://github.com/satoru-takeuchi/test-linux-stable

- Test Result (kernel .config, ktest config and test log):
http://satoru-takeuchi.org/test-linux-stable/results/<version>-<test datetime>.tar.xz

- Build Environment:
- OS: Debian Jessy x86_64
- CPU: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz x 4
- memory: 8GB

Quoted 4 lines

- Test Target Environment:
- Debian Jessy x86_64 (KVM guest on the Build Environment)
- # of vCPU: 2
- memory: 2GB

Wonderful, thanks for testing.

greg k-h