Immutable branch between MFD and Regulator due for v3.16 merge-window.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJTXhcuAAoJEFGvii+H/HdhoJEQAI15rEldcSpzLCYiinEfiKUI d+6zn5Gx6pKtkfCWdplHxM82Fe5H/kbgCLq+SSCQ6DFrOGXC34i4JnmhdCvcaU/K OEtXsG1i2PNzJwMFcnXVW5wD6LnS/b+243XtBtfQ887j9A1R2tEM9ka+i5AP3+O2 NoBT9DshWWnj16CRJbMMFgNqDI6+QUoirgKzOXLp9stuzrThYU7kaluyMmMUREAx tXl8jOBH2Nu0YBiVi6Cgn1xNqtX0Snc9UU1QcugJzuPtyseFsQGUp1cP/ahmeP0y EFzKoDbKpag1BV/IEsKWfiD6KEEPFd3IUcZugXIhlRKSGsEcIRTeu6PBFMq9FssF hfajzbTw7aDFmYq3Ifc4V6MGtalnCoJz0bsM5XA1voWqXJ+9Tqp4p/5xbJVn2ObA /e8k5ljeRH+PBuRKrxgmJJUP3n/QXlJMZ+IrI3BTSeMLu2xZ1U95ynbHO8s3Dxdd CpX4xbDq82cBn+JNG3K9+l8XTZUdaWwEQ18VylVcbBdEa4jS2lMyYKIFCJiERLNt LCD6hzMGjF7/qVeXhi9AyITEe1XrFSjeTv8WH2R3C4vVXLcjQ3bCnWTFlszbGBsK /H0dUWg0HofMrR/oATydWtrgj5F+1aEIdZZqDU0hUCvC849c62zprqXUe7TbP6FT yvAlikr5PGMIWw89DCn1 =NGmT -----END PGP SIGNATURE----- Merge tag 'ib-mfd-regulator-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into regulator-tps65090 Immutable branch between MFD and Regulator due for v3.16 merge-window.
This commit is contained in:
commit
3e93457b45
1
.mailmap
1
.mailmap
@ -99,6 +99,7 @@ Sachin P Sant <ssant@in.ibm.com>
|
|||||||
Sam Ravnborg <sam@mars.ravnborg.org>
|
Sam Ravnborg <sam@mars.ravnborg.org>
|
||||||
Sascha Hauer <s.hauer@pengutronix.de>
|
Sascha Hauer <s.hauer@pengutronix.de>
|
||||||
S.Çağlar Onur <caglar@pardus.org.tr>
|
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>
|
Simon Kelley <simon@thekelleys.org.uk>
|
||||||
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
||||||
Stephen Hemminger <shemminger@osdl.org>
|
Stephen Hemminger <shemminger@osdl.org>
|
||||||
|
@ -276,7 +276,7 @@ X!Isound/sound_firmware.c
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect1><title>Frame Buffer Memory</title>
|
<sect1><title>Frame Buffer Memory</title>
|
||||||
!Edrivers/video/fbmem.c
|
!Edrivers/video/fbdev/core/fbmem.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<!--
|
<!--
|
||||||
<sect1><title>Frame Buffer Console</title>
|
<sect1><title>Frame Buffer Console</title>
|
||||||
@ -284,7 +284,7 @@ X!Edrivers/video/console/fbcon.c
|
|||||||
</sect1>
|
</sect1>
|
||||||
-->
|
-->
|
||||||
<sect1><title>Frame Buffer Colormap</title>
|
<sect1><title>Frame Buffer Colormap</title>
|
||||||
!Edrivers/video/fbcmap.c
|
!Edrivers/video/fbdev/core/fbcmap.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<!-- FIXME:
|
<!-- FIXME:
|
||||||
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
|
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
|
||||||
@ -294,11 +294,11 @@ X!Idrivers/video/fbgen.c
|
|||||||
</sect1>
|
</sect1>
|
||||||
KAO -->
|
KAO -->
|
||||||
<sect1><title>Frame Buffer Video Mode Database</title>
|
<sect1><title>Frame Buffer Video Mode Database</title>
|
||||||
!Idrivers/video/modedb.c
|
!Idrivers/video/fbdev/core/modedb.c
|
||||||
!Edrivers/video/modedb.c
|
!Edrivers/video/fbdev/core/modedb.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
|
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
|
||||||
!Edrivers/video/macmodes.c
|
!Edrivers/video/fbdev/macmodes.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>Frame Buffer Fonts</title>
|
<sect1><title>Frame Buffer Fonts</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -2285,6 +2285,11 @@ void intel_crt_init(struct drm_device *dev)
|
|||||||
<sect2>
|
<sect2>
|
||||||
<title>Modeset Helper Functions Reference</title>
|
<title>Modeset Helper Functions Reference</title>
|
||||||
!Edrivers/gpu/drm/drm_crtc_helper.c
|
!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>
|
||||||
<sect2>
|
<sect2>
|
||||||
<title>fbdev Helper Functions Reference</title>
|
<title>fbdev Helper Functions Reference</title>
|
||||||
|
97
Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
Normal file
97
Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
Normal file
@ -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
|
ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
|
||||||
adi,adt7461 +/-1C TDM Extended Temp Range I.C
|
adi,adt7461 +/-1C TDM Extended Temp Range I.C
|
||||||
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)
|
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,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)
|
atmel,at97sc3204t i2c trusted platform module (TPM)
|
||||||
capella,cm32181 CM32181: Ambient Light Sensor
|
capella,cm32181 CM32181: Ambient Light Sensor
|
||||||
catalyst,24c32 i2c serial eeprom
|
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,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
|
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
|
||||||
mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
||||||
|
national,lm63 Temperature sensor with integrated fan control
|
||||||
national,lm75 I2C TEMP SENSOR
|
national,lm75 I2C TEMP SENSOR
|
||||||
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
|
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
|
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)
|
nuvoton,npct501 i2c trusted platform module (TPM)
|
||||||
nxp,pca9556 Octal SMBus and I2C registered interface
|
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
|
- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
|
||||||
the maximum frame size (there's contradiction in ePAPR).
|
the maximum frame size (there's contradiction in ePAPR).
|
||||||
- phy-mode: string, operation mode of the PHY interface; supported values are
|
- 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
|
"rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto
|
||||||
standard property;
|
standard property;
|
||||||
- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
|
- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
|
||||||
|
@ -119,7 +119,7 @@ Optional Properties (for HDMI pins):
|
|||||||
Example:
|
Example:
|
||||||
// pin controller node
|
// pin controller node
|
||||||
pinctrl@35004800 {
|
pinctrl@35004800 {
|
||||||
compatible = "brcmbcm11351-pinctrl";
|
compatible = "brcm,bcm11351-pinctrl";
|
||||||
reg = <0x35004800 0x430>;
|
reg = <0x35004800 0x430>;
|
||||||
|
|
||||||
// pin configuration node
|
// pin configuration node
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
* Energymicro efm32 UART
|
* Energymicro efm32 UART
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : Should be "efm32,uart"
|
- compatible : Should be "energymicro,efm32-uart"
|
||||||
- reg : Address and length of the register set
|
- reg : Address and length of the register set
|
||||||
- interrupts : Should contain uart interrupt
|
- interrupts : Should contain uart interrupt
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ Optional properties:
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
uart@0x4000c400 {
|
uart@0x4000c400 {
|
||||||
compatible = "efm32,uart";
|
compatible = "energymicro,efm32-uart";
|
||||||
reg = <0x4000c400 0x400>;
|
reg = <0x4000c400 0x400>;
|
||||||
interrupts = <15>;
|
interrupts = <15>;
|
||||||
efm32,location = <0>;
|
efm32,location = <0>;
|
||||||
|
@ -22,6 +22,7 @@ auo AU Optronics Corporation
|
|||||||
avago Avago Technologies
|
avago Avago Technologies
|
||||||
bosch Bosch Sensortec GmbH
|
bosch Bosch Sensortec GmbH
|
||||||
brcm Broadcom Corporation
|
brcm Broadcom Corporation
|
||||||
|
buffalo Buffalo, Inc.
|
||||||
calxeda Calxeda
|
calxeda Calxeda
|
||||||
capella Capella Microsystems, Inc
|
capella Capella Microsystems, Inc
|
||||||
cavium Cavium, Inc.
|
cavium Cavium, Inc.
|
||||||
@ -33,15 +34,18 @@ cortina Cortina Systems, Inc.
|
|||||||
crystalfontz Crystalfontz America, Inc.
|
crystalfontz Crystalfontz America, Inc.
|
||||||
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
|
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
|
||||||
davicom DAVICOM Semiconductor, Inc.
|
davicom DAVICOM Semiconductor, Inc.
|
||||||
dlink D-Link Systems, Inc.
|
|
||||||
denx Denx Software Engineering
|
denx Denx Software Engineering
|
||||||
|
digi Digi International Inc.
|
||||||
|
dlink D-Link Corporation
|
||||||
dmo Data Modul AG
|
dmo Data Modul AG
|
||||||
|
ebv EBV Elektronik
|
||||||
edt Emerging Display Technologies
|
edt Emerging Display Technologies
|
||||||
emmicro EM Microelectronic
|
emmicro EM Microelectronic
|
||||||
epfl Ecole Polytechnique Fédérale de Lausanne
|
epfl Ecole Polytechnique Fédérale de Lausanne
|
||||||
epson Seiko Epson Corp.
|
epson Seiko Epson Corp.
|
||||||
est ESTeem Wireless Modems
|
est ESTeem Wireless Modems
|
||||||
eukrea Eukréa Electromatique
|
eukrea Eukréa Electromatique
|
||||||
|
excito Excito
|
||||||
fsl Freescale Semiconductor
|
fsl Freescale Semiconductor
|
||||||
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||||
gef 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.
|
hisilicon Hisilicon Limited.
|
||||||
honeywell Honeywell
|
honeywell Honeywell
|
||||||
hp Hewlett Packard
|
hp Hewlett Packard
|
||||||
|
i2se I2SE GmbH
|
||||||
ibm International Business Machines (IBM)
|
ibm International Business Machines (IBM)
|
||||||
idt Integrated Device Technologies, Inc.
|
idt Integrated Device Technologies, Inc.
|
||||||
|
iom Iomega Corporation
|
||||||
img Imagination Technologies Ltd.
|
img Imagination Technologies Ltd.
|
||||||
intel Intel Corporation
|
intel Intel Corporation
|
||||||
intercontrol Inter Control Group
|
intercontrol Inter Control Group
|
||||||
|
isee ISEE 2007 S.L.
|
||||||
isl Intersil
|
isl Intersil
|
||||||
karo Ka-Ro electronics GmbH
|
karo Ka-Ro electronics GmbH
|
||||||
|
keymile Keymile GmbH
|
||||||
lacie LaCie
|
lacie LaCie
|
||||||
lantiq Lantiq Semiconductor
|
lantiq Lantiq Semiconductor
|
||||||
lg LG Corporation
|
lg LG Corporation
|
||||||
@ -70,9 +78,12 @@ maxim Maxim Integrated Products
|
|||||||
microchip Microchip Technology Inc.
|
microchip Microchip Technology Inc.
|
||||||
mosaixtech Mosaix Technologies, Inc.
|
mosaixtech Mosaix Technologies, Inc.
|
||||||
moxa Moxa
|
moxa Moxa
|
||||||
|
mpl MPL AG
|
||||||
|
mxicy Macronix International Co., Ltd.
|
||||||
national National Semiconductor
|
national National Semiconductor
|
||||||
neonode Neonode Inc.
|
neonode Neonode Inc.
|
||||||
netgear NETGEAR
|
netgear NETGEAR
|
||||||
|
newhaven Newhaven Display International
|
||||||
nintendo Nintendo
|
nintendo Nintendo
|
||||||
nokia Nokia
|
nokia Nokia
|
||||||
nvidia NVIDIA
|
nvidia NVIDIA
|
||||||
@ -82,10 +93,12 @@ opencores OpenCores.org
|
|||||||
panasonic Panasonic Corporation
|
panasonic Panasonic Corporation
|
||||||
phytec PHYTEC Messtechnik GmbH
|
phytec PHYTEC Messtechnik GmbH
|
||||||
picochip Picochip Ltd
|
picochip Picochip Ltd
|
||||||
|
plathome Plat'Home Co., Ltd.
|
||||||
powervr PowerVR (deprecated, use img)
|
powervr PowerVR (deprecated, use img)
|
||||||
qca Qualcomm Atheros, Inc.
|
qca Qualcomm Atheros, Inc.
|
||||||
qcom Qualcomm Technologies, Inc
|
qcom Qualcomm Technologies, Inc
|
||||||
qnap QNAP Systems, Inc.
|
qnap QNAP Systems, Inc.
|
||||||
|
raidsonic RaidSonic Technology GmbH
|
||||||
ralink Mediatek/Ralink Technology Corp.
|
ralink Mediatek/Ralink Technology Corp.
|
||||||
ramtron Ramtron International
|
ramtron Ramtron International
|
||||||
realtek Realtek Semiconductor Corp.
|
realtek Realtek Semiconductor Corp.
|
||||||
@ -95,6 +108,7 @@ rockchip Fuzhou Rockchip Electronics Co., Ltd
|
|||||||
samsung Samsung Semiconductor
|
samsung Samsung Semiconductor
|
||||||
sbs Smart Battery System
|
sbs Smart Battery System
|
||||||
schindler Schindler
|
schindler Schindler
|
||||||
|
seagate Seagate Technology PLC
|
||||||
sil Silicon Image
|
sil Silicon Image
|
||||||
silabs Silicon Laboratories
|
silabs Silicon Laboratories
|
||||||
simtek
|
simtek
|
||||||
@ -111,6 +125,7 @@ ti Texas Instruments
|
|||||||
tlm Trusted Logic Mobility
|
tlm Trusted Logic Mobility
|
||||||
toshiba Toshiba Corporation
|
toshiba Toshiba Corporation
|
||||||
toumaz Toumaz
|
toumaz Toumaz
|
||||||
|
usi Universal Scientifc Industrial Co., Ltd.
|
||||||
v3 V3 Semiconductor
|
v3 V3 Semiconductor
|
||||||
via VIA Technologies, Inc.
|
via VIA Technologies, Inc.
|
||||||
voipac Voipac Technologies s.r.o.
|
voipac Voipac Technologies s.r.o.
|
||||||
@ -119,3 +134,4 @@ wlf Wolfson Microelectronics
|
|||||||
wm Wondermedia Technologies, Inc.
|
wm Wondermedia Technologies, Inc.
|
||||||
xes Extreme Engineering Solutions (X-ES)
|
xes Extreme Engineering Solutions (X-ES)
|
||||||
xlnx Xilinx
|
xlnx Xilinx
|
||||||
|
zyxel ZyXEL Communications Corp.
|
||||||
|
@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー
|
|||||||
もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
|
もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
|
||||||
最新の安定版カーネルです。
|
最新の安定版カーネルです。
|
||||||
|
|
||||||
3.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
|
3.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
|
||||||
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
|
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
|
||||||
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
|
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
|
||||||
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
|
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
|
||||||
|
@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt
|
|||||||
|
|
||||||
-stable ツリーにパッチを送付する手続き-
|
-stable ツリーにパッチを送付する手続き-
|
||||||
|
|
||||||
- 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
|
- 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
|
||||||
を送る。
|
を送る。
|
||||||
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
|
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
|
||||||
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
|
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
|
||||||
日かかる場合がある。
|
日かかる場合がある。
|
||||||
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
|
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
|
||||||
メンテナーによるレビューのために -stable キューに追加される。
|
メンテナーによるレビューのために -stable キューに追加される。
|
||||||
- パッチに stable@kernel.org のアドレスが付加されているときには、それ
|
- パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
|
||||||
が Linus のツリーに入る時に自動的に stable チームに email される。
|
が Linus のツリーに入る時に自動的に stable チームに email される。
|
||||||
- セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
|
- セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
|
||||||
きではなく、代わりに security@kernel.org のアドレスに送られる。
|
きではなく、代わりに security@kernel.org のアドレスに送られる。
|
||||||
|
|
||||||
レビューサイクル-
|
レビューサイクル-
|
||||||
|
@ -804,13 +804,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
dhash_entries= [KNL]
|
dhash_entries= [KNL]
|
||||||
Set number of hash buckets for dentry cache.
|
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]
|
disable= [IPV6]
|
||||||
See Documentation/networking/ipv6.txt.
|
See Documentation/networking/ipv6.txt.
|
||||||
|
|
||||||
@ -2939,9 +2932,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
rhash_entries= [KNL,NET]
|
rhash_entries= [KNL,NET]
|
||||||
Set number of hash buckets for route cache
|
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
|
ro [KNL] Mount root device read-only on boot
|
||||||
|
|
||||||
root= [KNL] Root filesystem
|
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
|
sonypi.*= [HW] Sony Programmable I/O Control Device driver
|
||||||
See Documentation/laptops/sonypi.txt
|
See Documentation/laptops/sonypi.txt
|
||||||
|
|
||||||
specialix= [HW,SERIAL] Specialix multi-serial port adapter
|
|
||||||
See Documentation/serial/specialix.txt.
|
|
||||||
|
|
||||||
spia_io_base= [HW,MTD]
|
spia_io_base= [HW,MTD]
|
||||||
spia_fio_base=
|
spia_fio_base=
|
||||||
spia_pedr=
|
spia_pedr=
|
||||||
|
@ -63,8 +63,6 @@ Magic Name Number Structure File
|
|||||||
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
|
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
|
||||||
CMAGIC 0x0111 user include/linux/a.out.h
|
CMAGIC 0x0111 user include/linux/a.out.h
|
||||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.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
|
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
|
||||||
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
|
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
|
||||||
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
|
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
|
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
|
||||||
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
|
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
|
||||||
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.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
|
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
|
||||||
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
|
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
|
||||||
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
|
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
|
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
|
||||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
|
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
|
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
|
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
|
||||||
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
|
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
|
||||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
|
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
|
||||||
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
|
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
|
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
|
||||||
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
|
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
|
||||||
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.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
|
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
|
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
|
||||||
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
|
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
|
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
|
||||||
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
|
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
|
||||||
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.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
|
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
|
||||||
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
|
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
|
||||||
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
|
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
|
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
|
||||||
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
|
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
|
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
|
||||||
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.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
|
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
|
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
|
||||||
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
|
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
|
||||||
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
|
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
|
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
|
||||||
KMALLOC_MAGIC 0x87654321 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
|
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
|
||||||
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.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
|
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
|
||||||
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
|
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
|
||||||
CODA_MAGIC 0xC0DAC0DA coda_file_info fs/coda/coda_fs_i.h
|
CODA_MAGIC 0xC0DAC0DA coda_file_info fs/coda/coda_fs_i.h
|
||||||
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.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
|
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
|
||||||
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
|
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
|
||||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
|
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
|
||||||
|
@ -2,23 +2,15 @@
|
|||||||
- this file.
|
- this file.
|
||||||
README.cycladesZ
|
README.cycladesZ
|
||||||
- info on Cyclades-Z firmware loading.
|
- info on Cyclades-Z firmware loading.
|
||||||
digiepca.txt
|
|
||||||
- info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
|
|
||||||
driver
|
driver
|
||||||
- intro to the low level serial driver.
|
- intro to the low level serial driver.
|
||||||
moxa-smartio
|
moxa-smartio
|
||||||
- file with info on installing/using Moxa multiport serial driver.
|
- file with info on installing/using Moxa multiport serial driver.
|
||||||
n_gsm.txt
|
n_gsm.txt
|
||||||
- GSM 0710 tty multiplexer howto.
|
- GSM 0710 tty multiplexer howto.
|
||||||
riscom8.txt
|
|
||||||
- notes on using the RISCom/8 multi-port serial driver.
|
|
||||||
rocket.txt
|
rocket.txt
|
||||||
- info on the Comtrol RocketPort multiport serial driver.
|
- info on the Comtrol RocketPort multiport serial driver.
|
||||||
serial-rs485.txt
|
serial-rs485.txt
|
||||||
- info about RS485 structures and support in the kernel.
|
- 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
|
tty.txt
|
||||||
- guide to the locking policies of the tty layer.
|
- 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
|
the stable tree without anything else needing to be done by the author
|
||||||
or subsystem maintainer.
|
or subsystem maintainer.
|
||||||
- If the patch requires other patches as prerequisites which can be
|
- 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:
|
the sign-off area:
|
||||||
|
|
||||||
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
|
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
|
allocation fails, the kernel will search other nodes, in order of
|
||||||
increasing distance from the preferred node based on information
|
increasing distance from the preferred node based on information
|
||||||
provided by the platform firmware.
|
provided by the platform firmware.
|
||||||
containing the cpu where the allocation takes place.
|
|
||||||
|
|
||||||
Internally, the Preferred policy uses a single node--the
|
Internally, the Preferred policy uses a single node--the
|
||||||
preferred_node member of struct mempolicy. When the internal
|
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
|
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
|
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
|
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
|
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
|
Thanks to the consistent remapping, applications preparing
|
||||||
nodemasks to specify memory policies using this flag should
|
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版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
|
||||||
版内核。
|
版内核。
|
||||||
|
|
||||||
2.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发
|
2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发
|
||||||
布新版本。
|
布新版本。
|
||||||
|
|
||||||
内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
|
内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
|
||||||
|
67
Documentation/zh_CN/io_ordering.txt
Normal file
67
Documentation/zh_CN/io_ordering.txt
Normal file
@ -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
|
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
|
||||||
CMAGIC 0x0111 user include/linux/a.out.h
|
CMAGIC 0x0111 user include/linux/a.out.h
|
||||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.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
|
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
|
||||||
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
|
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
|
||||||
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
|
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
|
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
|
||||||
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
|
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
|
||||||
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.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
|
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
|
||||||
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
|
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
|
||||||
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
|
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
|
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
|
||||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
|
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
|
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
|
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
|
||||||
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
|
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
|
||||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
|
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
|
||||||
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
|
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
|
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
|
||||||
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
|
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
|
||||||
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.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
|
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
|
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
|
||||||
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
|
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
|
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
|
||||||
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
|
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
|
||||||
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.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
|
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
|
||||||
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
|
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
|
||||||
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
|
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
|
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
|
||||||
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
|
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
|
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
|
||||||
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.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
|
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
|
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
|
||||||
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
|
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
|
||||||
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
|
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
|
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
|
||||||
KMALLOC_MAGIC 0x87654321 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
|
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
|
||||||
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.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
|
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
|
||||||
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
|
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
|
||||||
CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h
|
CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h
|
||||||
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.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
|
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
|
||||||
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
|
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
|
||||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.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回复,如果没有被接受,收
|
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
|
||||||
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
|
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
|
||||||
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
|
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
|
||||||
|
@ -6782,7 +6782,7 @@ PERFORMANCE EVENTS SUBSYSTEM
|
|||||||
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||||
M: Paul Mackerras <paulus@samba.org>
|
M: Paul Mackerras <paulus@samba.org>
|
||||||
M: Ingo Molnar <mingo@redhat.com>
|
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
|
L: linux-kernel@vger.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
|
||||||
S: Supported
|
S: Supported
|
||||||
@ -8315,7 +8315,7 @@ F: include/linux/compiler.h
|
|||||||
|
|
||||||
SPEAR PLATFORM SUPPORT
|
SPEAR PLATFORM SUPPORT
|
||||||
M: Viresh Kumar <viresh.linux@gmail.com>
|
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: spear-devel@list.st.com
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
W: http://www.st.com/spear
|
W: http://www.st.com/spear
|
||||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
|||||||
VERSION = 3
|
VERSION = 3
|
||||||
PATCHLEVEL = 15
|
PATCHLEVEL = 15
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc1
|
EXTRAVERSION = -rc2
|
||||||
NAME = Shuffling Zombie Juror
|
NAME = Shuffling Zombie Juror
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *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
|
* 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
|
* The code contained herein is licensed under the GNU General Public
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
* 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_CRC7=y
|
||||||
CONFIG_XZ_DEC=y
|
CONFIG_XZ_DEC=y
|
||||||
CONFIG_AVERAGE=y
|
CONFIG_AVERAGE=y
|
||||||
CONFIG_PINCTRL_CAPRI=y
|
CONFIG_PINCTRL_BCM281XX=y
|
||||||
CONFIG_WATCHDOG=y
|
CONFIG_WATCHDOG=y
|
||||||
CONFIG_BCM_KONA_WDT=y
|
CONFIG_BCM_KONA_WDT=y
|
||||||
CONFIG_BCM_KONA_WDT_DEBUG=y
|
CONFIG_BCM_KONA_WDT_DEBUG=y
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Picked from realview
|
* Picked from realview
|
||||||
* Copyright (c) 2012 ST Microelectronics Limited
|
* 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
|
* 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
|
* 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
|
* based upon linux/arch/arm/mach-realview/platsmp.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 ST Microelectronics Ltd.
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* arch/arm/plat-spear/time.c
|
* arch/arm/plat-spear/time.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 ST Microelectronics
|
* 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
|
* This file is licensed under the terms of the GNU General Public
|
||||||
* License version 2. This program is licensed "as is" without any
|
* License version 2. This program is licensed "as is" without any
|
||||||
|
@ -259,7 +259,7 @@ start_ap:
|
|||||||
* Switch into virtual mode:
|
* Switch into virtual mode:
|
||||||
*/
|
*/
|
||||||
movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
|
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
|
mov cr.ipsr=r16
|
||||||
movl r17=1f
|
movl r17=1f
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
# define PSR_DEFAULT_BITS psr.ac
|
# define PSR_DEFAULT_BITS psr.ac
|
||||||
#else
|
#else
|
||||||
# define PSR_DEFAULT_BITS 0
|
# define PSR_DEFAULT_BITS 0
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
#include "kvm_minstate.h"
|
#include "kvm_minstate.h"
|
||||||
#include "vti.h"
|
#include "vti.h"
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
# define PSR_DEFAULT_BITS psr.ac
|
# define PSR_DEFAULT_BITS psr.ac
|
||||||
#else
|
#else
|
||||||
# define PSR_DEFAULT_BITS 0
|
# 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,
|
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
|
||||||
unsigned long pfn);
|
unsigned long pfn);
|
||||||
void (*flush_icache_range)(unsigned long start, unsigned long end);
|
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 (*local_flush_icache_range)(unsigned long start, unsigned long end);
|
||||||
|
|
||||||
void (*__flush_cache_vmap)(void);
|
void (*__flush_cache_vmap)(void);
|
||||||
void (*__flush_cache_vunmap)(void);
|
void (*__flush_cache_vunmap)(void);
|
||||||
|
|
||||||
void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
|
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);
|
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
|
||||||
|
void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
|
||||||
|
|
||||||
/* MIPS specific cache operations */
|
/* MIPS specific cache operations */
|
||||||
void (*flush_cache_sigtramp)(unsigned long addr);
|
void (*flush_cache_sigtramp)(unsigned long addr);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#ifndef _ASMPARISC_SHMPARAM_H
|
#ifndef _ASMPARISC_SHMPARAM_H
|
||||||
#define _ASMPARISC_SHMPARAM_H
|
#define _ASMPARISC_SHMPARAM_H
|
||||||
|
|
||||||
#define __ARCH_FORCE_SHMLBA 1
|
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
|
||||||
|
#define SHM_COLOUR 0x00400000 /* shared mappings colouring */
|
||||||
#define SHMLBA 0x00400000 /* attach addr needs to be 4 Mb aligned */
|
|
||||||
|
|
||||||
#endif /* _ASMPARISC_SHMPARAM_H */
|
#endif /* _ASMPARISC_SHMPARAM_H */
|
||||||
|
@ -323,7 +323,8 @@ void flush_dcache_page(struct page *page)
|
|||||||
* specifically accesses it, of course) */
|
* specifically accesses it, of course) */
|
||||||
|
|
||||||
flush_tlb_page(mpnt, addr);
|
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));
|
__flush_cache_page(mpnt, addr, page_to_phys(page));
|
||||||
if (old_addr)
|
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)");
|
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)
|
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,
|
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,
|
static inline unsigned long COLOR_ALIGN(unsigned long addr,
|
||||||
unsigned int last_mmap, unsigned long pgoff)
|
unsigned int last_mmap, unsigned long pgoff)
|
||||||
{
|
{
|
||||||
unsigned long base = (addr+SHMLBA-1) & ~(SHMLBA-1);
|
unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
|
||||||
unsigned long off = (SHMLBA-1) &
|
unsigned long off = (SHM_COLOUR-1) &
|
||||||
(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
|
(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
|
||||||
|
|
||||||
return base + off;
|
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_FIXED) {
|
||||||
if ((flags & MAP_SHARED) && last_mmap &&
|
if ((flags & MAP_SHARED) && last_mmap &&
|
||||||
(addr - shared_align_offset(last_mmap, pgoff))
|
(addr - shared_align_offset(last_mmap, pgoff))
|
||||||
& (SHMLBA - 1))
|
& (SHM_COLOUR - 1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
goto found_addr;
|
goto found_addr;
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
|||||||
info.length = len;
|
info.length = len;
|
||||||
info.low_limit = mm->mmap_legacy_base;
|
info.low_limit = mm->mmap_legacy_base;
|
||||||
info.high_limit = mmap_upper_limit();
|
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);
|
info.align_offset = shared_align_offset(last_mmap, pgoff);
|
||||||
addr = vm_unmapped_area(&info);
|
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_FIXED) {
|
||||||
if ((flags & MAP_SHARED) && last_mmap &&
|
if ((flags & MAP_SHARED) && last_mmap &&
|
||||||
(addr - shared_align_offset(last_mmap, pgoff))
|
(addr - shared_align_offset(last_mmap, pgoff))
|
||||||
& (SHMLBA - 1))
|
& (SHM_COLOUR - 1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
goto found_addr;
|
goto found_addr;
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||||||
info.length = len;
|
info.length = len;
|
||||||
info.low_limit = PAGE_SIZE;
|
info.low_limit = PAGE_SIZE;
|
||||||
info.high_limit = mm->mmap_base;
|
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);
|
info.align_offset = shared_align_offset(last_mmap, pgoff);
|
||||||
addr = vm_unmapped_area(&info);
|
addr = vm_unmapped_area(&info);
|
||||||
if (!(addr & ~PAGE_MASK))
|
if (!(addr & ~PAGE_MASK))
|
||||||
|
@ -392,7 +392,7 @@
|
|||||||
ENTRY_COMP(vmsplice)
|
ENTRY_COMP(vmsplice)
|
||||||
ENTRY_COMP(move_pages) /* 295 */
|
ENTRY_COMP(move_pages) /* 295 */
|
||||||
ENTRY_SAME(getcpu)
|
ENTRY_SAME(getcpu)
|
||||||
ENTRY_SAME(epoll_pwait)
|
ENTRY_COMP(epoll_pwait)
|
||||||
ENTRY_COMP(statfs64)
|
ENTRY_COMP(statfs64)
|
||||||
ENTRY_COMP(fstatfs64)
|
ENTRY_COMP(fstatfs64)
|
||||||
ENTRY_COMP(kexec_load) /* 300 */
|
ENTRY_COMP(kexec_load) /* 300 */
|
||||||
|
@ -470,7 +470,7 @@ static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* if a load or store fault occured we can get the faulty addr */
|
/* 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;
|
fault_addr = d->fault_addr;
|
||||||
|
|
||||||
/* error in load or store? */
|
/* error in load or store? */
|
||||||
|
@ -151,7 +151,7 @@ int fixup_exception(struct pt_regs *regs)
|
|||||||
fix = search_exception_tables(regs->iaoq[0]);
|
fix = search_exception_tables(regs->iaoq[0]);
|
||||||
if (fix) {
|
if (fix) {
|
||||||
struct exception_data *d;
|
struct exception_data *d;
|
||||||
d = &__get_cpu_var(exception_data);
|
d = this_cpu_ptr(&exception_data);
|
||||||
d->fault_ip = regs->iaoq[0];
|
d->fault_ip = regs->iaoq[0];
|
||||||
d->fault_space = regs->isr;
|
d->fault_space = regs->isr;
|
||||||
d->fault_addr = regs->ior;
|
d->fault_addr = regs->ior;
|
||||||
|
@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
|
|||||||
unsigned long in_devfn)
|
unsigned long in_devfn)
|
||||||
{
|
{
|
||||||
struct pci_controller* hose;
|
struct pci_controller* hose;
|
||||||
struct pci_bus *bus = NULL;
|
struct pci_bus *tmp_bus, *bus = NULL;
|
||||||
struct device_node *hose_node;
|
struct device_node *hose_node;
|
||||||
|
|
||||||
/* Argh ! Please forgive me for that hack, but that's the
|
/* 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
|
* used on pre-domains setup. We return the first match
|
||||||
*/
|
*/
|
||||||
|
|
||||||
list_for_each_entry(bus, &pci_root_buses, node) {
|
list_for_each_entry(tmp_bus, &pci_root_buses, node) {
|
||||||
if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
|
if (in_bus >= tmp_bus->number &&
|
||||||
|
in_bus <= tmp_bus->busn_res.end) {
|
||||||
|
bus = tmp_bus;
|
||||||
break;
|
break;
|
||||||
bus = NULL;
|
}
|
||||||
}
|
}
|
||||||
if (bus == NULL || bus->dev.of_node == NULL)
|
if (bus == NULL || bus->dev.of_node == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -232,6 +232,7 @@ int __node_distance(int a, int b)
|
|||||||
|
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(__node_distance);
|
||||||
|
|
||||||
static void initialize_distance_lookup_table(int nid,
|
static void initialize_distance_lookup_table(int nid,
|
||||||
const __be32 *associativity)
|
const __be32 *associativity)
|
||||||
|
@ -31,4 +31,23 @@
|
|||||||
#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL
|
#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL
|
||||||
#define SIGP_STATUS_NOT_RUNNING 0x00000400UL
|
#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 */
|
#endif /* __S390_ASM_SIGP_H */
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef __ASM_SMP_H
|
#ifndef __ASM_SMP_H
|
||||||
#define __ASM_SMP_H
|
#define __ASM_SMP_H
|
||||||
|
|
||||||
|
#include <asm/sigp.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
#include <asm/lowcore.h>
|
#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 int smp_vcpu_scheduled(int cpu) { return 1; }
|
||||||
static inline void smp_yield_cpu(int cpu) { }
|
static inline void smp_yield_cpu(int cpu) { }
|
||||||
static inline void smp_yield(void) { }
|
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_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 */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
@ -282,7 +282,8 @@
|
|||||||
#define __NR_finit_module 344
|
#define __NR_finit_module 344
|
||||||
#define __NR_sched_setattr 345
|
#define __NR_sched_setattr 345
|
||||||
#define __NR_sched_getattr 346
|
#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
|
* 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
|
* 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(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_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_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;
|
char *mode;
|
||||||
|
|
||||||
mode = user_mode(regs) ? "User" : "Krnl";
|
mode = user_mode(regs) ? "User" : "Krnl";
|
||||||
printk("%s PSW : %p %p (%pSR)\n",
|
printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
|
||||||
mode, (void *) regs->psw.mask,
|
if (!user_mode(regs))
|
||||||
(void *) regs->psw.addr,
|
printk(" (%pSR)", (void *)regs->psw.addr);
|
||||||
(void *) regs->psw.addr);
|
printk("\n");
|
||||||
printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
|
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),
|
"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),
|
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)
|
if (task->thread.per_flags & PER_FLAG_NO_TE)
|
||||||
cr_new &= ~(1UL << 55);
|
cr_new &= ~(1UL << 55);
|
||||||
if (cr_new != cr)
|
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. */
|
/* Set or clear transaction execution TDC bits 62 and 63. */
|
||||||
__ctl_store(cr, 2, 2);
|
__ctl_store(cr, 2, 2);
|
||||||
cr_new = cr & ~3UL;
|
cr_new = cr & ~3UL;
|
||||||
|
@ -1027,3 +1027,35 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
/* Setup zfcpdump support */
|
/* Setup zfcpdump support */
|
||||||
setup_zfcpdump();
|
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.
|
* 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)
|
static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
|
||||||
{
|
{
|
||||||
int cc;
|
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_finit_module,sys_finit_module,compat_sys_finit_module)
|
||||||
SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */
|
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_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;
|
register unsigned long reg0 asm("0") = 0;
|
||||||
unsigned long tmp1, tmp2;
|
unsigned long tmp1, tmp2;
|
||||||
|
|
||||||
if (unlikely(!size))
|
|
||||||
return 0;
|
|
||||||
update_primary_asce(current);
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" la %2,0(%1)\n"
|
" la %2,0(%1)\n"
|
||||||
" la %3,0(%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)
|
unsigned long __strnlen_user(const char __user *src, unsigned long size)
|
||||||
{
|
{
|
||||||
|
if (unlikely(!size))
|
||||||
|
return 0;
|
||||||
update_primary_asce(current);
|
update_primary_asce(current);
|
||||||
return strnlen_user_srst(src, size);
|
return strnlen_user_srst(src, size);
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,133 @@ static inline int user_space_fault(struct pt_regs *regs)
|
|||||||
return 0;
|
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)
|
static inline void report_user_fault(struct pt_regs *regs, long signr)
|
||||||
{
|
{
|
||||||
if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
|
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);
|
regs->int_code);
|
||||||
print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
|
print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
|
||||||
printk(KERN_CONT "\n");
|
printk(KERN_CONT "\n");
|
||||||
printk(KERN_ALERT "failing address: %lX\n",
|
printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
|
||||||
regs->int_parm_long & __FAIL_ADDR_MASK);
|
regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
|
||||||
|
dump_fault_info(regs);
|
||||||
show_regs(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;
|
address = regs->int_parm_long & __FAIL_ADDR_MASK;
|
||||||
if (!user_space_fault(regs))
|
if (!user_space_fault(regs))
|
||||||
printk(KERN_ALERT "Unable to handle kernel pointer dereference"
|
printk(KERN_ALERT "Unable to handle kernel pointer dereference"
|
||||||
" at virtual kernel address %p\n", (void *)address);
|
" in virtual kernel address space\n");
|
||||||
else
|
else
|
||||||
printk(KERN_ALERT "Unable to handle kernel paging request"
|
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");
|
die(regs, "Oops");
|
||||||
do_exit(SIGKILL);
|
do_exit(SIGKILL);
|
||||||
}
|
}
|
||||||
|
@ -250,8 +250,8 @@ archclean:
|
|||||||
PHONY += kvmconfig
|
PHONY += kvmconfig
|
||||||
kvmconfig:
|
kvmconfig:
|
||||||
$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
|
$(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)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config
|
||||||
$(Q)yes "" | $(MAKE) oldconfig
|
$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
|
||||||
|
|
||||||
define archhelp
|
define archhelp
|
||||||
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
|
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
| X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
|
| X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
|
||||||
| X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
|
| X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
|
||||||
| X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
|
| 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)
|
#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;
|
struct mce m;
|
||||||
int i;
|
int i;
|
||||||
unsigned long *v;
|
|
||||||
|
|
||||||
this_cpu_inc(mce_poll_count);
|
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))
|
if (!(m.status & MCI_STATUS_VAL))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
v = &get_cpu_var(mce_polled_error);
|
this_cpu_write(mce_polled_error, 1);
|
||||||
set_bit(0, v);
|
|
||||||
/*
|
/*
|
||||||
* Uncorrected or signalled events are handled by the exception
|
* Uncorrected or signalled events are handled by the exception
|
||||||
* handler when it is enabled, so don't process those here.
|
* 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
|
* cmci_discover_lock protects against parallel discovery attempts
|
||||||
* which could race against each other.
|
* 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_THRESHOLD 1
|
||||||
#define CMCI_POLL_INTERVAL (30 * HZ)
|
#define CMCI_POLL_INTERVAL (30 * HZ)
|
||||||
@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void)
|
|||||||
int bank;
|
int bank;
|
||||||
u64 val;
|
u64 val;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||||
owned = __get_cpu_var(mce_banks_owned);
|
owned = __get_cpu_var(mce_banks_owned);
|
||||||
for_each_set_bit(bank, owned, MAX_NR_BANKS) {
|
for_each_set_bit(bank, owned, MAX_NR_BANKS) {
|
||||||
rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
|
rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
|
||||||
val &= ~MCI_CTL2_CMCI_EN;
|
val &= ~MCI_CTL2_CMCI_EN;
|
||||||
wrmsrl(MSR_IA32_MCx_CTL2(bank), val);
|
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)
|
static bool cmci_storm_detect(void)
|
||||||
@ -211,7 +211,7 @@ static void cmci_discover(int banks)
|
|||||||
int i;
|
int i;
|
||||||
int bios_wrong_thresh = 0;
|
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++) {
|
for (i = 0; i < banks; i++) {
|
||||||
u64 val;
|
u64 val;
|
||||||
int bios_zero_thresh = 0;
|
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)));
|
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) {
|
if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) {
|
||||||
pr_info_once(
|
pr_info_once(
|
||||||
"bios_cmci_threshold: Some banks do not have valid thresholds set\n");
|
"bios_cmci_threshold: Some banks do not have valid thresholds set\n");
|
||||||
@ -316,10 +316,10 @@ void cmci_clear(void)
|
|||||||
|
|
||||||
if (!cmci_supported(&banks))
|
if (!cmci_supported(&banks))
|
||||||
return;
|
return;
|
||||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||||
for (i = 0; i < banks; i++)
|
for (i = 0; i < banks; i++)
|
||||||
__cmci_disable_bank(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)
|
static void cmci_rediscover_work_func(void *arg)
|
||||||
@ -360,9 +360,9 @@ void cmci_disable_bank(int bank)
|
|||||||
if (!cmci_supported(&banks))
|
if (!cmci_supported(&banks))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&cmci_discover_lock, flags);
|
spin_lock_irqsave(&cmci_discover_lock, flags);
|
||||||
__cmci_disable_bank(bank);
|
__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)
|
static void intel_init_cmci(void)
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
|
#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
|
||||||
#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
|
#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
|
||||||
#define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
|
#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 */
|
#define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
|
||||||
|
|
||||||
/* Clients have PP0, PKG */
|
/* Clients have PP0, PKG */
|
||||||
@ -72,6 +72,12 @@
|
|||||||
1<<RAPL_IDX_PKG_NRG_STAT|\
|
1<<RAPL_IDX_PKG_NRG_STAT|\
|
||||||
1<<RAPL_IDX_RAM_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
|
* event code: LSB 8 bits, passed in attr->config
|
||||||
* any other bit is reserved
|
* any other bit is reserved
|
||||||
@ -425,6 +431,24 @@ static struct attribute *rapl_events_cln_attr[] = {
|
|||||||
NULL,
|
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 = {
|
static struct attribute_group rapl_pmu_events_group = {
|
||||||
.name = "events",
|
.name = "events",
|
||||||
.attrs = NULL, /* patched at runtime */
|
.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);
|
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
|
||||||
int phys_id = topology_physical_package_id(cpu);
|
int phys_id = topology_physical_package_id(cpu);
|
||||||
u64 ms;
|
u64 ms;
|
||||||
|
u64 msr_rapl_power_unit_bits;
|
||||||
|
|
||||||
if (pmu)
|
if (pmu)
|
||||||
return 0;
|
return 0;
|
||||||
@ -518,6 +543,9 @@ static int rapl_cpu_prepare(int cpu)
|
|||||||
if (phys_id < 0)
|
if (phys_id < 0)
|
||||||
return -1;
|
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));
|
pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
|
||||||
if (!pmu)
|
if (!pmu)
|
||||||
return -1;
|
return -1;
|
||||||
@ -531,8 +559,7 @@ static int rapl_cpu_prepare(int cpu)
|
|||||||
*
|
*
|
||||||
* we cache in local PMU instance
|
* we cache in local PMU instance
|
||||||
*/
|
*/
|
||||||
rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
|
pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
||||||
pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
|
|
||||||
pmu->pmu = &rapl_pmu_class;
|
pmu->pmu = &rapl_pmu_class;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -631,11 +658,14 @@ static int __init rapl_pmu_init(void)
|
|||||||
switch (boot_cpu_data.x86_model) {
|
switch (boot_cpu_data.x86_model) {
|
||||||
case 42: /* Sandy Bridge */
|
case 42: /* Sandy Bridge */
|
||||||
case 58: /* Ivy Bridge */
|
case 58: /* Ivy Bridge */
|
||||||
case 60: /* Haswell */
|
|
||||||
case 69: /* Haswell-Celeron */
|
|
||||||
rapl_cntr_mask = RAPL_IDX_CLN;
|
rapl_cntr_mask = RAPL_IDX_CLN;
|
||||||
rapl_pmu_events_group.attrs = rapl_events_cln_attr;
|
rapl_pmu_events_group.attrs = rapl_events_cln_attr;
|
||||||
break;
|
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 45: /* Sandy Bridge-EP */
|
||||||
case 62: /* IvyTown */
|
case 62: /* IvyTown */
|
||||||
rapl_cntr_mask = RAPL_IDX_SRV;
|
rapl_cntr_mask = RAPL_IDX_SRV;
|
||||||
@ -650,7 +680,9 @@ static int __init rapl_pmu_init(void)
|
|||||||
cpu_notifier_register_begin();
|
cpu_notifier_register_begin();
|
||||||
|
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
rapl_cpu_prepare(cpu);
|
ret = rapl_cpu_prepare(cpu);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
rapl_cpu_init(cpu);
|
rapl_cpu_init(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,6 +705,7 @@ static int __init rapl_pmu_init(void)
|
|||||||
hweight32(rapl_cntr_mask),
|
hweight32(rapl_cntr_mask),
|
||||||
ktime_to_ms(pmu->timer_interval));
|
ktime_to_ms(pmu->timer_interval));
|
||||||
|
|
||||||
|
out:
|
||||||
cpu_notifier_register_done();
|
cpu_notifier_register_done();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -240,7 +240,7 @@ static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_s
|
|||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KB(x) ((x) * 1024)
|
#define KB(x) ((x) * 1024UL)
|
||||||
#define MB(x) (KB (KB (x)))
|
#define MB(x) (KB (KB (x)))
|
||||||
#define GB(x) (MB (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 *cur = kprobe_running();
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
|
|
||||||
switch (kcb->kprobe_status) {
|
if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) {
|
||||||
case KPROBE_HIT_SS:
|
/* This must happen on single-stepping */
|
||||||
case KPROBE_REENTER:
|
WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS &&
|
||||||
|
kcb->kprobe_status != KPROBE_REENTER);
|
||||||
/*
|
/*
|
||||||
* We are here because the instruction being single
|
* We are here because the instruction being single
|
||||||
* stepped caused a page fault. We reset the current
|
* 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
|
else
|
||||||
reset_current_kprobe();
|
reset_current_kprobe();
|
||||||
preempt_enable_no_resched();
|
preempt_enable_no_resched();
|
||||||
break;
|
} else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
|
||||||
case KPROBE_HIT_ACTIVE:
|
kcb->kprobe_status == KPROBE_HIT_SSDONE) {
|
||||||
case KPROBE_HIT_SSDONE:
|
|
||||||
/*
|
/*
|
||||||
* We increment the nmissed count for accounting,
|
* We increment the nmissed count for accounting,
|
||||||
* we can also use npre/npostfault 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,
|
* fixup routine could not handle it,
|
||||||
* Let do_page_fault() fix it.
|
* Let do_page_fault() fix it.
|
||||||
*/
|
*/
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +114,8 @@ EXPORT_SYMBOL(machine_real_restart);
|
|||||||
*/
|
*/
|
||||||
static int __init set_pci_reboot(const struct dmi_system_id *d)
|
static int __init set_pci_reboot(const struct dmi_system_id *d)
|
||||||
{
|
{
|
||||||
if (reboot_type != BOOT_CF9) {
|
if (reboot_type != BOOT_CF9_FORCE) {
|
||||||
reboot_type = BOOT_CF9;
|
reboot_type = BOOT_CF9_FORCE;
|
||||||
pr_info("%s series board detected. Selecting %s-method for reboots.\n",
|
pr_info("%s series board detected. Selecting %s-method for reboots.\n",
|
||||||
d->ident, "PCI");
|
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
|
* 1) If the FADT has the ACPI reboot register flag set, try it
|
||||||
* 2) If still alive, write to the keyboard controller
|
* 2) If still alive, write to the keyboard controller
|
||||||
* 3) If still alive, write to the ACPI reboot register again
|
* 3) If still alive, write to the ACPI reboot register again
|
||||||
* 4) If still alive, write to the keyboard controller again
|
* 4) If still alive, write to the keyboard controller again
|
||||||
* 5) If still alive, call the EFI runtime service to reboot
|
* 5) If still alive, call the EFI runtime service to reboot
|
||||||
* 6) If still alive, write to the PCI IO port 0xCF9 to reboot
|
* 6) If no EFI runtime service, call the BIOS to do a reboot
|
||||||
* 7) If still alive, inform BIOS to do a proper reboot
|
|
||||||
*
|
*
|
||||||
* If the machine is still alive at this stage, it gives up. We default to
|
* We default to following the same pattern. We also have
|
||||||
* following the same pattern, except that if we're still alive after (7) we'll
|
* two other reboot methods: 'triple fault' and 'PCI', which
|
||||||
* try to force a triple fault and then cycle between hitting the keyboard
|
* can be triggered via the reboot= kernel boot option or
|
||||||
* controller and doing that
|
* 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)
|
static void native_machine_emergency_restart(void)
|
||||||
{
|
{
|
||||||
@ -492,6 +495,11 @@ static void native_machine_emergency_restart(void)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
/* Could also try the reset bit in the Hammer NB */
|
/* Could also try the reset bit in the Hammer NB */
|
||||||
switch (reboot_type) {
|
switch (reboot_type) {
|
||||||
|
case BOOT_ACPI:
|
||||||
|
acpi_reboot();
|
||||||
|
reboot_type = BOOT_KBD;
|
||||||
|
break;
|
||||||
|
|
||||||
case BOOT_KBD:
|
case BOOT_KBD:
|
||||||
mach_reboot_fixups(); /* For board specific fixups */
|
mach_reboot_fixups(); /* For board specific fixups */
|
||||||
|
|
||||||
@ -509,43 +517,29 @@ static void native_machine_emergency_restart(void)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case BOOT_EFI:
|
||||||
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||||
efi.reset_system(reboot_mode == REBOOT_WARM ?
|
efi.reset_system(reboot_mode == REBOOT_WARM ?
|
||||||
EFI_RESET_WARM :
|
EFI_RESET_WARM :
|
||||||
EFI_RESET_COLD,
|
EFI_RESET_COLD,
|
||||||
EFI_SUCCESS, 0, NULL);
|
EFI_SUCCESS, 0, NULL);
|
||||||
reboot_type = BOOT_CF9_COND;
|
reboot_type = BOOT_BIOS;
|
||||||
break;
|
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;
|
port_cf9_safe = true;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case BOOT_CF9_COND:
|
case BOOT_CF9_SAFE:
|
||||||
if (port_cf9_safe) {
|
if (port_cf9_safe) {
|
||||||
u8 reboot_code = reboot_mode == REBOOT_WARM ?
|
u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E;
|
||||||
0x06 : 0x0E;
|
|
||||||
u8 cf9 = inb(0xcf9) & ~reboot_code;
|
u8 cf9 = inb(0xcf9) & ~reboot_code;
|
||||||
outb(cf9|2, 0xcf9); /* Request hard reset */
|
outb(cf9|2, 0xcf9); /* Request hard reset */
|
||||||
udelay(50);
|
udelay(50);
|
||||||
@ -553,7 +547,15 @@ static void native_machine_emergency_restart(void)
|
|||||||
outb(cf9|reboot_code, 0xcf9);
|
outb(cf9|reboot_code, 0xcf9);
|
||||||
udelay(50);
|
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;
|
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 =
|
const u32 kvm_supported_word9_x86_features =
|
||||||
F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
|
F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
|
||||||
F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) |
|
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 */
|
/* all calls to cpuid_count() should be made on the same cpu */
|
||||||
get_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));
|
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)
|
static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct kvm_cpuid_entry2 *best;
|
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)
|
struct kvm_mmu *mmu, bool ept)
|
||||||
{
|
{
|
||||||
unsigned bit, byte, pfec;
|
unsigned bit, byte, pfec;
|
||||||
u8 map;
|
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) {
|
for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) {
|
||||||
pfec = byte << 1;
|
pfec = byte << 1;
|
||||||
map = 0;
|
map = 0;
|
||||||
wf = pfec & PFERR_WRITE_MASK;
|
wf = pfec & PFERR_WRITE_MASK;
|
||||||
uf = pfec & PFERR_USER_MASK;
|
uf = pfec & PFERR_USER_MASK;
|
||||||
ff = pfec & PFERR_FETCH_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) {
|
for (bit = 0; bit < 8; ++bit) {
|
||||||
x = bit & ACC_EXEC_MASK;
|
x = bit & ACC_EXEC_MASK;
|
||||||
w = bit & ACC_WRITE_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 */
|
/* Allow supervisor writes if !cr0.wp */
|
||||||
w |= !is_write_protection(vcpu) && !uf;
|
w |= !is_write_protection(vcpu) && !uf;
|
||||||
/* Disallow supervisor fetches of user code if cr4.smep */
|
/* 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
|
} else
|
||||||
/* Not really needed: no U/S accesses on ept */
|
/* Not really needed: no U/S accesses on ept */
|
||||||
u = 1;
|
u = 1;
|
||||||
|
|
||||||
fault = (ff && !x) || (uf && !u) || (wf && !w);
|
fault = (ff && !x) || (uf && !u) || (wf && !w) ||
|
||||||
|
(smapf && smap);
|
||||||
map |= fault << bit;
|
map |= fault << bit;
|
||||||
}
|
}
|
||||||
mmu->permissions[byte] = map;
|
mmu->permissions[byte] = map;
|
||||||
|
@ -44,11 +44,17 @@
|
|||||||
#define PT_DIRECTORY_LEVEL 2
|
#define PT_DIRECTORY_LEVEL 2
|
||||||
#define PT_PAGE_TABLE_LEVEL 1
|
#define PT_PAGE_TABLE_LEVEL 1
|
||||||
|
|
||||||
#define PFERR_PRESENT_MASK (1U << 0)
|
#define PFERR_PRESENT_BIT 0
|
||||||
#define PFERR_WRITE_MASK (1U << 1)
|
#define PFERR_WRITE_BIT 1
|
||||||
#define PFERR_USER_MASK (1U << 2)
|
#define PFERR_USER_BIT 2
|
||||||
#define PFERR_RSVD_MASK (1U << 3)
|
#define PFERR_RSVD_BIT 3
|
||||||
#define PFERR_FETCH_MASK (1U << 4)
|
#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]);
|
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);
|
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_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
|
||||||
void kvm_init_shadow_ept_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);
|
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)
|
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
|
* Will a fault with a given page-fault error code (pfec) cause a permission
|
||||||
* fault with the given access (in ACC_* format)?
|
* fault with the given access (in ACC_* format)?
|
||||||
*/
|
*/
|
||||||
static inline bool permission_fault(struct kvm_mmu *mmu, unsigned pte_access,
|
static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
|
||||||
unsigned pfec)
|
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);
|
void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm);
|
||||||
|
@ -353,7 +353,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
|
|||||||
walker->ptes[walker->level - 1] = pte;
|
walker->ptes[walker->level - 1] = pte;
|
||||||
} while (!is_last_gpte(mmu, walker->level, 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;
|
errcode |= PFERR_PRESENT_MASK;
|
||||||
goto error;
|
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_PAE;
|
||||||
hw_cr4 |= X86_CR4_PSE;
|
hw_cr4 |= X86_CR4_PSE;
|
||||||
/*
|
/*
|
||||||
* SMEP is disabled if CPU is in non-paging mode in
|
* SMEP/SMAP is disabled if CPU is in non-paging mode
|
||||||
* hardware. However KVM always uses paging mode to
|
* in hardware. However KVM always uses paging mode to
|
||||||
* emulate guest non-paging mode with TDP.
|
* emulate guest non-paging mode with TDP.
|
||||||
* To emulate this behavior, SMEP needs to be manually
|
* To emulate this behavior, SMEP/SMAP needs to be
|
||||||
* disabled when guest switches to non-paging mode.
|
* 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)) {
|
} else if (!(cr4 & X86_CR4_PAE)) {
|
||||||
hw_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))
|
if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (!guest_cpuid_has_smap(vcpu) && (cr4 & X86_CR4_SMAP))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE))
|
if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE))
|
||||||
return 1;
|
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)))
|
(!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
|
||||||
kvm_mmu_reset_context(vcpu);
|
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)
|
if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE)
|
||||||
kvm_update_cpuid(vcpu);
|
kvm_update_cpuid(vcpu);
|
||||||
|
|
||||||
@ -1117,7 +1123,6 @@ static inline u64 get_kernel_ns(void)
|
|||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
WARN_ON(preemptible());
|
|
||||||
ktime_get_ts(&ts);
|
ktime_get_ts(&ts);
|
||||||
monotonic_to_bootbased(&ts);
|
monotonic_to_bootbased(&ts);
|
||||||
return timespec_to_ns(&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);
|
| (write ? PFERR_WRITE_MASK : 0);
|
||||||
|
|
||||||
if (vcpu_match_mmio_gva(vcpu, gva)
|
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 |
|
*gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT |
|
||||||
(gva & (PAGE_SIZE - 1));
|
(gva & (PAGE_SIZE - 1));
|
||||||
trace_vcpu_match_mmio(gva, *gpa, write, false);
|
trace_vcpu_match_mmio(gva, *gpa, write, false);
|
||||||
|
@ -54,5 +54,7 @@ syshdr-$(CONFIG_X86_64) += syscalls_64.h
|
|||||||
|
|
||||||
targets += $(uapisyshdr-y) $(syshdr-y)
|
targets += $(uapisyshdr-y) $(syshdr-y)
|
||||||
|
|
||||||
|
PHONY += all
|
||||||
all: $(addprefix $(uapi)/,$(uapisyshdr-y))
|
all: $(addprefix $(uapi)/,$(uapisyshdr-y))
|
||||||
all: $(addprefix $(out)/,$(syshdr-y))
|
all: $(addprefix $(out)/,$(syshdr-y))
|
||||||
|
@:
|
||||||
|
@ -359,3 +359,4 @@
|
|||||||
350 i386 finit_module sys_finit_module
|
350 i386 finit_module sys_finit_module
|
||||||
351 i386 sched_setattr sys_sched_setattr
|
351 i386 sched_setattr sys_sched_setattr
|
||||||
352 i386 sched_getattr sys_sched_getattr
|
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
|
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
|
||||||
hostprogs-y += relocs
|
hostprogs-y += relocs
|
||||||
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
||||||
|
PHONY += relocs
|
||||||
relocs: $(obj)/relocs
|
relocs: $(obj)/relocs
|
||||||
|
@:
|
||||||
|
@ -441,10 +441,11 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
|
|||||||
irq_ctx_init(cpu);
|
irq_ctx_init(cpu);
|
||||||
#else
|
#else
|
||||||
clear_tsk_thread_flag(idle, TIF_FORK);
|
clear_tsk_thread_flag(idle, TIF_FORK);
|
||||||
|
#endif
|
||||||
per_cpu(kernel_stack, cpu) =
|
per_cpu(kernel_stack, cpu) =
|
||||||
(unsigned long)task_stack_page(idle) -
|
(unsigned long)task_stack_page(idle) -
|
||||||
KERNEL_STACK_OFFSET + THREAD_SIZE;
|
KERNEL_STACK_OFFSET + THREAD_SIZE;
|
||||||
#endif
|
|
||||||
xen_setup_runstate_info(cpu);
|
xen_setup_runstate_info(cpu);
|
||||||
xen_setup_timer(cpu);
|
xen_setup_timer(cpu);
|
||||||
xen_init_lock_cpu(cpu);
|
xen_init_lock_cpu(cpu);
|
||||||
|
@ -274,7 +274,7 @@ void __init xen_init_spinlocks(void)
|
|||||||
printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
|
printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
printk(KERN_DEBUG "xen: PV spinlocks enabled\n");
|
||||||
pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
|
pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
|
||||||
pv_lock_ops.unlock_kick = xen_unlock_kick;
|
pv_lock_ops.unlock_kick = xen_unlock_kick;
|
||||||
}
|
}
|
||||||
@ -290,6 +290,9 @@ static __init int xen_init_spinlocks_jump(void)
|
|||||||
if (!xen_pvspin)
|
if (!xen_pvspin)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!xen_domain())
|
||||||
|
return 0;
|
||||||
|
|
||||||
static_key_slow_inc(¶virt_ticketlocks_enabled);
|
static_key_slow_inc(¶virt_ticketlocks_enabled);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,17 @@ ENDPROC(xen_sysexit)
|
|||||||
* stack state in whatever form its in, we keep things simple by only
|
* stack state in whatever form its in, we keep things simple by only
|
||||||
* using a single register which is pushed/popped on the stack.
|
* 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)
|
ENTRY(xen_iret)
|
||||||
/* test eflags for special cases */
|
/* test eflags for special cases */
|
||||||
testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
|
testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
|
||||||
@ -83,15 +94,13 @@ ENTRY(xen_iret)
|
|||||||
push %eax
|
push %eax
|
||||||
ESP_OFFSET=4 # bytes pushed onto stack
|
ESP_OFFSET=4 # bytes pushed onto stack
|
||||||
|
|
||||||
/*
|
/* Store vcpu_info pointer for easy access */
|
||||||
* Store vcpu_info pointer for easy access. Do it this way to
|
|
||||||
* avoid having to reload %fs
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
GET_THREAD_INFO(%eax)
|
pushw %fs
|
||||||
movl %ss:TI_cpu(%eax), %eax
|
movl $(__KERNEL_PERCPU), %eax
|
||||||
movl %ss:__per_cpu_offset(,%eax,4), %eax
|
movl %eax, %fs
|
||||||
mov %ss:xen_vcpu(%eax), %eax
|
movl %fs:xen_vcpu, %eax
|
||||||
|
POP_FS
|
||||||
#else
|
#else
|
||||||
movl %ss:xen_vcpu, %eax
|
movl %ss:xen_vcpu, %eax
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,8 +53,8 @@ obj-y += gpu/
|
|||||||
obj-$(CONFIG_CONNECTOR) += connector/
|
obj-$(CONFIG_CONNECTOR) += connector/
|
||||||
|
|
||||||
# i810fb and intelfb depend on char/agp/
|
# i810fb and intelfb depend on char/agp/
|
||||||
obj-$(CONFIG_FB_I810) += video/i810/
|
obj-$(CONFIG_FB_I810) += video/fbdev/i810/
|
||||||
obj-$(CONFIG_FB_INTEL) += video/intelfb/
|
obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
|
||||||
|
|
||||||
obj-$(CONFIG_PARPORT) += parport/
|
obj-$(CONFIG_PARPORT) += parport/
|
||||||
obj-y += base/ block/ misc/ mfd/ nfc/
|
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);
|
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)
|
static void klist_children_get(struct klist_node *n)
|
||||||
{
|
{
|
||||||
struct device_private *p = to_device_private_parent(n);
|
struct device_private *p = to_device_private_parent(n);
|
||||||
|
@ -187,8 +187,8 @@ static void driver_bound(struct device *dev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
|
pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name,
|
||||||
__func__, dev->driver->name);
|
__func__, dev_name(dev));
|
||||||
|
|
||||||
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
|
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
|
||||||
|
|
||||||
|
@ -39,8 +39,7 @@
|
|||||||
static ssize_t show_##name(struct device *dev, \
|
static ssize_t show_##name(struct device *dev, \
|
||||||
struct device_attribute *attr, char *buf) \
|
struct device_attribute *attr, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
unsigned int cpu = dev->id; \
|
return sprintf(buf, "%d\n", topology_##name(dev->id)); \
|
||||||
return sprintf(buf, "%d\n", topology_##name(cpu)); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
|
#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
|
||||||
|
@ -40,7 +40,7 @@ config SGI_MBCS
|
|||||||
source "drivers/tty/serial/Kconfig"
|
source "drivers/tty/serial/Kconfig"
|
||||||
|
|
||||||
config TTY_PRINTK
|
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
|
depends on EXPERT && TTY
|
||||||
default n
|
default n
|
||||||
---help---
|
---help---
|
||||||
|
@ -61,18 +61,18 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
bcm2835_rng_ops.priv = (unsigned long)rng_base;
|
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 */
|
/* register driver */
|
||||||
err = hwrng_register(&bcm2835_rng_ops);
|
err = hwrng_register(&bcm2835_rng_ops);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "hwrng registration failed\n");
|
dev_err(dev, "hwrng registration failed\n");
|
||||||
iounmap(rng_base);
|
iounmap(rng_base);
|
||||||
} else {
|
} else
|
||||||
dev_info(dev, "hwrng registered\n");
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,18 @@ config IPMI_SI
|
|||||||
Currently, only KCS and SMIC are supported. If
|
Currently, only KCS and SMIC are supported. If
|
||||||
you are using IPMI, you should probably say "y" here.
|
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
|
config IPMI_WATCHDOG
|
||||||
tristate 'IPMI Watchdog Timer'
|
tristate 'IPMI Watchdog Timer'
|
||||||
help
|
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)
|
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.
|
* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
|
||||||
|
@ -251,6 +251,7 @@ static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
|
|||||||
if (!GET_STATUS_OBF(status)) {
|
if (!GET_STATUS_OBF(status)) {
|
||||||
kcs->obf_timeout -= time;
|
kcs->obf_timeout -= time;
|
||||||
if (kcs->obf_timeout < 0) {
|
if (kcs->obf_timeout < 0) {
|
||||||
|
kcs->obf_timeout = OBF_RETRY_TIMEOUT;
|
||||||
start_error_recovery(kcs, "OBF not ready in time");
|
start_error_recovery(kcs, "OBF not ready in time");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
|
|||||||
static int ipmi_init_msghandler(void);
|
static int ipmi_init_msghandler(void);
|
||||||
static void smi_recv_tasklet(unsigned long);
|
static void smi_recv_tasklet(unsigned long);
|
||||||
static void handle_new_recv_msgs(ipmi_smi_t intf);
|
static void handle_new_recv_msgs(ipmi_smi_t intf);
|
||||||
|
static void need_waiter(ipmi_smi_t intf);
|
||||||
|
|
||||||
static int initialized;
|
static int initialized;
|
||||||
|
|
||||||
@ -73,14 +74,28 @@ static struct proc_dir_entry *proc_ipmi_root;
|
|||||||
*/
|
*/
|
||||||
#define MAX_MSG_TIMEOUT 60000
|
#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.
|
* The main "user" data structure.
|
||||||
*/
|
*/
|
||||||
struct ipmi_user {
|
struct ipmi_user {
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
|
|
||||||
/* Set to "0" when the user is destroyed. */
|
/* Set to false when the user is destroyed. */
|
||||||
int valid;
|
bool valid;
|
||||||
|
|
||||||
struct kref refcount;
|
struct kref refcount;
|
||||||
|
|
||||||
@ -92,7 +107,7 @@ struct ipmi_user {
|
|||||||
ipmi_smi_t intf;
|
ipmi_smi_t intf;
|
||||||
|
|
||||||
/* Does this interface receive IPMI events? */
|
/* Does this interface receive IPMI events? */
|
||||||
int gets_events;
|
bool gets_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmd_rcvr {
|
struct cmd_rcvr {
|
||||||
@ -383,6 +398,9 @@ struct ipmi_smi {
|
|||||||
unsigned int waiting_events_count; /* How many events in queue? */
|
unsigned int waiting_events_count; /* How many events in queue? */
|
||||||
char delivering_events;
|
char delivering_events;
|
||||||
char event_msg_printed;
|
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
|
* The event receiver for my BMC, only really used at panic
|
||||||
@ -395,7 +413,7 @@ struct ipmi_smi {
|
|||||||
|
|
||||||
/* For handling of maintenance mode. */
|
/* For handling of maintenance mode. */
|
||||||
int maintenance_mode;
|
int maintenance_mode;
|
||||||
int maintenance_mode_enable;
|
bool maintenance_mode_enable;
|
||||||
int auto_maintenance_timeout;
|
int auto_maintenance_timeout;
|
||||||
spinlock_t maintenance_mode_lock; /* Used in a timer... */
|
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 LIST_HEAD(smi_watchers);
|
||||||
static DEFINE_MUTEX(smi_watchers_mutex);
|
static DEFINE_MUTEX(smi_watchers_mutex);
|
||||||
|
|
||||||
|
|
||||||
#define ipmi_inc_stat(intf, stat) \
|
#define ipmi_inc_stat(intf, stat) \
|
||||||
atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
|
atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
|
||||||
#define ipmi_get_stat(intf, stat) \
|
#define ipmi_get_stat(intf, stat) \
|
||||||
@ -772,6 +789,7 @@ static int intf_next_seq(ipmi_smi_t intf,
|
|||||||
*seq = i;
|
*seq = i;
|
||||||
*seqid = intf->seq_table[i].seqid;
|
*seqid = intf->seq_table[i].seqid;
|
||||||
intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
|
intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
|
||||||
|
need_waiter(intf);
|
||||||
} else {
|
} else {
|
||||||
rv = -EAGAIN;
|
rv = -EAGAIN;
|
||||||
}
|
}
|
||||||
@ -941,7 +959,7 @@ int ipmi_create_user(unsigned int if_num,
|
|||||||
new_user->handler = handler;
|
new_user->handler = handler;
|
||||||
new_user->handler_data = handler_data;
|
new_user->handler_data = handler_data;
|
||||||
new_user->intf = intf;
|
new_user->intf = intf;
|
||||||
new_user->gets_events = 0;
|
new_user->gets_events = false;
|
||||||
|
|
||||||
if (!try_module_get(intf->handlers->owner)) {
|
if (!try_module_get(intf->handlers->owner)) {
|
||||||
rv = -ENODEV;
|
rv = -ENODEV;
|
||||||
@ -962,10 +980,15 @@ int ipmi_create_user(unsigned int if_num,
|
|||||||
*/
|
*/
|
||||||
mutex_unlock(&ipmi_interfaces_mutex);
|
mutex_unlock(&ipmi_interfaces_mutex);
|
||||||
|
|
||||||
new_user->valid = 1;
|
new_user->valid = true;
|
||||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
spin_lock_irqsave(&intf->seq_lock, flags);
|
||||||
list_add_rcu(&new_user->link, &intf->users);
|
list_add_rcu(&new_user->link, &intf->users);
|
||||||
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
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;
|
*user = new_user;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1019,7 +1042,13 @@ int ipmi_destroy_user(ipmi_user_t user)
|
|||||||
struct cmd_rcvr *rcvr;
|
struct cmd_rcvr *rcvr;
|
||||||
struct cmd_rcvr *rcvrs = NULL;
|
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. */
|
/* Remove the user from the interface's sequence table. */
|
||||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
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) {
|
if (intf->maintenance_mode != mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case IPMI_MAINTENANCE_MODE_AUTO:
|
case IPMI_MAINTENANCE_MODE_AUTO:
|
||||||
intf->maintenance_mode = mode;
|
|
||||||
intf->maintenance_mode_enable
|
intf->maintenance_mode_enable
|
||||||
= (intf->auto_maintenance_timeout > 0);
|
= (intf->auto_maintenance_timeout > 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPMI_MAINTENANCE_MODE_OFF:
|
case IPMI_MAINTENANCE_MODE_OFF:
|
||||||
intf->maintenance_mode = mode;
|
intf->maintenance_mode_enable = false;
|
||||||
intf->maintenance_mode_enable = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPMI_MAINTENANCE_MODE_ON:
|
case IPMI_MAINTENANCE_MODE_ON:
|
||||||
intf->maintenance_mode = mode;
|
intf->maintenance_mode_enable = true;
|
||||||
intf->maintenance_mode_enable = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
intf->maintenance_mode = mode;
|
||||||
|
|
||||||
maintenance_mode_update(intf);
|
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);
|
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;
|
unsigned long flags;
|
||||||
ipmi_smi_t intf = user->intf;
|
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);
|
INIT_LIST_HEAD(&msgs);
|
||||||
|
|
||||||
spin_lock_irqsave(&intf->events_lock, flags);
|
spin_lock_irqsave(&intf->events_lock, flags);
|
||||||
|
if (user->gets_events == val)
|
||||||
|
goto out;
|
||||||
|
|
||||||
user->gets_events = val;
|
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)
|
if (intf->delivering_events)
|
||||||
/*
|
/*
|
||||||
* Another thread is delivering events for this, so
|
* Another thread is delivering events for this, so
|
||||||
@ -1289,6 +1326,9 @@ int ipmi_register_for_cmd(ipmi_user_t user,
|
|||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (atomic_inc_return(&intf->event_waiters) == 1)
|
||||||
|
need_waiter(intf);
|
||||||
|
|
||||||
list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
|
list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
@ -1330,6 +1370,7 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
|
|||||||
mutex_unlock(&intf->cmd_rcvrs_mutex);
|
mutex_unlock(&intf->cmd_rcvrs_mutex);
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
while (rcvrs) {
|
while (rcvrs) {
|
||||||
|
atomic_dec(&intf->event_waiters);
|
||||||
rcvr = rcvrs;
|
rcvr = rcvrs;
|
||||||
rcvrs = rcvr->next;
|
rcvrs = rcvr->next;
|
||||||
kfree(rcvr);
|
kfree(rcvr);
|
||||||
@ -1535,7 +1576,7 @@ static int i_ipmi_request(ipmi_user_t user,
|
|||||||
= IPMI_MAINTENANCE_MODE_TIMEOUT;
|
= IPMI_MAINTENANCE_MODE_TIMEOUT;
|
||||||
if (!intf->maintenance_mode
|
if (!intf->maintenance_mode
|
||||||
&& !intf->maintenance_mode_enable) {
|
&& !intf->maintenance_mode_enable) {
|
||||||
intf->maintenance_mode_enable = 1;
|
intf->maintenance_mode_enable = true;
|
||||||
maintenance_mode_update(intf);
|
maintenance_mode_update(intf);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
||||||
@ -2876,6 +2917,8 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
|
|||||||
(unsigned long) intf);
|
(unsigned long) intf);
|
||||||
atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
|
atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
|
||||||
spin_lock_init(&intf->events_lock);
|
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);
|
INIT_LIST_HEAD(&intf->waiting_events);
|
||||||
intf->waiting_events_count = 0;
|
intf->waiting_events_count = 0;
|
||||||
mutex_init(&intf->cmd_rcvrs_mutex);
|
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,
|
static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
||||||
struct list_head *timeouts, long timeout_period,
|
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_recv_msg *msg;
|
||||||
struct ipmi_smi_handlers *handlers;
|
struct ipmi_smi_handlers *handlers;
|
||||||
@ -3977,8 +4021,10 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ent->timeout -= timeout_period;
|
ent->timeout -= timeout_period;
|
||||||
if (ent->timeout > 0)
|
if (ent->timeout > 0) {
|
||||||
|
(*waiting_msgs)++;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ent->retries_left == 0) {
|
if (ent->retries_left == 0) {
|
||||||
/* The message has used all its retries. */
|
/* 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;
|
struct ipmi_smi_msg *smi_msg;
|
||||||
/* More retries, send again. */
|
/* More retries, send again. */
|
||||||
|
|
||||||
|
(*waiting_msgs)++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start with the max timer, set to normal timer after
|
* Start with the max timer, set to normal timer after
|
||||||
* the message is sent.
|
* the message is sent.
|
||||||
@ -4040,17 +4088,13 @@ 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 list_head timeouts;
|
||||||
struct ipmi_recv_msg *msg, *msg2;
|
struct ipmi_recv_msg *msg, *msg2;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int i;
|
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
|
* Go through the seq table and find any messages that
|
||||||
@ -4062,7 +4106,7 @@ static void ipmi_timeout_handler(long timeout_period)
|
|||||||
for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
|
for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
|
||||||
check_msg_timeout(intf, &(intf->seq_table[i]),
|
check_msg_timeout(intf, &(intf->seq_table[i]),
|
||||||
&timeouts, timeout_period, i,
|
&timeouts, timeout_period, i,
|
||||||
&flags);
|
&flags, &waiting_msgs);
|
||||||
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
||||||
|
|
||||||
list_for_each_entry_safe(msg, msg2, &timeouts, link)
|
list_for_each_entry_safe(msg, msg2, &timeouts, link)
|
||||||
@ -4083,74 +4127,79 @@ static void ipmi_timeout_handler(long timeout_period)
|
|||||||
-= timeout_period;
|
-= timeout_period;
|
||||||
if (!intf->maintenance_mode
|
if (!intf->maintenance_mode
|
||||||
&& (intf->auto_maintenance_timeout <= 0)) {
|
&& (intf->auto_maintenance_timeout <= 0)) {
|
||||||
intf->maintenance_mode_enable = 0;
|
intf->maintenance_mode_enable = false;
|
||||||
maintenance_mode_update(intf);
|
maintenance_mode_update(intf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
||||||
flags);
|
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;
|
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. */
|
/* No event requests when in maintenance mode. */
|
||||||
if (intf->maintenance_mode_enable)
|
if (intf->maintenance_mode_enable)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
handlers = intf->handlers;
|
handlers = intf->handlers;
|
||||||
if (handlers)
|
if (handlers)
|
||||||
handlers->request_events(intf->send_info);
|
handlers->request_events(intf->send_info);
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct timer_list ipmi_timer;
|
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 atomic_t stop_operation;
|
||||||
static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
|
|
||||||
|
|
||||||
static void ipmi_timeout(unsigned long data)
|
static void ipmi_timeout(unsigned long data)
|
||||||
{
|
{
|
||||||
|
ipmi_smi_t intf;
|
||||||
|
int nt = 0;
|
||||||
|
|
||||||
if (atomic_read(&stop_operation))
|
if (atomic_read(&stop_operation))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ticks_to_req_ev--;
|
rcu_read_lock();
|
||||||
if (ticks_to_req_ev == 0) {
|
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
|
||||||
ipmi_request_event();
|
int lnt = 0;
|
||||||
ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
|
|
||||||
|
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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
|
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();
|
||||||
|
|
||||||
|
if (nt)
|
||||||
mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
|
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 smi_msg_inuse_count = ATOMIC_INIT(0);
|
||||||
static atomic_t recv_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;
|
unsigned char msg_flags;
|
||||||
|
|
||||||
/* Does the BMC have an event buffer? */
|
/* 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
|
* 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
|
* call. Generally used after a panic to make sure stuff goes
|
||||||
* out.
|
* out.
|
||||||
*/
|
*/
|
||||||
int run_to_completion;
|
bool run_to_completion;
|
||||||
|
|
||||||
/* The I/O port of an SI interface. */
|
/* The I/O port of an SI interface. */
|
||||||
int port;
|
int port;
|
||||||
@ -248,19 +248,25 @@ struct smi_info {
|
|||||||
/* The timer for this si. */
|
/* The timer for this si. */
|
||||||
struct timer_list si_timer;
|
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. */
|
/* The time (in jiffies) the last timeout occurred at. */
|
||||||
unsigned long last_timeout_jiffies;
|
unsigned long last_timeout_jiffies;
|
||||||
|
|
||||||
/* Used to gracefully stop the timer without race conditions. */
|
/* Used to gracefully stop the timer without race conditions. */
|
||||||
atomic_t stop_operation;
|
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
|
* The driver will disable interrupts when it gets into a
|
||||||
* situation where it cannot handle messages due to lack of
|
* situation where it cannot handle messages due to lack of
|
||||||
* memory. Once that situation clears up, it will re-enable
|
* memory. Once that situation clears up, it will re-enable
|
||||||
* interrupts.
|
* interrupts.
|
||||||
*/
|
*/
|
||||||
int interrupt_disabled;
|
bool interrupt_disabled;
|
||||||
|
|
||||||
/* From the get device id response... */
|
/* From the get device id response... */
|
||||||
struct ipmi_device_id device_id;
|
struct ipmi_device_id device_id;
|
||||||
@ -273,7 +279,7 @@ struct smi_info {
|
|||||||
* True if we allocated the device, false if it came from
|
* True if we allocated the device, false if it came from
|
||||||
* someplace else (like PCI).
|
* someplace else (like PCI).
|
||||||
*/
|
*/
|
||||||
int dev_registered;
|
bool dev_registered;
|
||||||
|
|
||||||
/* Slave address, could be reported from DMI. */
|
/* Slave address, could be reported from DMI. */
|
||||||
unsigned char slave_addr;
|
unsigned char slave_addr;
|
||||||
@ -297,19 +303,19 @@ struct smi_info {
|
|||||||
static int force_kipmid[SI_MAX_PARMS];
|
static int force_kipmid[SI_MAX_PARMS];
|
||||||
static int num_force_kipmid;
|
static int num_force_kipmid;
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static int pci_registered;
|
static bool pci_registered;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static int pnp_registered;
|
static bool pnp_registered;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_PARISC
|
#ifdef CONFIG_PARISC
|
||||||
static int parisc_registered;
|
static bool parisc_registered;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
|
static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
|
||||||
static int num_max_busy_us;
|
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 add_smi(struct smi_info *smi);
|
||||||
static int try_smi_init(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;
|
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
|
* 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
|
* 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)) {
|
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
|
||||||
start_disable_irq(smi_info);
|
start_disable_irq(smi_info);
|
||||||
smi_info->interrupt_disabled = 1;
|
smi_info->interrupt_disabled = true;
|
||||||
if (!atomic_read(&smi_info->stop_operation))
|
if (!atomic_read(&smi_info->stop_operation))
|
||||||
mod_timer(&smi_info->si_timer,
|
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
||||||
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)) {
|
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
|
||||||
start_enable_irq(smi_info);
|
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,
|
dev_warn(smi_info->dev,
|
||||||
"Maybe ok, but ipmi might run very slowly.\n");
|
"Maybe ok, but ipmi might run very slowly.\n");
|
||||||
} else
|
} else
|
||||||
smi_info->interrupt_disabled = 0;
|
smi_info->interrupt_disabled = false;
|
||||||
smi_info->si_state = SI_NORMAL;
|
smi_info->si_state = SI_NORMAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -853,6 +865,19 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
|
|||||||
return si_sm_result;
|
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,
|
static void sender(void *send_info,
|
||||||
struct ipmi_smi_msg *msg,
|
struct ipmi_smi_msg *msg,
|
||||||
int priority)
|
int priority)
|
||||||
@ -906,27 +931,11 @@ static void sender(void *send_info,
|
|||||||
else
|
else
|
||||||
list_add_tail(&msg->link, &smi_info->xmit_msgs);
|
list_add_tail(&msg->link, &smi_info->xmit_msgs);
|
||||||
|
|
||||||
if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
|
check_start_timer_thread(smi_info);
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&smi_info->si_lock, flags);
|
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;
|
struct smi_info *smi_info = send_info;
|
||||||
enum si_sm_result result;
|
enum si_sm_result result;
|
||||||
@ -1004,6 +1013,17 @@ static int ipmi_thread(void *data)
|
|||||||
|
|
||||||
spin_lock_irqsave(&(smi_info->si_lock), flags);
|
spin_lock_irqsave(&(smi_info->si_lock), flags);
|
||||||
smi_result = smi_event_handler(smi_info, 0);
|
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);
|
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||||
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
|
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
|
||||||
&busy_until);
|
&busy_until);
|
||||||
@ -1011,9 +1031,15 @@ static int ipmi_thread(void *data)
|
|||||||
; /* do nothing */
|
; /* do nothing */
|
||||||
else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
|
else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
|
||||||
schedule();
|
schedule();
|
||||||
else if (smi_result == SI_SM_IDLE)
|
else if (smi_result == SI_SM_IDLE) {
|
||||||
|
if (atomic_read(&smi_info->need_watch)) {
|
||||||
schedule_timeout_interruptible(100);
|
schedule_timeout_interruptible(100);
|
||||||
else
|
} else {
|
||||||
|
/* Wait to be woken up when we are needed. */
|
||||||
|
__set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
} else
|
||||||
schedule_timeout_interruptible(1);
|
schedule_timeout_interruptible(1);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1024,7 +1050,7 @@ static void poll(void *send_info)
|
|||||||
{
|
{
|
||||||
struct smi_info *smi_info = send_info;
|
struct smi_info *smi_info = send_info;
|
||||||
unsigned long flags = 0;
|
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
|
* 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);
|
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 int initialized;
|
||||||
|
|
||||||
static void smi_timeout(unsigned long data)
|
static void smi_timeout(unsigned long data)
|
||||||
@ -1073,10 +1110,6 @@ static void smi_timeout(unsigned long data)
|
|||||||
* SI_USEC_PER_JIFFY);
|
* SI_USEC_PER_JIFFY);
|
||||||
smi_result = smi_event_handler(smi_info, time_diff);
|
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)) {
|
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
|
||||||
/* Running with interrupts, only do long timeouts. */
|
/* Running with interrupts, only do long timeouts. */
|
||||||
timeout = jiffies + SI_TIMEOUT_JIFFIES;
|
timeout = jiffies + SI_TIMEOUT_JIFFIES;
|
||||||
@ -1098,7 +1131,10 @@ static void smi_timeout(unsigned long data)
|
|||||||
|
|
||||||
do_mod_timer:
|
do_mod_timer:
|
||||||
if (smi_result != SI_SM_IDLE)
|
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)
|
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. */
|
/* Set up the timer that drives the interface. */
|
||||||
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
|
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
|
||||||
new_smi->last_timeout_jiffies = jiffies;
|
smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
|
||||||
mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the user forcefully enabled the daemon.
|
* 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;
|
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;
|
struct smi_info *smi_info = send_info;
|
||||||
|
|
||||||
@ -1202,6 +1237,7 @@ static struct ipmi_smi_handlers handlers = {
|
|||||||
.get_smi_info = get_smi_info,
|
.get_smi_info = get_smi_info,
|
||||||
.sender = sender,
|
.sender = sender,
|
||||||
.request_events = request_events,
|
.request_events = request_events,
|
||||||
|
.set_need_watch = set_need_watch,
|
||||||
.set_maintenance_mode = set_maintenance_mode,
|
.set_maintenance_mode = set_maintenance_mode,
|
||||||
.set_run_to_completion = set_run_to_completion,
|
.set_run_to_completion = set_run_to_completion,
|
||||||
.poll = poll,
|
.poll = poll,
|
||||||
@ -1229,7 +1265,7 @@ static bool si_tryplatform = 1;
|
|||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static bool si_trypci = 1;
|
static bool si_trypci = 1;
|
||||||
#endif
|
#endif
|
||||||
static bool si_trydefaults = 1;
|
static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS);
|
||||||
static char *si_type[SI_MAX_PARMS];
|
static char *si_type[SI_MAX_PARMS];
|
||||||
#define MAX_SI_TYPE_STR 30
|
#define MAX_SI_TYPE_STR 30
|
||||||
static char si_type_str[MAX_SI_TYPE_STR];
|
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"
|
MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
|
||||||
" disabled(0). Normally the IPMI driver auto-detects"
|
" disabled(0). Normally the IPMI driver auto-detects"
|
||||||
" this, but the value may be overridden by this parm.");
|
" 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"
|
MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
|
||||||
" specified or found, default is 1. Setting to 0"
|
" specified or found, default is 1. Setting to 0"
|
||||||
" is useful for hot add of devices using hotmod.");
|
" 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));
|
INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
|
||||||
new_smi->curr_msg = NULL;
|
new_smi->curr_msg = NULL;
|
||||||
atomic_set(&new_smi->req_events, 0);
|
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++)
|
for (i = 0; i < SI_NUM_STATS; i++)
|
||||||
atomic_set(&new_smi->stats[i], 0);
|
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->stop_operation, 0);
|
||||||
|
atomic_set(&new_smi->need_watch, 0);
|
||||||
new_smi->intf_num = smi_num;
|
new_smi->intf_num = smi_num;
|
||||||
smi_num++;
|
smi_num++;
|
||||||
|
|
||||||
rv = try_enable_event_buffer(new_smi);
|
rv = try_enable_event_buffer(new_smi);
|
||||||
if (rv == 0)
|
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
|
* 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);
|
rv);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
new_smi->dev_registered = 1;
|
new_smi->dev_registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = ipmi_register_smi(&handlers,
|
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);
|
wait_for_timer_and_thread(new_smi);
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
new_smi->interrupt_disabled = 1;
|
new_smi->interrupt_disabled = true;
|
||||||
|
|
||||||
if (new_smi->intf) {
|
if (new_smi->intf) {
|
||||||
ipmi_unregister_smi(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) {
|
if (new_smi->dev_registered) {
|
||||||
platform_device_unregister(new_smi->pdev);
|
platform_device_unregister(new_smi->pdev);
|
||||||
new_smi->dev_registered = 0;
|
new_smi->dev_registered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -3521,14 +3558,14 @@ static int init_ipmi_si(void)
|
|||||||
printk(KERN_ERR PFX "Unable to register "
|
printk(KERN_ERR PFX "Unable to register "
|
||||||
"PCI driver: %d\n", rv);
|
"PCI driver: %d\n", rv);
|
||||||
else
|
else
|
||||||
pci_registered = 1;
|
pci_registered = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
if (si_tryacpi) {
|
if (si_tryacpi) {
|
||||||
pnp_register_driver(&ipmi_pnp_driver);
|
pnp_register_driver(&ipmi_pnp_driver);
|
||||||
pnp_registered = 1;
|
pnp_registered = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3544,7 +3581,7 @@ static int init_ipmi_si(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_PARISC
|
#ifdef CONFIG_PARISC
|
||||||
register_parisc_driver(&ipmi_parisc_driver);
|
register_parisc_driver(&ipmi_parisc_driver);
|
||||||
parisc_registered = 1;
|
parisc_registered = true;
|
||||||
/* poking PC IO addresses will crash machine, don't do it */
|
/* poking PC IO addresses will crash machine, don't do it */
|
||||||
si_trydefaults = 0;
|
si_trydefaults = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,7 +15,7 @@ config SYNCLINK_CS
|
|||||||
|
|
||||||
This driver may be built as a module ( = code which can be
|
This driver may be built as a module ( = code which can be
|
||||||
inserted in and removed from the running kernel whenever you want).
|
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.
|
here.
|
||||||
|
|
||||||
config CARDMAN_4000
|
config CARDMAN_4000
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
#include <linux/export.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
struct ttyprintk_port {
|
struct ttyprintk_port {
|
||||||
struct tty_port port;
|
struct tty_port port;
|
||||||
@ -210,10 +210,19 @@ static int __init ttyprintk_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
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);
|
tty_unregister_driver(ttyprintk_driver);
|
||||||
put_tty_driver(ttyprintk_driver);
|
put_tty_driver(ttyprintk_driver);
|
||||||
tty_port_destroy(&tpk_port.port);
|
tty_port_destroy(&tpk_port.port);
|
||||||
ttyprintk_driver = NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device_initcall(ttyprintk_init);
|
device_initcall(ttyprintk_init);
|
||||||
|
module_exit(ttyprintk_exit);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -197,7 +197,7 @@ config AMCC_PPC440SPE_ADMA
|
|||||||
|
|
||||||
config TIMB_DMA
|
config TIMB_DMA
|
||||||
tristate "Timberdale FPGA DMA support"
|
tristate "Timberdale FPGA DMA support"
|
||||||
depends on MFD_TIMBERDALE || HAS_IOMEM
|
depends on MFD_TIMBERDALE
|
||||||
select DMA_ENGINE
|
select DMA_ENGINE
|
||||||
help
|
help
|
||||||
Enable support for the Timberdale FPGA DMA engine.
|
Enable support for the Timberdale FPGA DMA engine.
|
||||||
|
@ -182,11 +182,13 @@ static void edma_execute(struct edma_chan *echan)
|
|||||||
echan->ecc->dummy_slot);
|
echan->ecc->dummy_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
edma_resume(echan->ch_num);
|
|
||||||
|
|
||||||
if (edesc->processed <= MAX_NR_SG) {
|
if (edesc->processed <= MAX_NR_SG) {
|
||||||
dev_dbg(dev, "first transfer starting %d\n", echan->ch_num);
|
dev_dbg(dev, "first transfer starting %d\n", echan->ch_num);
|
||||||
edma_start(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,
|
.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_ALIAS("platform:fsl-edma");
|
||||||
MODULE_DESCRIPTION("Freescale eDMA engine driver");
|
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;
|
struct sirfsoc_dma *sdma = ofdma->of_dma_data;
|
||||||
unsigned int request = dma_spec->args[0];
|
unsigned int request = dma_spec->args[0];
|
||||||
|
|
||||||
if (request > SIRFSOC_DMA_CHANNELS)
|
if (request >= SIRFSOC_DMA_CHANNELS)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return dma_get_slave_channel(&sdma->channels[request].chan);
|
return dma_get_slave_channel(&sdma->channels[request].chan);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* SPEAr platform SPI chipselect abstraction over gpiolib
|
* SPEAr platform SPI chipselect abstraction over gpiolib
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 ST Microelectronics
|
* 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
|
* This file is licensed under the terms of the GNU General Public
|
||||||
* License version 2. This program is licensed "as is" without any
|
* 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);
|
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_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
|
|||||||
|
|
||||||
drm-usb-y := drm_usb.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_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_FB_HELPER) += drm_fb_helper.o
|
||||||
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_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++) {
|
for (loop = 0; loop < CBR_PASSNUM2; loop++) {
|
||||||
if ((data = cbr_test2(ast)) != 0) {
|
if ((data = cbr_test2(ast)) != 0) {
|
||||||
data2 &= data;
|
data2 &= data;
|
||||||
if (!data)
|
if (!data2)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
|
#include <linux/console.h>
|
||||||
|
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
#include <drm/drm_crtc.h>
|
#include <drm/drm_crtc.h>
|
||||||
@ -87,8 +88,6 @@ struct bochs_device {
|
|||||||
struct bochs_framebuffer gfb;
|
struct bochs_framebuffer gfb;
|
||||||
struct drm_fb_helper helper;
|
struct drm_fb_helper helper;
|
||||||
int size;
|
int size;
|
||||||
int x1, y1, x2, y2; /* dirty rect */
|
|
||||||
spinlock_t dirty_lock;
|
|
||||||
bool initialized;
|
bool initialized;
|
||||||
} fb;
|
} fb;
|
||||||
};
|
};
|
||||||
|
@ -94,6 +94,49 @@ static struct drm_driver bochs_driver = {
|
|||||||
.dumb_destroy = drm_gem_dumb_destroy,
|
.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 */
|
/* pci interface */
|
||||||
|
|
||||||
@ -155,6 +198,7 @@ static struct pci_driver bochs_pci_driver = {
|
|||||||
.id_table = bochs_pci_tbl,
|
.id_table = bochs_pci_tbl,
|
||||||
.probe = bochs_pci_probe,
|
.probe = bochs_pci_probe,
|
||||||
.remove = bochs_pci_remove,
|
.remove = bochs_pci_remove,
|
||||||
|
.driver.pm = &bochs_pm_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
@ -190,7 +190,6 @@ int bochs_fbdev_init(struct bochs_device *bochs)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bochs->fb.helper.funcs = &bochs_fb_helper_funcs;
|
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,
|
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
|
||||||
1, 1);
|
1, 1);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
|
#include <drm/drm_crtc_helper.h>
|
||||||
|
|
||||||
#include "cirrus_drv.h"
|
#include "cirrus_drv.h"
|
||||||
|
|
||||||
@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
|
|||||||
drm_put_dev(dev);
|
drm_put_dev(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cirrus_pm_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(dev);
|
||||||
|
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||||
|
struct cirrus_device *cdev = drm_dev->dev_private;
|
||||||
|
|
||||||
|
drm_kms_helper_poll_disable(drm_dev);
|
||||||
|
|
||||||
|
if (cdev->mode_info.gfbdev) {
|
||||||
|
console_lock();
|
||||||
|
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
|
||||||
|
console_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cirrus_pm_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(dev);
|
||||||
|
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||||
|
struct cirrus_device *cdev = drm_dev->dev_private;
|
||||||
|
|
||||||
|
drm_helper_resume_force_mode(drm_dev);
|
||||||
|
|
||||||
|
if (cdev->mode_info.gfbdev) {
|
||||||
|
console_lock();
|
||||||
|
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
|
||||||
|
console_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
drm_kms_helper_poll_enable(drm_dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct file_operations cirrus_driver_fops = {
|
static const struct file_operations cirrus_driver_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = drm_open,
|
.open = drm_open,
|
||||||
@ -103,11 +139,17 @@ static struct drm_driver driver = {
|
|||||||
.dumb_destroy = drm_gem_dumb_destroy,
|
.dumb_destroy = drm_gem_dumb_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct dev_pm_ops cirrus_pm_ops = {
|
||||||
|
SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
|
||||||
|
cirrus_pm_resume)
|
||||||
|
};
|
||||||
|
|
||||||
static struct pci_driver cirrus_pci_driver = {
|
static struct pci_driver cirrus_pci_driver = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.id_table = pciidlist,
|
.id_table = pciidlist,
|
||||||
.probe = cirrus_pci_probe,
|
.probe = cirrus_pci_probe,
|
||||||
.remove = cirrus_pci_remove,
|
.remove = cirrus_pci_remove,
|
||||||
|
.driver.pm = &cirrus_pm_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init cirrus_init(void)
|
static int __init cirrus_init(void)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user