ASoC: Fixes for v3.15
A smattering of driver-specific fixes here, nothing generic. The Cirrus CODEC conversions to devm_ are leak fixes - the conversion adds missing error handling code. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTV5/GAAoJELSic+t+oim9PzQP/0byUSlYxSZArd9HekWmVu6/ 4oPj9+vD/vltFEvU18J3kMZFONQ5QZGQAojyTqrBTWO/QX/veu3tI0dOZay4mB20 1AhjXFyNC8r5njFJquQxYY3u13oU4SIklja0dePDZ5DRkMx3Xsl5QDuSDT6wHc97 YmvvjAQFwcZQYb7RkJnlyA3mKTX/Fsy8v2WIQRrsZFsqi+/ceq3eMe/rtgL0dVFD lSszCGHjzd+NIYyutKxqBn9oZ29IIcE3su46HE92tZR+5LqbY+Zl8mAIEj6mVQ78 EzQiVmN46sibZ6+loQllGdn4W1YPBwYRpfbDAOnZNkwq8I6wcxZ7dOvzeYyCknGI Lljv0vugxgZpdiMeW/1TlVRhN53PPlnOQzd41/wN3Hwzjh98+/kPWkbx1IKP/GyZ KhP74wNqsknbCFd+KVEqBWL0Y/utAGo1o6R/XGGttefDaofdAaj7kXx8ruhkoAnc spHqKO5ibac8DqO/9iOI2IlfzJU8dxgkiB1krYNC4ThOQQcWoOTgCUEGCD9bzvkM nHXEYdQtH2wiAcjveNtIbA+Mr8uFtwKQJAABTdSaQZUtEY9gXrQaMBJ5JowHV3/Z MoZJB6IRUYELF/HOrnem07U0cC4jfkzFs9Qp6t3gS8PDVJz6ZqoTpQke51+99dgu etiBnNhtwLs5YRPQKg0w =SzzI -----END PGP SIGNATURE----- Merge tag 'asoc-v3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Fixes for v3.15 A smattering of driver-specific fixes here, nothing generic. The Cirrus CODEC conversions to devm_ are leak fixes - the conversion adds missing error handling code.
This commit is contained in:
Коммит
474a596107
1
.mailmap
1
.mailmap
|
@ -99,6 +99,7 @@ Sachin P Sant <ssant@in.ibm.com>
|
|||
Sam Ravnborg <sam@mars.ravnborg.org>
|
||||
Sascha Hauer <s.hauer@pengutronix.de>
|
||||
S.Çağlar Onur <caglar@pardus.org.tr>
|
||||
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
|
||||
Simon Kelley <simon@thekelleys.org.uk>
|
||||
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
||||
Stephen Hemminger <shemminger@osdl.org>
|
||||
|
|
|
@ -276,7 +276,7 @@ X!Isound/sound_firmware.c
|
|||
</para>
|
||||
|
||||
<sect1><title>Frame Buffer Memory</title>
|
||||
!Edrivers/video/fbmem.c
|
||||
!Edrivers/video/fbdev/core/fbmem.c
|
||||
</sect1>
|
||||
<!--
|
||||
<sect1><title>Frame Buffer Console</title>
|
||||
|
@ -284,7 +284,7 @@ X!Edrivers/video/console/fbcon.c
|
|||
</sect1>
|
||||
-->
|
||||
<sect1><title>Frame Buffer Colormap</title>
|
||||
!Edrivers/video/fbcmap.c
|
||||
!Edrivers/video/fbdev/core/fbcmap.c
|
||||
</sect1>
|
||||
<!-- FIXME:
|
||||
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
|
||||
|
@ -294,11 +294,11 @@ X!Idrivers/video/fbgen.c
|
|||
</sect1>
|
||||
KAO -->
|
||||
<sect1><title>Frame Buffer Video Mode Database</title>
|
||||
!Idrivers/video/modedb.c
|
||||
!Edrivers/video/modedb.c
|
||||
!Idrivers/video/fbdev/core/modedb.c
|
||||
!Edrivers/video/fbdev/core/modedb.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
|
||||
!Edrivers/video/macmodes.c
|
||||
!Edrivers/video/fbdev/macmodes.c
|
||||
</sect1>
|
||||
<sect1><title>Frame Buffer Fonts</title>
|
||||
<para>
|
||||
|
|
|
@ -2285,6 +2285,11 @@ void intel_crt_init(struct drm_device *dev)
|
|||
<sect2>
|
||||
<title>Modeset Helper Functions Reference</title>
|
||||
!Edrivers/gpu/drm/drm_crtc_helper.c
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Output Probing Helper Functions Reference</title>
|
||||
!Pdrivers/gpu/drm/drm_probe_helper.c output probing helper overview
|
||||
!Edrivers/gpu/drm/drm_probe_helper.c
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>fbdev Helper Functions Reference</title>
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
Marvell Kirkwood SoC Family Device Tree Bindings
|
||||
------------------------------------------------
|
||||
|
||||
Boards with a SoC of the Marvell Kirkwook family, eg 88f6281
|
||||
|
||||
* Required root node properties:
|
||||
compatible: must contain "marvell,kirkwood"
|
||||
|
||||
In addition, the above compatible shall be extended with the specific
|
||||
SoC. Currently known SoC compatibles are:
|
||||
|
||||
"marvell,kirkwood-88f6192"
|
||||
"marvell,kirkwood-88f6281"
|
||||
"marvell,kirkwood-88f6282"
|
||||
"marvell,kirkwood-88f6283"
|
||||
"marvell,kirkwood-88f6702"
|
||||
"marvell,kirkwood-98DX4122"
|
||||
|
||||
And in addition, the compatible shall be extended with the specific
|
||||
board. Currently known boards are:
|
||||
|
||||
"buffalo,lschlv2"
|
||||
"buffalo,lsxhl"
|
||||
"buffalo,lsxl"
|
||||
"dlink,dns-320"
|
||||
"dlink,dns-320-a1"
|
||||
"dlink,dns-325"
|
||||
"dlink,dns-325-a1"
|
||||
"dlink,dns-kirkwood"
|
||||
"excito,b3"
|
||||
"globalscale,dreamplug-003-ds2001"
|
||||
"globalscale,guruplug"
|
||||
"globalscale,guruplug-server-plus"
|
||||
"globalscale,sheevaplug"
|
||||
"globalscale,sheevaplug"
|
||||
"globalscale,sheevaplug-esata"
|
||||
"globalscale,sheevaplug-esata-rev13"
|
||||
"iom,iconnect"
|
||||
"iom,iconnect-1.1"
|
||||
"iom,ix2-200"
|
||||
"keymile,km_kirkwood"
|
||||
"lacie,cloudbox"
|
||||
"lacie,inetspace_v2"
|
||||
"lacie,laplug"
|
||||
"lacie,netspace_lite_v2"
|
||||
"lacie,netspace_max_v2"
|
||||
"lacie,netspace_mini_v2"
|
||||
"lacie,netspace_v2"
|
||||
"marvell,db-88f6281-bp"
|
||||
"marvell,db-88f6282-bp"
|
||||
"marvell,mv88f6281gtw-ge"
|
||||
"marvell,rd88f6281"
|
||||
"marvell,rd88f6281"
|
||||
"marvell,rd88f6281-a0"
|
||||
"marvell,rd88f6281-a1"
|
||||
"mpl,cec4"
|
||||
"mpl,cec4-10"
|
||||
"netgear,readynas"
|
||||
"netgear,readynas"
|
||||
"netgear,readynas-duo-v2"
|
||||
"netgear,readynas-nv+-v2"
|
||||
"plathome,openblocks-a6"
|
||||
"plathome,openblocks-a7"
|
||||
"raidsonic,ib-nas6210"
|
||||
"raidsonic,ib-nas6210-b"
|
||||
"raidsonic,ib-nas6220"
|
||||
"raidsonic,ib-nas6220-b"
|
||||
"raidsonic,ib-nas62x0"
|
||||
"seagate,dockstar"
|
||||
"seagate,goflexnet"
|
||||
"synology,ds109"
|
||||
"synology,ds110jv10"
|
||||
"synology,ds110jv20"
|
||||
"synology,ds110jv30"
|
||||
"synology,ds111"
|
||||
"synology,ds209"
|
||||
"synology,ds210jv10"
|
||||
"synology,ds210jv20"
|
||||
"synology,ds212"
|
||||
"synology,ds212jv10"
|
||||
"synology,ds212jv20"
|
||||
"synology,ds212pv10"
|
||||
"synology,ds409"
|
||||
"synology,ds409slim"
|
||||
"synology,ds410j"
|
||||
"synology,ds411"
|
||||
"synology,ds411j"
|
||||
"synology,ds411slim"
|
||||
"synology,ds413jv10"
|
||||
"synology,rs212"
|
||||
"synology,rs409"
|
||||
"synology,rs411"
|
||||
"synology,rs812"
|
||||
"usi,topkick"
|
||||
"usi,topkick-1281P2"
|
||||
"zyxel,nsa310"
|
||||
"zyxel,nsa310a"
|
|
@ -13,8 +13,22 @@ ad,ad7414 SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert an
|
|||
ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
|
||||
adi,adt7461 +/-1C TDM Extended Temp Range I.C
|
||||
adt7461 +/-1C TDM Extended Temp Range I.C
|
||||
adi,adt7473 +/-1C TDM Extended Temp Range I.C
|
||||
adi,adt7475 +/-1C TDM Extended Temp Range I.C
|
||||
adi,adt7476 +/-1C TDM Extended Temp Range I.C
|
||||
adi,adt7490 +/-1C TDM Extended Temp Range I.C
|
||||
at,24c08 i2c serial eeprom (24cxx)
|
||||
atmel,24c00 i2c serial eeprom (24cxx)
|
||||
atmel,24c01 i2c serial eeprom (24cxx)
|
||||
atmel,24c02 i2c serial eeprom (24cxx)
|
||||
atmel,24c04 i2c serial eeprom (24cxx)
|
||||
atmel,24c16 i2c serial eeprom (24cxx)
|
||||
atmel,24c32 i2c serial eeprom (24cxx)
|
||||
atmel,24c64 i2c serial eeprom (24cxx)
|
||||
atmel,24c128 i2c serial eeprom (24cxx)
|
||||
atmel,24c256 i2c serial eeprom (24cxx)
|
||||
atmel,24c512 i2c serial eeprom (24cxx)
|
||||
atmel,24c1024 i2c serial eeprom (24cxx)
|
||||
atmel,at97sc3204t i2c trusted platform module (TPM)
|
||||
capella,cm32181 CM32181: Ambient Light Sensor
|
||||
catalyst,24c32 i2c serial eeprom
|
||||
|
@ -46,8 +60,10 @@ maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
|
|||
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
|
||||
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
|
||||
mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
||||
national,lm63 Temperature sensor with integrated fan control
|
||||
national,lm75 I2C TEMP SENSOR
|
||||
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
|
||||
national,lm85 Temperature sensor with integrated fan control
|
||||
national,lm92 ±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
|
||||
nuvoton,npct501 i2c trusted platform module (TPM)
|
||||
nxp,pca9556 Octal SMBus and I2C registered interface
|
||||
|
|
|
@ -10,7 +10,7 @@ The following properties are common to the Ethernet controllers:
|
|||
- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
|
||||
the maximum frame size (there's contradiction in ePAPR).
|
||||
- phy-mode: string, operation mode of the PHY interface; supported values are
|
||||
"mii", "gmii", "sgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
|
||||
"mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
|
||||
"rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto
|
||||
standard property;
|
||||
- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
|
||||
|
|
|
@ -119,7 +119,7 @@ Optional Properties (for HDMI pins):
|
|||
Example:
|
||||
// pin controller node
|
||||
pinctrl@35004800 {
|
||||
compatible = "brcmbcm11351-pinctrl";
|
||||
compatible = "brcm,bcm11351-pinctrl";
|
||||
reg = <0x35004800 0x430>;
|
||||
|
||||
// pin configuration node
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
* Energymicro efm32 UART
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "efm32,uart"
|
||||
- compatible : Should be "energymicro,efm32-uart"
|
||||
- reg : Address and length of the register set
|
||||
- interrupts : Should contain uart interrupt
|
||||
|
||||
|
@ -13,7 +13,7 @@ Optional properties:
|
|||
Example:
|
||||
|
||||
uart@0x4000c400 {
|
||||
compatible = "efm32,uart";
|
||||
compatible = "energymicro,efm32-uart";
|
||||
reg = <0x4000c400 0x400>;
|
||||
interrupts = <15>;
|
||||
efm32,location = <0>;
|
||||
|
|
|
@ -13,6 +13,9 @@ Required properties:
|
|||
"ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP)
|
||||
|
||||
- reg - <int> - I2C slave address
|
||||
- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
|
||||
DVDD-supply : power supplies for the device as covered in
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
|
||||
Optional properties:
|
||||
|
@ -24,9 +27,6 @@ Optional properties:
|
|||
3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD
|
||||
If this node is not mentioned or if the value is unknown, then
|
||||
micbias is set to 2.0V.
|
||||
- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
|
||||
DVDD-supply : power supplies for the device as covered in
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
CODEC output pins:
|
||||
* HPL
|
||||
|
|
|
@ -22,6 +22,7 @@ auo AU Optronics Corporation
|
|||
avago Avago Technologies
|
||||
bosch Bosch Sensortec GmbH
|
||||
brcm Broadcom Corporation
|
||||
buffalo Buffalo, Inc.
|
||||
calxeda Calxeda
|
||||
capella Capella Microsystems, Inc
|
||||
cavium Cavium, Inc.
|
||||
|
@ -33,15 +34,18 @@ cortina Cortina Systems, Inc.
|
|||
crystalfontz Crystalfontz America, Inc.
|
||||
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
|
||||
davicom DAVICOM Semiconductor, Inc.
|
||||
dlink D-Link Systems, Inc.
|
||||
denx Denx Software Engineering
|
||||
digi Digi International Inc.
|
||||
dlink D-Link Corporation
|
||||
dmo Data Modul AG
|
||||
ebv EBV Elektronik
|
||||
edt Emerging Display Technologies
|
||||
emmicro EM Microelectronic
|
||||
epfl Ecole Polytechnique Fédérale de Lausanne
|
||||
epson Seiko Epson Corp.
|
||||
est ESTeem Wireless Modems
|
||||
eukrea Eukréa Electromatique
|
||||
excito Excito
|
||||
fsl Freescale Semiconductor
|
||||
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||
|
@ -53,13 +57,17 @@ haoyu Haoyu Microelectronic Co. Ltd.
|
|||
hisilicon Hisilicon Limited.
|
||||
honeywell Honeywell
|
||||
hp Hewlett Packard
|
||||
i2se I2SE GmbH
|
||||
ibm International Business Machines (IBM)
|
||||
idt Integrated Device Technologies, Inc.
|
||||
iom Iomega Corporation
|
||||
img Imagination Technologies Ltd.
|
||||
intel Intel Corporation
|
||||
intercontrol Inter Control Group
|
||||
isee ISEE 2007 S.L.
|
||||
isl Intersil
|
||||
karo Ka-Ro electronics GmbH
|
||||
keymile Keymile GmbH
|
||||
lacie LaCie
|
||||
lantiq Lantiq Semiconductor
|
||||
lg LG Corporation
|
||||
|
@ -70,9 +78,12 @@ maxim Maxim Integrated Products
|
|||
microchip Microchip Technology Inc.
|
||||
mosaixtech Mosaix Technologies, Inc.
|
||||
moxa Moxa
|
||||
mpl MPL AG
|
||||
mxicy Macronix International Co., Ltd.
|
||||
national National Semiconductor
|
||||
neonode Neonode Inc.
|
||||
netgear NETGEAR
|
||||
newhaven Newhaven Display International
|
||||
nintendo Nintendo
|
||||
nokia Nokia
|
||||
nvidia NVIDIA
|
||||
|
@ -82,10 +93,12 @@ opencores OpenCores.org
|
|||
panasonic Panasonic Corporation
|
||||
phytec PHYTEC Messtechnik GmbH
|
||||
picochip Picochip Ltd
|
||||
plathome Plat'Home Co., Ltd.
|
||||
powervr PowerVR (deprecated, use img)
|
||||
qca Qualcomm Atheros, Inc.
|
||||
qcom Qualcomm Technologies, Inc
|
||||
qnap QNAP Systems, Inc.
|
||||
raidsonic RaidSonic Technology GmbH
|
||||
ralink Mediatek/Ralink Technology Corp.
|
||||
ramtron Ramtron International
|
||||
realtek Realtek Semiconductor Corp.
|
||||
|
@ -95,6 +108,7 @@ rockchip Fuzhou Rockchip Electronics Co., Ltd
|
|||
samsung Samsung Semiconductor
|
||||
sbs Smart Battery System
|
||||
schindler Schindler
|
||||
seagate Seagate Technology PLC
|
||||
sil Silicon Image
|
||||
silabs Silicon Laboratories
|
||||
simtek
|
||||
|
@ -111,6 +125,7 @@ ti Texas Instruments
|
|||
tlm Trusted Logic Mobility
|
||||
toshiba Toshiba Corporation
|
||||
toumaz Toumaz
|
||||
usi Universal Scientifc Industrial Co., Ltd.
|
||||
v3 V3 Semiconductor
|
||||
via VIA Technologies, Inc.
|
||||
voipac Voipac Technologies s.r.o.
|
||||
|
@ -119,3 +134,4 @@ wlf Wolfson Microelectronics
|
|||
wm Wondermedia Technologies, Inc.
|
||||
xes Extreme Engineering Solutions (X-ES)
|
||||
xlnx Xilinx
|
||||
zyxel ZyXEL Communications Corp.
|
||||
|
|
|
@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー
|
|||
もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
|
||||
最新の安定版カーネルです。
|
||||
|
||||
3.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
|
||||
3.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
|
||||
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
|
||||
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
|
||||
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
|
||||
|
|
|
@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt
|
|||
|
||||
-stable ツリーにパッチを送付する手続き-
|
||||
|
||||
- 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
|
||||
- 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
|
||||
を送る。
|
||||
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
|
||||
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
|
||||
日かかる場合がある。
|
||||
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
|
||||
メンテナーによるレビューのために -stable キューに追加される。
|
||||
- パッチに stable@kernel.org のアドレスが付加されているときには、それ
|
||||
- パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
|
||||
が Linus のツリーに入る時に自動的に stable チームに email される。
|
||||
- セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
|
||||
- セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
|
||||
きではなく、代わりに security@kernel.org のアドレスに送られる。
|
||||
|
||||
レビューサイクル-
|
||||
|
|
|
@ -804,13 +804,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
dhash_entries= [KNL]
|
||||
Set number of hash buckets for dentry cache.
|
||||
|
||||
digi= [HW,SERIAL]
|
||||
IO parameters + enable/disable command.
|
||||
|
||||
digiepca= [HW,SERIAL]
|
||||
See drivers/char/README.epca and
|
||||
Documentation/serial/digiepca.txt.
|
||||
|
||||
disable= [IPV6]
|
||||
See Documentation/networking/ipv6.txt.
|
||||
|
||||
|
@ -2939,9 +2932,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
rhash_entries= [KNL,NET]
|
||||
Set number of hash buckets for route cache
|
||||
|
||||
riscom8= [HW,SERIAL]
|
||||
Format: <io_board1>[,<io_board2>[,...<io_boardN>]]
|
||||
|
||||
ro [KNL] Mount root device read-only on boot
|
||||
|
||||
root= [KNL] Root filesystem
|
||||
|
@ -3083,9 +3073,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
sonypi.*= [HW] Sony Programmable I/O Control Device driver
|
||||
See Documentation/laptops/sonypi.txt
|
||||
|
||||
specialix= [HW,SERIAL] Specialix multi-serial port adapter
|
||||
See Documentation/serial/specialix.txt.
|
||||
|
||||
spia_io_base= [HW,MTD]
|
||||
spia_fio_base=
|
||||
spia_pedr=
|
||||
|
|
|
@ -63,8 +63,6 @@ Magic Name Number Structure File
|
|||
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
|
||||
CMAGIC 0x0111 user include/linux/a.out.h
|
||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
|
||||
RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
|
||||
SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
|
||||
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
|
||||
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
|
||||
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
|
||||
|
@ -82,7 +80,6 @@ STRIP_MAGIC 0x5303 strip drivers/net/strip.c
|
|||
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
|
||||
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
|
||||
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
|
||||
ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
|
||||
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
|
||||
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
|
||||
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
|
||||
|
@ -94,13 +91,10 @@ USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c
|
|||
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
|
||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
|
||||
A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
|
||||
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
|
||||
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
|
||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
|
||||
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
|
||||
RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
|
||||
SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
|
||||
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
|
||||
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
|
||||
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
|
||||
|
@ -116,7 +110,6 @@ ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h
|
|||
CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
|
||||
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
|
||||
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
|
||||
STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
|
||||
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
|
||||
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
|
||||
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
|
||||
|
@ -127,10 +120,8 @@ SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
|
|||
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
|
||||
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
|
||||
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
|
||||
STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
|
||||
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
|
||||
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
|
||||
EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
|
||||
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
|
||||
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h
|
||||
I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
|
||||
|
@ -142,17 +133,14 @@ SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h
|
|||
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
|
||||
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
|
||||
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
|
||||
STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
|
||||
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
|
||||
KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
|
||||
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
|
||||
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
|
||||
STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
|
||||
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
|
||||
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
|
||||
CODA_MAGIC 0xC0DAC0DA coda_file_info fs/coda/coda_fs_i.h
|
||||
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h
|
||||
STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
|
||||
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
|
||||
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
|
||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
|
||||
|
|
|
@ -2,23 +2,15 @@
|
|||
- this file.
|
||||
README.cycladesZ
|
||||
- info on Cyclades-Z firmware loading.
|
||||
digiepca.txt
|
||||
- info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
|
||||
driver
|
||||
- intro to the low level serial driver.
|
||||
moxa-smartio
|
||||
- file with info on installing/using Moxa multiport serial driver.
|
||||
n_gsm.txt
|
||||
- GSM 0710 tty multiplexer howto.
|
||||
riscom8.txt
|
||||
- notes on using the RISCom/8 multi-port serial driver.
|
||||
rocket.txt
|
||||
- info on the Comtrol RocketPort multiport serial driver.
|
||||
serial-rs485.txt
|
||||
- info about RS485 structures and support in the kernel.
|
||||
specialix.txt
|
||||
- info on hardware/driver for specialix IO8+ multiport serial card.
|
||||
sx.txt
|
||||
- info on the Specialix SX/SI multiport serial driver.
|
||||
tty.txt
|
||||
- guide to the locking policies of the tty layer.
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
NOTE: This driver is obsolete. Digi provides a 2.6 driver (dgdm) at
|
||||
http://www.digi.com for PCI cards. They no longer maintain this driver,
|
||||
and have no 2.6 driver for ISA cards.
|
||||
|
||||
This driver requires a number of user-space tools. They can be acquired from
|
||||
http://www.digi.com, but only works with 2.4 kernels.
|
||||
|
||||
|
||||
The Digi Intl. epca driver.
|
||||
----------------------------
|
||||
The Digi Intl. epca driver for Linux supports the following boards:
|
||||
|
||||
Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve
|
||||
Digi EISA/Xem, PCI/Xem, PCI/Xr
|
||||
|
||||
Limitations:
|
||||
------------
|
||||
Currently the driver only autoprobes for supported PCI boards.
|
||||
|
||||
The Linux MAKEDEV command does not support generating the Digiboard
|
||||
Devices. Users executing digiConfig to setup EISA and PC series cards
|
||||
will have their device nodes automatically constructed (cud?? for ~CLOCAL,
|
||||
and ttyD?? for CLOCAL). Users wishing to boot their board from the LILO
|
||||
prompt, or those users booting PCI cards may use buildDIGI to construct
|
||||
the necessary nodes.
|
||||
|
||||
Notes:
|
||||
------
|
||||
This driver may be configured via LILO. For users who have already configured
|
||||
their driver using digiConfig, configuring from LILO will override previous
|
||||
settings. Multiple boards may be configured by issuing multiple LILO command
|
||||
lines. For examples see the bottom of this document.
|
||||
|
||||
Device names start at 0 and continue up. Beware of this as previous Digi
|
||||
drivers started device names with 1.
|
||||
|
||||
PCI boards are auto-detected and configured by the driver. PCI boards will
|
||||
be allocated device numbers (internally) beginning with the lowest PCI slot
|
||||
first. In other words a PCI card in slot 3 will always have higher device
|
||||
nodes than a PCI card in slot 1.
|
||||
|
||||
LILO config examples:
|
||||
---------------------
|
||||
Using LILO's APPEND command, a string of comma separated identifiers or
|
||||
integers can be used to configure supported boards. The six values in order
|
||||
are:
|
||||
|
||||
Enable/Disable this card or Override,
|
||||
Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2),
|
||||
EISA/Xem (3), PC/64Xe (4), PC/Xi (5),
|
||||
Enable/Disable alternate pin arrangement,
|
||||
Number of ports on this card,
|
||||
I/O Port where card is configured (in HEX if using string identifiers),
|
||||
Base of memory window (in HEX if using string identifiers),
|
||||
|
||||
NOTE : PCI boards are auto-detected and configured. Do not attempt to
|
||||
configure PCI boards with the LILO append command. If you wish to override
|
||||
previous configuration data (As set by digiConfig), but you do not wish to
|
||||
configure any specific card (Example if there are PCI cards in the system)
|
||||
the following override command will accomplish this:
|
||||
-> append="digi=2"
|
||||
|
||||
Samples:
|
||||
append="digiepca=E,PC/Xe,D,16,200,D0000"
|
||||
or
|
||||
append="digi=1,0,0,16,512,851968"
|
||||
|
||||
Supporting Tools:
|
||||
-----------------
|
||||
Supporting tools include digiDload, digiConfig, buildPCI, and ditty. See
|
||||
drivers/char/README.epca for more details. Note,
|
||||
this driver REQUIRES that digiDload be executed prior to it being used.
|
||||
Failure to do this will result in an ENODEV error.
|
||||
|
||||
Documentation:
|
||||
--------------
|
||||
Complete documentation for this product may be found in the tool package.
|
||||
|
||||
Sources of information and support:
|
||||
-----------------------------------
|
||||
Digi Intl. support site for this product:
|
||||
|
||||
-> http://www.digi.com
|
||||
|
||||
Acknowledgments:
|
||||
----------------
|
||||
Much of this work (And even text) was derived from a similar document
|
||||
supporting the original public domain DigiBoard driver Copyright (C)
|
||||
1994,1995 Troy De Jongh. Many thanks to Christoph Lameter
|
||||
(christoph@lameter.com) and Mike McLagan (mike.mclagan@linux.org) who authored
|
||||
and contributed to the original document.
|
||||
|
||||
Changelog:
|
||||
----------
|
||||
10-29-04: Update status of driver, remove dead links in document
|
||||
James Nelson <james4765@gmail.com>
|
||||
|
||||
2000 (?) Original Document
|
|
@ -1,36 +0,0 @@
|
|||
* NOTE - this is an unmaintained driver. The original author cannot be located.
|
||||
|
||||
SDL Communications is now SBS Technologies, and does not have any
|
||||
information on these ancient ISA cards on their website.
|
||||
|
||||
James Nelson <james4765@gmail.com> - 12-12-2004
|
||||
|
||||
This is the README for RISCom/8 multi-port serial driver
|
||||
(C) 1994-1996 D.Gorodchanin
|
||||
See file LICENSE for terms and conditions.
|
||||
|
||||
NOTE: English is not my native language.
|
||||
I'm sorry for any mistakes in this text.
|
||||
|
||||
Misc. notes for RISCom/8 serial driver, in no particular order :)
|
||||
|
||||
1) This driver can support up to 4 boards at time.
|
||||
Use string "riscom8=0xXXX,0xXXX,0xXXX,0xXXX" at LILO prompt, for
|
||||
setting I/O base addresses for boards. If you compile driver
|
||||
as module use modprobe options "iobase=0xXXX iobase1=0xXXX iobase2=..."
|
||||
|
||||
2) The driver partially supports famous 'setserial' program, you can use almost
|
||||
any of its options, excluding port & irq settings.
|
||||
|
||||
3) There are some misc. defines at the beginning of riscom8.c, please read the
|
||||
comments and try to change some of them in case of problems.
|
||||
|
||||
4) I consider the current state of the driver as BETA.
|
||||
|
||||
5) SDL Communications WWW page is http://www.sdlcomm.com.
|
||||
|
||||
6) You can use the MAKEDEV program to create RISCom/8 /dev/ttyL* entries.
|
||||
|
||||
7) Minor numbers for first board are 0-7, for second 8-15, etc.
|
||||
|
||||
22 Apr 1996.
|
|
@ -1,383 +0,0 @@
|
|||
|
||||
specialix.txt -- specialix IO8+ multiport serial driver readme.
|
||||
|
||||
|
||||
|
||||
Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
|
||||
|
||||
Specialix pays for the development and support of this driver.
|
||||
Please DO contact io8-linux@specialix.co.uk if you require
|
||||
support.
|
||||
|
||||
This driver was developed in the BitWizard linux device
|
||||
driver service. If you require a linux device driver for your
|
||||
product, please contact devices@BitWizard.nl for a quote.
|
||||
|
||||
This code is firmly based on the riscom/8 serial driver,
|
||||
written by Dmitry Gorodchanin. The specialix IO8+ card
|
||||
programming information was obtained from the CL-CD1865 Data
|
||||
Book, and Specialix document number 6200059: IO8+ Hardware
|
||||
Functional Specification, augmented by document number 6200088:
|
||||
Merak Hardware Functional Specification. (IO8+/PCI is also
|
||||
called Merak)
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
|
||||
USA.
|
||||
|
||||
|
||||
Intro
|
||||
=====
|
||||
|
||||
|
||||
This file contains some random information, that I like to have online
|
||||
instead of in a manual that can get lost. Ever misplace your Linux
|
||||
kernel sources? And the manual of one of the boards in your computer?
|
||||
|
||||
|
||||
Addresses and interrupts
|
||||
========================
|
||||
|
||||
Address dip switch settings:
|
||||
The dip switch sets bits 2-9 of the IO address.
|
||||
|
||||
9 8 7 6 5 4 3 2
|
||||
+-----------------+
|
||||
0 | X X X X X X X |
|
||||
| | = IoBase = 0x100
|
||||
1 | X |
|
||||
+-----------------+ ------ RS232 connectors ---->
|
||||
|
||||
| | |
|
||||
edge connector
|
||||
| | |
|
||||
V V V
|
||||
|
||||
Base address 0x100 caused a conflict in one of my computers once. I
|
||||
haven't the foggiest why. My Specialix card is now at 0x180. My
|
||||
other computer runs just fine with the Specialix card at 0x100....
|
||||
The card occupies 4 addresses, but actually only two are really used.
|
||||
|
||||
The PCI version doesn't have any dip switches. The BIOS assigns
|
||||
an IO address.
|
||||
|
||||
The driver now still autoprobes at 0x100, 0x180, 0x250 and 0x260. If
|
||||
that causes trouble for you, please report that. I'll remove
|
||||
autoprobing then.
|
||||
|
||||
The driver will tell the card what IRQ to use, so you don't have to
|
||||
change any jumpers to change the IRQ. Just use a command line
|
||||
argument (irq=xx) to the insmod program to set the interrupt.
|
||||
|
||||
The BIOS assigns the IRQ on the PCI version. You have no say in what
|
||||
IRQ to use in that case.
|
||||
|
||||
If your specialix cards are not at the default locations, you can use
|
||||
the kernel command line argument "specialix=io0,irq0,io1,irq1...".
|
||||
Here "io0" is the io address for the first card, and "irq0" is the
|
||||
irq line that the first card should use. And so on.
|
||||
|
||||
Examples.
|
||||
|
||||
You use the driver as a module and have three cards at 0x100, 0x250
|
||||
and 0x180. And some way or another you want them detected in that
|
||||
order. Moreover irq 12 is taken (e.g. by your PS/2 mouse).
|
||||
|
||||
insmod specialix.o iobase=0x100,0x250,0x180 irq=9,11,15
|
||||
|
||||
The same three cards, but now in the kernel would require you to
|
||||
add
|
||||
|
||||
specialix=0x100,9,0x250,11,0x180,15
|
||||
|
||||
to the command line. This would become
|
||||
|
||||
append="specialix=0x100,9,0x250,11,0x180,15"
|
||||
|
||||
in your /etc/lilo.conf file if you use lilo.
|
||||
|
||||
The Specialix driver is slightly odd: It allows you to have the second
|
||||
or third card detected without having a first card. This has
|
||||
advantages and disadvantages. A slot that isn't filled by an ISA card,
|
||||
might be filled if a PCI card is detected. Thus if you have an ISA
|
||||
card at 0x250 and a PCI card, you would get:
|
||||
|
||||
sx0: specialix IO8+ Board at 0x100 not found.
|
||||
sx1: specialix IO8+ Board at 0x180 not found.
|
||||
sx2: specialix IO8+ board detected at 0x250, IRQ 12, CD1865 Rev. B.
|
||||
sx3: specialix IO8+ Board at 0x260 not found.
|
||||
sx0: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
|
||||
|
||||
This would happen if you don't give any probe hints to the driver.
|
||||
If you would specify:
|
||||
|
||||
specialix=0x250,11
|
||||
|
||||
you'd get the following messages:
|
||||
|
||||
sx0: specialix IO8+ board detected at 0x250, IRQ 11, CD1865 Rev. B.
|
||||
sx1: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
|
||||
|
||||
ISA probing is aborted after the IO address you gave is exhausted, and
|
||||
the PCI card is now detected as the second card. The ISA card is now
|
||||
also forced to IRQ11....
|
||||
|
||||
|
||||
Baud rates
|
||||
==========
|
||||
|
||||
The rev 1.2 and below boards use a CL-CD1864. These chips can only
|
||||
do 64kbit. The rev 1.3 and newer boards use a CL-CD1865. These chips
|
||||
are officially capable of 115k2.
|
||||
|
||||
The Specialix card uses a 25MHz crystal (in times two mode, which in
|
||||
fact is a divided by two mode). This is not enough to reach the rated
|
||||
115k2 on all ports at the same time. With this clock rate you can only
|
||||
do 37% of this rate. This means that at 115k2 on all ports you are
|
||||
going to lose characters (The chip cannot handle that many incoming
|
||||
bits at this clock rate.) (Yes, you read that correctly: there is a
|
||||
limit to the number of -=bits=- per second that the chip can handle.)
|
||||
|
||||
If you near the "limit" you will first start to see a graceful
|
||||
degradation in that the chip cannot keep the transmitter busy at all
|
||||
times. However with a central clock this slow, you can also get it to
|
||||
miss incoming characters. The driver will print a warning message when
|
||||
you are outside the official specs. The messages usually show up in
|
||||
the file /var/log/messages .
|
||||
|
||||
The specialix card cannot reliably do 115k2. If you use it, you have
|
||||
to do "extensive testing" (*) to verify if it actually works.
|
||||
|
||||
When "mgetty" communicates with my modem at 115k2 it reports:
|
||||
got: +++[0d]ATQ0V1H0[0d][0d][8a]O[cb][0d][8a]
|
||||
^^^^ ^^^^ ^^^^
|
||||
|
||||
The three characters that have the "^^^" under them have suffered a
|
||||
bit error in the highest bit. In conclusion: I've tested it, and found
|
||||
that it simply DOESN'T work for me. I also suspect that this is also
|
||||
caused by the baud rate being just a little bit out of tune.
|
||||
|
||||
I upgraded the crystal to 66Mhz on one of my Specialix cards. Works
|
||||
great! Contact me for details. (Voids warranty, requires a steady hand
|
||||
and more such restrictions....)
|
||||
|
||||
|
||||
(*) Cirrus logic CD1864 databook, page 40.
|
||||
|
||||
|
||||
Cables for the Specialix IO8+
|
||||
=============================
|
||||
|
||||
The pinout of the connectors on the IO8+ is:
|
||||
|
||||
pin short direction long name
|
||||
name
|
||||
Pin 1 DCD input Data Carrier Detect
|
||||
Pin 2 RXD input Receive
|
||||
Pin 3 DTR/RTS output Data Terminal Ready/Ready To Send
|
||||
Pin 4 GND - Ground
|
||||
Pin 5 TXD output Transmit
|
||||
Pin 6 CTS input Clear To Send
|
||||
|
||||
|
||||
-- 6 5 4 3 2 1 --
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----- -----+
|
||||
|__________|
|
||||
clip
|
||||
|
||||
Front view of an RJ12 connector. Cable moves "into" the paper.
|
||||
(the plug is ready to plug into your mouth this way...)
|
||||
|
||||
|
||||
NULL cable. I don't know who is going to use these except for
|
||||
testing purposes, but I tested the cards with this cable. (It
|
||||
took quite a while to figure out, so I'm not going to delete
|
||||
it. So there! :-)
|
||||
|
||||
|
||||
This end goes This end needs
|
||||
straight into the some twists in
|
||||
RJ12 plug. the wiring.
|
||||
IO8+ RJ12 IO8+ RJ12
|
||||
1 DCD white -
|
||||
- - 1 DCD
|
||||
2 RXD black 5 TXD
|
||||
3 DTR/RTS red 6 CTS
|
||||
4 GND green 4 GND
|
||||
5 TXD yellow 2 RXD
|
||||
6 CTS blue 3 DTR/RTS
|
||||
|
||||
|
||||
Same NULL cable, but now sorted on the second column.
|
||||
|
||||
1 DCD white -
|
||||
- - 1 DCD
|
||||
5 TXD yellow 2 RXD
|
||||
6 CTS blue 3 DTR/RTS
|
||||
4 GND green 4 GND
|
||||
2 RXD black 5 TXD
|
||||
3 DTR/RTS red 6 CTS
|
||||
|
||||
|
||||
|
||||
This is a modem cable usable for hardware handshaking:
|
||||
RJ12 DB25 DB9
|
||||
1 DCD white 8 DCD 1 DCD
|
||||
2 RXD black 3 RXD 2 RXD
|
||||
3 DTR/RTS red 4 RTS 7 RTS
|
||||
4 GND green 7 GND 5 GND
|
||||
5 TXD yellow 2 TXD 3 TXD
|
||||
6 CTS blue 5 CTS 8 CTS
|
||||
+---- 6 DSR 6 DSR
|
||||
+---- 20 DTR 4 DTR
|
||||
|
||||
This is a modem cable usable for software handshaking:
|
||||
It allows you to reset the modem using the DTR ioctls.
|
||||
I (REW) have never tested this, "but xxxxxxxxxxxxx
|
||||
says that it works." If you test this, please
|
||||
tell me and I'll fill in your name on the xxx's.
|
||||
|
||||
RJ12 DB25 DB9
|
||||
1 DCD white 8 DCD 1 DCD
|
||||
2 RXD black 3 RXD 2 RXD
|
||||
3 DTR/RTS red 20 DTR 4 DTR
|
||||
4 GND green 7 GND 5 GND
|
||||
5 TXD yellow 2 TXD 3 TXD
|
||||
6 CTS blue 5 CTS 8 CTS
|
||||
+---- 6 DSR 6 DSR
|
||||
+---- 4 RTS 7 RTS
|
||||
|
||||
I bought a 6 wire flat cable. It was colored as indicated.
|
||||
Check that yours is the same before you trust me on this.
|
||||
|
||||
|
||||
Hardware handshaking issues.
|
||||
============================
|
||||
|
||||
The driver can be told to operate in two different ways. The default
|
||||
behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when
|
||||
hardware handshaking is off. It behaves as the RTS hardware
|
||||
handshaking signal when hardware handshaking is selected.
|
||||
|
||||
When you use this, you have to use the appropriate cable. The
|
||||
cable will either be compatible with hardware handshaking or with
|
||||
software handshaking. So switching on the fly is not really an
|
||||
option.
|
||||
|
||||
I actually prefer to use the "specialix.sx_rtscts=1" option.
|
||||
This makes the DTR/RTS pin always an RTS pin, and ioctls to
|
||||
change DTR are always ignored. I have a cable that is configured
|
||||
for this.
|
||||
|
||||
|
||||
Ports and devices
|
||||
=================
|
||||
|
||||
Port 0 is the one furthest from the card-edge connector.
|
||||
|
||||
Devices:
|
||||
|
||||
You should make the devices as follows:
|
||||
|
||||
bash
|
||||
cd /dev
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \
|
||||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||
do
|
||||
echo -n "$i "
|
||||
mknod /dev/ttyW$i c 75 $i
|
||||
mknod /dev/cuw$i c 76 $i
|
||||
done
|
||||
echo ""
|
||||
|
||||
If your system doesn't come with these devices preinstalled, bug your
|
||||
linux-vendor about this. They have had ample time to get this
|
||||
implemented by now.
|
||||
|
||||
You cannot have more than 4 boards in one computer. The card only
|
||||
supports 4 different interrupts. If you really want this, contact me
|
||||
about this and I'll give you a few tips (requires soldering iron)....
|
||||
|
||||
If you have enough PCI slots, you can probably use more than 4 PCI
|
||||
versions of the card though....
|
||||
|
||||
The PCI version of the card cannot adhere to the mechanical part of
|
||||
the PCI spec because the 8 serial connectors are simply too large. If
|
||||
it doesn't fit in your computer, bring back the card.
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
Fixed bugs and restrictions:
|
||||
- During initialization, interrupts are blindly turned on.
|
||||
Having a shadow variable would cause an extra memory
|
||||
access on every IO instruction.
|
||||
- The interrupt (on the card) should be disabled when we
|
||||
don't allocate the Linux end of the interrupt. This allows
|
||||
a different driver/card to use it while all ports are not in
|
||||
use..... (a la standard serial port)
|
||||
== An extra _off variant of the sx_in and sx_out macros are
|
||||
now available. They don't set the interrupt enable bit.
|
||||
These are used during initialization. Normal operation uses
|
||||
the old variant which enables the interrupt line.
|
||||
- RTS/DTR issue needs to be implemented according to
|
||||
specialix' spec.
|
||||
I kind of like the "determinism" of the current
|
||||
implementation. Compile time flag?
|
||||
== Ok. Compile time flag! Default is how Specialix likes it.
|
||||
== Now a config time flag! Gets saved in your config file. Neat!
|
||||
- Can you set the IO address from the lilo command line?
|
||||
If you need this, bug me about it, I'll make it.
|
||||
== Hah! No bugging needed. Fixed! :-)
|
||||
- Cirrus logic hasn't gotten back to me yet why the CD1865 can
|
||||
and the CD1864 can't do 115k2. I suspect that this is
|
||||
because the CD1864 is not rated for 33MHz operation.
|
||||
Therefore the CD1864 versions of the card can't do 115k2 on
|
||||
all ports just like the CD1865 versions. The driver does
|
||||
not block 115k2 on CD1864 cards.
|
||||
== I called the Cirrus Logic representative here in Holland.
|
||||
The CD1864 databook is identical to the CD1865 databook,
|
||||
except for an extra warning at the end. Similar Bit errors
|
||||
have been observed in testing at 115k2 on both an 1865 and
|
||||
a 1864 chip. I see no reason why I would prohibit 115k2 on
|
||||
1864 chips and not do it on 1865 chips. Actually there is
|
||||
reason to prohibit it on BOTH chips. I print a warning.
|
||||
If you use 115k2, you're on your own.
|
||||
- A spiky CD may send spurious HUPs. Also in CLOCAL???
|
||||
-- A fix for this turned out to be counter productive.
|
||||
Different fix? Current behaviour is acceptable?
|
||||
-- Maybe the current implementation is correct. If anybody
|
||||
gets bitten by this, please report, and it will get fixed.
|
||||
|
||||
-- Testing revealed that when in CLOCAL, the problem doesn't
|
||||
occur. As warned for in the CD1865 manual, the chip may
|
||||
send modem intr's on a spike. We could filter those out,
|
||||
but that would be a cludge anyway (You'd still risk getting
|
||||
a spurious HUP when two spikes occur.).....
|
||||
|
||||
|
||||
|
||||
Bugs & restrictions:
|
||||
- This is a difficult card to autoprobe.
|
||||
You have to WRITE to the address register to even
|
||||
read-probe a CD186x register. Disable autodetection?
|
||||
-- Specialix: any suggestions?
|
||||
|
||||
|
|
@ -1,294 +0,0 @@
|
|||
|
||||
sx.txt -- specialix SX/SI multiport serial driver readme.
|
||||
|
||||
|
||||
|
||||
Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
|
||||
|
||||
Specialix pays for the development and support of this driver.
|
||||
Please DO contact support@specialix.co.uk if you require
|
||||
support.
|
||||
|
||||
This driver was developed in the BitWizard linux device
|
||||
driver service. If you require a linux device driver for your
|
||||
product, please contact devices@BitWizard.nl for a quote.
|
||||
|
||||
(History)
|
||||
There used to be an SI driver by Simon Allan. This is a complete
|
||||
rewrite from scratch. Just a few lines-of-code have been snatched.
|
||||
|
||||
(Sources)
|
||||
Specialix document number 6210028: SX Host Card and Download Code
|
||||
Software Functional Specification.
|
||||
|
||||
(Copying)
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
|
||||
USA.
|
||||
|
||||
(Addendum)
|
||||
I'd appreciate it that if you have fixes, that you send them
|
||||
to me first.
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This file contains some random information, that I like to have online
|
||||
instead of in a manual that can get lost. Ever misplace your Linux
|
||||
kernel sources? And the manual of one of the boards in your computer?
|
||||
|
||||
|
||||
Theory of operation
|
||||
===================
|
||||
|
||||
An important thing to know is that the driver itself doesn't have the
|
||||
firmware for the card. This means that you need the separate package
|
||||
"sx_firmware". For now you can get the source at
|
||||
|
||||
ftp://ftp.bitwizard.nl/specialix/sx_firmware_<version>.tgz
|
||||
|
||||
The firmware load needs a "misc" device, so you'll need to enable the
|
||||
"Support for user misc device modules" in your kernel configuration.
|
||||
The misc device needs to be called "/dev/specialix_sxctl". It needs
|
||||
misc major 10, and minor number 167 (assigned by HPA). The section
|
||||
on creating device files below also creates this device.
|
||||
|
||||
After loading the sx.o module into your kernel, the driver will report
|
||||
the number of cards detected, but because it doesn't have any
|
||||
firmware, it will not be able to determine the number of ports. Only
|
||||
when you then run "sx_firmware" will the firmware be downloaded and
|
||||
the rest of the driver initialized. At that time the sx_firmware
|
||||
program will report the number of ports installed.
|
||||
|
||||
In contrast with many other multi port serial cards, some of the data
|
||||
structures are only allocated when the card knows the number of ports
|
||||
that are connected. This means we won't waste memory for 120 port
|
||||
descriptor structures when you only have 8 ports. If you experience
|
||||
problems due to this, please report them: I haven't seen any.
|
||||
|
||||
|
||||
Interrupts
|
||||
==========
|
||||
|
||||
A multi port serial card, would generate a horrendous amount of
|
||||
interrupts if it would interrupt the CPU for every received
|
||||
character. Even more than 10 years ago, the trick not to use
|
||||
interrupts but to poll the serial cards was invented.
|
||||
|
||||
The SX card allow us to do this two ways. First the card limits its
|
||||
own interrupt rate to a rate that won't overwhelm the CPU. Secondly,
|
||||
we could forget about the cards interrupt completely and use the
|
||||
internal timer for this purpose.
|
||||
|
||||
Polling the card can take up to a few percent of your CPU. Using the
|
||||
interrupts would be better if you have most of the ports idle. Using
|
||||
timer-based polling is better if your card almost always has work to
|
||||
do. You save the separate interrupt in that case.
|
||||
|
||||
In any case, it doesn't really matter all that much.
|
||||
|
||||
The most common problem with interrupts is that for ISA cards in a PCI
|
||||
system the BIOS has to be told to configure that interrupt as "legacy
|
||||
ISA". Otherwise the card can pull on the interrupt line all it wants
|
||||
but the CPU won't see this.
|
||||
|
||||
If you can't get the interrupt to work, remember that polling mode is
|
||||
more efficient (provided you actually use the card intensively).
|
||||
|
||||
|
||||
Allowed Configurations
|
||||
======================
|
||||
|
||||
Some configurations are disallowed. Even though at a glance they might
|
||||
seem to work, they are known to lockup the bus between the host card
|
||||
and the device concentrators. You should respect the drivers decision
|
||||
not to support certain configurations. It's there for a reason.
|
||||
|
||||
Warning: Seriously technical stuff ahead. Executive summary: Don't use
|
||||
SX cards except configured at a 64k boundary. Skip the next paragraph.
|
||||
|
||||
The SX cards can theoretically be placed at a 32k boundary. So for
|
||||
instance you can put an SX card at 0xc8000-0xd7fff. This is not a
|
||||
"recommended configuration". ISA cards have to tell the bus controller
|
||||
how they like their timing. Due to timing issues they have to do this
|
||||
based on which 64k window the address falls into. This means that the
|
||||
32k window below and above the SX card have to use exactly the same
|
||||
timing as the SX card. That reportedly works for other SX cards. But
|
||||
you're still left with two useless 32k windows that should not be used
|
||||
by anybody else.
|
||||
|
||||
|
||||
Configuring the driver
|
||||
======================
|
||||
|
||||
PCI cards are always detected. The driver auto-probes for ISA cards at
|
||||
some sensible addresses. Please report if the auto-probe causes trouble
|
||||
in your system, or when a card isn't detected.
|
||||
|
||||
I'm afraid I haven't implemented "kernel command line parameters" yet.
|
||||
This means that if the default doesn't work for you, you shouldn't use
|
||||
the compiled-into-the-kernel version of the driver. Use a module
|
||||
instead. If you convince me that you need this, I'll make it for
|
||||
you. Deal?
|
||||
|
||||
I'm afraid that the module parameters are a bit clumsy. If you have a
|
||||
better idea, please tell me.
|
||||
|
||||
You can specify several parameters:
|
||||
|
||||
sx_poll: number of jiffies between timer-based polls.
|
||||
|
||||
Set this to "0" to disable timer based polls.
|
||||
Initialization of cards without a working interrupt
|
||||
will fail.
|
||||
|
||||
Set this to "1" if you want a polling driver.
|
||||
(on Intel: 100 polls per second). If you don't use
|
||||
fast baud rates, you might consider a value like "5".
|
||||
(If you don't know how to do the math, use 1).
|
||||
|
||||
sx_slowpoll: Number of jiffies between timer-based polls.
|
||||
Set this to "100" to poll once a second.
|
||||
This should get the card out of a stall if the driver
|
||||
ever misses an interrupt. I've never seen this happen,
|
||||
and if it does, that's a bug. Tell me.
|
||||
|
||||
sx_maxints: Number of interrupts to request from the card.
|
||||
The card normally limits interrupts to about 100 per
|
||||
second to offload the host CPU. You can increase this
|
||||
number to reduce latency on the card a little.
|
||||
Note that if you give a very high number you can overload
|
||||
your CPU as well as the CPU on the host card. This setting
|
||||
is inaccurate and not recommended for SI cards (But it
|
||||
works).
|
||||
|
||||
sx_irqmask: The mask of allowable IRQs to use. I suggest you set
|
||||
this to 0 (disable IRQs all together) and use polling if
|
||||
the assignment of IRQs becomes problematic. This is defined
|
||||
as the sum of (1 << irq) 's that you want to allow. So
|
||||
sx_irqmask of 8 (1 << 3) specifies that only irq 3 may
|
||||
be used by the SX driver. If you want to specify to the
|
||||
driver: "Either irq 11 or 12 is ok for you to use", then
|
||||
specify (1 << 11) | (1 << 12) = 0x1800 .
|
||||
|
||||
sx_debug: You can enable different sorts of debug traces with this.
|
||||
At "-1" all debugging traces are active. You'll get several
|
||||
times more debugging output than you'll get characters
|
||||
transmitted.
|
||||
|
||||
|
||||
Baud rates
|
||||
==========
|
||||
|
||||
Theoretically new SXDCs should be capable of more than 460k
|
||||
baud. However the line drivers usually give up before that. Also the
|
||||
CPU on the card may not be able to handle 8 channels going at full
|
||||
blast at that speed. Moreover, the buffers are not large enough to
|
||||
allow operation with 100 interrupts per second. You'll have to realize
|
||||
that the card has a 256 byte buffer, so you'll have to increase the
|
||||
number of interrupts per second if you have more than 256*100 bytes
|
||||
per second to transmit. If you do any performance testing in this
|
||||
area, I'd be glad to hear from you...
|
||||
|
||||
(Psst Linux users..... I think the Linux driver is more efficient than
|
||||
the driver for other OSes. If you can and want to benchmark them
|
||||
against each other, be my guest, and report your findings...... :-)
|
||||
|
||||
|
||||
Ports and devices
|
||||
=================
|
||||
|
||||
Port 0 is the top connector on the module closest to the host
|
||||
card. Oh, the ports on the SXDCs and TAs are labelled from 1 to 8
|
||||
instead of from 0 to 7, as they are numbered by linux. I'm stubborn in
|
||||
this: I know for sure that I wouldn't be able to calculate which port
|
||||
is which anymore if I would change that....
|
||||
|
||||
|
||||
Devices:
|
||||
|
||||
You should make the device files as follows:
|
||||
|
||||
#!/bin/sh
|
||||
# (I recommend that you cut-and-paste this into a file and run that)
|
||||
cd /dev
|
||||
t=0
|
||||
mknod specialix_sxctl c 10 167
|
||||
while [ $t -lt 64 ]
|
||||
do
|
||||
echo -n "$t "
|
||||
mknod ttyX$t c 32 $t
|
||||
mknod cux$t c 33 $t
|
||||
t=`expr $t + 1`
|
||||
done
|
||||
echo ""
|
||||
rm /etc/psdevtab
|
||||
ps > /dev/null
|
||||
|
||||
|
||||
This creates 64 devices. If you have more, increase the constant on
|
||||
the line with "while". The devices start at 0, as is customary on
|
||||
Linux. Specialix seems to like starting the numbering at 1.
|
||||
|
||||
If your system doesn't come with these devices pre-installed, bug your
|
||||
linux-vendor about this. They should have these devices
|
||||
"pre-installed" before the new millennium. The "ps" stuff at the end
|
||||
is to "tell" ps that the new devices exist.
|
||||
|
||||
Officially the maximum number of cards per computer is 4. This driver
|
||||
however supports as many cards in one machine as you want. You'll run
|
||||
out of interrupts after a few, but you can switch to polled operation
|
||||
then. At about 256 ports (More than 8 cards), we run out of minor
|
||||
device numbers. Sorry. I suggest you buy a second computer.... (Or
|
||||
switch to RIO).
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
Fixed bugs and restrictions:
|
||||
- Hangup processing.
|
||||
-- Done.
|
||||
|
||||
- the write path in generic_serial (lockup / oops).
|
||||
-- Done (Ugly: not the way I want it. Copied from serial.c).
|
||||
|
||||
- write buffer isn't flushed at close.
|
||||
-- Done. I still seem to lose a few chars at close.
|
||||
Sorry. I think that this is a firmware issue. (-> Specialix)
|
||||
|
||||
- drain hardware before changing termios
|
||||
- Change debug on the fly.
|
||||
- ISA free irq -1. (no firmware loaded).
|
||||
- adding c8000 as a probe address. Added warning.
|
||||
- Add a RAMtest for the RAM on the card.c
|
||||
- Crash when opening a port "way" of the number of allowed ports.
|
||||
(for example opening port 60 when there are only 24 ports attached)
|
||||
- Sometimes the use-count strays a bit. After a few hours of
|
||||
testing the use count is sometimes "3". If you are not like
|
||||
me and can remember what you did to get it that way, I'd
|
||||
appreciate an Email. Possibly fixed. Tell me if anyone still
|
||||
sees this.
|
||||
- TAs don't work right if you don't connect all the modem control
|
||||
signals. SXDCs do. T225 firmware problem -> Specialix.
|
||||
(Mostly fixed now, I think. Tell me if you encounter this!)
|
||||
|
||||
Bugs & restrictions:
|
||||
|
||||
- Arbitrary baud rates. Requires firmware update. (-> Specialix)
|
||||
|
||||
- Low latency (mostly firmware, -> Specialix)
|
||||
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ Procedure for submitting patches to the -stable tree:
|
|||
the stable tree without anything else needing to be done by the author
|
||||
or subsystem maintainer.
|
||||
- If the patch requires other patches as prerequisites which can be
|
||||
cherry-picked than this can be specified in the following format in
|
||||
cherry-picked, then this can be specified in the following format in
|
||||
the sign-off area:
|
||||
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
|
||||
|
|
|
@ -174,7 +174,6 @@ Components of Memory Policies
|
|||
allocation fails, the kernel will search other nodes, in order of
|
||||
increasing distance from the preferred node based on information
|
||||
provided by the platform firmware.
|
||||
containing the cpu where the allocation takes place.
|
||||
|
||||
Internally, the Preferred policy uses a single node--the
|
||||
preferred_node member of struct mempolicy. When the internal
|
||||
|
@ -275,9 +274,9 @@ Components of Memory Policies
|
|||
For example, consider a task that is attached to a cpuset with
|
||||
mems 2-5 that sets an Interleave policy over the same set with
|
||||
MPOL_F_RELATIVE_NODES. If the cpuset's mems change to 3-7, the
|
||||
interleave now occurs over nodes 3,5-6. If the cpuset's mems
|
||||
interleave now occurs over nodes 3,5-7. If the cpuset's mems
|
||||
then change to 0,2-3,5, then the interleave occurs over nodes
|
||||
0,3,5.
|
||||
0,2-3,5.
|
||||
|
||||
Thanks to the consistent remapping, applications preparing
|
||||
nodemasks to specify memory policies using this flag should
|
||||
|
|
|
@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循
|
|||
如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
|
||||
版内核。
|
||||
|
||||
2.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发
|
||||
2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发
|
||||
布新版本。
|
||||
|
||||
内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
Chinese translated version of Documentation/io_orderings.txt
|
||||
|
||||
If you have any comment or update to the content, please contact the
|
||||
original document maintainer directly. However, if you have a problem
|
||||
communicating in English you can also ask the Chinese maintainer for
|
||||
help. Contact the Chinese maintainer if this translation is outdated
|
||||
or if there is a problem with the translation.
|
||||
|
||||
Chinese maintainer: Lin Yongting <linyongting@gmail.com>
|
||||
---------------------------------------------------------------------
|
||||
Documentation/io_ordering.txt 的中文翻译
|
||||
|
||||
如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
|
||||
交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
|
||||
译存在问题,请联系中文版维护者。
|
||||
|
||||
中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com>
|
||||
中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com>
|
||||
中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com>
|
||||
|
||||
|
||||
以下为正文
|
||||
---------------------------------------------------------------------
|
||||
|
||||
在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
|
||||
保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
|
||||
设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
|
||||
而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
|
||||
这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
|
||||
屏障操作,mb(),不过仅适用于I/O)。
|
||||
|
||||
假设一个设备驱动程的具体例子:
|
||||
|
||||
...
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: val = readl(my_status);
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: val = readl(my_status);
|
||||
CPU B: ...
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
|
||||
上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
|
||||
发生了。不过很容易通过下面方法来修复:
|
||||
|
||||
...
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: val = readl(my_status);
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: (void)readl(safe_register); /* 配置寄存器?*/
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: val = readl(my_status);
|
||||
CPU B: ...
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: (void)readl(safe_register); /* 配置寄存器?*/
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
|
||||
在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
|
||||
再处理后面的读操作,防止引发数据不一致问题。
|
|
@ -63,8 +63,6 @@ struct tty_ldisc {
|
|||
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
|
||||
CMAGIC 0x0111 user include/linux/a.out.h
|
||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
|
||||
RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
|
||||
SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
|
||||
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
|
||||
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
|
||||
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
|
||||
|
@ -82,7 +80,6 @@ STRIP_MAGIC 0x5303 strip drivers/net/strip.c
|
|||
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
|
||||
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
|
||||
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
|
||||
ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
|
||||
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
|
||||
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
|
||||
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
|
||||
|
@ -94,13 +91,10 @@ USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c
|
|||
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
|
||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
|
||||
A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
|
||||
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
|
||||
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
|
||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
|
||||
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
|
||||
RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
|
||||
SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
|
||||
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
|
||||
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
|
||||
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
|
||||
|
@ -116,7 +110,6 @@ ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h
|
|||
CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
|
||||
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
|
||||
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
|
||||
STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
|
||||
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
|
||||
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
|
||||
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
|
||||
|
@ -127,10 +120,8 @@ SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
|
|||
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
|
||||
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
|
||||
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
|
||||
STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
|
||||
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
|
||||
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
|
||||
EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
|
||||
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
|
||||
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h
|
||||
I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
|
||||
|
@ -142,17 +133,14 @@ SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h
|
|||
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
|
||||
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
|
||||
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
|
||||
STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
|
||||
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
|
||||
KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
|
||||
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
|
||||
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
|
||||
STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
|
||||
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
|
||||
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
|
||||
CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h
|
||||
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h
|
||||
STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
|
||||
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
|
||||
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
|
||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
|
||||
|
|
|
@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译
|
|||
|
||||
向稳定版代码树提交补丁的过程:
|
||||
|
||||
- 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。
|
||||
- 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。
|
||||
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
|
||||
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
|
||||
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
|
||||
|
|
|
@ -6782,7 +6782,7 @@ PERFORMANCE EVENTS SUBSYSTEM
|
|||
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
M: Paul Mackerras <paulus@samba.org>
|
||||
M: Ingo Molnar <mingo@redhat.com>
|
||||
M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
|
||||
M: Arnaldo Carvalho de Melo <acme@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
|
||||
S: Supported
|
||||
|
@ -8315,7 +8315,7 @@ F: include/linux/compiler.h
|
|||
|
||||
SPEAR PLATFORM SUPPORT
|
||||
M: Viresh Kumar <viresh.linux@gmail.com>
|
||||
M: Shiraz Hashim <shiraz.hashim@st.com>
|
||||
M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
|
||||
L: spear-devel@list.st.com
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
W: http://www.st.com/spear
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Shuffling Zombie Juror
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_BARRIER_H
|
||||
#define __ASM_BARRIER_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */
|
||||
#define mb() __asm__ __volatile__ ("" : : : "memory")
|
||||
#define rmb() mb()
|
||||
#define wmb() mb()
|
||||
#define set_mb(var, value) do { var = value; mb(); } while (0)
|
||||
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
|
||||
#define read_barrier_depends() mb()
|
||||
|
||||
/* TODO-vineetg verify the correctness of macros here */
|
||||
#ifdef CONFIG_SMP
|
||||
#define smp_mb() mb()
|
||||
#define smp_rmb() rmb()
|
||||
#define smp_wmb() wmb()
|
||||
#else
|
||||
#define smp_mb() barrier()
|
||||
#define smp_rmb() barrier()
|
||||
#define smp_wmb() barrier()
|
||||
#endif
|
||||
|
||||
#define smp_read_barrier_depends() do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DTS file for SPEAr320 Evaluation Baord
|
||||
*
|
||||
* Copyright 2012 Shiraz Hashim <shiraz.hashim@st.com>
|
||||
* Copyright 2012 Shiraz Hashim <shiraz.linux.kernel@gmail.com>
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
|
|
|
@ -132,7 +132,7 @@ CONFIG_CRC_ITU_T=y
|
|||
CONFIG_CRC7=y
|
||||
CONFIG_XZ_DEC=y
|
||||
CONFIG_AVERAGE=y
|
||||
CONFIG_PINCTRL_CAPRI=y
|
||||
CONFIG_PINCTRL_BCM281XX=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_BCM_KONA_WDT=y
|
||||
CONFIG_BCM_KONA_WDT_DEBUG=y
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Picked from realview
|
||||
* Copyright (c) 2012 ST Microelectronics Limited
|
||||
* Shiraz Hashim <shiraz.hashim@st.com>
|
||||
* Shiraz Hashim <shiraz.linux.kernel@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* based upon linux/arch/arm/mach-realview/platsmp.c
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics Ltd.
|
||||
* Shiraz Hashim <shiraz.hashim@st.com>
|
||||
* Shiraz Hashim <shiraz.linux.kernel@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* arch/arm/plat-spear/time.c
|
||||
*
|
||||
* Copyright (C) 2010 ST Microelectronics
|
||||
* Shiraz Hashim<shiraz.hashim@st.com>
|
||||
* Shiraz Hashim<shiraz.linux.kernel@gmail.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
|
|
|
@ -259,7 +259,7 @@ start_ap:
|
|||
* Switch into virtual mode:
|
||||
*/
|
||||
movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
|
||||
|IA64_PSR_DI|IA64_PSR_AC)
|
||||
|IA64_PSR_DI)
|
||||
;;
|
||||
mov cr.ipsr=r16
|
||||
movl r17=1f
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#include <asm/unistd.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
# define PSR_DEFAULT_BITS psr.ac
|
||||
#else
|
||||
# define PSR_DEFAULT_BITS 0
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#include "kvm_minstate.h"
|
||||
#include "vti.h"
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
# define PSR_DEFAULT_BITS psr.ac
|
||||
#else
|
||||
# define PSR_DEFAULT_BITS 0
|
||||
|
|
|
@ -29,15 +29,15 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
|
|||
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
|
||||
unsigned long pfn);
|
||||
void (*flush_icache_range)(unsigned long start, unsigned long end);
|
||||
EXPORT_SYMBOL_GPL(flush_icache_range);
|
||||
void (*local_flush_icache_range)(unsigned long start, unsigned long end);
|
||||
|
||||
void (*__flush_cache_vmap)(void);
|
||||
void (*__flush_cache_vunmap)(void);
|
||||
|
||||
void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
|
||||
void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
|
||||
|
||||
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
|
||||
void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
|
||||
|
||||
/* MIPS specific cache operations */
|
||||
void (*flush_cache_sigtramp)(unsigned long addr);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef _ASMPARISC_SHMPARAM_H
|
||||
#define _ASMPARISC_SHMPARAM_H
|
||||
|
||||
#define __ARCH_FORCE_SHMLBA 1
|
||||
|
||||
#define SHMLBA 0x00400000 /* attach addr needs to be 4 Mb aligned */
|
||||
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
|
||||
#define SHM_COLOUR 0x00400000 /* shared mappings colouring */
|
||||
|
||||
#endif /* _ASMPARISC_SHMPARAM_H */
|
||||
|
|
|
@ -323,7 +323,8 @@ void flush_dcache_page(struct page *page)
|
|||
* specifically accesses it, of course) */
|
||||
|
||||
flush_tlb_page(mpnt, addr);
|
||||
if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
|
||||
if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
|
||||
!= (addr & (SHM_COLOUR - 1))) {
|
||||
__flush_cache_page(mpnt, addr, page_to_phys(page));
|
||||
if (old_addr)
|
||||
printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
static int get_offset(unsigned int last_mmap)
|
||||
{
|
||||
return (last_mmap & (SHMLBA-1)) >> PAGE_SHIFT;
|
||||
return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static unsigned long shared_align_offset(unsigned int last_mmap,
|
||||
|
@ -57,8 +57,8 @@ static unsigned long shared_align_offset(unsigned int last_mmap,
|
|||
static inline unsigned long COLOR_ALIGN(unsigned long addr,
|
||||
unsigned int last_mmap, unsigned long pgoff)
|
||||
{
|
||||
unsigned long base = (addr+SHMLBA-1) & ~(SHMLBA-1);
|
||||
unsigned long off = (SHMLBA-1) &
|
||||
unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
|
||||
unsigned long off = (SHM_COLOUR-1) &
|
||||
(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
|
||||
|
||||
return base + off;
|
||||
|
@ -101,7 +101,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
|||
if (flags & MAP_FIXED) {
|
||||
if ((flags & MAP_SHARED) && last_mmap &&
|
||||
(addr - shared_align_offset(last_mmap, pgoff))
|
||||
& (SHMLBA - 1))
|
||||
& (SHM_COLOUR - 1))
|
||||
return -EINVAL;
|
||||
goto found_addr;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
|||
info.length = len;
|
||||
info.low_limit = mm->mmap_legacy_base;
|
||||
info.high_limit = mmap_upper_limit();
|
||||
info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
|
||||
info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
|
||||
info.align_offset = shared_align_offset(last_mmap, pgoff);
|
||||
addr = vm_unmapped_area(&info);
|
||||
|
||||
|
@ -161,7 +161,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
if (flags & MAP_FIXED) {
|
||||
if ((flags & MAP_SHARED) && last_mmap &&
|
||||
(addr - shared_align_offset(last_mmap, pgoff))
|
||||
& (SHMLBA - 1))
|
||||
& (SHM_COLOUR - 1))
|
||||
return -EINVAL;
|
||||
goto found_addr;
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
info.length = len;
|
||||
info.low_limit = PAGE_SIZE;
|
||||
info.high_limit = mm->mmap_base;
|
||||
info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
|
||||
info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
|
||||
info.align_offset = shared_align_offset(last_mmap, pgoff);
|
||||
addr = vm_unmapped_area(&info);
|
||||
if (!(addr & ~PAGE_MASK))
|
||||
|
|
|
@ -392,7 +392,7 @@
|
|||
ENTRY_COMP(vmsplice)
|
||||
ENTRY_COMP(move_pages) /* 295 */
|
||||
ENTRY_SAME(getcpu)
|
||||
ENTRY_SAME(epoll_pwait)
|
||||
ENTRY_COMP(epoll_pwait)
|
||||
ENTRY_COMP(statfs64)
|
||||
ENTRY_COMP(fstatfs64)
|
||||
ENTRY_COMP(kexec_load) /* 300 */
|
||||
|
|
|
@ -470,7 +470,7 @@ static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
|
|||
return 0;
|
||||
|
||||
/* if a load or store fault occured we can get the faulty addr */
|
||||
d = &__get_cpu_var(exception_data);
|
||||
d = this_cpu_ptr(&exception_data);
|
||||
fault_addr = d->fault_addr;
|
||||
|
||||
/* error in load or store? */
|
||||
|
|
|
@ -151,7 +151,7 @@ int fixup_exception(struct pt_regs *regs)
|
|||
fix = search_exception_tables(regs->iaoq[0]);
|
||||
if (fix) {
|
||||
struct exception_data *d;
|
||||
d = &__get_cpu_var(exception_data);
|
||||
d = this_cpu_ptr(&exception_data);
|
||||
d->fault_ip = regs->iaoq[0];
|
||||
d->fault_space = regs->isr;
|
||||
d->fault_addr = regs->ior;
|
||||
|
|
|
@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
|
|||
unsigned long in_devfn)
|
||||
{
|
||||
struct pci_controller* hose;
|
||||
struct pci_bus *bus = NULL;
|
||||
struct pci_bus *tmp_bus, *bus = NULL;
|
||||
struct device_node *hose_node;
|
||||
|
||||
/* Argh ! Please forgive me for that hack, but that's the
|
||||
|
@ -229,10 +229,12 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
|
|||
* used on pre-domains setup. We return the first match
|
||||
*/
|
||||
|
||||
list_for_each_entry(bus, &pci_root_buses, node) {
|
||||
if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
|
||||
list_for_each_entry(tmp_bus, &pci_root_buses, node) {
|
||||
if (in_bus >= tmp_bus->number &&
|
||||
in_bus <= tmp_bus->busn_res.end) {
|
||||
bus = tmp_bus;
|
||||
break;
|
||||
bus = NULL;
|
||||
}
|
||||
}
|
||||
if (bus == NULL || bus->dev.of_node == NULL)
|
||||
return -ENODEV;
|
||||
|
|
|
@ -232,6 +232,7 @@ int __node_distance(int a, int b)
|
|||
|
||||
return distance;
|
||||
}
|
||||
EXPORT_SYMBOL(__node_distance);
|
||||
|
||||
static void initialize_distance_lookup_table(int nid,
|
||||
const __be32 *associativity)
|
||||
|
|
|
@ -31,4 +31,23 @@
|
|||
#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL
|
||||
#define SIGP_STATUS_NOT_RUNNING 0x00000400UL
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
|
||||
{
|
||||
register unsigned int reg1 asm ("1") = parm;
|
||||
int cc;
|
||||
|
||||
asm volatile(
|
||||
" sigp %1,%2,0(%3)\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
|
||||
if (status && cc == 1)
|
||||
*status = reg1;
|
||||
return cc;
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __S390_ASM_SIGP_H */
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef __ASM_SMP_H
|
||||
#define __ASM_SMP_H
|
||||
|
||||
#include <asm/sigp.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#include <asm/lowcore.h>
|
||||
|
@ -50,9 +52,18 @@ static inline int smp_store_status(int cpu) { return 0; }
|
|||
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
|
||||
static inline void smp_yield_cpu(int cpu) { }
|
||||
static inline void smp_yield(void) { }
|
||||
static inline void smp_stop_cpu(void) { }
|
||||
static inline void smp_fill_possible_mask(void) { }
|
||||
|
||||
static inline void smp_stop_cpu(void)
|
||||
{
|
||||
u16 pcpu = stap();
|
||||
|
||||
for (;;) {
|
||||
__pcpu_sigp(pcpu, SIGP_STOP, 0, NULL);
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
|
|
@ -282,7 +282,8 @@
|
|||
#define __NR_finit_module 344
|
||||
#define __NR_sched_setattr 345
|
||||
#define __NR_sched_getattr 346
|
||||
#define NR_syscalls 345
|
||||
#define __NR_renameat2 347
|
||||
#define NR_syscalls 348
|
||||
|
||||
/*
|
||||
* There are some system calls that are not present on 64 bit, some
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Compat sytem call wrappers.
|
||||
* Compat system call wrappers.
|
||||
*
|
||||
* Copyright IBM Corp. 2014
|
||||
*/
|
||||
|
@ -213,3 +213,4 @@ COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, i
|
|||
COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags);
|
||||
COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags);
|
||||
COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags);
|
||||
COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags);
|
||||
|
|
|
@ -144,10 +144,10 @@ void show_registers(struct pt_regs *regs)
|
|||
char *mode;
|
||||
|
||||
mode = user_mode(regs) ? "User" : "Krnl";
|
||||
printk("%s PSW : %p %p (%pSR)\n",
|
||||
mode, (void *) regs->psw.mask,
|
||||
(void *) regs->psw.addr,
|
||||
(void *) regs->psw.addr);
|
||||
printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
|
||||
if (!user_mode(regs))
|
||||
printk(" (%pSR)", (void *)regs->psw.addr);
|
||||
printk("\n");
|
||||
printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
|
||||
"P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER),
|
||||
mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO),
|
||||
|
|
|
@ -64,7 +64,7 @@ void update_cr_regs(struct task_struct *task)
|
|||
if (task->thread.per_flags & PER_FLAG_NO_TE)
|
||||
cr_new &= ~(1UL << 55);
|
||||
if (cr_new != cr)
|
||||
__ctl_load(cr, 0, 0);
|
||||
__ctl_load(cr_new, 0, 0);
|
||||
/* Set or clear transaction execution TDC bits 62 and 63. */
|
||||
__ctl_store(cr, 2, 2);
|
||||
cr_new = cr & ~3UL;
|
||||
|
|
|
@ -1027,3 +1027,35 @@ void __init setup_arch(char **cmdline_p)
|
|||
/* Setup zfcpdump support */
|
||||
setup_zfcpdump();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
static int no_removal_warning __initdata;
|
||||
|
||||
static int __init parse_no_removal_warning(char *str)
|
||||
{
|
||||
no_removal_warning = 1;
|
||||
return 0;
|
||||
}
|
||||
__setup("no_removal_warning", parse_no_removal_warning);
|
||||
|
||||
static int __init removal_warning(void)
|
||||
{
|
||||
if (no_removal_warning)
|
||||
return 0;
|
||||
printk(KERN_ALERT "\n\n");
|
||||
printk(KERN_CONT "Warning - you are using a 31 bit kernel!\n\n");
|
||||
printk(KERN_CONT "We plan to remove 31 bit kernel support from the kernel sources in March 2015.\n");
|
||||
printk(KERN_CONT "Currently we assume that nobody is using the 31 bit kernel on old 31 bit\n");
|
||||
printk(KERN_CONT "hardware anymore. If you think that the code should not be removed and also\n");
|
||||
printk(KERN_CONT "future versions of the Linux kernel should be able to run in 31 bit mode\n");
|
||||
printk(KERN_CONT "please let us know. Please write to:\n");
|
||||
printk(KERN_CONT "linux390@de.ibm.com (mail address) and/or\n");
|
||||
printk(KERN_CONT "linux-s390@vger.kernel.org (mailing list).\n\n");
|
||||
printk(KERN_CONT "Thank you!\n\n");
|
||||
printk(KERN_CONT "If this kernel runs on a 64 bit machine you may consider using a 64 bit kernel.\n");
|
||||
printk(KERN_CONT "This message can be disabled with the \"no_removal_warning\" kernel parameter.\n");
|
||||
schedule_timeout_uninterruptible(300 * HZ);
|
||||
return 0;
|
||||
}
|
||||
early_initcall(removal_warning);
|
||||
#endif
|
||||
|
|
|
@ -82,21 +82,6 @@ DEFINE_MUTEX(smp_cpu_state_mutex);
|
|||
/*
|
||||
* Signal processor helper functions.
|
||||
*/
|
||||
static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
|
||||
{
|
||||
register unsigned int reg1 asm ("1") = parm;
|
||||
int cc;
|
||||
|
||||
asm volatile(
|
||||
" sigp %1,%2,0(%3)\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
|
||||
if (status && cc == 1)
|
||||
*status = reg1;
|
||||
return cc;
|
||||
}
|
||||
|
||||
static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
|
||||
{
|
||||
int cc;
|
||||
|
|
|
@ -355,3 +355,4 @@ SYSCALL(sys_kcmp,sys_kcmp,compat_sys_kcmp)
|
|||
SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module)
|
||||
SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */
|
||||
SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr)
|
||||
SYSCALL(sys_renameat2,sys_renameat2,compat_sys_renameat2)
|
||||
|
|
|
@ -338,9 +338,6 @@ static inline unsigned long strnlen_user_srst(const char __user *src,
|
|||
register unsigned long reg0 asm("0") = 0;
|
||||
unsigned long tmp1, tmp2;
|
||||
|
||||
if (unlikely(!size))
|
||||
return 0;
|
||||
update_primary_asce(current);
|
||||
asm volatile(
|
||||
" la %2,0(%1)\n"
|
||||
" la %3,0(%0,%1)\n"
|
||||
|
@ -359,6 +356,8 @@ static inline unsigned long strnlen_user_srst(const char __user *src,
|
|||
|
||||
unsigned long __strnlen_user(const char __user *src, unsigned long size)
|
||||
{
|
||||
if (unlikely(!size))
|
||||
return 0;
|
||||
update_primary_asce(current);
|
||||
return strnlen_user_srst(src, size);
|
||||
}
|
||||
|
|
|
@ -126,6 +126,133 @@ static inline int user_space_fault(struct pt_regs *regs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bad_address(void *p)
|
||||
{
|
||||
unsigned long dummy;
|
||||
|
||||
return probe_kernel_address((unsigned long *)p, dummy);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
static void dump_pagetable(unsigned long asce, unsigned long address)
|
||||
{
|
||||
unsigned long *table = __va(asce & PAGE_MASK);
|
||||
|
||||
pr_alert("AS:%016lx ", asce);
|
||||
switch (asce & _ASCE_TYPE_MASK) {
|
||||
case _ASCE_TYPE_REGION1:
|
||||
table = table + ((address >> 53) & 0x7ff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont("R1:%016lx ", *table);
|
||||
if (*table & _REGION_ENTRY_INVALID)
|
||||
goto out;
|
||||
table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
|
||||
/* fallthrough */
|
||||
case _ASCE_TYPE_REGION2:
|
||||
table = table + ((address >> 42) & 0x7ff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont("R2:%016lx ", *table);
|
||||
if (*table & _REGION_ENTRY_INVALID)
|
||||
goto out;
|
||||
table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
|
||||
/* fallthrough */
|
||||
case _ASCE_TYPE_REGION3:
|
||||
table = table + ((address >> 31) & 0x7ff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont("R3:%016lx ", *table);
|
||||
if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE))
|
||||
goto out;
|
||||
table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
|
||||
/* fallthrough */
|
||||
case _ASCE_TYPE_SEGMENT:
|
||||
table = table + ((address >> 20) & 0x7ff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont(KERN_CONT "S:%016lx ", *table);
|
||||
if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE))
|
||||
goto out;
|
||||
table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
|
||||
}
|
||||
table = table + ((address >> 12) & 0xff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont("P:%016lx ", *table);
|
||||
out:
|
||||
pr_cont("\n");
|
||||
return;
|
||||
bad:
|
||||
pr_cont("BAD\n");
|
||||
}
|
||||
|
||||
#else /* CONFIG_64BIT */
|
||||
|
||||
static void dump_pagetable(unsigned long asce, unsigned long address)
|
||||
{
|
||||
unsigned long *table = __va(asce & PAGE_MASK);
|
||||
|
||||
pr_alert("AS:%08lx ", asce);
|
||||
table = table + ((address >> 20) & 0x7ff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont("S:%08lx ", *table);
|
||||
if (*table & _SEGMENT_ENTRY_INVALID)
|
||||
goto out;
|
||||
table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
|
||||
table = table + ((address >> 12) & 0xff);
|
||||
if (bad_address(table))
|
||||
goto bad;
|
||||
pr_cont("P:%08lx ", *table);
|
||||
out:
|
||||
pr_cont("\n");
|
||||
return;
|
||||
bad:
|
||||
pr_cont("BAD\n");
|
||||
}
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
static void dump_fault_info(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long asce;
|
||||
|
||||
pr_alert("Fault in ");
|
||||
switch (regs->int_parm_long & 3) {
|
||||
case 3:
|
||||
pr_cont("home space ");
|
||||
break;
|
||||
case 2:
|
||||
pr_cont("secondary space ");
|
||||
break;
|
||||
case 1:
|
||||
pr_cont("access register ");
|
||||
break;
|
||||
case 0:
|
||||
pr_cont("primary space ");
|
||||
break;
|
||||
}
|
||||
pr_cont("mode while using ");
|
||||
if (!user_space_fault(regs)) {
|
||||
asce = S390_lowcore.kernel_asce;
|
||||
pr_cont("kernel ");
|
||||
}
|
||||
#ifdef CONFIG_PGSTE
|
||||
else if ((current->flags & PF_VCPU) && S390_lowcore.gmap) {
|
||||
struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
|
||||
asce = gmap->asce;
|
||||
pr_cont("gmap ");
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
asce = S390_lowcore.user_asce;
|
||||
pr_cont("user ");
|
||||
}
|
||||
pr_cont("ASCE.\n");
|
||||
dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK);
|
||||
}
|
||||
|
||||
static inline void report_user_fault(struct pt_regs *regs, long signr)
|
||||
{
|
||||
if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
|
||||
|
@ -138,8 +265,9 @@ static inline void report_user_fault(struct pt_regs *regs, long signr)
|
|||
regs->int_code);
|
||||
print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
|
||||
printk(KERN_CONT "\n");
|
||||
printk(KERN_ALERT "failing address: %lX\n",
|
||||
regs->int_parm_long & __FAIL_ADDR_MASK);
|
||||
printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
|
||||
regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
|
||||
dump_fault_info(regs);
|
||||
show_regs(regs);
|
||||
}
|
||||
|
||||
|
@ -177,11 +305,13 @@ static noinline void do_no_context(struct pt_regs *regs)
|
|||
address = regs->int_parm_long & __FAIL_ADDR_MASK;
|
||||
if (!user_space_fault(regs))
|
||||
printk(KERN_ALERT "Unable to handle kernel pointer dereference"
|
||||
" at virtual kernel address %p\n", (void *)address);
|
||||
" in virtual kernel address space\n");
|
||||
else
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request"
|
||||
" at virtual user address %p\n", (void *)address);
|
||||
|
||||
" in virtual user address space\n");
|
||||
printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
|
||||
regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
|
||||
dump_fault_info(regs);
|
||||
die(regs, "Oops");
|
||||
do_exit(SIGKILL);
|
||||
}
|
||||
|
|
|
@ -250,8 +250,8 @@ archclean:
|
|||
PHONY += kvmconfig
|
||||
kvmconfig:
|
||||
$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config
|
||||
$(Q)yes "" | $(MAKE) oldconfig
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config
|
||||
$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
|
||||
|
||||
define archhelp
|
||||
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
| X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
|
||||
| X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
|
||||
| X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
|
||||
| X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
|
||||
| X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP))
|
||||
|
||||
#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
|
||||
|
||||
|
|
|
@ -598,7 +598,6 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
|
|||
{
|
||||
struct mce m;
|
||||
int i;
|
||||
unsigned long *v;
|
||||
|
||||
this_cpu_inc(mce_poll_count);
|
||||
|
||||
|
@ -618,8 +617,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
|
|||
if (!(m.status & MCI_STATUS_VAL))
|
||||
continue;
|
||||
|
||||
v = &get_cpu_var(mce_polled_error);
|
||||
set_bit(0, v);
|
||||
this_cpu_write(mce_polled_error, 1);
|
||||
/*
|
||||
* Uncorrected or signalled events are handled by the exception
|
||||
* handler when it is enabled, so don't process those here.
|
||||
|
|
|
@ -42,7 +42,7 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned);
|
|||
* cmci_discover_lock protects against parallel discovery attempts
|
||||
* which could race against each other.
|
||||
*/
|
||||
static DEFINE_RAW_SPINLOCK(cmci_discover_lock);
|
||||
static DEFINE_SPINLOCK(cmci_discover_lock);
|
||||
|
||||
#define CMCI_THRESHOLD 1
|
||||
#define CMCI_POLL_INTERVAL (30 * HZ)
|
||||
|
@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void)
|
|||
int bank;
|
||||
u64 val;
|
||||
|
||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
owned = __get_cpu_var(mce_banks_owned);
|
||||
for_each_set_bit(bank, owned, MAX_NR_BANKS) {
|
||||
rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
|
||||
val &= ~MCI_CTL2_CMCI_EN;
|
||||
wrmsrl(MSR_IA32_MCx_CTL2(bank), val);
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
}
|
||||
|
||||
static bool cmci_storm_detect(void)
|
||||
|
@ -211,7 +211,7 @@ static void cmci_discover(int banks)
|
|||
int i;
|
||||
int bios_wrong_thresh = 0;
|
||||
|
||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
for (i = 0; i < banks; i++) {
|
||||
u64 val;
|
||||
int bios_zero_thresh = 0;
|
||||
|
@ -266,7 +266,7 @@ static void cmci_discover(int banks)
|
|||
WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
|
||||
}
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) {
|
||||
pr_info_once(
|
||||
"bios_cmci_threshold: Some banks do not have valid thresholds set\n");
|
||||
|
@ -316,10 +316,10 @@ void cmci_clear(void)
|
|||
|
||||
if (!cmci_supported(&banks))
|
||||
return;
|
||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
for (i = 0; i < banks; i++)
|
||||
__cmci_disable_bank(i);
|
||||
raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
}
|
||||
|
||||
static void cmci_rediscover_work_func(void *arg)
|
||||
|
@ -360,9 +360,9 @@ void cmci_disable_bank(int bank)
|
|||
if (!cmci_supported(&banks))
|
||||
return;
|
||||
|
||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||
__cmci_disable_bank(bank);
|
||||
raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
}
|
||||
|
||||
static void intel_init_cmci(void)
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
|
||||
#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
|
||||
#define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
|
||||
#define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */
|
||||
#define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */
|
||||
#define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
|
||||
|
||||
/* Clients have PP0, PKG */
|
||||
|
@ -72,6 +72,12 @@
|
|||
1<<RAPL_IDX_PKG_NRG_STAT|\
|
||||
1<<RAPL_IDX_RAM_NRG_STAT)
|
||||
|
||||
/* Servers have PP0, PKG, RAM, PP1 */
|
||||
#define RAPL_IDX_HSW (1<<RAPL_IDX_PP0_NRG_STAT|\
|
||||
1<<RAPL_IDX_PKG_NRG_STAT|\
|
||||
1<<RAPL_IDX_RAM_NRG_STAT|\
|
||||
1<<RAPL_IDX_PP1_NRG_STAT)
|
||||
|
||||
/*
|
||||
* event code: LSB 8 bits, passed in attr->config
|
||||
* any other bit is reserved
|
||||
|
@ -425,6 +431,24 @@ static struct attribute *rapl_events_cln_attr[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *rapl_events_hsw_attr[] = {
|
||||
EVENT_PTR(rapl_cores),
|
||||
EVENT_PTR(rapl_pkg),
|
||||
EVENT_PTR(rapl_gpu),
|
||||
EVENT_PTR(rapl_ram),
|
||||
|
||||
EVENT_PTR(rapl_cores_unit),
|
||||
EVENT_PTR(rapl_pkg_unit),
|
||||
EVENT_PTR(rapl_gpu_unit),
|
||||
EVENT_PTR(rapl_ram_unit),
|
||||
|
||||
EVENT_PTR(rapl_cores_scale),
|
||||
EVENT_PTR(rapl_pkg_scale),
|
||||
EVENT_PTR(rapl_gpu_scale),
|
||||
EVENT_PTR(rapl_ram_scale),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group rapl_pmu_events_group = {
|
||||
.name = "events",
|
||||
.attrs = NULL, /* patched at runtime */
|
||||
|
@ -511,6 +535,7 @@ static int rapl_cpu_prepare(int cpu)
|
|||
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
|
||||
int phys_id = topology_physical_package_id(cpu);
|
||||
u64 ms;
|
||||
u64 msr_rapl_power_unit_bits;
|
||||
|
||||
if (pmu)
|
||||
return 0;
|
||||
|
@ -518,6 +543,9 @@ static int rapl_cpu_prepare(int cpu)
|
|||
if (phys_id < 0)
|
||||
return -1;
|
||||
|
||||
if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
|
||||
return -1;
|
||||
|
||||
pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
|
||||
if (!pmu)
|
||||
return -1;
|
||||
|
@ -531,8 +559,7 @@ static int rapl_cpu_prepare(int cpu)
|
|||
*
|
||||
* we cache in local PMU instance
|
||||
*/
|
||||
rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
|
||||
pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
|
||||
pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
||||
pmu->pmu = &rapl_pmu_class;
|
||||
|
||||
/*
|
||||
|
@ -631,11 +658,14 @@ static int __init rapl_pmu_init(void)
|
|||
switch (boot_cpu_data.x86_model) {
|
||||
case 42: /* Sandy Bridge */
|
||||
case 58: /* Ivy Bridge */
|
||||
case 60: /* Haswell */
|
||||
case 69: /* Haswell-Celeron */
|
||||
rapl_cntr_mask = RAPL_IDX_CLN;
|
||||
rapl_pmu_events_group.attrs = rapl_events_cln_attr;
|
||||
break;
|
||||
case 60: /* Haswell */
|
||||
case 69: /* Haswell-Celeron */
|
||||
rapl_cntr_mask = RAPL_IDX_HSW;
|
||||
rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
|
||||
break;
|
||||
case 45: /* Sandy Bridge-EP */
|
||||
case 62: /* IvyTown */
|
||||
rapl_cntr_mask = RAPL_IDX_SRV;
|
||||
|
@ -650,7 +680,9 @@ static int __init rapl_pmu_init(void)
|
|||
cpu_notifier_register_begin();
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
rapl_cpu_prepare(cpu);
|
||||
ret = rapl_cpu_prepare(cpu);
|
||||
if (ret)
|
||||
goto out;
|
||||
rapl_cpu_init(cpu);
|
||||
}
|
||||
|
||||
|
@ -673,6 +705,7 @@ static int __init rapl_pmu_init(void)
|
|||
hweight32(rapl_cntr_mask),
|
||||
ktime_to_ms(pmu->timer_interval));
|
||||
|
||||
out:
|
||||
cpu_notifier_register_done();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -240,7 +240,7 @@ static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_s
|
|||
return base;
|
||||
}
|
||||
|
||||
#define KB(x) ((x) * 1024)
|
||||
#define KB(x) ((x) * 1024UL)
|
||||
#define MB(x) (KB (KB (x)))
|
||||
#define GB(x) (MB (KB (x)))
|
||||
|
||||
|
|
|
@ -897,9 +897,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
struct kprobe *cur = kprobe_running();
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
switch (kcb->kprobe_status) {
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_REENTER:
|
||||
if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) {
|
||||
/* This must happen on single-stepping */
|
||||
WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS &&
|
||||
kcb->kprobe_status != KPROBE_REENTER);
|
||||
/*
|
||||
* We are here because the instruction being single
|
||||
* stepped caused a page fault. We reset the current
|
||||
|
@ -914,9 +915,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
else
|
||||
reset_current_kprobe();
|
||||
preempt_enable_no_resched();
|
||||
break;
|
||||
case KPROBE_HIT_ACTIVE:
|
||||
case KPROBE_HIT_SSDONE:
|
||||
} else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
|
||||
kcb->kprobe_status == KPROBE_HIT_SSDONE) {
|
||||
/*
|
||||
* We increment the nmissed count for accounting,
|
||||
* we can also use npre/npostfault count for accounting
|
||||
|
@ -945,10 +945,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
* fixup routine could not handle it,
|
||||
* Let do_page_fault() fix it.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,8 +114,8 @@ EXPORT_SYMBOL(machine_real_restart);
|
|||
*/
|
||||
static int __init set_pci_reboot(const struct dmi_system_id *d)
|
||||
{
|
||||
if (reboot_type != BOOT_CF9) {
|
||||
reboot_type = BOOT_CF9;
|
||||
if (reboot_type != BOOT_CF9_FORCE) {
|
||||
reboot_type = BOOT_CF9_FORCE;
|
||||
pr_info("%s series board detected. Selecting %s-method for reboots.\n",
|
||||
d->ident, "PCI");
|
||||
}
|
||||
|
@ -458,20 +458,23 @@ void __attribute__((weak)) mach_reboot_fixups(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Windows compatible x86 hardware expects the following on reboot:
|
||||
* To the best of our knowledge Windows compatible x86 hardware expects
|
||||
* the following on reboot:
|
||||
*
|
||||
* 1) If the FADT has the ACPI reboot register flag set, try it
|
||||
* 2) If still alive, write to the keyboard controller
|
||||
* 3) If still alive, write to the ACPI reboot register again
|
||||
* 4) If still alive, write to the keyboard controller again
|
||||
* 5) If still alive, call the EFI runtime service to reboot
|
||||
* 6) If still alive, write to the PCI IO port 0xCF9 to reboot
|
||||
* 7) If still alive, inform BIOS to do a proper reboot
|
||||
* 6) If no EFI runtime service, call the BIOS to do a reboot
|
||||
*
|
||||
* If the machine is still alive at this stage, it gives up. We default to
|
||||
* following the same pattern, except that if we're still alive after (7) we'll
|
||||
* try to force a triple fault and then cycle between hitting the keyboard
|
||||
* controller and doing that
|
||||
* We default to following the same pattern. We also have
|
||||
* two other reboot methods: 'triple fault' and 'PCI', which
|
||||
* can be triggered via the reboot= kernel boot option or
|
||||
* via quirks.
|
||||
*
|
||||
* This means that this function can never return, it can misbehave
|
||||
* by not rebooting properly and hanging.
|
||||
*/
|
||||
static void native_machine_emergency_restart(void)
|
||||
{
|
||||
|
@ -492,6 +495,11 @@ static void native_machine_emergency_restart(void)
|
|||
for (;;) {
|
||||
/* Could also try the reset bit in the Hammer NB */
|
||||
switch (reboot_type) {
|
||||
case BOOT_ACPI:
|
||||
acpi_reboot();
|
||||
reboot_type = BOOT_KBD;
|
||||
break;
|
||||
|
||||
case BOOT_KBD:
|
||||
mach_reboot_fixups(); /* For board specific fixups */
|
||||
|
||||
|
@ -509,43 +517,29 @@ static void native_machine_emergency_restart(void)
|
|||
}
|
||||
break;
|
||||
|
||||
case BOOT_TRIPLE:
|
||||
load_idt(&no_idt);
|
||||
__asm__ __volatile__("int3");
|
||||
|
||||
/* We're probably dead after this, but... */
|
||||
reboot_type = BOOT_KBD;
|
||||
break;
|
||||
|
||||
case BOOT_BIOS:
|
||||
machine_real_restart(MRR_BIOS);
|
||||
|
||||
/* We're probably dead after this, but... */
|
||||
reboot_type = BOOT_TRIPLE;
|
||||
break;
|
||||
|
||||
case BOOT_ACPI:
|
||||
acpi_reboot();
|
||||
reboot_type = BOOT_KBD;
|
||||
break;
|
||||
|
||||
case BOOT_EFI:
|
||||
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
efi.reset_system(reboot_mode == REBOOT_WARM ?
|
||||
EFI_RESET_WARM :
|
||||
EFI_RESET_COLD,
|
||||
EFI_SUCCESS, 0, NULL);
|
||||
reboot_type = BOOT_CF9_COND;
|
||||
reboot_type = BOOT_BIOS;
|
||||
break;
|
||||
|
||||
case BOOT_CF9:
|
||||
case BOOT_BIOS:
|
||||
machine_real_restart(MRR_BIOS);
|
||||
|
||||
/* We're probably dead after this, but... */
|
||||
reboot_type = BOOT_CF9_SAFE;
|
||||
break;
|
||||
|
||||
case BOOT_CF9_FORCE:
|
||||
port_cf9_safe = true;
|
||||
/* Fall through */
|
||||
|
||||
case BOOT_CF9_COND:
|
||||
case BOOT_CF9_SAFE:
|
||||
if (port_cf9_safe) {
|
||||
u8 reboot_code = reboot_mode == REBOOT_WARM ?
|
||||
0x06 : 0x0E;
|
||||
u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E;
|
||||
u8 cf9 = inb(0xcf9) & ~reboot_code;
|
||||
outb(cf9|2, 0xcf9); /* Request hard reset */
|
||||
udelay(50);
|
||||
|
@ -553,7 +547,15 @@ static void native_machine_emergency_restart(void)
|
|||
outb(cf9|reboot_code, 0xcf9);
|
||||
udelay(50);
|
||||
}
|
||||
reboot_type = BOOT_BIOS;
|
||||
reboot_type = BOOT_TRIPLE;
|
||||
break;
|
||||
|
||||
case BOOT_TRIPLE:
|
||||
load_idt(&no_idt);
|
||||
__asm__ __volatile__("int3");
|
||||
|
||||
/* We're probably dead after this, but... */
|
||||
reboot_type = BOOT_KBD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
|
|||
const u32 kvm_supported_word9_x86_features =
|
||||
F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
|
||||
F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) |
|
||||
F(ADX);
|
||||
F(ADX) | F(SMAP);
|
||||
|
||||
/* all calls to cpuid_count() should be made on the same cpu */
|
||||
get_cpu();
|
||||
|
|
|
@ -48,6 +48,14 @@ static inline bool guest_cpuid_has_smep(struct kvm_vcpu *vcpu)
|
|||
return best && (best->ebx & bit(X86_FEATURE_SMEP));
|
||||
}
|
||||
|
||||
static inline bool guest_cpuid_has_smap(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
||||
best = kvm_find_cpuid_entry(vcpu, 7, 0);
|
||||
return best && (best->ebx & bit(X86_FEATURE_SMAP));
|
||||
}
|
||||
|
||||
static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
|
|
@ -3601,20 +3601,27 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
|
|||
}
|
||||
}
|
||||
|
||||
static void update_permission_bitmask(struct kvm_vcpu *vcpu,
|
||||
void update_permission_bitmask(struct kvm_vcpu *vcpu,
|
||||
struct kvm_mmu *mmu, bool ept)
|
||||
{
|
||||
unsigned bit, byte, pfec;
|
||||
u8 map;
|
||||
bool fault, x, w, u, wf, uf, ff, smep;
|
||||
bool fault, x, w, u, wf, uf, ff, smapf, cr4_smap, cr4_smep, smap = 0;
|
||||
|
||||
smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
|
||||
cr4_smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
|
||||
cr4_smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP);
|
||||
for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) {
|
||||
pfec = byte << 1;
|
||||
map = 0;
|
||||
wf = pfec & PFERR_WRITE_MASK;
|
||||
uf = pfec & PFERR_USER_MASK;
|
||||
ff = pfec & PFERR_FETCH_MASK;
|
||||
/*
|
||||
* PFERR_RSVD_MASK bit is set in PFEC if the access is not
|
||||
* subject to SMAP restrictions, and cleared otherwise. The
|
||||
* bit is only meaningful if the SMAP bit is set in CR4.
|
||||
*/
|
||||
smapf = !(pfec & PFERR_RSVD_MASK);
|
||||
for (bit = 0; bit < 8; ++bit) {
|
||||
x = bit & ACC_EXEC_MASK;
|
||||
w = bit & ACC_WRITE_MASK;
|
||||
|
@ -3626,12 +3633,33 @@ static void update_permission_bitmask(struct kvm_vcpu *vcpu,
|
|||
/* Allow supervisor writes if !cr0.wp */
|
||||
w |= !is_write_protection(vcpu) && !uf;
|
||||
/* Disallow supervisor fetches of user code if cr4.smep */
|
||||
x &= !(smep && u && !uf);
|
||||
x &= !(cr4_smep && u && !uf);
|
||||
|
||||
/*
|
||||
* SMAP:kernel-mode data accesses from user-mode
|
||||
* mappings should fault. A fault is considered
|
||||
* as a SMAP violation if all of the following
|
||||
* conditions are ture:
|
||||
* - X86_CR4_SMAP is set in CR4
|
||||
* - An user page is accessed
|
||||
* - Page fault in kernel mode
|
||||
* - if CPL = 3 or X86_EFLAGS_AC is clear
|
||||
*
|
||||
* Here, we cover the first three conditions.
|
||||
* The fourth is computed dynamically in
|
||||
* permission_fault() and is in smapf.
|
||||
*
|
||||
* Also, SMAP does not affect instruction
|
||||
* fetches, add the !ff check here to make it
|
||||
* clearer.
|
||||
*/
|
||||
smap = cr4_smap && u && !uf && !ff;
|
||||
} else
|
||||
/* Not really needed: no U/S accesses on ept */
|
||||
u = 1;
|
||||
|
||||
fault = (ff && !x) || (uf && !u) || (wf && !w);
|
||||
fault = (ff && !x) || (uf && !u) || (wf && !w) ||
|
||||
(smapf && smap);
|
||||
map |= fault << bit;
|
||||
}
|
||||
mmu->permissions[byte] = map;
|
||||
|
|
|
@ -44,11 +44,17 @@
|
|||
#define PT_DIRECTORY_LEVEL 2
|
||||
#define PT_PAGE_TABLE_LEVEL 1
|
||||
|
||||
#define PFERR_PRESENT_MASK (1U << 0)
|
||||
#define PFERR_WRITE_MASK (1U << 1)
|
||||
#define PFERR_USER_MASK (1U << 2)
|
||||
#define PFERR_RSVD_MASK (1U << 3)
|
||||
#define PFERR_FETCH_MASK (1U << 4)
|
||||
#define PFERR_PRESENT_BIT 0
|
||||
#define PFERR_WRITE_BIT 1
|
||||
#define PFERR_USER_BIT 2
|
||||
#define PFERR_RSVD_BIT 3
|
||||
#define PFERR_FETCH_BIT 4
|
||||
|
||||
#define PFERR_PRESENT_MASK (1U << PFERR_PRESENT_BIT)
|
||||
#define PFERR_WRITE_MASK (1U << PFERR_WRITE_BIT)
|
||||
#define PFERR_USER_MASK (1U << PFERR_USER_BIT)
|
||||
#define PFERR_RSVD_MASK (1U << PFERR_RSVD_BIT)
|
||||
#define PFERR_FETCH_MASK (1U << PFERR_FETCH_BIT)
|
||||
|
||||
int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
|
||||
void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
|
||||
|
@ -73,6 +79,8 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
|
|||
void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
|
||||
void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context,
|
||||
bool execonly);
|
||||
void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
|
||||
bool ept);
|
||||
|
||||
static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
|
||||
{
|
||||
|
@ -110,10 +118,30 @@ static inline bool is_write_protection(struct kvm_vcpu *vcpu)
|
|||
* Will a fault with a given page-fault error code (pfec) cause a permission
|
||||
* fault with the given access (in ACC_* format)?
|
||||
*/
|
||||
static inline bool permission_fault(struct kvm_mmu *mmu, unsigned pte_access,
|
||||
unsigned pfec)
|
||||
static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
|
||||
unsigned pte_access, unsigned pfec)
|
||||
{
|
||||
return (mmu->permissions[pfec >> 1] >> pte_access) & 1;
|
||||
int cpl = kvm_x86_ops->get_cpl(vcpu);
|
||||
unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
|
||||
|
||||
/*
|
||||
* If CPL < 3, SMAP prevention are disabled if EFLAGS.AC = 1.
|
||||
*
|
||||
* If CPL = 3, SMAP applies to all supervisor-mode data accesses
|
||||
* (these are implicit supervisor accesses) regardless of the value
|
||||
* of EFLAGS.AC.
|
||||
*
|
||||
* This computes (cpl < 3) && (rflags & X86_EFLAGS_AC), leaving
|
||||
* the result in X86_EFLAGS_AC. We then insert it in place of
|
||||
* the PFERR_RSVD_MASK bit; this bit will always be zero in pfec,
|
||||
* but it will be one in index if SMAP checks are being overridden.
|
||||
* It is important to keep this branchless.
|
||||
*/
|
||||
unsigned long smap = (cpl - 3) & (rflags & X86_EFLAGS_AC);
|
||||
int index = (pfec >> 1) +
|
||||
(smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1));
|
||||
|
||||
return (mmu->permissions[index] >> pte_access) & 1;
|
||||
}
|
||||
|
||||
void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm);
|
||||
|
|
|
@ -353,7 +353,7 @@ retry_walk:
|
|||
walker->ptes[walker->level - 1] = pte;
|
||||
} while (!is_last_gpte(mmu, walker->level, pte));
|
||||
|
||||
if (unlikely(permission_fault(mmu, pte_access, access))) {
|
||||
if (unlikely(permission_fault(vcpu, mmu, pte_access, access))) {
|
||||
errcode |= PFERR_PRESENT_MASK;
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -3484,13 +3484,14 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
|||
hw_cr4 &= ~X86_CR4_PAE;
|
||||
hw_cr4 |= X86_CR4_PSE;
|
||||
/*
|
||||
* SMEP is disabled if CPU is in non-paging mode in
|
||||
* hardware. However KVM always uses paging mode to
|
||||
* SMEP/SMAP is disabled if CPU is in non-paging mode
|
||||
* in hardware. However KVM always uses paging mode to
|
||||
* emulate guest non-paging mode with TDP.
|
||||
* To emulate this behavior, SMEP needs to be manually
|
||||
* disabled when guest switches to non-paging mode.
|
||||
* To emulate this behavior, SMEP/SMAP needs to be
|
||||
* manually disabled when guest switches to non-paging
|
||||
* mode.
|
||||
*/
|
||||
hw_cr4 &= ~X86_CR4_SMEP;
|
||||
hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
|
||||
} else if (!(cr4 & X86_CR4_PAE)) {
|
||||
hw_cr4 &= ~X86_CR4_PAE;
|
||||
}
|
||||
|
|
|
@ -652,6 +652,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
|||
if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has_smap(vcpu) && (cr4 & X86_CR4_SMAP))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE))
|
||||
return 1;
|
||||
|
||||
|
@ -680,6 +683,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
|||
(!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
|
||||
kvm_mmu_reset_context(vcpu);
|
||||
|
||||
if ((cr4 ^ old_cr4) & X86_CR4_SMAP)
|
||||
update_permission_bitmask(vcpu, vcpu->arch.walk_mmu, false);
|
||||
|
||||
if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE)
|
||||
kvm_update_cpuid(vcpu);
|
||||
|
||||
|
@ -1117,7 +1123,6 @@ static inline u64 get_kernel_ns(void)
|
|||
{
|
||||
struct timespec ts;
|
||||
|
||||
WARN_ON(preemptible());
|
||||
ktime_get_ts(&ts);
|
||||
monotonic_to_bootbased(&ts);
|
||||
return timespec_to_ns(&ts);
|
||||
|
@ -4164,7 +4169,8 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
|
|||
| (write ? PFERR_WRITE_MASK : 0);
|
||||
|
||||
if (vcpu_match_mmio_gva(vcpu, gva)
|
||||
&& !permission_fault(vcpu->arch.walk_mmu, vcpu->arch.access, access)) {
|
||||
&& !permission_fault(vcpu, vcpu->arch.walk_mmu,
|
||||
vcpu->arch.access, access)) {
|
||||
*gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT |
|
||||
(gva & (PAGE_SIZE - 1));
|
||||
trace_vcpu_match_mmio(gva, *gpa, write, false);
|
||||
|
|
|
@ -54,5 +54,7 @@ syshdr-$(CONFIG_X86_64) += syscalls_64.h
|
|||
|
||||
targets += $(uapisyshdr-y) $(syshdr-y)
|
||||
|
||||
PHONY += all
|
||||
all: $(addprefix $(uapi)/,$(uapisyshdr-y))
|
||||
all: $(addprefix $(out)/,$(syshdr-y))
|
||||
@:
|
||||
|
|
|
@ -359,3 +359,4 @@
|
|||
350 i386 finit_module sys_finit_module
|
||||
351 i386 sched_setattr sys_sched_setattr
|
||||
352 i386 sched_getattr sys_sched_getattr
|
||||
353 i386 renameat2 sys_renameat2
|
||||
|
|
|
@ -40,4 +40,6 @@ $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/ina
|
|||
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
|
||||
hostprogs-y += relocs
|
||||
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
||||
PHONY += relocs
|
||||
relocs: $(obj)/relocs
|
||||
@:
|
||||
|
|
|
@ -441,10 +441,11 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
|
|||
irq_ctx_init(cpu);
|
||||
#else
|
||||
clear_tsk_thread_flag(idle, TIF_FORK);
|
||||
#endif
|
||||
per_cpu(kernel_stack, cpu) =
|
||||
(unsigned long)task_stack_page(idle) -
|
||||
KERNEL_STACK_OFFSET + THREAD_SIZE;
|
||||
#endif
|
||||
|
||||
xen_setup_runstate_info(cpu);
|
||||
xen_setup_timer(cpu);
|
||||
xen_init_lock_cpu(cpu);
|
||||
|
|
|
@ -274,7 +274,7 @@ void __init xen_init_spinlocks(void)
|
|||
printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG "xen: PV spinlocks enabled\n");
|
||||
pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
|
||||
pv_lock_ops.unlock_kick = xen_unlock_kick;
|
||||
}
|
||||
|
@ -290,6 +290,9 @@ static __init int xen_init_spinlocks_jump(void)
|
|||
if (!xen_pvspin)
|
||||
return 0;
|
||||
|
||||
if (!xen_domain())
|
||||
return 0;
|
||||
|
||||
static_key_slow_inc(¶virt_ticketlocks_enabled);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,17 @@ ENDPROC(xen_sysexit)
|
|||
* stack state in whatever form its in, we keep things simple by only
|
||||
* using a single register which is pushed/popped on the stack.
|
||||
*/
|
||||
|
||||
.macro POP_FS
|
||||
1:
|
||||
popw %fs
|
||||
.pushsection .fixup, "ax"
|
||||
2: movw $0, (%esp)
|
||||
jmp 1b
|
||||
.popsection
|
||||
_ASM_EXTABLE(1b,2b)
|
||||
.endm
|
||||
|
||||
ENTRY(xen_iret)
|
||||
/* test eflags for special cases */
|
||||
testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
|
||||
|
@ -83,15 +94,13 @@ ENTRY(xen_iret)
|
|||
push %eax
|
||||
ESP_OFFSET=4 # bytes pushed onto stack
|
||||
|
||||
/*
|
||||
* Store vcpu_info pointer for easy access. Do it this way to
|
||||
* avoid having to reload %fs
|
||||
*/
|
||||
/* Store vcpu_info pointer for easy access */
|
||||
#ifdef CONFIG_SMP
|
||||
GET_THREAD_INFO(%eax)
|
||||
movl %ss:TI_cpu(%eax), %eax
|
||||
movl %ss:__per_cpu_offset(,%eax,4), %eax
|
||||
mov %ss:xen_vcpu(%eax), %eax
|
||||
pushw %fs
|
||||
movl $(__KERNEL_PERCPU), %eax
|
||||
movl %eax, %fs
|
||||
movl %fs:xen_vcpu, %eax
|
||||
POP_FS
|
||||
#else
|
||||
movl %ss:xen_vcpu, %eax
|
||||
#endif
|
||||
|
|
|
@ -53,8 +53,8 @@ obj-y += gpu/
|
|||
obj-$(CONFIG_CONNECTOR) += connector/
|
||||
|
||||
# i810fb and intelfb depend on char/agp/
|
||||
obj-$(CONFIG_FB_I810) += video/i810/
|
||||
obj-$(CONFIG_FB_INTEL) += video/intelfb/
|
||||
obj-$(CONFIG_FB_I810) += video/fbdev/i810/
|
||||
obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
|
||||
|
||||
obj-$(CONFIG_PARPORT) += parport/
|
||||
obj-y += base/ block/ misc/ mfd/ nfc/
|
||||
|
|
|
@ -614,39 +614,6 @@ void device_remove_bin_file(struct device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(device_remove_bin_file);
|
||||
|
||||
/**
|
||||
* device_schedule_callback_owner - helper to schedule a callback for a device
|
||||
* @dev: device.
|
||||
* @func: callback function to invoke later.
|
||||
* @owner: module owning the callback routine
|
||||
*
|
||||
* Attribute methods must not unregister themselves or their parent device
|
||||
* (which would amount to the same thing). Attempts to do so will deadlock,
|
||||
* since unregistration is mutually exclusive with driver callbacks.
|
||||
*
|
||||
* Instead methods can call this routine, which will attempt to allocate
|
||||
* and schedule a workqueue request to call back @func with @dev as its
|
||||
* argument in the workqueue's process context. @dev will be pinned until
|
||||
* @func returns.
|
||||
*
|
||||
* This routine is usually called via the inline device_schedule_callback(),
|
||||
* which automatically sets @owner to THIS_MODULE.
|
||||
*
|
||||
* Returns 0 if the request was submitted, -ENOMEM if storage could not
|
||||
* be allocated, -ENODEV if a reference to @owner isn't available.
|
||||
*
|
||||
* NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an
|
||||
* underlying sysfs routine (since it is intended for use by attribute
|
||||
* methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
|
||||
*/
|
||||
int device_schedule_callback_owner(struct device *dev,
|
||||
void (*func)(struct device *), struct module *owner)
|
||||
{
|
||||
return sysfs_schedule_callback(&dev->kobj,
|
||||
(void (*)(void *)) func, dev, owner);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
|
||||
|
||||
static void klist_children_get(struct klist_node *n)
|
||||
{
|
||||
struct device_private *p = to_device_private_parent(n);
|
||||
|
|
|
@ -187,8 +187,8 @@ static void driver_bound(struct device *dev)
|
|||
return;
|
||||
}
|
||||
|
||||
pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
|
||||
__func__, dev->driver->name);
|
||||
pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name,
|
||||
__func__, dev_name(dev));
|
||||
|
||||
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
static ssize_t show_##name(struct device *dev, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
unsigned int cpu = dev->id; \
|
||||
return sprintf(buf, "%d\n", topology_##name(cpu)); \
|
||||
return sprintf(buf, "%d\n", topology_##name(dev->id)); \
|
||||
}
|
||||
|
||||
#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
|
||||
|
|
|
@ -40,7 +40,7 @@ config SGI_MBCS
|
|||
source "drivers/tty/serial/Kconfig"
|
||||
|
||||
config TTY_PRINTK
|
||||
bool "TTY driver to output user messages via printk"
|
||||
tristate "TTY driver to output user messages via printk"
|
||||
depends on EXPERT && TTY
|
||||
default n
|
||||
---help---
|
||||
|
|
|
@ -61,18 +61,18 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
|
|||
}
|
||||
bcm2835_rng_ops.priv = (unsigned long)rng_base;
|
||||
|
||||
/* set warm-up count & enable */
|
||||
__raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
|
||||
__raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
|
||||
|
||||
/* register driver */
|
||||
err = hwrng_register(&bcm2835_rng_ops);
|
||||
if (err) {
|
||||
dev_err(dev, "hwrng registration failed\n");
|
||||
iounmap(rng_base);
|
||||
} else {
|
||||
} else
|
||||
dev_info(dev, "hwrng registered\n");
|
||||
|
||||
/* set warm-up count & enable */
|
||||
__raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
|
||||
__raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,18 @@ config IPMI_SI
|
|||
Currently, only KCS and SMIC are supported. If
|
||||
you are using IPMI, you should probably say "y" here.
|
||||
|
||||
config IPMI_SI_PROBE_DEFAULTS
|
||||
bool 'Probe for all possible IPMI system interfaces by default'
|
||||
default n
|
||||
depends on IPMI_SI
|
||||
help
|
||||
Modern systems will usually expose IPMI interfaces via a discoverable
|
||||
firmware mechanism such as ACPI or DMI. Older systems do not, and so
|
||||
the driver is forced to probe hardware manually. This may cause boot
|
||||
delays. Say "n" here to disable this manual probing. IPMI will then
|
||||
only be available on older systems if the "ipmi_si_intf.trydefaults=1"
|
||||
boot argument is passed.
|
||||
|
||||
config IPMI_WATCHDOG
|
||||
tristate 'IPMI Watchdog Timer'
|
||||
help
|
||||
|
|
|
@ -352,7 +352,7 @@ static inline void write_all_bytes(struct si_sm_data *bt)
|
|||
|
||||
static inline int read_all_bytes(struct si_sm_data *bt)
|
||||
{
|
||||
unsigned char i;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
|
||||
|
|
|
@ -251,8 +251,9 @@ static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
|
|||
if (!GET_STATUS_OBF(status)) {
|
||||
kcs->obf_timeout -= time;
|
||||
if (kcs->obf_timeout < 0) {
|
||||
start_error_recovery(kcs, "OBF not ready in time");
|
||||
return 1;
|
||||
kcs->obf_timeout = OBF_RETRY_TIMEOUT;
|
||||
start_error_recovery(kcs, "OBF not ready in time");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
|
|||
static int ipmi_init_msghandler(void);
|
||||
static void smi_recv_tasklet(unsigned long);
|
||||
static void handle_new_recv_msgs(ipmi_smi_t intf);
|
||||
static void need_waiter(ipmi_smi_t intf);
|
||||
|
||||
static int initialized;
|
||||
|
||||
|
@ -73,14 +74,28 @@ static struct proc_dir_entry *proc_ipmi_root;
|
|||
*/
|
||||
#define MAX_MSG_TIMEOUT 60000
|
||||
|
||||
/* Call every ~1000 ms. */
|
||||
#define IPMI_TIMEOUT_TIME 1000
|
||||
|
||||
/* How many jiffies does it take to get to the timeout time. */
|
||||
#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
|
||||
|
||||
/*
|
||||
* Request events from the queue every second (this is the number of
|
||||
* IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
|
||||
* future, IPMI will add a way to know immediately if an event is in
|
||||
* the queue and this silliness can go away.
|
||||
*/
|
||||
#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
|
||||
|
||||
/*
|
||||
* The main "user" data structure.
|
||||
*/
|
||||
struct ipmi_user {
|
||||
struct list_head link;
|
||||
|
||||
/* Set to "0" when the user is destroyed. */
|
||||
int valid;
|
||||
/* Set to false when the user is destroyed. */
|
||||
bool valid;
|
||||
|
||||
struct kref refcount;
|
||||
|
||||
|
@ -92,7 +107,7 @@ struct ipmi_user {
|
|||
ipmi_smi_t intf;
|
||||
|
||||
/* Does this interface receive IPMI events? */
|
||||
int gets_events;
|
||||
bool gets_events;
|
||||
};
|
||||
|
||||
struct cmd_rcvr {
|
||||
|
@ -383,6 +398,9 @@ struct ipmi_smi {
|
|||
unsigned int waiting_events_count; /* How many events in queue? */
|
||||
char delivering_events;
|
||||
char event_msg_printed;
|
||||
atomic_t event_waiters;
|
||||
unsigned int ticks_to_req_ev;
|
||||
int last_needs_timer;
|
||||
|
||||
/*
|
||||
* The event receiver for my BMC, only really used at panic
|
||||
|
@ -395,7 +413,7 @@ struct ipmi_smi {
|
|||
|
||||
/* For handling of maintenance mode. */
|
||||
int maintenance_mode;
|
||||
int maintenance_mode_enable;
|
||||
bool maintenance_mode_enable;
|
||||
int auto_maintenance_timeout;
|
||||
spinlock_t maintenance_mode_lock; /* Used in a timer... */
|
||||
|
||||
|
@ -451,7 +469,6 @@ static DEFINE_MUTEX(ipmi_interfaces_mutex);
|
|||
static LIST_HEAD(smi_watchers);
|
||||
static DEFINE_MUTEX(smi_watchers_mutex);
|
||||
|
||||
|
||||
#define ipmi_inc_stat(intf, stat) \
|
||||
atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
|
||||
#define ipmi_get_stat(intf, stat) \
|
||||
|
@ -772,6 +789,7 @@ static int intf_next_seq(ipmi_smi_t intf,
|
|||
*seq = i;
|
||||
*seqid = intf->seq_table[i].seqid;
|
||||
intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
|
||||
need_waiter(intf);
|
||||
} else {
|
||||
rv = -EAGAIN;
|
||||
}
|
||||
|
@ -941,7 +959,7 @@ int ipmi_create_user(unsigned int if_num,
|
|||
new_user->handler = handler;
|
||||
new_user->handler_data = handler_data;
|
||||
new_user->intf = intf;
|
||||
new_user->gets_events = 0;
|
||||
new_user->gets_events = false;
|
||||
|
||||
if (!try_module_get(intf->handlers->owner)) {
|
||||
rv = -ENODEV;
|
||||
|
@ -962,10 +980,15 @@ int ipmi_create_user(unsigned int if_num,
|
|||
*/
|
||||
mutex_unlock(&ipmi_interfaces_mutex);
|
||||
|
||||
new_user->valid = 1;
|
||||
new_user->valid = true;
|
||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
||||
list_add_rcu(&new_user->link, &intf->users);
|
||||
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
||||
if (handler->ipmi_watchdog_pretimeout) {
|
||||
/* User wants pretimeouts, so make sure to watch for them. */
|
||||
if (atomic_inc_return(&intf->event_waiters) == 1)
|
||||
need_waiter(intf);
|
||||
}
|
||||
*user = new_user;
|
||||
return 0;
|
||||
|
||||
|
@ -1019,7 +1042,13 @@ int ipmi_destroy_user(ipmi_user_t user)
|
|||
struct cmd_rcvr *rcvr;
|
||||
struct cmd_rcvr *rcvrs = NULL;
|
||||
|
||||
user->valid = 0;
|
||||
user->valid = false;
|
||||
|
||||
if (user->handler->ipmi_watchdog_pretimeout)
|
||||
atomic_dec(&intf->event_waiters);
|
||||
|
||||
if (user->gets_events)
|
||||
atomic_dec(&intf->event_waiters);
|
||||
|
||||
/* Remove the user from the interface's sequence table. */
|
||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
||||
|
@ -1155,25 +1184,23 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode)
|
|||
if (intf->maintenance_mode != mode) {
|
||||
switch (mode) {
|
||||
case IPMI_MAINTENANCE_MODE_AUTO:
|
||||
intf->maintenance_mode = mode;
|
||||
intf->maintenance_mode_enable
|
||||
= (intf->auto_maintenance_timeout > 0);
|
||||
break;
|
||||
|
||||
case IPMI_MAINTENANCE_MODE_OFF:
|
||||
intf->maintenance_mode = mode;
|
||||
intf->maintenance_mode_enable = 0;
|
||||
intf->maintenance_mode_enable = false;
|
||||
break;
|
||||
|
||||
case IPMI_MAINTENANCE_MODE_ON:
|
||||
intf->maintenance_mode = mode;
|
||||
intf->maintenance_mode_enable = 1;
|
||||
intf->maintenance_mode_enable = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
intf->maintenance_mode = mode;
|
||||
|
||||
maintenance_mode_update(intf);
|
||||
}
|
||||
|
@ -1184,7 +1211,7 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode)
|
|||
}
|
||||
EXPORT_SYMBOL(ipmi_set_maintenance_mode);
|
||||
|
||||
int ipmi_set_gets_events(ipmi_user_t user, int val)
|
||||
int ipmi_set_gets_events(ipmi_user_t user, bool val)
|
||||
{
|
||||
unsigned long flags;
|
||||
ipmi_smi_t intf = user->intf;
|
||||
|
@ -1194,8 +1221,18 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
|
|||
INIT_LIST_HEAD(&msgs);
|
||||
|
||||
spin_lock_irqsave(&intf->events_lock, flags);
|
||||
if (user->gets_events == val)
|
||||
goto out;
|
||||
|
||||
user->gets_events = val;
|
||||
|
||||
if (val) {
|
||||
if (atomic_inc_return(&intf->event_waiters) == 1)
|
||||
need_waiter(intf);
|
||||
} else {
|
||||
atomic_dec(&intf->event_waiters);
|
||||
}
|
||||
|
||||
if (intf->delivering_events)
|
||||
/*
|
||||
* Another thread is delivering events for this, so
|
||||
|
@ -1289,6 +1326,9 @@ int ipmi_register_for_cmd(ipmi_user_t user,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (atomic_inc_return(&intf->event_waiters) == 1)
|
||||
need_waiter(intf);
|
||||
|
||||
list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
|
||||
|
||||
out_unlock:
|
||||
|
@ -1330,6 +1370,7 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
|
|||
mutex_unlock(&intf->cmd_rcvrs_mutex);
|
||||
synchronize_rcu();
|
||||
while (rcvrs) {
|
||||
atomic_dec(&intf->event_waiters);
|
||||
rcvr = rcvrs;
|
||||
rcvrs = rcvr->next;
|
||||
kfree(rcvr);
|
||||
|
@ -1535,7 +1576,7 @@ static int i_ipmi_request(ipmi_user_t user,
|
|||
= IPMI_MAINTENANCE_MODE_TIMEOUT;
|
||||
if (!intf->maintenance_mode
|
||||
&& !intf->maintenance_mode_enable) {
|
||||
intf->maintenance_mode_enable = 1;
|
||||
intf->maintenance_mode_enable = true;
|
||||
maintenance_mode_update(intf);
|
||||
}
|
||||
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
||||
|
@ -2876,6 +2917,8 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
|
|||
(unsigned long) intf);
|
||||
atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
|
||||
spin_lock_init(&intf->events_lock);
|
||||
atomic_set(&intf->event_waiters, 0);
|
||||
intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
|
||||
INIT_LIST_HEAD(&intf->waiting_events);
|
||||
intf->waiting_events_count = 0;
|
||||
mutex_init(&intf->cmd_rcvrs_mutex);
|
||||
|
@ -3965,7 +4008,8 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
|
|||
|
||||
static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
||||
struct list_head *timeouts, long timeout_period,
|
||||
int slot, unsigned long *flags)
|
||||
int slot, unsigned long *flags,
|
||||
unsigned int *waiting_msgs)
|
||||
{
|
||||
struct ipmi_recv_msg *msg;
|
||||
struct ipmi_smi_handlers *handlers;
|
||||
|
@ -3977,8 +4021,10 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
|||
return;
|
||||
|
||||
ent->timeout -= timeout_period;
|
||||
if (ent->timeout > 0)
|
||||
if (ent->timeout > 0) {
|
||||
(*waiting_msgs)++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->retries_left == 0) {
|
||||
/* The message has used all its retries. */
|
||||
|
@ -3995,6 +4041,8 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
|||
struct ipmi_smi_msg *smi_msg;
|
||||
/* More retries, send again. */
|
||||
|
||||
(*waiting_msgs)++;
|
||||
|
||||
/*
|
||||
* Start with the max timer, set to normal timer after
|
||||
* the message is sent.
|
||||
|
@ -4040,117 +4088,118 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
|||
}
|
||||
}
|
||||
|
||||
static void ipmi_timeout_handler(long timeout_period)
|
||||
static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period)
|
||||
{
|
||||
ipmi_smi_t intf;
|
||||
struct list_head timeouts;
|
||||
struct ipmi_recv_msg *msg, *msg2;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
unsigned int waiting_msgs = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
|
||||
tasklet_schedule(&intf->recv_tasklet);
|
||||
/*
|
||||
* Go through the seq table and find any messages that
|
||||
* have timed out, putting them in the timeouts
|
||||
* list.
|
||||
*/
|
||||
INIT_LIST_HEAD(&timeouts);
|
||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
||||
for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
|
||||
check_msg_timeout(intf, &(intf->seq_table[i]),
|
||||
&timeouts, timeout_period, i,
|
||||
&flags, &waiting_msgs);
|
||||
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
||||
|
||||
/*
|
||||
* Go through the seq table and find any messages that
|
||||
* have timed out, putting them in the timeouts
|
||||
* list.
|
||||
*/
|
||||
INIT_LIST_HEAD(&timeouts);
|
||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
||||
for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
|
||||
check_msg_timeout(intf, &(intf->seq_table[i]),
|
||||
&timeouts, timeout_period, i,
|
||||
&flags);
|
||||
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
||||
list_for_each_entry_safe(msg, msg2, &timeouts, link)
|
||||
deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
|
||||
|
||||
list_for_each_entry_safe(msg, msg2, &timeouts, link)
|
||||
deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
|
||||
|
||||
/*
|
||||
* Maintenance mode handling. Check the timeout
|
||||
* optimistically before we claim the lock. It may
|
||||
* mean a timeout gets missed occasionally, but that
|
||||
* only means the timeout gets extended by one period
|
||||
* in that case. No big deal, and it avoids the lock
|
||||
* most of the time.
|
||||
*/
|
||||
/*
|
||||
* Maintenance mode handling. Check the timeout
|
||||
* optimistically before we claim the lock. It may
|
||||
* mean a timeout gets missed occasionally, but that
|
||||
* only means the timeout gets extended by one period
|
||||
* in that case. No big deal, and it avoids the lock
|
||||
* most of the time.
|
||||
*/
|
||||
if (intf->auto_maintenance_timeout > 0) {
|
||||
spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
|
||||
if (intf->auto_maintenance_timeout > 0) {
|
||||
spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
|
||||
if (intf->auto_maintenance_timeout > 0) {
|
||||
intf->auto_maintenance_timeout
|
||||
-= timeout_period;
|
||||
if (!intf->maintenance_mode
|
||||
&& (intf->auto_maintenance_timeout <= 0)) {
|
||||
intf->maintenance_mode_enable = 0;
|
||||
maintenance_mode_update(intf);
|
||||
}
|
||||
intf->auto_maintenance_timeout
|
||||
-= timeout_period;
|
||||
if (!intf->maintenance_mode
|
||||
&& (intf->auto_maintenance_timeout <= 0)) {
|
||||
intf->maintenance_mode_enable = false;
|
||||
maintenance_mode_update(intf);
|
||||
}
|
||||
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
||||
flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
||||
flags);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
tasklet_schedule(&intf->recv_tasklet);
|
||||
|
||||
return waiting_msgs;
|
||||
}
|
||||
|
||||
static void ipmi_request_event(void)
|
||||
static void ipmi_request_event(ipmi_smi_t intf)
|
||||
{
|
||||
ipmi_smi_t intf;
|
||||
struct ipmi_smi_handlers *handlers;
|
||||
|
||||
rcu_read_lock();
|
||||
/*
|
||||
* Called from the timer, no need to check if handlers is
|
||||
* valid.
|
||||
*/
|
||||
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
|
||||
/* No event requests when in maintenance mode. */
|
||||
if (intf->maintenance_mode_enable)
|
||||
continue;
|
||||
/* No event requests when in maintenance mode. */
|
||||
if (intf->maintenance_mode_enable)
|
||||
return;
|
||||
|
||||
handlers = intf->handlers;
|
||||
if (handlers)
|
||||
handlers->request_events(intf->send_info);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
handlers = intf->handlers;
|
||||
if (handlers)
|
||||
handlers->request_events(intf->send_info);
|
||||
}
|
||||
|
||||
static struct timer_list ipmi_timer;
|
||||
|
||||
/* Call every ~1000 ms. */
|
||||
#define IPMI_TIMEOUT_TIME 1000
|
||||
|
||||
/* How many jiffies does it take to get to the timeout time. */
|
||||
#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
|
||||
|
||||
/*
|
||||
* Request events from the queue every second (this is the number of
|
||||
* IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
|
||||
* future, IPMI will add a way to know immediately if an event is in
|
||||
* the queue and this silliness can go away.
|
||||
*/
|
||||
#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
|
||||
|
||||
static atomic_t stop_operation;
|
||||
static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
|
||||
|
||||
static void ipmi_timeout(unsigned long data)
|
||||
{
|
||||
ipmi_smi_t intf;
|
||||
int nt = 0;
|
||||
|
||||
if (atomic_read(&stop_operation))
|
||||
return;
|
||||
|
||||
ticks_to_req_ev--;
|
||||
if (ticks_to_req_ev == 0) {
|
||||
ipmi_request_event();
|
||||
ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
|
||||
int lnt = 0;
|
||||
|
||||
if (atomic_read(&intf->event_waiters)) {
|
||||
intf->ticks_to_req_ev--;
|
||||
if (intf->ticks_to_req_ev == 0) {
|
||||
ipmi_request_event(intf);
|
||||
intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
|
||||
}
|
||||
lnt++;
|
||||
}
|
||||
|
||||
lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME);
|
||||
|
||||
lnt = !!lnt;
|
||||
if (lnt != intf->last_needs_timer &&
|
||||
intf->handlers->set_need_watch)
|
||||
intf->handlers->set_need_watch(intf->send_info, lnt);
|
||||
intf->last_needs_timer = lnt;
|
||||
|
||||
nt += lnt;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
|
||||
|
||||
mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
|
||||
if (nt)
|
||||
mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
|
||||
}
|
||||
|
||||
static void need_waiter(ipmi_smi_t intf)
|
||||
{
|
||||
/* Racy, but worst case we start the timer twice. */
|
||||
if (!timer_pending(&ipmi_timer))
|
||||
mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
|
||||
}
|
||||
|
||||
static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0);
|
||||
static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);
|
||||
|
|
|
@ -217,7 +217,7 @@ struct smi_info {
|
|||
unsigned char msg_flags;
|
||||
|
||||
/* Does the BMC have an event buffer? */
|
||||
char has_event_buffer;
|
||||
bool has_event_buffer;
|
||||
|
||||
/*
|
||||
* If set to true, this will request events the next time the
|
||||
|
@ -230,7 +230,7 @@ struct smi_info {
|
|||
* call. Generally used after a panic to make sure stuff goes
|
||||
* out.
|
||||
*/
|
||||
int run_to_completion;
|
||||
bool run_to_completion;
|
||||
|
||||
/* The I/O port of an SI interface. */
|
||||
int port;
|
||||
|
@ -248,19 +248,25 @@ struct smi_info {
|
|||
/* The timer for this si. */
|
||||
struct timer_list si_timer;
|
||||
|
||||
/* This flag is set, if the timer is running (timer_pending() isn't enough) */
|
||||
bool timer_running;
|
||||
|
||||
/* The time (in jiffies) the last timeout occurred at. */
|
||||
unsigned long last_timeout_jiffies;
|
||||
|
||||
/* Used to gracefully stop the timer without race conditions. */
|
||||
atomic_t stop_operation;
|
||||
|
||||
/* Are we waiting for the events, pretimeouts, received msgs? */
|
||||
atomic_t need_watch;
|
||||
|
||||
/*
|
||||
* The driver will disable interrupts when it gets into a
|
||||
* situation where it cannot handle messages due to lack of
|
||||
* memory. Once that situation clears up, it will re-enable
|
||||
* interrupts.
|
||||
*/
|
||||
int interrupt_disabled;
|
||||
bool interrupt_disabled;
|
||||
|
||||
/* From the get device id response... */
|
||||
struct ipmi_device_id device_id;
|
||||
|
@ -273,7 +279,7 @@ struct smi_info {
|
|||
* True if we allocated the device, false if it came from
|
||||
* someplace else (like PCI).
|
||||
*/
|
||||
int dev_registered;
|
||||
bool dev_registered;
|
||||
|
||||
/* Slave address, could be reported from DMI. */
|
||||
unsigned char slave_addr;
|
||||
|
@ -297,19 +303,19 @@ struct smi_info {
|
|||
static int force_kipmid[SI_MAX_PARMS];
|
||||
static int num_force_kipmid;
|
||||
#ifdef CONFIG_PCI
|
||||
static int pci_registered;
|
||||
static bool pci_registered;
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI
|
||||
static int pnp_registered;
|
||||
static bool pnp_registered;
|
||||
#endif
|
||||
#ifdef CONFIG_PARISC
|
||||
static int parisc_registered;
|
||||
static bool parisc_registered;
|
||||
#endif
|
||||
|
||||
static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
|
||||
static int num_max_busy_us;
|
||||
|
||||
static int unload_when_empty = 1;
|
||||
static bool unload_when_empty = true;
|
||||
|
||||
static int add_smi(struct smi_info *smi);
|
||||
static int try_smi_init(struct smi_info *smi);
|
||||
|
@ -434,6 +440,13 @@ static void start_clear_flags(struct smi_info *smi_info)
|
|||
smi_info->si_state = SI_CLEARING_FLAGS;
|
||||
}
|
||||
|
||||
static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
|
||||
{
|
||||
smi_info->last_timeout_jiffies = jiffies;
|
||||
mod_timer(&smi_info->si_timer, new_val);
|
||||
smi_info->timer_running = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we have a situtaion where we run out of memory and cannot
|
||||
* allocate messages, we just leave them in the BMC and run the system
|
||||
|
@ -444,10 +457,9 @@ static inline void disable_si_irq(struct smi_info *smi_info)
|
|||
{
|
||||
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
|
||||
start_disable_irq(smi_info);
|
||||
smi_info->interrupt_disabled = 1;
|
||||
smi_info->interrupt_disabled = true;
|
||||
if (!atomic_read(&smi_info->stop_operation))
|
||||
mod_timer(&smi_info->si_timer,
|
||||
jiffies + SI_TIMEOUT_JIFFIES);
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,7 +467,7 @@ static inline void enable_si_irq(struct smi_info *smi_info)
|
|||
{
|
||||
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
|
||||
start_enable_irq(smi_info);
|
||||
smi_info->interrupt_disabled = 0;
|
||||
smi_info->interrupt_disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,7 +712,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
|
|||
dev_warn(smi_info->dev,
|
||||
"Maybe ok, but ipmi might run very slowly.\n");
|
||||
} else
|
||||
smi_info->interrupt_disabled = 0;
|
||||
smi_info->interrupt_disabled = false;
|
||||
smi_info->si_state = SI_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
@ -853,6 +865,19 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
|
|||
return si_sm_result;
|
||||
}
|
||||
|
||||
static void check_start_timer_thread(struct smi_info *smi_info)
|
||||
{
|
||||
if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
if (smi_info->thread)
|
||||
wake_up_process(smi_info->thread);
|
||||
|
||||
start_next_msg(smi_info);
|
||||
smi_event_handler(smi_info, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void sender(void *send_info,
|
||||
struct ipmi_smi_msg *msg,
|
||||
int priority)
|
||||
|
@ -906,27 +931,11 @@ static void sender(void *send_info,
|
|||
else
|
||||
list_add_tail(&msg->link, &smi_info->xmit_msgs);
|
||||
|
||||
if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
|
||||
/*
|
||||
* last_timeout_jiffies is updated here to avoid
|
||||
* smi_timeout() handler passing very large time_diff
|
||||
* value to smi_event_handler() that causes
|
||||
* the send command to abort.
|
||||
*/
|
||||
smi_info->last_timeout_jiffies = jiffies;
|
||||
|
||||
mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
if (smi_info->thread)
|
||||
wake_up_process(smi_info->thread);
|
||||
|
||||
start_next_msg(smi_info);
|
||||
smi_event_handler(smi_info, 0);
|
||||
}
|
||||
check_start_timer_thread(smi_info);
|
||||
spin_unlock_irqrestore(&smi_info->si_lock, flags);
|
||||
}
|
||||
|
||||
static void set_run_to_completion(void *send_info, int i_run_to_completion)
|
||||
static void set_run_to_completion(void *send_info, bool i_run_to_completion)
|
||||
{
|
||||
struct smi_info *smi_info = send_info;
|
||||
enum si_sm_result result;
|
||||
|
@ -1004,6 +1013,17 @@ static int ipmi_thread(void *data)
|
|||
|
||||
spin_lock_irqsave(&(smi_info->si_lock), flags);
|
||||
smi_result = smi_event_handler(smi_info, 0);
|
||||
|
||||
/*
|
||||
* If the driver is doing something, there is a possible
|
||||
* race with the timer. If the timer handler see idle,
|
||||
* and the thread here sees something else, the timer
|
||||
* handler won't restart the timer even though it is
|
||||
* required. So start it here if necessary.
|
||||
*/
|
||||
if (smi_result != SI_SM_IDLE && !smi_info->timer_running)
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
|
||||
&busy_until);
|
||||
|
@ -1011,9 +1031,15 @@ static int ipmi_thread(void *data)
|
|||
; /* do nothing */
|
||||
else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
|
||||
schedule();
|
||||
else if (smi_result == SI_SM_IDLE)
|
||||
schedule_timeout_interruptible(100);
|
||||
else
|
||||
else if (smi_result == SI_SM_IDLE) {
|
||||
if (atomic_read(&smi_info->need_watch)) {
|
||||
schedule_timeout_interruptible(100);
|
||||
} else {
|
||||
/* Wait to be woken up when we are needed. */
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
}
|
||||
} else
|
||||
schedule_timeout_interruptible(1);
|
||||
}
|
||||
return 0;
|
||||
|
@ -1024,7 +1050,7 @@ static void poll(void *send_info)
|
|||
{
|
||||
struct smi_info *smi_info = send_info;
|
||||
unsigned long flags = 0;
|
||||
int run_to_completion = smi_info->run_to_completion;
|
||||
bool run_to_completion = smi_info->run_to_completion;
|
||||
|
||||
/*
|
||||
* Make sure there is some delay in the poll loop so we can
|
||||
|
@ -1049,6 +1075,17 @@ static void request_events(void *send_info)
|
|||
atomic_set(&smi_info->req_events, 1);
|
||||
}
|
||||
|
||||
static void set_need_watch(void *send_info, bool enable)
|
||||
{
|
||||
struct smi_info *smi_info = send_info;
|
||||
unsigned long flags;
|
||||
|
||||
atomic_set(&smi_info->need_watch, enable);
|
||||
spin_lock_irqsave(&smi_info->si_lock, flags);
|
||||
check_start_timer_thread(smi_info);
|
||||
spin_unlock_irqrestore(&smi_info->si_lock, flags);
|
||||
}
|
||||
|
||||
static int initialized;
|
||||
|
||||
static void smi_timeout(unsigned long data)
|
||||
|
@ -1073,10 +1110,6 @@ static void smi_timeout(unsigned long data)
|
|||
* SI_USEC_PER_JIFFY);
|
||||
smi_result = smi_event_handler(smi_info, time_diff);
|
||||
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
|
||||
smi_info->last_timeout_jiffies = jiffies_now;
|
||||
|
||||
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
|
||||
/* Running with interrupts, only do long timeouts. */
|
||||
timeout = jiffies + SI_TIMEOUT_JIFFIES;
|
||||
|
@ -1098,7 +1131,10 @@ static void smi_timeout(unsigned long data)
|
|||
|
||||
do_mod_timer:
|
||||
if (smi_result != SI_SM_IDLE)
|
||||
mod_timer(&(smi_info->si_timer), timeout);
|
||||
smi_mod_timer(smi_info, timeout);
|
||||
else
|
||||
smi_info->timer_running = false;
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
}
|
||||
|
||||
static irqreturn_t si_irq_handler(int irq, void *data)
|
||||
|
@ -1146,8 +1182,7 @@ static int smi_start_processing(void *send_info,
|
|||
|
||||
/* Set up the timer that drives the interface. */
|
||||
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
|
||||
new_smi->last_timeout_jiffies = jiffies;
|
||||
mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
/*
|
||||
* Check if the user forcefully enabled the daemon.
|
||||
|
@ -1188,7 +1223,7 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void set_maintenance_mode(void *send_info, int enable)
|
||||
static void set_maintenance_mode(void *send_info, bool enable)
|
||||
{
|
||||
struct smi_info *smi_info = send_info;
|
||||
|
||||
|
@ -1202,6 +1237,7 @@ static struct ipmi_smi_handlers handlers = {
|
|||
.get_smi_info = get_smi_info,
|
||||
.sender = sender,
|
||||
.request_events = request_events,
|
||||
.set_need_watch = set_need_watch,
|
||||
.set_maintenance_mode = set_maintenance_mode,
|
||||
.set_run_to_completion = set_run_to_completion,
|
||||
.poll = poll,
|
||||
|
@ -1229,7 +1265,7 @@ static bool si_tryplatform = 1;
|
|||
#ifdef CONFIG_PCI
|
||||
static bool si_trypci = 1;
|
||||
#endif
|
||||
static bool si_trydefaults = 1;
|
||||
static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS);
|
||||
static char *si_type[SI_MAX_PARMS];
|
||||
#define MAX_SI_TYPE_STR 30
|
||||
static char si_type_str[MAX_SI_TYPE_STR];
|
||||
|
@ -1328,7 +1364,7 @@ module_param_array(force_kipmid, int, &num_force_kipmid, 0);
|
|||
MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
|
||||
" disabled(0). Normally the IPMI driver auto-detects"
|
||||
" this, but the value may be overridden by this parm.");
|
||||
module_param(unload_when_empty, int, 0);
|
||||
module_param(unload_when_empty, bool, 0);
|
||||
MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
|
||||
" specified or found, default is 1. Setting to 0"
|
||||
" is useful for hot add of devices using hotmod.");
|
||||
|
@ -3336,18 +3372,19 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
|
||||
new_smi->curr_msg = NULL;
|
||||
atomic_set(&new_smi->req_events, 0);
|
||||
new_smi->run_to_completion = 0;
|
||||
new_smi->run_to_completion = false;
|
||||
for (i = 0; i < SI_NUM_STATS; i++)
|
||||
atomic_set(&new_smi->stats[i], 0);
|
||||
|
||||
new_smi->interrupt_disabled = 1;
|
||||
new_smi->interrupt_disabled = true;
|
||||
atomic_set(&new_smi->stop_operation, 0);
|
||||
atomic_set(&new_smi->need_watch, 0);
|
||||
new_smi->intf_num = smi_num;
|
||||
smi_num++;
|
||||
|
||||
rv = try_enable_event_buffer(new_smi);
|
||||
if (rv == 0)
|
||||
new_smi->has_event_buffer = 1;
|
||||
new_smi->has_event_buffer = true;
|
||||
|
||||
/*
|
||||
* Start clearing the flags before we enable interrupts or the
|
||||
|
@ -3381,7 +3418,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
rv);
|
||||
goto out_err;
|
||||
}
|
||||
new_smi->dev_registered = 1;
|
||||
new_smi->dev_registered = true;
|
||||
}
|
||||
|
||||
rv = ipmi_register_smi(&handlers,
|
||||
|
@ -3430,7 +3467,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
wait_for_timer_and_thread(new_smi);
|
||||
|
||||
out_err:
|
||||
new_smi->interrupt_disabled = 1;
|
||||
new_smi->interrupt_disabled = true;
|
||||
|
||||
if (new_smi->intf) {
|
||||
ipmi_unregister_smi(new_smi->intf);
|
||||
|
@ -3466,7 +3503,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
|
||||
if (new_smi->dev_registered) {
|
||||
platform_device_unregister(new_smi->pdev);
|
||||
new_smi->dev_registered = 0;
|
||||
new_smi->dev_registered = false;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -3521,14 +3558,14 @@ static int init_ipmi_si(void)
|
|||
printk(KERN_ERR PFX "Unable to register "
|
||||
"PCI driver: %d\n", rv);
|
||||
else
|
||||
pci_registered = 1;
|
||||
pci_registered = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (si_tryacpi) {
|
||||
pnp_register_driver(&ipmi_pnp_driver);
|
||||
pnp_registered = 1;
|
||||
pnp_registered = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3544,7 +3581,7 @@ static int init_ipmi_si(void)
|
|||
|
||||
#ifdef CONFIG_PARISC
|
||||
register_parisc_driver(&ipmi_parisc_driver);
|
||||
parisc_registered = 1;
|
||||
parisc_registered = true;
|
||||
/* poking PC IO addresses will crash machine, don't do it */
|
||||
si_trydefaults = 0;
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,7 @@ config SYNCLINK_CS
|
|||
|
||||
This driver may be built as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want).
|
||||
The module will be called synclinkmp. If you want to do that, say M
|
||||
The module will be called synclink_cs. If you want to do that, say M
|
||||
here.
|
||||
|
||||
config CARDMAN_4000
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
struct ttyprintk_port {
|
||||
struct tty_port port;
|
||||
|
@ -210,10 +210,19 @@ static int __init ttyprintk_init(void)
|
|||
return 0;
|
||||
|
||||
error:
|
||||
put_tty_driver(ttyprintk_driver);
|
||||
tty_port_destroy(&tpk_port.port);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ttyprintk_exit(void)
|
||||
{
|
||||
tty_unregister_driver(ttyprintk_driver);
|
||||
put_tty_driver(ttyprintk_driver);
|
||||
tty_port_destroy(&tpk_port.port);
|
||||
ttyprintk_driver = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_initcall(ttyprintk_init);
|
||||
module_exit(ttyprintk_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -197,7 +197,7 @@ config AMCC_PPC440SPE_ADMA
|
|||
|
||||
config TIMB_DMA
|
||||
tristate "Timberdale FPGA DMA support"
|
||||
depends on MFD_TIMBERDALE || HAS_IOMEM
|
||||
depends on MFD_TIMBERDALE
|
||||
select DMA_ENGINE
|
||||
help
|
||||
Enable support for the Timberdale FPGA DMA engine.
|
||||
|
|
|
@ -182,11 +182,13 @@ static void edma_execute(struct edma_chan *echan)
|
|||
echan->ecc->dummy_slot);
|
||||
}
|
||||
|
||||
edma_resume(echan->ch_num);
|
||||
|
||||
if (edesc->processed <= MAX_NR_SG) {
|
||||
dev_dbg(dev, "first transfer starting %d\n", echan->ch_num);
|
||||
edma_start(echan->ch_num);
|
||||
} else {
|
||||
dev_dbg(dev, "chan: %d: completed %d elements, resuming\n",
|
||||
echan->ch_num, edesc->processed);
|
||||
edma_resume(echan->ch_num);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -968,7 +968,17 @@ static struct platform_driver fsl_edma_driver = {
|
|||
.remove = fsl_edma_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(fsl_edma_driver);
|
||||
static int __init fsl_edma_init(void)
|
||||
{
|
||||
return platform_driver_register(&fsl_edma_driver);
|
||||
}
|
||||
subsys_initcall(fsl_edma_init);
|
||||
|
||||
static void __exit fsl_edma_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&fsl_edma_driver);
|
||||
}
|
||||
module_exit(fsl_edma_exit);
|
||||
|
||||
MODULE_ALIAS("platform:fsl-edma");
|
||||
MODULE_DESCRIPTION("Freescale eDMA engine driver");
|
||||
|
|
|
@ -666,7 +666,7 @@ static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec,
|
|||
struct sirfsoc_dma *sdma = ofdma->of_dma_data;
|
||||
unsigned int request = dma_spec->args[0];
|
||||
|
||||
if (request > SIRFSOC_DMA_CHANNELS)
|
||||
if (request >= SIRFSOC_DMA_CHANNELS)
|
||||
return NULL;
|
||||
|
||||
return dma_get_slave_channel(&sdma->channels[request].chan);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* SPEAr platform SPI chipselect abstraction over gpiolib
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics
|
||||
* Shiraz Hashim <shiraz.hashim@st.com>
|
||||
* Shiraz Hashim <shiraz.linux.kernel@gmail.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
|
@ -205,6 +205,6 @@ static int __init spics_gpio_init(void)
|
|||
}
|
||||
subsys_initcall(spics_gpio_init);
|
||||
|
||||
MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
|
||||
MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
|
||||
MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
|
|||
|
||||
drm-usb-y := drm_usb.o
|
||||
|
||||
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o
|
||||
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o
|
||||
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
|
||||
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
|
||||
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
|
||||
|
|
|
@ -572,7 +572,7 @@ static u32 cbr_scan2(struct ast_private *ast)
|
|||
for (loop = 0; loop < CBR_PASSNUM2; loop++) {
|
||||
if ((data = cbr_test2(ast)) != 0) {
|
||||
data2 &= data;
|
||||
if (!data)
|
||||
if (!data2)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
|
@ -87,8 +88,6 @@ struct bochs_device {
|
|||
struct bochs_framebuffer gfb;
|
||||
struct drm_fb_helper helper;
|
||||
int size;
|
||||
int x1, y1, x2, y2; /* dirty rect */
|
||||
spinlock_t dirty_lock;
|
||||
bool initialized;
|
||||
} fb;
|
||||
};
|
||||
|
|
|
@ -94,6 +94,49 @@ static struct drm_driver bochs_driver = {
|
|||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* pm interface */
|
||||
|
||||
static int bochs_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||
struct bochs_device *bochs = drm_dev->dev_private;
|
||||
|
||||
drm_kms_helper_poll_disable(drm_dev);
|
||||
|
||||
if (bochs->fb.initialized) {
|
||||
console_lock();
|
||||
fb_set_suspend(bochs->fb.helper.fbdev, 1);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bochs_pm_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||
struct bochs_device *bochs = drm_dev->dev_private;
|
||||
|
||||
drm_helper_resume_force_mode(drm_dev);
|
||||
|
||||
if (bochs->fb.initialized) {
|
||||
console_lock();
|
||||
fb_set_suspend(bochs->fb.helper.fbdev, 0);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
drm_kms_helper_poll_enable(drm_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops bochs_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,
|
||||
bochs_pm_resume)
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* pci interface */
|
||||
|
||||
|
@ -155,6 +198,7 @@ static struct pci_driver bochs_pci_driver = {
|
|||
.id_table = bochs_pci_tbl,
|
||||
.probe = bochs_pci_probe,
|
||||
.remove = bochs_pci_remove,
|
||||
.driver.pm = &bochs_pm_ops,
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
|
|
@ -190,7 +190,6 @@ int bochs_fbdev_init(struct bochs_device *bochs)
|
|||
int ret;
|
||||
|
||||
bochs->fb.helper.funcs = &bochs_fb_helper_funcs;
|
||||
spin_lock_init(&bochs->fb.dirty_lock);
|
||||
|
||||
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
|
||||
1, 1);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче